Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get rid of duplicating content inside <p> #1205

Closed
alyrik opened this issue Jun 6, 2016 · 11 comments
Closed

How to get rid of duplicating content inside <p> #1205

alyrik opened this issue Jun 6, 2016 · 11 comments

Comments

@alyrik
Copy link

alyrik commented Jun 6, 2016

I'm using custom buttons to insert videos and presentations (with iframe). It's inserted in such way:

var embed = '<span class="project-text__video" src="' + videoId + '"><iframe width="560" height="315" src="//www.youtube.com/embed/' + videoId + '" frameborder="0" allowfullscreen></iframe></span>';

restoreSelection();
textAngular.$editor().wrapSelection('insertHTML', embed, true);

Everything is OK. But pressing Enter (when caret is inside that inserted block) causes its duplication.

screen shot 2016-06-06 at 17 12 22

How to handle this? I want it to create new empty <p> but not to duplicate inner content.

@stevenkissack
Copy link

Maybe a plunkr demo here would clear up the behaviour you're describing and allow people to track down why this is happening.

@alyrik
Copy link
Author

alyrik commented Jun 7, 2016

@stevokk, here's a plunker

Try to add a video (press a button). When the video is added try to set caret right on that block with a player (before it). Then press Enter. You'll see that <p class="project-text__video"> is duplicating right above the video block.

screen shot 2016-06-07 at 17 28 35

@alyrik
Copy link
Author

alyrik commented Jul 1, 2016

There is one workaround: just change embed tree's structure:

var embed = '<p><span alt="video" src="' + videoId + '"></span><iframe width="560" height="315" src="//www.youtube.com/embed/' + videoId + '" frameborder="0" allowfullscreen></iframe></p>';

@pbassut pbassut added the bug label Jul 3, 2016
@JoelParke
Copy link
Collaborator

JoelParke commented Jul 17, 2016

I am assuming that this is the same with the 1.5.2 release, but could you verify? As I wasn't able to reproduce. (but I also was very tired! and maybe it's gone?) Thanks!

@gregory-h
Copy link

gregory-h commented Aug 11, 2016

I can confirm this with 1.5.3 and it's a serious issue for us.

We're using insertHtml to inject content of the form <span>..</span>. After doing an insert my editor content looks like this, with the editor cursor posioned af the end of the inserted line.
Client First Name

The markup looks like this
<p><span class="user-view client.firstName">Client First Name</span><br></p>

Immediately after doing an insert anything typed goes into my span text, ie
<p><span class="user-view client.firstName">Client First Name and typed text</span><br></p>

Pressing enter duplicates the injected html but with empty text
`

Client First Name and typed text


`

The problem seems to be that after doing an insert the current selection doesn't match the view. One workaround mentioned is to wrap the injected content in a <p>, but that's not an option for us we need to inject inline content.

@JoelParke
Copy link
Collaborator

I see the issue and am investigating.  Sorry that it took so long to get to this one.... 
Joel

@JoelParke
Copy link
Collaborator

JoelParke commented Sep 9, 2016

It turns out that the issue isn't any difference between the html and the text view.  That does exist and I am working to remove that if I can without breaking anything else.

But it seems that rangy doesn't really allow you to select something that is not visible.  For example I attempted changing:

embed = '<span></span><span class="project-text__video" src="' + videoId + '"><iframe width="560" height="315" src="//www.youtube.com/embed/' + videoId + '" frameborder="0" allowfullscreen></iframe></span>';

but that didn't help , but the following gets you much closer to what you want...

embed = '<span>&#65279;</span><span class="project-text__video" src="' + videoId + '"><iframe width="560" height="315" src="//www.youtube.com/embed/' + videoId + '" frameborder="0" allowfullscreen></iframe></span>';

where the &#65279; is a zero space 'space' which allows you to type into that <span>.  I also changed the taSelection.getSelection() code slightly in this case, and I have more to look at tomorrow.  

@JoelParke
Copy link
Collaborator

JoelParke commented Sep 10, 2016

I have a PR that I am going to check-in later today as soon as I can test it more fully. Basically you will need to put the unicode no-width space character:

    &#62579;

before your html that you will embed. This helps the browser do the right thing and we notice this no-width space and do the right thing behind the scenes.

For example:

    var embed = '&#65279;<p class="project-text__video" src="' + videoId + '"><iframe width="560" height="315" src="//www.youtube.com/embed/' + videoId + '" frameborder="0" allowfullscreen></iframe></p>';

   OR

     var embed = '&#65279;<span class="project-text__video" src="' + videoId + '"><iframe width="560" height="315" src="//www.youtube.com/embed/' + videoId + '" frameborder="0" allowfullscreen></iframe></span>';

work well now. As soon as I put the code out there, please check and verify!!
This was a pain because it is the browser that does the real work.

@JoelParke
Copy link
Collaborator

After testing I see that this works fine on Chrome, but NOT on Firefox, so it will take a bit more time &^%&( ;-).

@JoelParke
Copy link
Collaborator

I have code with:

embed = '<span>&#65279;</span><span class="project-text__video" src="' + videoId + '"><iframe width="560" height="315" src="//www.youtube.com/embed/' + videoId + '" frameborder="0" allowfullscreen></iframe>X</span>';

working well.  But I also noticed that the ngModel is not updated with the correct html... so... a bit more.

JoelParke added a commit to JoelParke/textAngular that referenced this issue Sep 14, 2016
… content inside <p>

 DOM - added taSelection.updateLeftArrowKey() and taSelection.updateRightArrowKey()
       so that we check the selection after the cursor is moved and correct for the
       differences between Firefox and Chrome.
     - added taSelection.getFlattenedDom() that returns the nodes needed to allow
       the updateLeftArrowKey() and updateRightArrowKey() to function.
       Basically this returns a flattened set of Nodes that have text content as well
       as the associated parent Nodes.
     - insertHtml() now allows the insertion of a text with the zero-width space character.
 demo.html - fixed a bug where is had two editors with the same name.
 globals - added '#text' and 'spam' to the VALIDELEMENTS
         - defined ENTER_KEYCODE, TAB_KEYCODE, LEFT_ARROW, RIGHT_ARROW to make the code
           more transparent.
 main - small formatting change to the code.
 taBind - now use ENTER_KEYCODE, TAB_KEYCODE, LEFT_ARROW, RIGHT_ARROW definitions from global
        - shifted to using nodeName whenever we call match(VALIDELEMENTS)
        - element.on('keyup') now detects the LEFT_ARROW and RIGHT_ARROW and calls the
          taSelection.updateLeftArrowKey() or taSelection.updateRightArrowKey()
@JoelParke
Copy link
Collaborator

JoelParke commented Sep 14, 2016

I just merged in PR #1315 and believe this fixes this issue.  PLEASE test and left me know.  This was a royal pain, but I like the behavior now.  Closing this issue. please reopen in needed.

JoelParke added a commit that referenced this issue Sep 14, 2016
fix(DOM, globals, main, taBind): Fix for #1205 Duplicating content in…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants