From de3bbce29fe078be214bf434b1ad71857c8bbd4e Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Fri, 19 Oct 2012 11:24:40 -0600 Subject: [PATCH] Only show events w/ descriptions in EventPalette Also, auto-generate human readable event name in editor. This is a good example of how we could do this automatically for some kind of `onCommand`, `command`, `onInteractiveEvent` method that combines the event name, documentation string, and handler in one shot. --- spec/extensions/event-palette-spec.coffee | 15 +++++++---- spec/stdlib/jquery-extensions-spec.coffee | 14 +++++----- src/app/editor.coffee | 4 +++ .../event-palette/event-palette.coffee | 27 +++++++------------ .../event-palette/event-palette.css | 10 +++++++ src/stdlib/jquery-extensions.coffee | 8 +++--- src/stdlib/underscore-extensions.coffee | 11 ++++++++ static/atom.css | 4 +++ 8 files changed, 61 insertions(+), 32 deletions(-) diff --git a/spec/extensions/event-palette-spec.coffee b/spec/extensions/event-palette-spec.coffee index 346c63e88..b2764d5aa 100644 --- a/spec/extensions/event-palette-spec.coffee +++ b/spec/extensions/event-palette-spec.coffee @@ -18,9 +18,14 @@ describe "EventPalette", -> describe "when event-palette:toggle is triggered on the root view", -> it "shows a list of all valid events for the previously focused element, then focuses the mini-editor and selects the first event", -> - for [event, description] in rootView.getActiveEditor().events() - expect(palette.list.find(".event:contains(#{event})")).toExist() - + for eventName, description of rootView.getActiveEditor().events() + eventLi = palette.list.children("[data-event-name='#{eventName}']") + if description + expect(eventLi).toExist() + expect(eventLi.children('.event-name')).toHaveText(eventName) + expect(eventLi.children('.event-description')).toHaveText(description) + else + expect(eventLi).not.toExist() expect(palette.miniEditor.isFocused).toBeTruthy() expect(palette.find('.event:first')).toHaveClass 'selected' @@ -48,10 +53,10 @@ describe "EventPalette", -> it "detaches the palette, then focuses the previously focused element and emits the selected event on it", -> eventHandler = jasmine.createSpy 'eventHandler' activeEditor = rootView.getActiveEditor() - [eventName, description] = palette.array[4] + {eventName} = palette.array[5] activeEditor.preempt eventName, eventHandler - palette.confirmed(palette.array[4]) + palette.confirmed(palette.array[5]) expect(activeEditor.isFocused).toBeTruthy() expect(eventHandler).toHaveBeenCalled() diff --git a/spec/stdlib/jquery-extensions-spec.coffee b/spec/stdlib/jquery-extensions-spec.coffee index 6608d4eb8..21e8862a7 100644 --- a/spec/stdlib/jquery-extensions-spec.coffee +++ b/spec/stdlib/jquery-extensions-spec.coffee @@ -56,6 +56,7 @@ describe 'jQuery extensions', -> view.document 'a1': "A1: Waste perfectly-good steak" view.on 'a1', -> view.on 'a2', -> + view.on 'b1', -> # should not appear as a duplicate divB = view.find('#b') @@ -68,10 +69,9 @@ describe 'jQuery extensions', -> view.find('#c').on 'c', -> view.find('#d').on 'd', -> - expect(view.find('#c').events()).toEqual [ - ['c'], - ['b1', "B1: Super-sonic bomber"], - ['b2', "B2: Looks evil. Kinda is."], - ['a1', "A1: Waste perfectly-good steak"], - ['a2'] - ] + expect(view.find('#c').events()).toEqual + 'c': null + 'b1': "B1: Super-sonic bomber" + 'b2': "B2: Looks evil. Kinda is." + 'a1': "A1: Waste perfectly-good steak" + 'a2': null diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 6fb40ee1a..a56baac52 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -155,10 +155,14 @@ class Editor extends View 'editor:toggle-line-comments': @toggleLineCommentsInSelection 'editor:log-cursor-scope': @logCursorScope + documentation = {} for name, method of editorBindings + documentation[name] = _.humanizeEventName(name) do (name, method) => @on name, => method.call(this); false + @document(documentation) + getCursor: (index) -> @activeEditSession.getCursor(index) getCursors: -> @activeEditSession.getCursors() getLastCursor: -> @activeEditSession.getLastCursor() diff --git a/src/extensions/event-palette/event-palette.coffee b/src/extensions/event-palette/event-palette.coffee index 0b1951e35..c7373ca93 100644 --- a/src/extensions/event-palette/event-palette.coffee +++ b/src/extensions/event-palette/event-palette.coffee @@ -13,7 +13,7 @@ class EventPalette extends SelectList @viewClass: -> "#{super} event-palette" - filterKey: 0 # filter on the event name for now + filterKey: 'eventDescription' initialize: (@rootView) -> @on 'event-palette:toggle', => @cancel() @@ -21,29 +21,22 @@ class EventPalette extends SelectList attach: -> @previouslyFocusedElement = $(':focus') - @setArray(@previouslyFocusedElement.events()) + events = [] + for eventName, eventDescription of @previouslyFocusedElement.events() + events.push({eventName, eventDescription}) if eventDescription + @setArray(events) @appendTo(@rootView) @miniEditor.setText('') @miniEditor.focus() - itemForElement: ([eventName, description]) -> + itemForElement: ({eventName, eventDescription}) -> $$ -> - @li class: 'event', => + @li class: 'event', 'data-event-name': eventName, => + @div eventDescription, class: 'event-description' @div eventName, class: 'event-name' - @div description, class: 'event-description' + @div class: 'clear-float' - populateEventList: -> - events = @previouslyFocusedElement.events() - table = $$ -> - @table => - for [event, description] in events - @tr class: 'event', => - @td event, class: 'event-name' - @td description if description - - @eventList.html(table) - - confirmed: ([eventName, description]) -> + confirmed: ({eventName}) -> @cancel() @previouslyFocusedElement.trigger(eventName) diff --git a/src/extensions/event-palette/event-palette.css b/src/extensions/event-palette/event-palette.css index a04d80554..55927df35 100644 --- a/src/extensions/event-palette/event-palette.css +++ b/src/extensions/event-palette/event-palette.css @@ -6,3 +6,13 @@ .event-palette ol { max-height: 300px; } + +.event-palette ol .event-description { + float: left; + display: inline-block; +} + +.event-palette ol .event-name { + float: right; + display: inline-block; +} diff --git a/src/stdlib/jquery-extensions.coffee b/src/stdlib/jquery-extensions.coffee index e1752cec8..928e15c0a 100644 --- a/src/stdlib/jquery-extensions.coffee +++ b/src/stdlib/jquery-extensions.coffee @@ -56,10 +56,12 @@ $.fn.document = (eventDescriptions) -> $.fn.events = -> documentation = @data('documentation') ? {} - events = _.keys(@data('events') ? {}).map (eventName) -> - _.compact([eventName, documentation[eventName]]) + events = {} + + for eventName of @data('events') ? {} + events[eventName] = documentation[eventName] ? null if @hasParent() - events.concat(@parent().events()) + _.extend(@parent().events(), events) else events diff --git a/src/stdlib/underscore-extensions.coffee b/src/stdlib/underscore-extensions.coffee index 1fda906ee..1f58aadf4 100644 --- a/src/stdlib/underscore-extensions.coffee +++ b/src/stdlib/underscore-extensions.coffee @@ -51,3 +51,14 @@ _.mixin # even though only some strictly require it when inside of [] regex = RegExp('[' + specials.join('\\') + ']', 'g') string.replace(regex, "\\$&"); + + humanizeEventName: (eventName) -> + if /:/.test(eventName) + [namespace, name] = eventName.split(':') + return "#{@humanizeEventName(namespace)}: #{@humanizeEventName(name)}" + + words = eventName.split('-') + words.map(_.capitalize).join(' ') + + capitalize: (word) -> + word[0].toUpperCase() + word[1..] \ No newline at end of file diff --git a/static/atom.css b/static/atom.css index e11f60493..0197af4d6 100644 --- a/static/atom.css +++ b/static/atom.css @@ -68,3 +68,7 @@ html, body { background: #991212; -webkit-transition: background 200ms ease-out; } + +.clear-float { + clear: both; +}