Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
c0b7c75b
Commit
c0b7c75b
authored
Mar 19, 2015
by
Nick Stenning
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2057 from hypothesis/toastr
Replace flash service with angular-toastr
parents
e53a7820
f3b7d065
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
484 additions
and
133 deletions
+484
-133
account-controller.coffee
h/static/scripts/account/account-controller.coffee
+6
-3
account.coffee
h/static/scripts/account/account.coffee
+1
-1
auth-controller.coffee
h/static/scripts/account/auth-controller.coffee
+2
-1
account-controller-test.coffee
h/static/scripts/account/test/account-controller-test.coffee
+13
-9
auth-controller-test.coffee
h/static/scripts/account/test/auth-controller-test.coffee
+2
-2
app.coffee
h/static/scripts/app.coffee
+1
-0
annotation.coffee
h/static/scripts/directives/annotation.coffee
+2
-2
flash-service.coffee
h/static/scripts/flash-service.coffee
+7
-75
session-service.coffee
h/static/scripts/session/session-service.coffee
+2
-1
session-service-test.coffee
h/static/scripts/session/test/session-service-test.coffee
+3
-3
angular-toastr.css
h/static/scripts/vendor/angular-toastr/angular-toastr.css
+187
-0
angular-toastr.js
h/static/scripts/vendor/angular-toastr/angular-toastr.js
+258
-0
base.scss
h/static/styles/base.scss
+0
-36
No files found.
h/static/scripts/account/account-controller.coffee
View file @
c0b7c75b
...
...
@@ -10,7 +10,8 @@ class AccountController
onSuccess
=
(
form
,
response
)
->
# Fire flash messages.
for
type
,
msgs
of
response
.
flash
flash
(
type
,
msgs
)
for
m
in
msgs
flash
[
type
](
m
)
form
.
$setPristine
()
formModel
=
form
.
$name
.
slice
(
0
,
-
4
)
...
...
@@ -26,9 +27,11 @@ class AccountController
formHelpers
.
applyValidationErrors
(
form
,
response
.
data
.
errors
)
else
if
response
.
data
.
flash
flash
(
type
,
msgs
)
for
own
type
,
msgs
of
response
.
data
.
flash
for
own
type
,
msgs
of
response
.
data
.
flash
for
m
in
msgs
flash
[
type
](
m
)
else
flash
(
'error'
,
'Sorry, we were unable to perform your request'
)
flash
.
error
(
'Sorry, we were unable to perform your request'
)
$scope
.
$broadcast
'formState'
,
form
.
$name
,
''
# Update status btn
...
...
h/static/scripts/account/account.coffee
View file @
c0b7c75b
...
...
@@ -89,7 +89,7 @@ configure = [
authCheck
.
reject
'no session'
return
null
.
catch
(
err
)
->
flash
'error'
,
'Sign out failed!'
flash
.
error
(
'Sign out failed!'
)
throw
err
]
...
...
h/static/scripts/account/auth-controller.coffee
View file @
c0b7c75b
...
...
@@ -48,8 +48,9 @@ class AuthController
timeout
=
$timeout
->
angular
.
copy
{},
$scope
.
model
$scope
.
form
?
.
$setPristine
()
flash
'info'
,
flash
.
info
(
'For your security, the forms have been reset due to inactivity.'
)
,
300000
...
...
h/static/scripts/account/test/account-controller-test.coffee
View file @
c0b7c75b
...
...
@@ -26,7 +26,11 @@ describe 'h:AccountController', ->
beforeEach
module
(
$provide
,
$filterProvider
)
->
sandbox
=
sinon
.
sandbox
.
create
()
fakeSession
=
{}
fakeFlash
=
sandbox
.
spy
()
fakeFlash
=
success
:
sandbox
.
spy
()
info
:
sandbox
.
spy
()
warning
:
sandbox
.
spy
()
error
:
sandbox
.
spy
()
fakeIdentity
=
logout
:
sandbox
.
spy
()
fakeFormHelpers
=
...
...
@@ -120,9 +124,7 @@ describe 'h:AccountController', ->
controller
=
createController
()
$scope
.
submit
(
fakeForm
)
assert
.
calledWith
(
fakeFlash
,
'success'
,
[
'Your profile has been updated.'
])
assert
.
calledWith
(
fakeFlash
.
success
,
'Your profile has been updated.'
)
it
'displays a flash message if a server error occurs'
,
->
fakeForm
=
createFakeForm
()
...
...
@@ -136,7 +138,7 @@ describe 'h:AccountController', ->
flash
:
error
:
[
'Something bad happened'
]
assert
.
calledWith
(
fakeFlash
,
'error'
,
[
'Something bad happened'
]
)
assert
.
calledWith
(
fakeFlash
.
error
,
'Something bad happened'
)
it
'displays a fallback flash message if none are present'
,
->
fakeForm
=
createFakeForm
()
...
...
@@ -148,7 +150,8 @@ describe 'h:AccountController', ->
status
:
500
data
:
{}
assert
.
calledWith
(
fakeFlash
,
'error'
,
'Sorry, we were unable to perform your request'
)
assert
.
calledWith
(
fakeFlash
.
error
,
'Sorry, we were unable to perform your request'
)
describe
'.delete'
,
->
createFakeForm
=
(
overrides
=
{})
->
...
...
@@ -217,9 +220,9 @@ describe 'h:AccountController', ->
flash
:
error
:
[
'Something bad happened'
]
assert
.
calledWith
(
fakeFlash
,
'error'
,
[
'Something bad happened'
]
)
assert
.
calledWith
(
fakeFlash
.
error
,
'Something bad happened'
)
it
'displays a fallback
flash
message if none are present'
,
->
it
'displays a fallback
toast
message if none are present'
,
->
fakeForm
=
createFakeForm
()
controller
=
createController
()
$scope
.
delete
(
fakeForm
)
...
...
@@ -229,4 +232,5 @@ describe 'h:AccountController', ->
status
:
500
data
:
{}
assert
.
calledWith
(
fakeFlash
,
'error'
,
'Sorry, we were unable to perform your request'
)
assert
.
calledWith
(
fakeFlash
.
error
,
'Sorry, we were unable to perform your request'
)
h/static/scripts/account/test/auth-controller-test.coffee
View file @
c0b7c75b
...
...
@@ -18,7 +18,7 @@ class MockSession
$promise
:
finally
:
sandbox
.
stub
()
mockFlash
=
sandbox
.
spy
()
mockFlash
=
info
:
sandbox
.
spy
()
mockFormHelpers
=
applyValidationErrors
:
sandbox
.
spy
()
describe
'h:AuthController'
,
->
...
...
@@ -117,7 +117,7 @@ describe 'h:AuthController', ->
$timeout
.
lastCall
.
args
[
0
]()
assert
.
called
$scope
.
form
.
$setPristine
,
'the form is pristine'
assert
.
deepEqual
$scope
.
model
,
{},
'the model is erased'
assert
.
called
mockFlash
,
'a notification is flashed
'
assert
.
called
mockFlash
.
info
,
'a flash notification is shown
'
it
'should not happen if the model is empty'
,
->
$scope
.
model
=
undefined
...
...
h/static/scripts/app.coffee
View file @
c0b7c75b
...
...
@@ -11,6 +11,7 @@ imports = [
'ngRoute'
'ngSanitize'
'ngTagsInput'
'h.flash'
'h.helpers'
'h.identity'
'h.session'
...
...
h/static/scripts/directives/annotation.coffee
View file @
c0b7c75b
...
...
@@ -151,9 +151,9 @@ AnnotationController = [
###
this.save = ->
unless model.user or model.deleted
return flash
'info', 'Please sign in to save your annotations.'
return flash
.info('Please sign in to save your annotations.')
unless validate(@annotation)
return flash
'info', 'Please add text or a tag before publishing.'
return flash
.info('Please add text or a tag before publishing.')
# Update stored tags with the new tags of this annotation
tags = @annotation.tags.filter (tag) ->
...
...
h/static/scripts/flash-service.coffee
View file @
c0b7c75b
escape
=
(
html
)
->
html
.
replace
(
/&(?!\w+;)/g
,
'&'
)
.
replace
(
/</g
,
'<'
)
.
replace
(
/>/g
,
'>'
)
.
replace
(
/"/g
,
'"'
)
class
Notification
# Default options.
options
:
html
:
"<div class='annotator-notice'></div>"
classes
:
show
:
"annotator-notice-show"
info
:
"annotator-notice-info"
success
:
"annotator-notice-success"
error
:
"annotator-notice-error"
@
INFO
:
'info'
@
ERROR
:
'error'
@
SUCCESS
:
'success'
constructor
:
(
options
)
->
element
=
$
(
@
options
.
html
).
hide
()[
0
]
@
element
=
$
(
element
)
@
options
=
$
.
extend
(
true
,
{},
@
options
,
options
)
# Retain the fat arrow binding despite skipping the super-class constructor
# XXX: replace with _appendElement override when we move to Annotator v2.
show
:
(
message
,
status
=
Notification
.
INFO
)
=>
@
currentStatus
=
status
$
(
@
element
)
.
addClass
(
@
options
.
classes
.
show
)
.
addClass
(
@
options
.
classes
[
@
currentStatus
])
.
html
(
escape
(
message
||
""
))
setTimeout
@
hide
,
5000
@
element
.
prependTo
(
document
.
body
).
slideDown
()
hide
:
=>
@
currentStatus
?=
Annotator
.
Notification
.
INFO
$
(
@
element
)
.
removeClass
(
@
options
.
classes
.
show
)
.
removeClass
(
@
options
.
classes
[
@
currentStatus
])
@
element
.
slideUp
=>
@
element
.
remove
()
class
FlashProvider
queues
:
''
:
[]
info
:
[]
error
:
[]
success
:
[]
notice
:
null
$get
:
->
angular
.
bind
this
,
this
.
_flash
_process
:
->
for
q
,
msgs
of
@
queues
if
msgs
.
length
msg
=
msgs
.
shift
()
unless
q
then
[
q
,
msg
]
=
msg
notice
=
new
Notification
()
notice
.
show
(
msg
,
q
)
break
_flash
:
(
queue
,
messages
)
->
if
@
queues
[
queue
]
?
@
queues
[
queue
]
=
@
queues
[
queue
]
?
.
concat
messages
this
.
_process
()
angular
.
module
(
'h'
)
.
provider
(
'flash'
,
FlashProvider
)
angular
.
module
(
'h.flash'
,
[
'toastr'
]).
factory
(
'flash'
,
[
'toastr'
,
(
toastr
)
->
info
:
angular
.
bind
(
toastr
,
toastr
.
info
)
success
:
angular
.
bind
(
toastr
,
toastr
.
success
)
warning
:
angular
.
bind
(
toastr
,
toastr
.
warning
)
error
:
angular
.
bind
(
toastr
,
toastr
.
error
)
])
h/static/scripts/session/session-service.coffee
View file @
c0b7c75b
...
...
@@ -60,7 +60,8 @@ class SessionProvider
# Fire flash messages.
for
q
,
msgs
of
data
.
flash
flash
q
,
msgs
for
m
in
msgs
flash
[
q
](
m
)
xsrf
.
token
=
model
.
csrf
...
...
h/static/scripts/session/test/session-service-test.coffee
View file @
c0b7c75b
...
...
@@ -19,8 +19,8 @@ describe 'h.session', ->
beforeEach
module
(
$provide
,
sessionProvider
)
->
sandbox
=
sinon
.
sandbox
.
create
()
fakeFlash
=
sandbox
.
spy
()
fakeDocument
=
{
prop
:
->
'/session'
}
fakeFlash
=
error
:
sandbox
.
spy
()
fakeXsrf
=
{
token
:
'faketoken'
}
$provide
.
value
'$document'
,
fakeDocument
...
...
@@ -56,11 +56,11 @@ describe 'h.session', ->
it
'should invoke the flash service with any flash messages'
,
->
response
=
flash
:
error
:
'fail'
error
:
[
'fail'
]
$httpBackend
.
expectPOST
(
url
).
respond
(
response
)
result
=
session
.
login
({})
$httpBackend
.
flush
()
assert
.
calledWith
fakeFlash
,
'error'
,
'fail'
assert
.
calledWith
fakeFlash
.
error
,
'fail'
it
'should assign errors and status reasons to the model'
,
->
response
=
...
...
h/static/scripts/vendor/angular-toastr/angular-toastr.css
0 → 100644
View file @
c0b7c75b
.toast-title
{
font-weight
:
bold
;
}
.toast-message
{
-ms-word-wrap
:
break-word
;
word-wrap
:
break-word
;
}
.toast-message
a
,
.toast-message
label
{
color
:
#ffffff
;
}
.toast-message
a
:hover
{
color
:
#cccccc
;
text-decoration
:
none
;
}
.toast-close-button
{
position
:
relative
;
right
:
-0.3em
;
top
:
-0.3em
;
float
:
right
;
font-size
:
20px
;
font-weight
:
bold
;
color
:
#ffffff
;
-webkit-text-shadow
:
0
1px
0
#ffffff
;
text-shadow
:
0
1px
0
#ffffff
;
opacity
:
0.8
;
-ms-filter
:
progid
:
DXImageTransform
.
Microsoft
.
Alpha
(
Opacity
=
80
);
filter
:
alpha
(
opacity
=
80
);
}
.toast-close-button
:hover
,
.toast-close-button
:focus
{
color
:
#000000
;
text-decoration
:
none
;
cursor
:
pointer
;
opacity
:
0.4
;
-ms-filter
:
progid
:
DXImageTransform
.
Microsoft
.
Alpha
(
Opacity
=
40
);
filter
:
alpha
(
opacity
=
40
);
}
/*Additional properties for button version
iOS requires the button element instead of an anchor tag.
If you want the anchor version, it requires `href="#"`.*/
button
.toast-close-button
{
padding
:
0
;
cursor
:
pointer
;
background
:
transparent
;
border
:
0
;
-webkit-appearance
:
none
;
}
.toast-top-full-width
{
top
:
0
;
right
:
0
;
width
:
100%
;
}
.toast-bottom-full-width
{
bottom
:
0
;
right
:
0
;
width
:
100%
;
}
.toast-top-left
{
top
:
12px
;
left
:
12px
;
}
.toast-top-right
{
top
:
12px
;
right
:
12px
;
}
.toast-bottom-right
{
right
:
12px
;
bottom
:
12px
;
}
.toast-bottom-left
{
bottom
:
12px
;
left
:
12px
;
}
#toast-container
{
position
:
fixed
;
z-index
:
999999
;
/*overrides*/
}
#toast-container
*
{
-moz-box-sizing
:
border-box
;
-webkit-box-sizing
:
border-box
;
box-sizing
:
border-box
;
}
#toast-container
>
div
{
margin
:
0
0
6px
;
padding
:
15px
15px
15px
50px
;
width
:
300px
;
-moz-border-radius
:
3px
3px
3px
3px
;
-webkit-border-radius
:
3px
3px
3px
3px
;
border-radius
:
3px
3px
3px
3px
;
background-position
:
15px
center
;
background-repeat
:
no-repeat
;
-moz-box-shadow
:
0
0
12px
#999999
;
-webkit-box-shadow
:
0
0
12px
#999999
;
box-shadow
:
0
0
12px
#999999
;
color
:
#ffffff
;
opacity
:
0.8
;
-ms-filter
:
progid
:
DXImageTransform
.
Microsoft
.
Alpha
(
Opacity
=
80
);
filter
:
alpha
(
opacity
=
80
);
}
#toast-container
>
:hover
{
-moz-box-shadow
:
0
0
12px
#000000
;
-webkit-box-shadow
:
0
0
12px
#000000
;
box-shadow
:
0
0
12px
#000000
;
opacity
:
1
;
-ms-filter
:
progid
:
DXImageTransform
.
Microsoft
.
Alpha
(
Opacity
=
100
);
filter
:
alpha
(
opacity
=
100
);
cursor
:
pointer
;
}
#toast-container
>
.toast-info
{
background-image
:
url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=")
!important
;
}
#toast-container
>
.toast-error
{
background-image
:
url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=")
!important
;
}
#toast-container
>
.toast-success
{
background-image
:
url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==")
!important
;
}
#toast-container
>
.toast-warning
{
background-image
:
url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=")
!important
;
}
#toast-container
.toast-top-full-width
>
div
,
#toast-container
.toast-bottom-full-width
>
div
{
width
:
96%
;
margin
:
auto
;
}
.toast
{
background-color
:
#030303
;
}
.toast-success
{
background-color
:
#51a351
;
}
.toast-error
{
background-color
:
#bd362f
;
}
.toast-info
{
background-color
:
#2f96b4
;
}
.toast-warning
{
background-color
:
#f89406
;
}
/*Animations*/
.toast
{
opacity
:
1
!important
;
}
.toast.ng-enter
{
opacity
:
0
!important
;
transition
:
opacity
.3s
linear
;
}
.toast.ng-enter.ng-enter-active
{
opacity
:
1
!important
;
}
.toast.ng-leave
{
opacity
:
1
;
transition
:
opacity
.3s
linear
;
}
.toast.ng-leave.ng-leave-active
{
opacity
:
0
!important
;
}
/*Responsive Design*/
@media
all
and
(
max-width
:
240px
)
{
#toast-container
>
div
{
padding
:
8px
8px
8px
50px
;
width
:
11em
;
}
#toast-container
.toast-close-button
{
right
:
-0.2em
;
top
:
-0.2em
;
}
}
@media
all
and
(
min-width
:
241px
)
and
(
max-width
:
480px
)
{
#toast-container
>
div
{
padding
:
8px
8px
8px
50px
;
width
:
18em
;
}
#toast-container
.toast-close-button
{
right
:
-0.2em
;
top
:
-0.2em
;
}
}
@media
all
and
(
min-width
:
481px
)
and
(
max-width
:
768px
)
{
#toast-container
>
div
{
padding
:
15px
15px
15px
50px
;
width
:
25em
;
}
}
h/static/scripts/vendor/angular-toastr/angular-toastr.js
0 → 100644
View file @
c0b7c75b
angular
.
module
(
'toastr'
,
[])
.
directive
(
'toast'
,
[
'$compile'
,
'$timeout'
,
'toastr'
,
function
(
$compile
,
$timeout
,
toastr
)
{
return
{
replace
:
true
,
templateUrl
:
'templates/toastr/toastr.html'
,
link
:
function
(
scope
,
element
,
attrs
)
{
var
timeout
;
scope
.
toastClass
=
scope
.
options
.
toastClass
;
scope
.
titleClass
=
scope
.
options
.
titleClass
;
scope
.
messageClass
=
scope
.
options
.
messageClass
;
if
(
scope
.
options
.
closeHtml
)
{
var
button
=
angular
.
element
(
scope
.
options
.
closeHtml
);
button
.
addClass
(
'toast-close-button'
);
button
.
attr
(
'ng-click'
,
'close()'
);
$compile
(
button
)(
scope
);
element
.
prepend
(
button
);
}
scope
.
init
=
function
()
{
if
(
scope
.
options
.
timeOut
)
{
timeout
=
createTimeout
(
scope
.
options
.
timeOut
);
}
};
element
.
on
(
'mouseenter'
,
function
()
{
if
(
timeout
)
{
$timeout
.
cancel
(
timeout
);
}
});
scope
.
tapToast
=
function
()
{
if
(
scope
.
options
.
tapToDismiss
)
{
scope
.
close
();
}
};
scope
.
close
=
function
()
{
toastr
.
remove
(
scope
.
toastId
);
};
element
.
on
(
'mouseleave'
,
function
()
{
if
(
scope
.
options
.
timeOut
===
0
&&
scope
.
options
.
extendedTimeOut
===
0
)
{
return
;
}
timeout
=
createTimeout
(
scope
.
options
.
extendedTimeOut
);
});
function
createTimeout
(
time
)
{
return
$timeout
(
function
()
{
toastr
.
remove
(
scope
.
toastId
);
},
time
);
}
}
};
}])
.
constant
(
'toastrConfig'
,
{
allowHtml
:
false
,
closeButton
:
false
,
closeHtml
:
'<button>×</button>'
,
containerId
:
'toast-container'
,
extendedTimeOut
:
1000
,
iconClasses
:
{
error
:
'toast-error'
,
info
:
'toast-info'
,
success
:
'toast-success'
,
warning
:
'toast-warning'
},
messageClass
:
'toast-message'
,
positionClass
:
'toast-top-right'
,
tapToDismiss
:
true
,
timeOut
:
5000
,
titleClass
:
'toast-title'
,
toastClass
:
'toast'
})
.
factory
(
'toastr'
,
[
'$animate'
,
'$compile'
,
'$document'
,
'$rootScope'
,
'$sce'
,
'toastrConfig'
,
'$q'
,
function
(
$animate
,
$compile
,
$document
,
$rootScope
,
$sce
,
toastrConfig
,
$q
)
{
var
container
,
index
=
0
,
toasts
=
[];
var
containerDefer
=
$q
.
defer
();
var
toastr
=
{
clear
:
clear
,
error
:
error
,
info
:
info
,
remove
:
remove
,
success
:
success
,
warning
:
warning
};
return
toastr
;
/* Public API */
function
clear
(
toast
)
{
if
(
toast
)
{
remove
(
toast
.
toastId
);
}
else
{
for
(
var
i
=
0
;
i
<
toasts
.
length
;
i
++
)
{
remove
(
toasts
[
i
].
toastId
);
}
}
}
function
error
(
message
,
title
,
optionsOverride
)
{
return
_notify
({
iconClass
:
_getOptions
().
iconClasses
.
error
,
message
:
message
,
optionsOverride
:
optionsOverride
,
title
:
title
});
}
function
info
(
message
,
title
,
optionsOverride
)
{
return
_notify
({
iconClass
:
_getOptions
().
iconClasses
.
info
,
message
:
message
,
optionsOverride
:
optionsOverride
,
title
:
title
});
}
function
success
(
message
,
title
,
optionsOverride
)
{
return
_notify
({
iconClass
:
_getOptions
().
iconClasses
.
success
,
message
:
message
,
optionsOverride
:
optionsOverride
,
title
:
title
});
}
function
warning
(
message
,
title
,
optionsOverride
)
{
return
_notify
({
iconClass
:
_getOptions
().
iconClasses
.
warning
,
message
:
message
,
optionsOverride
:
optionsOverride
,
title
:
title
});
}
/* Internal functions */
function
_getOptions
()
{
return
angular
.
extend
({},
toastrConfig
);
}
function
_setContainer
(
options
)
{
if
(
container
)
{
return
containerDefer
.
promise
;
}
// If the container is there, don't create it.
container
=
angular
.
element
(
'<div></div>'
);
container
.
attr
(
'id'
,
options
.
containerId
);
container
.
addClass
(
options
.
positionClass
);
container
.
css
({
'pointer-events'
:
'auto'
});
var
body
=
$document
.
find
(
'body'
).
eq
(
0
);
$animate
.
enter
(
container
,
body
,
null
,
function
()
{
containerDefer
.
resolve
();
});
return
containerDefer
.
promise
;
}
function
_notify
(
map
)
{
var
options
=
_getOptions
();
var
newToast
=
{
toastId
:
index
++
,
scope
:
$rootScope
.
$new
()
};
newToast
.
iconClass
=
map
.
iconClass
;
if
(
map
.
optionsOverride
)
{
options
=
angular
.
extend
(
options
,
map
.
optionsOverride
);
newToast
.
iconClass
=
map
.
optionsOverride
.
iconClass
||
newToast
.
iconClass
;
}
createScope
(
newToast
,
map
,
options
);
newToast
.
el
=
createToast
(
newToast
.
scope
);
toasts
.
push
(
newToast
);
_setContainer
(
options
).
then
(
function
()
{
$animate
.
enter
(
newToast
.
el
,
container
,
null
,
function
()
{
newToast
.
scope
.
init
();
});
});
return
newToast
;
function
createScope
(
toast
,
map
,
options
)
{
if
(
options
.
allowHtml
)
{
toast
.
scope
.
allowHtml
=
true
;
toast
.
scope
.
title
=
$sce
.
trustAsHtml
(
map
.
title
);
toast
.
scope
.
message
=
$sce
.
trustAsHtml
(
map
.
message
);
}
else
{
toast
.
scope
.
title
=
map
.
title
;
toast
.
scope
.
message
=
map
.
message
;
}
toast
.
scope
.
toastType
=
toast
.
iconClass
;
toast
.
scope
.
toastId
=
toast
.
toastId
;
toast
.
scope
.
options
=
{
extendedTimeOut
:
options
.
extendedTimeOut
,
messageClass
:
options
.
messageClass
,
tapToDismiss
:
options
.
tapToDismiss
,
timeOut
:
options
.
timeOut
,
titleClass
:
options
.
titleClass
,
toastClass
:
options
.
toastClass
};
if
(
options
.
closeButton
)
{
toast
.
scope
.
options
.
closeHtml
=
options
.
closeHtml
;
}
}
function
createToast
(
scope
)
{
var
angularDomEl
=
angular
.
element
(
'<div toast></div>'
);
return
$compile
(
angularDomEl
)(
scope
);
}
}
function
remove
(
toastIndex
)
{
var
toast
=
findToast
(
toastIndex
);
if
(
toast
)
{
// Avoid clicking when fading out
$animate
.
leave
(
toast
.
el
,
function
()
{
toast
.
scope
.
$destroy
();
if
(
container
&&
container
.
children
().
length
===
0
)
{
toasts
=
[];
container
.
remove
();
container
=
null
;
containerDefer
=
$q
.
defer
();
}
});
}
function
findToast
(
toastId
)
{
for
(
var
i
=
0
;
i
<
toasts
.
length
;
i
++
)
{
if
(
toasts
[
i
].
toastId
===
toastId
)
{
return
toasts
[
i
];
}
}
}
}
}]);
angular
.
module
(
'toastr'
).
run
([
'$templateCache'
,
function
(
$templateCache
)
{
'use strict'
;
$templateCache
.
put
(
'templates/toastr/toastr.html'
,
"<div class=
\"
{{toastClass}} {{toastType}}
\"
ng-click=
\"
tapToast()
\"
>
\n
"
+
" <div ng-switch on=
\"
allowHtml
\"
>
\n
"
+
" <div ng-switch-default ng-if=
\"
title
\"
class=
\"
{{titleClass}}
\"
>{{title}}</div>
\n
"
+
" <div ng-switch-default class=
\"
{{messageClass}}
\"
>{{message}}</div>
\n
"
+
" <div ng-switch-when=
\"
true
\"
ng-if=
\"
title
\"
class=
\"
{{titleClass}}
\"
ng-bind-html=
\"
title
\"
></div>
\n
"
+
" <div ng-switch-when=
\"
true
\"
class=
\"
{{messageClass}}
\"
ng-bind-html=
\"
message
\"
></div>
\n
"
+
" </div>
\n
"
+
"</div>"
);
}]);
h/static/styles/base.scss
View file @
c0b7c75b
...
...
@@ -29,47 +29,11 @@
background
:
url("../images/noise_1.png")
;
}
//FLASH/TOAST/ALERTS///////////////////////////////
.annotator-notice
{
@include
box-shadow
(
inset
2px
1px
1px
hsla
(
0
,
0%
,
0%
,
.1
));
@include
single-transition
(
opacity
,
.2s
);
direction
:
ltr
;
font-family
:
$sans-font-family
;
font-weight
:
300
;
line-height
:
29px
;
opacity
:
0
;
position
:
relative
;
text-align
:
center
;
z-index
:
5
;
&
.show
,
&
.annotator-notice-show
{
opacity
:
1
;
}
}
.annotator-hide
{
display
:
none
;
visibility
:
hidden
;
}
.annotator-notice-info
{
color
:
#3a87ad
;
background-color
:
#d9edf7
;
border-color
:
#98BED1
;
}
.annotator-notice-success
{
color
:
#468847
;
background-color
:
#dff0d8
;
border-color
:
#8DC98E
;
}
.annotator-notice-error
{
color
:
#b94a48
;
background-color
:
#f2dede
;
border-color
:
#F5A1A0
;
}
// Icons
[
class
^=
"h-icon-"
],
[
class
*=
" h-icon-"
]
{
vertical-align
:
middle
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment