Commit 8f64e090 authored by Randall Leeds's avatar Randall Leeds

Start to simplify our angular namespaces

Move toward cleaning up our angular namespaces and organization. By
flattening our namespaces and changing our file naming we're able to
reduce the boilerplate needed for angular module and asset bundle
definitions.

- Kill all the ``h.*`` angular submodules except for ``h.auth``,
  ``h.helpers`` and ``h.identity``. This vastly reduces the amount
  of dependency repetition throughout our angular files as all
  the dependencies of the entire main h module can be declared in
  app.coffee and all the other files simply add their exports to
  the main module.

- Add a helpers/helpers.coffee module definition file so that the
  rest of the helpers can use the 1-arity ``angular.module`` getter
  to attach themselves. These files can all be included with a glob
  in the asset bundle definition.

- Use the glob syntax to include all the directives in the asset
  bundle definition.

- Rename the controller modules in the auth bundle with a '-controller'
  suffix. These can be similarly globbed in the bundle definition.

- Make auth/auth.coffee a module definition file so that the
  rest of the component can use the 1-arity ``angular.module`` getter
  to attach themselves. These files can all be included with globs
  in the asset bundle definition.

- Ensure that all controllers are named in the ``FooController`` style.
parent f547c126
imports = [
'ngAnimate'
'ngRoute'
'ngSanitize'
'ngTagsInput'
'bootstrap'
'h.auth'
'h.controllers'
'h.directives'
'h.filters'
'h.streamsearch'
'h.helpers.formHelpers'
'h.helpers'
'h.identity'
]
......
imports = [
'h.session'
]
class AccountController
@inject = ['$scope', '$filter', 'flash', 'session', 'identity', 'formHelpers']
constructor: ($scope, $filter, flash, session, identity, formHelpers) ->
......@@ -72,5 +68,5 @@ class AccountController
promise.$promise.then(successHandler, errorHandler)
angular.module('h.account', imports)
angular.module('h.auth')
.controller('AccountController', AccountController)
class AuthController
this.$inject = ['$scope', '$timeout', 'flash', 'session', 'formHelpers']
constructor: ( $scope, $timeout, flash, session, formHelpers ) ->
timeout = null
success = (data) ->
if $scope.tab is 'forgot' then $scope.tab = 'activate'
if data.userid then $scope.$emit 'session', data
$scope.model = null
$scope.form?.$setPristine()
failure = (form, response) ->
{errors, reason} = response.data
formHelpers.applyValidationErrors(form, errors, reason)
this.submit = (form) ->
delete form.responseErrorMessage
form.$setValidity('response', true)
return unless form.$valid
$scope.$broadcast 'formState', form.$name, 'loading'
session[form.$name] $scope.model, success,
angular.bind(this, failure, form)
.$promise.finally -> $scope.$broadcast 'formState', form.$name, ''
$scope.model = null
$scope.tab = 'login'
$scope.$on '$destroy', ->
if timeout
$timeout.cancel timeout
$scope.$watchCollection 'model', (value) ->
# Reset the auth forms after five minutes of inactivity
if timeout
$timeout.cancel timeout
# If the model is not empty, start the timeout
if value and not angular.equals(value, {})
timeout = $timeout ->
$scope.form?.$setPristine()
$scope.model = null
flash 'info',
'For your security, the forms have been reset due to inactivity.'
, 300000
angular.module('h.auth')
.controller('AuthController', AuthController)
imports = [
'ngResource'
'h.identity'
'h.session'
'h.helpers'
]
class AuthController
this.$inject = ['$scope', '$timeout', 'flash', 'session', 'formHelpers']
constructor: ( $scope, $timeout, flash, session, formHelpers ) ->
timeout = null
configure = ['$httpProvider', 'identityProvider', ($httpProvider, identityProvider) ->
defaults = $httpProvider.defaults
success = (data) ->
if $scope.tab is 'forgot' then $scope.tab = 'activate'
if data.userid then $scope.$emit 'session', data
$scope.model = null
$scope.form?.$setPristine()
failure = (form, response) ->
{errors, reason} = response.data
formHelpers.applyValidationErrors(form, errors, reason)
this.submit = (form) ->
delete form.responseErrorMessage
form.$setValidity('response', true)
return unless form.$valid
$scope.$broadcast 'formState', form.$name, 'loading'
session[form.$name] $scope.model, success,
angular.bind(this, failure, form)
.$promise.finally -> $scope.$broadcast 'formState', form.$name, ''
$scope.model = null
$scope.tab = 'login'
$scope.$on '$destroy', ->
if timeout
$timeout.cancel timeout
$scope.$watchCollection 'model', (value) ->
# Reset the auth forms after five minutes of inactivity
if timeout
$timeout.cancel timeout
# If the model is not empty, start the timeout
if value and not angular.equals(value, {})
timeout = $timeout ->
$scope.form?.$setPristine()
$scope.model = null
flash 'info',
'For your security, the forms have been reset due to inactivity.'
, 300000
# Use the Pyramid XSRF header name
defaults.xsrfHeaderName = 'X-CSRF-Token'
$httpProvider.interceptors.push ['documentHelpers', (documentHelpers) ->
request: (config) ->
endpoint = documentHelpers.absoluteURI('/app')
if config.url.indexOf(endpoint) == 0
# Set the cross site request forgery token
cookieName = config.xsrfCookieName || defaults.xsrfCookieName
headerName = config.xsrfHeaderName || defaults.xsrfHeaderName
config.headers[headerName] ?= csrfToken
config
]
configure = ['$provide', 'identityProvider', ($provide, identityProvider) ->
identityProvider.checkAuthorization = [
'session',
(session) ->
......@@ -76,4 +45,3 @@ configure = ['$provide', 'identityProvider', ($provide, identityProvider) ->
angular.module('h.auth', imports, configure)
.controller('AuthController', AuthController)
imports = [
'ngResource'
'h.flash'
'h.helpers.documentHelpers'
]
ACTION = [
'login'
'logout'
......@@ -106,24 +99,5 @@ class SessionProvider
]
configure = ['$httpProvider', ($httpProvider) ->
defaults = $httpProvider.defaults
# Use the Pyramid XSRF header name
defaults.xsrfHeaderName = 'X-CSRF-Token'
$httpProvider.interceptors.push ['documentHelpers', (documentHelpers) ->
request: (config) ->
endpoint = documentHelpers.absoluteURI('/app')
if config.url.indexOf(endpoint) == 0
# Set the cross site request forgery token
cookieName = config.xsrfCookieName || defaults.xsrfCookieName
headerName = config.xsrfHeaderName || defaults.xsrfHeaderName
config.headers[headerName] ?= csrfToken
config
]
]
angular.module('h.session', imports, configure)
angular.module('h.auth')
.provider('session', SessionProvider)
imports = [
'bootstrap'
'h.flash'
'h.helpers.documentHelpers'
'h.identity'
'h.services'
'h.socket'
'h.searchfilters'
]
# User authorization function for the Permissions plugin.
authorizeAction = (action, annotation, user) ->
if annotation.permissions
......@@ -35,7 +24,7 @@ authorizeAction = (action, annotation, user) ->
true
class App
class AppController
this.$inject = [
'$location', '$q', '$route', '$scope', '$timeout',
'annotator', 'flash', 'identity', 'socket', 'streamfilter',
......@@ -347,7 +336,7 @@ class App
$scope.sort = name: 'Location'
class AnnotationViewer
class AnnotationViewerController
this.$inject = ['$routeParams', '$scope', 'streamfilter']
constructor: ($routeParams, $scope, streamfilter) ->
# Tells the view that these annotations are standalone
......@@ -372,7 +361,7 @@ class AnnotationViewer
sock.send(JSON.stringify({filter}))
class Viewer
class ViewerController
this.$inject = ['$scope', 'annotator']
constructor: ( $scope, annotator ) ->
# Tells the view that these annotations are embedded into the owner doc
......@@ -396,7 +385,7 @@ class Viewer
true
angular.module('h.controllers', imports)
.controller('AppController', App)
.controller('ViewerController', Viewer)
.controller('AnnotationViewerController', AnnotationViewer)
angular.module('h')
.controller('AppController', AppController)
.controller('ViewerController', ViewerController)
.controller('AnnotationViewerController', AnnotationViewerController)
imports = [
'ngSanitize'
'ngTagsInput'
'h.helpers.documentHelpers'
'h.services'
]
formInput = ->
link: (scope, elem, attr, [form, model, validator]) ->
return unless form?.$name and model?.$name and validator
......@@ -220,7 +212,7 @@ match = ->
require: 'ngModel'
angular.module('h.directives', imports)
angular.module('h')
.directive('formInput', formInput)
.directive('formValidate', formValidate)
.directive('privacy', privacy)
......
......@@ -288,6 +288,6 @@ annotation = ['annotator', 'documentHelpers', (annotator, documentHelpers) ->
]
angular.module('h.directives')
angular.module('h')
.controller('AnnotationController', AnnotationController)
.directive('annotation', annotation)
......@@ -73,6 +73,6 @@ deepCount = [
]
angular.module('h.directives')
angular.module('h')
.controller('DeepCountController', DeepCountController)
.directive('deepCount', deepCount)
......@@ -324,4 +324,5 @@ markdown = ['$filter', '$sanitize', '$sce', '$timeout', ($filter, $sanitize, $sc
templateUrl: 'markdown.html'
]
angular.module('h.directives').directive('markdown', markdown)
angular.module('h')
.directive('markdown', markdown)
......@@ -36,4 +36,5 @@ simpleSearch = ['$parse', ($parse) ->
]
angular.module('h.directives').directive('simpleSearch', simpleSearch)
angular.module('h')
.directive('simpleSearch', simpleSearch)
......@@ -41,4 +41,5 @@ statusButton = ->
transclude: 'element'
angular.module('h.directives').directive('statusButton', statusButton)
angular.module('h')
.directive('statusButton', statusButton)
......@@ -173,6 +173,6 @@ threadFilter = [
]
angular.module('h.directives')
angular.module('h')
.controller('ThreadFilterController', ThreadFilterController)
.directive('threadFilter', threadFilter)
......@@ -110,6 +110,6 @@ thread = [
]
angular.module('h.directives')
angular.module('h')
.controller('ThreadController', ThreadController)
.directive('thread', thread)
......@@ -70,7 +70,7 @@ elide = (text, split_length) ->
text
angular.module('h.filters', [])
angular.module('h')
.filter('converter', -> (new Converter()).makeHtml)
.filter('fuzzyTime', -> fuzzyTime)
.filter('moment', momentFilter)
......
......@@ -44,5 +44,5 @@ class FlashProvider
this._process()
angular.module('h.flash', ['ngResource'])
angular.module('h')
.provider('flash', FlashProvider)
......@@ -16,5 +16,5 @@ createDocumentHelpers = [
]
angular.module('h.helpers.documentHelpers', [])
angular.module('h.helpers')
.factory('documentHelpers', createDocumentHelpers)
......@@ -14,5 +14,5 @@ createFormHelpers = ->
form.responseErrorMessage = reason
angular.module('h.helpers.formHelpers', [])
angular.module('h.helpers')
.factory('formHelpers', createFormHelpers)
angular.module('h.helpers', [])
......@@ -348,7 +348,7 @@ class StreamFilter
this
angular.module('h.searchfilters', [])
angular.module('h')
.service('searchfilter', SearchFilter)
.service('queryparser', QueryParser)
.service('streamfilter', StreamFilter)
......@@ -516,7 +516,7 @@ class ViewFilter
count++
annotation.id
angular.module('h.services', [])
angular.module('h')
.factory('render', renderFactory)
.provider('drafts', DraftProvider)
.service('annotator', Hypothesis)
......
imports = [
'h.helpers.documentHelpers'
]
clientID = ->
# Generate client ID
buffer = (new Array(16))
......@@ -40,7 +35,7 @@ class Socket extends SockJS
this.send = send
angular.module('h.socket', imports)
angular.module('h')
.factory('clientID', clientID)
.factory('socket', socket)
.run(run)
imports = [
'bootstrap'
'h.controllers'
'h.directives'
'h.filters'
'h.flash'
'h.searchfilters'
]
class StreamSearch
class StreamSearchController
this.inject = [
'$scope', '$rootScope', '$routeParams',
'annotator', 'queryparser', 'searchfilter', 'streamfilter'
......@@ -45,5 +36,5 @@ class StreamSearch
sock.send(JSON.stringify({filter}))
angular.module('h.streamsearch', imports, configure)
.controller('StreamSearchController', StreamSearch)
angular.module('h')
.controller('StreamSearchController', StreamSearchController)
......@@ -2,7 +2,7 @@ assert = chai.assert
sinon.assert.expose assert, prefix: null
sandbox = sinon.sandbox.create()
describe 'h.account.AccountController', ->
describe 'h.auth.AccountController', ->
$scope = null
fakeFlash = null
fakeSession = null
......@@ -12,7 +12,7 @@ describe 'h.account.AccountController', ->
disableUserPromise = null
createController = null
beforeEach module('h.account')
beforeEach module('h.auth')
beforeEach module ($provide, $filterProvider) ->
fakeSession = {}
......
......@@ -3,7 +3,7 @@ assert = chai.assert
describe 'h.controllers', ->
fakeParams = null
beforeEach module('h.controllers')
beforeEach module('h')
beforeEach module ($provide) ->
fakeParams = {id: 'test'}
......
......@@ -10,6 +10,7 @@ describe 'h.directives', ->
fakeWindow = {open: sinon.spy()}
fakeDocument = angular.element({
createElement: (tag) -> document.createElement(tag)
baseURI: 'http://example.com'
})
$provide.value('$window', fakeWindow)
......@@ -22,8 +23,7 @@ describe 'h.directives', ->
return
beforeEach module('h.templates')
beforeEach module('h.directives')
beforeEach module('h')
beforeEach inject (_$compile_, _$rootScope_, _$injector_) ->
$compile = _$compile_
......
......@@ -8,7 +8,7 @@ describe 'h.directives.annotation', ->
createController = null
flash = null
beforeEach module('h.directives')
beforeEach module('h')
beforeEach inject ($controller, $rootScope) ->
$scope = $rootScope.$new()
......
......@@ -6,7 +6,7 @@ describe 'h.directives', ->
fakeWindow = null
isolate = null
beforeEach module('h.directives')
beforeEach module('h')
beforeEach inject (_$compile_, _$rootScope_) ->
$compile = _$compile_
......
......@@ -5,7 +5,7 @@ describe 'h.directives.statusButton', ->
$compile = null
$element = null
beforeEach module('h.directives')
beforeEach module('h')
beforeEach inject (_$compile_, _$rootScope_) ->
$compile = _$compile_
......
......@@ -8,7 +8,7 @@ describe 'h.directives.thread', ->
createController = null
flash = null
beforeEach module('h.directives')
beforeEach module('h')
beforeEach inject ($controller, $rootScope) ->
$scope = $rootScope.$new()
......
......@@ -4,7 +4,7 @@ sinon.assert.expose(assert, prefix: '')
describe 'h.helpers.formHelpers', ->
formHelpers = null
beforeEach module('h.helpers.formHelpers')
beforeEach module('h.helpers')
beforeEach inject (_formHelpers_) ->
formHelpers = _formHelpers_
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment