Text HTML gadget does not render content

XMLWordPrintable

    • Type: Bug
    • Resolution: Fixed
    • Priority: Highest
    • 9.4.26
    • Affects Version/s: 7.0.2, 8.20.30, 9.4.23, 9.6.0, 9.7.0, 9.8.0
    • Component/s: Dashboard & Gadgets
    • 7
    • 45
    • Severity 2 - Major
    • 544
    • Hide
      Atlassian Update – Aug 2, 2024

      Hi everyone,

      We are happy to announce that both the Atlassian and Chromium development teams have fixed this bug. The Atlassian-provided patch will be available in Jira Data Center 9.4.26 (JSM DC 5.4.26) and later. To receive the fix, you'll need to upgrade Jira to that version. You can track releases at Jira Software release notes and Jira Service Management release notes. Jira Data Center 9.12 (JSM DC 5.12) is not affected by this bug.

      The Chromium-provided patch is already available in Chrome Canary 129.0.6619.0 and later. This will reach Google Chrome stable and Microsoft Edge according to the respective products' release cadences.

      Show
      Atlassian Update – Aug 2, 2024 Hi everyone, We are happy to announce that both the Atlassian and Chromium development teams have fixed this bug. The Atlassian-provided patch will be available in Jira Data Center 9.4.26 (JSM DC 5.4.26) and later. To receive the fix, you'll need to upgrade Jira to that version. You can track releases at Jira Software release notes and Jira Service Management release notes . Jira Data Center 9.12 (JSM DC 5.12) is not affected by this bug. The Chromium-provided patch is already available in Chrome Canary 129.0.6619.0 and later. This will reach Google Chrome stable and Microsoft Edge according to the respective products' release cadences.

      Steps to Reproduce

      1. Enable the "Text (text-gadget)" module in ⚙️ (gear icon) > Manage apps > Manage apps (all apps) > "Atlassian Jira - Plugins - Gadgets Plugin".
      2. Add a sample Text gadget on a dashboard.
      3. Add sample content and save it:
        <h1>Test</h1>
      4. Refresh the Dashboard page.

      Expected Results

      The content should be rendered.

      Actual Results

      The content may briefly appear and quickly disappear, or not render whatsoever.

      Workaround

      Workaround 1

      Add the following script to the contents of the announcement banner:

      <!-- Workaround for JRASERVER-77886 -->
      <script type='text/javascript'>
      try {
          const auiStyles = '<style>.text-dashboard-item-container {html,body,p,div,h1,h2,h3,h4,h5,h6,img,pre,form,fieldset{margin:0;padding:0;}}.text-dashboard-item-container {ul,ol,dl{margin:0;}}.text-dashboard-item-container {img,fieldset{border:0;}}.text-dashboard-item-container {img:-moz-broken{font-size:inherit;}}.text-dashboard-item-container {details,main,summary{display:block;}}.text-dashboard-item-container {audio,canvas,progress,video{display:inline-block;vertical-align:baseline;}}.text-dashboard-item-container {audio:not([controls]){display:none;height:0;}}.text-dashboard-item-container {[hidden],template{display:none;}}.text-dashboard-item-container {input[type="button"],input[type="submit"],input[type="reset"]{-webkit-appearance:button;}}.text-dashboard-item-container {[lang|=en],body{font-family:Arial,sans-serif;}}.text-dashboard-item-container {body{color:#333;font-size:14px;line-height:1.4285714285714;}}.text-dashboard-item-container {[lang|=ja]{font-family:"Hiragino Kaku Gothic Pro","?????? Pro W3","????",Meiryo,"?? ?????",Verdana,Arial,sans-serif;}}.text-dashboard-item-container {.aui-group,.aui-panel,.aui-tabs,blockquote,dl,form.aui,h1,h2,h3,h4,h5,h6,ol,p,pre,table.aui,ul{margin:10px 0 0;}}.text-dashboard-item-container {.aui-group:first-child,.aui-panel:first-child,.aui-tabs:first-child,blockquote:first-child,dl:first-child,form.aui:first-child,h1:first-child,h2:first-child,h3:first-child,h4:first-child,h5:first-child,h6:first-child,ol:first-child,p:first-child,pre:first-child,table.aui:first-child,ul:first-child{margin-top:0;}}.text-dashboard-item-container {.aui-page-header-hero .aui-page-header-main h1,.aui-page-header-hero .aui-page-header-main h2,.aui-page-header-marketing .aui-page-header-main h1,.aui-page-header-marketing .aui-page-header-main h2,h1{color:#333;font-size:32px;font-weight:400;line-height:1.25;text-transform:none;margin:30px 0 0;}}.text-dashboard-item-container {h2{color:#333;font-size:24px;font-weight:400;line-height:1.25;text-transform:none;margin:30px 0 0;}}.text-dashboard-item-container {.aui-page-header-hero .aui-page-header-main p,.aui-page-header-marketing .aui-page-header-main p,h3{color:#333;font-size:20px;font-weight:400;line-height:1.5;text-transform:none;margin:30px 0 0;}}.text-dashboard-item-container {h4,h5,h6{font-weight:700;margin:20px 0 0;}}.text-dashboard-item-container {h6,small{font-size:12px;}}.text-dashboard-item-container {blockquote,h6,q,small{color:#707070;}}.text-dashboard-item-container {h4{color:#333;font-size:16px;line-height:1.25;text-transform:none;}}.text-dashboard-item-container {h5{color:#333;font-size:14px;line-height:1.42857143;text-transform:none;}}.text-dashboard-item-container {h6{line-height:1.66666667;text-transform:uppercase;}}.text-dashboard-item-container {h1:first-child,h2:first-child,h3:first-child,h4:first-child,h5:first-child,h6:first-child{margin-top:0;}}.text-dashboard-item-container {h1+h2,h2+h3,h3+h4,h4+h5,h5+h6{margin-top:10px;}}.text-dashboard-item-container {.aui-group>.aui-item>h1:first-child,.aui-group>.aui-item>h2:first-child,.aui-group>.aui-item>h3:first-child,.aui-group>.aui-item>h4:first-child,.aui-group>.aui-item>h5:first-child,.aui-group>.aui-item>h6:first-child{margin-top:20px;}}.text-dashboard-item-container {.aui-group:first-child>.aui-item>h1:first-child,.aui-group:first-child>.aui-item>h2:first-child,.aui-group:first-child>.aui-item>h3:first-child,.aui-group:first-child>.aui-item>h4:first-child,.aui-group:first-child>.aui-item>h5:first-child,.aui-group:first-child>.aui-item>h6:first-child{margin-top:0;}}.text-dashboard-item-container {small{line-height:1.3333333333333;}}.text-dashboard-item-container {code,kbd{font-family:monospace;}}.text-dashboard-item-container {address,cite,dfn,var{font-style:italic;}}.text-dashboard-item-container {blockquote{border-left:1px solid #ccc;margin-left:19px;padding:10px 20px;}}.text-dashboard-item-container {blockquote>cite{display:block;margin-top:10px;}}.text-dashboard-item-container {q:before{content:open-quote;}}.text-dashboard-item-container {q:after{content:close-quote;}}.text-dashboard-item-container {abbr{border-bottom:1px #707070 dotted;cursor:help;}}</style>';
      
          if (document.URL.indexOf("/secure/Dashboard.jspa") >= 0) {
              waitForElementToDisplay(".gadget-inline", fixTextGadgets, 1000, 9000);
      
              function fixTextGadgets() {
                  const dashboardId = document.querySelector('meta[name="ajs-dashboard-id"]').content;
                  const textGadgets = extractIDs();
                  const contextPath = AJS.contextPath();
      
                  textGadgets.forEach(id => {
                      $.ajax({
                          url: `${contextPath}/rest/dashboards/1.0/${dashboardId}/gadget/${id}/prefs`,
                          type: "GET",
                          dataType: "json",
                          success: function (data) {
                              const htmlToPaste = htmlDecode(data.fields
                                  .find(obj => obj.name === 'html').value);
                              const gadgetDiv = $(`#gadget-${id}`);
                              gadgetDiv.prepend(auiStyles);
                              gadgetDiv.find('.text-dashboard-item-container').html(htmlToPaste);
                          }
                      })
                  });
              }
      
              function extractIDs() {
                  const divs = document.querySelectorAll('div.gadget-inline');
                  const ids = [];
      
                  divs.forEach(div => {
                      if (div.querySelector('iframe')) {
                          const id = div.id;
                          const match = id.match(/gadget-(\d+)/);
                          if (match) {
                              ids.push(match[1]);
                          }
                      }
                  });
      
                  return ids;
              }
      
              function waitForElementToDisplay(selector, callback, checkFrequencyInMs, timeoutInMs) {
                  const startTimeInMs = Date.now();
                  (function loopSearch() {
                      if (document.querySelector(selector) != null) {
                          callback();
                          return;
                      } else {
                          setTimeout(function () {
                              if (timeoutInMs && Date.now() - startTimeInMs > timeoutInMs)
                                  return;
                              loopSearch();
                          }, checkFrequencyInMs);
                      }
                  })();
              }
      
              function htmlDecode(input) {
                  const doc = new DOMParser().parseFromString(input, "text/html");
                  return doc.documentElement.textContent;
              }
          }
      } catch (error) {
          console.log("[Jira Announcement Banner Custom Script] [ERROR] Failed to re-render the text gadgets: " + error)
      }
      </script>
      

      (Updated 7/24 to reintroduce content styling)

      Workaround 2

      1. Navigate to chrome://flags/#render-document.
      2. Set the "Enable RenderDocument" experiment to disabled.
      3. Restart the browser.

      If your users' browsers are managed, a Google Workspace admin may be able to enforce this via a policy: https://support.google.com/chrome/a/answer/2657289.

      Note

      This is caused by a Chromium bug: https://issues.chromium.org/issues/352352911. The Chromium team fixed this in 129.0.6619.0 and later.

      Jira 9.10+ (JSM 5.10+) is unaffected. The Fix Version will be updated soon, along with news on whether a backport to 9.4 (JSM 5.4) is possible.

        1. image-2024-07-15-18-54-28-250.png
          53 kB
          Sandip Shrivastava

            Assignee:
            Przemyslaw Czuj (Inactive)
            Reporter:
            Sandip Shrivastava
            Votes:
            22 Vote for this issue
            Watchers:
            40 Start watching this issue

              Created:
              Updated:
              Resolved: