From f542d04543286e07aee6b1e7043ffc960dd37943 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Tue, 21 Jan 2025 13:15:37 +0530 Subject: [PATCH] chore: Added colgroup tag support --- CHANGELOG.md | 4 +++- LICENSE | 2 +- __test__/mock/json-element-mock-result.ts | 2 +- src/helper/sanitize.ts | 6 +++--- src/nodes/node-type.ts | 2 ++ src/options/default-node-options.ts | 22 ++++++++++++++++++++-- 6 files changed, 30 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3edc932..8379a89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog -## [1.3.16](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.3.16) (2024-12-11) + +## [1.3.16](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.3.16) (2025-01-27) + - Enh: Added support for colgroup and col tags inside table tag - Fix: Updated rendorOption code block in reaadme file ## [1.3.15](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.3.15) (2024-11-18) diff --git a/LICENSE b/LICENSE index 66737f1..0c5a253 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ The MIT License (MIT) -Copyright (c) 2016-2024 Contentstack +Copyright (c) 2016-2025 Contentstack Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/__test__/mock/json-element-mock-result.ts b/__test__/mock/json-element-mock-result.ts index 0951311..a4fab81 100644 --- a/__test__/mock/json-element-mock-result.ts +++ b/__test__/mock/json-element-mock-result.ts @@ -9,7 +9,7 @@ const h6Html = "
Nunc porta diam vitae purus semper, ut consequat lorem vehic const orderListHtml = "
  1. Morbi in quam molestie, fermentum diam vitae, bibendum ipsum.
  2. Pellentesque mattis lacus in quam aliquam congue
  3. Integer feugiat leo dignissim, lobortis enim vitae, mollis lectus.
  4. Sed in ante lacinia, molestie metus eu, fringilla sapien.
" const unorderListHtml = "" const imgHtml = "" -const tableHtml = "

Header 1

Header 2

Body row 1 data 1

Body row 1 data 2

Body row 2 data 1

Body row 2 data 2

" +const tableHtml = "

Header 1

Header 2

Body row 1 data 1

Body row 1 data 2

Body row 2 data 1

Body row 2 data 2

" const blockquoteHtml = "
Praesent eu ex sed nibh venenatis pretium.
" const codeHtml = "Code template." const linkInPHtml = "LINK" diff --git a/src/helper/sanitize.ts b/src/helper/sanitize.ts index ec66426..b2d66ca 100644 --- a/src/helper/sanitize.ts +++ b/src/helper/sanitize.ts @@ -1,8 +1,8 @@ -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'; -type AllowedAttributes = 'href' | 'title' | 'target' | 'alt' | 'src' | 'class' | 'id' | 'style' | 'colspan' | 'rowspan' | 'content-type-uid' | 'data-sys-asset-uid' | 'sys-style-type' | 'data-type'; +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'; +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'; -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 { +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 { // Regular expression to find and remove all HTML tags except the allowed ones const sanitized = input.replace(/<\/?([a-z][a-z0-9]*)\b[^<>]*>/gi, (match, tag) => { return allowedTags.includes(tag.toLowerCase()) ? match : ''; diff --git a/src/nodes/node-type.ts b/src/nodes/node-type.ts index d7b6fa7..392cc70 100644 --- a/src/nodes/node-type.ts +++ b/src/nodes/node-type.ts @@ -27,6 +27,8 @@ enum NodeType { TABLE_ROW = 'tr', TABLE_HEAD = 'th', TABLE_DATA = 'td', + COL_GROUP = 'colgroup', + COL = 'col', BLOCK_QUOTE = 'blockquote', CODE = 'code', diff --git a/src/options/default-node-options.ts b/src/options/default-node-options.ts index ca516d1..f6a64a2 100644 --- a/src/options/default-node-options.ts +++ b/src/options/default-node-options.ts @@ -59,8 +59,26 @@ export const defaultNodeOption: RenderOption = { [NodeType.HR]:(node: Node, next: Next) => { return `
` }, - [NodeType.TABLE]:(node: Node, next: Next) => { - return `${sanitizeHTML(next(node.children))}` + [NodeType.TABLE]: (node: Node, next: Next) => { + // Generate colgroup if colWidths attribute is present + let colgroupHTML = ''; + if (node.attrs.colWidths && Array.isArray(node.attrs.colWidths)) { + const totalWidth = node.attrs.colWidths.reduce((sum, width) => sum + width, 0); + colgroupHTML = `<${NodeType.COL_GROUP} data-width="${totalWidth}">`; + node.attrs.colWidths.forEach(colWidth => { + const widthPercentage = (colWidth / totalWidth) * 100; + colgroupHTML += `<${NodeType.COL} style="width:${widthPercentage.toFixed(2)}%"/>`; + }); + colgroupHTML += ``; + } + + // Generate table with colgroup and other attributes + return `` + + `${colgroupHTML}` + + `${sanitizeHTML(next(node.children))}` + + ``; }, [NodeType.TABLE_HEADER]:(node: Node, next: Next) => { return `${sanitizeHTML(next(node.children))}`