Merge branch 'master' into settings-pane

Conflicts:
	assets/scripts/app/routes.coffee
	assets/scripts/app/templates/profile/tabs/hooks.hbs
This commit is contained in:
Hiro Asari 2014-01-17 07:09:04 -05:00
commit 8b6be08ef4
55 changed files with 46014 additions and 4188 deletions

View File

@ -31,6 +31,11 @@ input assets.scripts do
end
match 'vendor/**/*.js' do
if assets.production?
reject 'ember.js'
else
reject 'ember.prod.js'
end
safe_concat assets.vendor_order, 'vendor.js'
end

58
Gemfile
View File

@ -40,61 +40,3 @@ group :test do
gem 'sinatra-contrib'
end
require 'bundler/installer'
module ::Bundler
class Installer < Environment
MAX_RETRIES = 3
def install_gem_from_spec(spec, standalone = false)
retries = 1
# Download the gem to get the spec, because some specs that are returned
# by rubygems.org are broken and wrong.
Bundler::Fetcher.fetch(spec) if spec.source.is_a?(Bundler::Source::Rubygems)
# Fetch the build settings, if there are any
settings = Bundler.settings["build.#{spec.name}"]
Bundler.rubygems.with_build_args [settings] do
spec.source.install(spec)
Bundler.ui.debug "from #{spec.loaded_from} "
end
# newline comes after installing, some gems say "with native extensions"
Bundler.ui.info ""
if Bundler.settings[:bin] && standalone
generate_standalone_bundler_executable_stubs(spec)
elsif Bundler.settings[:bin]
generate_bundler_executable_stubs(spec, :force => true)
end
FileUtils.rm_rf(Bundler.tmp)
rescue Gem::RemoteFetcher::FetchError => e
if retries <= MAX_RETRIES
Bundler.ui.warn "#{e.class}: #{e.message}"
Bundler.ui.warn "Installing #{spec.name} (#{spec.version}) failed."
Bundler.ui.warn "Retrying (#{retries}/#{MAX_RETRIES})"
retries += 1
sleep retries
retry
else
Bundler.ui.warn "Installing #{spec.name} (#{spec.version}) failed after #{retries} retries: #{e.message}."
Bundler.ui.warn "Giving up"
msg = "An error, most likely because of network issues, has occurred trying to install #{spec.name} (#{spec.version}), "
msg << "and Bundler cannot continue."
raise Bundler::InstallError, msg
end
rescue Exception => e
# install hook failed
raise e if e.is_a?(Bundler::InstallHookError) || e.is_a?(Bundler::SecurityError)
# other failure, likely a native extension build failure
Bundler.ui.info ""
Bundler.ui.warn "#{e.class}: #{e.message}"
msg = "An error occurred while installing #{spec.name} (#{spec.version}),"
msg << " and Bundler cannot continue.\nMake sure that `gem install"
msg << " #{spec.name} -v '#{spec.version}'` succeeds before bundling."
Bundler.ui.debug e.backtrace.join("\n")
raise Bundler::InstallError, msg
end
end
end

View File

