safari-ctl
Version:
A Command Line Tool to control Safari for MacOS. (Browsing/FillingForm/GetSetCopyURL/JavascriptInjection/GetTitle/Search)
270 lines (258 loc) • 9.65 kB
JavaScript
// Generated by CoffeeScript 2.4.1
//!/usr/bin/env coffee
var AppName, D, E, GetOpt, OsaScript, P, PackageName, checkError, ctx, doActivateIfNecessary, e, optUsages;
GetOpt = require('@kssfilo/getopt');
OsaScript = require('node-osascript');
AppName = "safari-ctl";
PackageName = "safari-ctl";
P = console.log;
E = (e) => {
var ref, ref1;
switch (false) {
case (ref = typeof e) !== 'string' && ref !== 'value':
return console.error(e);
case !ctx.isDebugMode:
return console.error(e);
default:
if ((ref1 = e[0]) != null ? ref1.message : void 0) {
return console.error(e[0].message);
} else {
return console.error(e.toString());
}
}
};
D = (str) => {
if (ctx.isDebugMode) {
return E(`${AppName}:` + str);
}
};
ctx = {
command: 'print',
isDebugMode: false,
isRecipeJsDebugMode: false,
url: null,
doActivate: false,
javaScript: null,
query: null,
text: null,
dropResult: false
};
optUsages = {
h: "show this help",
d: "debug mode",
p: "print current Safari's URL(default)",
t: "print current Safari's title",
g: "print selected string on current Safari's tab",
c: "copy current Safari's URL into the clipboard",
s: ["URL", "set <URL> to Safari's active tab"],
S: ["URL", "same as -s but set focus to Safari"],
q: ["query", "search <query> to Safari's active tab"],
Q: ["URL", "same as -q but set focus to Safari"],
m: "marks all <a> link with number to click by next -a command(*)",
a: ["number", "click <number> link. you can know link number by -m command(*)"],
M: "marks all <input> with number to click/set by next -A command(*)",
A: ["number", "click <number> input. you can know input number by -M command(*)"],
I: ["string", "works with -A, Input <string> instead of click. for filling form(*)"],
b: "history back(*)",
f: "history forward(*)",
n: "scroll to next page(*)",
N: "scroll to previous page (*)",
j: ["javascript", "run <javascript> on active tab(*)"],
J: ["javascript", "same as s but set focus to Safari(*)"]
};
try {
GetOpt.setopt('h?dptgcs:S:q:Q:ma:MA:I:bfnNj:J:');
} catch (error) {
e = error;
switch (e.type) {
case 'unknown':
E(`Unknown option:${e.opt}`);
break;
case 'required':
E(`Required parameter for option:${e.opt}`);
}
process.exit(1);
}
try {
GetOpt.getopt(function(o, p) {
var index;
switch (o) {
case 'h':
case '?':
ctx.command = 'usage';
if (p[0] !== '') {
return ctx.restCommand = p[0];
}
break;
case 'd':
return ctx.isDebugMode = true;
case 'c':
return ctx.command = 'copy';
case 'p':
return ctx.command = 'print';
case 's':
ctx.command = 'set';
return ctx.url = p[0];
case 'S':
ctx.command = 'set';
ctx.url = p[0];
return ctx.doActivate = true;
case 't':
return ctx.command = 'printTitle';
case 'j':
ctx.command = 'javaScript';
return ctx.javaScript = p[0];
case 'J':
ctx.command = 'javaScript';
ctx.javaScript = p[0];
return ctx.doActivate = true;
case 'g':
ctx.command = 'javaScript';
return ctx.javaScript = "document.getSelection().toString()";
case 'q':
ctx.command = 'search';
return ctx.query = p[0];
case 'Q':
ctx.command = 'search';
ctx.query = p[0];
return ctx.doActivate = true;
case 'm':
ctx.command = 'javaScript';
return ctx.javaScript = 'var $OSA$=document.getElementsByTagName("a");for(var i=0;i<$OSA$.length;i++){v=$OSA$[i];v.innerHTML="<span style=background-color:yellow>"+i+"</span>:"+v.innerHTML;}';
case 'M':
ctx.command = 'javaScript';
return ctx.javaScript = 'var $OSA$=document.getElementsByTagName("input");for(var i=0;i<$OSA$.length;i++){v=$OSA$[i];var e=document.createElement("span");e.style="background-color:lightgreen";e.innerText=i;v.before(e);}';
case 'a':
ctx.command = 'javaScript';
index = Number(p[0]);
ctx.javaScript = `var $OSA$=document.getElementsByTagName('a');$OSA$[${index}].click()`;
return ctx.dropResult = true;
case 'A':
ctx.command = 'javaScript';
index = Number(p[0]);
ctx.javaScript = `var $OSA$=document.getElementsByTagName('input');$OSA$[${index}].click()`;
return ctx.dropResult = true;
case 'I':
ctx.text = p[0];
return ctx.dropResult = true;
case 'b':
ctx.command = 'javaScript';
return ctx.javaScript = "history.back()";
case 'f':
ctx.command = 'javaScript';
return ctx.javaScript = "history.forward()";
case 'n':
ctx.command = 'javaScript';
ctx.javaScript = "window.scrollBy({top:window.innerHeight,left:0,behavior:'smooth'})";
return ctx.dropResult = true;
case 'N':
ctx.command = 'javaScript';
ctx.javaScript = "window.scrollBy({top:-window.innerHeight,left:0,behavior:'smooth'})";
return ctx.dropResult = true;
}
});
if (ctx.command === 'usage') {
P(`## Command line\n\n ${AppName} [options]\n \n A Command Line Tool to control Safari for MacOS. (Browsing/FillingForm/GetSetCopyURL/JavascriptInjection/GetTitle/Search)\n \n Copyright (C) 2019-2019 @kssfilo(https://kanasys.com/gtech/)\n\n## Prepare\n\n(*)You must enable the 'Allow JavaScript from Apple Events' option in Safari's Develop menu to use some features.\n\n## Options\n\n${GetOpt.getHelp(optUsages)} \n\n## Examples\n\n### Get current URL on Safari\n\n $ ${AppName}\n https://github.com\n\n### Copy current URL on Safari to the clipboard\n\n $ ${AppName} -s\n\n### Open specified URL on Safari\n\n $ ${AppName} -s 'http://github.com'\n # withoug focus\n\n $ ${AppName} -S 'github.com'\n # with focus(omiting scheme->appends https://)\n\n### Gets window title\n\n $ ${AppName} -t\n\n### Navigating by command line\n\n $ ${AppName} -m\n # marks all <a> with numbers\n\n $ ${AppName} -a 32\n # click 32'th <a>\n\n $ ${AppName} -b\n # history back\n\n $ ${AppName} -M\n # marks all <input> with numbers\n\n $ ${AppName} -A 0 -I 'Japan'\n # Fill 0th input with 'Japan'\n\n $ ${AppName} -A 1\n # click 1st input button\n\n### Searchs Bing with word "Japan" (JavaScript injection)\n\n $ ${AppName} -s 'https://bing.com'\n $ ${AppName} -j 'document.getElementById("sb_form_q").value="Japan";document.getElementById("sb_form_go").click()'\n\n### Print string in Bing search form\n\n $ ${AppName} -j 'document.getElementById("sb_form_q").value'\n Japan`);
process.exit(0);
}
D(`==starting ${AppName}`);
if (ctx.javaScript) {
ctx.javaScript = ctx.javaScript.replace(/"/g, '\\"');
}
if (ctx.url && !ctx.url.match(/^https?:\/\//)) {
ctx.url = "https://" + ctx.url;
}
D("sanity checking..");
if (ctx.text && !ctx.javaScript) {
throw "-I works with -A";
}
if (ctx.text && ctx.javaScript) {
D("CHECK");
ctx.javaScript = ctx.javaScript.replace(/click\(\)$/, `value='${ctx.text}'`);
}
D("..OK");
D("-------");
D("-options");
D(`${JSON.stringify(ctx, null, 2)}`);
if (ctx.isCheckCommand || ctx.isDebugMode) {
if (ctx.restCommand != null) {
E(`command:${ctx.restCommand}`);
}
if (ctx.restCommand != null) {
E(`method:${ctx.command}`);
}
if (ctx.restParam != null) {
E(`params:${JSON.stringify(ctx.restParam)}`);
}
}
checkError = (e) => {
if (e) {
P(e.toString());
return process.exit(1);
}
};
doActivateIfNecessary = (cb) => {
if (ctx.doActivate) {
return OsaScript.execute("tell application \"safari\"\nactivate\nend tell", cb);
} else {
return cb(null, null, null);
}
};
switch (ctx.command) {
case 'print':
OsaScript.execute("tell application \"safari\"\nURL in front document\nend tell", (e, r, w) => {
checkError(e);
return P(r);
});
break;
case 'printTitle':
OsaScript.execute("tell application \"safari\"\nname of front document\nend tell", (e, r, w) => {
checkError(e);
return P(r);
});
break;
case 'copy':
OsaScript.execute("tell application \"safari\"\nset curURL to URL in front document\nset the clipboard to curURL\nend tell", (e, r, w) => {
return checkError(e);
});
break;
case 'set':
OsaScript.execute("tell application \"safari\"\nset URL in front document to URLTOSET\nend tell", {
URLTOSET: ctx.url
}, (e, r, w) => {
checkError(e);
return doActivateIfNecessary((e, r, w) => {
return checkError(e);
});
});
break;
case 'search':
OsaScript.execute("tell application \"safari\"\nsearch the web in front document for QUERY\nend tell", {
QUERY: ctx.query
}, (e, r, w) => {
checkError(e);
return doActivateIfNecessary((e, r, w) => {
return checkError(e);
});
});
break;
case 'javaScript':
D(ctx.javaScript);
doActivateIfNecessary((e, r, w) => {
checkError(e);
return OsaScript.execute("tell application \"safari\"\ndo JavaScript TORUN in front document\nend tell", {
TORUN: ctx.javaScript
}, (e, r, w) => {
checkError(e);
if (r && !ctx.dropResult) {
return P(r);
}
});
});
}
} catch (error) {
e = error;
E(console.error(e.toString()));
process.exit(1);
}