NaughtySquid
NaughtySquid

Reputation: 2097

jquery find won't find the "b" html element

So I am scraping HTML from Google Docs when copying and pasting, to convert it into BBCode for my sites editor.

It's messy (I don't control how Google Docs renders obviously), but pasting something simple would like like (this is 3 lines of text from a Google Doc):

<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta charset="utf-8">
<b style="font-weight:normal;" id="docs-internal-guid-7304b159-0210-bb69-2db2-b4cc8d9a2d67">
<p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">Test File</span></p><br>
<p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:700;font-style:italic;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre-wrap;">This is a test</span></p><br>
<p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"><a href="https://www.test.com" style="text-decoration:none;"><span style="font-size:11pt;font-family:Arial;color:#1155cc;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;">Test link</span></a></p>
</b><br class="Apple-interchange-newline">

The actual JS code I have right now to do it:

$('textarea').on('paste',function(e) 
{
    e.preventDefault();
    var text = (e.originalEvent || e).clipboardData.getData('text/html') || prompt('Paste something..');

    console.log(text);

    var jqTxt = jQuery(text);

    jqTxt.find("a").each(function(item, el)
    {
        $(el).replaceWith("[url=" + el.href + "]" + el.textContent + "[/url]");
    });

    jqTxt.find("br").each(function(item, el)
    {
        $(el).replaceWith("\n");
    });

    jqTxt.find("b").each(function(item, el)
    {
        $(el).replaceWith("[b]" + el.textContent + "[/b]");
    });

    jqTxt.find("p").each(function(item, el)
    {
        $(el).replaceWith(el.textContent+"\r\n");
    });

    window.document.execCommand('insertText', false, jqTxt.text());
});

It works for the links, the br and the p tags, but not for the b tags and I'm not sure why.

This method replaces what I want, then the rest is thrown away as we're making it normal text again.

Upvotes: 1

Views: 61

Answers (1)

Jeff B
Jeff B

Reputation: 30099

When you parse the html with jQuery(), the top parent items are actually returned.

In this case, <b> is a top-level parent. So, jqTxt is actually the collection of b and the two meta elements.

So, since find() only looks at descendants of the current selected items, b is not found. Any descendant b elements would be found just fine, but you don't have any.

A simple solution to this would be to wrap your input text with some dummy tags before parsing:

text = "<div>" + text + "</div>";

Example (without paste code): https://jsfiddle.net/rka9em0p/

Upvotes: 3

Related Questions