diff --git a/app/assets/javascripts/app/app.js b/app/assets/javascripts/app/app.js deleted file mode 100644 index 020baacb..00000000 --- a/app/assets/javascripts/app/app.js +++ /dev/null @@ -1,236 +0,0 @@ -//= require_tree ./templates -//= require_self - -App = Em.Application.create(); -App.Store = DS.Store.extend({ revision: 4, adapter: DS.fixtureAdapter }); - -App.Repository = DS.Model.extend({ - ownerName: DS.attr('string'), - name: DS.attr('string'), - - builds: DS.hasMany('App.Build', { key: 'build_ids' }), - - lastBuild: function() { - return this.getPath('builds.firstObject'); - }.property() -}); - -App.Build = DS.Model.extend({ - number: DS.attr('number'), - repository: DS.belongsTo('App.Repository') -}); - -App.Build.FIXTURES = [ - { id: 1, repositoryId: 1, repository_id: 1, number: 1 }, - { id: 2, repositoryId: 1, repository_id: 1, number: 2 }, - { id: 3, repositoryId: 2, repository_id: 2, number: 3 }, - { id: 4, repositoryId: 3, repository_id: 3, number: 4 } -]; - -App.Repository.FIXTURES = [ - { id: 1, owner_name: 'travis-ci', name: 'travis-core', build_ids: [1, 2] }, - { id: 2, owner_name: 'travis-ci', name: 'travis-assets', build_ids: [3] }, - { id: 3, owner_name: 'travis-ci', name: 'travis-hub', build_ids: [4] }, -]; - -App.ApplicationController = Em.Controller.extend(); -App.RepositoriesController = Em.ArrayController.extend(); -App.RepositoryController = Em.Controller.extend(); -App.TabsController = Em.Controller.extend(); -App.CurrentController = Em.Controller.extend(); -App.HistoryController = Em.ArrayController.extend(); -App.BuildController = Em.Controller.extend(); -App.LoadingController = Em.Controller.extend(); - -App.ApplicationView = Em.View.extend({ templateName: 'application' }); -App.RepositoriesView = Em.View.extend({ templateName: 'repositories' }); -App.RepositoryView = Em.View.extend({ templateName: 'repository' }); -App.TabsView = Em.View.extend({ templateName: 'tabs' }); -App.CurrentView = Em.View.extend({ templateName: 'current' }); -App.HistoryView = Em.View.extend({ templateName: 'history' }); -App.BuildView = Em.View.extend({ templateName: 'build' }); -App.LoadingView = Em.View.extend({ templateName: 'loading' }); - -App.store = App.Store.create(); - -var onTrue = function(object, path, callback) { - if(object.getPath(path)) { - callback(); - } else { - var observer = function() { - object.removeObserver(path, observer); - callback() - }; - object.addObserver(path, observer); - } -}; - -var onLoaded = function(object, callback) { - if(object) { - var path = Ember.isArray(object) ? 'firstObject.isLoaded' : 'isLoaded'; - // should observe RecordArray.isLoaded instead, but that doesn't seem to exist? - onTrue(object, path, function() { - callback(Ember.isArray(object) ? object.get('firstObject') : object); - }); - } else { - callback(object); - } -} - -App.Router = Em.Router.extend({ - enableLogging: true, - location: 'hash', - - root: Em.Route.extend({ - viewRepository: Ember.Route.transitionTo('current'), - - index: Em.Route.extend({ - route: '/', - - connectOutlets: function(router) { - router.connectLayout({}, function(repository) { - router.connectCurrent(repository.get('lastBuild')); - }); - }, - - viewCurrent: Ember.Route.transitionTo('current'), - viewHistory: Ember.Route.transitionTo('history'), - viewBuild: Ember.Route.transitionTo('build'), - }), - - current: Em.Route.extend({ - route: '/:ownerName/:name', - - serialize: function(router, repository) { - return router.serializeRepository(repository); - }, - - connectOutlets: function(router, repository) { - var params = router.serializeRepository(repository); - router.connectLayout(params, function(repository) { - router.connectCurrent(repository.get('lastBuild')); - }); - } - }), - viewCurrent: Ember.Route.transitionTo('current'), - - history: Em.Route.extend({ - route: '/:ownerName/:name/builds', - - serialize: function(router, repository) { - return router.serializeRepository(repository); - }, - - connectOutlets: function(router, repository) { - var params = router.serializeRepository(repository); - router.connectLayout(params, function(repository) { - var builds = repository.get('builds'); - // why do i have to wait here. is repo.isLoaded true before the hasMany array is loaded? - onLoaded(builds, function() { - router.connectHistory(builds) - }) - }); - } - }), - viewHistory: Ember.Route.transitionTo('history'), - - build: Em.Route.extend({ - route: '/:ownerName/:name/builds/:id', - - serialize: function(router, build) { - return router.serializeBuild(build); - }, - - connectOutlets: function(router, build) { - params = router.serializeBuild(build); - router.connectLayout(params, function(repository, build) { - router.connectBuild(build) - }); - } - }), - viewBuild: Ember.Route.transitionTo('build') - }), - - serializeRepository: function(repository) { - if(repository instanceof DS.Model) { - return repository.getProperties('ownerName', 'name'); - } else { - return repository || {}; - } - }, - - serializeBuild: function(build) { - if(build instanceof DS.Model) { - var repository = build.get('repository') - // var repository = App.Repository.find(build.get('repositoryId')); // wat. - var params = this.serializeRepository(repository); - return $.extend(params, { id: build.get('id') }); - } else { - return build || {}; - } - }, - - connectLayout: function(params, callback) { - var repositories = App.Repository.find(); - this.connectLeft(repositories); - this.connectMain(repositories, params, callback); - this.connectRight(); - }, - - connectLeft: function(repositories) { - this.get('applicationController').connectOutlet({ outletName: 'left', name: 'repositories', context: repositories }) - }, - - connectRight: function() { - // this.get('applicationController').connectOutlet({ outletName: 'right', name: 'sidebar' }) - }, - - connectLoading: function() { - this.get('applicationController').connectOutlet({ outletName: 'main', name: 'loading' }); - }, - - connectMain: function(repositories, params, callback) { - this.connectLoading(); - - if(params.ownerName && params.name) { - // needs to implement findQuery - // var repositories = App.Repository.find(params); - repositories = App.Repository.find().filter(function(data) { - return data.get('owner_name') == params.owner_name && data.get('name') == params.name; - }) - } - var build = params.id ? App.Build.find(params.id) : undefined; - - onLoaded(repositories, function(repository) { - onLoaded(build, function(build) { - this.connectTabs(repository, build); - this.connectRepository(repository); - callback(repository, build); - }.bind(this)); - }.bind(this)); - }, - - connectRepository: function(repository) { - this.get('applicationController').connectOutlet({ outletName: 'main', name: 'repository', context: repository }); - }, - - connectTabs: function(repository, build) { - this.setPath('tabsController.repository', repository); - this.setPath('tabsController.build', build); - this.get('repositoryController').connectOutlet({ outletName: 'tabs', name: 'tabs' }); - }, - - connectCurrent: function(build) { - this.get('repositoryController').connectOutlet({ outletName: 'tab', name: 'current', context: build}); - }, - - connectHistory: function(builds) { - this.get('repositoryController').connectOutlet({ outletName: 'tab', name: 'history', context: builds}); - }, - - connectBuild: function(build) { - this.get('repositoryController').connectOutlet({ outletName: 'tab', name: 'build', context: build}); - } -}); - -App.initialize(); diff --git a/app/assets/javascripts/app/app.js.coffee b/app/assets/javascripts/app/app.js.coffee new file mode 100644 index 00000000..2f4d7ab0 --- /dev/null +++ b/app/assets/javascripts/app/app.js.coffee @@ -0,0 +1,13 @@ +#= require_tree ./models +#= require_tree ./templates +#= require ./controllers.js +#= require ./views.js +#= require ./routes.js +#= require_self + +Travis = window.Travis +Travis.store = DS.Store.extend( + revision: 4 + adapter: Travis.FixtureAdapter.create() +).create() +Travis.initialize() diff --git a/app/assets/javascripts/app/controllers.js.coffee b/app/assets/javascripts/app/controllers.js.coffee new file mode 100644 index 00000000..64742c72 --- /dev/null +++ b/app/assets/javascripts/app/controllers.js.coffee @@ -0,0 +1,8 @@ +Travis.ApplicationController = Em.Controller.extend() +Travis.RepositoriesController = Em.ArrayController.extend() +Travis.RepositoryController = Em.Controller.extend() +Travis.TabsController = Em.Controller.extend() +Travis.CurrentController = Em.Controller.extend() +Travis.HistoryController = Em.ArrayController.extend() +Travis.BuildController = Em.Controller.extend() +Travis.LoadingController = Em.Controller.extend() diff --git a/app/assets/javascripts/app/models/build.js.coffee b/app/assets/javascripts/app/models/build.js.coffee new file mode 100644 index 00000000..57a6c266 --- /dev/null +++ b/app/assets/javascripts/app/models/build.js.coffee @@ -0,0 +1,63 @@ +@Travis.Build = Travis.Model.extend # Travis.Helpers, + repository_id: DS.attr('number') + state: DS.attr('string') + number: DS.attr('number') + branch: DS.attr('string') + message: DS.attr('string') + result: DS.attr('number') + duration: DS.attr('number') + started_at: DS.attr('string') + finished_at: DS.attr('string') + committed_at: DS.attr('string') + committer_name: DS.attr('string') + committer_email: DS.attr('string') + author_name: DS.attr('string') + author_email: DS.attr('string') + compare_url: DS.attr('string') + + repository: DS.belongsTo('Travis.Repository') + commit: DS.belongsTo('Travis.Commit') + # jobs: DS.hasMany('Travis.Job') + + config: (-> + @getPath 'data.config' + ).property('data.config') + + isMatrix: (-> + @getPath('data.job_ids.length') > 1 + ).property('data.job_ids.length') + + isFailureMatrix: (-> + @get('allowedFailureJobs').length > 0 + ).property('allowedFailureJobs') + + # TODO why does the hasMany association not work? + jobs: (-> + Travis.Job.findMany(@getPath('data.job_ids')) + ).property('data.job_ids.length') + + requiredJobs: (-> + @get('jobs').filter (item, index) -> item.get('allow_failure') isnt true + ).property('jobs') + + allowedFailureJobs: (-> + @get('jobs').filter (item, index) -> item.get 'allow_failure' + ).property('jobs') + + tick: -> + @notifyPropertyChange 'duration' + @notifyPropertyChange 'finished_at' + +@Travis.Build.reopenClass + byRepositoryId: (id, parameters) -> + @find($.extend(parameters || {}, repository_id: id, orderBy: 'number DESC')) + + olderThanNumber: (id, build_number) -> + @find(url: '/repositories/' + id + '/builds.json?bare=true&after_number=' + build_number, repository_id: id, orderBy: 'number DESC') + +@Travis.Build.FIXTURES = [ + { id: 1, repository_id: 1, number: 1, event_type: 'push' }, + { id: 2, repository_id: 1, number: 2, event_type: 'push' }, + { id: 3, repository_id: 2, number: 3, event_type: 'push' }, + { id: 4, repository_id: 3, number: 4, event_type: 'push' } +] diff --git a/app/assets/javascripts/app/models/repository.js.coffee b/app/assets/javascripts/app/models/repository.js.coffee new file mode 100644 index 00000000..ebea1c59 --- /dev/null +++ b/app/assets/javascripts/app/models/repository.js.coffee @@ -0,0 +1,67 @@ +@Travis.Repository = Travis.Model.extend # Travis.Helpers, + slug: DS.attr('string') + name: DS.attr('string') + owner: DS.attr('string') + description: DS.attr('string') + last_build_id: DS.attr('number') + last_build_number: DS.attr('string') + last_build_result: DS.attr('number') + last_build_started_at: DS.attr('string') + last_build_finished_at: DS.attr('string') + + builds: (-> + Travis.Build.byRepositoryId @get('id'), event_type: 'push' + ).property() + + pullRequests: (-> + Travis.Build.byRepositoryId @get('id'), event_type: 'pull_request' + ).property() + + lastBuild: (-> + Travis.Build.find @get('last_build_id') + ).property('last_build_id') + + last_build_duration: (-> + duration = @getPath('data.last_build_duration') + duration = @durationFrom(@get('last_build_started_at'), @get('last_build_finished_at')) unless duration + duration + ).property('data.last_build_duration', 'last_build_started_at', 'last_build_finished_at') + + stats: (-> + return unless Travis.env is 'production' + url = 'https://api.github.com/json/repos/show/' + @get('slug') + @get('_stats') || $.get(url, (data) => @set('_stats', data)) && undefined + ).property('_stats') + + select: -> + Travis.Repository.select(self.get('id')) + + tick: -> + @notifyPropertyChange 'last_build_duration' + @notifyPropertyChange 'last_build_finished_at' + +@Travis.Repository.reopenClass + recent: -> + @find() + + ownedBy: (owner) -> + @find(owner: owner, orderBy: 'name') + + search: (query) -> + @find(search: query, orderBy: 'name') + + bySlug: (slug) -> + repo = $.detect(@find().toArray(), (repo) -> repo.get('slug') == slug) + if repo then Ember.ArrayProxy.create(content: [repo]) else @find(slug: slug) + + select: (id) -> + @find().forEach (repository) -> + repository.set 'selected', repository.get('id') is id + +@Travis.Repository.FIXTURES = [ + { id: 1, owner: 'travis-ci', name: 'travis-core', build_ids: [1, 2] }, + { id: 2, owner: 'travis-ci', name: 'travis-assets', build_ids: [3] }, + { id: 3, owner: 'travis-ci', name: 'travis-hub', build_ids: [4] }, +] + + diff --git a/app/assets/javascripts/app/routes.js.coffee b/app/assets/javascripts/app/routes.js.coffee new file mode 100644 index 00000000..96a9a2db --- /dev/null +++ b/app/assets/javascripts/app/routes.js.coffee @@ -0,0 +1,132 @@ +Travis.Router = Em.Router.extend + enableLogging: true + location: 'hash' + + root: Em.Route.extend + viewRepository: Ember.Route.transitionTo('current') + index: Em.Route.extend + route: '/' + connectOutlets: (router) -> + router.connectLayout {}, (repository) -> + router.connectCurrent repository.get('lastBuild') + + viewCurrent: Ember.Route.transitionTo('current') + viewHistory: Ember.Route.transitionTo('history') + viewBuild: Ember.Route.transitionTo('build') + + current: Em.Route.extend + route: '/:owner/:name' + serialize: (router, repository) -> + router.serializeRepository repository + + connectOutlets: (router, repository) -> + params = router.serializeRepository(repository) + router.connectLayout params, (repository) -> + builds = repository.get('builds') + onceLoaded builds, -> + router.connectCurrent builds.get('firstObject') + + viewCurrent: Ember.Route.transitionTo('current') + history: Em.Route.extend + route: '/:owner/:name/builds' + serialize: (router, repository) -> + router.serializeRepository repository + + connectOutlets: (router, repository) -> + params = router.serializeRepository(repository) + router.connectLayout params, (repository) -> + builds = repository.get('builds') + onceLoaded builds, -> + router.connectHistory builds + + viewHistory: Ember.Route.transitionTo('history') + build: Em.Route.extend + route: '/:owner/:name/builds/:id' + serialize: (router, build) -> + router.serializeBuild build + + connectOutlets: (router, build) -> + params = router.serializeBuild(build) + router.connectLayout params, (repository, build) -> + router.connectBuild build + + viewBuild: Ember.Route.transitionTo('build') + + serializeRepository: (repository) -> + if repository instanceof DS.Model + repository.getProperties 'owner', 'name' + else + repository or {} + + serializeBuild: (build) -> + if build instanceof DS.Model + repository = build.get('repository') + params = @serializeRepository(repository) + $.extend params, + id: build.get('id') + else + build or {} + + connectLayout: (params, callback) -> + repositories = Travis.Repository.find() + @connectLeft repositories + @connectMain repositories, params, callback + @connectRight() + + connectLeft: (repositories) -> + @get('applicationController').connectOutlet + outletName: 'left' + name: 'repositories' + context: repositories + + connectRight: -> + # ... + + connectLoading: -> + @get('applicationController').connectOutlet + outletName: 'main' + name: 'loading' + + connectMain: (repositories, params, callback) -> + @connectLoading() + if params.owner and params.name + repositories = Travis.Repository.find().filter (data) -> + data.get('owner_name') is params.owner_name and data.get('name') is params.name + build = (if params.id then Travis.Build.find(params.id) else `undefined`) + + onceLoaded repositories, build, => + repository = repositories.get('firstObject') + @connectRepository repository + @connectTabs repository, build + callback repository, build + + connectRepository: (repository) -> + @get('applicationController').connectOutlet + outletName: 'main' + name: 'repository' + context: repository + + connectTabs: (repository, build) -> + @setPath 'tabsController.repository', repository + @setPath 'tabsController.build', build + @get('repositoryController').connectOutlet + outletName: 'tabs' + name: 'tabs' + + connectCurrent: (build) -> + @get('repositoryController').connectOutlet + outletName: 'tab' + name: 'current' + context: build + + connectHistory: (builds) -> + @get('repositoryController').connectOutlet + outletName: 'tab' + name: 'history' + context: builds + + connectBuild: (build) -> + @get('repositoryController').connectOutlet + outletName: 'tab' + name: 'build' + context: build diff --git a/app/assets/javascripts/app/store.js b/app/assets/javascripts/app/store.js deleted file mode 100644 index 8b137891..00000000 --- a/app/assets/javascripts/app/store.js +++ /dev/null @@ -1 +0,0 @@ - diff --git a/app/assets/javascripts/app/templates/history.hbs b/app/assets/javascripts/app/templates/builds/list.hbs similarity index 100% rename from app/assets/javascripts/app/templates/history.hbs rename to app/assets/javascripts/app/templates/builds/list.hbs diff --git a/app/assets/javascripts/app/templates/build.hbs b/app/assets/javascripts/app/templates/builds/show.hbs similarity index 100% rename from app/assets/javascripts/app/templates/build.hbs rename to app/assets/javascripts/app/templates/builds/show.hbs diff --git a/app/assets/javascripts/app/templates/current.hbs b/app/assets/javascripts/app/templates/current.hbs deleted file mode 100644 index 88c7d791..00000000 --- a/app/assets/javascripts/app/templates/current.hbs +++ /dev/null @@ -1,3 +0,0 @@ -current build {{content.id}} - - diff --git a/app/assets/javascripts/app/templates/repositories.hbs b/app/assets/javascripts/app/templates/repositories/list.hbs similarity index 67% rename from app/assets/javascripts/app/templates/repositories.hbs rename to app/assets/javascripts/app/templates/repositories/list.hbs index 20fe4415..5ab23480 100644 --- a/app/assets/javascripts/app/templates/repositories.hbs +++ b/app/assets/javascripts/app/templates/repositories/list.hbs @@ -1,6 +1,6 @@ diff --git a/app/assets/javascripts/app/templates/repository.hbs b/app/assets/javascripts/app/templates/repositories/show.hbs similarity index 55% rename from app/assets/javascripts/app/templates/repository.hbs rename to app/assets/javascripts/app/templates/repositories/show.hbs index 81613968..1fb4ce61 100644 --- a/app/assets/javascripts/app/templates/repository.hbs +++ b/app/assets/javascripts/app/templates/repositories/show.hbs @@ -1,4 +1,4 @@ -

