refactor: improve documentation generation

This commit is contained in:
Maddison Hellstrom 2018-11-09 17:47:39 -08:00
parent 1eec6c5644
commit 9a559a143f
8 changed files with 324 additions and 123 deletions

204
README.md
View File

@ -30,21 +30,109 @@ Features
### Site-Specific Key Mappings
Key mappings have been included which can help you perform some common actions
on many popular sites.
181 key mappings for 16 unique
sites have been included which can help you perform some common actions:
Some examples of these mappings are:
- Star the current GitHub/GitLab repository: `<site-leader>s`
- Follow a user on Twitter: `<site-leader>f`
- Upvote a post/comment on Reddit/HackerNews `<site-leader>s`
- Analyze the current Amazon Product using Fakespot `<site-leader>fs`
<table>
<tbody>
<tr><th colspan="2"><strong>global</strong></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>w</code></td><td>Scroll up</td></tr>
<tr><td><code>s</code></td><td>Scroll down</td></tr>
<tr><td><code>gi</code></td><td>Edit current URL with vim editor</td></tr>
<tr><td><code>gi</code></td><td>Edit current URL with vim editor</td></tr>
<tr><td><code>gI</code></td><td>View image in new tab</td></tr>
<tr><td><code>yp</code></td><td>Copy URL path of current page</td></tr>
<tr><td><code>yI</code></td><td>Copy Image URL</td></tr>
<tr><td><code>;se</code></td><td>Edit Settings</td></tr>
<tr><td><code>gS</code></td><td>Open Chrome settings</td></tr>
<tr><td><code>&#x3D;w</code></td><td>Lookup whois information for domain</td></tr>
<tr><td><code>&#x3D;d</code></td><td>Lookup dns information for domain</td></tr>
<tr><td><code>&#x3D;D</code></td><td>Lookup all information for domain</td></tr>
<tr><td><code>;pd</code></td><td>Toggle PDF viewer from SurfingKeys</td></tr>
<tr><th colspan="2"><a href="//amazon.com">amazon.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;fs</code></td><td>Fakespot</td></tr>
<tr><th colspan="2"><a href="//behance.net">behance.net</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;s</code></td><td>Appreciate project</td></tr>
<tr><td><code>&lt;Space&gt;b</code></td><td>Add project to collection</td></tr>
<tr><td><code>&lt;Space&gt;a</code></td><td>View project</td></tr>
<tr><td><code>&lt;Space&gt;A</code></td><td>View project (new tab)</td></tr>
<tr><th colspan="2"><a href="//dribbble.com">dribbble.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;s</code></td><td>Heart Shot</td></tr>
<tr><td><code>&lt;Space&gt;a</code></td><td>View shot</td></tr>
<tr><td><code>&lt;Space&gt;A</code></td><td>View shot (new tab)</td></tr>
<tr><td><code>&lt;Space&gt;v</code></td><td>View attachment image</td></tr>
<tr><td><code>&lt;Space&gt;V</code></td><td>Yank attachment image source URL</td></tr>
<tr><td><code>&lt;Space&gt;z</code></td><td>Zoom shot</td></tr>
<tr><th colspan="2"><a href="//fonts.adobe.com">fonts.adobe.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;a</code></td><td>Activate font</td></tr>
<tr><td><code>&lt;Space&gt;s</code></td><td>Favorite font</td></tr>
<tr><th colspan="2"><a href="//github.com">github.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;a</code></td><td>View Repository</td></tr>
<tr><td><code>&lt;Space&gt;u</code></td><td>View User</td></tr>
<tr><td><code>&lt;Space&gt;f</code></td><td>View File</td></tr>
<tr><td><code>&lt;Space&gt;i</code></td><td>View Issue</td></tr>
<tr><td><code>&lt;Space&gt;gp</code></td><td>Go to parent</td></tr>
<tr><td><code>&lt;Space&gt;s</code></td><td>Toggle Star</td></tr>
<tr><td><code>&lt;Space&gt;S</code></td><td>Check Star</td></tr>
<tr><td><code>&lt;Space&gt;y</code></td><td>Copy Project Path</td></tr>
<tr><td><code>&lt;Space&gt;Y</code></td><td>Copy Project Path (including domain)</td></tr>
<tr><td><code>&lt;Space&gt;D</code></td><td>View GoDoc for Project</td></tr>
<tr><th colspan="2"><a href="//gitlab.com">gitlab.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;s</code></td><td>Toggle Star</td></tr>
<tr><td><code>&lt;Space&gt;y</code></td><td>Copy Project Path</td></tr>
<tr><td><code>&lt;Space&gt;Y</code></td><td>Copy Project Path (including domain)</td></tr>
<tr><td><code>&lt;Space&gt;D</code></td><td>View GoDoc for Project</td></tr>
<tr><th colspan="2"><a href="//google.com">google.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;a</code></td><td>Open search result</td></tr>
<tr><td><code>&lt;Space&gt;A</code></td><td>Open search result (new tab)</td></tr>
<tr><th colspan="2"><a href="//news.ycombinator.com">news.ycombinator.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;x</code></td><td>Collapse comment</td></tr>
<tr><td><code>&lt;Space&gt;X</code></td><td>Collapse next comment</td></tr>
<tr><td><code>&lt;Space&gt;s</code></td><td>Upvote</td></tr>
<tr><td><code>&lt;Space&gt;S</code></td><td>Downvote</td></tr>
<tr><td><code>&lt;Space&gt;a</code></td><td>View post (link)</td></tr>
<tr><td><code>&lt;Space&gt;A</code></td><td>View post (link) (new tab)</td></tr>
<tr><td><code>&lt;Space&gt;c</code></td><td>View post (comments)</td></tr>
<tr><td><code>&lt;Space&gt;C</code></td><td>View post (comments) (new tab)</td></tr>
<tr><td><code>&lt;Space&gt;p</code></td><td>Go to parent</td></tr>
<tr><th colspan="2"><a href="//producthunt.com">producthunt.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;a</code></td><td>View product (external)</td></tr>
<tr><td><code>&lt;Space&gt;v</code></td><td>View product</td></tr>
<tr><td><code>&lt;Space&gt;s</code></td><td>Upvote product</td></tr>
<tr><th colspan="2"><a href="//reddit.com">reddit.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;x</code></td><td>Collapse comment</td></tr>
<tr><td><code>&lt;Space&gt;X</code></td><td>Collapse next comment</td></tr>
<tr><td><code>&lt;Space&gt;s</code></td><td>Upvote</td></tr>
<tr><td><code>&lt;Space&gt;S</code></td><td>Downvote</td></tr>
<tr><td><code>&lt;Space&gt;e</code></td><td>Expand expando</td></tr>
<tr><td><code>&lt;Space&gt;a</code></td><td>View post (link)</td></tr>
<tr><td><code>&lt;Space&gt;A</code></td><td>View post (link) (new tab)</td></tr>
<tr><td><code>&lt;Space&gt;c</code></td><td>View post (comments)</td></tr>
<tr><td><code>&lt;Space&gt;C</code></td><td>View post (comments) (new tab)</td></tr>
<tr><th colspan="2"><a href="//twitter.com">twitter.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;f</code></td><td>Follow user</td></tr>
<tr><td><code>&lt;Space&gt;s</code></td><td>Like tweet</td></tr>
<tr><td><code>&lt;Space&gt;R</code></td><td>Retweet</td></tr>
<tr><td><code>&lt;Space&gt;c</code></td><td>Comment/Reply</td></tr>
<tr><td><code>&lt;Space&gt;t</code></td><td>New tweet</td></tr>
<tr><td><code>&lt;Space&gt;T</code></td><td>Tweet to</td></tr>
<tr><td><code>&lt;Space&gt;r</code></td><td>Load new tweets</td></tr>
<tr><td><code>&lt;Space&gt;g</code></td><td>Goto user</td></tr>
<tr><th colspan="2"><a href="//vimeo.com">vimeo.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;F</code></td><td>Toggle fullscreen</td></tr>
<tr><th colspan="2"><a href="//wikipedia.org">wikipedia.org</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;s</code></td><td>Toggle simple version of current article</td></tr>
<tr><th colspan="2"><a href="//yelp.com">yelp.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>&lt;Space&gt;fs</code></td><td>Fakespot</td></tr>
<tr><th colspan="2"><a href="//youtube.com">youtube.com</a></th></tr><tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>
<tr><td><code>A</code></td><td>Open video</td></tr>
<tr><td><code>C</code></td><td>Open channel</td></tr>
<tr><td><code>gH</code></td><td>Goto homepage</td></tr>
<tr><td><code>F</code></td><td>Toggle fullscreen</td></tr>
<tr><td><code>&lt;Space&gt;</code></td><td>Play/pause</td></tr>
The mappings are activated by typing the `<site-leader>` (`<space>` by default),
followed by the key sequence.
See [keys.js](./keys.js) for all of the mappings.
<!--TODO: Autogenerate list of site mappings-->
</tbody>
</table>
### Bundled Search Engine Completions
@ -55,51 +143,51 @@ You can access a Search Engine auto-completion by pressing the search leader key
For example, to open the Wikipedia completion, you would type `awp` while in normal mode.
| Alias | Name | Domain | Screenshots |
| ---- | ------ | ----- | ----- |
| `af` | `archforums` | `Google Custom Search` | |
| `al` | `archlinux` | `www.archlinux.org` | |
| `au` | `AUR` | `aur.archlinux.org` | |
| `aw` | `archwiki` | `wiki.archlinux.org` | |
| `az` | `amazon` | `smile.amazon.com` | |
| `cl` | `craigslist` | `craigslist.org` | |
| `co` | `crunchbase-orgs` | `www.crunchbase.com` | |
| `cp` | `crunchbase-people` | `www.crunchbase.com` | [:framed_picture:](#crunchbase-people) |
| `cs` | `chromestore` | `chrome.google.com` | |
| `de` | `define` | `onelook.com` | [:framed_picture:](#define) |
| `dg` | `duckduckgo` | `duckduckgo.com` | |
| `dh` | `dockerhub` | `hub.docker.com` | [:framed_picture:](#dockerhub) |
| `do` | `domainr` | `domainr.com` | [:framed_picture:](#domainr) |
| `eb` | `ebay` | `www.ebay.com` | |
| `ex` | `exdocs` | `hex.pm` | |
| `gd` | `godoc` | `godoc.org` | |
| `gg` | `golang` | `Google Custom Search` | |
| `gh` | `github` | `github.com` | [:framed_picture:](#github) |
| `gi` | `google-images` | `www.google.com` | |
| `gl` | `google-lucky` | `www.google.com` | |
| `go` | `google` | `www.google.com` | |
| `gs` | `go-search` | `go-search.org` | |
| `gw` | `gowalker` | `gowalker.org` | |
| `ha` | `hackage` | `hackage.haskell.org` | |
| `hd` | `hexdocs` | `hex.pm` | |
| `hn` | `hackernews` | `hn.algolia.com` | [:framed_picture:](#hackernews) |
| `ho` | `hoogle` | `www.haskell.org` | [:framed_picture:](#hoogle) |
| `hw` | `haskellwiki` | `wiki.haskell.org` | |
| `hx` | `hex` | `hex.pm` | |
| `hy` | `hayoo` | `hayoo.fh-wedel.de` | |
| `jq` | `jquery` | `Google Custom Search` | |
| `md` | `mdn` | `developer.mozilla.org` | [:framed_picture:](#mdn) |
| `no` | `node` | `Google Custom Search` | |
| `np` | `npm` | `www.npmjs.com` | [:framed_picture:](#npm) |
| `ow` | `owasp` | `www.owasp.org` | |
| `re` | `reddit` | `www.reddit.com` | |
| `so` | `stackoverflow` | `stackoverflow.com` | |
| `th` | `thesaurus` | `www.onelook.com` | [:framed_picture:](#thesaurus) |
| `vw` | `vimwikia` | `vim.wikia.com` | |
| `wa` | `wolframalpha` | `www.wolframalpha.com` | [:framed_picture:](#wolframalpha) [:framed_picture:](#wolframalpha-2) |
| `wp` | `wikipedia` | `en.wikipedia.org` | |
| `ws` | `wikipedia-simple` | `simple.wikipedia.org` | |
| `yp` | `yelp` | `www.yelp.com` | |
| `yt` | `youtube` | `www.youtube.com` | [:framed_picture:](#youtube) |
| ----- | ---- | ------ | ----------- |
| `af` | `archforums` | `Google Custom Search` | |
| `al` | `archlinux` | `www.archlinux.org` | |
| `au` | `AUR` | `aur.archlinux.org` | |
| `aw` | `archwiki` | `wiki.archlinux.org` | |
| `az` | `amazon` | `smile.amazon.com` | |
| `cl` | `craigslist` | `craigslist.org` | |
| `co` | `crunchbase-orgs` | `www.crunchbase.com` | |
| `cp` | `crunchbase-people` | `www.crunchbase.com` | [:framed_picture:](#crunchbase-people) |
| `cs` | `chromestore` | `chrome.google.com` | |
| `de` | `define` | `onelook.com` | [:framed_picture:](#define) |
| `dg` | `duckduckgo` | `duckduckgo.com` | |
| `dh` | `dockerhub` | `hub.docker.com` | [:framed_picture:](#dockerhub) |
| `do` | `domainr` | `domainr.com` | [:framed_picture:](#domainr) |
| `eb` | `ebay` | `www.ebay.com` | |
| `ex` | `exdocs` | `hex.pm` | |
| `gd` | `godoc` | `godoc.org` | |
| `gg` | `golang` | `Google Custom Search` | |
| `gh` | `github` | `github.com` | [:framed_picture:](#github) |
| `gi` | `google-images` | `www.google.com` | |
| `gl` | `google-lucky` | `www.google.com` | |
| `go` | `google` | `www.google.com` | |
| `gs` | `go-search` | `go-search.org` | |
| `gw` | `gowalker` | `gowalker.org` | |
| `ha` | `hackage` | `hackage.haskell.org` | |
| `hd` | `hexdocs` | `hex.pm` | |
| `hn` | `hackernews` | `hn.algolia.com` | [:framed_picture:](#hackernews) |
| `ho` | `hoogle` | `www.haskell.org` | [:framed_picture:](#hoogle) |
| `hw` | `haskellwiki` | `wiki.haskell.org` | |
| `hx` | `hex` | `hex.pm` | |
| `hy` | `hayoo` | `hayoo.fh-wedel.de` | |
| `jq` | `jquery` | `Google Custom Search` | |
| `md` | `mdn` | `developer.mozilla.org` | [:framed_picture:](#mdn) |
| `no` | `node` | `Google Custom Search` | |
| `np` | `npm` | `www.npmjs.com` | [:framed_picture:](#npm) |
| `ow` | `owasp` | `www.owasp.org` | |
| `re` | `reddit` | `www.reddit.com` | |
| `so` | `stackoverflow` | `stackoverflow.com` | |
| `th` | `thesaurus` | `www.onelook.com` | [:framed_picture:](#thesaurus) |
| `vw` | `vimwikia` | `vim.wikia.com` | |
| `wa` | `wolframalpha` | `www.wolframalpha.com` | [:framed_picture:](#wolframalpha) [:framed_picture:](#wolframalpha-2) |
| `wp` | `wikipedia` | `en.wikipedia.org` | |
| `ws` | `wikipedia-simple` | `simple.wikipedia.org` | |
| `yp` | `yelp` | `www.yelp.com` | |
| `yt` | `youtube` | `www.youtube.com` | [:framed_picture:](#youtube) |
Installation

View File

@ -24,21 +24,14 @@ Features
### Site-Specific Key Mappings
Key mappings have been included which can help you perform some common actions
on many popular sites.
<!--{{KEYS_MAPS_COUNT}}--> key mappings for <!--{{KEYS_SITES_COUNT}}--> unique
sites have been included which can help you perform some common actions:
Some examples of these mappings are:
- Star the current GitHub/GitLab repository: `<site-leader>s`
- Follow a user on Twitter: `<site-leader>f`
- Upvote a post/comment on Reddit/HackerNews `<site-leader>s`
- Analyze the current Amazon Product using Fakespot `<site-leader>fs`
The mappings are activated by typing the `<site-leader>` (`<space>` by default),
followed by the key sequence.
See [keys.js](./keys.js) for all of the mappings.
<!--TODO: Autogenerate list of site mappings-->
<table>
<tbody>
<!--{{KEYS_TABLE}}-->
</tbody>
</table>
### Bundled Search Engine Completions
@ -49,7 +42,7 @@ You can access a Search Engine auto-completion by pressing the search leader key
For example, to open the Wikipedia completion, you would type `awp` while in normal mode.
| Alias | Name | Domain | Screenshots |
| ---- | ------ | ----- | ----- |
| ----- | ---- | ------ | ----------- |
<!--{{COMPL_TABLE}}-->
Installation

View File

@ -1,6 +1,7 @@
const ghReservedNames = require("github-reserved-names")
const util = require("./util")
const Hints = require("./hints")
const actions = {}
@ -10,17 +11,17 @@ const actions = {}
// URL Manipulation/querying
// -------------------------
actions.vimEditURL = () => Front
.showEditor(window.location.href, (data) => {
window.location.href = data
.showEditor(util.getCurrentLocation(), (url) => {
actions.openLink(url)()
}, "url")
actions.getURLPath = ({ count = 0, domain = false } = {}) => {
let path = window.location.pathname.slice(1)
let path = util.getCurrentLocation("pathname").slice(1)
if (count) {
path = path.split("/").slice(0, count).join("/")
}
if (domain) {
path = `${window.location.hostname}/${path}`
path = `${util.getCurrentLocation("hostname")}/${path}`
}
return path
}
@ -32,16 +33,18 @@ actions.copyURLPath = ({ count, domain } = {}) =>
// ----------------
const domainDossierUrl = "http://centralops.net/co/DomainDossier.aspx"
actions.showWhois = ({ hostname = window.location.hostname } = {}) =>
() => tabOpenLink(`${domainDossierUrl}?dom_whois=true&addr=${hostname}`)
actions.showWhois = ({ hostname = util.getCurrentLocation("hostname") } = {}) =>
() => actions.openLink(`${domainDossierUrl}?dom_whois=true&addr=${hostname}`, { newTab: true })()
actions.showDns = ({ hostname = window.location.hostname, verbose = false } = {}) =>
actions.showDns = ({ hostname = util.getCurrentLocation("hostname"), verbose = false } = {}) =>
() => {
let u = ""
if (verbose) {
tabOpenLink(`${domainDossierUrl}?dom_whois=true&dom_dns=true&traceroute=true&net_whois=true&svc_scan=true&addr=${hostname}`)
u = `${domainDossierUrl}?dom_whois=true&dom_dns=true&traceroute=true&net_whois=true&svc_scan=true&addr=${hostname}`
} else {
tabOpenLink(`${domainDossierUrl}?dom_dns=true&addr=${hostname}`)
u = `${domainDossierUrl}?dom_dns=true&addr=${hostname}`
}
actions.openLink(u, { newTab: true })()
}
// Surfingkeys-specific actions
@ -49,9 +52,18 @@ actions.showDns = ({ hostname = window.location.hostname, verbose = false } = {}
actions.createHint = (selector, action = Hints.dispatchMouseClick) =>
() => Hints.create(selector, action)
actions.open = ({ newTab = false, prop = "href" } = {}) => a => window.open(a[prop], newTab ? "_BLANK" : undefined)
actions.openAnchor = ({ newTab = false, prop = "href" } = {}) =>
a => actions.openLink(a[prop], { newTab })()
actions.editSettings = () => tabOpenLink("/pages/options.html")
actions.openLink = (u, { newTab = false } = {}) =>
() => {
if (window === undefined) {
return
}
window.open(u, newTab ? "_blank" : "_self")
}
actions.editSettings = actions.openLink("/pages/options.html", { newTab: true })
actions.togglePdfViewer = () =>
chrome.storage.local.get("noPdfViewer", (resp) => {
@ -71,18 +83,19 @@ actions.togglePdfViewer = () =>
// FakeSpot
// --------
actions.fakeSpot = (url = window.location.href) => tabOpenLink(`http://fakespot.com/analyze?url=${url}`)
actions.fakeSpot =
(url = util.getCurrentLocation("href")) => actions.openLink(`http://fakespot.com/analyze?url=${url}`, { newTab: true })()
// Godoc
// -----
actions.viewGodoc = () =>
tabOpenLink(`https://godoc.org/${actions.getURLPath({ count: 2, domain: true })}`)
actions.openLink(`https://godoc.org/${actions.getURLPath({ count: 2, domain: true })}`, { newTab: true })()
// GitHub
// ------
actions.gh = {}
actions.gh.star = ({ toggle = false } = {}) => () => {
const repo = window.location.pathname.slice(1).split("/").slice(0, 2).join("/")
const repo = util.getCurrentLocation("pathname").slice(1).split("/").slice(0, 2).join("/")
const container = document.querySelector("div.starring-container")
const status = container.classList.contains("on")
@ -113,13 +126,14 @@ actions.gh.openRepo = () => {
const u = new URL(a.href)
const [user, repo, ...rest] = u.pathname.split("/").filter(s => s !== "")
return (
u.origin === window.location.origin &&
u.origin === util.getCurrentLocation("origin") &&
u.hash === "" &&
u.search === "" &&
typeof user === "string" &&
user.length > 0 &&
typeof repo === "string" &&
repo.length > 0 &&
rest.length === 0 &&
repo.length >= 1 &&
/^([a-zA-Z0-9]+-?)+$/.test(user) &&
!ghReservedNames.check(user)
)
@ -133,10 +147,11 @@ actions.gh.openUser = () => {
const u = new URL(a.href)
const [user, ...rest] = u.pathname.split("/").filter(s => s !== "")
return (
u.origin === window.location.origin &&
u.origin === util.getCurrentLocation("origin") &&
u.hash === "" &&
u.search === "" &&
typeof user === "string" &&
user.length > 0 &&
rest.length === 0 &&
/^([a-zA-Z0-9]+-?)+$/.test(user) &&
!ghReservedNames.check(user)
@ -151,10 +166,13 @@ actions.gh.openFile = () => {
const u = new URL(a.href)
const [user, repo, maybeBlob, ...rest] = u.pathname.split("/").filter(s => s !== "")
return (
u.origin === window.location.origin &&
u.origin === util.getCurrentLocation("origin") &&
u.hash === "" &&
u.search === "" &&
typeof user === "string" &&
user.length > 0 &&
typeof repo === "string" &&
repo.length > 0 &&
typeof maybeBlob === "string" &&
( maybeBlob === "blob" || maybeBlob === "tree" ) &&
rest.length !== 0 &&
@ -165,9 +183,33 @@ actions.gh.openFile = () => {
Hints.create(elements, Hints.dispatchMouseClick)
}
actions.gh.openIssue = () => {
const elements = [...document.querySelectorAll("a[href]")]
.filter(a => {
const u = new URL(a.href)
const [user, repo, maybeIssues, maybeIssueNum, ...rest] = u.pathname.split("/").filter(s => s !== "")
return (
u.origin === util.getCurrentLocation("origin") &&
u.hash === "" &&
u.search === "" &&
typeof user === "string" &&
user.length > 0 &&
typeof repo === "string" &&
repo.length > 0 &&
maybeIssues === "issues" &&
typeof maybeIssueNum === "string" &&
maybeIssueNum.length > 0 &&
/^([a-zA-Z0-9]+-?)+$/.test(user) &&
!ghReservedNames.check(user)
)
})
Hints.create(elements, Hints.dispatchMouseClick)
}
actions.gh.goParent = () => {
const segments = window.location.pathname
const segments = util.getCurrentLocation("pathname")
.split("/").filter(s => s !== "")
console.log(`goParent: ${segments}`)
const newPath = (() => {
const [user, repo, maybeBlob] = segments
switch(segments.length) {
@ -188,8 +230,11 @@ actions.gh.goParent = () => {
}
return segments.slice(0, segments.length - 1)
})()
console.log(`newPath: ${newPath}`)
if(newPath !== false) {
window.location.assign(`${window.location.origin}/${newPath.join("/")}`)
const u = `${util.getCurrentLocation("origin")}/${newPath.join("/")}`
console.log(`newPath u: ${u}`)
actions.openLink(u)()
}
}
@ -197,7 +242,7 @@ actions.gh.goParent = () => {
// ------
actions.gl = {}
actions.gl.star = () => {
const repo = window.location.pathname.slice(1).split("/").slice(0, 2).join("/")
const repo = util.getCurrentLocation("pathname").slice(1).split("/").slice(0, 2).join("/")
const btn = document.querySelector(".btn.star-btn > span")
btn.click()
const action = `${btn.textContent.toLowerCase()}red`
@ -242,7 +287,7 @@ actions.hn.goParent = () => {
if (!par) {
return
}
window.location.assign(par.href)
actions.openLink(par.href)()
}
actions.hn.collapseNextComment = () => {
@ -258,20 +303,25 @@ actions.hn.collapseNextComment = () => {
actions.ph = {}
actions.ph.openExternal = () => {
Hints.create("ul[class^='postsList_'] > li > div[class^='item_']", p =>
tabOpenLink(p.querySelector("div[class^='meta_'] > div[class^='actions_'] > div[class^='minorActions_'] > a:nth-child(1)").href))
actions.openLink(
p.querySelector("div[class^='meta_'] > div[class^='actions_'] > div[class^='minorActions_'] > a:nth-child(1)").href
, { newTab: true }
)()
)
}
// Dribbble
// --------
actions.dr = {}
actions.dr.attachment = (cb = a => tabOpenLink(a)) =>
actions.dr.attachment = (cb = a => actions.openLink(a, { newTab: true })()) =>
actions.createHint(".attachments .thumb", a => cb(a.src.replace("/thumbnail/", "/")))
// Wikipedia
// ---------
actions.wp = {}
actions.wp.toggleSimple = () => {
window.location.hostname = window.location.hostname.split(".")
const u = new URL(util.getCurrentLocation("href"))
u.hostname = u.hostname.split(".")
.map((s, i) => {
if (i === 0) {
return s === "simple" ? "" : "simple"

16
conf.js
View File

@ -3,12 +3,11 @@ const keys = require("./keys")
const completions = require("./completions")
// ---- Settings ----//
settings.hintAlign = "left"
settings.omnibarSuggestionTimeout = 500
settings.richHintsForKeystroke = 1
// ---- Theme ----//
settings.theme = `
util.addSettings({
hintAlign : "left",
omnibarSuggestionTimeout : 500,
richHintsForKeystroke : 1,
theme: `
/* Disable RichHints CSS animation */
.expandRichHints {
animation: 0s ease-in-out 1 forwards expandRichHints;
@ -16,7 +15,8 @@ settings.theme = `
.collapseRichHints {
animation: 0s ease-in-out 1 forwards collapseRichHints;
}
`
`
})
// Leader for site-specific mappings
const siteleader = "<Space>"
@ -30,3 +30,5 @@ util.rmMaps(keys.unmaps.mappings)
util.rmSearchAliases(keys.unmaps.searchAliases)
util.processMaps(keys.maps, siteleader)
util.processCompletions(completions, searchleader)
module.exports = { siteleader, searchleader }

View File

@ -10,6 +10,11 @@ const fs = require("fs")
const { spawn } = require("child_process")
const { URL } = require("url")
const compl = require("./completions")
const conf = require("./conf")
const keys = require("./keys")
const util = require("./util")
const paths = {
scripts: ["conf.priv.js", "completions.js", "conf.js", "actions.js", "help.js", "keys.js", "util.js"],
entry: "conf.js",
@ -81,7 +86,6 @@ gulp.task("watch-nogulpfile", () => {
})
gulp.task("readme", () => {
const compl = require("./completions") // eslint-disable-line global-require
const screens = {}
let screenshotList = ""
fs.readdirSync(path.join(__dirname, paths.screenshots)).forEach((s) => {
@ -92,7 +96,8 @@ gulp.task("readme", () => {
}
screens[alias].push(path.join(paths.screenshots, path.basename(s)))
})
const table = Object.keys(compl).sort((a, b) => {
const complTable = Object.keys(compl).sort((a, b) => {
if (a < b) return -1
if (a > b) return 1
return 0
@ -109,12 +114,35 @@ gulp.task("readme", () => {
screenshotList += `![${c.name} screenshot](./${url})\n\n`
})
}
return `${a}| \`${c.alias}\` | \`${c.name}\` | \`${domain}\` | ${s} |\n`
return `${a} | \`${c.alias}\` | \`${c.name}\` | \`${domain}\` | ${s} |\n`
}, "")
const keysTable = Object.keys(keys.maps).sort((a, b) => {
if (a === "global") return -1
if (b === "global") return 1
if (a < b) return -1
if (a > b) return 1
return 0
}).reduce((acc1, domain) => {
const header = "<tr><td><strong>Mapping</strong></td><td><strong>Description</strong></td></tr>"
const c = keys.maps[domain]
const maps = c.reduce((acc2, map) => {
const leader = typeof map.leader !== "undefined" ? map.leader : domain === "global" ? "" : conf.siteleader
const mapStr = util.escape(`${leader}${map.alias}`.replace(" ", "<space>"))
console.log({leader, mapStr, sl: conf.siteleader, ml: map.leader })
return `${acc2}<tr><td><code>${mapStr}</code></td><td>${map.description}</td></tr>\n`
}, "")
const domainStr = domain === "global" ? "<strong>global</strong>" : `<a href="//${domain}">${domain}</a>`
return `${acc1}<tr><th colspan="2">${domainStr}</th></tr>${header}\n${maps}`
}, "")
return gulp.src(["./README.tmpl.md"])
.pipe(replace("<!--{{DISCLAIMER}}-->", disclaimer))
.pipe(replace("<!--{{COMPL_COUNT}}-->", Object.keys(compl).length))
.pipe(replace("<!--{{COMPL_TABLE}}-->", table))
.pipe(replace("<!--{{COMPL_TABLE}}-->", complTable))
.pipe(replace("<!--{{KEYS_MAPS_COUNT}}-->", Object.keys(keys.maps).reduce((acc, m) => acc + m.length, 0)))
.pipe(replace("<!--{{KEYS_SITES_COUNT}}-->", Object.keys(keys.maps).length))
.pipe(replace("<!--{{KEYS_TABLE}}-->", keysTable))
.pipe(replace("<!--{{SCREENSHOTS}}-->", screenshotList))
.pipe(rename("README.md"))
.pipe(gulp.dest("."))

9
hints.js Normal file
View File

@ -0,0 +1,9 @@
if (typeof Hints === "undefined") {
module.exports = {
create: () => {},
dispatchMouseClick: () => {},
}
} else {
module.exports = Hints
}

20
keys.js
View File

@ -49,7 +49,7 @@ const maps = {
alias: "gI",
category: categories.pageNav,
description: "View image in new tab",
callback: actions.createHint("img", i => tabOpenLink(i.src)),
callback: actions.createHint("img", i => actions.openLink(i.src)()),
},
{
alias: "yp",
@ -117,7 +117,7 @@ const maps = {
{
alias: "A",
description: "Open search result (new tab)",
callback: actions.createHint(".r>a", actions.open({ newTab: true })),
callback: actions.createHint(".r>a", actions.openAnchor({ newTab: true })),
},
],
@ -135,7 +135,7 @@ const maps = {
leader: "",
alias: "A",
description: "Open video",
callback: actions.createHint("*[id='video-title']", actions.open({ newTab: true })),
callback: actions.createHint("*[id='video-title']", actions.openAnchor({ newTab: true })),
},
{
leader: "",
@ -147,7 +147,7 @@ const maps = {
leader: "",
alias: "gH",
description: "Goto homepage",
callback: () => window.location.assign("https://www.youtube.com/feed/subscriptions?flow=2"),
callback: actions.openLink("https://www.youtube.com/feed/subscriptions?flow=2"),
},
{
leader: "",
@ -324,7 +324,7 @@ const maps = {
{
alias: "A",
description: "View post (link) (new tab)",
callback: actions.createHint(".title", actions.open({ newTab: true })),
callback: actions.createHint(".title", actions.openAnchor({ newTab: true })),
},
{
alias: "c",
@ -334,7 +334,7 @@ const maps = {
{
alias: "C",
description: "View post (comments) (new tab)",
callback: actions.createHint(".comments", actions.open({ newTab: true })),
callback: actions.createHint(".comments", actions.openAnchor({ newTab: true })),
},
],
@ -367,7 +367,7 @@ const maps = {
{
alias: "A",
description: "View post (link) (new tab)",
callback: actions.createHint(".storylink", actions.open({ newTab: true })),
callback: actions.createHint(".storylink", actions.openAnchor({ newTab: true })),
},
{
alias: "c",
@ -377,7 +377,7 @@ const maps = {
{
alias: "C",
description: "View post (comments) (new tab)",
callback: actions.createHint("td > a[href*='item']:not(.storylink)", actions.open({ newTab: true })),
callback: actions.createHint("td > a[href*='item']:not(.storylink)", actions.openAnchor({ newTab: true })),
},
{
alias: "p",
@ -418,7 +418,7 @@ const maps = {
{
alias: "A",
description: "View shot (new tab)",
callback: actions.createHint(".dribbble-over, .gif-target, .more-thumbs a", actions.open({ newTab: true })),
callback: actions.createHint(".dribbble-over, .gif-target, .more-thumbs a", actions.openAnchor({ newTab: true })),
},
{
alias: "v",
@ -456,7 +456,7 @@ const maps = {
{
alias: "A",
description: "View project (new tab)",
callback: actions.createHint(".rf-project-cover__title", actions.open({ newTab: true })),
callback: actions.createHint(".rf-project-cover__title", actions.openAnchor({ newTab: true })),
},
],

39
util.js
View File

@ -2,6 +2,13 @@ const { categories } = require("./help")
const util = {}
util.getCurrentLocation = (prop = "href") => {
if (typeof window === "undefined") {
return ""
}
return window.location[prop]
}
util.escape = str => String(str).replace(/[&<>"'`=/]/g, s => ({
"&": "&amp;",
"<": "&lt;",
@ -46,14 +53,27 @@ util.isRectVisibleInViewport = rect => (
util.isElementInViewport = e => util.isRectVisibleInViewport(e.getBoundingClientRect())
// Process Unmaps
util.rmMaps = a => a.forEach(u => unmap(u))
util.rmMaps = a => {
if (typeof unmap === "undefined") {
return
}
a.forEach(u => unmap(u))
}
util.rmSearchAliases = a => Object.entries(a).forEach(([leader, items]) =>
util.rmSearchAliases = a => Object.entries(a).forEach(([leader, items]) =>{
if (typeof removeSearchAliasX === "undefined") {
return
}
items.forEach(v =>
removeSearchAliasX(v, leader)))
removeSearchAliasX(v, leader)
)
})
// Process Mappings
util.processMaps = (maps, siteleader) =>
util.processMaps = (maps, siteleader) => {
if (typeof map === "undefined" || typeof mapkey === "undefined") {
return
}
Object.entries(maps).forEach(([domain, domainMaps]) =>
domainMaps.forEach(((mapObj) => {
const {
@ -82,11 +102,22 @@ util.processMaps = (maps, siteleader) =>
mapkey(key, fullDescription, callback, opts)
}
})))
}
// process completions
util.processCompletions = (completions, searchleader) => Object.values(completions).forEach((s) => {
if (typeof Front === "undefined" || typeof addSearchAliasX === "undefined" || typeof mapkey === "undefined") {
return
}
addSearchAliasX(s.alias, s.name, s.search, searchleader, s.compl, s.callback)
mapkey(`${searchleader}${s.alias}`, `#8Search ${s.name}`, () => Front.openOmnibar({ type: "SearchEngine", extra: s.alias }))
})
util.addSettings = (s) => {
if (typeof settings === "undefined") {
return
}
Object.assign(settings, s)
}
module.exports = util