Skip to content

Commit a78eb89

Browse files
committed
0.4.0 - support for blocks with depth #3
1 parent 9431f6b commit a78eb89

File tree

5 files changed

+145
-10
lines changed

5 files changed

+145
-10
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.4.0
2+
- added support for blocks with depth
3+
- block renderer now receives a second argument - depth
4+
15
## 0.3.0
26
- redraft now has a default export
37
- directly importing renderRaw is now deprecated

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,20 @@ const renderers = {
5353
CODE: (children) => <span style={styles.code}>{children}</span>,
5454
},
5555
/**
56-
* Note that children are an array of blocks with same styling
56+
* Blocks receive children and depth
57+
* Note that children are an array of blocks with same styling,
5758
*/
5859
blocks: {
5960
unstyled: (children) => children.map(child => <p>{child}</p>),
6061
blockquote: (children) => <blockquote>{addBreaklines(children)}</blockquote>,
6162
'header-one': (children) => children.map(child => <h1>{child}</h1>),
6263
'header-two': (children) => children.map(child => <h2>{child}</h2>),
6364
'code-block': (children) => <pre style={styles.codeBlock}>{addBreaklines(children)}</pre>,
64-
'unordered-list-item': (children) => <ul>{children.map(child => <li>{child}</li>)}</ul>,
65-
'ordered-list-item': (children) => <ol>{children.map(child => <li>{child}</li>)}</ol>,
65+
'unordered-list-item': (children, depth) => <ul class={`ul-level-${depth}`}>{children.map(child => <li>{child}</li>)}</ul>,
66+
'ordered-list-item': (children, depth) => <ol class={`ol-level-${depth}`}>{children.map(child => <li>{child}</li>)}</ol>,
6667
},
6768
/**
68-
* For entities what gets passed is children and the entity data
69+
* Entities receive children and the entity data
6970
*/
7071
entities: {
7172
LINK: (children, data) => <Link to={data.url}>{children}/>,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "redraft",
3-
"version": "0.3.0",
3+
"version": "0.4.0",
44
"description": "Renders the result of Draft.js convertToRaw using provided callbacks, works well with React",
55
"main": "./lib/index.js",
66
"scripts": {

src/render.js

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,43 @@ export const renderNode = (node, styleRendrers, entityRenderers, entityMap) => {
4141
return children;
4242
};
4343

44+
/**
45+
* Nests blocks by depth as children
46+
*/
47+
const byDepth = blocks => {
48+
let group = [];
49+
const depthStack = [];
50+
let prevDepth = 0;
51+
const unwind = targetDepth => {
52+
let i = prevDepth - targetDepth;
53+
// in case depthStack is too short for target depth
54+
if (depthStack.length < i) {
55+
i = depthStack.length;
56+
}
57+
for (i; i > 0; i--) {
58+
const tmp = group;
59+
group = depthStack.pop();
60+
group[group.length - 1].children = tmp;
61+
}
62+
};
63+
64+
blocks.forEach((block) => {
65+
// if type of the block has changed render the block and clear group
66+
if (prevDepth < block.depth) {
67+
depthStack.push(group);
68+
group = [];
69+
} else if (prevDepth > block.depth) {
70+
unwind(block.depth);
71+
}
72+
prevDepth = block.depth;
73+
group.push(block);
74+
});
75+
if (prevDepth !== 0) {
76+
unwind(0);
77+
}
78+
return group;
79+
};
80+
4481

4582
/**
4683
* Renders blocks grouped by type using provided blockStyleRenderers
@@ -52,26 +89,35 @@ const renderBlocks = (blocks, inlineRendrers = {}, blockRenderers = {},
5289
let group = [];
5390
let prevType = null;
5491
const Parser = new RawParser;
92+
let prevDepth = 0;
5593
blocks.forEach((block) => {
5694
const node = Parser.parse(block);
5795
const renderedNode = renderNode(node, inlineRendrers, entityRenderers, entityMap);
5896
// if type of the block has changed render the block and clear group
5997
if (prevType && prevType !== block.type) {
6098
if (blockRenderers[prevType]) {
61-
rendered.push(blockRenderers[prevType](group));
99+
rendered.push(blockRenderers[prevType](group, prevDepth));
62100
} else {
63101
rendered.push(group);
64102
}
65103
group = [];
66104
}
105+
// handle children
106+
if (block.children) {
107+
const children = renderBlocks(block.children, inlineRendrers,
108+
blockRenderers, entityRenderers, entityMap);
109+
renderedNode.push(children);
110+
}
67111
// push current node to group
68112
group.push(renderedNode);
113+
69114
// lastly save current type for refference
70115
prevType = block.type;
116+
prevDepth = block.depth;
71117
});
72118
// render last group
73119
if (blockRenderers[prevType]) {
74-
rendered.push(blockRenderers[prevType](group));
120+
rendered.push(blockRenderers[prevType](group, prevDepth));
75121
} else {
76122
rendered.push(group);
77123
}
@@ -91,7 +137,7 @@ export const render = (raw, renderers = {}, arg3 = {}, arg4 = {}) => {
91137
// Logs a deprecation warning if not in production
92138
deprecated('passing renderers separetly is deprecated'); // eslint-disable-line
93139
}
94-
const blocks = raw.blocks;
140+
const blocks = byDepth(raw.blocks);
95141
if (!blocks || blocks[0].text.length === 0) {
96142
return null;
97143
}

test/render.js

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ const raw2 = {
7878
}],
7979
};
8080

81-
const rawWithDepth = {
81+
const rawWithDepth = {
8282
entityMap: {},
8383
blocks: [
8484
{
@@ -115,6 +115,80 @@ const rawWithDepth = {
115115
}],
116116
};
117117

118+
const rawWithDepth2 = {
119+
entityMap: {},
120+
blocks: [
121+
{
122+
key: 'eunbc',
123+
type: 'unordered-list-item',
124+
text: 'Hey',
125+
depth: 0,
126+
inlineStyleRanges: [],
127+
entityRanges: [],
128+
},
129+
{
130+
key: '9nl08',
131+
type: 'unordered-list-item',
132+
text: 'Ho',
133+
depth: 1,
134+
inlineStyleRanges: [],
135+
entityRanges: [],
136+
},
137+
{
138+
key: '9qp7i',
139+
type: 'unordered-list-item',
140+
text: 'Let\'s',
141+
depth: 2,
142+
inlineStyleRanges: [],
143+
entityRanges: [],
144+
},
145+
{
146+
key: '1hegu',
147+
type: 'ordered-list-item',
148+
text: 'Go',
149+
depth: 0,
150+
inlineStyleRanges: [],
151+
entityRanges: [],
152+
}],
153+
};
154+
155+
const rawWithDepth3 = {
156+
entityMap: {},
157+
blocks: [
158+
{
159+
key: 'eunbc',
160+
type: 'unordered-list-item',
161+
text: 'Hey',
162+
depth: 0,
163+
inlineStyleRanges: [],
164+
entityRanges: [],
165+
},
166+
{
167+
key: '9nl08',
168+
type: 'unordered-list-item',
169+
text: 'Ho',
170+
depth: 0,
171+
inlineStyleRanges: [],
172+
entityRanges: [],
173+
},
174+
{
175+
key: '9qp7i',
176+
type: 'unordered-list-item',
177+
text: 'Let\'s',
178+
depth: 2,
179+
inlineStyleRanges: [],
180+
entityRanges: [],
181+
},
182+
{
183+
key: '1hegu',
184+
type: 'ordered-list-item',
185+
text: 'Go',
186+
depth: 0,
187+
inlineStyleRanges: [],
188+
entityRanges: [],
189+
}],
190+
};
191+
118192
// to render to a plain string we need to be sure all the arrays are joined after render
119193
const joinRecursively = (array) => array.map((child) => {
120194
if (Array.isArray(child)) {
@@ -165,9 +239,19 @@ describe('renderRaw', () => {
165239
const joined = joinRecursively(rendered);
166240
joined.should.equal('<p><strong>Lorem </strong><a href="http://zombo.com/" ><strong><em>ipsum</em></strong></a><strong><em> dolor</em></strong><em> sit amet,</em> pro nisl sonet ad. </p><blockquote>Eos affert numquam id, in est meis nobis. Legimus singulis suscipiantur eum in, <em>ceteros invenire </em>tractatos his id. </blockquote><p><strong>Facer facilis definiebas ea pro, mei malis libris latine an. Senserit moderatius vituperata vis in.</strong></p>'); // eslint-disable-line max-len
167241
});
168-
it('should render blocks with depth correctly', () => {
242+
it('should render blocks with depth correctly 1/2', () => {
169243
const rendered = redraft(rawWithDepth, renderers);
170244
const joined = joinRecursively(rendered);
171245
joined.should.equal("<ul><li>Hey<ul><li>Ho<ul><li>Let's</li></ul><ol><li>Go</li></ol></li></ul></li></ul>"); // eslint-disable-line max-len
172246
});
247+
it('should render blocks with depth correctly 2/2', () => {
248+
const rendered = redraft(rawWithDepth2, renderers);
249+
const joined = joinRecursively(rendered);
250+
joined.should.equal("<ul><li>Hey<ul><li>Ho<ul><li>Let's</li></ul></li></ul></li></ul><ol><li>Go</li></ol>"); // eslint-disable-line max-len
251+
});
252+
it('should render blocks with depth when depth jumps from 0 to 2', () => {
253+
const rendered = redraft(rawWithDepth3, renderers);
254+
const joined = joinRecursively(rendered);
255+
joined.should.equal("<ul><li>Hey</li><li>Ho<ul><li>Let's</li></ul></li></ul><ol><li>Go</li></ol>"); // eslint-disable-line max-len
256+
});
173257
});

0 commit comments

Comments
 (0)