diff --git a/atom/browser/api/lib/menu-item.coffee b/atom/browser/api/lib/menu-item.coffee index 11d87f5713..2dda5a9b4d 100644 --- a/atom/browser/api/lib/menu-item.coffee +++ b/atom/browser/api/lib/menu-item.coffee @@ -1,7 +1,27 @@ BrowserWindow = require 'browser-window' +v8Util = process.atomBinding 'v8_util' nextCommandId = 0 +overrideProperty = (item, name, defaultValue) -> + item[name] ?= defaultValue + + return unless process.platform is 'win32' + v8Util.setHiddenValue item, name, item[name] + Object.defineProperty item, name, + enumerable: true + get: -> v8Util.getHiddenValue item, name + set: (val) -> + v8Util.setHiddenValue item, name, val + item.menu?._updateStates() + +overrideReadOnlyProperty = (item, name, defaultValue) -> + item[name] ?= defaultValue + Object.defineProperty item, name, + enumerable: true + writable: false + value: item[name] + class MenuItem @types = ['normal', 'separator', 'submenu', 'checkbox', 'radio'] @@ -13,14 +33,14 @@ class MenuItem @type = 'submenu' if not @type? and @submenu? throw new Error('Invalid submenu') if @type is 'submenu' and @submenu?.constructor isnt Menu - @type = @type ? 'normal' - @label = @label ? '' - @sublabel = @sublabel ? '' - @accelerator = @accelerator ? null - @enabled = @enabled ? true - @visible = @visible ? true - @checked = @checked ? false - @submenu = @submenu ? null + overrideReadOnlyProperty this, 'type', 'normal' + overrideReadOnlyProperty this, 'accelerator', null + overrideReadOnlyProperty this, 'submenu', null + overrideProperty this, 'label', '' + overrideProperty this, 'sublabel', '' + overrideProperty this, 'enabled', true + overrideProperty this, 'visible', true + overrideProperty this, 'checked', false throw new Error("Unknown menu type #{@type}") if MenuItem.types.indexOf(@type) is -1 diff --git a/atom/browser/api/lib/menu.coffee b/atom/browser/api/lib/menu.coffee index 0e7b4c263f..a2cdd2e9f1 100644 --- a/atom/browser/api/lib/menu.coffee +++ b/atom/browser/api/lib/menu.coffee @@ -64,18 +64,7 @@ Menu::insert = (pos, item) -> switch item.type when 'normal' then @insertItem pos, item.commandId, item.label - when 'checkbox' - # Update states when clicked on Windows. - if process.platform is 'win32' - v8Util.setHiddenValue item, 'checked', item.checked - Object.defineProperty item, 'checked', - enumerable: true - get: -> v8Util.getHiddenValue item, 'checked' - set: (val) => - v8Util.setHiddenValue item, 'checked', val - @_updateStates() if process.platform is 'win32' - - @insertCheckItem pos, item.commandId, item.label + when 'checkbox' then @insertCheckItem pos, item.commandId, item.label when 'separator' then @insertSeparator pos when 'submenu' then @insertSubMenu pos, item.commandId, item.label, item.submenu when 'radio' @@ -85,7 +74,6 @@ Menu::insert = (pos, item) -> @groupsMap[item.groupId].push item # Setting a radio menu item should flip other items in the group. - v8Util.setHiddenValue item, 'checked', item.checked Object.defineProperty item, 'checked', enumerable: true get: -> v8Util.getHiddenValue item, 'checked' @@ -101,6 +89,9 @@ Menu::insert = (pos, item) -> @setSublabel pos, item.sublabel if item.sublabel? + # Make menu accessable to items. + item.menu = this + # Remember the items. @items.splice pos, 0, item @commandsMap[item.commandId] = item