diff --git a/src/packages/command-logger/index.coffee b/src/packages/command-logger/index.coffee new file mode 100644 index 000000000..4bff38c81 --- /dev/null +++ b/src/packages/command-logger/index.coffee @@ -0,0 +1 @@ +module.exports = require 'command-logger/src/command-logger' diff --git a/src/packages/command-logger/spec/command-logger-spec.coffee b/src/packages/command-logger/spec/command-logger-spec.coffee new file mode 100644 index 000000000..8e7da0f4c --- /dev/null +++ b/src/packages/command-logger/spec/command-logger-spec.coffee @@ -0,0 +1,50 @@ +RootView = require 'root-view' +CommandLogger = require 'command-logger' + +describe "CommandLogger", -> + [rootView, commandLogger, editor] = [] + + beforeEach -> + rootView = new RootView(require.resolve('fixtures/sample.js')) + rootView.activateExtension(CommandLogger) + editor = rootView.getActiveEditor() + commandLogger = CommandLogger.instance + rootView.attachToDom() + + afterEach -> + rootView.deactivate() + + describe "when a command is triggered", -> + it "records the number of times the command is triggered", -> + expect(commandLogger.eventLog['core:backspace']).toBeUndefined() + editor.trigger 'core:backspace' + expect(commandLogger.eventLog['core:backspace'].count).toBe 1 + editor.trigger 'core:backspace' + expect(commandLogger.eventLog['core:backspace'].count).toBe 2 + + it "records the date the command was last triggered", -> + expect(commandLogger.eventLog['core:backspace']).toBeUndefined() + editor.trigger 'core:backspace' + lastRun = commandLogger.eventLog['core:backspace'].lastRun + expect(lastRun).toBeGreaterThan 0 + advanceClock(100) + editor.trigger 'core:backspace' + expect(commandLogger.eventLog['core:backspace'].lastRun).toBeGreaterThan lastRun + + describe "when the data is cleared", -> + it "removes all triggered events from the log", -> + expect(commandLogger.eventLog['core:backspace']).toBeUndefined() + editor.trigger 'core:backspace' + expect(commandLogger.eventLog['core:backspace'].count).toBe 1 + rootView.trigger 'command-logger:clear-data' + expect(commandLogger.eventLog['core:backspace']).toBeUndefined() + + describe "when the command logger is toggled", -> + it "displays all the commands triggered", -> + editor.trigger 'core:backspace' + editor.trigger 'core:backspace' + rootView.trigger 'command-logger:toggle' + expect(rootView.find('.command-logger > li > .event-count:eq(0)')).toHaveText '2' + expect(rootView.find('.command-logger > li > .event-description:eq(0)')).toHaveText 'Core: Backspace' + expect(rootView.find('.command-logger > li > .event-count:eq(1)')).toHaveText '1' + expect(rootView.find('.command-logger > li > .event-description:eq(1)')).toHaveText 'Command Logger: Toggle' diff --git a/src/packages/command-logger/src/command-logger.coffee b/src/packages/command-logger/src/command-logger.coffee new file mode 100644 index 000000000..f4755a4a6 --- /dev/null +++ b/src/packages/command-logger/src/command-logger.coffee @@ -0,0 +1,67 @@ +{View, $$, $$$} = require 'space-pen' +ScrollView = require 'scroll-view' +$ = require 'jquery' +_ = require 'underscore' + +module.exports = +class CommandLogger extends ScrollView + @activate: (rootView, state) -> + @instance = new CommandLogger(rootView, state?.eventLog) + + @content: (rootView) -> + @ol class: 'command-logger', tabindex: -1 + + @serialize: -> + @instance.serialize() + + eventLog: null + + initialize: (@rootView, @eventLog={}) -> + super + + requireStylesheet 'command-logger.css' + + @rootView.command 'command-logger:toggle', => @toggle() + @rootView.command 'command-logger:clear-data', => @eventLog = {} + @command 'core:cancel', => @detach() + + registerEvent = (eventName) => + eventNameLog = @eventLog[eventName] + unless eventNameLog + eventNameLog = count: 0, name: eventName + @eventLog[eventName] = eventNameLog + eventNameLog.count++ + eventNameLog.lastRun = new Date().getTime() + + originalTrigger = $.fn.trigger + $.fn.trigger = (eventName) -> + eventName = eventName.type if eventName.type + registerEvent(eventName) if $(this).events()[eventName] + originalTrigger.apply(this, arguments) + + toggle: -> + if @hasParent() + @detach() + else + @attach() + + getHtml: -> + sorted = _.sortBy(@eventLog, (event) => -event.count) + $$$ -> + for eventName, details of sorted + @li => + @span "#{details.count}", class: 'event-count' + @span "#{_.humanizeEventName(details.name)}", class: 'event-description' + @span "Last run on #{new Date(details.lastRun).toString()}", class: 'event-last-run' + + attach: -> + @rootView.append(this) + @html(@getHtml()) + @focus() + + detach: -> + super() + @rootView.focus() + + serialize: -> + eventLog: @eventLog diff --git a/static/command-logger.css b/static/command-logger.css new file mode 100644 index 000000000..89730a4cb --- /dev/null +++ b/static/command-logger.css @@ -0,0 +1,25 @@ +.command-logger { + position: absolute; + width: 100%; + height: 100%; + top: 0px; + left: 0px; + background: #1e1e1e; + color: #d2d2d2; + overflow: auto; + opacity: 0.85; + z-index: 99; + padding: 20px; +} + +.command-logger li { + padding: 5px; +} + +.command-logger .event-count { + padding-right: 10px; +} + +.command-logger .event-description { + padding-right: 10px; +}