diff --git a/assets/scripts/app/app.coffee b/assets/scripts/app/app.coffee
index 3f5adc8e..4e16be6f 100644
--- a/assets/scripts/app/app.coffee
+++ b/assets/scripts/app/app.coffee
@@ -33,7 +33,7 @@ unless window.TravisApplication
@slider = new Travis.Slider()
@pusher = new Travis.Pusher(Travis.config.pusher_key) if Travis.config.pusher_key
- @tailing = new Travis.Tailing($(window), '#tail', '#log')
+ @tailing = new Travis.Tailing()
@set('auth', Travis.Auth.create(app: this, endpoint: Travis.config.api_endpoint))
diff --git a/assets/scripts/app/components.coffee b/assets/scripts/app/components.coffee
new file mode 100644
index 00000000..da423edd
--- /dev/null
+++ b/assets/scripts/app/components.coffee
@@ -0,0 +1,9 @@
+Travis.TravisSwitchComponent = Ember.Component.extend
+ tagName: 'a'
+ classNames: ['travis-switch']
+ classNameBindings: ['active']
+
+ activeBinding: 'target.active'
+
+ click: ->
+ @sendAction('action', @get('target'))
diff --git a/assets/scripts/app/tailing.coffee b/assets/scripts/app/tailing.coffee
index 3df8c872..fab3fec8 100644
--- a/assets/scripts/app/tailing.coffee
+++ b/assets/scripts/app/tailing.coffee
@@ -1,17 +1,12 @@
-class @Travis.Tailing
+@Travis.Tailing = ->
+ @position = $(window).scrollTop()
+ $(window).scroll( $.throttle( 200, @onScroll.bind(this) ) )
+ this
+
+$.extend Travis.Tailing.prototype,
options:
timeout: 200
- tail: ->
- $(@tail_selector)
- log: ->
- $(@log_selector)
-
- constructor: (@window, @tail_selector, @log_selector) ->
- @position = @window.scrollTop()
- @window.scroll( $.throttle( 200, @onScroll.bind(this) ) )
- this
-
run: ->
@autoScroll()
@positionButton()
@@ -21,43 +16,37 @@ class @Travis.Tailing
if @active() then @stop() else @start()
active: ->
- @tail().hasClass('active')
+ $('#tail').hasClass('active')
start: ->
- @tail().addClass('active')
+ $('#tail').addClass('active')
@run()
stop: ->
- @tail().removeClass('active')
+ $('#tail').removeClass('active')
autoScroll: ->
- return false unless @active()
- logBottom = @log().offset().top + @log().outerHeight() + 40
- winBottom = @window.scrollTop() + @window.height()
-
- if logBottom - winBottom > 0
- @window.scrollTop(logBottom - @window.height())
- true
- else
- false
+ return unless @active()
+ win = $(window)
+ log = $('#log')
+ logBottom = log.offset().top + log.outerHeight() + 40
+ winBottom = win.scrollTop() + win.height()
+ win.scrollTop(logBottom - win.height()) if logBottom - winBottom > 0
onScroll: ->
@positionButton()
- position = @window.scrollTop()
+ position = $(window).scrollTop()
@stop() if position < @position
@position = position
positionButton: ->
- return if @tail().length is 0
- offset = @window.scrollTop() - @log().offset().top
- max = @log().height() - @tail().height() + 5
-
- if offset > 0 && offset <= max
- @tail().removeClass('bottom')
- @tail().addClass('scrolling')
+ tail = $('#tail')
+ return if tail.length is 0
+ offset = $(window).scrollTop() - $('#log').offset().top
+ max = $('#log').height() - $('#tail').height() + 5
+ offset = max if offset > max
+ if offset > 0
+ tail.css(top: offset - 2)
else
- if offset > max
- @tail().addClass('bottom')
- else
- @tail().removeClass('bottom')
- @tail().removeClass('scrolling')
+ tail.css(top: 0)
+
diff --git a/assets/scripts/app/templates/components/travis-switch.hbs b/assets/scripts/app/templates/components/travis-switch.hbs
new file mode 100644
index 00000000..e7b20837
--- /dev/null
+++ b/assets/scripts/app/templates/components/travis-switch.hbs
@@ -0,0 +1,5 @@
+{{#if active}}
+ ON
+{{else}}
+ OFF
+{{/if}}
diff --git a/assets/scripts/app/templates/jobs/pre.hbs b/assets/scripts/app/templates/jobs/pre.hbs
index c3aee48e..b8259c2c 100644
--- a/assets/scripts/app/templates/jobs/pre.hbs
+++ b/assets/scripts/app/templates/jobs/pre.hbs
@@ -1,14 +1,7 @@
-
-
+
diff --git a/assets/scripts/app/templates/layouts/top.hbs b/assets/scripts/app/templates/layouts/top.hbs
index 0f583cf6..fef5be50 100644
--- a/assets/scripts/app/templates/layouts/top.hbs
+++ b/assets/scripts/app/templates/layouts/top.hbs
@@ -7,7 +7,7 @@
{{#link-to "index.current"}}{{t layouts.top.home}}{{/link-to}}
- {{t layouts.top.blog}}
+ {{t layouts.top.blog}}
{{t layouts.top.status}}
@@ -17,8 +17,8 @@
Help
{{else}}
diff --git a/assets/scripts/app/views/log.coffee b/assets/scripts/app/views/log.coffee
index 631765b3..87bf913b 100644
--- a/assets/scripts/app/views/log.coffee
+++ b/assets/scripts/app/views/log.coffee
@@ -47,7 +47,7 @@ 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)
+ @lineSelector = new Travis.LinesSelector(@$().find('#log'), @scroll)
@observeParts()
observeParts: ->
diff --git a/assets/scripts/lib/travis/lines_selector.coffee b/assets/scripts/lib/travis/lines_selector.coffee
index e49a456e..ba4242cb 100644
--- a/assets/scripts/lib/travis/lines_selector.coffee
+++ b/assets/scripts/lib/travis/lines_selector.coffee
@@ -1,10 +1,19 @@
class Travis.LinesSelector
+ Location:
+ getHash: ->
+ window.location.hash
+
+ setHash: (hash) ->
+ path = "#{window.location.pathname}#{hash}"
+ window.history.pushState({ path: path }, null, path);
+
element: null
scroll: null
location: null
last_selected_line: null
- constructor: (@element, @scroll, @location) ->
+ constructor: (@element, @scroll, location) ->
+ @location = location || @Location
Ember.run.scheduleOnce 'afterRender', this, ->
@last_selected_line = @getSelectedLines()?.first
@highlightLines()
@@ -17,7 +26,7 @@ class Travis.LinesSelector
false
willDestroy: ->
- @location.hash = ''
+ @location.setHash('')
loadLineNumbers: (element, multiple) ->
@setHashValueWithLine(element, multiple)
@@ -40,7 +49,7 @@ class Travis.LinesSelector
hash = "#L#{line_number}"
@last_selected_line = line_number
- @location.hash = hash
+ @location.setHash(hash)
getLineNumberFromElement: (element) ->
@element.find('p:visible').index(element) + 1
@@ -49,7 +58,7 @@ class Travis.LinesSelector
@element.find('p.highlight').removeClass('highlight')
getSelectedLines: ->
- if match = @location.hash.match(/#L(\d+)(-L(\d+))?$/)
+ if match = @location.getHash().match(/#L(\d+)(-L(\d+))?$/)
first = match[1]
last = match[3] || match[1]
{first: first, last: last}
diff --git a/assets/scripts/spec/unit/line_selector_spec.coffee b/assets/scripts/spec/unit/line_selector_spec.coffee
index cbd4f12b..04e882cf 100644
--- a/assets/scripts/spec/unit/line_selector_spec.coffee
+++ b/assets/scripts/spec/unit/line_selector_spec.coffee
@@ -1,4 +1,10 @@
-fakeLocation = {}
+fakeLocation = {
+ getHash: ->
+ @hash || ''
+ setHash: (hash) ->
+ @hash = hash
+}
+
fakeScroll =
tryScroll: sinon.spy()
diff --git a/assets/scripts/spec/unit/tailing_spec.coffee b/assets/scripts/spec/unit/tailing_spec.coffee
deleted file mode 100644
index 18a836f0..00000000
--- a/assets/scripts/spec/unit/tailing_spec.coffee
+++ /dev/null
@@ -1,89 +0,0 @@
-fakeWindow =
- scroll: sinon.spy()
- scrollTop: sinon.stub().returns(0)
- height: sinon.stub().returns(40)
-element = jQuery('
')
-log = jQuery('
')
-tail = new Travis.Tailing(fakeWindow, '#specTail', '#specLog')
-tail.tail = -> element
-tail.log = -> log
-
-module "Travis.Tailing",
- setup: ->
- jQuery('body').append(element)
- jQuery('body').append(log)
-
- teardown: ->
- element.remove()
- log.remove()
- tail.stop()
-
-test "toggle", ->
- equal(element.hasClass('active'), false)
- tail.toggle()
- equal(element.hasClass('active'), true)
- tail.toggle()
- stop()
-
- Ember.run.later ->
- start()
- equal(element.hasClass('active'), false)
- , 300
-
-test "active", ->
- equal(tail.active(), false)
- element.addClass('active')
- equal(tail.active(), true)
-
-test "autoscroll when inactive", ->
- tail.scrollTo = sinon.spy()
-
- equal(tail.active(), false)
- equal(tail.autoScroll(), false)
- equal(tail.scrollTo.called, false)
-
-test "autoscroll", ->
- element.addClass('active')
- log.offset = -> {top: 1}
- log.outerHeight = -> 1
-
- equal(tail.active(), true)
- equal(tail.autoScroll(), true)
- equal(fakeWindow.scrollTop.calledWith(2), true)
-
-test "autoscroll when we're at the bottom", ->
- element.addClass('active')
- log.offset = -> {top: 0}
- log.outerHeight = -> 0
-
- equal(tail.active(), true)
- equal(tail.autoScroll(), false)
- equal(fakeWindow.scrollTop.calledWith(0), false)
-
-test 'should stop scrolling if the position changed', ->
- element.addClass('active')
- tail.position = 100
- tail.onScroll()
- equal(element.hasClass('active'), false)
-
-test 'positionButton adds the scrolling class', ->
- log.offset = -> {top: -1}
-
- tail.positionButton()
- equal(element.hasClass('scrolling'), true)
- equal(element.hasClass('bottom'), false)
-
-test 'positionButton removes the scrolling class', ->
- log.offset = -> {top: 1}
- tail.positionButton()
- equal(element.hasClass('scrolling'), false)
- equal(element.hasClass('bottom'), false)
-
-test 'positionButton sets the button as bottom', ->
- log.offset = -> {top: -100}
- log.height = -> 50
- tail.height = -> 1
-
- tail.positionButton()
- equal(element.hasClass('scrolling'), false)
- equal(element.hasClass('bottom'), true)
diff --git a/assets/scripts/travis.coffee b/assets/scripts/travis.coffee
index 2491ca60..95770a69 100644
--- a/assets/scripts/travis.coffee
+++ b/assets/scripts/travis.coffee
@@ -167,6 +167,7 @@ require 'slider'
require 'tailing'
require 'templates'
require 'views'
+require 'components'
require 'config/locales'
diff --git a/assets/styles/components/travis-switch.sass b/assets/styles/components/travis-switch.sass
new file mode 100644
index 00000000..342aaac6
--- /dev/null
+++ b/assets/styles/components/travis-switch.sass
@@ -0,0 +1,33 @@
+.travis-switch
+ position: relative
+ display: block
+ width: 60px
+ height: 18px
+ margin: 0 10px 0 15px
+ padding: 0 10px 0 0
+ border: 1px solid #bdbdbd
+ line-height: 21px
+ font-size: 11px
+ color: #999
+ cursor: pointer
+ text-align: right
+ &:before
+ content: ""
+ position: absolute
+ top: -1px
+ left: -1px
+ width: 28px
+ height: 18px
+ background: #e9e9e7
+ border: 1px solid #bdbdbd
+
+.travis-switch.active
+ width: 56px
+ padding: 0 0 0 14px
+ background: #40454f
+ border: 1px solid #bdbdbd
+ color: #fff
+ text-align: left
+ &:before
+ left: auto
+ right: -1px
diff --git a/assets/styles/main/log.sass b/assets/styles/main/log.sass
index d5793a54..a6083550 100644
--- a/assets/styles/main/log.sass
+++ b/assets/styles/main/log.sass
@@ -88,66 +88,44 @@ pre#log
#log-container
position: relative
-#log-container
- #tail
- z-index: 99
- position: absolute
- display: block
- top: 0
- right: 2px
- margin: 13px 10px 0 0
- padding: 0 2px 0 3px
- color: #666
- text-shadow: 0px 1px 0px #fff
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif
- font-size: $font-size-tiny
- line-height: 14px
- text-decoration: none
- white-space: nowrap
- border: 1px solid #bbb
- border-top-color: #ddd
- border-bottom-color: #bbb
- @include border-radius(8px)
- @include background(linear-gradient(#fff, #e0e0e0))
+#log-container #tail
+ z-index: 99
+ position: absolute
+ display: block
+ top: 0
+ right: 2px
+ margin: 13px 10px 0 0
+ padding: 0 2px 0 3px
+ color: #666
+ text-shadow: 0px 1px 0px #fff
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif
+ font-size: $font-size-tiny
+ line-height: 14px
+ text-decoration: none
+ white-space: nowrap
+ border: 1px solid #bbb
+ border-top-color: #ddd
+ border-bottom-color: #bbb
+ @include border-radius(8px)
+ @include background(linear-gradient(#fff, #e0e0e0))
+ label
+ display: none
+ cursor: pointer
+
+ &:hover
+ padding: 1px 4px 1px 6px
label
- display: none
- cursor: pointer
+ display: inline
- &:hover
- padding: 1px 4px 1px 6px
- label
- display: inline
-
- &.scrolling
- position: fixed
- right: 32px
-
- &.bottom
- bottom: 45px
- top: inherit
-
- .status
- display: inline-block
- margin-right: 1px
- width: 8px
- height: 8px
- background-color: #aaa
- @include border-radius(4px)
- @include box-shadow(white 1px 1px 2px)
-
- &.active .status
- background-color: #6b0
-
- .to-top
- position: fixed
+ .status
display: inline-block
- bottom: 5px
- right: 35px
- width: 50px
- float: right
- margin-right: 2px
- padding-right: 16px
- text-align: right
- color: #999
- background: inline-image('ui/to-top.png') no-repeat right 6px
+ margin-right: 1px
+ width: 8px
+ height: 8px
+ background-color: #aaa
+ @include border-radius(4px)
+ @include box-shadow(white 1px 1px 2px)
+
+ &.active .status
+ background-color: #6b0
diff --git a/assets/styles/main/sponsors.sass b/assets/styles/main/sponsors.sass
index e5c79998..cfbbdc16 100644
--- a/assets/styles/main/sponsors.sass
+++ b/assets/styles/main/sponsors.sass
@@ -3,3 +3,12 @@
// float: left
margin-top: 0
color: #999
+ .to-top
+ display: inline-block
+ width: 50px
+ float: right
+ margin-right: 2px
+ padding-right: 16px
+ text-align: right
+ color: #999
+ background: inline-image('ui/to-top.png') no-repeat right 6px
diff --git a/assets/styles/profile/hooks.sass b/assets/styles/profile/hooks.sass
index 6c003d4a..2411c8ee 100644
--- a/assets/styles/profile/hooks.sass
+++ b/assets/styles/profile/hooks.sass
@@ -66,41 +66,6 @@
padding-right: 0
background: inline-image('ui/repo-settings.png') no-repeat 3px 4px
- .switch
- position: relative
- display: block
- width: 60px
- height: 18px
- margin: 0 10px 0 15px
- padding: 0 10px 0 0
- border: 1px solid #bdbdbd
- line-height: 21px
- font-size: 11px
- color: #999
- cursor: pointer
- text-align: right
- &:before
- content: ""
- position: absolute
- top: -1px
- left: -1px
- width: 28px
- height: 18px
- background: #e9e9e7
- border: 1px solid #bdbdbd
-
- &.active .switch
- width: 56px
- padding: 0 0 0 14px
- background: #40454f
- border: 1px solid #bdbdbd
- color: #fff
- text-align: left
- &:before
- left: auto
- right: -1px
-
-
&:hover
> a
color: $color-link-highlight