Skip to content

Commit 2cf5db6

Browse files
authored
Merge pull request #31 from contentstack/next
feat: jsonToHTML style attr resolution
2 parents 355c0fe + da495e8 commit 2cf5db6

File tree

13 files changed

+16527
-285
lines changed

13 files changed

+16527
-285
lines changed

.github/workflows/sast-scan.yml

Lines changed: 0 additions & 11 deletions
This file was deleted.

.github/workflows/secrets-scan.yml

Lines changed: 0 additions & 11 deletions
This file was deleted.

README.md

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,45 +30,45 @@ To render embedded items on the front-end, use the renderOptions function, and d
3030
const renderOption = {
3131
// to render Supercharged RTE NodeType content like paragraph, link, table, order list, un-order list and more.
3232
p: (node, next) => {
33-
`<p class='class-id'>${next(node.children)}</p>` // you will need to call next function with node children contents
34-
}
33+
return `<p class='class-id'>${next(node.children)}</p>` // you will need to call next function with node children contents
34+
},
3535
h1: (node, next) => {
36-
`<h1 class='class-id'>${next(node.children)}</h1>` // you will need to call next function with node children contents
37-
}
36+
return `<h1 class='class-id'>${next(node.children)}</h1>` // you will need to call next function with node children contents
37+
},
3838
// to render Supercharged RTE MarkType content like bold, italic, underline, strikethrough, inlineCode, subscript, and superscript
3939
bold: (text) => {
40-
`<b>${next(node.children)}</b>`
41-
}
40+
return `<b>${next(node.children)}</b>`
41+
},
4242
// to render block-type embedded items
4343
block: {
4444
'product': (item, metadata) => {
45-
`<div>
46-
<h2 >${item.title}</h2>
47-
<img src=${item.product_image.url} alt=${item.product_image.title}/>
48-
<p>${item.price}</p>
49-
</div>`
45+
return `<div>
46+
<h2 >${item.title}</h2>
47+
<img src=${item.product_image.url} alt=${item.product_image.title}/>
48+
<p>${item.price}</p>
49+
</div>`
5050
},
5151
// to render the default
5252
'$default': (item, metadata) => {
53-
`<div>
54-
<h2>${item.title}</h2>
55-
<p>${item.description}</p>
56-
</div>`
53+
return `<div>
54+
<h2>${item.title}</h2>
55+
<p>${item.description}</p>
56+
</div>`
5757
}
5858
},
5959
// to display inline embedded items
6060
inline: {
6161
'$default': (item, metadata) => {
62-
`<span><b>${item.title}</b> - ${item.description}</span>`
62+
return `<span><b>${item.title}</b> - ${item.description}</span>`
6363
}
6464
},
6565
// to display embedded items inserted via link
6666
link: (item, metadata) => {
67-
`<a href="${metadata.attributes.href}">${metadata.text}</a>`
67+
return `<a href="${metadata.attributes.href}">${metadata.text}</a>`
6868
},
6969
// to display assets
7070
display: (item, metadata) => {
71-
`<img src=${metadata.attributes.src} alt=${metadata.alt} />`
71+
return `<img src=${metadata.attributes.src} alt=${metadata.alt} />`
7272
}
7373
}
7474
```
@@ -104,7 +104,7 @@ Contentstack.Utils.render({ entry, path: ["rte_fieldUid", "group.rteFieldUID"],
104104
```
105105

106106
#### Render Supercharged RTE contents
107-
To get a single entry, you need to provide the stack API key, environment name, delivery token, content type and entry UID. Then, use `Contentstack.Utils.jsonToHtml` function as shown below:
107+
To get a single entry, you need to provide the stack API key, environment name, delivery token, content type and entry UID. Then, use `Contentstack.Utils.jsonToHTML` function as shown below:
108108
```js
109109
import * as Contentstack from 'contentstack'
110110
const stack = Contentstack.Stack({
@@ -117,7 +117,7 @@ stack.ContentType('<CONTENT_TYPE_UID>')
117117
.toJSON()
118118
.fetch()
119119
.then(entry => {
120-
Contentstack.Utils.jsonToHtml({
120+
Contentstack.Utils.jsonToHTML({
121121
entry,
122122
path: ["rte_fieldUid", "group.rteFieldUID"],
123123
renderOption
@@ -155,7 +155,7 @@ stack.ContentType('<CONTENT_TYPE_UID>')
155155
```
156156

