jQuery-widowFix icon indicating copy to clipboard operation
jQuery-widowFix copied to clipboard

Non-breaking spaces added inside HTML tags

Open jonathanpatt opened this issue 12 years ago • 11 comments

I've been noticing a number of nbsps being added within the opening tags of HTML elements, for example:

<img src="..." &nbsp;alt="..." />

In most browsers, this doesn't break anything, but in IE it tends to break that element and cause (in the case of the img tag) a broken image to show instead. I've also noticed this occurring in form elements—for example, causing a hidden field to be visible.

jonathanpatt avatar Jul 03 '12 13:07 jonathanpatt

Thanks for the note. Is the <img> the last thing in the fixed element? I ran into a similar issue if a link is the last thing in the element.

It would be mega-helpful if you could make a fiddle that reproduces the bug.

matthewlein avatar Jul 03 '12 14:07 matthewlein

Yes, it occurs to the last element (or only element, if there's only one) within a fixed element. Seems to occur with any sort of element. http://jsfiddle.net/DzpBm/1/ illustrates it with form inputs—the first is a text input, the last a password. If you look at the last input with a DOM inspector, you'll see the &nbsp; added immediately before the name attribute. WebKit and Gecko tolerate the presence of an &nbsp; in this location, but IE (at least up through IE9) behaves oddly—in this example, the password field reverts to a standard text input instead, which is how I noticed the issue in the first place.

jonathanpatt avatar Jul 03 '12 15:07 jonathanpatt

OK, thanks. I'm not too worried about that kind of case, IMO it shouldn't be used there. But I will see about smartening it up a little in the next version to protect against images and tags with classes, etc. Will have to try to think of something clever...

matthewlein avatar Jul 03 '12 16:07 matthewlein

In situations with form fields, yes, it generally shouldn't be used anyway—I just used that as an example because it was where I had first encountered it in a situation where I had an overly-broad selector list. However, there is a situation where it does become more of a problem, such as where a CMS wraps every line within a dynamic content area in a <p>, including when that line is just a single <img>. Also, situations where there are inline graphics within paragraphs, such as Wikipedia's external link icons.

jonathanpatt avatar Jul 03 '12 16:07 jonathanpatt

Good points. I hate it when CMSs do that. :)

matthewlein avatar Jul 03 '12 16:07 matthewlein

I'm getting this happening: <a&nbsp;href="

kevadamson avatar Feb 22 '13 14:02 kevadamson

Likewise, even with linkFix: false supplied in the options.

lazyatom avatar Mar 15 '13 16:03 lazyatom

This is kind of a big issue - getting this behavior in a lot of unwanted places. I think a good solution would be to have widowFix ignore elements within html tags.

If you have widowFix set to run on say, .entry-content p then anything within html tags within

tags will get extra   added. There are lots of times

elements will have html within: links, text formatting, etc. This is super no bueno.

If you have to start getting super specific with your selectors then it kind of defeats the purpose of this plugin.

joshuaiz avatar Jun 12 '15 02:06 joshuaiz

Breaks inline css. <div class="indicator" style="background-color: #9d612f"></div> is turned into <div class="indicator" style="background-color:&nbsp;#9d612f"></div> which won't render anywhere afaik.

joakimc avatar Dec 16 '15 17:12 joakimc

I agree that this is a not perfect solution, and I'm open to PRs with tests that show its fixed :smile:

matthewlein avatar Dec 16 '15 19:12 matthewlein

I recommend not using this plugin. Here's an alternative simpler method that doesn't break your HTML:

function nbsp(html) {
    var text = $(html).text().replace(/\n/g, '').split(' ').filter(Boolean),
        secondLastWord = text[text.length - 2],
        lastWord = text[text.length - 1];

    return (
        html.substring(html.lastIndexOf(secondLastWord), 0, secondLastWord.length) +
        secondLastWord + '&nbsp;' +
        html.substring(html.lastIndexOf(secondLastWord) + secondLastWord.length)
    ).replace(secondLastWord + '&nbsp; ', secondLastWord + '&nbsp;').replace(' ' + lastWord, lastWord);
}

Sample covered cases:

nbsp(`<h3 class="h1 divider">
        Get a closer <span class="nowrap">close-up.</span>
      </h3>`);
nbsp(`<h3 class="h1 divider">
        Get a closer close-up.<img src="" alt="some text" />
      </h3>`);
nbsp(`<h3>Get a closer closeup.<div style="background: #fff;"></div></h3>`);
nbsp(`<h3>Get a closer close-up.</h3>`);
nbsp(`<h3>Get a closer closeup.</h3>`);

tomasdev avatar Oct 23 '17 17:10 tomasdev