patternjavascriptMinor
Stripping formatting from text - Am I using an efficient jQuery selector?
Viewed 0 times
selectorstrippingformattingtextefficientjqueryusingfrom
Problem
I'm making a comment box using a contenteditable div, but I want to remove formatting from text a user might copy/paste into it (also no CTRL+B or CTRL+I shortcuts allowed either). Only "approved" formatting ("tagged" names, URLs, etc).
Originally I went the regex route but was informed regex + html is not a good approach, so I then tried using jQuery/DOM manipulation and found a solution there as well.
I am worried though, that my jQuery selector used in
Two utility functions (for reference)
main handler with super long selector in
```
$('#input').on('paste', function() {
var $inputDiv = $(this);
setTimeout(function() {
var oldHTML = '', newHTML = '';
// look through the commentbox for headings and other (mostly) block
// elements
var $nodesToReplace = $inputDiv.find('h1,h2,h3,h4,h5,h6,address,article,aside,blockquote,div,p,pre,dd,dt');
var $nodesToRemove = $inputDiv.find('*').not($nodesToReplace);
$nodesToRemove.each(function(){
console.log('Nodes with tags to remove: ',$(this).outerHtml());
$(this).removeElemTags();
});
$nodesToReplace.each(function(){
console.log('Nodes with tags to replace: ',$(this).outerHt
Originally I went the regex route but was informed regex + html is not a good approach, so I then tried using jQuery/DOM manipulation and found a solution there as well.
I am worried though, that my jQuery selector used in
$nodesToReplace is too long and possibly inefficient although it basically describes what I want returned. I'm just wondering if there was another more elegant/shorter/more efficient way to do this that I may have overlooked. Here's the code:Two utility functions (for reference)
// Change an Element's type (change it's html tags) to "newType"
jQuery.fn.changeElemTypeTo = function(newType){
// just make sure it's a plain element name
newType.replace(/[]/ig,'');
var newElemStr = '' + this.html() + '';
console.log('*Nodes with tags replaced: ',newElemStr);
return this.replaceWith(newElemStr);
};
// Remove/strip the html tags from an element
jQuery.fn.removeElemTags = function(){
var tmp = this.replaceWith(this.html());
console.log('*Node with tags Removed: ',this.html());
return tmp;
};main handler with super long selector in
$nodesToReplace...```
$('#input').on('paste', function() {
var $inputDiv = $(this);
setTimeout(function() {
var oldHTML = '', newHTML = '';
// look through the commentbox for headings and other (mostly) block
// elements
var $nodesToReplace = $inputDiv.find('h1,h2,h3,h4,h5,h6,address,article,aside,blockquote,div,p,pre,dd,dt');
var $nodesToRemove = $inputDiv.find('*').not($nodesToReplace);
$nodesToRemove.each(function(){
console.log('Nodes with tags to remove: ',$(this).outerHtml());
$(this).removeElemTags();
});
$nodesToReplace.each(function(){
console.log('Nodes with tags to replace: ',$(this).outerHt
Solution
I struggled with the same issue in the past, and decided to simply use a disposable DOM element to convert the HTML to plaintext:
With this approach, we still needed to allow the user to enter a single tag. For this, we simply implemented a microformat where the user enters "placeholders" with bracket symbols:
Hello [[person]], having a good day?
Since this is just plain text, it will not be removed by the above conversion process, and can simply be replaced with the appropriate HTML tags:
var message = "..."; // Contains HTML markup
var tmp = document.createElement("DIV");
tmp.innerHTML = message;
var message = tmp.textContent||tmp.innerText;
// message now contains plaintext, and tmp can be disposed ofWith this approach, we still needed to allow the user to enter a single tag. For this, we simply implemented a microformat where the user enters "placeholders" with bracket symbols:
Hello [[person]], having a good day?
Since this is just plain text, it will not be removed by the above conversion process, and can simply be replaced with the appropriate HTML tags:
message.replace('/\[\[person\]\]/g', 'some name');Code Snippets
var message = "..."; // Contains HTML markup
var tmp = document.createElement("DIV");
tmp.innerHTML = message;
var message = tmp.textContent||tmp.innerText;
// message now contains plaintext, and tmp can be disposed ofmessage.replace('/\[\[person\]\]/g', '<strong>some name</strong>');Context
StackExchange Code Review Q#22731, answer score: 2
Revisions (0)
No revisions yet.