-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathclient.coffee
152 lines (130 loc) · 4.89 KB
/
client.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
`#!/usr/bin/env node
`
utils = require "./utils"
utils.extend global, utils
optimist = require "optimist"
args = optimist.usage("Usage: $0 [--sock=PATH]")
.alias("h", "help")
.default("sock", config.sock)
.argv
if args.help
optimist.showHelp()
process.exit(0)
chromix = require("./chromix-too")(args.sock).chromix
[ commandName, commandArgs ] =
if 2 < process.argv.length then [ process.argv[2], process.argv[3...] ] else [ "ping", [] ]
# Extract the query flags (for chrome.tabs.query) from the arguments. Return the new arguments and the
# query-flags object.
getQueryFlags = (commandArgs) ->
validQueryFlags = {}
# These are the valid boolean flags listed here: https://developer.chrome.com/extensions/tabs#method-query.
for flag in "active pinned audible muted highlighted discarded autoDiscardable currentWindow lastFocusedWindow".split " "
validQueryFlags[flag] = true
queryFlags = {}
commandArgs =
for arg in commandArgs
if arg of validQueryFlags
queryFlags[arg] = true
continue
# Use a leading "-" or "!" to negate the test; e.g. "-audible" or "!active".
else if arg[0] in ["-", "!"] and arg[1..] of validQueryFlags
queryFlags[arg[1..]] = false
continue
# For symmetry, we also allow "+"; e.g. "+audible".
else if arg[0] in ["+"] and arg[1..] of validQueryFlags
queryFlags[arg[1..]] = true
continue
else
arg
[ commandArgs, queryFlags ]
# Filter tabs by the remaining command-line arguements. We require a match in either the URL or the title.
# If the argument is a bare number, then we require it to match the tab Id.
filterTabs = do ->
integerRegex = /^\d+$/
(commandArgs, tabs) ->
for tab in tabs
continue unless do ->
for arg in commandArgs
if integerRegex.test(arg) and tab.id == parseInt arg
continue
else if integerRegex.test arg
return false
else if tab.url.indexOf(arg) == -1 and tab.title.indexOf(arg) == -1
return false
true
tab
# Return an array of tabs matching the flags and other arguments on the command line.
getMatchingTabs = (commandArgs, callback) ->
[ commandArgs, queryFlags ] = getQueryFlags commandArgs
chromix "chrome.tabs.query", {}, queryFlags, (tabs) ->
tabs = filterTabs commandArgs, tabs
process.exit 1 if tabs.length == 0
callback tabs
focusWindow = (windowId) ->
chromix "chrome.windows.update", {}, windowId, {focused: true}, ->
switch commandName
when "ls", "list", "tabs"
getMatchingTabs commandArgs, (tabs) ->
console.log "#{tab.id} #{tab.url} #{tab.title}" for tab in tabs
when "tid" # Like "ls", but outputs only the tab Id of the matching tabs.
getMatchingTabs commandArgs, (tabs) ->
console.log "#{tab.id}" for tab in tabs
when "focus", "activate"
getMatchingTabs commandArgs, (tabs) ->
for tab in tabs
chromix "chrome.tabs.update", {}, tab.id, {selected: true}
focusWindow tab.windowId
when "select"
getMatchingTabs commandArgs, (tabs) ->
for tab in tabs
chromix "chrome.tabs.update", {}, tab.id, {selected: true}
when "reload"
getMatchingTabs commandArgs, (tabs) ->
chromix "chrome.tabs.reload", {}, tab.id, {} for tab in tabs
when "url"
[url, commandArgs...] = commandArgs
getMatchingTabs commandArgs, (tabs) ->
chromix "chrome.tabs.update", {}, tab.id, {url} for tab in tabs
when "rm", "remove", "close"
getMatchingTabs commandArgs, (tabs) ->
chromix "chrome.tabs.remove", {}, tab.id for tab in tabs
when "open", "create"
for arg in commandArgs
do (arg) ->
chromix "chrome.tabs.create", {}, {url: arg}, (tab) ->
focusWindow tab.windowId
console.log "#{tab.id} #{tab.url}"
when "ping"
chromix "ping", {}, (response) ->
if response == "ok"
process.exit 0
else
process.exit 1
when "file"
for arg in commandArgs
url = if arg.indexOf("file://") == 0 then arg else "file://#{require("path").resolve arg}"
do (url) ->
getMatchingTabs [], (tabs) ->
tabs = (t for t in tabs when t.url.indexOf(url) == 0)
if tabs.length == 0
chromix "chrome.tabs.create", {}, {url: url}, (tab) ->
focusWindow tab.windowId
console.log "#{tab.id} #{tab.url}"
else
for tab in tabs
do (tab) ->
chromix "chrome.tabs.update", {}, tab.id, {selected: true}, ->
chromix "chrome.tabs.reload", {}, tab.id, {}, ->
focusWindow tab.windowId
when "raw", "josn"
args =
for arg in commandArgs[1..]
try
JSON.parse arg
catch
arg
chromix commandArgs[0], {}, args..., (response) ->
console.log JSON.stringify response
else
console.error "error: unknown command: #{commandName}"
process.exit 2