mika-cn / maoxian-web-clipper

A web extension to clip information from web page. Save it to your local machine to avoid information invalidation. Not bored registration, Not charged.
MIT License
995 stars 116 forks source link

關於 wiznotePlus 處理 Frame 文件的疑問 #87

Closed mika-cn closed 2 years ago

mika-cn commented 4 years ago

當前的 wiznotePlus 好像漏了處理 Frame 文件,現在我對該文件做了些改動,詳見: https://github.com/mika-cn/maoxian-web-clipper/blob/enhance-storage-paths/src/js/content/input-parser-wiznoteplus.js

主要是一些路徑方面的改動,我把 Frame 文件,放到了 index_files 裏面。不知道 wiznotePlus 那邊能否處理這些文件?

mika-cn commented 4 years ago

@altairwei

altairwei commented 4 years ago

我有空测试下,有结果会在这里跟进

mika-cn commented 4 years ago

你 PR 修復的那個問題,怪我太急發佈,沒等你的反饋。 我現在嘗試發佈一個新版本,不過 chrome 得等三個工作日

altairwei commented 4 years ago

你 PR 修復的那個問題,怪我太急發佈,沒等你的反饋。 我現在嘗試發佈一個新版本,不過 chrome @得等三個工作日

年前太忙,我也没来得及跟进

mika-cn commented 4 years ago

這事還是怪我,感覺在發佈這件事上,還是得慢些來,特別是 google 這麼一搞,一旦有問題,就得暴露問題至少3天。 爬_牆去

mika-cn commented 4 years ago

[1月29更新之后无法保存]https://github.com/mika-cn/maoxian-assistant/issues/2)

altairwei commented 4 years ago

我在思考如果将 input-parser 与各自的 clipper-handler 合并在一起,是否有助于项目的维护?不过这样做会让 Content Script 增加与插件通信的次数。

mika-cn commented 4 years ago

現在各個路徑變量化之後,input-parser 就有點多餘了,確實可以合併到 clipper-handler 裏面去。增加通信次數倒是沒什麼。

在我看來比較理想的情況下是,clipping-handler 可以提供 config。然後擴展設置裏面的配置只適用於 browser 這個 clipping-handler。

其實我覺得 NativeApp,和 WizNotePlus 這兩個 clipping-handler 可以由一個通用 clipping-handler 對接。只是現在 NativeApp 已經和擴展本身耦合很緊,感覺已經分不開了。

這只是我現在想的,就是能使其具備「插件化」,那樣子就會很好維護,擴展本身也可以更開放。也不知道其他軟件的插件是怎麼樣設計的。

altairwei commented 4 years ago

关于 MaoXian WebClipper 架构的插件化,我以前有一些考虑,有空我整理整理思路再跟你讨论下。

我们可以先从粒度最大的抽象层级来理解剪裁插件:选取 => 解析 => 储存。每个抽象层级都制定相应的契约(或者说“接口”),比如 clipping-handler 就位于 “储存” 这一抽象层级,那么 MaoXian Clipper 就可以为 clipping-handler 制定抽象的接口,任何一个具体的 clipping-handler 都必须实现这些接口。

软件设计的最佳实践就是 “高内聚低耦合”,所有关于 “储存” 的代码都由具体的 clipping-handler 负责,这样可能让代码维护起来跟轻松些。

mika-cn commented 4 years ago

了解

altairwei commented 4 years ago

不好意思 mika,我不是很理解 Frame 文件主要是什么情况下出现的?是指 <frame> 标签的内容吗?

mika-cn commented 4 years ago

@altairwei

主要是 <iframe><frame> 標籤。有的網頁會有內嵌的網頁,當保存成 HTML 時候,這些網頁是保存成單獨的文件的(iframe 的內容不好嵌入到主文件,樣式不好處理)。以前是和主文件保存在同一個目錄,現在是允許用戶自己設置存儲位置 。

而如果保存成 Markdown,則這些 iframe 的內容會嵌入到主文件中,Markdown 沒有額外的文件。

altairwei commented 4 years ago

@altairwei

主要是 <iframe><frame> 標籤。有的網頁會有內嵌的網頁,當保存成 HTML 時候,這些網頁是保存成單獨的文件的(iframe 的內容不好嵌入到主文件,樣式不好處理)。以前是和主文件保存在同一個目錄,現在是允許用戶自己設置存儲位置 。

而如果保存成 Markdown,則這些 iframe 的內容會嵌入到主文件中,Markdown 沒有額外的文件。

那这些单独 iframe 文件的 assests 会被储存到哪呢?跟主文件的 assets 一样的位置吗?

mika-cn commented 4 years ago

是的,asset 文件的存儲位置和主文件一樣。

