1

I have to create a screenshot capturing extension using javascript. The extension now capturing the whole document using document.body. but now I want to capture the only visible area when using the extension. How can I get the elements only visible area of the HTML document?

current screenshot

enter image description here

but I need to capture

enter image description here

In here below code sample I passing the document.body into domtoimage.toPng() like this,

  async function onSupportButtonClick() {
    try {
      setSupportButtonLoading(true)
      const corsImages = [];
      const originalCorsSources = [];
      proxifyCorsImages(corsImages, originalCorsSources)
      const supportEmail = document.getElementById(JIRASUPPOTER_SUPPORT_MODAL_EMAIL)
      if (supportEmail) supportEmail.value = document?.profile?.email ?? ""
      const imageContainer = document.getElementById(JIRASUPPOTER_SUPPORT_MODAL_IMAGE_CONTAINER);
      imageContainer.innerHTML = "" //removing previous screenshot
      const dataUrl = await domtoimage.toPng(document.body, { imagePlaceholder: EMPTY_IMAGE_PLACEHOLDER })
      deproxifyCorsImages(corsImages, originalCorsSources)
      setMuiModalsDisplay("none");
      setScreenshotImage(dataUrl, imageContainer)
    } catch (err) {
      console.log(err)
      showSupportAlert(createElementFromHTML(errorAlertChild), JIRASUPPOTER_SUPPORT_ALERT_TYPES.WARNING)
    }
    const modal = document.getElementById(JIRASUPPOTER_SUPPORT_MODAL);
    if (modal) modal.style.display = "flex";
  }
avishka
  • 171
  • 1
  • 5
  • 19
  • 1
    could you provide some extension code? – Dean Van Greunen Aug 04 '22 at 11:59
  • 1
    you can't do it with a css selector alone. For sure it requires some javascript and there are some hints here on how to test a given element is in the viewport: https://stackoverflow.com/questions/123999/how-can-i-tell-if-a-dom-element-is-visible-in-the-current-viewport but it will be up to you to pass the list of elements to test against that. I hope that helps somehow. Maybe also [this](https://stackoverflow.com/questions/4912092/using-html5-canvas-javascript-to-take-in-browser-screenshots) may help (using WebRTC) – Diego D Aug 04 '22 at 12:04
  • Can your extension capture any `div`? – IT goldman Aug 04 '22 at 12:21
  • yeah, it can capture any div @ITgoldman – avishka Aug 04 '22 at 12:45

1 Answers1

0

Add an element that is fixed, then capture it. This element of course should contain all the content that is in <body> therefore it sits between them. Only thing left is to restore the scroll position. It seems to be working.

window.setTimeout(function() {
  var div = document.createElement('div')
  div.classList.add('frame')
  var y = window.scrollY;
  Array.prototype.slice.call(document.body.children).forEach(function(child) {
    div.appendChild(child)
  })
  document.body.appendChild(div)
  div.scrollTop = y;
  
}, 1000)
.frame {
  position: fixed;
  
  border: 2px solid red;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: auto;
}
<!doctype html>
<html>

