Skip to content

Latest commit

 

History

History
366 lines (231 loc) · 10.4 KB

File metadata and controls

366 lines (231 loc) · 10.4 KB

code

  • ❌ 表示不可行
  • ✔️ 表示可行
  • 🔍 表示有待研究

基本概念

模型

当前模型: model-7

model-1

直接将 docsify 的index.html传递给 Webview, 由于安全权限, 有大量的 js, css 文件(本地的或远程的)无法加载

需要原来的路径(orginPath)进行vscode.Uri.file(originPath)替换

model-2

inspired by:How to Build a VS Code extension for Markdown preview using Remark processor

  • server

    以 docsify 的index.html为入口, 建议一个服务端server, 不妨设为http://localhost:3000

  • Webview

    把 Webview 看作客户端一部分

flowchart LR
    subgraph client ["client"]
        Webview[(Webview)]
    end
    server[(server)]
    client --"request"--> server
    server --"html"--> Webview
Loading

基本思路是爬取渲染后的 html 代码, 结果没有成功, 详见request-失败

model-3

inspired by:

核心: 通过 iframe 来解析 server 端的 html

模型转变: 将 Webview 看作服务端的一部分, vscode 看作是客户端

flowchart TB
    subgraph client ["client"]
        vscode[(vscode)]
    end
    subgraph server ["server"]
    direction TB
        Webview[(Webview)]
        localhost[("localhost:3000")]
    end
    vscode --"request"--> Webview
    Webview --"iframe"--> localhost
    Webview --"content"-->vscode
Loading

!> 无法控制 iframe 的元素, 比如说 scroll, 详见cross-origin

  • 收获

    • 实现了页面自动跳转

      可以通过控制 iframe 的链接来进行页面跳转

      当打开 vscode 上面的/ch03/README.md, 只需要设定iframe.src=https://localhost:3000/#/ch03/README.md即可让 Webview 显示对应的渲染网页

model-4

  • 🔍

inspired by:

核心: 在 docsify 的index.html中植入postMessage的代码

flowchart LR

    vscode[(vscode)]

    Webview[(Webview)]
    subgraph localhost["localhost:3000"]
    direction TB
        subgraph index["index.html"]
            injectedCode(("injected code"))
        end
    end

    vscode --"request"--> Webview
    Webview --"iframe"--> localhost
    Webview --"content"-->vscode
    Webview --"iframe.contentWindow.postMessage"--> injectedCode
    injectedCode --"window.parent.postMessage"--> Webview
Loading

我不知道为什么不起作用, 就是 iframe 没有接收到消息, 我没有深入研究 😖 😖 😖

我发现由 iframe 发送消息给父窗口是可行的, 之前不行是因为没有添加'*'参数, 而父窗口发送给 iframe, 我好像也是没有添加'*'参数, 此参数的含义参见MDN Window.postMessage()

window.parent.window.postMessage(
  {
    command: "contextmenu",
  },
  "*"
);

model-5

  • 🔍

inspired by HTTP Server / HTML Preview

核心: 采用 WebSocket 进行通信

flowchart LR

    vscode[(vscode)]
    Webview[(Webview)]
    subgraph localhost["localhost:3000"]
    direction LR
        index["index.html"]
        proxyHtml["proxy.html"]
    end
    proxyHtml --"iframe"-->index
    vscode --"request"--> Webview
    Webview --"iframe"--> localhost
    Webview --"content"-->vscode
    vscode --"socket"--> proxyHtml
    proxyHtml --"socket"--> vscode
Loading

采用了proxy.htmliframeindex.html的方式, proxy.htmlindex.htmlthe same origin, 可以访问iframe.contenWindow.document

!> 但是无法使用http://localhost:3000/#/ch03/README.md的方式进行跳转, 所有的链接与http://localhost:3000/内容相同, 原因是我的proxy.html没有对#/ch03/README.md的处理, 我不会处理 😖 😖 😖