{{content.ownerName}}/{{content.name}}

+

{{content.owner}}/{{content.name}}

{{outlet tabs}} diff --git a/app/assets/javascripts/app/templates/tabs.hbs b/app/assets/javascripts/app/templates/repositories/tabs.hbs similarity index 100% rename from app/assets/javascripts/app/templates/tabs.hbs rename to app/assets/javascripts/app/templates/repositories/tabs.hbs diff --git a/app/assets/javascripts/app/views.js.coffee b/app/assets/javascripts/app/views.js.coffee new file mode 100644 index 00000000..b3b2b400 --- /dev/null +++ b/app/assets/javascripts/app/views.js.coffee @@ -0,0 +1,9 @@ +Travis.ApplicationView = Em.View.extend templateName: 'application' +Travis.RepositoriesView = Em.View.extend templateName: 'repositories/list' +Travis.RepositoryView = Em.View.extend templateName: 'repositories/show' +Travis.TabsView = Em.View.extend templateName: 'repositories/tabs' +Travis.CurrentView = Em.View.extend templateName: 'builds/show' +Travis.HistoryView = Em.View.extend templateName: 'builds/list' +Travis.BuildView = Em.View.extend templateName: 'builds/show' +Travis.LoadingView = Em.View.extend templateName: 'loading' + diff --git a/app/assets/javascripts/lib/data_store_adapter.js.coffee b/app/assets/javascripts/lib/data_store_adapter.js.coffee new file mode 100644 index 00000000..f303fb61 --- /dev/null +++ b/app/assets/javascripts/lib/data_store_adapter.js.coffee @@ -0,0 +1,127 @@ +@Travis.FixtureAdapter = DS.Adapter.extend + find: (store, type, id) -> + fixtures = type.FIXTURES + Ember.assert "Unable to find fixtures for model type " + type.toString(), !!fixtures + return if fixtures.hasLoaded + setTimeout (-> + store.loadMany type, fixtures + fixtures.hasLoaded = true + ), 300 + + findMany: -> + @find.apply this, arguments + + findAll: (store, type) -> + fixtures = type.FIXTURES + Ember.assert "Unable to find fixtures for model type " + type.toString(), !!fixtures + ids = fixtures.map (item, index, self) -> + item.id + store.loadMany type, ids, fixtures + + findQuery: (store, type, params, array) -> + fixtures = type.FIXTURES + Ember.assert "Unable to find fixtures for model type " + type.toString(), !!fixtures + hashes = for fixture in fixtures + matches = for key, value of params + key == 'orderBy' || fixture[key] == value + if matches.reduce((a, b) -> a && b) then fixture else null + array.load(hashes.compact()) + +@Travis.DataStoreAdapter = DS.RESTAdapter.extend + init: -> + @_super() + # TODO should be able to specify these as strings + @set 'mappings', + builds: Travis.Build, + commits: Travis.Commit, + jobs: Travis.Job + service_hooks: Travis.ServiceHook + + plurals: + repository: 'repositories', + branch: 'branches' + + updateRecord: (store, type, record) -> + id = get(record, record.get('primaryKey') || 'id') + root = @rootForType(type) + plural = @pluralize(root) + url = @buildURL(type.url || plural, id) + data = root: record.toJSON() + + @ajax url, 'PUT', + data: data + success: (json) -> + @sideload(store, type, json, root) + store.didUpdateRecord(record, json && json[root]) + + find: (store, type, id) -> + root = @rootForType(type) + plural = @pluralize(root) + url = @buildURL(type.url || plural, id) + + @ajax url, 'GET', + success: (json) -> + @sideload(store, type, json, root) + store.load(type, json[root]) + accepts: + json: 'application/vnd.travis-ci.2+json' + + findMany: (store, type, ids) -> + root = @rootForType(type) + plural = @pluralize(root) + url = @buildURL(type.url || plural) + + @ajax url, 'GET', + data: + ids: ids + success: (json) -> + @sideload(store, type, json, plural) + store.loadMany(type, json[plural]) + accepts: + json: 'application/vnd.travis-ci.2+json' + + findAll: (store, type) -> + root = @rootForType(type) + plural = @pluralize(root) + url = @buildURL(type.url || plural) + + @ajax url, 'GET', + success: (json) -> + @sideload(store, type, json, plural) + store.loadMany(type, json[plural]) + accepts: + json: 'application/vnd.travis-ci.2+json' + + findQuery: (store, type, query, recordArray) -> + root = @rootForType(type) + plural = @pluralize(root) + url = @buildURL(type.url || plural) + + @ajax url, 'GET', + data: query, + success: (json) -> + @sideload(store, type, json, plural) + recordArray.load(json[plural]) + accepts: + json: 'application/vnd.travis-ci.2+json' + + rootForType: (type) -> + # sorry, but this seems very weird, really + # return type.url if (type.url) + + parts = type.toString().split('.') + name = parts[parts.length - 1] + name.replace(/([A-Z])/g, '_$1').toLowerCase().slice(1) + + buildURL: (record, suffix) -> + Ember.assert('Namespace URL (' + @namespace + ') must not start with slash', !@namespace || @namespace.toString().charAt(0) != '/') + Ember.assert('Record URL (' + record + ') must not start with slash', !record || record.toString().charAt(0) != '/') + Ember.assert('URL suffix (' + suffix + ') must not start with slash', !suffix || suffix.toString().charAt(0) != '/') + + url = [''] + url.push(@namespace) if (@namespace != undefined) + url.push(record) + url.push(suffix) if (suffix != undefined) + url.join('/') + + diff --git a/app/assets/javascripts/lib/hax0rs.js.coffee b/app/assets/javascripts/lib/hax0rs.js.coffee new file mode 100644 index 00000000..da27df4b --- /dev/null +++ b/app/assets/javascripts/lib/hax0rs.js.coffee @@ -0,0 +1,26 @@ +window.onTrue = (object, path, callback) -> + if object.getPath(path) + callback() + else + observer = -> + object.removeObserver path, observer + callback() + object.addObserver path, observer + +window.onceLoaded = -> + objects = Array.prototype.slice.apply(arguments) + callback = objects.pop() + + # sadly Ember.Enumerable.compact does not remove undefined values + objects = (if object then object else null for object in objects).compact() + object = objects.shift() + + if object + path = if Ember.isArray(object) then 'firstObject.isLoaded' else 'isLoaded' + onTrue object, path, -> + if objects.length == 0 + callback(object) + else + onceLoaded.apply(objects + [callback]) + else + callback object diff --git a/app/assets/javascripts/lib/model.js.coffee b/app/assets/javascripts/lib/model.js.coffee new file mode 100644 index 00000000..252be1dc --- /dev/null +++ b/app/assets/javascripts/lib/model.js.coffee @@ -0,0 +1,17 @@ +@Travis.Model = DS.Model.extend + primaryKey: 'id' + id: DS.attr('number') + + refresh: -> + id = @get('id') + Travis.app.store.adapter.find(Travis.app.store, @constructor, id) if id + + update: (attrs) -> + $.each attrs, (key, value) => + @set(key, value) unless key is 'id' + this + +@Travis.Model.reopenClass + load: (attrs) -> + Travis.app.store.load(this, attrs) + diff --git a/app/assets/javascripts/travis.js b/app/assets/javascripts/travis.js index 59100086..b9ba2a2b 100644 --- a/app/assets/javascripts/travis.js +++ b/app/assets/javascripts/travis.js @@ -1,2 +1,5 @@ +//= require_self +//= require_tree ./lib //= require app/app.js +Travis = Em.Application.create();