kiwix / kiwix-android

Kiwix for Android
https://android.kiwix.org
GNU General Public License v3.0
894 stars 447 forks source link

Reader does not support iframes with srcdoc attribute #4084

Open benoit74 opened 6 days ago

benoit74 commented 6 days ago

Describe the bug I have a test ZIM with an iframe with has an srcdoc attribute instead of the classical src (i.e. code is "inline").

The iframe stays blank.

This is the same issue as https://github.com/kiwix/kiwix-apple/issues/1027 but Android-side.

Expected behavior

iFrame content displays

Steps to reproduce the behavior:

Test ZIM: tests_eng_mdn-page_2024-11.zim.zip (remove .zip extension added to please GitHub)

Open the ZIM and see the blank "Output" area

Screenshots

Image

Environment

Logs NA

MohitMaliFtechiz commented 1 day ago

@benoit74, It is a bit weird the HTML content is changing after going to the webView. There is an empty <title> so the whole script is going inside the <title> tag.

The incoming HTML from the ZIM file seems correct.

<!doctype html>
<html lang="en">
<head>

    <!-- WB Insert -->
    <script src="../../../_zim_static/wombat.js"></script>
    <script src="../../../_zim_static/wombatSetup.js"></script>
    <script>
        // Get the current url we are serving from.
        // We cannot know it at zim creation as it depends of our server.
        const current_url = (function () {
          var href = new URL(window.location.href);
          href.hash = "";

          return href.toString();
        })();

        const wbinfo = wombatSetup.getWombatInfo(
          current_url,
          "interactive-examples.mdn.mozilla.net",
          "https",
          "https://interactive-examples.mdn.mozilla.net/pages/tabbed/section.html",
          current_url.substring(0, current_url.length - ("interactive-examples.mdn.mozilla.net/pages/tabbed/section.html".length))
        );

        if (window && window._WBWombatInit) {
          window._WBWombatInit(wbinfo);
        }
    </script>

    <!-- End WB Insert -->
    <meta charset="UTF-8"/>
    <meta http-equiv="x-ua-compatible" content="ie=edge"/>
    <title>HTML Demo: &lt;section></title>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <link href="../../css/codemirror.css%3Fv%3D341af68" rel="stylesheet"/>
    <link href="../../css/editor-tabbed.css%3Fv%3D341af68" rel="stylesheet"/>
</head>

<body>
<header class="output-header border-rounded-top">
    <h4 class="output-heading">HTML Demo: &lt;section></h4>
    <button id="reset" class="reset" type="button">Reset</button>
</header>
<noscript>
    <div id="warning-no-script" class="warning-container">
        <div class="warning">
            The interactive example cannot be shown because JavaScript is
            disabled.
        </div>
    </div>
</noscript>
<div id="warning-mathml-not-supported" class="warning-container hidden">
    <div class="warning">
        The interactive example cannot be shown because MathML is not supported
        by your browser.
    </div>
</div>
<div id="editor-container" class="editor-container tabbed-standard hidden border-rounded-bottom"
     data-editor-type="tabbed">
    <section id="tab-container" class="tabs">
        <div class="tab-list" id="tablist" role="tablist">
            <button role="tab" aria-selected="false" aria-controls="html-panel" id="html"
                    class="hidden">
                HTML
            </button>
            <button role="tab" aria-selected="false" aria-controls="css-panel" id="css"
                    class="hidden" tabindex="-1">
                CSS
            </button>
            <button role="tab" aria-selected="false" aria-controls="js-panel" id="js" class="hidden"
                    tabindex="-1">
                JavaScript
            </button>
        </div>
        <section id="html-panel" tabindex="0" role="tabpanel" aria-labelledby="html" class="hidden"
                 aria-hidden="true">
            <div id="html-editor">
                                                                                                                <pre><code>&lt;h1>Choosing an Apple&lt;/h1>
                                                                                                    &lt;section>
                                                                                                      &lt;h2>Introduction&lt;/h2>
                                                                                                      &lt;p>This document provides a guide to help with the important task of choosing the correct Apple.&lt;/p>
                                                                                                    &lt;/section>

                                                                                                    &lt;section>
                                                                                                      &lt;h2>Criteria&lt;/h2>
                                                                                                      &lt;p>
                                                                                                        There are many different criteria to be considered when choosing an Apple — size, color, firmness, sweetness,
                                                                                                        tartness...
                                                                                                      &lt;/p>
                                                                                                    &lt;/section>
                                                                                                    </code></pre>
            </div>
        </section>
        <section id="css-panel" tabindex="0" role="tabpanel" aria-labelledby="css" class="hidden"
                 aria-hidden="true">
            <div id="css-editor">
                                                                                                                <pre>
                                                                                                                <code>h1,
                                                                                                    h2 {
                                                                                                      margin: 0;
                                                                                                    }
                                                                                                    </code>
                                                                                                    </pre>
            </div>
        </section>
        <section id="js-panel" tabindex="0" role="tabpanel" aria-labelledby="js" class="hidden"
                 aria-hidden="true">
            <div id="js-editor">
                <pre><code></code></pre>
            </div>
        </section>
    </section>
    <div id="output" class="output-container">
        <h4 class="output-label">Output</h4>
        <iframe id="output-iframe"></iframe>
    </div>
