Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trix editor define custom attachment styles

I added an image to the Trix editor, generating the following code:

<figure 
    data-trix-attachment="{lots of data}" 
    data-trix-content-type="image/jpeg"
    data-trix-attributes="{'presentation':'gallery'}" 
    class="attachment attachment--preview attachment--jpg">
    <img src="http://myhost/myimage.jpg" width="5731" height="3821">
    <figcaption class="attachment__caption">
        <span class="attachment__name">cool.jpg</span> <span class="attachment__size">4.1 MB</span>
    </figcaption>
</figure>

When I display the generated HTML from the editor on my Bootstrap-based page, the image obviously extends the screen (see the width and height) and I'd like to remove these props and also assign the img-fluid class to it.

So basically I thought to use the config:

Trix.config.css.attachment = 'img-fluid'

But that does a) not change the attachment class to img-fluid and it also would not apply the changes to the image but the figure.

I would like to avoid using jQuery each time I display the content and traverse all figures and then manipulate the image's properties at runtime.

Isn't there a solution to define these styles when adding the attachment?

like image 870
Jankapunkt Avatar asked Mar 15 '19 14:03

Jankapunkt


1 Answers

Trix does not have any kind of support to change the image element inside the attachment. One way to do it is by using MutationObserver to check for mutations inside Trix editor that apply to attributes, childList and subtree.

If we have a width or height attributes mutation to an img target node with a figure parent node, then we remove those attributes and we can apply the class img-fluid to the first attribute mutation, for example width.

Run code snippet and try to add some image attachments to see or inspect the HTML

Please read inline comments

// Listen to trix-attachment-add event so we'll get rid of the progress bar just for this demo
// Here we should upload the attachment and handle progress properly
document.addEventListener("trix-attachment-add", event => {
  const { attachment } = event.attachment;
 
  // Get rid of the progress bar
  attachment.setUploadProgress(100)
});


// Get the Trix editor
const editor = document.querySelector('trix-editor');

// Instantiating an observer
const observer = new MutationObserver(function (mutations) {
  mutations.forEach(({ type, target, attributeName }) => {
    
    // If the parent is a figure with an img target
    if (target.parentNode.tagName === 'FIGURE' && 
        target.nodeName === 'IMG')
    {
      if (type === 'attributes') {
        switch(attributeName) {

          // If we have attribute width
          case 'width':
            // Remove attribute width
            target.removeAttribute('width');
            // Add img-fluid only once
            target.classList.add('img-fluid');
            break;

          // If we have attribute height
          case 'height':
            // Remove attribute height
            target.removeAttribute('height');
            break;
        }
      }

      // Render images HTML code
      renderHtmlOutput();
    }

  });
});

// Observing Trix Editor
observer.observe(editor, {
  attributes: true,
  childList: true,
  subtree: true
});

// Function to render every figure > img HTML code
function renderHtmlOutput() {
  const images = editor.querySelectorAll('figure > img');
  let output = '';

  for(const image of images) {
    output += image.outerHTML.replace(/ /g, "\n  ") + "\n";
  }

  document.getElementById('output-html').textContent = output;
}
body {
  height: 100vh;
  margin: 0;
  flex-direction: column;
  display: flex;
}
#main {
  display: flex;
  flex-direction: row;
  flex: 1;
  margin: 10px;
}

#editor-container {
  flex: 3;
}

#output-container {
  flex: 2;
  margin-left: 20px;
  border-left: 1px solid lightgray;
  overflow: auto;
}

#output-html {
  margin: 0;
  padding: 10px;
  font-size: small;
  color: blue;
}

/* Hide some Trix buttons to free horizontal space */
.trix-button--icon-increase-nesting-level,
.trix-button--icon-decrease-nesting-level,
.trix-button--icon-bullet-list,
.trix-button--icon-number-list { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/trix/1.2.1/trix.js" integrity="sha256-2D+ZJyeHHlEMmtuQTVtXt1gl0zRLKr51OCxyFfmFIBM=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/trix/1.2.1/trix.css" integrity="sha256-yebzx8LjuetQ3l4hhQ5eNaOxVLgqaY1y8JcrXuJrAOg=" crossorigin="anonymous"/>

<section id="main">
  <div id="editor-container">
    <form>
      <input id="editor" value="Editor content goes here" type="hidden" name="content">
      <trix-editor input="editor"></trix-editor>
    </form>
  </div>
  <div id="output-container">
    <pre id="output-html"></pre>
  </div>
</section>
like image 150
Christos Lytras Avatar answered Sep 23 '22 04:09

Christos Lytras