157157
#### Render Supercharged RTE contents
158-
To get a multiple entries, you need to provide the stack API key, environment name, delivery token, content type and entry UID. Then, use `Contentstack.Utils.jsonToHtml` function as shown below:
158+
To get a multiple entries, you need to provide the stack API key, environment name, delivery token, content type and entry UID. Then, use `Contentstack.Utils.jsonToHTML` function as shown below:
159159
```js
160160
import * as Contentstack from 'contentstack'
161161
const stack = Contentstack.Stack({
@@ -170,7 +170,7 @@ stack.ContentType('<CONTENT_TYPE_UID>')
170170
.find()
171171
.then(result => {
172172
result.forEach(entry => {
173-
Contentstack.Utils.jsonToHtml({
173+
Contentstack.Utils.jsonToHTML({
174174
entry,
175175
path: ["rte_fieldUid", "group.rteFieldUID"],
176176
renderOption

__test__/default-node-options.test.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,35 @@ const imgNode: Node = {
1919

2020
}
2121

22+
const imgNodeWithURL: Node = {
23+
type: NodeType.IMAGE,
24+
attrs: {url: "https://image.url/Donald.jog.png"},
25+
children:[]
26+
27+
}
28+
2229
const linkNode: Node = {
2330
type: NodeType.LINK,
2431
attrs: {href: "https://image.url/Donald.jog.png"},
2532
children:[]
2633

2734
}
2835

36+
const linkNodeWithURL: Node = {
37+
type: NodeType.LINK,
38+
attrs: {url: "https://image.url/Donald.jog.png"},
39+
children:[]
40+
41+
}
42+
2943
const embedNode: Node = {
3044
type: NodeType.EMBED,
31-
"attrs": {
32-
src: "https://www.youtube.com/"
33-
},
45+
attrs: { src: "https://www.youtube.com/" },
46+
children: []
47+
}
48+
const embedNodeWithURL: Node = {
49+
type: NodeType.EMBED,
50+
attrs: { url: "https://www.youtube.com/" },
3451
children: []
3552
}
3653

@@ -54,6 +71,15 @@ describe('Default node render options', () => {
5471
expect(renderString).toEqual('<iframe src="https://www.youtube.com/">text</iframe>')
5572
done()
5673
})
74+
it('Should return link string with url as attr', done => {
75+
let renderString = (defaultNodeOption[NodeType.LINK] as RenderNode)(linkNodeWithURL, next)
76+
expect(renderString).toEqual(`<a href="${linkNodeWithURL.attrs.url}">text</a>`)
77+
renderString = (defaultNodeOption[NodeType.IMAGE] as RenderNode)(imgNodeWithURL, next)
78+
expect(renderString).toEqual(`<img src="${imgNodeWithURL.attrs.url}" />text`)
79+
renderString = (defaultNodeOption[NodeType.EMBED] as RenderNode)(embedNodeWithURL, next)
80+
expect(renderString).toEqual(`<iframe src="${embedNodeWithURL.attrs.url}">text</iframe>`)
81+
done()
82+
})
5783
it('Should return Heading string', done => {
5884
let renderString = (defaultNodeOption[NodeType.HEADING_1] as RenderNode)(node, next)
5985
expect(renderString).toEqual('<h1>text</h1>')

__test__/default-options.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import StyleType from '../src/embedded-types/style-type';
22
import { defaultOptions } from '../src/options/default-options';
3-
import { entryContentBlank, entryContentURL, entryContentTitle, entryContentTitleURL } from './mock/entry-mock';
3+
import { entryContentBlank, entryContentURL, entryContentTitle, entryContentTitleURL, entryContentURLWithoutSystemUid, entryContentURLWithSystemNoUid } from './mock/entry-mock';
44
import { RenderItem } from '../src/options/index';
55
import { assetContentBlank,
66
assetContentUrl,
@@ -51,6 +51,11 @@ describe('Default Option test', () => {
5151
done()
5252
})
5353

54+
it('Default options Entry with only uid, url, system-uid test', done => {
55+
expect(entryBlockFunction(entryContentURLWithoutSystemUid, embedAttributes)).toEqual(`<div><p>${entryContentURLWithoutSystemUid.uid}</p><p>Content type: <span></span></p></div>`)
56+
done()
57+
})
58+
5459
it('Default options Asset with only uid test', done => {
5560
expect(assetDisplaableFunction(assetContentBlank, embedAttributes)).toEqual(`<img src="undefined" alt="${assetContentBlank.uid}" />`)
5661
expect(assetDownloadFunction(assetContentBlank, embedAttributes)).toEqual(`<a href="undefined\">${assetContentBlank.uid}</a>`)

