3

I will try do describe the issue:

I'm using contenteditable to edit text in DIV. The standard for elements I need to have in that DIV is:

paragraph:

<p style="someStyles"><span style="someStyles">TEXT GOES HERE</span></p>

empty line:

<p style="someStyles"><span style="someStyles"><br></span></p>

Due to some user text manipulations like copy/paste standard is messed in that DIV like here (ex. of case):

<span style="someStyles">
    <p style="someStyles">SOME TEXT HERE</p>
    <p style="someStyles">SOME TEXT HERE</p>
</span>

Im looking for a solution that will take messed text elements and rearrange it to given standard I wrote about above, any suggestions ?

After rearranging elements it should look like this:

<p style="someStyles">
    <span style="someStyles">SOME TEXT HERE</span>
    <span style="someStyles">SOME TEXT HERE</span>
</p>

P.S - I want to make that rearrange function on keyup event while typing and only for whole p element that caret is on.

itradoRD
  • 53
  • 1
  • 5
  • You forgot to paste the code you tried. Showing a sample where one can reproduce the issue might help. How you're adding your SPAN elements and classes? – Roko C. Buljan Jan 30 '15 at 13:48
  • Your standard can be messed up in infinitely many ways by the user. You gave one example (which is solvable), but if I understand correctly, you are asking for an algorithm that can convert any kind off mess to your standard (which isn't solvable). – zord Jan 30 '15 at 14:05
  • @RokoC.Buljan text is the same as paragraph described above with empty lines between. I will try to provide some more examples. – itradoRD Jan 30 '15 at 15:29

1 Answers1

1

As I stated in my comment, I can't see a general solution to this, but your specific example could be solved like this. And you can easily make several other conversions based on this one.

The replace function is based on this answer.

// this converts an element to another tag
function replace(thisWith, that) {
    $(thisWith).replaceWith(function() {
        var i, replacement = $('<' + that + '>').html($(this).html());
        for (i = 0; i < this.attributes.length; i++) {
            replacement.attr(this.attributes[i].name, this.attributes[i].value);
        }
        return replacement;
    });
}

function convert() {
    // get SPANs that has Ps inside
    var $spans = $("#content span").has("p");
    $spans.each(function () {
        // change children Ps into SPANs
        replace($(this).children("p"), "span");
        // change parent SPAN into P
        replace(this, "p");        
    });
}

Here is a test jsfiddle.

Community
  • 1
  • 1
zord
  • 4,538
  • 2
  • 25
  • 30