The CMS I'm using has a really annoying WYSIWYG editor called Summernote. This editor is nice looking and actually works quite well, but the HTML it outputs is shockingly bad and doesn't have any configuration options for styling output. For example, this is some bold, italic text with an underline:
<span style="text-decoration: underline;">
<span style="font-style: italic;">
<span style="font-weight: bold;">
Help!! I'm being squashed by 3 heavy tags.
</span>
</span>
</span>
Images have inline CSS styles, giving the images fixed widths, which is uber-useless for responsive sites:
<img src="..." style="width:832px;">
And YouTube iFrame's have fixed sizes which fly off mobile phone screens:
<iframe src="..." width="560" height="380">
So, as you can see, it's not great, but I don't have the option of changing the editor (not allowed to) and I need to come up with a way of rectifying these issues before the HTML is saved in the database. In my case, using jQuery.
So, after a little trial and error, I've managed to fix the responsive issues with this little snippet:
var code = $('#summernote').code();
var newCode = $('<div></div>').append(code)
.find('iframe').wrap('<div class="flexVideo"/>')
.end()
.find('img').removeAttr('style').wrap('<div class="flexPhoto"/>')
.end()
.html();
As you can see, this wraps all iFrame's in a responsive wrapper, wraps all images in another wrapper (for non-responsive purposes) and removes all inline styles from the images making them more fluid. This works great, but I'm really struggling on the last part; replacing all of those span tags with proper elements and I unfortunately need to ask for some help.
I understand that using something like this could select the SPAN elements for BOLD and using wrapInner() and unwrap() I could replace the spans with proper textual elements:
$('span').filter(function() {
return $(this).css('font-weight') == 'bold';
}).wrapInner('<b></b>').unwrap()
BUT
1) I cannot even get the wrapInner() to work on it's own (check this fiddle).
2) If this is actually possible, both physically and efficiently, please advice how and also advise on how to chain them all together.
3) Sometimes the spans orders are different, dependant on the order of buttons clicked.
This is my shoddy, failure of an attempt:
var code = $('#summernote').code();
var newCode = $('<div></div>').append(code)
.find('iframe').wrap('<div class="flexVideo"/>')
.end()
.find('img').removeAttr('style').wrap('<div class="flexPhoto"/>')
.end()
.find('span').filter(function() {
return $(this).css('font-weight') == 'bold';
})
.wrapInner('<b></b>')
.unwrap()
.end()
.html();
See this failing JSFIDDLE demo. There are no errors, but it's certainly not doing as it's told. I've tried shouting at it, but that didn't work.
THE AMAZING ANSWER
For all those frustrated Summernote users, you may find this useful. Why is it amazing? Well, although it's split into multiple lines in this example, this is actually a one-liner!!
var newCode = $('<div></div>').append(code)
.find('iframe')
.wrap('<div class="flexVideo"/>')
.end()
.find('img')
.removeAttr('style')
.wrap('<div class="flexPhoto"/>')
.end()
.find('span')
.filter("[style*='underline']")
.removeAttr('style')
.addClass('underline')
.end()
.filter("[style*='bold']")
.wrapInner('<b></b>')
.children()
.unwrap()
.end()
.end()
.filter("[style*='italic']")
.wrapInner('<i></i>')
.children()
.unwrap()
.end()
.end()
.end()
.html();
What does it do?
- Removes inline styles from images restricting responsiveness.
- Wraps images in a DIV (personal preference for overlaying images with buttons and text).
- Wraps iframe videos in a DIV to allow responsiveness.
- Replaces inline
text-decoration:underlinewith classunderline. - Replaces
<span style="font-style:italic">tags with proper<i>tags. - Replaces
<span style="font-weight:bold">tags with proper<b>tags.
strongtag inside theemtag. Or vice versa. Styling should not come from html, but from css :) - skip405<em>You are in <strong>BIG</strong> trouble</em>is perfectly acceptable markup. There's a good read about it here: stackoverflow.com/questions/2200590/… - TheCarverem, I would certainly try to avoid that. I guess I just didn't make myself clear enough. Anyways, I guess this question has been answered and solves your problem. Cheers :) - skip405