From 686581cfccc15ff3d15a444dea5d76b86f091850 Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:44:50 +0530 Subject: [PATCH] chore: Fixed table cell merge issue --- CHANGELOG.md | 3 +++ package-lock.json | 4 ++-- package.json | 2 +- src/helper/sanitize.ts | 21 ++++++++++++--------- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e78677..b17d141 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## [1.3.14](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.3.14) (2024-11-18) + - Fix: Added Table cell merge in table tags + ## [1.3.13](https://github.com/contentstack/contentstack-utils-javascript/tree/v1.3.13) (2024-10-22) - Enh: Node version bump diff --git a/package-lock.json b/package-lock.json index 9b29e97..d6fbce1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/utils", - "version": "1.3.13", + "version": "1.3.14", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/utils", - "version": "1.3.13", + "version": "1.3.14", "license": "MIT", "devDependencies": { "@babel/preset-env": "^7.22.20", diff --git a/package.json b/package.json index 4c25fb7..6e6b2ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/utils", - "version": "1.3.13", + "version": "1.3.14", "description": "Contentstack utilities for Javascript", "main": "dist/index.es.js", "types": "dist/types/index.d.ts", diff --git a/src/helper/sanitize.ts b/src/helper/sanitize.ts index c413ff2..a94fa3e 100644 --- a/src/helper/sanitize.ts +++ b/src/helper/sanitize.ts @@ -1,19 +1,22 @@ -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'; -type AllowedAttributes = 'href' | 'title' | 'target' | 'alt' | 'src' | 'class' | 'id' | 'style'; +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'; +type AllowedAttributes = 'href' | 'title' | 'target' | 'alt' | 'src' | 'class' | 'id' | 'style' | 'colspan' | 'rowspan' | 'content-type-uid' | 'data-sys-asset-uid' | 'sys-style-type'; -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'], allowedAttributes: AllowedAttributes[] = ['href', 'title', 'target', 'alt', 'src', 'class', 'id', 'style']): 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'], allowedAttributes: AllowedAttributes[] = ['href', 'title', 'target', 'alt', 'src', 'class', 'id', 'style', 'colspan', 'rowspan', 'content-type-uid', 'data-sys-asset-uid', 'sys-style-type']): 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 : ''; }); // Regular expression to remove all attributes except the allowed ones - const cleaned = sanitized.replace(/\s([a-z:]+)=['"][^'"]*['"]/gi - , (match, attribute) => { - return allowedAttributes.includes(attribute.toLowerCase()) ? match : ''; + const cleaned = sanitized.replace(/<([a-z][a-z0-9]*)\b[^<>]*>/gi, (match, tag) => { + if (!allowedTags.includes(tag.toLowerCase())) { + return match; // Ignore tags not in allowedTags + } + // For each tag that is allowed, clean its attributes + return match.replace(/\s([a-z\-]+)=['"][^'"]*['"]/gi, (attributeMatch, attribute) => { + return allowedAttributes.includes(attribute.toLowerCase()) ? attributeMatch : ''; + }); }); - return cleaned; -} - +} \ No newline at end of file