@20minutes/draft-convert 3.0.3 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -3
- package/esm/blockEntities.js +58 -61
- package/esm/blockInlineStyles.js +64 -87
- package/esm/convertFromHTML.js +442 -478
- package/esm/convertToHTML.js +71 -93
- package/esm/default/defaultBlockHTML.js +33 -30
- package/esm/default/defaultInlineHTML.js +16 -16
- package/esm/encodeBlock.js +36 -40
- package/esm/index.js +1 -1
- package/esm/util/accumulateFunction.js +7 -9
- package/esm/util/blockTypeObjectFunction.js +7 -9
- package/esm/util/getBlockTags.js +19 -19
- package/esm/util/getElementHTML.js +24 -28
- package/esm/util/getElementTagLength.js +14 -16
- package/esm/util/getNestedBlockTags.js +20 -25
- package/esm/util/parseHTML.js +15 -15
- package/esm/util/rangeSort.js +6 -6
- package/esm/util/splitReactElement.js +27 -13
- package/esm/util/styleObjectFunction.js +6 -8
- package/esm/util/updateMutation.js +57 -47
- package/lib/blockEntities.js +74 -69
- package/lib/blockInlineStyles.js +81 -96
- package/lib/convertFromHTML.js +459 -487
- package/lib/convertToHTML.js +93 -107
- package/lib/default/defaultBlockHTML.js +47 -35
- package/lib/default/defaultInlineHTML.js +29 -21
- package/lib/encodeBlock.js +50 -46
- package/lib/index.js +25 -23
- package/lib/util/accumulateFunction.js +13 -11
- package/lib/util/blockTypeObjectFunction.js +13 -11
- package/lib/util/getBlockTags.js +35 -27
- package/lib/util/getElementHTML.js +40 -36
- package/lib/util/getElementTagLength.js +28 -22
- package/lib/util/getNestedBlockTags.js +35 -32
- package/lib/util/parseHTML.js +22 -18
- package/lib/util/rangeSort.js +13 -9
- package/lib/util/splitReactElement.js +42 -19
- package/lib/util/styleObjectFunction.js +12 -10
- package/lib/util/updateMutation.js +64 -51
- package/package.json +24 -28
- package/dist/draft-convert.js +0 -440
- package/dist/draft-convert.min.js +0 -1
package/README.md
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
@20minutes/draft-convert
|
|
2
2
|
===============
|
|
3
3
|
|
|
4
|
-
[](https://www.npmjs.com/package/@20minutes%2Fdraft-convert)
|
|
4
|
+
[](https://github.com/20minutes/draft-convert/actions/workflows/tests.yml)
|
|
5
|
+
[](https://www.npmjs.com/package/@20minutes/draft-convert)
|
|
7
6
|
|
|
8
7
|
Forked version:
|
|
9
8
|
- with deps up to date
|
package/esm/blockEntities.js
CHANGED
|
@@ -1,67 +1,64 @@
|
|
|
1
|
-
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
2
|
-
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
3
|
-
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; }
|
|
4
|
-
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) { _defineProperty(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; }
|
|
5
1
|
import updateMutation from './util/updateMutation';
|
|
6
2
|
import rangeSort from './util/rangeSort';
|
|
7
3
|
import getElementHTML from './util/getElementHTML';
|
|
8
4
|
import getElementTagLength from './util/getElementTagLength';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
5
|
+
const converter = (entity = {}, originalText = '')=>originalText;
|
|
6
|
+
export default ((block, entityMap, entityConverter = converter)=>{
|
|
7
|
+
let resultText = [
|
|
8
|
+
...block.text
|
|
9
|
+
];
|
|
10
|
+
let getEntityHTML = entityConverter;
|
|
11
|
+
if (entityConverter.__isMiddleware) {
|
|
12
|
+
getEntityHTML = entityConverter(converter);
|
|
13
|
+
}
|
|
14
|
+
if (Object.prototype.hasOwnProperty.call(block, 'entityRanges') && block.entityRanges.length > 0) {
|
|
15
|
+
let entities = block.entityRanges.sort(rangeSort);
|
|
16
|
+
let styles = block.inlineStyleRanges;
|
|
17
|
+
for(let index = 0; index < entities.length; index += 1){
|
|
18
|
+
const entityRange = entities[index];
|
|
19
|
+
const entity = entityMap[entityRange.key];
|
|
20
|
+
const originalText = resultText.slice(entityRange.offset, entityRange.offset + entityRange.length).join('');
|
|
21
|
+
const entityHTML = getEntityHTML(entity, originalText);
|
|
22
|
+
const elementHTML = getElementHTML(entityHTML, originalText);
|
|
23
|
+
let converted;
|
|
24
|
+
if (!!elementHTML || elementHTML === '') {
|
|
25
|
+
converted = [
|
|
26
|
+
...elementHTML
|
|
27
|
+
];
|
|
28
|
+
} else {
|
|
29
|
+
converted = originalText;
|
|
30
|
+
}
|
|
31
|
+
const prefixLength = getElementTagLength(entityHTML, 'start');
|
|
32
|
+
const suffixLength = getElementTagLength(entityHTML, 'end');
|
|
33
|
+
const updateLaterMutation = (mutation, mutationIndex)=>{
|
|
34
|
+
if (mutationIndex > index || Object.prototype.hasOwnProperty.call(mutation, 'style')) {
|
|
35
|
+
return updateMutation(mutation, entityRange.offset, entityRange.length, converted.length, prefixLength, suffixLength);
|
|
36
|
+
}
|
|
37
|
+
return mutation;
|
|
38
|
+
};
|
|
39
|
+
const updateLaterMutations = (mutationList)=>mutationList.reduce((acc, mutation, mutationIndex)=>{
|
|
40
|
+
const updatedMutation = updateLaterMutation(mutation, mutationIndex);
|
|
41
|
+
if (Array.isArray(updatedMutation)) {
|
|
42
|
+
return acc.concat(updatedMutation);
|
|
43
|
+
}
|
|
44
|
+
return acc.concat([
|
|
45
|
+
updatedMutation
|
|
46
|
+
]);
|
|
47
|
+
}, []);
|
|
48
|
+
entities = updateLaterMutations(entities);
|
|
49
|
+
styles = updateLaterMutations(styles);
|
|
50
|
+
resultText = [
|
|
51
|
+
...resultText.slice(0, entityRange.offset),
|
|
52
|
+
...converted,
|
|
53
|
+
...resultText.slice(entityRange.offset + entityRange.length)
|
|
54
|
+
];
|
|
41
55
|
}
|
|
42
|
-
return
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return acc.concat(updatedMutation);
|
|
49
|
-
}
|
|
50
|
-
return acc.concat([updatedMutation]);
|
|
51
|
-
}, []);
|
|
52
|
-
};
|
|
53
|
-
entities = updateLaterMutations(entities);
|
|
54
|
-
styles = updateLaterMutations(styles);
|
|
55
|
-
resultText = [].concat(_toConsumableArray(resultText.slice(0, entityRange.offset)), _toConsumableArray(converted), _toConsumableArray(resultText.slice(entityRange.offset + entityRange.length)));
|
|
56
|
-
};
|
|
57
|
-
for (var index = 0; index < entities.length; index += 1) {
|
|
58
|
-
_loop(index);
|
|
56
|
+
return {
|
|
57
|
+
...block,
|
|
58
|
+
text: resultText.join(''),
|
|
59
|
+
inlineStyleRanges: styles,
|
|
60
|
+
entityRanges: entities
|
|
61
|
+
};
|
|
59
62
|
}
|
|
60
|
-
return
|
|
61
|
-
|
|
62
|
-
inlineStyleRanges: styles,
|
|
63
|
-
entityRanges: entities
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
return block;
|
|
67
|
-
});
|
|
63
|
+
return block;
|
|
64
|
+
});
|
package/esm/blockInlineStyles.js
CHANGED
|
@@ -1,98 +1,75 @@
|
|
|
1
|
-
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
2
1
|
import invariant from 'invariant';
|
|
3
2
|
import styleObjectFunction from './util/styleObjectFunction';
|
|
4
3
|
import accumulateFunction from './util/accumulateFunction';
|
|
5
4
|
import getElementHTML from './util/getElementHTML';
|
|
6
5
|
import rangeSort from './util/rangeSort';
|
|
7
6
|
import defaultInlineHTML from './default/defaultInlineHTML';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
const subtractStyles = (original, toRemove)=>original.filter((el)=>!toRemove.some((elToRemove)=>elToRemove.style === el.style));
|
|
8
|
+
const popEndingStyles = (styleStack, endingStyles)=>endingStyles.reduceRight((stack, style)=>{
|
|
9
|
+
const styleToRemove = stack[stack.length - 1];
|
|
10
|
+
invariant(styleToRemove.style === style.style, `Style ${styleToRemove.style} to be removed doesn't match expected ${style.style}`);
|
|
11
|
+
return stack.slice(0, -1);
|
|
12
|
+
}, styleStack);
|
|
13
|
+
const characterStyles = (offset, ranges)=>ranges.filter((range)=>offset >= range.offset && offset < range.offset + range.length);
|
|
14
|
+
const rangeIsSubset = (firstRange, secondRange)=>{
|
|
15
|
+
// returns true if the second range is a subset of the first
|
|
16
|
+
const secondStartWithinFirst = firstRange.offset <= secondRange.offset;
|
|
17
|
+
const secondEndWithinFirst = firstRange.offset + firstRange.length >= secondRange.offset + secondRange.length;
|
|
18
|
+
return secondStartWithinFirst && secondEndWithinFirst;
|
|
14
19
|
};
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return
|
|
20
|
-
}, styleStack);
|
|
20
|
+
const latestStyleLast = (s1, s2)=>{
|
|
21
|
+
// make sure longer-lasting styles are added first
|
|
22
|
+
const s2endIndex = s2.offset + s2.length;
|
|
23
|
+
const s1endIndex = s1.offset + s1.length;
|
|
24
|
+
return s2endIndex - s1endIndex;
|
|
21
25
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
var secondEndWithinFirst = firstRange.offset + firstRange.length >= secondRange.offset + secondRange.length;
|
|
31
|
-
return secondStartWithinFirst && secondEndWithinFirst;
|
|
32
|
-
};
|
|
33
|
-
var latestStyleLast = function latestStyleLast(s1, s2) {
|
|
34
|
-
// make sure longer-lasting styles are added first
|
|
35
|
-
var s2endIndex = s2.offset + s2.length;
|
|
36
|
-
var s1endIndex = s1.offset + s1.length;
|
|
37
|
-
return s2endIndex - s1endIndex;
|
|
38
|
-
};
|
|
39
|
-
var getStylesToReset = function getStylesToReset(remainingStyles, newStyles) {
|
|
40
|
-
var i = 0;
|
|
41
|
-
while (i < remainingStyles.length) {
|
|
42
|
-
if (newStyles.every(rangeIsSubset.bind(null, remainingStyles[i]))) {
|
|
43
|
-
i += 1;
|
|
44
|
-
} else {
|
|
45
|
-
return remainingStyles.slice(i);
|
|
26
|
+
const getStylesToReset = (remainingStyles, newStyles)=>{
|
|
27
|
+
let i = 0;
|
|
28
|
+
while(i < remainingStyles.length){
|
|
29
|
+
if (newStyles.every(rangeIsSubset.bind(null, remainingStyles[i]))) {
|
|
30
|
+
i += 1;
|
|
31
|
+
} else {
|
|
32
|
+
return remainingStyles.slice(i);
|
|
33
|
+
}
|
|
46
34
|
}
|
|
47
|
-
|
|
48
|
-
return [];
|
|
49
|
-
};
|
|
50
|
-
var appendStartMarkup = function appendStartMarkup(inlineHTML, string, styleRange) {
|
|
51
|
-
return string + getElementHTML(inlineHTML(styleRange.style)).start;
|
|
52
|
-
};
|
|
53
|
-
var prependEndMarkup = function prependEndMarkup(inlineHTML, string, styleRange) {
|
|
54
|
-
return getElementHTML(inlineHTML(styleRange.style)).end + string;
|
|
55
|
-
};
|
|
56
|
-
var defaultCustomInlineHTML = function defaultCustomInlineHTML(next) {
|
|
57
|
-
return function (style) {
|
|
58
|
-
return next(style);
|
|
59
|
-
};
|
|
35
|
+
return [];
|
|
60
36
|
};
|
|
37
|
+
const appendStartMarkup = (inlineHTML, string, styleRange)=>string + getElementHTML(inlineHTML(styleRange.style)).start;
|
|
38
|
+
const prependEndMarkup = (inlineHTML, string, styleRange)=>getElementHTML(inlineHTML(styleRange.style)).end + string;
|
|
39
|
+
const defaultCustomInlineHTML = (next)=>(style)=>next(style);
|
|
61
40
|
defaultCustomInlineHTML.__isMiddleware = true;
|
|
62
|
-
export default (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return
|
|
96
|
-
|
|
97
|
-
return result;
|
|
98
|
-
});
|
|
41
|
+
export default ((rawBlock, customInlineHTML = defaultCustomInlineHTML)=>{
|
|
42
|
+
invariant(rawBlock !== null && rawBlock !== undefined, 'Expected raw block to be non-null');
|
|
43
|
+
let inlineHTML;
|
|
44
|
+
if (customInlineHTML.__isMiddleware === true) {
|
|
45
|
+
inlineHTML = customInlineHTML(defaultInlineHTML);
|
|
46
|
+
} else {
|
|
47
|
+
inlineHTML = accumulateFunction(styleObjectFunction(customInlineHTML), styleObjectFunction(defaultInlineHTML));
|
|
48
|
+
}
|
|
49
|
+
let result = '';
|
|
50
|
+
let styleStack = [];
|
|
51
|
+
const sortedRanges = rawBlock.inlineStyleRanges.sort(rangeSort);
|
|
52
|
+
const originalTextArray = [
|
|
53
|
+
...rawBlock.text
|
|
54
|
+
];
|
|
55
|
+
for(let i = 0; i < originalTextArray.length; i += 1){
|
|
56
|
+
const styles = characterStyles(i, sortedRanges);
|
|
57
|
+
const endingStyles = subtractStyles(styleStack, styles);
|
|
58
|
+
const newStyles = subtractStyles(styles, styleStack);
|
|
59
|
+
const remainingStyles = subtractStyles(styleStack, endingStyles);
|
|
60
|
+
// reset styles: look for any already existing styles that will need to
|
|
61
|
+
// end before styles that are being added on this character. to solve this
|
|
62
|
+
// close out those current tags and all nested children,
|
|
63
|
+
// then open new ones nested within the new styles.
|
|
64
|
+
const resetStyles = getStylesToReset(remainingStyles, newStyles);
|
|
65
|
+
const openingStyles = resetStyles.concat(newStyles).sort(latestStyleLast);
|
|
66
|
+
const openingStyleTags = openingStyles.reduce(appendStartMarkup.bind(null, inlineHTML), '');
|
|
67
|
+
const endingStyleTags = endingStyles.concat(resetStyles).reduce(prependEndMarkup.bind(null, inlineHTML), '');
|
|
68
|
+
result += endingStyleTags + openingStyleTags + originalTextArray[i];
|
|
69
|
+
styleStack = popEndingStyles(styleStack, resetStyles.concat(endingStyles));
|
|
70
|
+
styleStack = styleStack.concat(openingStyles);
|
|
71
|
+
invariant(styleStack.length === styles.length, `Character ${i}: ${styleStack.length - styles.length} styles left on stack that should no longer be there`);
|
|
72
|
+
}
|
|
73
|
+
result = styleStack.reduceRight((res, openStyle)=>res + getElementHTML(inlineHTML(openStyle.style)).end, result);
|
|
74
|
+
return result;
|
|
75
|
+
});
|