<head>
  <meta name="viewport" content="width=device-width" />
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Simple Transactional Email</title>
  <style>
    /* -------------------------------------
          GLOBAL RESETS
      ------------------------------------- */
    
    img {
      border: none;
      -ms-interpolation-mode: bicubic;
      max-width: 100%;
    }
    
    body {
      background-color: #f6f6f6;
      font-family: sans-serif;
      -webkit-font-smoothing: antialiased;
      font-size: 14px;
      line-height: 1.4;
      margin: 0;
      padding: 0;
      -ms-text-size-adjust: 100%;
      -webkit-text-size-adjust: 100%;
    }
    
    table {
      border-collapse: separate;
      mso-table-lspace: 0pt;
      mso-table-rspace: 0pt;
      width: 100%;
    }
    
    table td {
      font-family: sans-serif;
      font-size: 14px;
      vertical-align: top;
    }
    /* -------------------------------------
          BODY & CONTAINER
      ------------------------------------- */
    
    .body {
      background-color: #f6f6f6;
      width: 100%;
    }
    /* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
    
    .container {
      display: block;
      margin: 0 auto !important;
      /* makes it centered */
      max-width: 580px;
      padding: 10px;
      width: 580px;
    }
    /* This should also be a block element, so that it will fill 100% of the .container */
    
    .content {
      box-sizing: border-box;
      display: block;
      margin: 0 auto;
      max-width: 580px;
      padding: 10px;
    }
    /* -------------------------------------
          HEADER, FOOTER, MAIN
      ------------------------------------- */
    
    .main {
      background: #ffffff;
      border-radius: 3px;
      width: 100%;
    }
    
    .wrapper {
      box-sizing: border-box;
      padding: 20px;
    }
    
    .content-block {
      padding-bottom: 10px;
      padding-top: 10px;
    }
    
    .footer {
      clear: both;
      margin-top: 10px;
      text-align: center;
      width: 100%;
    }
    
    .footer td,
    .footer p,
    .footer span,
    .footer a {
      color: #999999;
      font-size: 12px;
      text-align: center;
    }
    /* -------------------------------------
          TYPOGRAPHY
      ------------------------------------- */
    
    h1,
    h2,
    h3,
    h4 {
      color: #000000;
      font-family: sans-serif;
      font-weight: 400;
      line-height: 1.4;
      margin: 0;
      margin-bottom: 30px;
    }
    
    h1 {
      font-size: 35px;
      font-weight: 300;
      text-align: center;
      text-transform: capitalize;
    }
    
    p,
    ul,
    ol {
      font-family: sans-serif;
      font-size: 14px;
      font-weight: normal;
      margin: 0;
      margin-bottom: 15px;
    }
    
    p li,
    ul li,
    ol li {
      list-style-position: inside;
      margin-left: 5px;
    }
    
    a {
      color: #3498db;
      text-decoration: underline;
    }
    /* -------------------------------------
          BUTTONS
      ------------------------------------- */
    
    .btn {
      box-sizing: border-box;
      width: 100%;
    }
    
    .btn>tbody>tr>td {
      padding-bottom: 15px;
    }
    
    .btn table {
      width: auto;
    }
    
    .btn table td {
      background-color: #ffffff;
      border-radius: 5px;
      text-align: center;
    }
    
    .btn a {
      background-color: #ffffff;
      border: solid 1px #3498db;
      border-radius: 5px;
      box-sizing: border-box;
      color: #3498db;
      cursor: pointer;
      display: inline-block;
      font-size: 14px;
      font-weight: bold;
      margin: 0;
      padding: 12px 25px;
      text-decoration: none;
      text-transform: capitalize;
    }
    
    .btn-primary table td {
      background-color: #3498db;
    }
    
    .btn-primary a {
      background-color: #3498db;
      border-color: #3498db;
      color: #ffffff;
    }
    /* -------------------------------------
          OTHER STYLES THAT MIGHT BE USEFUL
      ------------------------------------- */
    
    .last {
      margin-bottom: 0;
    }
    
    .first {
      margin-top: 0;
    }
    
    .align-center {
      text-align: center;
    }
    
    .align-right {
      text-align: right;
    }
    
    .align-left {
      text-align: left;
    }
    
    .clear {
      clear: both;
    }
    
    .mt0 {
      margin-top: 0;
    }
    
    .mb0 {
      margin-bottom: 0;
    }
    
    .preheader {
      color: transparent;
      display: none;
      height: 0;
      max-height: 0;
      max-width: 0;
      opacity: 0;
      overflow: hidden;
      mso-hide: all;
      visibility: hidden;
      width: 0;
    }
    
    .powered-by a {
      text-decoration: none;
    }
    
    hr {
      border: 0;
      border-bottom: 1px solid #f6f6f6;
      Margin: 20px 0;
    }
    /* -------------------------------------
          RESPONSIVE AND MOBILE FRIENDLY STYLES
      ------------------------------------- */
    
    @media only screen and (max-width: 620px) {
      table[class=body] h1 {
        font-size: 28px !important;
        margin-bottom: 10px !important;
      }
      table[class=body] p,
      table[class=body] ul,
      table[class=body] ol,
      table[class=body] td,
      table[class=body] span,
      table[class=body] a {
        font-size: 16px !important;
      }
      table[class=body] .wrapper,
      table[class=body] .article {
        padding: 10px !important;
      }
      table[class=body] .content {
        padding: 0 !important;
      }
      table[class=body] .container {
        padding: 0 !important;
        width: 100% !important;
      }
      table[class=body] .main {
        border-left-width: 0 !important;
        border-radius: 0 !important;
        border-right-width: 0 !important;
      }
      table[class=body] .btn table {
        width: 100% !important;
      }
      table[class=body] .btn a {
        width: 100% !important;
      }
      table[class=body] .img-responsive {
        height: auto !important;
        max-width: 100% !important;
        width: auto !important;
      }
    }
    /* -------------------------------------
          PRESERVE THESE STYLES IN THE HEAD
      ------------------------------------- */
    
    @media all {
      .ExternalClass {
        width: 100%;
      }
      .ExternalClass,
      .ExternalClass p,
      .ExternalClass span,
      .ExternalClass font,
      .ExternalClass td,
      .ExternalClass div {
        line-height: 100%;
      }
      .apple-link a {
        color: inherit !important;
        font-family: inherit !important;
        font-size: inherit !important;
        font-weight: inherit !important;
        line-height: inherit !important;
        text-decoration: none !important;
      }
      .btn-primary table td:hover {
        background-color: #34495e !important;
      }
      .btn-primary a:hover {
        background-color: #34495e !important;
        border-color: #34495e !important;
      }
    }
  </style>
