Skip to content

Commit 2d621f5

Browse files
chore: Added colgroup tag support (#124)
1 parent 54c4804 commit 2d621f5

File tree

6 files changed

+30
-8
lines changed

6 files changed

+30
-8
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Changelog
2-
## [1.3.16](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.3.16) (2024-12-11)
2+
3+
## [1.3.16](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.3.16) (2025-01-27)
4+
- Enh: Added support for colgroup and col tags inside table tag
35
- Fix: Updated rendorOption code block in reaadme file
46

57
## [1.3.15](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.3.15) (2024-11-18)

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
The MIT License (MIT)
22

33

4-
Copyright (c) 2016-2024 Contentstack
4+
Copyright (c) 2016-2025 Contentstack
55

66
Permission is hereby granted, free of charge, to any person obtaining a copy
77
of this software and associated documentation files (the "Software"), to deal

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const h6Html = "<h6>Nunc porta diam vitae purus semper, ut consequat lorem vehic
99
const orderListHtml = "<ol class=\"table\" id=\"table_id\"><li style=\"text-align:justify;\" class=\"class\">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 class=\"table\" id=\"table_id\"><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\" />"
12-
const tableHtml = "<table><thead class=\"class\"><tr><th><p>Header 1</p></th><th><p>Header 2</p></th></tr></thead><tbody class=\"class\" id=\"id\"><tr class=\"class\" id=\"id\"><td><p>Body row 1 data 1</p></td><td class=\"class\" id=\"id\"><p>Body row 1 data 2</p></td></tr><tr id=\"class\"><td><p>Body row 2 data 1</p></td><td><p class=\"class\">Body row 2 data 2</p></td></tr></tbody></table>"
12+
const tableHtml = "<table><colgroup data-width=\"500\"><col style=\"width:50.00%\"/><col style=\"width:50.00%\"/></colgroup><thead class=\"class\"><tr><th><p>Header 1</p></th><th><p>Header 2</p></th></tr></thead><tbody class=\"class\" id=\"id\"><tr class=\"class\" id=\"id\"><td><p>Body row 1 data 1</p></td><td class=\"class\" id=\"id\"><p>Body row 1 data 2</p></td></tr><tr id=\"class\"><td><p>Body row 2 data 1</p></td><td><p class=\"class\">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>"

src/helper/sanitize.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

2-
type AllowedTags = 'p' | 'a' | 'strong' | 'em' | 'ul' | 'ol' | 'li' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'sub' | 'u' | 'table' | 'thead' | 'tbody' | 'tr' | 'th' | 'td' | 'span' | 'fragment' | 'strike' | 'sup' | 'br'| 'img';
3-
type AllowedAttributes = 'href' | 'title' | 'target' | 'alt' | 'src' | 'class' | 'id' | 'style' | 'colspan' | 'rowspan' | 'content-type-uid' | 'data-sys-asset-uid' | 'sys-style-type' | 'data-type';
2+
type AllowedTags = 'p' | 'a' | 'strong' | 'em' | 'ul' | 'ol' | 'li' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'sub' | 'u' | 'table' | 'thead' | 'tbody' | 'tr' | 'th' | 'td' | 'span' | 'fragment' | 'strike' | 'sup' | 'br'| 'img' | 'colgroup' | 'col' | 'div';
3+
type AllowedAttributes = 'href' | 'title' | 'target' | 'alt' | 'src' | 'class' | 'id' | 'style' | 'colspan' | 'rowspan' | 'content-type-uid' | 'data-sys-asset-uid' | 'sys-style-type' | 'data-type' | 'data-width' | 'data-rows' | 'data-cols';
44

5-
export function sanitizeHTML(input: string, allowedTags: AllowedTags[] = ['p', 'a', 'strong', 'em', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'sub', 'u', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'span', 'fragment', 'sup', 'strike', 'br', 'img'], allowedAttributes: AllowedAttributes[] = ['href', 'title', 'target', 'alt', 'src', 'class', 'id', 'style', 'colspan', 'rowspan', 'content-type-uid', 'data-sys-asset-uid', 'sys-style-type', 'data-type']): string {
5+
export function sanitizeHTML(input: string, allowedTags: AllowedTags[] = ['p', 'a', 'strong', 'em', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'sub', 'u', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'span', 'fragment', 'sup', 'strike', 'br', 'img', 'colgroup', 'col', 'div'], allowedAttributes: AllowedAttributes[] = ['href', 'title', 'target', 'alt', 'src', 'class', 'id', 'style', 'colspan', 'rowspan', 'content-type-uid', 'data-sys-asset-uid', 'sys-style-type', 'data-type', 'data-width', 'data-rows', 'data-cols']): string {
66
// Regular expression to find and remove all HTML tags except the allowed ones
77
const sanitized = input.replace(/<\/?([a-z][a-z0-9]*)\b[^<>]*>/gi, (match, tag) => {
88
return allowedTags.includes(tag.toLowerCase()) ? match : '';

src/nodes/node-type.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ enum NodeType {
2727
TABLE_ROW = 'tr',
2828
TABLE_HEAD = 'th',
2929
TABLE_DATA = 'td',
30+
COL_GROUP = 'colgroup',
31+
COL = 'col',
3032

3133
BLOCK_QUOTE = 'blockquote',
3234
CODE = 'code',

src/options/default-node-options.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,26 @@ export const defaultNodeOption: RenderOption = {
5959
[NodeType.HR]:(node: Node, next: Next) => {
6060
return `<hr>`
6161
},
62-
[NodeType.TABLE]:(node: Node, next: Next) => {
63-
return `<table${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs['class-name'] ? ` class="${node.attrs['class-name']}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``}>${sanitizeHTML(next(node.children))}</table>`
62+
[NodeType.TABLE]: (node: Node, next: Next) => {
63+
// Generate colgroup if colWidths attribute is present
64+
let colgroupHTML = '';
65+
if (node.attrs.colWidths && Array.isArray(node.attrs.colWidths)) {
66+
const totalWidth = node.attrs.colWidths.reduce((sum, width) => sum + width, 0);
67+
colgroupHTML = `<${NodeType.COL_GROUP} data-width="${totalWidth}">`;
68+
node.attrs.colWidths.forEach(colWidth => {
69+
const widthPercentage = (colWidth / totalWidth) * 100;
70+
colgroupHTML += `<${NodeType.COL} style="width:${widthPercentage.toFixed(2)}%"/>`;
71+
});
72+
colgroupHTML += `</${NodeType.COL_GROUP}>`;
73+
}
74+
75+
// Generate table with colgroup and other attributes
76+
return `<table${node.attrs.style ? ` style="${node.attrs.style}"` : ``}` +
77+
`${node.attrs['class-name'] ? ` class="${node.attrs['class-name']}"` : ``}` +
78+
`${node.attrs.id ? ` id="${node.attrs.id}"` : ``}>` +
79+
`${colgroupHTML}` +
80+
`${sanitizeHTML(next(node.children))}` +
81+
`</table>`;
6482
},
6583
[NodeType.TABLE_HEADER]:(node: Node, next: Next) => {
6684
return `<thead${node.attrs.style ? ` style="${node.attrs.style}"` : ``}${node.attrs['class-name'] ? ` class="${node.attrs['class-name']}"` : ``}${node.attrs.id ? ` id="${node.attrs.id}"` : ``}>${sanitizeHTML(next(node.children))}</thead>`

0 commit comments

Comments
 (0)