Jelmerro / Vieb

Vim Inspired Electron Browser - Vim bindings for the web by design
https://vieb.dev
GNU General Public License v3.0
1.32k stars 65 forks source link

Reader-Mode Support #247

Closed i3d closed 2 years ago

i3d commented 3 years ago

Checklist

Addition or change Introduce a new native Reader-Mode like how Safari does. This reader mode will allow pages and any links from the start of the reader view to be rendered in specific reader-mode view that's free of distraction/reading-friendly, util ESC is pressed.

Alternatives considered

  1. Using extension. Chrome has some reader view extensions, but almost all of them require interactive togging, or the ones that offer keybindings (e.g. this one https://chrome.google.com/webstore/detail/read-pro/ckjogkiieodbdmkeabpnhdaagilainco), for some reason, the keybinding doesn't seem to work at all. I suspect the layer b/w the chrome keybinding and the vieb layer keybinding is not typically transparent.
  2. Using some online transfer tool (e.g. outline.com/, or some read later sites)... Qutebrowser also doesn't have native reader-mode and some their users are using the online transfer. Since this isn't native, the user will have to config another site as a dependency, it may work at one time but fail the other. It is not a very reliable way to support reader-mode.

FYI, If Vieb's direction is to eventually have a full chrome extension support and let extensions to offer this functionality, then I guess we could also just close this FR.

Jelmerro commented 3 years ago

While Vieb will eventually support more and more extensions, it's a long term project. It's also not something I am personally able to solve or implement, and as such the progress is tracked in #130. With this in mind, I think a reader mode inside Vieb would be nice to have. I think this package might make it fairly easy to implement this, but I'll have a proper look later this week.

i3d commented 3 years ago

Thanks very much in considering! No pressure at all.

Jelmerro commented 3 years ago

After some work using the readability library, I came up with the following implementation. There are a couple of issues with this:

So while this "works", the code is not great and I'm sure there must be a better way to display the readability library results on the page that either isn't documented or requires another library of some sort, because writing this from scratch seems like an entire project in and of itself.

const toggleReaderMode = () => {
    if (document.body.querySelector(".vieb-reader-mode-base")) {
        document.body.querySelector(".vieb-reader-mode-base").remove()
        return
    }
    const {Readability} = require("@mozilla/readability")
    const r = new Readability(document.cloneNode(true), {"disableJSONLD": true})
    const parsed = r.parse()
    const settingsFile = joinPath(
        ipcRenderer.sendSync("appdata-path"), "webviewsettings")
    const settings = readJSON(settingsFile) || {}
    const readerEl = document.createElement("div")
    readerEl.className = "vieb-reader-mode-base"
    const titleEl = document.createElement("div")
    titleEl.textContent = parsed.title
    titleEl.className = "title"
    readerEl.appendChild(titleEl)
    const contentEl = document.createElement("div")
    contentEl.innerHTML = parsed.content
    contentEl.className = "content"
    readerEl.appendChild(contentEl)
    const styleEl = document.createElement("style")
    styleEl.textContent = `
    html, body {
        overflow: hidden !important;
    }
    .vieb-reader-mode-base {
        font-size: ${settings.fontsize || "14"}px;z-index: 999999;
        text-align: center;position: fixed;top: 0;bottom: 0;left: 0;right: 0;
        background: ${settings.bg || "#333"};color: ${settings.fg || "#eee"};
        height: 100vh;overflow: auto;
    }
    .vieb-reader-mode-base .title {
        min-width: 450px;width: 50vw;margin: auto;font-size: 5em;
    }
    .vieb-reader-mode-base .content {
        min-width: 450px;width: 50vw;margin: auto;
    }
    .vieb-reader-mode-base img {
        min-width: 450px;max-width: none;width: 50vw;margin: auto;
        min-height: none;max-height: none;height: auto;
    }`
    readerEl.appendChild(styleEl)
    document.body.appendChild(readerEl)
}

For now I won't continue on this myself, if somebody knows the missing link to display the readability results nicely, feel free to use the above code for parsing the page and creating a PR based on that.

Jelmerro commented 2 years ago

I implemented a readerview in the new 8.0.0 release!