highlight multiple lines

We can now highlight multiple lines, adding #L1-L2 to the hash.
We can select the ending line with shift + click.

Closes travis-ci/travis-ci#1829
This commit is contained in:
Damien Mathieu 2014-01-07 11:18:15 +01:00
parent d569938687
commit c9e0f07a5a
9 changed files with 86 additions and 28 deletions

View File

@ -2,7 +2,7 @@ Travis.BuildController = Ember.Controller.extend
needs: ['repo'] needs: ['repo']
repoBinding: 'controllers.repo.repo' repoBinding: 'controllers.repo.repo'
commitBinding: 'build.commit' commitBinding: 'build.commit'
lineNumberBinding: 'controllers.repo.lineNumber' lineNumbersBinding: 'controllers.repo.lineNumbers'
currentUserBinding: 'controllers.repo.currentUser' currentUserBinding: 'controllers.repo.currentUser'
tabBinding: 'controllers.repo.tab' tabBinding: 'controllers.repo.tab'

View File

@ -4,7 +4,7 @@ Travis.JobController = Em.Controller.extend
jobBinding: 'controllers.repo.job' jobBinding: 'controllers.repo.job'
repoBinding: 'controllers.repo.repo' repoBinding: 'controllers.repo.repo'
commitBinding: 'job.commit' commitBinding: 'job.commit'
lineNumberBinding: 'controllers.repo.lineNumber' lineNumbersBinding: 'controllers.repo.lineNumbers'
currentUserBinding: 'controllers.repo.currentUser' currentUserBinding: 'controllers.repo.currentUser'
tabBinding: 'controllers.repo.tab' tabBinding: 'controllers.repo.tab'

View File

@ -72,3 +72,13 @@ Travis.RepoController = Travis.Controller.extend
urlGithub: (-> urlGithub: (->
Travis.Urls.githubRepo(@get('repo.slug')) Travis.Urls.githubRepo(@get('repo.slug'))
).property('repo.slug') ).property('repo.slug')
setLineNumbers: (start, end) ->
lines = []
index = start
while index <= (end || start)
lines.push(index)
index++
@set('lineNumbers', lines)

View File

@ -82,7 +82,7 @@ Ember.Route.reopen
Travis.Router.reopen Travis.Router.reopen
transitionTo: -> transitionTo: ->
this.container.lookup('controller:repo').set('lineNumber', null) this.container.lookup('controller:repo').set('lineNumbers', [])
@_super.apply this, arguments @_super.apply this, arguments
@ -113,7 +113,8 @@ Travis.ApplicationRoute = Ember.Route.extend Travis.LineNumberParser,
setupController: -> setupController: ->
@_super.apply this, arguments @_super.apply this, arguments
this.controllerFor('repo').set('lineNumber', @fetchLineNumber()) line_numbers = @fetchLineNumbers(document.location.hash)
this.controllerFor('repo').setLineNumbers line_numbers[0], line_numbers[1]
Travis.SetupLastBuild = Ember.Mixin.create Travis.SetupLastBuild = Ember.Mixin.create
setupController: -> setupController: ->

View File

@ -26,7 +26,7 @@ Travis.reopen
console.log 'log view: did insert' if Log.DEBUG console.log 'log view: did insert' if Log.DEBUG
@_super.apply this, arguments @_super.apply this, arguments
@createEngine() @createEngine()
@lineNumberDidChange() @lineNumbersDidChange()
willDestroyElement: -> willDestroyElement: ->
console.log 'log view: will destroy' if Log.DEBUG console.log 'log view: will destroy' if Log.DEBUG
@ -63,9 +63,9 @@ Travis.reopen
@engine.set(part.number, part.content) @engine.set(part.number, part.content)
@propertyDidChange('limited') @propertyDidChange('limited')
lineNumberDidChange: (-> lineNumbersDidChange: (->
@scroll.set(number) if !@get('isDestroyed') && number = @get('controller.lineNumber') @scroll.set(numbers) if !@get('isDestroyed') && numbers = @get('controller.lineNumbers')
).observes('controller.lineNumber') ).observes('controller.lineNumbers')
limited: (-> limited: (->
@engine?.limit?.limited @engine?.limit?.limited
@ -80,22 +80,35 @@ Travis.reopen
event.preventDefault() event.preventDefault()
numberLineOnHover: -> numberLineOnHover: ->
$('#log').on 'mouseenter', 'a', -> $('#log').on 'mouseenter', 'a', (event) ->
$(@).attr('href', '#L' + ($("#log p:visible").index(@parentNode) + 1)) hovered = $("#log p:visible").index(@parentNode) + 1
selected = $("#log p:visible").index($('#log p.highlight')) + 1
if event.shiftKey
end = "-L#{hovered}"
start = selected
else
start = hovered
end = ''
$(@).attr('href', "#L#{start}#{end}")
click: (event) -> click: (event) ->
if (href = $(event.target).attr('href')) && matches = href?.match(/#L(\d+)$/) if (href = $(event.target).attr('href')) && matches = href?.match(Travis.LineNumberRegex)
@lineNumberClicked(matches[1]) lines = [matches[1], matches[3]].sort (a, b) -> a - b
@lineNumberClicked(lines[0], lines[1])
event.stopPropagation() event.stopPropagation()
false false
else else
target = $(event.target) target = $(event.target)
target.closest('.fold').toggleClass('open') target.closest('.fold').toggleClass('open')
lineNumberClicked: (number) -> lineNumberClicked: (start, end) ->
path = "#{window.location.pathname}#L#{number}" second_number = if end then "-L#{end}" else ''
path = "#{window.location.pathname}#L#{start}#{second_number}"
window.history.pushState({ path: path }, null, path); window.history.pushState({ path: path }, null, path);
@set('controller.lineNumber', number) @get('controller.controllers.repo').setLineNumbers(start, end)
actions: actions:
toTop: () -> toTop: () ->
@ -105,25 +118,32 @@ Travis.reopen
Log.Scroll = -> Log.Scroll = ->
Log.Scroll.prototype = $.extend new Log.Listener, Log.Scroll.prototype = $.extend new Log.Listener,
set: (number) -> set: (numbers) ->
return unless number return unless numbers.length > 0
@number = number @numbers = numbers
@tryScroll() @tryScroll()
insert: (log, data, pos) -> insert: (log, data, pos) ->
@tryScroll() if @number @tryScroll() if @numbers
true true
tryScroll: -> tryScroll: ->
if element = $("#log p:visible")[@number - 1] @removeHighlights()
@scrollToFirstLine()
first_line = @numbers[0] - 1
last_line = @numbers[@numbers.length - 1]
$('#log').find('p:visible').slice(first_line, last_line).addClass('highlight')
@numbers = undefined
removeHighlights: ->
$('#log p.highlight').removeClass('highlight')
scrollToFirstLine: ->
if element = $("#log p:visible")[@numbers[0] - 1]
$('#main').scrollTop(0) $('#main').scrollTop(0)
$('html, body').scrollTop($(element).offset()?.top) # weird, html works in chrome, body in firefox $('html, body').scrollTop($(element).offset()?.top) # weird, html works in chrome, body in firefox
@highlight(element)
@number = undefined
highlight: (element) ->
$('#log p.highlight').removeClass('highlight')
$(element).addClass('highlight')
# Log.Logger = -> # Log.Logger = ->
# Log.Logger.prototype = $.extend new Log.Listener, # Log.Logger.prototype = $.extend new Log.Listener,

View File

@ -1,3 +1,14 @@
Travis.LineNumberRegex = /#L(\d+)(-L(\d+))?$/
Travis.LineNumberParser = Ember.Mixin.create Travis.LineNumberParser = Ember.Mixin.create
fetchLineNumber: ->
match[1] if match = document.location.hash.match(/#L(\d+)$/) fetchLineNumbers: (hash) ->
if match = hash.match(Travis.LineNumberRegex)
start = match[1]
end = match[3]
if end?
[start, end]
else
[start]
else
[]

View File

@ -0,0 +1,12 @@
object = Ember.Object.extend(Travis.LineNumberParser)
subject = object.create()
module "Travis.LineNumberParser",
test "without line numbers", ->
deepEqual subject.fetchLineNumbers(''), []
test "with a start date only", ->
deepEqual subject.fetchLineNumbers('#L5'), ['5']
test "with a start and end dates", ->
deepEqual subject.fetchLineNumbers('#L5-L6'), ['5', '6']

View File

@ -23,6 +23,7 @@ $yellow-light-2: #fffcf4
$gray-dark-1: #333 $gray-dark-1: #333
$gray-dark-2: #444 $gray-dark-2: #444
$gray-dark-3: #666 $gray-dark-3: #666
$gray-dark-4: #777
$gray-medium-1: #999 $gray-medium-1: #999
$gray-medium-2: #aaa $gray-medium-2: #aaa
$gray-medium-3: #c4cbcc $gray-medium-3: #c4cbcc
@ -65,6 +66,7 @@ $color-bg-log: #222222
$color-bg-log-fold: $gray-dark-1 $color-bg-log-fold: $gray-dark-1
$color-bg-log-hover: $gray-dark-2 $color-bg-log-hover: $gray-dark-2
$color-bg-log-highlight: $gray-dark-3 $color-bg-log-highlight: $gray-dark-3
$color-bg-log-fold-highlight: $gray-dark-4
$color-bg-slider: $slate-blue-3 $color-bg-slider: $slate-blue-3
$color-bg-left: $gray-light-4 $color-bg-left: $gray-light-4
$color-bg-list-odd: $white $color-bg-list-odd: $white

View File

@ -57,6 +57,8 @@ pre#log
// &.active // &.active
p:first-of-type p:first-of-type
background: $color-bg-log-fold inline-image('ui/log.fold.open.2.png') no-repeat 8px 3px background: $color-bg-log-fold inline-image('ui/log.fold.open.2.png') no-repeat 8px 3px
&.highlight
background-color: $color-bg-log-fold-highlight
&:not(.open) p:first-of-type &:not(.open) p:first-of-type
visibility: visible visibility: visible