Permalink
Browse files

Initial commit of UI Framework

  • Loading branch information...
0 parents commit 1cb81bcf044bcee310e27445ece346b9ce10008a @jawsthegame jawsthegame committed Oct 1, 2012
Showing with 2,989 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. +46 −0 Makefile
  3. 0 README.md
  4. +75 −0 app/controllers/controller.coffee
  5. +21 −0 app/controllers/form_controller.coffee
  6. +54 −0 app/controllers/login_controller.coffee
  7. +28 −0 app/controllers/navigation_controller.coffee
  8. +43 −0 app/index.coffee
  9. +104 −0 app/lib/date.js
  10. +36 −0 app/lib/events.coffee
  11. +3 −0 app/lib/form_error.haml
  12. +49 −0 app/lib/format.coffee
  13. +188 −0 app/lib/forms.coffee
  14. +9 −0 app/lib/jquery-ui-1.8.22.datepicker-only.min.js
  15. +13 −0 app/models/collection.coffee
  16. +53 −0 app/models/filtered_collection.coffee
  17. +21 −0 app/models/loader.coffee
  18. +29 −0 app/models/model.coffee
  19. +49 −0 app/models/user.coffee
  20. +7 −0 app/templates/layout.haml
  21. +2 −0 app/templates/login/layout.haml
  22. +18 −0 app/templates/login/view.haml
  23. +16 −0 app/templates/navigation/index.haml
  24. +1 −0 app/templates/search_view.haml
  25. +4 −0 app/templates/tab.haml
  26. +26 −0 app/views/detail_view.coffee
  27. +87 −0 app/views/list_view.coffee
  28. +33 −0 app/views/login/login_view.coffee
  29. +50 −0 app/views/navigation_view.coffee
  30. +26 −0 app/views/notice_view.coffee
  31. +19 −0 app/views/search_view.coffee
  32. +28 −0 app/views/tab_view.coffee
  33. +63 −0 app/views/view.coffee
  34. +19 −0 package.json
  35. +9 −0 slug.js
  36. +17 −0 slug.json
  37. +245 −0 test/controllers/controller_spec.coffee
  38. +29 −0 test/controllers/navigation_controller_spec.coffee
  39. +3 −0 test/controllers/test_aaa_template.haml
  40. +5 −0 test/controllers/test_controller_layout.haml
  41. +1 −0 test/controllers/test_sort_template.haml
  42. +3 −0 test/controllers/test_zzz_template.haml
  43. +24 −0 test/lib/chai_extensions.coffee
  44. +43 −0 test/lib/events_spec.coffee
  45. +29 −0 test/lib/form_view_spec_template.haml
  46. +44 −0 test/lib/format_spec.coffee
  47. +311 −0 test/lib/forms_spec.coffee
  48. +471 −0 test/lib/mock_server.js
  49. +73 −0 test/setup.coffee
  50. +5 −0 test/templates/detail_view.haml
  51. +76 −0 test/views/detail_spec.coffee
  52. +157 −0 test/views/list_view_spec.coffee
  53. +37 −0 test/views/notice_view_spec.coffee
  54. +23 −0 test/views/search_view_spec.coffee
  55. +28 −0 test/views/tab_view_spec.coffee
  56. +3 −0 test/views/test_form.haml
  57. +2 −0 test/views/test_list_layout.haml
  58. +1 −0 test/views/test_list_template.haml
  59. +7 −0 test/views/test_template.haml
  60. +121 −0 test/views/view_spec.coffee
