uchcode
12/31/2016 - 10:46 AM

JXA (JavaScript for Automation) DockMenu applet example.

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
}