model-6

  • ✔️ -> 0.0.1 - 0.2.2

inspired by live-server

直接 inject 一段代码到index.html

flowchart LR

    vscode[(vscode)]

    Webview[(Webview)]
    subgraph localhost["localhost:3000"]
    direction TB
        subgraph index["index.html"]
            injectedCode(("injected code"))
        end
    end

    vscode --"request"--> Webview
    Webview --"iframe"--> localhost
    Webview --"content"-->vscode
    vscode --"socket"--> injectedCode
    injectedCode --"socket"--> vscode
Loading

采用 proxy 设计模式

flowchart LR
    vscode[(vscode)]
    Webview[(Webview)]
    proxy[(proxy)]
    localhost[("localhost:3000")]
    vscode --"request"--> proxy
    Webview --"iframe"--> localhost
    proxy --"content"-->vscode
    proxy --"scroll sync"--> localhost
    Webview --"content"--> proxy
    proxy --"change url"--> Webview
Loading

碰到问题reload-时-scroll-不起作用

model-7

  • ✔️ -> 1.0.0 - now

结合了 model-5model-6

将 vscode 与 html 的 message 传递分成了两类

  • websocket

    message:

    • markdown saved
  • iframe

    message:

    • scroll sync
    • open the external link

feature

open in browser

!> context menu 是和 document 绑定的, 所以在iframe中捕捉消息

如果在 iframe 中处理 contextmenu 信号, 将导致打开浏览器时候, 也会处理到 contextmenu 信号, 所以, 应该将信号转发给父窗口, 然后打开外部链接

简单使用右键即打开网页

editor syncs with preview

see details here

issue

request-失败

  • 🔍

用 express 搭建了一个服务端http://localhost:3000

  • 想直接通过 express 获取渲染后的 html

    不会 😭 😭 😭, 我搜了很多, 都没搜到类似的问题(I don't know how to explain the issue because my English is far from perfect.)

  • 用爬虫技术

    • request请求http://localhost:3000, http://localhost:3000/#/, 返回的都是 502,请求失败

    • curl get nothing

    • 尝试requestGitHub 建立好的网页, 比如我的 blog: https://dzylikecode.github.io/#/, 但是返回的是index.html的源码, 而不是渲染后的 html 代码

    重要的是, 用浏览器是可以访问http://localhost:3000的, 但是用request就不行

cross-origin

引用iframe.contentWindow.document会报错如下

Uncaught DOMException: Blocked a frame with origin "vscode-webview://19phs4cus40ic26q2jiibe80p036ukca36l2hblkvpa9bnq8dv7g" from accessing a cross-origin frame.

reload-时-scroll-不起作用

  • ✔️

  • 当 scroll scrollbar 时可以正常同步

    执行前 执行后
  • 当 reload 的时候, the position of scrollbar 不正确

    执行前 执行后

这是因为在 window.onload 的时候, docsify 还没有被渲染, 所以 window 的滚动条的范围实际上很小, 基本上为 0

  • 解决方法

    在 docsify 加载完后进行 scroll

    • 采用延时函数,等 docsify 加载

      感觉不太稳定

    • 在 docisfy 加载完的时候执行

      ✨ ✨ ✨

      通过插件的形式植入到 docsify 中, 在 docsify 的 hook.ready 中执行

docsify-插件-ready

  • 同级目录下没有对应 sidebar 文件的 markdown, 链接是不会执行 docsify 的 hook.ready 函数, 所以滚动条会滚动失败

可以尝试使用 hook.mounted 来代替 hook.ready(不可以, 完全失效), 只能添加一个空的 sidebar 文件

setConfiguration

执行以下代码

vscode.workspace
  .getConfiguration("docsifyPreview")
  .update("indexFile", newPath, false);

然后在settings.json中查看, 发现没有更新, 需要过一段时间, 即里面执行下面的代码

vscode.workspace.getConfiguration("docsifyPreview").indexFile;

并没有获得立马更新的值