You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by pp...@apache.org on 2023/10/31 12:57:27 UTC
(atlas) branch master updated: ATLAS-4805: (UI)Text editor improvements and code clean up
This is an automated email from the ASF dual-hosted git repository.
ppawar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/master by this push:
new 35ce839f0 ATLAS-4805: (UI)Text editor improvements and code clean up
35ce839f0 is described below
commit 35ce839f0a24f8080ca5d0f6841e261c8becb347
Author: Farhan Khan <fa...@freestoneinfotech.com>
AuthorDate: Tue Oct 31 16:26:54 2023 +0530
ATLAS-4805: (UI)Text editor improvements and code clean up
Signed-off-by: Prasad Pawar <pr...@cloudera.com>
---
dashboardv2/public/css/scss/trumbowyg.scss | 2 ++
dashboardv2/public/js/utils/Helper.js | 5 +++++
dashboardv2/public/js/utils/Utils.js | 13 ++++++++++---
.../business_metadata/BusinessMetadataDetailLayoutView.js | 3 ++-
.../business_metadata/BusinessMetadataTableLayoutView.js | 2 +-
.../public/js/views/tag/TagAttributeDetailLayoutView.js | 6 ++++--
dashboardv3/public/css/scss/trumbowyg.scss | 2 ++
dashboardv3/public/js/utils/Helper.js | 5 +++++
dashboardv3/public/js/utils/Utils.js | 13 ++++++++++---
.../business_metadata/BusinessMetadataDetailLayoutView.js | 3 ++-
.../business_metadata/BusinessMetadataTableLayoutView.js | 2 +-
.../public/js/views/tag/TagAttributeDetailLayoutView.js | 6 ++++--
12 files changed, 48 insertions(+), 14 deletions(-)
diff --git a/dashboardv2/public/css/scss/trumbowyg.scss b/dashboardv2/public/css/scss/trumbowyg.scss
index a5463eadd..88a7a9775 100644
--- a/dashboardv2/public/css/scss/trumbowyg.scss
+++ b/dashboardv2/public/css/scss/trumbowyg.scss
@@ -289,6 +289,8 @@ $slow-transition-duration: 300ms !default;
}
.trumbowyg-dropdown {
+ top: auto !important;
+ bottom: 0px;
max-width: 300px;
max-height: 250px;
overflow-y: auto;
diff --git a/dashboardv2/public/js/utils/Helper.js b/dashboardv2/public/js/utils/Helper.js
index 8efeeb9c5..86a7aac49 100644
--- a/dashboardv2/public/js/utils/Helper.js
+++ b/dashboardv2/public/js/utils/Helper.js
@@ -134,6 +134,11 @@ define(['require',
$('.trumbowyg').css('border', '1px solid #8fa5b1');
}
});
+ $('body').on('change', '.trumbowyg-modal-box input[name="url"], .trumbowyg-modal-box input[name="text"]', function(e) {
+ var inputValue = e.target.value;
+ var sanitizedValue = Utils.sanitizeHtmlContent({ data: inputValue });
+ e.target.value = sanitizedValue;
+ });
$('body').on('keyup input', '.modal-body', function(e) {
var target = e.target,
isGlossary = (e.target.dataset.id === "searchTerm" || e.target.dataset.id === "searchCategory") ? true : false; // assign term/category modal
diff --git a/dashboardv2/public/js/utils/Utils.js b/dashboardv2/public/js/utils/Utils.js
index 25ce3190e..b4e02971e 100644
--- a/dashboardv2/public/js/utils/Utils.js
+++ b/dashboardv2/public/js/utils/Utils.js
@@ -1296,18 +1296,25 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
$parent.css('border', '1px solid #8fa5b1');
}).on('tbwchange', function(e) {
options.callback ? options.callback(e) : null;
+ e.target.value = Utils.sanitizeHtmlContent({ data: e.target.value });
}).on('tbwmodalopen', function(e) {
$('input[name="title"], input[name="target"]').parent().css('display', 'none');
});
}
Utils.sanitizeHtmlContent = function(options) {
- var editorContent, cleanedContent;
+ var editorContent, cleanedContent,
+ config = {
+ ALLOWED_TAGS: ['b', 'em', 'strong', 'u', 'a', 'ul', 'ol', 'li', 'p', 'strike', 'h1', 'h2', 'h3', 'h4'],
+ ALLOWED_ATTR: ['href'],
+ FORBID_TAGS: ['script', 'img', 'iframe', 'svg', 'title'],
+ FORBID_ATTR: ['onmouseover', 'onload', 'onclick', 'onerror']
+ };
editorContent = options.selector ? $(options.selector).trumbowyg('html') : options.data;
if (options && editorContent) {
- cleanedContent = DOMPurify.sanitize(editorContent, { FORBID_TAGS: ['img', 'script', 'iframe', 'embed', 'svg', 'meta'], ALLOWED_ATTR: ['target', 'href'] });
+ cleanedContent = DOMPurify.sanitize(editorContent, config);
}
- return cleanedContent;
+ return cleanedContent || "";
}
//-----------------------------------------END---------------------//
diff --git a/dashboardv2/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js b/dashboardv2/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
index b3d1ff337..f08fb3424 100644
--- a/dashboardv2/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
+++ b/dashboardv2/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
@@ -58,8 +58,9 @@ define(['require',
},
renderDetail: function() {
this.ui.title.html('<span>' + this.model.get('name') + '</span>');
+ var sanitizedDescription = Utils.sanitizeHtmlContent({data: this.model.get("description")});
if (this.model.get('description')) {
- this.isTextTypeChecked ? this.ui.description.text(this.model.get('description')) : this.ui.description.html(this.model.get('description'));
+ this.isTextTypeChecked ? this.ui.description.text(sanitizedDescription) : this.ui.description.html(sanitizedDescription);
}
},
onDestroy: function() {
diff --git a/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js b/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
index ccff1fdaf..c02236843 100644
--- a/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
+++ b/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
@@ -301,7 +301,7 @@ define(['require',
if (description.length > 50) {
description = description.substr(0, 50) + "...";
}
- return description;
+ return Utils.sanitizeHtmlContent({data: description});
}
})
},
diff --git a/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js b/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
index 3b26f0e0e..14f1b8c3e 100644
--- a/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
+++ b/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
@@ -57,7 +57,7 @@ define(['require',
events["click " + this.ui.editButton] = 'onEditButton';
events["change " + this.ui.textType] = function(e) {
this.isTextTypeChecked = !this.isTextTypeChecked;
- this.isTextTypeChecked ? this.ui.description.text(this.model.get("description")) : this.ui.description.html(this.model.get("description"));
+ this.isTextTypeChecked ? this.ui.description.text(this.sanitizedDescription) : this.ui.description.html(this.sanitizedDescription);
};
return events;
},
@@ -68,6 +68,7 @@ define(['require',
initialize: function(options) {
_.extend(this, _.pick(options, 'tag', 'collection', 'enumDefCollection'));
this.isTextTypeChecked = false;
+ this.sanitizedDescription = "";
},
bindEvents: function() {
this.listenTo(this.collection, 'reset', function() {
@@ -127,7 +128,8 @@ define(['require',
}
this.ui.title.html('<span>' + (Utils.getName(this.model.toJSON())) + '</span>');
if (this.model.get("description")) {
- this.isTextTypeChecked ? this.ui.description.text(this.model.get("description")) : this.ui.description.html(this.model.get("description"));
+ this.sanitizedDescription = Utils.sanitizeHtmlContent({data: this.model.get("description")});
+ this.isTextTypeChecked ? this.ui.description.text(this.sanitizedDescription) : this.ui.description.html(this.sanitizedDescription);
}
if (attributeDefs) {
if (!_.isArray(attributeDefs)) {
diff --git a/dashboardv3/public/css/scss/trumbowyg.scss b/dashboardv3/public/css/scss/trumbowyg.scss
index a5463eadd..88a7a9775 100644
--- a/dashboardv3/public/css/scss/trumbowyg.scss
+++ b/dashboardv3/public/css/scss/trumbowyg.scss
@@ -289,6 +289,8 @@ $slow-transition-duration: 300ms !default;
}
.trumbowyg-dropdown {
+ top: auto !important;
+ bottom: 0px;
max-width: 300px;
max-height: 250px;
overflow-y: auto;
diff --git a/dashboardv3/public/js/utils/Helper.js b/dashboardv3/public/js/utils/Helper.js
index 71101a74f..c942ac534 100644
--- a/dashboardv3/public/js/utils/Helper.js
+++ b/dashboardv3/public/js/utils/Helper.js
@@ -140,6 +140,11 @@ define(['require',
$('.trumbowyg').css('border', '1px solid #8fa5b1');
}
});
+ $('body').on('change', '.trumbowyg-modal-box input[name="url"], .trumbowyg-modal-box input[name="text"]', function(e) {
+ var inputValue = e.target.value;
+ var sanitizedValue = Utils.sanitizeHtmlContent({ data: inputValue });
+ e.target.value = sanitizedValue;
+ });
$('body').on('keyup input', '.modal-body', function(e) {
var target = e.target,
isGlossary = (e.target.dataset.id === "searchTerm" || e.target.dataset.id === "searchCategory") ? true : false; // assign term/category modal
diff --git a/dashboardv3/public/js/utils/Utils.js b/dashboardv3/public/js/utils/Utils.js
index f60d4be5b..dcd737c01 100644
--- a/dashboardv3/public/js/utils/Utils.js
+++ b/dashboardv3/public/js/utils/Utils.js
@@ -1311,18 +1311,25 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
$parent.css('border', '1px solid #8fa5b1');
}).on('tbwchange', function(e) {
options.callback ? options.callback(e) : null;
+ e.target.value = Utils.sanitizeHtmlContent({ data: e.target.value });
}).on('tbwmodalopen', function(e) {
$('input[name="title"], input[name="target"]').parent().css('display', 'none');
});
}
Utils.sanitizeHtmlContent = function(options) {
- var editorContent, cleanedContent;
+ var editorContent, cleanedContent,
+ config = {
+ ALLOWED_TAGS: ['b', 'em', 'strong', 'u', 'a', 'ul', 'ol', 'li', 'p', 'strike', 'h1', 'h2', 'h3', 'h4'],
+ ALLOWED_ATTR: ['href'],
+ FORBID_TAGS: ['script', 'img', 'iframe', 'svg', 'title'],
+ FORBID_ATTR: ['onmouseover', 'onload', 'onclick', 'onerror', 'src']
+ };
editorContent = options.selector ? $(options.selector).trumbowyg('html') : options.data;
if (options && editorContent) {
- cleanedContent = DOMPurify.sanitize(editorContent, { FORBID_TAGS: ['img', 'script', 'iframe', 'embed', 'svg', 'meta'], ALLOWED_ATTR: ['target', 'href'] });
+ cleanedContent = DOMPurify.sanitize(editorContent, config);
}
- return cleanedContent;
+ return cleanedContent || "";
}
//-----------------------------------------END---------------------//
diff --git a/dashboardv3/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js b/dashboardv3/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
index 0921d4371..b7d12d665 100644
--- a/dashboardv3/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
+++ b/dashboardv3/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
@@ -61,8 +61,9 @@ define(['require',
},
renderDetail: function() {
this.ui.title.html('<span>' + this.model.get('name') + '</span>');
+ var sanitizedDescription = Utils.sanitizeHtmlContent({data: this.model.get("description")});
if (this.model.get('description')) {
- this.isTextTypeChecked ? this.ui.description.text(this.model.get('description')) : this.ui.description.html(this.model.get('description'));
+ this.isTextTypeChecked ? this.ui.description.text(sanitizedDescription) : this.ui.description.html(sanitizedDescription);
}
}
});
diff --git a/dashboardv3/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js b/dashboardv3/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
index 2e8d7c10c..274630656 100644
--- a/dashboardv3/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
+++ b/dashboardv3/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
@@ -301,7 +301,7 @@ define(['require',
if (description.length > 50) {
description = description.substr(0, 50) + "...";
}
- return description;
+ return Utils.sanitizeHtmlContent({data: description});
}
})
},
diff --git a/dashboardv3/public/js/views/tag/TagAttributeDetailLayoutView.js b/dashboardv3/public/js/views/tag/TagAttributeDetailLayoutView.js
index 2a22d3212..95d706281 100644
--- a/dashboardv3/public/js/views/tag/TagAttributeDetailLayoutView.js
+++ b/dashboardv3/public/js/views/tag/TagAttributeDetailLayoutView.js
@@ -61,7 +61,7 @@ define(['require',
};
events["change " + this.ui.textType] = function(e) {
this.isTextTypeChecked = !this.isTextTypeChecked;
- this.isTextTypeChecked ? this.ui.description.text(this.model.get("description")) : this.ui.description.html(this.model.get("description"));
+ this.isTextTypeChecked ? this.ui.description.text(this.sanitizedDescription) : this.ui.description.html(this.sanitizedDescription);
};
return events;
},
@@ -72,6 +72,7 @@ define(['require',
initialize: function(options) {
_.extend(this, _.pick(options, 'tag', 'collection', 'enumDefCollection'));
this.isTextTypeChecked = false;
+ this.sanitizedDescription = "";
},
bindEvents: function() {
this.listenTo(this.collection, 'reset', function() {
@@ -131,7 +132,8 @@ define(['require',
}
this.ui.title.html('<span>' + (Utils.getName(this.model.toJSON())) + '</span>');
if (this.model.get("description")) {
- this.isTextTypeChecked ? this.ui.description.text(this.model.get("description")) : this.ui.description.html(this.model.get("description"));
+ this.sanitizedDescription = Utils.sanitizeHtmlContent({data: this.model.get("description")});
+ this.isTextTypeChecked ? this.ui.description.text(this.sanitizedDescription) : this.ui.description.html(this.sanitizedDescription);
}
if (attributeDefs) {
if (!_.isArray(attributeDefs)) {