</head>

<body class="">
  <table border="0" cellpadding="0" cellspacing="0" class="body">
    <tr>
      <td>&nbsp;</td>
      <td class="container">
        <div class="content">

          <!-- START CENTERED WHITE CONTAINER -->
          <span class="preheader">This is preheader text. Some clients will show this text as a preview.</span>
          <table class="main">

            <!-- START MAIN CONTENT AREA -->
            <tr>
              <td class="wrapper">
                <table border="0" cellpadding="0" cellspacing="0">
                  <tr>
                    <td>
                      <p>Hi there,</p>
                      <h1>Scroll the page,</h1>
                      <h1>In a second it will capture,</h1>
                      <h1>Hi there,</h1>
                      <h1>Hi there,</h1>
                      <p>Sometimes you just want to send a simple HTML email with a simple design and clear call to action. This is it.</p>
                      <table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
                        <tbody>
                          <tr>
                            <td align="left">
                              <table border="0" cellpadding="0" cellspacing="0">
                                <tbody>
                                  <tr>
                                    <td> <a href="http://htmlemail.io" target="_blank">Email Call To Action</a> </td>
                                  </tr>
                                </tbody>
                              </table>
                            </td>
                          </tr>
                        </tbody>
                      </table>
                      <p>This is a really simple email template. Its sole purpose is to get the recipient to click the button with no distractions.</p>
                      <p>Good luck! Hope it works.</p>
                    </td>
                  </tr>
                </table>
              </td>
            </tr>

            <!-- END MAIN CONTENT AREA -->
          </table>

          <!-- START FOOTER -->
          <div class="footer">
            <table border="0" cellpadding="0" cellspacing="0">
              <tr>
                <td class="content-block">
Hi There,
Sometimes you just want to send a simple HTML email with a simple design and clear call to action. This is it.

Email Call To Action
This is a really simple email template. Its sole purpose is to get the recipient to click the button with no distractions.

Good luck! Hope it works.                
                  <span class="apple-link">Company Inc, 3 Abbey Road, San Francisco CA 94102</span>
                  <br> Don't like these emails? <a href="http://i.imgur.com/CScmqnj.gif">Unsubscribe</a>.
                </td>
              </tr>
              <tr>
                <td class="content-block powered-by">
                  Powered by <a href="http://htmlemail.io">HTML Email</a>.
                </td>
              </tr>
            </table>
          </div>
          <!-- END FOOTER -->

          <!-- END CENTERED WHITE CONTAINER -->
        </div>
      </td>
      <td>&nbsp;</td>
    </tr>
  </table>

  <!-- Fork on GitHub -->
  <a href="https://github.com/leemunroe/responsive-html-email-template"><img style="position: absolute; top: 0; left: 0; border: 0;" src="https://camo.githubusercontent.com/567c3a48d796e2fc06ea80409cc9dd82bf714434/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f6c6566745f6461726b626c75655f3132313632312e706e67"
      alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_left_darkblue_121621.png"></a>

</body>

</html>
IT goldman
  • 14,885
  • 2
  • 14
  • 28