alignment-react
Version:
Alignment display engine for React
551 lines (532 loc) • 16.3 kB
JavaScript
import React, { createContext, useState, useEffect, Fragment } from 'react';
import { string, node, bool, shape, arrayOf, objectOf, instanceOf, func } from 'prop-types';
import { parseString } from 'xml2js';
var xmlToJson = function xmlToJson(xml) {
var json;
parseString(xml, {
explicitCharkey: true
}, function (_err, result) {
json = result;
});
return json;
};
var AlignmentContext = createContext();
AlignmentContext.displayName = 'AlignmentContext';
var Alignment = function Alignment(_ref) {
var alignment = _ref.alignment,
children = _ref.children;
var json = xmlToJson(alignment);
return /*#__PURE__*/React.createElement(AlignmentContext.Provider, {
value: {
json: json
}
}, children);
};
Alignment.propTypes = {
alignment: string.isRequired,
children: node
};
Alignment.defaultProps = {
children: null
};
var styles = {"button":"_h8zHp","right":"_1e_49"};
var Collapse = function Collapse(_ref) {
var title = _ref.title,
children = _ref.children,
beginCollapsed = _ref.collapsed;
var _useState = useState(beginCollapsed),
collapsed = _useState[0],
setCollapsed = _useState[1];
var toggleCollapse = function toggleCollapse() {
return setCollapsed(!collapsed);
};
useEffect(function () {
setCollapsed(beginCollapsed);
}, [beginCollapsed]);
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("button", {
type: "button",
className: styles.button,
onClick: toggleCollapse
}, /*#__PURE__*/React.createElement("div", null, title), /*#__PURE__*/React.createElement("div", {
className: styles.right
}, collapsed ? '+' : '-')), collapsed ? null : children);
};
Collapse.propTypes = {
title: string.isRequired,
children: node.isRequired,
collapsed: bool
};
Collapse.defaultProps = {
collapsed: true
};
var SentenceContext = createContext();
SentenceContext.displayName = 'SentenceContext';
var commentType = shape({
$: shape({
"class": string.isRequired
}).isRequired,
_: string
});
var refsType = shape({
$: shape({
nrefs: string.isRequired
}).isRequired
});
var wordType = shape({
$: shape({
n: string.isRequired
}).isRequired,
comment: arrayOf(commentType),
text: arrayOf(shape({
_: string.isRequired
})),
refs: arrayOf(refsType)
});
var wordListType = shape({
$: shape({
lnum: string.isRequired
}).isRequired,
comment: arrayOf(commentType),
w: arrayOf(wordType)
});
var sentenceType = shape({
$: shape({
n: string.isRequired
}).isRequired,
wds: arrayOf(wordListType)
});
var alignmentType = shape({
'aligned-text': shape({
sentence: arrayOf(sentenceType).isRequired
}).isRequired
});
var activeType = shape({
selected: shape({
lnum: string.isRequired,
n: string.isRequired
}).isRequired,
aligned: objectOf(instanceOf(Set)).isRequired
});
var styles$1 = {"comments":"_3uKPb","dl":"_3qDVw","container":"_36mOc","dt":"_3oJfY","dd":"_3IQKY"};
var commentDl = function commentDl(_ref, lnum, n, ii) {
var title = _ref.title,
value = _ref.value;
return /*#__PURE__*/React.createElement("dl", {
key: "comment-" + lnum + "-" + n + "-" + ii,
className: styles$1.dl
}, /*#__PURE__*/React.createElement("div", {
className: styles$1.container
}, /*#__PURE__*/React.createElement("dt", {
className: styles$1.dt
}, title), /*#__PURE__*/React.createElement("dd", {
className: styles$1.dd
}, value)));
};
var wordListDls = function wordListDls(_ref2) {
var wds = _ref2.wds,
active = _ref2.active;
var dls = [];
(wds || []).forEach(function (_ref3) {
var lnum = _ref3.$.lnum,
w = _ref3.w;
return (w || []).forEach(function (_ref4) {
var n = _ref4.$.n,
comment = _ref4.comment,
text = _ref4.text;
return (comment || []).forEach(function (_ref5, ii) {
var commentText = _ref5._;
var title = (text || []).map(function (_ref6) {
var _ = _ref6._;
return _;
}).join(' ');
if (active && active.aligned && active.aligned[lnum] && active.aligned[lnum].has(n)) {
dls.push(commentDl({
title: title,
value: commentText
}, lnum, n, ii));
}
});
});
});
return dls;
};
var Comments = function Comments(_ref7) {
var sentence = _ref7.sentence,
active = _ref7.active;
if (!active) {
return false;
}
var wds = sentence && sentence.wds;
var dls = wordListDls({
wds: wds,
active: active
});
if (dls.length === 0) {
return false;
}
return /*#__PURE__*/React.createElement("div", {
className: styles$1.comments
}, dls);
};
Comments.propTypes = {
sentence: sentenceType.isRequired,
active: activeType
};
Comments.defaultProps = {
active: null
};
var CommentsWithContext = function CommentsWithContext() {
return /*#__PURE__*/React.createElement(SentenceContext.Consumer, null, function (_ref) {
var sentence = _ref.sentence,
active = _ref.active;
return /*#__PURE__*/React.createElement(Comments, {
sentence: sentence,
active: active
});
});
};
var styles$2 = {"text":"_2vy3L","word":"_2xbMK","active":"_1NIy8"};
var wordSpans = function wordSpans(words, lnum, active, toggleActive) {
var spans = [];
words.w.forEach(function (word) {
var text = word.text,
n = word.$.n;
var classes = [styles$2.word];
var innerText = text.map(function (_ref) {
var _ = _ref._;
return _;
}).join( /*#__PURE__*/React.createElement("br", null));
if (active && active.aligned && active.aligned[lnum] && active.aligned[lnum].has(n)) {
classes.push(styles$2.active);
}
var onClick = function onClick() {
toggleActive([lnum, n]);
};
var onKeyDown = function onKeyDown(event) {
var key = event.key;
if (key === 'Enter') {
onClick();
}
};
spans.push( /*#__PURE__*/React.createElement("span", {
key: n,
role: "button",
tabIndex: "0",
className: classes.join(' '),
onClick: onClick,
onKeyDown: onKeyDown
}, innerText));
spans.push(' ');
});
spans.pop();
return spans;
};
var Segment = function Segment(_ref2) {
var lnum = _ref2.lnum,
sentence = _ref2.sentence,
active = _ref2.active,
toggleActive = _ref2.toggleActive;
var words = sentence && sentence.wds ? sentence.wds.find(function (_ref3) {
var $ = _ref3.$;
return $.lnum === lnum;
}) : false;
if (!words) {
return false;
}
return /*#__PURE__*/React.createElement("div", {
className: styles$2.text
}, /*#__PURE__*/React.createElement("p", null, wordSpans(words, lnum, active, toggleActive)));
};
Segment.propTypes = {
lnum: string.isRequired,
sentence: sentenceType.isRequired,
active: activeType,
toggleActive: func
};
Segment.defaultProps = {
active: null,
toggleActive: function toggleActive() {}
};
var SegmentWithContext = function SegmentWithContext(_ref) {
var lnum = _ref.lnum;
return /*#__PURE__*/React.createElement(SentenceContext.Consumer, null, function (_ref2) {
var sentence = _ref2.sentence,
active = _ref2.active,
toggleActive = _ref2.toggleActive;
return /*#__PURE__*/React.createElement(Segment, {
lnum: lnum,
sentence: sentence,
active: active,
toggleActive: toggleActive
});
});
};
SegmentWithContext.propTypes = {
lnum: string.isRequired
};
var uniq = function uniq(array) {
return Array.from(new Set(array));
};
var buildIdMap = function buildIdMap(alignedText, sentence) {
var idMap = {};
var lnums = uniq(alignedText.language.map(function (_ref) {
var lnum = _ref.$.lnum;
return lnum;
}));
lnums.forEach(function (ln) {
idMap[ln] = {};
});
var addToSet = function addToSet(outerLnum, outerN, innerLnum, innerN) {
if (!idMap[outerLnum][outerN]) {
idMap[outerLnum][outerN] = {};
lnums.forEach(function (ln) {
idMap[outerLnum][outerN][ln] = new Set();
});
}
idMap[outerLnum][outerN][innerLnum].add(innerN);
};
var unifySets = function unifySets(lnum1, n1, lnum2, n2) {
idMap[lnum1][n1][lnum1].forEach(function (v) {
return idMap[lnum2][n2][lnum1].add(v);
});
idMap[lnum1][n1][lnum2].forEach(function (v) {
return idMap[lnum2][n2][lnum2].add(v);
});
idMap[lnum2][n2][lnum1] = idMap[lnum1][n1][lnum1];
idMap[lnum2][n2][lnum2] = idMap[lnum1][n1][lnum2];
};
sentence.wds.forEach(function (wd) {
var lnum = wd.$.lnum;
wd.w.forEach(function (word) {
var n = word.$.n;
addToSet(lnum, n, lnum, n);
if (word.refs) {
var nrefs = word.refs[0].$.nrefs.split(/\s+/);
lnums.forEach(function (lnumRef) {
if (lnumRef !== lnum) {
nrefs.forEach(function (nref) {
addToSet(lnum, n, lnumRef, nref);
addToSet(lnumRef, nref, lnum, n);
unifySets(lnum, n, lnumRef, nref);
});
}
});
}
});
});
return idMap;
};
var WrappedSentence = function WrappedSentence(_ref2) {
var n = _ref2.n,
json = _ref2.json,
children = _ref2.children;
var _useState = useState(null),
active = _useState[0],
setActive = _useState[1];
useEffect(function () {
setActive(null);
}, [n, json]);
var alignedText = json['aligned-text'];
var sentence = (alignedText.sentence || []).find(function (_ref3) {
var sentenceN = _ref3.$.n;
return n === sentenceN;
});
var idMap = buildIdMap(alignedText, sentence);
var toggleActive = function toggleActive(_ref4) {
var lnum = _ref4[0],
wordId = _ref4[1];
if (active && active.aligned && active.aligned[lnum] && active.aligned[lnum].has(wordId)) {
setActive(null);
} else if (idMap[lnum] && idMap[lnum][wordId]) {
setActive({
selected: {
lnum: lnum,
n: n
},
aligned: idMap[lnum][wordId]
});
}
};
return /*#__PURE__*/React.createElement(SentenceContext.Provider, {
value: {
sentence: sentence,
active: active,
toggleActive: toggleActive
}
}, children);
};
var Sentence = function Sentence(_ref5) {
var n = _ref5.n,
children = _ref5.children;
return /*#__PURE__*/React.createElement(AlignmentContext.Consumer, null, function (_ref6) {
var json = _ref6.json;
return /*#__PURE__*/React.createElement(WrappedSentence, {
n: n,
json: json
}, children);
});
};
WrappedSentence.propTypes = {
n: string.isRequired,
json: alignmentType.isRequired,
children: node
};
WrappedSentence.defaultProps = {
children: null
};
Sentence.propTypes = {
n: string.isRequired,
children: node
};
Sentence.defaultProps = {
children: null
};
var styles$3 = {"xml":"_3LPRm","word":"_39t71","active":"_jYWJE","highlight":"_11I1P","bracket":"_7xRyo","element":"_2wtEi","attribute":"_2A3wI","attributeText":"_3DzH_"};
var tab = function tab(indent) {
return /*#__PURE__*/React.createElement(Fragment, null, ' '.repeat(indent * 4));
};
var attributesToJsx = function attributesToJsx(attributes) {
return Object.entries(attributes || {}).map(function (_ref) {
var key = _ref[0],
value = _ref[1];
return /*#__PURE__*/React.createElement(Fragment, {
key: key
}, ' ', /*#__PURE__*/React.createElement("span", {
className: styles$3.attribute
}, key, "="), /*#__PURE__*/React.createElement("span", {
className: styles$3.attributeText
}, "\"", value, "\""));
});
};
var openingTag = function openingTag(name, attributes, key, indent, close, br) {
if (indent === void 0) {
indent = 0;
}
if (close === void 0) {
close = false;
}
if (br === void 0) {
br = true;
}
return /*#__PURE__*/React.createElement(Fragment, {
key: key
}, /*#__PURE__*/React.createElement("span", {
className: styles$3.bracket
}, tab(indent), "<"), /*#__PURE__*/React.createElement("span", {
className: styles$3.element
}, name), attributesToJsx(attributes), close ? ' /' : '', /*#__PURE__*/React.createElement("span", {
className: styles$3.bracket
}, ">"), br && /*#__PURE__*/React.createElement("br", null));
};
var closingTag = function closingTag(name, key, indent) {
if (indent === void 0) {
indent = 0;
}
return /*#__PURE__*/React.createElement(Fragment, {
key: key
}, /*#__PURE__*/React.createElement("span", {
className: styles$3.bracket
}, tab(indent), "<"), /*#__PURE__*/React.createElement("span", {
className: styles$3.element
}, "/", name), /*#__PURE__*/React.createElement("span", {
className: styles$3.bracket
}, ">"));
};
var renderComment = function renderComment(comment, key, indent) {
var _ = comment._,
$ = comment.$;
if (_) {
return /*#__PURE__*/React.createElement("div", {
key: key
}, openingTag('comment', $, "open-" + key, indent, false, false), _, closingTag('comment', "close-" + key));
}
return /*#__PURE__*/React.createElement("div", {
key: key
}, openingTag('comment', comment.$, key, indent, true));
};
var renderText = function renderText(text, key, indent) {
var _ = text._,
$ = text.$;
return /*#__PURE__*/React.createElement("div", {
key: key
}, openingTag('text', $, "open-" + key, indent, false, false), _, closingTag('text', "close-" + key));
};
var renderWord = function renderWord(word, key, lnum, active, toggleActive, indent) {
var text = word.text,
refs = word.refs,
comment = word.comment,
n = word.$.n;
var classes = [styles$3.word];
var onClick = function onClick() {
toggleActive([lnum, n]);
};
var onKeyDown = function onKeyDown(event) {
var eventKey = event.key;
if (eventKey === 'Enter') {
onClick();
}
};
if (active && active.aligned && active.aligned[lnum] && active.aligned[lnum].has(n)) {
classes.push(styles$3.active);
}
return /*#__PURE__*/React.createElement("div", {
key: lnum + "-" + n,
role: "button",
tabIndex: "0",
className: classes.join(' '),
onClick: onClick,
onKeyDown: onKeyDown
}, openingTag('w', word.$, "open-" + key, indent), comment && comment.map(function (cmt, ii) {
return renderComment(cmt, "comment-" + key + "-" + ii, indent + 1);
}), text && text.map(function (txt, ii) {
return renderText(txt, "text-" + key + "-" + ii, indent + 1);
}), refs && refs.map(function (rfs, ii) {
return openingTag('refs', rfs.$, "ref-" + key + "-" + ii, indent + 1);
}), closingTag('w', "close-" + key, indent));
};
var renderWordList = function renderWordList(wordList, active, toggleActive) {
var w = wordList.w,
comment = wordList.comment,
$ = wordList.$;
var lnum = $.lnum;
return /*#__PURE__*/React.createElement(Fragment, {
key: lnum
}, openingTag('wds', $, "open-" + lnum, 2, true), comment && comment.map(function (cmt, ii) {
return renderComment(cmt, lnum + "-" + ii, 3);
}), w && w.map(function (word, ii) {
return renderWord(word, lnum + "-" + ii, lnum, active, toggleActive, 3);
}), closingTag('wds', "close-" + lnum, 2), /*#__PURE__*/React.createElement("br", null));
};
var Xml = function Xml(_ref2) {
var sentence = _ref2.sentence,
active = _ref2.active,
toggleActive = _ref2.toggleActive;
return /*#__PURE__*/React.createElement("div", {
className: styles$3.xml
}, openingTag('sentence', sentence.$, 'sentence'), sentence.wds && sentence.wds.map(function (wordList) {
return renderWordList(wordList, active, toggleActive);
}), closingTag('sentence', 'sentence-close'));
};
Xml.propTypes = {
active: activeType,
sentence: sentenceType.isRequired,
toggleActive: func
};
Xml.defaultProps = {
active: null,
toggleActive: function toggleActive() {}
};
var XmlWithContext = function XmlWithContext() {
return /*#__PURE__*/React.createElement(SentenceContext.Consumer, null, function (_ref) {
var sentence = _ref.sentence,
active = _ref.active,
toggleActive = _ref.toggleActive;
return /*#__PURE__*/React.createElement(Xml, {
sentence: sentence,
active: active,
toggleActive: toggleActive
});
});
};
export { Alignment, Collapse, CommentsWithContext as Comments, SegmentWithContext as Segment, Sentence, XmlWithContext as Xml };
//# sourceMappingURL=index.modern.js.map