mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-12-27 00:25:06 +03:00
188 lines
6.3 KiB
CoffeeScript
188 lines
6.3 KiB
CoffeeScript
ContextMenuManager = require '../src/context-menu-manager'
|
|
|
|
describe "ContextMenuManager", ->
|
|
[contextMenu, parent, child, grandchild] = []
|
|
|
|
beforeEach ->
|
|
{resourcePath} = atom.getLoadSettings()
|
|
contextMenu = new ContextMenuManager({resourcePath})
|
|
|
|
parent = document.createElement("div")
|
|
child = document.createElement("div")
|
|
grandchild = document.createElement("div")
|
|
parent.classList.add('parent')
|
|
child.classList.add('child')
|
|
grandchild.classList.add('grandchild')
|
|
child.appendChild(grandchild)
|
|
parent.appendChild(child)
|
|
|
|
describe "::add(itemsBySelector)", ->
|
|
it "can add top-level menu items that can be removed with the returned disposable", ->
|
|
disposable = contextMenu.add
|
|
'.parent': [{label: 'A', command: 'a'}]
|
|
'.child': [{label: 'B', command: 'b'}]
|
|
'.grandchild': [{label: 'C', command: 'c'}]
|
|
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [
|
|
{label: 'C', command: 'c'}
|
|
{label: 'B', command: 'b'}
|
|
{label: 'A', command: 'a'}
|
|
]
|
|
|
|
disposable.dispose()
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual []
|
|
|
|
it "can add submenu items to existing menus that can be removed with the returned disposable", ->
|
|
disposable1 = contextMenu.add
|
|
'.grandchild': [{label: 'A', submenu: [{label: 'B', command: 'b'}]}]
|
|
disposable2 = contextMenu.add
|
|
'.grandchild': [{label: 'A', submenu: [{label: 'C', command: 'c'}]}]
|
|
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{
|
|
label: 'A',
|
|
submenu: [
|
|
{label: 'B', command: 'b'}
|
|
{label: 'C', command: 'c'}
|
|
]
|
|
}]
|
|
|
|
disposable2.dispose()
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{
|
|
label: 'A',
|
|
submenu: [
|
|
{label: 'B', command: 'b'}
|
|
]
|
|
}]
|
|
|
|
disposable1.dispose()
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual []
|
|
|
|
it "favors the most specific / recently added item in the case of a duplicate label", ->
|
|
grandchild.classList.add('foo')
|
|
|
|
disposable1 = contextMenu.add
|
|
'.grandchild': [{label: 'A', command: 'a'}]
|
|
disposable2 = contextMenu.add
|
|
'.grandchild.foo': [{label: 'A', command: 'b'}]
|
|
disposable3 = contextMenu.add
|
|
'.grandchild': [{label: 'A', command: 'c'}]
|
|
disposable4 = contextMenu.add
|
|
'.child': [{label: 'A', command: 'd'}]
|
|
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'b'}]
|
|
|
|
disposable2.dispose()
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'c'}]
|
|
|
|
disposable3.dispose()
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'a'}]
|
|
|
|
disposable1.dispose()
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'd'}]
|
|
|
|
it "allows multiple separators, but not adjacent to each other", ->
|
|
contextMenu.add
|
|
'.grandchild': [
|
|
{label: 'A', command: 'a'},
|
|
{type: 'separator'},
|
|
{type: 'separator'},
|
|
{label: 'B', command: 'b'},
|
|
{type: 'separator'},
|
|
{type: 'separator'},
|
|
{label: 'C', command: 'c'}
|
|
]
|
|
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [
|
|
{label: 'A', command: 'a'},
|
|
{type: 'separator'},
|
|
{label: 'B', command: 'b'},
|
|
{type: 'separator'},
|
|
{label: 'C', command: 'c'}
|
|
]
|
|
|
|
it "excludes items marked for display in devMode unless in dev mode", ->
|
|
disposable1 = contextMenu.add
|
|
'.grandchild': [{label: 'A', command: 'a', devMode: true}, {label: 'B', command: 'b', devMode: false}]
|
|
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'B', command: 'b'}]
|
|
|
|
contextMenu.devMode = true
|
|
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'a'}, {label: 'B', command: 'b'}]
|
|
|
|
it "allows items to be associated with `created` hooks which are invoked on template construction with the item and event", ->
|
|
createdEvent = null
|
|
|
|
item = {
|
|
label: 'A',
|
|
command: 'a',
|
|
created: (event) ->
|
|
@command = 'b'
|
|
createdEvent = event
|
|
}
|
|
|
|
contextMenu.add('.grandchild': [item])
|
|
|
|
dispatchedEvent = {target: grandchild}
|
|
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual [{label: 'A', command: 'b'}]
|
|
expect(item.command).toBe 'a' # doesn't modify original item template
|
|
expect(createdEvent).toBe dispatchedEvent
|
|
|
|
it "allows items to be associated with `shouldDisplay` hooks which are invoked on construction to determine whether the item should be included", ->
|
|
shouldDisplayEvent = null
|
|
shouldDisplay = true
|
|
|
|
item = {
|
|
label: 'A',
|
|
command: 'a',
|
|
shouldDisplay: (event) ->
|
|
@foo = 'bar'
|
|
shouldDisplayEvent = event
|
|
shouldDisplay
|
|
}
|
|
contextMenu.add('.grandchild': [item])
|
|
|
|
dispatchedEvent = {target: grandchild}
|
|
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual [{label: 'A', command: 'a'}]
|
|
expect(item.foo).toBeUndefined() # doesn't modify original item template
|
|
expect(shouldDisplayEvent).toBe dispatchedEvent
|
|
|
|
shouldDisplay = false
|
|
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual []
|
|
|
|
it "throws an error when the selector is invalid", ->
|
|
addError = null
|
|
try
|
|
contextMenu.add '<>': [{label: 'A', command: 'a'}]
|
|
catch error
|
|
addError = error
|
|
expect(addError.message).toContain('<>')
|
|
|
|
describe "when the menus are specified in a legacy format", ->
|
|
beforeEach ->
|
|
jasmine.snapshotDeprecations()
|
|
|
|
afterEach ->
|
|
jasmine.restoreDeprecationsSnapshot()
|
|
|
|
it "allows items to be specified in the legacy format for now", ->
|
|
contextMenu.add '.parent':
|
|
'A': 'a'
|
|
'Separator 1': '-'
|
|
'B':
|
|
'C': 'c'
|
|
'Separator 2': '-'
|
|
'D': 'd'
|
|
|
|
expect(contextMenu.templateForElement(parent)).toEqual [
|
|
{label: 'A', command: 'a'}
|
|
{type: 'separator'}
|
|
{
|
|
label: 'B'
|
|
submenu: [
|
|
{label: 'C', command: 'c'}
|
|
{type: 'separator'}
|
|
{label: 'D', command: 'd'}
|
|
]
|
|
}
|
|
]
|