__test__/json-to-html.test.ts

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
import { jsonToHTML } from '../src/json-to-html'
22
import { embeddedAssetWithRenderOption } from './mock/render-options'
33
import {
4-
plainTextJson,
5-
paragraphEntry,
6-
embeddedAssetJsonEntry,
7-
paragraphJsonArrayEntry,
4+
blockquoteJson,
5+
codeJson,
6+
embeddedAssetJsonEntry,
87
h1Json,
98
h2Json,
109
h3Json,
1110
h4Json,
1211
h5Json,
1312
h6Json,
14-
orderListJson,
15-
unorderListJson,
1613
imgJson,
1714
imgJsonURL,
18-
tableJson,
19-
blockquoteJson,
20-
codeJson,
2115
linkInPJson,
22-
linkInPJsonUrl} from './mock/json-element-mock'
16+
linkInPJsonUrl,
17+
orderListJson,
18+
paragraphEntry,
19+
paragraphJsonArrayEntry,
20+
plainTextJson,
21+
styleinPJson,
22+
tableJson,
23+
unorderListJson} from './mock/json-element-mock'
2324
import {
2425
blockquoteHtml,
2526
codeHtml,
@@ -35,6 +36,7 @@ import {
3536
orderListHtml,
3637
paragraphHtml,
3738
plainTextHtml,
39+
styleinPHtml,
3840
tableHtml,
3941
unorderListHtml} from './mock/json-element-mock-result'
4042
describe('Node parser paragraph content', () => {
@@ -493,3 +495,22 @@ describe('Node parse link in paragraph content', () => {
493495
done()
494496
})
495497
})
498+
499+
500+
describe('Node parse style attribute', () => {
501+
it('Should return style attribute in paragraph html content', done => {
502+
const entry = {
503+
uid: 'entry_uid_19',
504+
supercharged_rte: {
505+
...styleinPJson
506+
},
507+
_embedded_items: {}
508+
}
509+
const paths = ['supercharged_rte']
510+
511+
jsonToHTML({ entry, paths})
512+
513+
expect(entry.supercharged_rte).toEqual(styleinPHtml)
514+
done()
515+
})
516+
})

__test__/mock/entry-mock.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ export const entryContentTitleURL = {
2323
_content_type_uid: "content_type_uid"
2424
}
2525

26+
export const entryContentURLWithoutSystemUid = {
27+
uid: "uid",
28+
url: "url"
29+
}
30+
31+
export const entryContentURLWithSystemNoUid = {
32+
uid: "uid",
33+
url: "url",
34+
system: { url: "system_uid"}
35+
}
36+
2637
export const assetDownloadJson = {
2738
type: 'asset',
2839
'data-sys-asset-uid': 'asset_uid_1',

__test__/mock/json-element-mock-result.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ const h3Html = "<h3><strong><em><u><sub>Mauris venenatis dui id massa sollicitud
66
const h4Html = "<h4><strong><em><u><sub>MaNullam feugiat turpis quis elit interdum, vitae laoreet quam viverra</sub></u></em></strong></h4>"
77
const h5Html = "<h5>Mauris venenatis dui id massa sollicitudin, non bibendum nunc dictum.</h5>"
88
const h6Html = "<h6>Nunc porta diam vitae purus semper, ut consequat lorem vehicula.</h6>"
9-
const orderListHtml = "<ol><li>Morbi in quam molestie, fermentum diam vitae, bibendum ipsum.</li><li>Pellentesque mattis lacus in quam aliquam congue</li><li>Integer feugiat leo dignissim, lobortis enim vitae, mollis lectus.</li><li>Sed in ante lacinia, molestie metus eu, fringilla sapien.</li></ol>"
9+
const orderListHtml = "<ol><li style=\"text-align:justify;\">Morbi in quam molestie, fermentum diam vitae, bibendum ipsum.</li><li style=\"text-align:justify;\">Pellentesque mattis lacus in quam aliquam congue</li><li style=\"text-align:justify;\">Integer feugiat leo dignissim, lobortis enim vitae, mollis lectus.</li><li style=\"text-align:justify;\">Sed in ante lacinia, molestie metus eu, fringilla sapien.</li></ol>"
1010
const unorderListHtml = "<ul><li>Sed quis metus sed mi hendrerit mollis vel et odio.</li><li>Integer vitae sem dignissim, elementum libero vel, fringilla massa.</li><li>Integer imperdiet arcu sit amet tortor faucibus aliquet.</li><li>Aenean scelerisque velit vitae dui vehicula, at congue massa sagittis.</li></ul>"
1111
const imgHtml = "<img src=\"https://image.url/Donald.jog.png\" />"
1212
const tableHtml = "<table><thead><tr><th><p>Header 1</p></th><th><p>Header 2</p></th></tr></thead><tbody><tr><td><p>Body row 1 data 1</p></td><td><p>Body row 1 data 2</p></td></tr><tr><td><p>Body row 2 data 1</p></td><td><p>Body row 2 data 2</p></td></tr></tbody></table>"
1313
const blockquoteHtml = "<blockquote>Praesent eu ex sed nibh venenatis pretium.</blockquote>"
1414
const codeHtml = "<code>Code template.</code>"
1515
const linkInPHtml = "<strong><em><u><sub></sub></u></em></strong><a href=\"LINK.com\">LINK</a>"
16-
const linkInPURLHtml = "<strong><em><u><sub></sub></u></em></strong><a href=\"LINK.com\" target=\"_self\">LINK</a>"
16+
const linkInPURLHtml = "<strong><em><u><sub></sub></u></em></strong><a href=\"LINK.com\" target=\"_blank\">LINK</a>"
17+
const styleinPHtml = "<p style=\"text-align:right;\">This is <span>second</span> <u>JSON</u> entry</p><p style=\"text-align:left;\"><a href=\"example.com\" target=\"_blank\">Example</a></p>"
1718

1819
export {
1920
h1Html,
@@ -32,4 +33,5 @@ export {
3233
linkInPURLHtml,
3334
blockquoteHtml,
3435
unorderListHtml,
36+
styleinPHtml,
3537
}

__test__/mock/json-element-mock.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ const linkInPJsonUrl = {
664664
"type": "a",
665665
"attrs": {
666666
"url": "LINK.com",
667-
"target": "_self"
667+
"target": "_blank"
668668
},
669669
"children": [
670670
{
@@ -681,6 +681,53 @@ const linkInPJsonUrl = {
681681
type: "doc"
682682
}
683683

684+
const styleinPJson = {
685+
type: 'doc',
686+
attrs: {},
687+
uid: '7611f269eb4e4f4e9a0c8274decd1e0a',
688+
children: [
689+
{
690+
type: 'p',
691+
attrs: {
692+
style: { 'text-align': 'right' },
693+
'redactor-attributes': {},
694+
dir: 'ltr'
695+
},
696+
uid: '24b09a8e7efa42a2a909cfbc4da403b1',
697+
children: [
698+
{ text: 'This is ' },
699+
{ text: 'second', inlineCode: true },
700+
{ text: ' ' },
701+
{ text: 'JSON', underline: true },
702+
{ text: ' entry' }
703+
]
704+
},
705+
{
706+
type: 'p',
707+
attrs: {
708+
style: { 'text-align': 'left' },
709+
'redactor-attributes': {},
710+
dir: 'ltr'
711+
},
712+
uid: '7eb3984120fe4f3ea18fdeff84326ff4',
713+
children: [
714+
{ text: '' },
715+
{
716+
uid: '76aa06b02ec64a44bd6a0f4ccde11b6a',
717+
type: 'a',
718+
attrs: {
719+
url: 'example.com',
720+
target: '_blank'
721+
},
722+
children: [ { text: 'Example' } ]
723+
},
724+
{ text: '' }
725+
]
726+
}
727+
],
728+
_version: 6
729+
}
730+
684731
const assetReferenceJson = {
685732
uid: "node_uid_12",
686733
_version: 1,
@@ -1030,6 +1077,7 @@ export {
10301077
tableJson,
10311078
linkInPJson,
10321079
linkInPJsonUrl,
1080+
styleinPJson,
10331081
plainTextJson,
10341082
paragraphJson,
10351083
orderListJson,

0 commit comments

Comments
 (0)