@ -10,7 +10,7 @@
# Handlebars
* Can't {{bindAttr}} be just {{attr}}? Who cares it's "bound" in that context?
* Can't {{bind-attr}} be just {{attr}}? Who cares it's "bound" in that context?
{{#each}} isn't {{#bindEach}} either.
* Why is {{#collection contentBinding="foo"}} not just {{#collection foo}}?

View File

@ -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()
@tailing = new Travis.Tailing($(window), '#tail', '#log')
@set('auth', Travis.Auth.create(app: this, endpoint: Travis.config.api_endpoint))

View File

@ -2,7 +2,6 @@ Travis.BuildController = Ember.Controller.extend
needs: ['repo']
repoBinding: 'controllers.repo.repo'
commitBinding: 'build.commit'
lineNumberBinding: 'controllers.repo.lineNumber'
currentUserBinding: 'controllers.repo.currentUser'
tabBinding: 'controllers.repo.tab'
@ -15,11 +14,3 @@ Travis.BuildController = Ember.Controller.extend
urlGithubCommit: (->
Travis.Urls.githubCommit(@get('repo.slug'), @get('commit.sha'))
).property('repo.slug', 'commit.sha')
urlAuthor: (->
Travis.Urls.email(@get('commit.authorEmail'))
).property('commit.authorEmail')
urlCommitter: (->
Travis.Urls.email(@get('commit.committerEmail'))
).property('commit.committerEmail')

View File

@ -4,7 +4,6 @@ Travis.JobController = Em.Controller.extend
jobBinding: 'controllers.repo.job'
repoBinding: 'controllers.repo.repo'
commitBinding: 'job.commit'
lineNumberBinding: 'controllers.repo.lineNumber'
currentUserBinding: 'controllers.repo.currentUser'
tabBinding: 'controllers.repo.tab'
@ -13,11 +12,3 @@ Travis.JobController = Em.Controller.extend
urlGithubCommit: (->
Travis.Urls.githubCommit(@get('repo.slug'), @get('commit.sha'))
).property('repo.slug', 'commit.sha')
urlAuthor: (->
Travis.Urls.email(@get('commit.authorEmail'))
).property('commit.authorEmail')
urlCommitter: (->
Travis.Urls.email(@get('commit.committerEmail'))
).property('commit.committerEmail')

View File

@ -75,19 +75,28 @@ require 'config/emoij'
self._githubReferenceLink(reference, { owner: owner, repo: repo }, { owner: matchedOwner, repo: matchedRepo, number: matchedNumber } )
text = text.replace @_githubUserRegexp, (reference, username) ->
self._githubUserLink(reference, username)
text = text.replace @_githubCommitReferenceRegexp, (reference, matchedOwner, matchedRepo, matchedSHA) ->
self._githubCommitReferenceLink(reference, { owner: owner, repo: repo }, { owner: matchedOwner, repo: matchedRepo, sha: matchedSHA })
text
_githubReferenceRegexp: new RegExp("([\\w-]+)?\\/?([\\w-]+)?(?:#|gh-)(\\d+)", 'g')
_githubReferenceLink: (reference, current, matched) ->
owner = matched.owner || current.owner
repo = matched.repo || current.repo
"<a href=\"http://github.com/#{owner}/#{repo}/issues/#{matched.number}\">#{reference}</a>"
_githubReferenceRegexp: new RegExp("([\\w-]+)?\\/?([\\w-]+)?(?:#|gh-)(\\d+)", 'g')
"<a href=\"https://github.com/#{owner}/#{repo}/issues/#{matched.number}\">#{reference}</a>"
_githubUserRegexp: new RegExp("\\B@([\\w-]+)", 'g')
_githubUserLink: (reference, username) ->
"<a href=\"http://github.com/#{username}\">#{reference}</a>"
"<a href=\"https://github.com/#{username}\">#{reference}</a>"
_githubCommitReferenceRegexp: new RegExp("([\\w-]+)?\\/([\\w-]+)?@([0-9A-Fa-f]+)", 'g')
_githubCommitReferenceLink: (reference, current, matched) ->
owner = matched.owner || current.owner
repo = matched.repo || current.repo
"<a href=\"https://github.com/#{owner}/#{repo}/commit/#{matched.sha}\">#{reference}</a>"
_normalizeDateString: (string) ->
if window.JHW

View File

@ -3,22 +3,22 @@
"#{Travis.config.api_endpoint}/jobs/#{id}/log.txt?deansi=true"
githubPullRequest: (slug, pullRequestNumber) ->
"http://github.com/#{slug}/pull/#{pullRequestNumber}"
"https://github.com/#{slug}/pull/#{pullRequestNumber}"
githubCommit: (slug, sha) ->
"http://github.com/#{slug}/commit/#{sha}"
"https://github.com/#{slug}/commit/#{sha}"
githubRepo: (slug) ->
"http://github.com/#{slug}"
"https://github.com/#{slug}"
githubWatchers: (slug) ->
"http://github.com/#{slug}/watchers"
"https://github.com/#{slug}/watchers"
githubNetwork: (slug) ->
"http://github.com/#{slug}/network"
"https://github.com/#{slug}/network"
githubAdmin: (slug) ->
"http://github.com/#{slug}/settings/hooks#travis_minibucket"
"https://github.com/#{slug}/settings/hooks#travis_minibucket"
statusImage: (slug, branch) ->
"#{location.protocol}//#{location.host}/#{slug}.png" + if branch then "?branch=#{branch}" else ''

View File

@ -7,7 +7,7 @@ require 'travis/model'
_reposCount: Ember.attr(Number, key: 'repos_count')
urlGithub: (->
"http://github.com/#{@get('login')}"
"https://github.com/#{@get('login')}"
).property()
# TODO: maybe it would be good to add a "default" value for Ember.attr

View File

@ -45,7 +45,7 @@ require 'travis/model'
).property('jobs.@each.allowFailure')
rawConfigKeys: (->
keys = Travis.Helpers.configKeys(@get('config'))
keys = []
@get('jobs').forEach (job) ->
Travis.Helpers.configKeys(job.get('config')).forEach (key) ->

View File

@ -16,11 +16,11 @@ require 'travis/model'
).property('ownerName', 'name')
urlGithub: (->
"http://github.com/#{@get('slug')}"
"https://github.com/#{@get('slug')}"
).property()
urlGithubAdmin: (->
"http://github.com/#{@get('slug')}/settings/hooks#travis_minibucket"
"https://github.com/#{@get('slug')}/settings/hooks#travis_minibucket"
).property()
toggle: ->

View File

@ -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())
@ -60,7 +59,6 @@ Ember.Route.reopen
if !@signedIn() && @get('needsAuth')
Travis.auth.set('afterSignInTransition', transition)
transition.abort()
Ember.RSVP.reject("needs-auth")
else
@_super.apply(this, arguments)
@ -116,12 +114,6 @@ Travis.Router.map ->
@route 'index', path: '/'
@route 'profile', path: '/profile'
Travis.ApplicationRoute = Ember.Route.extend Travis.LineNumberParser,
setupController: ->
@_super.apply this, arguments
this.controllerFor('repo').set('lineNumber', @fetchLineNumber())
Travis.SetupLastBuild = Ember.Mixin.create
setupController: ->
@repoDidLoad()

View File

@ -1,12 +1,17 @@
@Travis.Tailing = ->
@position = $(window).scrollTop()
$(window).scroll( $.throttle( 200, @onScroll.bind(this) ) )
this
$.extend Travis.Tailing.prototype,
class @Travis.Tailing
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()
@ -16,38 +21,43 @@ $.extend Travis.Tailing.prototype,
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 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
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
onScroll: ->
@positionButton()
position = $(window).scrollTop()
position = @window.scrollTop()
@stop() if position < @position
@position = position
positionButton: ->
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
return if @tail().length is 0
offset = @window.scrollTop() - @log().offset().top
max = @log().height() - @tail().height() + 5
if offset > 0
tail.css(position: 'fixed', right: 32)
if offset > 0 && offset <= max
@tail().removeClass('bottom')
@tail().addClass('scrolling')
else
tail.css(position: 'absolute', right: 2)
if offset > max
@tail().addClass('bottom')
else
@tail().removeClass('bottom')
@tail().removeClass('scrolling')

View File

@ -26,16 +26,16 @@
<td class="number">
<span class="status"></span>
{{#if id}}
{{#linkTo "build" repo this}}
{{#link-to "build" repo this}}
{{number}}
{{/linkTo}}
{{/link-to}}
{{/if}}
</td>
<td class="message">
{{{formatMessage commit.message short="true" repoBinding=build.repo}}}
</td>
<td class="commit">
<a {{bindAttr href="view.urlGithubCommit"}}>
<a {{bind-attr href="view.urlGithubCommit"}}>
{{formatCommit commit}}
</a>
</td>
@ -44,15 +44,15 @@
</td>
{{#if view.isPullRequestsList}}
<td>
<a {{bindAttr href="view.urlGithubPullRequest"}}>
<a {{bind-attr href="view.urlGithubPullRequest"}}>
#{{pullRequestNumber}}
</a>
</td>
{{/if}}
<td class="duration" {{bindAttr title="duration"}}>
<td class="duration" {{bind-attr title="duration"}}>
{{formatDuration duration}}
</td>
<td class="finished_at timeago" {{bindAttr title="formattedFinishedAt"}}>
<td class="finished_at timeago" {{bind-attr title="formattedFinishedAt"}}>
{{formatTime finishedAt}}
</td>
{{/view}}

View File

@ -8,38 +8,38 @@
<span class="status"></span>
{{#if build.id}}
{{#if build.repo.slug}}
{{#linkTo "build" repo build}}{{build.number}}{{/linkTo}}
{{#link-to "build" repo build}}{{build.number}}{{/link-to}}
{{/if}}
{{/if}}
</dd>
<dt>{{t builds.state}}</dt>
<dd class="state">{{capitalize build.state}}</dd>
<dt class="finished_at_label">{{t builds.finished_at}}</dt>
<dd class="finished_at timeago" {{bindAttr title="build.formattedFinishedAt"}}>{{formatTime build.finishedAt}}</dd>
<dd class="finished_at timeago" {{bind-attr title="build.formattedFinishedAt"}}>{{formatTime build.finishedAt}}</dd>
<dt>{{t builds.duration}}</dt>
<dd class="duration" {{bindAttr title="startedAt"}}>{{formatDuration build.duration}}</dd>
<dd class="duration" {{bind-attr title="startedAt"}}>{{formatDuration build.duration}}</dd>
</div>
{{#with build}}
<div class="right">
<dt>{{t builds.commit}}</dt>
<dd class="commit"><a {{bindAttr href="controller.urlGithubCommit"}}>{{formatCommit commit}}</a></dd>
<dd class="commit"><a {{bind-attr href="controller.urlGithubCommit"}}>{{formatCommit commit}}</a></dd>
{{#if pullRequest}}
<dt>{{t builds.pull_request}}</dt>
<dd class="pull_request"><a {{bindAttr href="commit.compareUrl"}}>#{{pullRequestNumber}} {{pullRequestTitle}}</a></dd>
<dd class="pull_request"><a {{bind-attr href="commit.compareUrl"}}>#{{pullRequestNumber}} {{pullRequestTitle}}</a></dd>
{{else}}
{{#if commit.compareUrl}}
<dt>{{t builds.compare}}</dt>
<dd class="compare"><a {{bindAttr href="commit.compareUrl"}}>{{pathFrom commit.compareUrl}}</a></dd>
<dd class="compare"><a {{bind-attr href="commit.compareUrl"}}>{{pathFrom commit.compareUrl}}</a></dd>
{{/if}}
{{/if}}
{{#if commit.authorName}}
<dt>{{t builds.author}}</dt>
<dd class="author"><a {{bindAttr href="controller.urlAuthor"}}>{{commit.authorName}}</a></dd>
<dd class="author">{{commit.authorName}}</dd>
{{/if}}
{{#if commit.committerName}}
<dt>{{t builds.committer}}</dt>
<dd class="committer"><a {{bindAttr href="controller.urlCommitter"}}>{{commit.committerName}}</a></dd>
<dd class="committer">{{commit.committerName}}</dd>
{{/if}}
</div>
{{/with}}

View File

@ -25,14 +25,14 @@
<span class="status"></span>
{{#if job.id}}
{{#if job.repo.slug}}
{{#linkTo "job" repo job}}{{number}}{{/linkTo}}
{{#link-to "job" repo job}}{{number}}{{/link-to}}
{{/if}}
{{/if}}
</td>
<td class="duration" {{bindAttr title="startedAt"}}>
<td class="duration" {{bind-attr title="startedAt"}}>
{{formatDuration duration}}
</td>
<td class="finished_at timeago" {{bindAttr title="formattedFinishedAt"}}>
<td class="finished_at timeago" {{bind-attr title="formattedFinishedAt"}}>
{{formatTime finishedAt}}
</td>
{{#each value in configValues}}

View File

@ -17,14 +17,14 @@
{{#if view.job.sponsor.name}}
<p class="sponsor">
{{t builds.messages.sponsored_by}}
<a {{bindAttr href="sponsor.url"}}>{{sponsor.name}}</a>
<a {{bind-attr href="sponsor.url"}}>{{sponsor.name}}</a>
</p>
{{/if}}
{{#if view.limited}}
<p class="warning">
This log is too long to be displayed. Please reduce the verbosity of your
build or download the the <a {{bindAttr href="view.plainTextLogUrl"}}>raw log</a>.
build or download the the <a {{bind-attr href="view.plainTextLogUrl"}}>raw log</a>.
</p>
{{/if}}
</div>

View File

@ -1,5 +1,5 @@
{{#if job.isLoaded}}
<div {{bindAttr class="view.color"}}>
<div {{bind-attr class="view.color"}}>
<dl id="summary">
<div class="left">
<dt>Job</dt>
@ -7,38 +7,38 @@
<span class="status"></span>
{{#if job.id}}
{{#if job.repo.slug}}
{{#linkTo "job" repo job}}{{job.number}}{{/linkTo}}
{{#link-to "job" repo job}}{{job.number}}{{/link-to}}
{{/if}}
{{/if}}
</dd>
<dt>{{t jobs.state}}</dt>
<dd class="state">{{capitalize job.state}}</dd>
<dt class="finished_at_label">{{t jobs.finished_at}}</dt>
<dd class="finished_at timeago" {{bindAttr title="job.formattedFinishedAt"}}>{{formatTime job.finishedAt}}</dd>
<dd class="finished_at timeago" {{bind-attr title="job.formattedFinishedAt"}}>{{formatTime job.finishedAt}}</dd>
<dt>{{t jobs.duration}}</dt>
<dd class="duration" {{bindAttr title="startedAt"}}>{{formatDuration job.duration}}</dd>
<dd class="duration" {{bind-attr title="startedAt"}}>{{formatDuration job.duration}}</dd>
</div>
{{#with job}}
<div class="right">
<dt>{{t jobs.commit}}</dt>
<dd class="commit"><a {{bindAttr href="controller.urlGithubCommit"}}>{{formatCommit commit}}</a></dd>
<dd class="commit"><a {{bind-attr href="controller.urlGithubCommit"}}>{{formatCommit commit}}</a></dd>
{{#if build.pullRequest}}
<dt>{{t builds.pull_request}}</dt>
<dd class="pull_request"><a {{bindAttr href="commit.compareUrl"}}>#{{build.pullRequestNumber}} {{build.pullRequestTitle}}</a></dd>
<dd class="pull_request"><a {{bind-attr href="commit.compareUrl"}}>#{{build.pullRequestNumber}} {{build.pullRequestTitle}}</a></dd>
{{else}}
{{#if commit.compareUrl}}
<dt>{{t jobs.compare}}</dt>
<dd class="compare"><a {{bindAttr href="commit.compareUrl"}}>{{pathFrom commit.compareUrl}}</a></dd>
<dd class="compare"><a {{bind-attr href="commit.compareUrl"}}>{{pathFrom commit.compareUrl}}</a></dd>
{{/if}}
{{/if}}
{{#if commit.authorName}}
<dt>{{t jobs.author}}</dt>
<dd class="author"><a {{bindAttr href="controller.urlAuthor"}}>{{commit.authorName}}</a></dd>
<dd class="author">{{commit.authorName}}</dd>
{{/if}}
{{#if commit.committerName}}
<dt>{{t jobs.committer}}</dt>
<dd class="committer"><a {{bindAttr href="controller.urlCommitter"}}>{{commit.committerName}}</a></dd>
<dd class="committer">{{commit.committerName}}</dd>
{{/if}}
</div>
{{/with}}

View File

@ -1,10 +1,10 @@
{{#linkTo "index.current"}}
{{#link-to "index.current"}}
<h1>Travis</h1>
{{/linkTo}}
{{/link-to}}
<ul id="navigation">
<li class="home">
{{#linkTo "index.current"}}{{t layouts.top.home}}{{/linkTo}}
{{#link-to "index.current"}}{{t layouts.top.home}}{{/link-to}}
</li>
<li>
<a href="http://about.travis-ci.org/blog">{{t layouts.top.blog}}</a>
@ -29,13 +29,13 @@
<li class="traviscicom">
<a href="http://travis-ci.com">Travis CI for Private Repositories</a>
</li>
<li {{bindAttr class="view.classProfile"}}>
<li {{bind-attr class="view.classProfile"}}>
<p class="handle">
{{#if signedOut}}
<a class="signed-out" href="#" {{action "signIn" target="Travis"}}>{{t layouts.top.github_login}}</a>
{{/if}}
{{#if signedIn}}
{{#linkTo "profile" class="signed-in"}}<img {{bindAttr src="gravatarUrl"}}/>{{userName}}{{/linkTo}}
{{#link-to "profile" class="signed-in"}}<img {{bind-attr src="gravatarUrl"}}/>{{userName}}{{/link-to}}
{{/if}}
{{#if signingIn}}
<span class="signing-in">{{t layouts.top.signing_in}}</span>
@ -43,7 +43,7 @@
</p>
<ul>
<li>
{{#linkTo "profile.index" class="signed-in"}}{{t layouts.top.accounts}}{{/linkTo}}
{{#link-to "profile.index" class="signed-in"}}{{t layouts.top.accounts}}{{/link-to}}
</li>
<li>
<a href="/" {{action "signOut" target="Travis"}}>{{t layouts.top.sign_out}}</a>

View File

@ -11,7 +11,7 @@
<div class="column-right">
<span class="steps">Step 1: &nbsp; Enabling your projects</span>
<p>
Start by going to your {{#linkTo "profile.index"}}profile{{/linkTo}} and enable one of your projects. We've been
Start by going to your {{#link-to "profile.index"}}profile{{/link-to}} and enable one of your projects. We've been
synchronizing all repositories you have administrative access to. Pick one and flip the switch next to it.
</p>
</div>

View File

@ -2,14 +2,14 @@
</div>
<ul class="tabs">
<li id="tab_accounts" {{bindAttr class="view.classAccounts"}}>
<li id="tab_accounts" {{bind-attr class="view.classAccounts"}}>
<h5><a name="accounts" href="">Accounts</a></h5>
</li>
</ul>
<div class="tab">
{{#collection Travis.AccountsListView contentBinding="controller"}}
{{#linkTo "account.index" view.account class="name"}}{{view.name}}{{/linkTo}}
{{#link-to "account.index" view.account class="name"}}{{view.name}}{{/link-to}}
<p class="summary">
<span class="repos_label">Repositories:</span>
<abbr class="repos">{{view.account.reposCount}}</abbr>

View File

@ -1,17 +1,17 @@
<ul class="tabs">
<li id="tab_hooks" {{bindAttr class="view.classHooks"}}>
<li id="tab_hooks" {{bind-attr class="view.classHooks"}}>
<h5>
{{#with view.account}}
{{#if login}}
{{#linkTo "account.index" this}}Repositories{{/linkTo}}
{{#link-to "account.index" this}}Repositories{{/link-to}}
{{/if}}
{{/with}}
</h5>
</li>
{{#if view.displayUser}}
<li id="tab_user" {{bindAttr class="view.classUser"}}>
<li id="tab_user" {{bind-attr class="view.classUser"}}>
<h5>
{{#linkTo "account.profile" view.account}}Profile{{/linkTo}}
{{#link-to "account.profile" view.account}}Profile{{/link-to}}
</h5>
</li>
{{/if}}

View File

@ -17,8 +17,8 @@
<ul id="hooks">
{{#each hook in hooks}}
<li {{bindAttr class="hook.active:active"}}>
<a {{bindAttr href="hook.urlGithub"}} rel="nofollow">{{hook.slug}}</a>
<li {{bind-attr class="hook.active:active"}}>
<a {{bind-attr href="hook.urlGithub"}} rel="nofollow">{{hook.slug}}</a>
{{#if hook.isSaving}}<span class="loading"></span>{{/if}}
<p class="description">{{hook.description}}</p>
@ -54,8 +54,8 @@
<ul>
{{#each hook in unAdminisetableHooks}}
<li {{bindAttr class="hook.active:active"}}>
<a {{bindAttr href="hook.urlGithub"}} rel="nofollow">{{hook.slug}}</a>
<li {{bind-attr class="hook.active:active"}}>
<a {{bind-attr href="hook.urlGithub"}} rel="nofollow">{{hook.slug}}</a>
<p class="description">{{hook.description}}</p>
</li>
{{/each}}

View File

@ -1,4 +1,4 @@
<img {{bindAttr src="view.gravatarUrl"}}>
<img {{bind-attr src="view.gravatarUrl"}}>
<dl class="profile">
<div>
@ -6,7 +6,7 @@
{{t profiles.show.github}}:
</dt>
<dd>
<a {{bindAttr href="urlGithub"}}>{{user.login}}</a>
<a {{bind-attr href="urlGithub"}}>{{user.login}}</a>
</dd>
</div>
<div>

View File

@ -2,16 +2,16 @@
{{#each queue in controller}}
<li class="queue">
<h4>{{t queue}}: {{queue.name}}</h4>
<ul {{bindAttr id="queue.id"}}>
<ul {{bind-attr id="queue.id"}}>
{{#each job in queue}}
{{#view Travis.QueueItemView jobBinding="job"}}
{{#if job.repo.slug}}
{{#linkTo "job" job.repo job}}
{{#link-to "job" job.repo job}}
<span class="slug">
{{job.repo.slug}}
</span>
#{{job.number}}
{{/linkTo}}
{{/link-to}}
{{/if}}
{{/view}}
{{else}}

View File

@ -11,22 +11,22 @@
<div class="slug-and-status">
<span class="status"></span>
{{#if slug}}
{{#linkTo "repo" this class="slug"}}{{slug}}{{/linkTo}}
{{#link-to "repo" this class="slug"}}{{slug}}{{/link-to}}
{{/if}}
</div>
{{#with lastBuildHash}}
{{#if repo.slug}}
{{#linkTo "build" repo id class="last_build"}}{{number}}{{/linkTo}}
{{#link-to "build" repo id class="last_build"}}{{number}}{{/link-to}}
{{/if}}
{{/with}}
<p class="summary">
<span class="duration-icon"></span><span class="duration_label">{{t repositories.duration}}:</span>
<abbr class="duration" {{bindAttr title="lastBuildStartedAt"}}>{{formatDuration lastBuildDuration}}</abbr>
<span class="duration_label">{{t repositories.duration}}:</span>
<abbr class="duration" {{bind-attr title="lastBuildStartedAt"}}>{{formatDuration lastBuildDuration}}</abbr>
</p>
<p class="summary">
<span class="finished-icon"></span><span class="finished_at_label">{{t repositories.finished_at}}:</span>
<abbr class="finished_at timeago" {{bindAttr title="lastBuildFinishedAt"}}>{{formatTime lastBuildFinishedAt}}</abbr>
<abbr class="finished_at timeago" {{bind-attr title="lastBuildFinishedAt"}}>{{formatTime lastBuildFinishedAt}}</abbr>
</p>
<div class="indicator"><span></span></div>

View File

@ -1,13 +1,13 @@
<ul class="tabs">
<li id="tab_owned" {{bindAttr class="view.classOwned"}}>
<li id="tab_owned" {{bind-attr class="view.classOwned"}}>
<h5><a {{action "activate" "owned" target="view"}}>{{t layouts.application.my_repositories}}</a></h5>
</li>
<li id="tab_recent" {{bindAttr class="view.classRecent"}}>
<li id="tab_recent" {{bind-attr class="view.classRecent"}}>
<h5><a {{action "activate" "recent" target="view"}}>{{t layouts.application.recent}}</a></h5>
</li>
<li id="tab_search" {{bindAttr class="view.classSearch"}}>
<li id="tab_search" {{bind-attr class="view.classSearch"}}>
<h5><a {{action "activate" "search" target="view"}}>{{t layouts.application.search}}</a></h5>
</li>
</ul>

View File

@ -1,12 +1,12 @@
<div id="repo" {{bindAttr class="view.className"}}>
<div id="repo" {{bind-attr class="view.className"}}>
{{#if view.isEmpty}}
{{view Travis.ReposEmptyView}}
{{else}}
{{#if repo.isLoaded}}
{{#with repo}}
<div id="repo-header">
<h3>{{#linkTo "repo" this}}{{slug}}{{/linkTo}}</h3>
<div class="github-icon"><a {{bindAttr href="controller.urlGithub"}}><img src="/images/icons/github.png" width="21" height="21"/></a></div>
<h3>{{#link-to "repo" this}}{{slug}}{{/link-to}}</h3>
<div class="github-icon"><a {{bind-attr href="controller.urlGithub"}}><img src="/images/icons/github.png" width="21" height="21"/></a></div>
{{view Travis.RepoShowToolsView}}
</div>

View File

@ -3,39 +3,39 @@
{{#if view.displayCancelBuild}}
<li class="icon" title="Cancel Build">
<a href="#" {{action "cancelBuild" target="view"}}
{{bindAttr class="view.canCancelBuild::disabled"}}><img class="icon" src="/images/icons/off.png" width="20"></a>
{{bind-attr class="view.canCancelBuild::disabled"}}><img class="icon" src="/images/icons/off.png" width="20"></a>
</li>
{{/if}}
{{#if view.displayCancelJob}}
<li class="icon" title="Cancel Job">
<a href="#" {{action "cancelJob" target="view"}}
{{bindAttr class="view.canCancelJob::disabled"}}><img class="icon" width="20" src="/images/icons/off.png"/></a>
{{bind-attr class="view.canCancelJob::disabled"}}><img class="icon" width="20" src="/images/icons/off.png"/></a>
</li>
{{/if}}
{{#if view.displayRequeueBuild}}
<li class="icon" title="Restart Build">
<a href="#" {{action "requeueBuild" target="view"}}
{{bindAttr class="view.canRequeueBuild::disabled"}}><img class="icon" src="/images/icons/repeat.png" width="20"></a>
{{bind-attr class="view.canRequeueBuild::disabled"}}><img class="icon" src="/images/icons/repeat.png" width="20"></a>
</li>
{{/if}}
{{#if view.displayRequeueJob}}
<li class="icon" title="Restart Job">
<a href="#" {{action "requeueJob" target="view"}}
{{bindAttr class="view.canRequeueJob::disabled"}}><img src="/images/icons/repeat.png" width="20"></a>
{{bind-attr class="view.canRequeueJob::disabled"}}><img src="/images/icons/repeat.png" width="20"></a>
</li>
{{/if}}
{{!TODO: for some reason showDownloadLog, which just delegates to jobIdForLog
does not refresh 'if' properly, need further investigation}}
{{#if view.jobIdForLog}}
<li class="icon" title="Download Log">
<a class="download-log" {{bindAttr href="view.plainTextLogUrl"}}><img class="icon" src="/images/icons/align-justify.png" width="20"/></a>
<a class="download-log" {{bind-attr href="view.plainTextLogUrl"}}><img class="icon" src="/images/icons/align-justify.png" width="20"/></a>
</li>
{{/if}}
{{#if view.displayCodeClimate}}
<li class="icon" title="Test Coverage with Code Climate">
<a href="#" name="code-climate"
{{action "codeClimatePopup" target="view"}}
{{bindAttr class=":open-popup"}}>
{{bind-attr class=":open-popup"}}>
<img src="/images/icons/code-climate-icon.png"/>
</a>
</li>

View File

@ -1,58 +1,58 @@
<ul class="tabs">
<li id="tab_current" {{bindAttr class="view.classCurrent"}}>
<li id="tab_current" {{bind-attr class="view.classCurrent"}}>
<h5>
{{#if repo.slug}}
{{#linkTo "repo" repo currentWhen="repo.index"}}
{{#link-to "repo" repo currentWhen="repo.index"}}
{{t repositories.tabs.current}}
{{/linkTo}}
{{/link-to}}
{{/if}}
</h5>
</li>
<li id="tab_builds" {{bindAttr class="view.classBuilds"}}>
<li id="tab_builds" {{bind-attr class="view.classBuilds"}}>
<h5>
{{#if repo.slug}}
{{#linkTo "builds" repo}}
{{#link-to "builds" repo}}
{{t repositories.tabs.build_history}}
{{/linkTo}}
{{/link-to}}
{{/if}}
</h5>
</li>
<li id="tab_pull_requests" {{bindAttr class="view.classPullRequests"}}>
<li id="tab_pull_requests" {{bind-attr class="view.classPullRequests"}}>
<h5>
{{#if repo.slug}}
{{#linkTo "pullRequests" repo}}
{{#link-to "pullRequests" repo}}
{{t repositories.tabs.pull_requests}}
{{/linkTo}}
{{/link-to}}
{{/if}}
</h5>
</li>
<li id="tab_branches" {{bindAttr class="view.classBranches"}}>
<li id="tab_branches" {{bind-attr class="view.classBranches"}}>
<h5>
{{#if repo.slug}}
{{#linkTo "branches" repo}}
{{#link-to "branches" repo}}
{{t repositories.tabs.branches}}
{{/linkTo}}
{{/link-to}}
{{/if}}
</h5>
</li>
<li id="tab_build" {{bindAttr class="view.classBuild"}}>
<li id="tab_build" {{bind-attr class="view.classBuild"}}>
<h5>
{{#if build.id}}
{{#if repo.slug}}
{{#linkTo "build" repo build}}
{{#link-to "build" repo build}}
{{t repositories.tabs.build}} #{{build.number}}
{{/linkTo}}
{{/link-to}}
{{/if}}
{{/if}}
</h5>
</li>
<li id="tab_job" {{bindAttr class="view.classJob"}}>
<li id="tab_job" {{bind-attr class="view.classJob"}}>
<h5>
{{#if job.id}}
{{#if repo.slug}}
{{#linkTo "job" repo job}}
{{#link-to "job" repo job}}
{{t repositories.tabs.job}} #{{job.number}}
{{/linkTo}}
{{/link-to}}
{{/if}}
{{/if}}
</h5>

View File

@ -6,7 +6,7 @@
<li>
<a href="#" name="regenerate-key"
{{action "regenerateKeyPopup" target="view"}}
{{bindAttr class=":open-popup view.canRegenerateKey::disabled"}}>
{{bind-attr class=":open-popup view.canRegenerateKey::disabled"}}>
Regenerate Key
</a>
</li>
@ -20,7 +20,7 @@
</ul>
{{#if view.displayStatusImages}}
<a href="#" id="status-image-popup" name="status-images" class="open-popup" {{action "statusImages" target="view"}}>
<img {{bindAttr src="view.statusImageUrl"}} title="Build Status Images"/>
<img {{bind-attr src="view.statusImageUrl"}} title="Build Status Images"/>
</a>
{{/if}}
@ -64,8 +64,8 @@
<p>
Integrating <a href="https://codeclimate.com">Code Climate's test coverage</a> reporting with your test
suite on Travis CI allows to track changes in coverage over time. If you haven't tried it out already, <a
{{bindAttr href="Travis.config.code_climate_url"}}" target="_blank">sign
up today</a> for to improve your code's quality. New customers get 20% off for the first three months!
{{bind-attr href="Travis.config.code_climate_url"}}" target="_blank">sign
up today</a> to improve your code's quality. New customers get 20% off for the first three months!
</p>
<p>

View File

@ -9,25 +9,25 @@
</p>
<p>
<label>{{t repositories.image_url}}:</label>
<input type="text" class="url" {{bindAttr value="view.statusImageUrl"}}></input>
<input type="text" class="url" {{bind-attr value="view.statusImageUrl"}}></input>
</p>
<p>
<label>{{t repositories.markdown}}:</label>
<input type="text" class="markdown" {{bindAttr value="view.markdownStatusImage"}}></input>
<input type="text" class="markdown" {{bind-attr value="view.markdownStatusImage"}}></input>
</p>
<p>
<label>{{t repositories.textile}}:</label>
<input type="text" class="textile" {{bindAttr value="view.textileStatusImage"}}></input>
<input type="text" class="textile" {{bind-attr value="view.textileStatusImage"}}></input>
</p>
<p>
<label>{{t repositories.rdoc}}:</label>
<input type="text" class="rdoc" {{bindAttr value="view.rdocStatusImage"}}></input>
<input type="text" class="rdoc" {{bind-attr value="view.rdocStatusImage"}}></input>
</p>
<p>
<label>{{t repositories.asciidoc}}:</label>
<input type="text" class="asciidoc" {{bindAttr value="view.asciidocStatusImage"}}></input>
<input type="text" class="asciidoc" {{bind-attr value="view.asciidocStatusImage"}}></input>
</p>
<p>
<label>{{t repositories.rst}}:</label>
<input type="text" class="rst" {{bindAttr value="view.rstStatusImage"}}></input>
<input type="text" class="rst" {{bind-attr value="view.rstStatusImage"}}></input>
</p>

View File

@ -14,9 +14,9 @@
<div class="status"></div>
{{#if worker.isWorking}}
{{#if worker.jobId}}
{{#linkTo "job" worker.repo worker.jobId}}
{{#link-to "job" worker.repo worker.jobId}}
{{view.display}}
{{/linkTo}}
{{/link-to}}
{{/if}}
{{else}}
{{view.display}}

View File

@ -29,11 +29,3 @@ Travis.reopen
urlGithubCommit: (->
Travis.Urls.githubCommit(@get('repo.slug'), @get('commit.sha'))
).property('repo.slug', 'commit.sha')
urlAuthor: (->
Travis.Urls.email(@get('commit.authorEmail'))
).property('commit.authorEmail')
urlCommitter: (->
Travis.Urls.email(@get('commit.committerEmail'))
).property('commit.committerEmail')

View File

@ -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()
@lineNumberDidChange()
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')
lineNumberDidChange: (->
@scroll.set(number) if !@get('isDestroyed') && number = @get('controller.lineNumber')
).observes('controller.lineNumber')
limited: (->
@engine?.limit?.limited
).property()
@ -79,24 +76,11 @@ Travis.reopen
Travis.tailing.toggle()
event.preventDefault()
numberLineOnHover: ->
$('#log').on 'mouseenter', 'a', ->
$(@).attr('href', '#L' + ($("#log p:visible").index(@parentNode) + 1))
click: (event) ->
if (href = $(event.target).attr('href')) && matches = href?.match(/#L(\d+)$/)
@lineNumberClicked(matches[1])
event.stopPropagation()
false
else
target = $(event.target)
target = $(event.target)
if target.prop('tagName') == 'P'
target.closest('.fold').toggleClass('open')
lineNumberClicked: (number) ->
path = "#{window.location.pathname}#L#{number}"
window.history.pushState({ path: path }, null, path);
@set('controller.lineNumber', number)
actions:
toTop: () ->
$(window).scrollTop(0)
@ -105,25 +89,14 @@ Travis.reopen
Log.Scroll = ->
Log.Scroll.prototype = $.extend new Log.Listener,
set: (number) ->
return unless number
@number = number
@tryScroll()
insert: (log, data, pos) ->
@tryScroll() if @number
@tryScroll() if @numbers
true
tryScroll: ->
if element = $("#log p:visible")[@number - 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
@highlight(element)
@number = undefined
highlight: (element) ->
$('#log p.highlight').removeClass('highlight')
$(element).addClass('highlight')
$('html, body').scrollTop(element.offset()?.top) # weird, html works in chrome, body in firefox
# Log.Logger = ->
# Log.Logger.prototype = $.extend new Log.Listener,

View File

@ -37,7 +37,7 @@ Travis.reopen
tabBinding: 'controller.tab'
contextBinding: 'controller'
# hrm. how to parametrize bindAttr?
# hrm. how to parametrize bind-attr?
classCurrent: (->
'active' if @get('tab') == 'current'
).property('tab')

View File

@ -4,7 +4,7 @@
tabBinding: 'controller.tab'
# hrm. how to parametrize bindAttr?
# hrm. how to parametrize bind-attr?
classHome: (->
'active' if @get('tab') == 'home'
).property('tab')

View File

@ -1,3 +0,0 @@
Travis.LineNumberParser = Ember.Mixin.create
fetchLineNumber: ->
match[1] if match = document.location.hash.match(/#L(\d+)$/)

View File

@ -0,0 +1,55 @@
class Travis.LinesSelector
element: null
scroll: null
location: null
last_selected_line: null
constructor: (@element, @scroll, @location) ->
Ember.run.scheduleOnce 'afterRender', this, ->
@last_selected_line = @getSelectedLines()?.first
@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 - 1, lines.last).addClass('highlight')
@scroll.tryScroll()
setHashValueWithLine: (line, multiple) ->
line_number = @getLineNumberFromElement(line)
if multiple && @last_selected_line?
lines = [line_number, @last_selected_line].sort (a,b) -> a - b
hash = "#L#{lines[0]}-L#{lines[1]}"
else
hash = "#L#{line_number}"
@last_selected_line = line_number
@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]
last = match[3] || match[1]
{first: first, last: last}

View File

@ -66,7 +66,7 @@ test "updating current build", ->
state: 'started'
config: {}
pull_request: false
compare_url: 'http://github.com/compare/0123456..1234567'
compare_url: 'https://github.com/compare/0123456..1234567'
repository:
id: 1
last_build_number: '3'

View File

@ -1,6 +1,6 @@
@displaysRepository = (repo) ->
equal($('#repo h3 a').attr('href'), repo.href, 'repository title should link to repo page')
equal($('#repo .github-icon a').attr('href'), "http://github.com#{repo.href}", 'github icon should link to repo on github')
equal($('#repo .github-icon a').attr('href'), "https://github.com#{repo.href}", 'github icon should link to repo on github')
@displaysTabs = (tabs) ->
for name, tab of tabs
@ -27,13 +27,13 @@
equal(element.text(), data.duration)
element = $('#summary .commit a')
equal(element.attr('href'), "http://github.com/#{data.repo}/commit/#{data.commit}")
equal(element.attr('href'), "https://github.com/#{data.repo}/commit/#{data.commit}")
element = $('#summary .commit a')
equal(element.text(), "#{data.commit} (#{data.branch})")
element = $('#summary .compare a')
equal(element.attr('href'), "http://github.com/compare/#{data.compare}")
equal(element.attr('href'), "https://github.com/compare/#{data.compare}")
element = $('#summary .compare a')
equal(element.text(), data.compare)

View File

@ -24,10 +24,10 @@ builds = [
]
commits = [
{ id: '1', sha: '1234567', branch: 'master', message: 'commit message 1', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'http://github.com/compare/0123456..1234567' },
{ id: '2', sha: '2345678', branch: 'feature', message: 'commit message 2', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'http://github.com/compare/0123456..2345678' },
{ id: '3', sha: '3456789', branch: 'master', message: 'commit message 3', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'http://github.com/compare/0123456..3456789' },
{ id: '4', sha: '4567890', branch: 'master', message: 'commit message 4', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'http://github.com/compare/0123456..4567890' },
{ id: '1', sha: '1234567', branch: 'master', message: 'commit message 1', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'https://github.com/compare/0123456..1234567' },
{ id: '2', sha: '2345678', branch: 'feature', message: 'commit message 2', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'https://github.com/compare/0123456..2345678' },
{ id: '3', sha: '3456789', branch: 'master', message: 'commit message 3', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'https://github.com/compare/0123456..3456789' },
{ id: '4', sha: '4567890', branch: 'master', message: 'commit message 4', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'https://github.com/compare/0123456..4567890' },
]
jobs = [

View File

@ -3,53 +3,53 @@ module "Travis.Helpers.githubify"
test 'replaces #Num with github issues link', ->
message = 'Solved #11hey'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'Solved <a href="http://github.com/travis-ci/travis-web/issues/11">#11</a>hey'
expected = 'Solved <a href="https://github.com/travis-ci/travis-web/issues/11">#11</a>hey'
equal(result, expected, "#num should be converted to a link")
test 'replaces User#Num with github issues link to forked repo', ->
message = 'Solved test#11hey'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'Solved <a href="http://github.com/test/travis-web/issues/11">test#11</a>hey'
expected = 'Solved <a href="https://github.com/test/travis-web/issues/11">test#11</a>hey'
equal(result, expected, "user#num should be converted to a link")
test 'replaces User/Project#Num with github issues link to another repo', ->
message = 'Solved test_1-a2/test-a_11#11hey'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'Solved <a href="http://github.com/test_1-a2/test-a_11/issues/11">test_1-a2/test-a_11#11</a>hey'
expected = 'Solved <a href="https://github.com/test_1-a2/test-a_11/issues/11">test_1-a2/test-a_11#11</a>hey'
equal(result, expected, "owner/repo#num should be converted to a link")
test 'replaces gh-Num with github issues link', ->
message = 'Solved gh-22hey'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'Solved <a href="http://github.com/travis-ci/travis-web/issues/22">gh-22</a>hey'
expected = 'Solved <a href="https://github.com/travis-ci/travis-web/issues/22">gh-22</a>hey'
equal(result, expected, "gh-Num should be converted to a link")
test 'replaces multiple references with github issues links', ->
message = 'Try #1 and test#2 and test/testing#3'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'Try <a href="http://github.com/travis-ci/travis-web/issues/1">#1</a> and '
expected += '<a href="http://github.com/test/travis-web/issues/2">test#2</a> and '
expected += '<a href="http://github.com/test/testing/issues/3">test/testing#3</a>'
expected = 'Try <a href="https://github.com/travis-ci/travis-web/issues/1">#1</a> and '
expected += '<a href="https://github.com/test/travis-web/issues/2">test#2</a> and '
expected += '<a href="https://github.com/test/testing/issues/3">test/testing#3</a>'
equal(result, expected, "references should be converted to links")
test 'replaces multiple references with github issues links', ->
message = 'Try #1 and test#2 and test/testing#3'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'Try <a href="http://github.com/travis-ci/travis-web/issues/1">#1</a> and '
expected += '<a href="http://github.com/test/travis-web/issues/2">test#2</a> and '
expected += '<a href="http://github.com/test/testing/issues/3">test/testing#3</a>'
expected = 'Try <a href="https://github.com/travis-ci/travis-web/issues/1">#1</a> and '
expected += '<a href="https://github.com/test/travis-web/issues/2">test#2</a> and '
expected += '<a href="https://github.com/test/testing/issues/3">test/testing#3</a>'
equal(result, expected, "references should be converted to links")
test 'replaces @user with github user link', ->
message = 'It is for you @tender_love1'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'It is for you <a href="http://github.com/tender_love1">@tender_love1</a>'
expected = 'It is for you <a href="https://github.com/tender_love1">@tender_love1</a>'
equal(result, expected, "@user should be converted to a link")
@ -58,3 +58,17 @@ test 'does not replace @user if it is a sign-off', ->
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
equal(result, message, "@user should not be converted to a link if it matches an email")
test 'replaces one commit reference with github commit link', ->
message = 'See travis-ci/travis-core@732fe00'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'See <a href="https://github.com/travis-ci/travis-core/commit/732fe00">travis-ci/travis-core@732fe00</a>'
equal(result, expected, "Commit reference should be converted to a link")
test 'replaces multiple commit references with github commit links', ->
message = 'See travis-ci/travis-core@732fe00 and travis-ci/travis-web@3b6aa17'
result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web')
expected = 'See <a href="https://github.com/travis-ci/travis-core/commit/732fe00">travis-ci/travis-core@732fe00</a> and <a href="https://github.com/travis-ci/travis-web/commit/3b6aa17">travis-ci/travis-web@3b6aa17</a>'
equal(result, expected, "Commit references should be converted to links")

View File

@ -0,0 +1,92 @@
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)
test "uses the last selected line as second selection line", ->
selector = null
Ember.run ->
selector = new Travis.LinesSelector(element, fakeScroll, fakeLocation)
wait().then ->
$('#fakeLog p:last a').click()
equal($('#fakeLog p.highlight').length, 1)
equal(3, selector.last_selected_line)
event = jQuery.Event('click')
event.shiftKey = true
$('#fakeLog p:first a').trigger(event)
equal($('#fakeLog p.highlight').length, 3)
equal($('#fakeLog p:nth-child(1)').hasClass('highlight'), true)
equal($('#fakeLog p:nth-child(2)').hasClass('highlight'), true)
equal($('#fakeLog p:nth-child(3)').hasClass('highlight'), true)
equal('#L1-L3', fakeLocation.hash)
equal(1, selector.last_selected_line)

View File

@ -0,0 +1,89 @@
fakeWindow =
scroll: sinon.spy()
scrollTop: sinon.stub().returns(0)
height: sinon.stub().returns(40)
element = jQuery('<div id="specTail"></div>')
log = jQuery('<div id="specLog"></div>')
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)

File diff suppressed because it is too large Load Diff

39142
assets/scripts/vendor/ember.prod.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -23,6 +23,7 @@ $yellow-light-2: #fffcf4
$gray-dark-1: #333
$gray-dark-2: #444
$gray-dark-3: #666
$gray-dark-4: #777
$gray-medium-1: #999
$gray-medium-2: #aaa
$gray-medium-3: #c4cbcc
@ -65,6 +66,7 @@ $color-bg-log: #222222
$color-bg-log-fold: $gray-dark-1
$color-bg-log-hover: $gray-dark-2
$color-bg-log-highlight: $gray-dark-3
$color-bg-log-fold-highlight: $gray-dark-4
$color-bg-slider: $slate-blue-3
$color-bg-left: $gray-light-4
$color-bg-list-odd: $white
@ -119,7 +121,7 @@ $ansi-black: #4E4E4E
$ansi-black-bold: #7C7C7C
$ansi-red: #FF6C60
$ansi-red-bold: #FFB6B0
$ansi-green: #A8FF60
$ansi-green: #00AA00
$ansi-green-bold: #CEFFAB
$ansi-yellow: #FFFFB6
$ansi-yellow-bold: #FFFFCB
@ -127,8 +129,8 @@ $ansi-blue: #96CBFE
$ansi-blue-bold: #B5DCFE
$ansi-magenta: #FF73FD
$ansi-magenta-bold: #FF9CFE
$ansi-cyan: #C6C5FE
$ansi-cyan-bold: #DFDFFE
$ansi-cyan: #00AAAA
$ansi-cyan-bold: #55FFFF
$ansi-white: #EEEEEE
$ansi-white-bold: #FFFFFF
$ansi-grey: #969696

View File

@ -27,7 +27,7 @@ html, body
top: -40px
left: 0
width: 100%
min-width: 1211px
min-width: 930px
height: 55px
z-index: 1000

View File

@ -57,6 +57,8 @@ pre#log
// &.active
p:first-of-type
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
visibility: visible
@ -117,6 +119,14 @@ pre#log
label
display: inline
&.scrolling
position: fixed
right: 32px
&.bottom
bottom: 45px
top: inherit
.status
display: inline-block
margin-right: 1px

View File

@ -8,6 +8,7 @@ module Travis
TYPES = [:styles, :scripts, :images, :static, :vendor]
VENDOR_ORDER = %w(jquery.min minispade handlebars ember)
PRODUCTION_VENDOR_ORDER = %w(jquery.min minispade handlebars ember.prod)
SPEC_VENDOR_ORDER = %w(jasmine jasmine-html jasmine-runner sinon)
attr_reader :roots, :env
@ -30,7 +31,8 @@ module Travis
end
def vendor_order
VENDOR_ORDER.map { |name| "vendor/#{name}.js" }
order = production? ? PRODUCTION_VENDOR_ORDER : VENDOR_ORDER
order.map { |name| "vendor/#{name}.js" }
end
def spec_vendor_order

View File

@ -18,22 +18,28 @@ ja:
messages:
sponsored_by: このテストは以下のスポンサーの協力で行いました。
name: ビルド
pr:
pull_request:
pr:
pull_request: プルリクエスト
started_at: 開始時刻
state:
state: ステイタス
datetime:
distance_in_words:
hours_exact:
minutes_exact:
seconds_exact:
hours_exact:
one: ! '%{count} 時間'
other: ! '%{count} 時間'
minutes_exact:
one: ! '%{count} 分'
other: ! '%{count} 分'
seconds_exact:
one: ! '%{count} 秒'
other: ! '%{count} 秒'
errors:
messages:
already_confirmed:
not_found:
not_locked:
already_confirmed: は既に承認済みです
not_found: は見つかりませんでした
not_locked: はロックされていません
home:
name:
name:
jobs:
allowed_failures: 失敗許容範囲内
author: 制作者
@ -48,9 +54,9 @@ ja:
message: メッセージ
messages:
sponsored_by: このテストは以下のスポンサーの協力で行いました。
sponsored_by:
sponsored_by:
started_at: 開始時刻
state:
state: ステイタス
layouts:
about:
alpha: まだアルファですよ!
@ -80,7 +86,7 @@ ja:
job: ジョブ
log: ログ
top:
accounts:
accounts:
admin: 管理
blog: ブログ
docs: Travisとは
@ -88,11 +94,11 @@ ja:
home: ホーム
profile: プロフィール
sign_out: ログアウト
signing_in:
signing_in: ログイン中
stats: 統計
status:
status: ステイタス
locales:
ca:
ca:
de: Deutsch
en: English
es: Español
@ -107,7 +113,7 @@ ja:
profiles:
show:
email: メール
github: Github
github: GitHub
locale: 言語
message:
config: 詳細設定
@ -121,7 +127,7 @@ ja:
your_repos: リポジトリ
queue: キュー
repositories:
asciidoc:
asciidoc: AsciiDoc
branch: ブランチ
commit: コミット
duration: 処理時間
@ -138,7 +144,7 @@ ja:
current: 最新
job: ジョブ
pull_requests: プルリクエスト
test:
test:
textile: .textile
repository:
duration: 時間
@ -151,6 +157,6 @@ ja:
total_builds: 合計ビルド数
total_projects: 合計リポジトリ
user:
failure:
signed_out:
failure:
signed_out:
workers: ワーカー

View File

@ -92,7 +92,7 @@ ru:
job: Задача
log: Журнал
top:
accounts: аккаунты
accounts: Аккаунты
admin: Управление
blog: Блог
docs: Документация
@ -100,7 +100,7 @@ ru:
home: Главная
profile: Профиль
sign_out: Выход
signing_in: авторизация
signing_in: Авторизация
stats: Статистика
status:
locales: