Skip to content

Instantly share code, notes, and snippets.

@barneycarroll
Last active March 23, 2019 23:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save barneycarroll/5582659 to your computer and use it in GitHub Desktop.
Save barneycarroll/5582659 to your computer and use it in GitHub Desktop.
Get rid of redundant whitespace & empty structural elements, in that order
void function semanticContentScope(context, jQuery){
var $ = context.jQuery || jQuery || false;
if(!$){
return false;
}
// Strips elements of duplicate, leading and trailing whitespace and removes empty non-functional elements recursively
function semanticContent(markup){
// Conversion
if(markup instanceof HTMLElement){
markup = markup.outerHTML;
}
// If nothing was passed, or we were just passed a string full of whitespace, return empty string
if(!markup && /^\s*$/.test(markup)){
return '';
}
// Wrap contents, add each node to collection, and inverse order:
// Start at the bottom of the tree, such that recursive iteration removes elements containing nothing but empty elements
var $wrapper = $('<div>').append(markup);
var $contents = $wrapper.add($wrapper.find('*'));
var $reversed = [].reverse.call($contents);
// Iterate through each element, starting with end nodes and working up
$reversed.each(function lipoIterator(index, el){
var $el = $(el);
var markup = el.innerHTML;
// These rules only apply to known structural and styling elements:
// We shouldn't be removing or tampering with, ie, <img>s or <hr>s
if(!/^(b|bold|br|em|font|mark|span|strong|p|div|u)$/i.test(el.tagName)){
return;
}
// If the node contains nothing but whitespace, nerf it
if(/^br$/i.test(el.tagName) || !markup.replace(/\s|&(nbsp|#160);|<br\/?>/gi,'').length){
$el.remove();
}
else {
// Replace contents with whitespace-sanitized version
$el.html(markup
// Replace encoded non-breaking spaces with breaking spaces
.replace(/&(nbsp|#160);/gi,' ')
// Trim leading and trailing whitespace
.replace(/^\s+|\s+$/g, '')
// Deduplicate whitespace
.replace(/(\s){2,}/g, function(multiple,instance){
return instance;
})
);
}
});
return $reversed.eq(-1).html();
}
$.fn.semanticContent = function $semanticContentScope(){
var $yield = $();
this.each(function(){
$yield.add($(semanticContent(this));
});
return $yield;
};
context.semanticContent = semanticContent;
}(this, jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment