Trix: Editor loses focus when `enter`-ing and `backspace`ing around attachments

Created on 16 Mar 2016  Â·  8Comments  Â·  Source: basecamp/trix

In certain instances when typing enter or backspace around an inserted attachment, the editor can lose focus. This is particularly bad in backspace scenarios as a user may continue hitting backspace causing the browser’s back behavior to be triggered. I can, with some amount of certainty, say that we’re seeing this in recent versions of Chrome but I haven’t done an exhaustive check against other browsers.

To recreate from the Trix site:

  1. Insert an attachment from the console:

``` javascript
const attachment = new Trix.Attachment({content: ''});

 document.querySelector('trix-editor').editor.insertAttachment(attachment);

```

  1. Focus cursor at the front of inserted video and hit enter a few times. Editor should lose focus. Similarly, and this is a little harder to reproduce, if you arrow around the attachment and hit backspace the editor will eventually lose focus as well.

Most helpful comment

This isn't an issue with attachments generally, but rather with content attachments containing an <iframe>. <iframe>s are reloaded when they're moved in the DOM, and I suspect this causes a focus or selection change. It's possible this issue is specific to Youtube embeds. I haven't tested others. The only workaround I can think of for now to avoid inserting iframes and use a placeholder image instead. If anything, it would prevent the frequent reloading when Trix renders.

In Basecamp, we use preview image when editing and swap in the actual embed when rendering.

embed

All 8 comments

This isn't an issue with attachments generally, but rather with content attachments containing an <iframe>. <iframe>s are reloaded when they're moved in the DOM, and I suspect this causes a focus or selection change. It's possible this issue is specific to Youtube embeds. I haven't tested others. The only workaround I can think of for now to avoid inserting iframes and use a placeholder image instead. If anything, it would prevent the frequent reloading when Trix renders.

In Basecamp, we use preview image when editing and swap in the actual embed when rendering.

embed

Thanks @javan, this helps a ton. I'll close this ticket now as I think that answers what we were seeing and how to potentially solve it.

In Basecamp, we use preview image when editing and swap in the actual embed when rendering.

hi @javan, are you able to share some code for this functionality?

For youtube embed, I'm currently inserting an iframe, like in #120, but content attachments are put into a <figure> tag. Also the shifting focus (mentioned above) within the editor is an accessibility blocker, so your method with an image placeholder is definitely the way to go.

Any guidance appreciated! Thanks.

@heidiv once we receive an answer, let's capture these techniques on the wiki. I imagine many people will need to solve this problem for themselves and it would be nice to have the techniques in a place that doesn't involve searching the issue tracker. Ping me if you'd like me help. I'm happy to!

@jrguenther nice yeah. I have the preview image happening (code snippet below - youtube specific)

screen shot 2016-07-14 at 3 14 47 pm

videlement = document.querySelector("input[name=insertvideo]")
youtube_id = videlement.value.split('=').pop()
preview_image = 'http://img.youtube.com/vi/'+youtube_id+'/0.jpg'                 
element.editor.insertHTML("<img src='"+preview_image+"' alt='Placeholder image for video'>")

and the embed attachment code would be

embed = '<iframe width="420" height="315" src="https://www.youtube.com/embed/'+youtube_id+'" frameborder="0" allowfullscreen></iframe>'
attachment = new Trix.Attachment({content: embed})
element.editor.insertAttachment(attachment)

Still need to do the switcheroo from image to vid. Perhaps there's a way to attache as <video> instead of figure...

are you able to share some code for this functionality?

There are a number of moving parts on both the server and client so it's not exactly a shareable snippet. We get the preview image from YouTube's (and other services) oEmbed API leaning on ruby-oembed for help with that. When rendering, we filter the content throught a custom html-pipeline filter that scans for relevant Trix attachments and swaps them out with the oEmbed content.

Ok, thanks @javan !

Hey, I'm trying to implement the youtube embedding thing but I can't capture the "Insert" button event.

myDialogHtml =
    '<div class="trix-dialog trix-dialog--link" data-trix-dialog="myDialog" data-trix-dialog-attribute="src">
        <div class="dialog-content">
           <div class="trix-dialog__link-fields">
            <input type="url" name="src" class="trix-input trix-input--dialog" placeholder="Enter a URL…" required="" data-trix-input="" disabled="disabled">
            <div class="trix-button-group">
              <input type="button" class="trix-button trix-button--dialog" value="Insert" data-trix-method="makeAttachment">
            </div>
          </div>
        </div>
      </div>';
  dialogElement = event.target.toolbarElement.querySelector(".trix-dialogs");
  dialogElement.insertAdjacentHTML("beforeend", myDialogHtml);

and then:

makeAttachment = (_) ->
  console.log 'TODO Attachment'

But the makeAttachment method is never fired. any thoughts?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lcsqlpete picture lcsqlpete  Â·  3Comments

lanzhiheng picture lanzhiheng  Â·  4Comments

adueck picture adueck  Â·  3Comments

marpstar picture marpstar  Â·  5Comments

binchentx picture binchentx  Â·  5Comments