拿目前 input-parser-wiznoteplus.js 來說,裏面和存儲路徑相關的代碼爲:

      // Keep all paths relative to $WIZNOTE_TEMP/webclipping                   
      const storageInfo =  {
          /** the path to place index.html and assetFolder */
          mainFileFolder: clipId,
          mainFileName: mainFilename,
          infoFileFolder: clipId + "/index_files",
          /** the path to place frame files */
          frameFileFolder: clipId + "/index_files",
          /** the path to place asset files */
          assetFolder: clipId + "/index_files",
          /** the path is relative to index.html */
          assetRelativePath: "index_files"
      };

那麼主文件裏面的圖片路徑爲 index_files/image.png,而 frame 文件裏面的圖片路徑爲 image.jpg (因爲 frame 文件和 asset 文件的存儲路徑是同一個目錄 $clipId/index_files)。資源文件是存在同一個地方,而引用路徑不同。

這個 storageInfo 對象裏面的 assetRelativePath 還是指主文件的 asset 文件的相對路徑。Frame 文件使用的 assetRelativePath,會根據 frameFileFolder 和 assetFolder 計算出來 (具體在 content-frame.js 裏面算的)。

altairwei commented 4 years ago

我理解了,而且现在正好碰到一个例子,主体内容都在 iframe 里,正好用来测试

altairwei commented 4 years ago

我查看了下 src/js/capturer/iframe.js 源代码,似乎只有那些拥有 src 属性的 iframe 才会被正确处理?现在我碰到了一个 例子 ,这个页面的所有主要内容都在 iframe 里面,但是 <iframe> 标签没有 src 属性。

这种类型的 iframe 该如何处理呢?

mika-cn commented 4 years ago

你是说通过 Iframe 的 srcdoc 设置的内容,这一种情况?

这种情况目前还没有处理。我留了个 TODO (src/js/capturer/iframe.js)。这种情况和 有 src 属性的这种情况得分开处理。记得当时遇到的困难好像是:很难获取到 iframe 里面的 dom 对象,得抽空去解决这种情况。

altairwei commented 4 years ago

你是说通过 Iframe 的 srcdoc 设置的内容,这一种情况?

这种情况目前还没有处理。我留了个 TODO (src/js/capturer/iframe.js)。这种情况和 有 src 属性的这种情况得分开处理。记得当时遇到的困难好像是:很难获取到 iframe 里面的 dom 对象,得抽空去解决这种情况。

在前面我提到的示例链接里,iframe 没有 src 也没有 srcdoc

mika-cn commented 4 years ago

这种有 srcdoc 属性的 iframe ,和你说的这种直接把内容写上去(这种情况我之前没见到 HTML 文档里有介绍),应该都属于 inline-frame 。为了软件更健壮,这种情况是要处理的。

    // in content script, frameNode.contentWindow is undefined.
    // window.frames includes current layer frames.
    //   firefox: all frames (includes frame outside body node)
    //   chrome: frames inside body node.

    if (srcdoc) {
      // inline iframe
      // assetName = Asset.getNameByContent({content: srcdoc, extension: 'frame.html'});
      // TODO ?
      node.setAttribute('data-mx-warn', 'srcdoc attribute was not captured by MaoXian');
      return {node, tasks};
    }

这是我之前留的注释信息,主要是 in content script, frameNode.contentWindow is undefined。我当时也没有很深入地去尝试,你可以试下看如何解决。

我们需要拿到里面的 window 对象,以便获取一些样式(比如:去除隐藏的元素)

altairwei commented 4 years ago

Content Script 确实没有获取页面 window 对象的访问权限,它跟页面运行在不同的 javascript 上下文中,只拥有 DOM 访问权限。就我想到的解决方法而言,最简单的就是将 <script></script> 注入到 iframe 中,然后这个注入脚本用来获取页面的 window 对象。不过由于我目前对 iframe 处理流程不太熟悉,可能得后面再尝试下。

我先尝试让 clipping-handler-wiznoteplus 处理下拥有 src 属性的 iframe 。

altairwei commented 4 years ago

我用你发给我的 iframe 文档测试了一下,结果如下:

mika-cn commented 2 years ago

最新的版本應該能很好地處理 srcdoc 這種 iframe 了。先關閉該 issue。

altairwei commented 2 years ago

Hello Mika,

我想请教一下你,以下两个行为是否有实现的可能性?

  1. 当选区完全位于 iframe 内部时,把 iframe 的文档剪裁成主要的 html 文档(index.html),而不是当作 assests 处理。
  2. 当选区内存在 iframe 时,将 iframe 文档的 body 内容提取并嵌入主文档,以达到去除 iframe 的目的。