Skip to content

Instantly share code, notes, and snippets.

@uchcode
Last active May 10, 2023 14:31
Show Gist options
  • Save uchcode/32e607790a0b204db27ee6496e1da5b5 to your computer and use it in GitHub Desktop.
Save uchcode/32e607790a0b204db27ee6496e1da5b5 to your computer and use it in GitHub Desktop.
JXA (JavaScript for Automation) DockMenu applet example.
ObjC.import('Cocoa')
App = Application.currentApplication()
App.includeStandardAdditions = true
const RESOURCE = $.NSBundle.mainBundle.resourcePath.js
const HOST = 'localhost'
const PORT = 8080
const ADDR = `${HOST}:${PORT}`
const DIR = `${RESOURCE}/public_html/`
const LOG = `${RESOURCE}/webserver.log`
const SERV = `cd "${DIR}"; php -S ${ADDR} 1>> "${LOG}" 2>&1 &`
const PID = `ps aux | grep '[p]hp -S ${ADDR}\' | awk '{print $2}'`
const HOME = `http://${ADDR}/`
MyAction = SimpleSubclass('Action', {
start(sender) {
if (App.doShellScript(PID)) return $.NSLog('already launched.')
App.doShellScript(SERV)
$.NSLog(`server pid: ${App.doShellScript(PID)}`)
$.NSLog('start')
},
stop(sender) {
$.NSLog(`server pid: ${App.doShellScript(PID)}`)
App.doShellScript(`${PID} | sort | xargs kill`)
$.NSLog('stop')
},
restart(sender) {
this.stop(this)
delay(1)
this.start(this)
$.NSLog('restart')
},
status(sender) {
if (App.doShellScript(PID)) {
var msg = 'status: running...'
} else {
var msg = 'status: stop.'
}
App.activate()
App.displayAlert(msg)
$.NSLog(msg)
},
log(sender) {
App.doShellScript(`open "${LOG}"`)
},
documentRoot(sender) {
App.doShellScript(`open "${DIR}"`)
},
})
MyMenu = $.NSMenu.alloc.init
MyMenu.addItem( MenuItem('Start', 'start:', MyAction) )
MyMenu.addItem( MenuItem('Stop', 'stop:', MyAction) )
MyMenu.addItem( MenuItem('Restart', 'restart:', MyAction) )
MyMenu.addItem( MenuItem() )
MyMenu.addItem( MenuItem('Document Root', 'documentRoot:', MyAction) )
MyMenu.addItem( MenuItem('Status', 'status:', MyAction) )
MyMenu.addItem( MenuItem('Log', 'log:', MyAction) )
$.NSApplication.sharedApplication.dockMenu = MyMenu
function reopen() {
App.openLocation(HOME)
$.NSLog(`open ${HOME}`)
}
function quit() {
MyAction.stop(this)
$.NSLog('quit')
}
function run(argv) {
MyAction.start(this)
reopen()
$.NSLog('run')
}
//=====================================================================
function MenuItem(title, action, target) {
if (!title && !action && !target) return $.NSMenuItem.separatorItem
let i = $.NSMenuItem.alloc.init
i.title = title
i.action = action
i.target = target
return i
}
function SimpleSubclass(_name, methods) {
if ($[_name]) return $[_name].alloc.init
let _methods = {}
for (let m in methods) {
_methods[m+':'] = {
types: ['void', ['id']],
implementation: methods[m],
}
}
ObjC.registerSubclass({
name: _name,
methods: _methods,
})
return $[_name].alloc.init
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment