Closed nojusmickus closed 5 years ago
I have macros that will open 1st/2nd/3rd link when I am on Google for me.
For example I have bound this macro to ctrl+v:
And it will instantly open first result on Google for me.
I also use sVim and have bindings configured. Pressing d
will open link hints and I can choose results by typing letters:
The macro calls this JXA:
(() => {
'use strict';
const main = () => {
const
linkIndex = 0,
strXPath = "//*[@class='r']/a",
saf = Application("Safari"),
ws = saf.windows;
return bindLR(
0 < ws.length ? (
Right(ws.at(0))
) : Left('No window open in Safari'),
w => {
const
xs = pageXPathHarvest(
saf, w, strXPath
);
return 0 < xs.length ? (
// Safari effect
//tabsOpened(saf, w, xs),
nthLinkOpened(saf, xs, linkIndex),
// Keyboard Maestro value
Right(
xs.reduce(
(a, link) =>
`${a}[${link[0]}](${link[1]})\n`,
''
)
)
) : Left(
'Perhaps not a Google search page ?\n' +
'(No links matching "' + strXPath + '")'
);
}
);
};
// SAFARI ---------------------------------------------
// Harvest elements from Safari by XPath pattern
const pageXPathHarvest = (browser, oWin, strXPath) =>
browser.doJavaScript(
`(${xpathHarvest})("${strXPath}")`, { in
: oWin.currentTab
}
);
// tabsOpened :: Application -> Window -> (String, String) -> IO()
const tabsOpened = (safari, oWin, links) => {
const winTabs = oWin.tabs;
links.map(link => winTabs.push(safari.Tab({
url: link[1]
})))
};
// nthLinkOpened :: Application -> (String, String) -> Int -> IO()
const nthLinkOpened = (safari, links, i) =>
(ds =>
(
ds.length < 1 && ds.push(safari.Document()),
ds.at(0)
)
.url = links[i][1]
)(safari.documents);
// Harvesting function to run in the browser context
const xpathHarvest = strPath => {
const
r = document.evaluate(strPath, document, null, 0, null),
xs = [];
let oNode;
while (oNode = r.iterateNext()) {
xs.push([oNode.text, oNode.href]);
}
return xs;
};
// GENERIC FUNCTIONS ----------------------------------
// https://github.com/RobTrew/prelude-jxa
// Left :: a -> Either a b
const Left = x => ({
type: 'Either',
Left: x
});
// Right :: b -> Either a b
const Right = x => ({
type: 'Either',
Right: x
});
// bindLR (>>=) :: Either a -> (a -> Either b) -> Either b
const bindLR = (m, mf) =>
m.Right !== undefined ? (
mf(m.Right)
) : m;
// MAIN
return main();
})();
I share all macros I use on Gumorad. 🙂
Thank you :)
Hi Nikita, could you share how you open links after a google search in Safari using your keyboard? The native tab navigation from accessibility feature is too slow and I couldn't find anything similar to Keyboard navigation for Safari, thanks!