HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Stripping formatting from text - Am I using an efficient jQuery selector?

Submitted by: @import:stackexchange-codereview··
0
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 $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:

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 of


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:

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 of
message.replace('/\[\[person\]\]/g', '<strong>some name</strong>');

Context

StackExchange Code Review Q#22731, answer score: 2

Revisions (0)

No revisions yet.