@@ -0,0 +1,2 @@
+node_modules
+tags
@@ -0,0 +1,46 @@
+mocha = @./node_modules/.bin/mocha \
+ --compilers coffee:coffee-script
+
+HEM = @./node_modules/.bin/hem
+
+FILES?=`find ./test -type f -name '*.coffee'`
+HOST?=http://localhost
+OUTPUT?=host.html
+
+# If PAT is passed in, feed that to mocha. It will only run tests matching that
+# pattern.
+ifneq ('', PAT)
+MOCHA=$(mocha) -g "$(PAT)"
+else
+MOCHA=$(mocha)
+endif
+
+export NODE_PATH=./app
+
+xunit:
+ $(MOCHA) -R xunit $(FILES)
+
+test:
+ $(MOCHA) -R spec $(FILES)
+
+debug:
+ $(MOCHA) --debug-brk -R spec $(FILES)
+
+watch:
+ $(MOCHA) -R dot -w $(FILES)
+
+update:
+ @npm install
+
+tags:
+ @ctags -R app
+
+deploy:
+ @rm -f ./public/application.*
+ $(HEM) build
+ @sed "s|http://localhost:[0-9]*|$(HOST)|g" ./public/index.html > ./public/$(OUTPUT)
+ @s3cmd sync --acl-public ./public/ s3://partners.vistarmedia.com
+ @rm -f ./public/application.*
+ @rm -f ./public/$(OUTPUT)
+
+.PHONY: test
No changes.
@@ -0,0 +1,75 @@
+Backbone = require 'backbone'
+$ = require 'jqueryify2'
+
+events = require 'lib/events'
+
+
+class Controller extends Backbone.Router
+ views: {}
+ events: {}
+
+ constructor: (opts) ->
+ super
+
+ @history = if (opts? and opts.history?) then opts.history else Backbone.history
+ @_localEl = @_createLocalEl()
+ @_pageEl = $(arguments[0]?.el or '<div>')
+
+ @_setupViews()
+ @_setupEventHandling()
+
+ activate: ->
+ @_pageEl.children().detach()
+ @_pageEl.append(@_localEl)
+ @_cleanupChildView()
+ this
+
+ destroy: ->
+ @_cleanupChildView()
+
+ for _, viewName of @views
+ @[viewName].remove()
+
+ for pattern, methodName of @events
+ [viewName, match] = pattern.split '.'
+ view = @[viewName]
+ view.off match
+
+ trackNew: ->
+ @_cleanupChildView()
+ args = (v for k, v of arguments)
+ controllerType = args[0]
+
+ initArgs = args[1..]
+ initArgs.push {el: @_pageEl}
+
+ @_child = new controllerType(initArgs...)
+ @_child
+
+ _createLocalEl: ->
+ $('<div>').addClass(@constructor.name)
+ .append(@layout())
+
+ _render: ->
+ if @layout then @$el.empty().append(@layout())
+ @_setupViews()
+
+ _setupViews: ->
+ selectors = Object.keys(@views)
+ selectors.sort()
+
+ for selector in selectors
+ @_localEl.find(selector).append(@[@views[selector]].el)
+
+ _setupEventHandling: ->
+ for pattern, methodName of @events
+ [viewName, match] = pattern.split '.'
+ method = @[methodName]
+ view = @[viewName]
+ view.on(match, method, this)
+
+ _cleanupChildView: ->
+ @_child?.destroy()
+ @_child = undefined
+
+module.exports = events.track Controller
@@ -0,0 +1,21 @@
+_ = require 'underscore'
+Deferred = require('jqueryify2').Deferred
+
+Controller = require 'controllers/controller'
+
+
+class FormController extends Controller
+ layout: _.template('<div class="form-view"></div>')
+
+ views:
+ '.form-view': 'formView'
+
+ constructor: (@formView, opts) ->
+ super(opts)
+
+ save: ->
+ @activate()
+ @formView.deferred
+
+
+module.exports = FormController
@@ -0,0 +1,54 @@
+Deferred = require('jqueryify2').Deferred
+Backbone = require 'backbone'
+
+Controller = require 'controllers/controller'
+LoginView = require 'views/login/login_view'
+NoticeView = require 'views/notice_view'
+User = require 'models/user'
+
+
+class LoginController extends Controller
+ layout: require 'templates/login/layout'
+
+ views:
+ '.login-view': 'loginView'
+ '.login-view .notice': 'noticeView'
+
+ events:
+ 'loginView.change': 'checkCredentials'
+
+ routes:
+ 'login': 'login'
+ 'logout': 'logout'
+
+ constructor: ->
+ @whoami = User.fetch
+ @auth = User.authenticate
+
+ @loginView = new LoginView().render()
+ @noticeView = new NoticeView().render()
+
+ super
+
+ login: ->
+ @deferred = new Deferred
+ @whoami()
+ .done((user) => @deferred.resolve(user))
+ .fail((reason) => @activate())
+
+ @deferred.promise()
+
+ logout: ->
+ User.current?.logout().done =>
+ document.location = '/'
+
+ checkCredentials: (credentials) =>
+ @loginView.disable()
+
+ @auth(credentials.email, credentials.password)
+ .always(@loginView.enable)
+ .done(@deferred.resolve)
+ .fail((msg) => @noticeView.error(msg))
+
+
+module.exports = LoginController
@@ -0,0 +1,28 @@
+_ = require 'underscore'
+Backbone = require 'backbone'
+
+Controller = require 'controllers/controller'
+NavigationView = require 'views/navigation_view'
+
+
+class NavigationController extends Controller
+ layout: _.template('<div></div>')
+
+ views:
+ 'div': 'navigation'
+
+ constructor: (@user, opts) ->
+ @navigation = new NavigationView(@user).render()
+ super(opts)
+
+ @history = opts.history or Backbone.history
+ @history.on('route', @navigated, this)
+
+ destroy: ->
+ @history.off 'all'
+ super
+
+ navigated: ->
+ @navigation.updateSecondary(document.location.hash)
+
+module.exports = NavigationController
@@ -0,0 +1,43 @@
+$ = require 'jqueryify2'
+datepicker = require 'lib/jquery-ui-1.8.22.datepicker-only.min'
+Backbone = require 'backbone'
+
+loadModel = require 'models/loader'
+
+NavigationController = require 'controllers/navigation_controller'
+TabView = require 'views/tab_view'
+
+
+class App
+
+ # Create the applicatoin with the given API root. All AJAX requests will be
+ # made relative to this root. If omitted, the application will run as if it
+ # was being served from / on the same host as the API.
+ constructor: (@apiRoot) ->
+ module.exports.apiRoot = @apiRoot
+
+ root = $('body')
+ @loginController = new LoginController(el: root)
+
+ (do @login)
+ .pipe(@loadModel)
+ .pipe(@showUI)
+
+ login: =>
+ User.authenticateAgainst(@apiRoot)
+ @loginController.login()
+
+ loadModel: =>
+ $('body').text('loading...')
+ loadModel(@apiRoot)
+
+ showUI: (model) =>
+ layout = $('body').empty().append(require 'templates/layout')
+
+ main = layout.find('.body')
+ navigation = layout.find('.navigation')
+
+ Backbone.history.start()
+
+
+module.exports.app = App
Oops, something went wrong. Retry.

0 comments on commit 1cb81bc

Please sign in to comment.