内联PDF预览

太好了!谢谢 @Johani。我可以确认它现在在所有 3 个浏览器中都能正常工作。

4 个赞

太棒了——这些是扎实的改进,显然需要付出大量努力才能实现。感谢倾听我们这些在自托管世界中略显烦人的共谋者!

现在该组件是否支持 S3 上传?

3 个赞

我尚未测试过,但如果您的存储桶配置正确,它应该可以正常工作。该组件会发起一个 请求 来加载 PDF。

在 JavaScript 中发起的此类请求,如果源未被允许访问该文件,则会被阻止。随后您会遇到 CORS 错误。如果您检查控制台,可能会看到类似以下内容。

image

该组件对此无能为力。所有处理都必须在您的 S3 配置中完成。必须允许源(即您的 Discourse 域名)发起此类请求,以避免 CORS 问题。

9 个赞

谢谢!我稍后会勇敢地重新尝试 S3。

另一个建议:文件名前加空格时按 Tab 键处理

我希望 PDF 默认以内联方式显示,如果文件名中包含空格,则在新标签页中打开。这样作者可以针对每个 PDF 选择内联或标签页模式,而不是针对每个组件进行选择。

或许组件设置应改为“您希望默认行为是什么?”,如果文件名中包含空格,则采用另一种行为。

或者,您也可以询问空格应执行的操作(内联 / 标签页 / 下载)。

2 个赞

啊!Chrome 又只显示灰色方框了。Firefox 和 Safari 正常。

3 个赞

这个主题组件是否将 PDF 发送到外部解释器?
我已启用“安全媒体”,因为我想避免文件被外部服务加载。

1 个赞

我发现这是因为以下代码:

<a class="attachment pdf-attachment" href="...pdf">doc.pdf
  <iframe src="blob:... " height="500" loading="lazy" class="pdf-preview">
  </iframe>
</a>

如果您将上述代码替换为以下内容:

<a class="attachment pdf-attachment" href="...pdf">doc.pdf</a>
<iframe src="blob:... " height="500" loading="lazy" class="pdf-preview"></iframe>

它就能正常工作。
但我不确定如何在现有代码中修复此问题。

5 个赞

@Johani
该错误与以下代码的第 34 至 41 行相关:

        const setUpPreviewType = (pdf) => {
          if (previewMode === "Inline") {
            const preview = createPreviewElement();
            pdf.classList.add("pdf-attachment");
            pdf.append(preview);

            return preview;
          }
4 个赞

此解决方案似乎适用于所有浏览器。

4 个赞

pdf.parentNode.append(preview); 似乎可以解决问题(但在有多个 PDF 的情况下,预览会显示在所有链接下方,而不是每个链接下方)。

3 个赞

但如果父节点是段落,那么这就不应该是个问题,因为链接和 iframe 将位于段落标签内。

因此,要绕过此问题,您只需在附件之间添加一个换行符:

[doc1.pdf|attachment](...)

[doc2.pdf|attachment](...)

使用您的解决方案后,PDF 预览在 Chrome 中也能正确显示。

3 个赞

我刚提交了一些更改。

是的,这比直接忽略文件更合理。更新后的工作流程如下:

  1. 如果将设置设为“新标签页”,该组件不会在帖子中附加任何预览。点击链接时,PDF 将在新标签页中打开。

  2. 如果将设置设为“内联”,该组件默认会在帖子中为所有 PDF 附加预览。如果文件名以空格开头,则不会附加预览,但点击链接时 PDF 会在新标签页中打开,而不是直接下载。

    所有原生浏览器 PDF 查看器都提供下载按钮,因此如果需要,您可以从那里下载。

感谢 @sharewoodsDavid 提供的调试信息和细节。原来 <iframe> 标签作为 <a> 标签的后代会导致验证失败。

元素 iframe 不得作为 a 元素的后代出现

因此,您的修复非常准确。我已在上述 PR 中进行了相应更改。

如果您想在某个元素之后添加另一个元素,可以使用 after(),示例如下:

someElement.after(newElement)

如果您想在某个元素之前添加另一个元素,可以使用 insertBefore(),示例如下:

// parentNode:您希望在其之前插入元素的父节点
// newNode:您希望插入的元素
// referenceNode:您希望在其之前插入元素的参考节点

parentNode.insertBefore(newNode, referenceNode)

不是。此过程不涉及任何外部服务。工作原理如下:

  1. 用户访问包含 PDF 附件的帖子。
  2. 用户的浏览器请求该附件。
  3. 服务器将其发送给用户的浏览器。
  4. 用户的浏览器使用内置 PDF 查看器读取该文件。

仅此而已。

7 个赞

完美 - 谢谢 @Johani。确认在 Chrome、Firefox 和 Safari 中均可用。:+1:

3 个赞

太棒了!非常感谢。我已经安装并运行成功了!正是我想要的。

5 个赞

这是否会追溯到论坛中已发布的 PDF?

2 个赞

我在测试站点上进行了测试,发现它也适用于现有的,无需“重新生成 HTML”。:+1:

6 个赞

上周我在源代码中看到了一次更新,所以我猜这个组件是活动的。但遗憾的是,它在任何浏览器上都从未对我起作用。是因为“媒体设置”安全吗?\n\n我是唯一一个无法使其工作的人,还是这是一个常见问题?

2 个赞

对我来说也从未奏效过。

2 个赞

该组件运行良好。您看到什么问题/错误?

3 个赞

我只看到了一个普通的下载链接。我没有深入挖掘,因为它对我来说并不重要,只是锦上添花而已。所以,抱歉,我无法提供更多信息。

编辑

好吧,我再次检查了——上次是有些时候了。

DiscourseHub 显示了这个(iPad),Discourse 的日志中没有错误:

但当我尝试使用 Safari 时,它显示了第一页,而不是第二页。

1 个赞