Last active
April 2, 2024 03:31
-
-
Save hytor-yang/6e8cf7f3f45cc6ba598f0c20ea9fa383 to your computer and use it in GitHub Desktop.
Surfingkeys customization with jd/douban/taobao search and copy tab(s) as markdown feature.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { | |
aceVimMap, | |
mapkey, | |
imap, | |
imapkey, | |
insertJS, | |
getClickableElements, | |
vmapkey, | |
map, | |
unmap, | |
cmap, | |
addSearchAlias, | |
removeSearchAlias, | |
tabOpenLink, | |
readText, | |
Clipboard, | |
Front, | |
Hints, | |
Visual, | |
RUNTIME, | |
} = api; | |
/* Key Bindings */ | |
// A VSCode convention for Tab History back/forward | |
map("<Ctrl-->", "B"); | |
map("<Ctrl-_>", "F"); | |
/* Search Alias */ | |
// Remove Duckduckgo Search | |
removeSearchAlias("d"); | |
// Add Search for JD (京东), Taobao(淘宝), Douban Book(豆瓣图书) | |
addSearchAlias( | |
"j", | |
"jd", | |
"http://search.jd.com/Search?enc=utf-8&keyword=", | |
"s" | |
); | |
addSearchAlias( | |
"tb", | |
"taobao", | |
"https://s.taobao.com/search?q=", | |
"s", | |
"https://suggest.taobao.com/sug?code=utf-8&q=", | |
function (response) { | |
var res = []; | |
try { | |
res = JSON.parse(response.text).result.map(function (it) { | |
return it[0]; | |
}); | |
} catch (e) {} | |
return res; | |
} | |
); | |
addSearchAlias( | |
"db", | |
"doubanbook", | |
"https://www.douban.com/search?cat=1001&q=", | |
"s" | |
); | |
/* Advanced Bookmark, and Page Meta Copy */ | |
// Util to remove URL query and hash. | |
// ⚠️ It's so rude that some URL would break due to necessary query params missing. | |
// Use a well maintained URL Cleaning Extension instead. Or purify only those targets that you quite sure. | |
function _cleanupUrl(url, doCleanup) { | |
return doCleanup ? /http[^#\?]*/.exec(url)[0] : url; | |
} | |
function getAliDevopsTaskId() { | |
const workitemIdElSelector = "[class^=workItemTitle--idBox]" | |
let workitemIdEl = document.querySelector(workitemIdElSelector); | |
if (workitemIdEl == null) { | |
blinkAliDevopsWorkItemIdBox() | |
workitemIdEl = document.querySelector(workitemIdElSelector); | |
} | |
return workitemIdEl && workitemIdEl.innerText || ''; | |
} | |
function blinkAliDevopsWorkItemIdBox() { | |
// Thx to [brookhong/Surfingkeys#1345](https://github.com/brookhong/Surfingkeys/issues/1345) | |
// insertJS is currently the only way I figured out to 'call tab page's window global API.' | |
insertJS(function () { | |
if (typeof window.aoneCallback_workitemDrawerSetHideIdShowTitle != 'function') { | |
console.log('Oops, Aliyun Devops priviate API aoneCallback_workitemDrawerSetHideIdShowTitle is not available...') | |
return | |
} | |
window.aoneCallback_workitemDrawerSetHideIdShowTitle(false) | |
window.setTimeout(function () { | |
window.aoneCallback_workitemDrawerSetHideIdShowTitle(true) | |
}, 200) | |
}) | |
} | |
// Custimized Bookmark | |
function _getCurrentTabTitle(doCleanup) { | |
let title = document.title; | |
const url = location.href; | |
const urlHost = location.hostname; | |
const urlPath = location.pathname; | |
let prefix = ""; | |
// Get actual article title for Wechat Public Account page. 获取微信公众号文章的实际标题 | |
// You may don't need this if you are using dedicated User Script. 如果使用了专门的 User Script, 这个功能就不必要了。 | |
// e.g. [修改微信公众号文章title标题](https://greasyfork.org/en/scripts/375439-%E4%BF%AE%E6%94%B9%E5%BE%AE%E4%BF%A1%E5%85%AC%E4%BC%97%E5%8F%B7%E6%96%87%E7%AB%A0title%E6%A0%87%E9%A2%98) | |
// if (urlHost === 'mp.weixin.qq.com') { | |
// title = document.getElementById('activity-name').innerText | |
// } | |
// For Alfred Forum. Remove suffix of 'Discussion & Help - Alfred App Community Forum' | |
if (urlHost.includes("www.alfredforum.com")) { | |
title = title.replace( | |
"- Discussion & Help - Alfred App Community Forum", | |
"" | |
); | |
} | |
// For Zhihu. 精简私信、消息提示文字 | |
if (urlHost.includes("www.zhihu.com")) { | |
title = title.replace(/\(\d+.*(消息|私信)\) /, "").replace(" - 知乎", ""); | |
} | |
// For Github. | |
if (urlHost === "github.com") { | |
const issuesRegexPattern = /issues\/\d+$/; | |
const prRegexPattern = /pull\/\d+$/; | |
if (issuesRegexPattern.test(urlPath)) { | |
// Github issue detail page. Simplify to ${repo-name}#${issue-no}. e.g. [vitejs/vite#123](https://github.com/vitejs/vite/issues/123) | |
const issuePathParts = /\/(.*)\/issues\/(\d+)$/.exec(urlPath); | |
const [, repoName, issueNo] = issuePathParts; | |
title = `${repoName}#${issueNo}`; | |
} else if (prRegexPattern.test(urlPath)) { | |
// Github pull request detail page. Simplify to ${repo-name} PR #${pr-no}. e.g. [vitejs/vite PR #456](https://github.com/vitejs/vite/pull/456) | |
const prPathParts = /\/(.*)\/pull\/(\d+)$/.exec(urlPath); | |
const [, repoName, prNo] = prPathParts; | |
title = `${repoName} PR #${prNo}`; | |
} else { | |
// Github Repo root page. Add Stars. e.g. 61.4k★ [vitejs/vite: Next generation frontend tooling. It's fast!](https://github.com/vitejs/vite) | |
const starCountEl = document.querySelector("#repo-stars-counter-star"); | |
const starCount = (starCountEl && starCountEl.innerText.trim()) || "0"; | |
prefix = | |
starCount.endsWith("k") || parseInt(starCount) > 99 | |
? `${starCount}★ ` | |
: ""; | |
} | |
} | |
// For Aliyun Devops, get workitem title and id. 阿里云效,获取工作项标题与 ID。 | |
if ( | |
urlHost === "devops.aliyun.com" && | |
((urlPath.startsWith("/projex/workitem") && | |
url.includes("openWorkitemIdentifier=")) || | |
/projex\/project\/\w+\/(req|task)/.test(urlPath)) | |
) { | |
const workitemTitleEl = document.querySelector("#workitemTitleInputBox"); | |
title = (workitemTitleEl && workitemTitleEl.value || "") + ', ' + getAliDevopsTaskId(); | |
} | |
return { prefix, title, url: _cleanupUrl(url, doCleanup) }; | |
} | |
// Custimized Markdown Format Bookmark | |
function _getCurrentTabMarkdown(doCleanup) { | |
const { prefix, title, url } = _getCurrentTabTitle(doCleanup); | |
return `${prefix}[${title}](${url})`; | |
} | |
// Custimized Markdown Format Bookmark for All Opened Tabs. | |
function _copyAllTabsMarkdown(doCleanup) { | |
RUNTIME("getTabs", null, (response) => { | |
const tabs = (response && response.tabs) || []; | |
markdownStr = tabs | |
.filter( | |
(tab) => tab.url.startsWith("http") && tab.url.indexOf("cache") === -1 | |
) | |
.map((tab) => `[${tab.title}](${_cleanupUrl(tab.url, doCleanup)})`) | |
.concat(_getCurrentTabMarkdown(doCleanup)) | |
.join("\n"); | |
Clipboard.write(markdownStr); | |
}); | |
} | |
mapkey( | |
"ybb", | |
"Copy current tab in Markdown format", | |
function () { | |
Clipboard.write(_getCurrentTabMarkdown()); | |
}, | |
{} | |
); | |
mapkey( | |
"ybcb", | |
"Copy current tab in Markdown format, removing query and hash in URL", | |
function () { | |
Clipboard.write(_getCurrentTabMarkdown(true)); | |
}, | |
{} | |
); | |
mapkey( | |
"ybl", | |
"Copy current tab's title, with custimized transformation.", | |
function () { | |
const { title } = _getCurrentTabTitle(); | |
Clipboard.write(title); | |
}, | |
{} | |
); | |
mapkey( | |
"yba", | |
"Copy all tabs in Markdown format", | |
function () { | |
_copyAllTabsMarkdown(); | |
}, | |
{} | |
); | |
mapkey( | |
"ybca", | |
"Copy all tabs in Markdown format, removing query and hash in URL", | |
function () { | |
_copyAllTabsMarkdown(true); | |
}, | |
{} | |
); | |
// Shared theme setting from Official SurfingKeys repo? Credit to original author | |
settings.theme = ` | |
.sk_theme { | |
font-family: Input Sans Condensed, Charcoal, sans-serif; | |
font-size: 10pt; | |
background: #24272e; | |
color: #abb2bf; | |
} | |
.sk_theme tbody { | |
color: #fff; | |
} | |
.sk_theme input { | |
color: #d0d0d0; | |
} | |
.sk_theme .url { | |
color: #61afef; | |
} | |
.sk_theme .annotation { | |
color: #56b6c2; | |
} | |
.sk_theme .omnibar_highlight { | |
color: #528bff; | |
} | |
.sk_theme .omnibar_timestamp { | |
color: #e5c07b; | |
} | |
.sk_theme .omnibar_visitcount { | |
color: #98c379; | |
} | |
.sk_theme #sk_omnibarSearchResult>ul>li:nth-child(odd) { | |
background: #303030; | |
} | |
.sk_theme #sk_omnibarSearchResult>ul>li.focused { | |
background: #3e4452; | |
} | |
#sk_status, #sk_find { | |
font-size: 20pt; | |
}`; | |
// click `Save` button to make above settings to take effect. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment