extract the log lines selector into a separate component
This commit is contained in:
parent
c9e0f07a5a
commit
ff1aad3f03
|
@ -2,7 +2,6 @@ Travis.BuildController = Ember.Controller.extend
|
|||
needs: ['repo']
|
||||
repoBinding: 'controllers.repo.repo'
|
||||
commitBinding: 'build.commit'
|
||||
lineNumbersBinding: 'controllers.repo.lineNumbers'
|
||||
currentUserBinding: 'controllers.repo.currentUser'
|
||||
tabBinding: 'controllers.repo.tab'
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ Travis.JobController = Em.Controller.extend
|
|||
jobBinding: 'controllers.repo.job'
|
||||
repoBinding: 'controllers.repo.repo'
|
||||
commitBinding: 'job.commit'
|
||||
lineNumbersBinding: 'controllers.repo.lineNumbers'
|
||||
currentUserBinding: 'controllers.repo.currentUser'
|
||||
tabBinding: 'controllers.repo.tab'
|
||||
|
||||
|
|
|
@ -72,13 +72,3 @@ Travis.RepoController = Travis.Controller.extend
|
|||
urlGithub: (->
|
||||
Travis.Urls.githubRepo(@get('repo.slug'))
|
||||
).property('repo.slug')
|
||||
|
||||
setLineNumbers: (start, end) ->
|
||||
lines = []
|
||||
index = start
|
||||
|
||||
while index <= (end || start)
|
||||
lines.push(index)
|
||||
index++
|
||||
|
||||
@set('lineNumbers', lines)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
require 'travis/location'
|
||||
require 'travis/line_number_parser'
|
||||
|
||||
Ember.Router.reopen
|
||||
location: (if testMode? then Ember.NoneLocation.create() else Travis.Location.create())
|
||||
|
@ -80,12 +79,6 @@ Ember.Route.reopen
|
|||
Travis.storeAfterSignInPath(path)
|
||||
@transitionTo('auth')
|
||||
|
||||
Travis.Router.reopen
|
||||
transitionTo: ->
|
||||
this.container.lookup('controller:repo').set('lineNumbers', [])
|
||||
|
||||
@_super.apply this, arguments
|
||||
|
||||
Travis.Router.map ->
|
||||
@resource 'index', path: '/', ->
|
||||
@route 'current', path: '/'
|
||||
|
@ -109,13 +102,6 @@ Travis.Router.map ->
|
|||
@route 'index', path: '/'
|
||||
@route 'profile', path: '/profile'
|
||||
|
||||
Travis.ApplicationRoute = Ember.Route.extend Travis.LineNumberParser,
|
||||
setupController: ->
|
||||
@_super.apply this, arguments
|
||||
|
||||
line_numbers = @fetchLineNumbers(document.location.hash)
|
||||
this.controllerFor('repo').setLineNumbers line_numbers[0], line_numbers[1]
|
||||
|
||||
Travis.SetupLastBuild = Ember.Mixin.create
|
||||
setupController: ->
|
||||
@repoDidLoad()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require 'log'
|
||||
require 'travis/lines_selector'
|
||||
|
||||
Log.DEBUG = false
|
||||
Log.LIMIT = 10000
|
||||
|
@ -26,12 +27,12 @@ Travis.reopen
|
|||
console.log 'log view: did insert' if Log.DEBUG
|
||||
@_super.apply this, arguments
|
||||
@createEngine()
|
||||
@lineNumbersDidChange()
|
||||
|
||||
willDestroyElement: ->
|
||||
console.log 'log view: will destroy' if Log.DEBUG
|
||||
parts = @get('log.parts')
|
||||
parts.removeArrayObserver(@, didChange: 'partsDidChange', willChange: 'noop')
|
||||
@lineSelector?.willDestroy()
|
||||
|
||||
versionDidChange: (->
|
||||
@rerender() if @get('state') == 'inDOM'
|
||||
|
@ -46,8 +47,8 @@ Travis.reopen
|
|||
console.log 'log view: create engine' if Log.DEBUG
|
||||
@scroll = new Log.Scroll
|
||||
@engine = Log.create(limit: Log.LIMIT, listeners: [@scroll])
|
||||
@lineSelector = new Travis.LinesSelector(@$().find('#log'), @scroll, window.location)
|
||||
@observeParts()
|
||||
@numberLineOnHover()
|
||||
|
||||
observeParts: ->
|
||||
parts = @get('log.parts')
|
||||
|
@ -63,10 +64,6 @@ Travis.reopen
|
|||
@engine.set(part.number, part.content)
|
||||
@propertyDidChange('limited')
|
||||
|
||||
lineNumbersDidChange: (->
|
||||
@scroll.set(numbers) if !@get('isDestroyed') && numbers = @get('controller.lineNumbers')
|
||||
).observes('controller.lineNumbers')
|
||||
|
||||
limited: (->
|
||||
@engine?.limit?.limited
|
||||
).property()
|
||||
|
@ -79,37 +76,11 @@ Travis.reopen
|
|||
Travis.tailing.toggle()
|
||||
event.preventDefault()
|
||||
|
||||
numberLineOnHover: ->
|
||||
$('#log').on 'mouseenter', 'a', (event) ->
|
||||
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) ->
|
||||
if (href = $(event.target).attr('href')) && matches = href?.match(Travis.LineNumberRegex)
|
||||
lines = [matches[1], matches[3]].sort (a, b) -> a - b
|
||||
|
||||
@lineNumberClicked(lines[0], lines[1])
|
||||
event.stopPropagation()
|
||||
false
|
||||
else
|
||||
target = $(event.target)
|
||||
target = $(event.target)
|
||||
if target.prop('tagName') == 'P'
|
||||
target.closest('.fold').toggleClass('open')
|
||||
|
||||
lineNumberClicked: (start, end) ->
|
||||
second_number = if end then "-L#{end}" else ''
|
||||
path = "#{window.location.pathname}#L#{start}#{second_number}"
|
||||
window.history.pushState({ path: path }, null, path);
|
||||
@get('controller.controllers.repo').setLineNumbers(start, end)
|
||||
|
||||
actions:
|
||||
toTop: () ->
|
||||
$(window).scrollTop(0)
|
||||
|
@ -118,32 +89,14 @@ Travis.reopen
|
|||
|
||||
Log.Scroll = ->
|
||||
Log.Scroll.prototype = $.extend new Log.Listener,
|
||||
set: (numbers) ->
|
||||
return unless numbers.length > 0
|
||||
@numbers = numbers
|
||||
@tryScroll()
|
||||
|
||||
insert: (log, data, pos) ->
|
||||
@tryScroll() if @numbers
|
||||
true
|
||||
|
||||
tryScroll: ->
|
||||
@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]
|
||||
if element = $("#log p:visible.highlight:first")
|
||||
$('#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
|
||||
|
||||
# Log.Logger = ->
|
||||
# Log.Logger.prototype = $.extend new Log.Listener,
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
Travis.LineNumberRegex = /#L(\d+)(-L(\d+))?$/
|
||||
Travis.LineNumberParser = Ember.Mixin.create
|
||||
|
||||
fetchLineNumbers: (hash) ->
|
||||
if match = hash.match(Travis.LineNumberRegex)
|
||||
start = match[1]
|
||||
end = match[3]
|
||||
|
||||
if end?
|
||||
[start, end]
|
||||
else
|
||||
[start]
|
||||
else
|
||||
[]
|
53
assets/scripts/lib/travis/lines_selector.coffee
Normal file
53
assets/scripts/lib/travis/lines_selector.coffee
Normal file
|
@ -0,0 +1,53 @@
|
|||
class Travis.LinesSelector
|
||||
element: null
|
||||
scroll: null
|
||||
location: null
|
||||
|
||||
constructor: (@element, @scroll, @location) ->
|
||||
Ember.run.scheduleOnce 'afterRender', this, ->
|
||||
@highlightLines()
|
||||
|
||||
@element.on 'click', 'a', (event) =>
|
||||
element = $(event.target).parent('p')
|
||||
@loadLineNumbers(element, event.shiftKey)
|
||||
|
||||
event.preventDefault()
|
||||
false
|
||||
|
||||
willDestroy: ->
|
||||
@location.hash = ''
|
||||
|
||||
loadLineNumbers: (element, multiple) ->
|
||||
@setHashValueWithLine(element, multiple)
|
||||
@highlightLines()
|
||||
|
||||
highlightLines: ->
|
||||
@removeAllHighlights()
|
||||
|
||||
if lines = @getSelectedLines()
|
||||
@element.find('p:visible').slice(lines.first, lines.last).addClass('highlight')
|
||||
@scroll.tryScroll()
|
||||
|
||||
setHashValueWithLine: (line, multiple) ->
|
||||
line_number = @getLineNumberFromElement(line)
|
||||
|
||||
if !multiple
|
||||
hash = "#L#{line_number}"
|
||||
else
|
||||
selected_line = @element.find('p:visible.highlight:first')[0]
|
||||
selected_number = @getLineNumberFromElement(selected_line)
|
||||
lines = [line_number, selected_number].sort (a,b) -> a - b
|
||||
hash = "#L#{lines[0]}-L#{lines[1]}"
|
||||
@location.hash = hash
|
||||
|
||||
getLineNumberFromElement: (element) ->
|
||||
@element.find('p:visible').index(element) + 1
|
||||
|
||||
removeAllHighlights: ->
|
||||
@element.find('p.highlight').removeClass('highlight')
|
||||
|
||||
getSelectedLines: ->
|
||||
if match = @location.hash.match(/#L(\d+)(-L(\d+))?$/)
|
||||
first = match[1] - 1
|
||||
last = match[3] || match[1]
|
||||
{first: first, last: last}
|
|
@ -1,12 +0,0 @@
|
|||
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']
|
70
assets/scripts/spec/unit/line_selector_spec.coffee
Normal file
70
assets/scripts/spec/unit/line_selector_spec.coffee
Normal file
|
@ -0,0 +1,70 @@
|
|||
fakeLocation = {}
|
||||
fakeScroll =
|
||||
tryScroll: sinon.spy()
|
||||
|
||||
element = jQuery('<div id="fakeLog">
|
||||
<p><a></a>first line</p>
|
||||
<p><a></a>second line</p>
|
||||
<p><a></a>third line</p>
|
||||
</div>')
|
||||
|
||||
module "Travis.LinesSelector",
|
||||
setup: ->
|
||||
fakeLocation.hash = ''
|
||||
jQuery('body').append(element)
|
||||
|
||||
teardown: ->
|
||||
element.remove()
|
||||
|
||||
test "defaults to no line selected", ->
|
||||
Ember.run ->
|
||||
new Travis.LinesSelector(element, fakeScroll, fakeLocation)
|
||||
|
||||
wait().then ->
|
||||
equal($('#fakeLog p.highlight').length, 0)
|
||||
|
||||
test "defaults to a single line selected", ->
|
||||
fakeLocation.hash = '#L2'
|
||||
Ember.run ->
|
||||
new Travis.LinesSelector(element, fakeScroll, fakeLocation)
|
||||
|
||||
wait().then ->
|
||||
equal($('#fakeLog p.highlight').length, 1)
|
||||
equal($('#fakeLog p:nth-child(2)').hasClass('highlight'), true)
|
||||
|
||||
test "defaults to multiple lines selected", ->
|
||||
fakeLocation.hash = '#L2-L3'
|
||||
Ember.run ->
|
||||
new Travis.LinesSelector(element, fakeScroll, fakeLocation)
|
||||
|
||||
wait().then ->
|
||||
equal($('#fakeLog p.highlight').length, 2)
|
||||
equal($('#fakeLog p:nth-child(2)').hasClass('highlight'), true)
|
||||
equal($('#fakeLog p:nth-child(3)').hasClass('highlight'), true)
|
||||
|
||||
test "selects a single line", ->
|
||||
Ember.run ->
|
||||
new Travis.LinesSelector(element, fakeScroll, fakeLocation)
|
||||
|
||||
wait().then ->
|
||||
equal($('#fakeLog p.highlight').length, 0)
|
||||
$('#fakeLog p:first a').click()
|
||||
equal($('#fakeLog p.highlight').length, 1)
|
||||
equal($('#fakeLog p:nth-child(1)').hasClass('highlight'), true)
|
||||
equal('#L1', fakeLocation.hash)
|
||||
|
||||
test "selects multiple lines", ->
|
||||
fakeLocation.hash = '#L2'
|
||||
Ember.run ->
|
||||
new Travis.LinesSelector(element, fakeScroll, fakeLocation)
|
||||
wait().then ->
|
||||
equal($('#fakeLog p.highlight').length, 1)
|
||||
|
||||
event = jQuery.Event('click')
|
||||
event.shiftKey = true
|
||||
$('#fakeLog p:first a').trigger(event)
|
||||
|
||||
equal($('#fakeLog p.highlight').length, 2)
|
||||
equal($('#fakeLog p:nth-child(1)').hasClass('highlight'), true)
|
||||
equal($('#fakeLog p:nth-child(2)').hasClass('highlight'), true)
|
||||
equal('#L1-L2', fakeLocation.hash)
|
Loading…
Reference in New Issue
Block a user