</div>

<section class="console-container hidden" aria-hidden="true">
    <h4 class="console-label">Console Output</h4>
    <button type="button" id="clear" class="clear">
        <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 877.714 1024" class="icon-clear">
            <path class="path0" fill="currentColor"
                  d="M749.714 510.286c0-62.286-18.286-120-49.714-168.571L269.143 772.001c49.143 32 107.429 50.857 169.714 50.857 171.429 0 310.857-140 310.857-312.571zM178.857 681.143l431.429-430.857c-49.143-33.143-108-52-171.429-52-171.429 0-310.857 140-310.857 312 0 63.429 18.857 121.714 50.857 170.857zm698.857-170.857c0 243.429-196.571 440.571-438.857 440.571S0 753.714 0 510.286c0-242.857 196.571-440 438.857-440s438.857 197.143 438.857 440z"/>
        </svg>
        clear console
    </button>
    <div id="console" class="console"><code></code></div>
</section>
<template id="output-body">
    <div id="html-output" class="output editor-tabbed">
        %html-content%
    </div>

    <script>
        function executeExample() {
          'use script';
          try {
          %js-content%
          } catch(e) {
            console.error(e);
          }
        }
    </script>
</template>
<template id="output-head">
    <meta charset="UTF-8" />
    <title></title>
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link href="../../css/editor-tabbed.css%3Fv%3D341af68" rel="stylesheet" />
    <style>

    </style>
    <style id="css-output">
      %css-content%
    </style>
</template>
<script src="../../js/codemirror.js%3Fv%3D341af68"></script>
<script src="../../js/editor-tabbed.js%3Fv%3D341af68"></script>
</body>
</html>

and the HTML that is changing is this which is inside the srcdoc.

<template id="output-head">
    <meta charset="UTF-8" />
    <title></title>
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link href="../../css/editor-tabbed.css%3Fv%3D341af68" rel="stylesheet" />
    <style>

    </style>
    <style id="css-output">
      %css-content%
    </style>
</template>
<template id="output-body">
    <div id="html-output" class="output editor-tabbed">
        %html-content%
    </div>

    <script>
        function executeExample() {
          'use script';
          try {
          %js-content%
          } catch(e) {
            console.error(e);
          }
        }
    </script>
</template>

The output-head is changing after going into the webView. It becomes this.

<iframe id="output-iframe" srcdoc="
<!DOCTYPE html>
<html id=&quot;output-root&quot;>
<head>
      <meta charset=&quot;UTF-8&quot;>
      <meta http-equiv=&quot;x-ua-compatible&quot; content=&quot;ie=edge&quot;>
      <title><..editor-tabbed.css%3Fv%3D341af68&quot; rel=&quot;stylesheet&quot;>
      <style>

      <style>
    </head>
<body>
      <div id=&quot;html-output&quot; class=&quot;output editor-tabbed&quot;>
        <h1>Choosing an Apple</h1>
<section>
  <h2>Introduction</h2>
  <p>This document provides a guide to help with the important task of choosing the correct Apple.</p>
</section>

<section>
  <h2>Criteria</h2>
  <p>
    There are many different criteria to be considered when choosing an Apple — size, color, firmness, sweetness,
    tartness...
  </p>
</section>

      <script>
    </body>
</html>
"></iframe>

Image

As you can see there are two <style> tags but without closing tags. Also, there <link> is going inside the <title> tag, and the closing </title> tag is missing. Because of these issues, the content is not displaying.

If I properly close these tags the content starts displaying.

Image

So it might be two issues, either the issue is inside the script from where this HTML code is changing(editor-tabbed.js) since from here we are changing the HTML.

Image

or it is a webView problem it is not reading the content.

So I have started my research on this and found there is an empty title tag in the <template id="output-head"> which causing the problem. If I remove the title tag from the ZIM content then it starts the loading content.

Image

but still, you can see the example is not perfectly working, there is h1,h2 { margin: 100; } showing in the output which is wrong. It is because of style tag is going inside the link tag as you can see.

Image

So now we know the title tag is not creating a problem the problem is something else.

If I look at the loaded content in webView it is correctly loading as you can see in the below screenshots,

With title tag Without Title tag
Image Image

But after changing it via script the output-head HTML is corrupted. So there is some issue inside the script which is causing this error.

benoit74 commented 1 day ago

Thank you for the detailed analysis and feedback!

It is a bit weird the HTML content is changing after going to the webView.

This is unfortunately the original website behavior, and it is kept unmodified in the ZIM.

What is weird is that the same ZIM works in all other Kiwix readers (besides Apple which had also an issue but it is mostly solved now), so HTML/JS code is probably not that bad.

Can you please try to load original URL https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section into a Webview and see if we have the same problem or not? It could help to indicate it is a bug linked to bad cooperation between MDN code and the webview, or if we have a problem more linked to wombat / warc2zim / specific code path on Android webview in the JS (would be weird, but why not ...). Thanks

MohitMaliFtechiz commented 1 day ago

@benoit74 Directly loading the original URL in webView working fine. So it is not a compatibility issue with webView.

Image

Image