Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
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
edx
edx-platform
Commits
d8b419c6
Commit
d8b419c6
authored
Aug 26, 2015
by
muhammad-ammar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Review changes
parent
6134e8b5
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
614 additions
and
559 deletions
+614
-559
cms/static/coffee/spec/views/feedback_spec.coffee
+0
-315
common/static/common/js/components/utils/view_utils.js
+5
-1
common/static/common/js/components/views/feedback.js
+139
-133
common/static/common/js/components/views/feedback_alert.js
+39
-34
common/static/common/js/components/views/feedback_notification.js
+30
-25
common/static/common/js/components/views/feedback_prompt.js
+38
-33
common/static/common/js/spec/components/feedback_spec.js
+336
-0
common/static/common/js/spec/components/view_utils_spec.js
+6
-2
common/static/common/js/spec_helpers/view_helpers.js
+9
-6
common/static/common/templates/components/system-feedback.underscore
+2
-3
lms/djangoapps/teams/static/teams/js/spec/views/team_profile_spec.js
+5
-5
lms/static/sass/_build-lms.scss
+1
-2
lms/static/sass/_mixins-inherited.scss
+2
-0
lms/static/sass/_mixins.scss
+2
-0
No files found.
cms/static/coffee/spec/views/feedback_spec.coffee
deleted
100644 → 0
View file @
6134e8b5
define
[
"jquery"
,
"js/views/feedback"
,
"js/views/feedback_notification"
,
"js/views/feedback_alert"
,
"js/views/feedback_prompt"
,
"sinon"
],
(
$
,
SystemFeedback
,
NotificationView
,
AlertView
,
PromptView
,
sinon
)
->
tpl
=
readFixtures
(
'system-feedback.underscore'
)
beforeEach
->
setFixtures
(
sandbox
({
id
:
"page-alert"
}))
appendSetFixtures
(
sandbox
({
id
:
"page-notification"
}))
appendSetFixtures
(
sandbox
({
id
:
"page-prompt"
}))
appendSetFixtures
(
$
(
"<script>"
,
{
id
:
"system-feedback-tpl"
,
type
:
"text/template"
}).
text
(
tpl
))
@
addMatchers
toBeShown
:
->
@
actual
.
hasClass
(
"is-shown"
)
and
not
@
actual
.
hasClass
(
"is-hiding"
)
toBeHiding
:
->
@
actual
.
hasClass
(
"is-hiding"
)
and
not
@
actual
.
hasClass
(
"is-shown"
)
toContainText
:
(
text
)
->
# remove this when we upgrade jasmine-jquery
trimmedText
=
$
.
trim
(
@
actual
.
text
())
if
text
and
$
.
isFunction
(
text
.
test
)
return
text
.
test
(
trimmedText
)
else
return
trimmedText
.
indexOf
(
text
)
!=
-
1
;
toHaveBeenPrevented
:
->
# remove this when we upgrade jasmine-jquery
eventName
=
@
actual
.
eventName
selector
=
@
actual
.
selector
@
message
=
->
[
"Expected event
#{
eventName
}
to have been prevented on
#{
selector
}
"
,
"Expected event
#{
eventName
}
not to have been prevented on
#{
selector
}
"
]
return
jasmine
.
JQuery
.
events
.
wasPrevented
(
selector
,
eventName
)
describe
"SystemFeedback"
,
->
beforeEach
->
@
options
=
title
:
"Portal"
message
:
"Welcome to the Aperture Science Computer-Aided Enrichment Center"
# it will be interesting to see when this.render is called, so lets spy on it
@
renderSpy
=
spyOn
(
AlertView
.
Confirmation
.
prototype
,
'render'
).
andCallThrough
()
@
showSpy
=
spyOn
(
AlertView
.
Confirmation
.
prototype
,
'show'
).
andCallThrough
()
@
hideSpy
=
spyOn
(
AlertView
.
Confirmation
.
prototype
,
'hide'
).
andCallThrough
()
@
clock
=
sinon
.
useFakeTimers
()
afterEach
->
@
clock
.
restore
()
it
"requires a type and an intent"
,
->
neither
=
=>
new
SystemFeedback
(
@
options
)
noType
=
=>
options
=
$
.
extend
({},
@
options
)
options
.
intent
=
"confirmation"
new
SystemFeedback
(
options
)
noIntent
=
=>
options
=
$
.
extend
({},
@
options
)
options
.
type
=
"alert"
new
SystemFeedback
(
options
)
both
=
=>
options
=
$
.
extend
({},
@
options
)
options
.
type
=
"alert"
options
.
intent
=
"confirmation"
new
SystemFeedback
(
options
)
expect
(
neither
).
toThrow
()
expect
(
noType
).
toThrow
()
expect
(
noIntent
).
toThrow
()
expect
(
both
).
not
.
toThrow
()
# for simplicity, we'll use AlertView.Confirmation from here on,
# which extends and proxies to SystemFeedback
it
"does not show on initalize"
,
->
view
=
new
AlertView
.
Confirmation
(
@
options
)
expect
(
@
renderSpy
).
not
.
toHaveBeenCalled
()
expect
(
@
showSpy
).
not
.
toHaveBeenCalled
()
# Disabled flaky test TNL-559
xit
"renders the template"
,
->
view
=
new
AlertView
.
Confirmation
(
@
options
)
view
.
show
()
expect
(
view
.
$
(
".action-close"
)).
toBeDefined
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
expect
(
view
.
$el
).
toContainText
(
@
options
.
title
)
expect
(
view
.
$el
).
toContainText
(
@
options
.
message
)
# Disabled flaky test TNL-559
xit
"close button sends a .hide() message"
,
->
view
=
new
AlertView
.
Confirmation
(
@
options
).
show
()
view
.
$
(
".action-close"
).
click
()
expect
(
@
hideSpy
).
toHaveBeenCalled
()
@
clock
.
tick
(
900
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
describe
"PromptView"
,
->
# for some reason, expect($("body")) blows up the test runner, so this test
# just exercises the Prompt rather than asserting on anything. Best I can
# do for now. :(
it
"changes class on body"
,
->
# expect($("body")).not.toHaveClass("prompt-is-shown")
view
=
new
PromptView
.
Confirmation
({
title
:
"Portal"
message
:
"Welcome to the Aperture Science Computer-Aided Enrichment Center"
})
# expect($("body")).toHaveClass("prompt-is-shown")
view
.
hide
()
# expect($("body")).not.toHaveClass("prompt-is-shown")
describe
"NotificationView.Mini"
,
->
beforeEach
->
@
view
=
new
NotificationView
.
Mini
()
it
"should have minShown set to 1250 by default"
,
->
expect
(
@
view
.
options
.
minShown
).
toEqual
(
1250
)
it
"should have closeIcon set to false by default"
,
->
expect
(
@
view
.
options
.
closeIcon
).
toBeFalsy
()
# Disabled flaky test TNL-559
xdescribe
"SystemFeedback click events"
,
->
beforeEach
->
@
primaryClickSpy
=
jasmine
.
createSpy
(
'primaryClick'
)
@
secondaryClickSpy
=
jasmine
.
createSpy
(
'secondaryClick'
)
@
view
=
new
NotificationView
.
Warning
(
title
:
"Unsaved"
,
message
:
"Your content is currently Unsaved."
,
actions
:
primary
:
text
:
"Save"
,
class
:
"save-button"
,
click
:
@
primaryClickSpy
secondary
:
text
:
"Revert"
,
class
:
"cancel-button"
,
click
:
@
secondaryClickSpy
)
@
view
.
show
()
it
"should trigger the primary event on a primary click"
,
->
@
view
.
$
(
".action-primary"
).
click
()
expect
(
@
primaryClickSpy
).
toHaveBeenCalled
()
expect
(
@
secondaryClickSpy
).
not
.
toHaveBeenCalled
()
it
"should trigger the secondary event on a secondary click"
,
->
@
view
.
$
(
".action-secondary"
).
click
()
expect
(
@
secondaryClickSpy
).
toHaveBeenCalled
()
expect
(
@
primaryClickSpy
).
not
.
toHaveBeenCalled
()
it
"should apply class to primary action"
,
->
expect
(
@
view
.
$
(
".action-primary"
)).
toHaveClass
(
"save-button"
)
it
"should apply class to secondary action"
,
->
expect
(
@
view
.
$
(
".action-secondary"
)).
toHaveClass
(
"cancel-button"
)
it
"should preventDefault on primary action"
,
->
spyOnEvent
(
".action-primary"
,
"click"
)
@
view
.
$
(
".action-primary"
).
click
()
expect
(
"click"
).
toHaveBeenPreventedOn
(
".action-primary"
)
it
"should preventDefault on secondary action"
,
->
spyOnEvent
(
".action-secondary"
,
"click"
)
@
view
.
$
(
".action-secondary"
).
click
()
expect
(
"click"
).
toHaveBeenPreventedOn
(
".action-secondary"
)
# Disabled flaky test TNL-559
xdescribe
"SystemFeedback not preventing events"
,
->
beforeEach
->
@
clickSpy
=
jasmine
.
createSpy
(
'clickSpy'
)
@
view
=
new
AlertView
.
Confirmation
(
title
:
"It's all good"
message
:
"No reason for this alert"
actions
:
primary
:
text
:
"Whatever"
click
:
@
clickSpy
preventDefault
:
false
)
@
view
.
show
()
it
"should not preventDefault"
,
->
spyOnEvent
(
".action-primary"
,
"click"
)
@
view
.
$
(
".action-primary"
).
click
()
expect
(
"click"
).
not
.
toHaveBeenPreventedOn
(
".action-primary"
)
expect
(
@
clickSpy
).
toHaveBeenCalled
()
# Disabled flaky test TNL-559
xdescribe
"SystemFeedback multiple secondary actions"
,
->
beforeEach
->
@
secondarySpyOne
=
jasmine
.
createSpy
(
'secondarySpyOne'
)
@
secondarySpyTwo
=
jasmine
.
createSpy
(
'secondarySpyTwo'
)
@
view
=
new
NotificationView
.
Warning
(
title
:
"No Primary"
,
message
:
"Pick a secondary action"
,
actions
:
secondary
:
[
{
text
:
"Option One"
class
:
"option-one"
click
:
@
secondarySpyOne
},
{
text
:
"Option Two"
class
:
"option-two"
click
:
@
secondarySpyTwo
}
]
)
@
view
.
show
()
it
"should render both"
,
->
expect
(
@
view
.
el
).
toContain
(
".action-secondary.option-one"
)
expect
(
@
view
.
el
).
toContain
(
".action-secondary.option-two"
)
expect
(
@
view
.
el
).
not
.
toContain
(
".action-secondary.option-one.option-two"
)
expect
(
@
view
.
$
(
".action-secondary.option-one"
)).
toContainText
(
"Option One"
)
expect
(
@
view
.
$
(
".action-secondary.option-two"
)).
toContainText
(
"Option Two"
)
it
"should differentiate clicks (1)"
,
->
@
view
.
$
(
".option-one"
).
click
()
expect
(
@
secondarySpyOne
).
toHaveBeenCalled
()
expect
(
@
secondarySpyTwo
).
not
.
toHaveBeenCalled
()
it
"should differentiate clicks (2)"
,
->
@
view
.
$
(
".option-two"
).
click
()
expect
(
@
secondarySpyOne
).
not
.
toHaveBeenCalled
()
expect
(
@
secondarySpyTwo
).
toHaveBeenCalled
()
describe
"NotificationView minShown and maxShown"
,
->
beforeEach
->
@
showSpy
=
spyOn
(
NotificationView
.
Confirmation
.
prototype
,
'show'
)
@
showSpy
.
andCallThrough
()
@
hideSpy
=
spyOn
(
NotificationView
.
Confirmation
.
prototype
,
'hide'
)
@
hideSpy
.
andCallThrough
()
@
clock
=
sinon
.
useFakeTimers
()
afterEach
->
@
clock
.
restore
()
# Disabled flaky test TNL-559
xit
"should not have minShown or maxShown by default"
,
->
view
=
new
NotificationView
.
Confirmation
()
expect
(
view
.
options
.
minShown
).
toEqual
(
0
)
expect
(
view
.
options
.
maxShown
).
toEqual
(
Infinity
)
# Disabled flaky test TNL-559
xit
"a minShown view should not hide too quickly"
,
->
view
=
new
NotificationView
.
Confirmation
({
minShown
:
1000
})
view
.
show
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
# call hide() on it, but the minShown should prevent it from hiding right away
view
.
hide
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
# wait for the minShown timeout to expire, and check again
@
clock
.
tick
(
1001
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
# Disabled flaky test TNL-559
xit
"a maxShown view should hide by itself"
,
->
view
=
new
NotificationView
.
Confirmation
({
maxShown
:
1000
})
view
.
show
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
# wait for the maxShown timeout to expire, and check again
@
clock
.
tick
(
1001
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
# Disabled flaky test TNL-559
xit
"a minShown view can stay visible longer"
,
->
view
=
new
NotificationView
.
Confirmation
({
minShown
:
1000
})
view
.
show
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
# wait for the minShown timeout to expire, and check again
@
clock
.
tick
(
1001
)
expect
(
@
hideSpy
).
not
.
toHaveBeenCalled
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
# can now hide immediately
view
.
hide
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
# Disabled flaky test TNL-559
xit
"a maxShown view can hide early"
,
->
view
=
new
NotificationView
.
Confirmation
({
maxShown
:
1000
})
view
.
show
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
# wait 50 milliseconds, and hide it early
@
clock
.
tick
(
50
)
view
.
hide
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
# wait for timeout to expire, make sure it doesn't do anything weird
@
clock
.
tick
(
1000
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
it
"a view can have both maxShown and minShown"
,
->
view
=
new
NotificationView
.
Confirmation
({
minShown
:
1000
,
maxShown
:
2000
})
view
.
show
()
# can't hide early
@
clock
.
tick
(
50
)
view
.
hide
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
@
clock
.
tick
(
1000
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
# show it again, and let it hide automatically
view
.
show
()
@
clock
.
tick
(
1050
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
@
clock
.
tick
(
1000
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
common/static/common/js/components/utils/view_utils.js
View file @
d8b419c6
/**
* Provides useful utilities for views.
*/
define
([
"jquery"
,
"underscore"
,
"gettext"
,
"js/views/feedback_notification"
,
"js/views/feedback_prompt"
],
;(
function
(
define
)
{
'use strict'
;
define
([
"jquery"
,
"underscore"
,
"gettext"
,
"common/js/components/views/feedback_notification"
,
"common/js/components/views/feedback_prompt"
],
function
(
$
,
_
,
gettext
,
NotificationView
,
PromptView
)
{
var
toggleExpandCollapse
,
showLoadingIndicator
,
hideLoadingIndicator
,
confirmThenRunOperation
,
runOperationShowingMessage
,
disableElementWhileRunning
,
getScrollOffset
,
setScrollOffset
,
...
...
@@ -246,3 +249,4 @@ define(["jquery", "underscore", "gettext", "js/views/feedback_notification", "js
'checkTotalKeyLengthViolations'
:
checkTotalKeyLengthViolations
};
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
common/static/common/js/components/views/feedback.js
View file @
d8b419c6
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"backbone"
,
"js/utils/templates"
],
function
(
$
,
_
,
str
,
Backbone
,
TemplateUtils
)
{
var
SystemFeedback
=
Backbone
.
View
.
extend
({
options
:
{
title
:
""
,
message
:
""
,
intent
:
null
,
// "warning", "confirmation", "error", "announcement", "step-required", etc
type
:
null
,
// "alert", "notification", or "prompt": set by subclass
shown
:
true
,
// is this view currently being shown?
icon
:
true
,
// should we render an icon related to the message intent?
closeIcon
:
true
,
// should we render a close button in the top right corner?
minShown
:
0
,
// length of time after this view has been shown before it can be hidden (milliseconds)
maxShown
:
Infinity
// length of time after this view has been shown before it will be automatically hidden (milliseconds)
;(
function
(
define
)
{
'use strict'
;
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"backbone"
,
"text!common/templates/components/system-feedback.underscore"
],
function
(
$
,
_
,
str
,
Backbone
,
systemFeedbackTemplate
)
{
var
SystemFeedback
=
Backbone
.
View
.
extend
({
options
:
{
title
:
""
,
message
:
""
,
intent
:
null
,
// "warning", "confirmation", "error", "announcement", "step-required", etc
type
:
null
,
// "alert", "notification", or "prompt": set by subclass
shown
:
true
,
// is this view currently being shown?
icon
:
true
,
// should we render an icon related to the message intent?
closeIcon
:
true
,
// should we render a close button in the top right corner?
minShown
:
0
,
// length of time after this view has been shown before it can be hidden (milliseconds)
maxShown
:
Infinity
// length of time after this view has been shown before it will be automatically hidden (milliseconds)
/* Could also have an "actions" hash: here is an example demonstrating
the expected structure. For each action, by default the framework
will call preventDefault on the click event before the function is
run; to make it not do that, just pass `preventDefault: false` in
the action object.
/* Could also have an "actions" hash: here is an example demonstrating
the expected structure. For each action, by default the framework
will call preventDefault on the click event before the function is
run; to make it not do that, just pass `preventDefault: false` in
the action object.
actions: {
primary: {
"text": "Save",
"class": "action-save",
"click": function(view) {
// do something when Save is clicked
}
},
secondary: [
{
"text": "Cancel",
"class": "action-cancel",
"click": function(view) {}
}, {
"text": "Discard Changes",
"class": "action-discard",
"click": function(view) {}
}
]
}
*/
},
initialize
:
function
()
{
if
(
!
this
.
options
.
type
)
{
throw
"SystemFeedback: type required (given "
+
JSON
.
stringify
(
this
.
options
)
+
")"
;
actions: {
primary: {
"text": "Save",
"class": "action-save",
"click": function(view) {
// do something when Save is clicked
}
},
secondary: [
{
"text": "Cancel",
"class": "action-cancel",
"click": function(view) {}
}, {
"text": "Discard Changes",
"class": "action-discard",
"click": function(view) {}
}
]
}
if
(
!
this
.
options
.
intent
)
{
throw
"SystemFeedback: intent required (given "
+
JSON
.
stringify
(
this
.
options
)
+
")"
;
}
this
.
template
=
TemplateUtils
.
loadTemplate
(
"system-feedback"
);
this
.
setElement
(
$
(
"#page-"
+
this
.
options
.
type
));
// handle single "secondary" action
if
(
this
.
options
.
actions
&&
this
.
options
.
actions
.
secondary
&&
!
_
.
isArray
(
this
.
options
.
actions
.
secondary
))
{
this
.
options
.
actions
.
secondary
=
[
this
.
options
.
actions
.
secondary
];
}
return
this
;
},
*/
},
// public API: show() and hide()
show
:
function
()
{
clearTimeout
(
this
.
hideTimeout
);
this
.
options
.
shown
=
true
;
this
.
shownAt
=
new
Date
();
this
.
render
();
if
(
$
.
isNumeric
(
this
.
options
.
maxShown
))
{
this
.
hideTimeout
=
setTimeout
(
_
.
bind
(
this
.
hide
,
this
),
this
.
options
.
maxShown
);
}
return
this
;
},
initialize
:
function
()
{
if
(
!
this
.
options
.
type
)
{
throw
"SystemFeedback: type required (given "
+
JSON
.
stringify
(
this
.
options
)
+
")"
;
}
if
(
!
this
.
options
.
intent
)
{
throw
"SystemFeedback: intent required (given "
+
JSON
.
stringify
(
this
.
options
)
+
")"
;
}
this
.
setElement
(
$
(
"#page-"
+
this
.
options
.
type
));
// handle single "secondary" action
if
(
this
.
options
.
actions
&&
this
.
options
.
actions
.
secondary
&&
!
_
.
isArray
(
this
.
options
.
actions
.
secondary
))
{
this
.
options
.
actions
.
secondary
=
[
this
.
options
.
actions
.
secondary
];
}
return
this
;
},
hide
:
function
()
{
if
(
this
.
shownAt
&&
$
.
isNumeric
(
this
.
options
.
minShown
)
&&
this
.
options
.
minShown
>
new
Date
()
-
this
.
shownAt
)
{
// public API: show() and hide()
show
:
function
()
{
clearTimeout
(
this
.
hideTimeout
);
this
.
hideTimeout
=
setTimeout
(
_
.
bind
(
this
.
hide
,
this
),
this
.
options
.
minShown
-
(
new
Date
()
-
this
.
shownAt
));
}
else
{
this
.
options
.
shown
=
false
;
delete
this
.
shownAt
;
this
.
options
.
shown
=
true
;
this
.
shownAt
=
new
Date
();
this
.
render
();
}
return
this
;
},
if
(
$
.
isNumeric
(
this
.
options
.
maxShown
))
{
this
.
hideTimeout
=
setTimeout
(
_
.
bind
(
this
.
hide
,
this
),
this
.
options
.
maxShown
);
}
return
this
;
},
hide
:
function
()
{
if
(
this
.
shownAt
&&
$
.
isNumeric
(
this
.
options
.
minShown
)
&&
this
.
options
.
minShown
>
new
Date
()
-
this
.
shownAt
)
{
clearTimeout
(
this
.
hideTimeout
);
this
.
hideTimeout
=
setTimeout
(
_
.
bind
(
this
.
hide
,
this
),
this
.
options
.
minShown
-
(
new
Date
()
-
this
.
shownAt
));
}
else
{
this
.
options
.
shown
=
false
;
delete
this
.
shownAt
;
this
.
render
();
}
return
this
;
},
// the rest of the API should be considered semi-private
events
:
{
"click .action-close"
:
"hide"
,
"click .action-primary"
:
"primaryClick"
,
"click .action-secondary"
:
"secondaryClick"
},
// the rest of the API should be considered semi-private
events
:
{
"click .action-close"
:
"hide"
,
"click .action-primary"
:
"primaryClick"
,
"click .action-secondary"
:
"secondaryClick"
},
render
:
function
()
{
// there can be only one active view of a given type at a time: only
// one alert, only one notification, only one prompt. Therefore, we'll
// use a singleton approach.
var
singleton
=
SystemFeedback
[
"active_"
+
this
.
options
.
type
];
if
(
singleton
&&
singleton
!==
this
)
{
singleton
.
stopListening
();
singleton
.
undelegateEvents
();
}
this
.
$el
.
html
(
this
.
template
(
this
.
options
));
SystemFeedback
[
"active_"
+
this
.
options
.
type
]
=
this
;
return
this
;
},
render
:
function
()
{
// there can be only one active view of a given type at a time: only
// one alert, only one notification, only one prompt. Therefore, we'll
// use a singleton approach.
var
singleton
=
SystemFeedback
[
"active_"
+
this
.
options
.
type
];
if
(
singleton
&&
singleton
!==
this
)
{
singleton
.
stopListening
();
singleton
.
undelegateEvents
();
}
this
.
$el
.
html
(
_
.
template
(
systemFeedbackTemplate
)
(
this
.
options
));
SystemFeedback
[
"active_"
+
this
.
options
.
type
]
=
this
;
return
this
;
},
primaryClick
:
function
(
event
)
{
var
actions
,
primary
;
actions
=
this
.
options
.
actions
;
if
(
!
actions
)
{
return
;
}
primary
=
actions
.
primary
;
if
(
!
primary
)
{
return
;
}
if
(
primary
.
preventDefault
!==
false
)
{
event
.
preventDefault
();
}
if
(
primary
.
click
)
{
primary
.
click
.
call
(
event
.
target
,
this
,
event
);
}
},
primaryClick
:
function
(
event
)
{
var
actions
,
primary
;
actions
=
this
.
options
.
actions
;
if
(
!
actions
)
{
return
;
}
primary
=
actions
.
primary
;
if
(
!
primary
)
{
return
;
}
if
(
primary
.
preventDefault
!==
false
)
{
event
.
preventDefault
();
}
if
(
primary
.
click
)
{
primary
.
click
.
call
(
event
.
target
,
this
,
event
);
}
},
secondaryClick
:
function
(
event
)
{
var
actions
,
secondaryList
,
secondary
,
i
;
actions
=
this
.
options
.
actions
;
if
(
!
actions
)
{
return
;
}
secondaryList
=
actions
.
secondary
;
if
(
!
secondaryList
)
{
return
;
}
// which secondary action was clicked?
i
=
0
;
// default to the first secondary action (easier for testing)
if
(
event
&&
event
.
target
)
{
i
=
_
.
indexOf
(
this
.
$
(
".action-secondary"
),
event
.
target
);
}
secondary
=
secondaryList
[
i
];
if
(
secondary
.
preventDefault
!==
false
)
{
event
.
preventDefault
();
}
if
(
secondary
.
click
)
{
secondary
.
click
.
call
(
event
.
target
,
this
,
event
);
secondaryClick
:
function
(
event
)
{
var
actions
,
secondaryList
,
secondary
,
i
;
actions
=
this
.
options
.
actions
;
if
(
!
actions
)
{
return
;
}
secondaryList
=
actions
.
secondary
;
if
(
!
secondaryList
)
{
return
;
}
// which secondary action was clicked?
i
=
0
;
// default to the first secondary action (easier for testing)
if
(
event
&&
event
.
target
)
{
i
=
_
.
indexOf
(
this
.
$
(
".action-secondary"
),
event
.
target
);
}
secondary
=
secondaryList
[
i
];
if
(
secondary
.
preventDefault
!==
false
)
{
event
.
preventDefault
();
}
if
(
secondary
.
click
)
{
secondary
.
click
.
call
(
event
.
target
,
this
,
event
);
}
}
}
});
return
SystemFeedback
;
});
return
SystemFeedback
;
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
common/static/common/js/components/views/feedback_alert.js
View file @
d8b419c6
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"js/views/feedback"
],
function
(
$
,
_
,
str
,
SystemFeedbackView
)
{
var
Alert
=
SystemFeedbackView
.
extend
({
options
:
$
.
extend
({},
SystemFeedbackView
.
prototype
.
options
,
{
type
:
"alert"
}),
slide_speed
:
900
,
show
:
function
()
{
SystemFeedbackView
.
prototype
.
show
.
apply
(
this
,
arguments
);
this
.
$el
.
hide
();
this
.
$el
.
slideDown
(
this
.
slide_speed
);
return
this
;
},
hide
:
function
()
{
this
.
$el
.
slideUp
({
duration
:
this
.
slide_speed
});
setTimeout
(
_
.
bind
(
SystemFeedbackView
.
prototype
.
hide
,
this
,
arguments
),
this
.
slideSpeed
);
}
});
;(
function
(
define
)
{
'use strict'
;
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"common/js/components/views/feedback"
],
function
(
$
,
_
,
str
,
SystemFeedbackView
)
{
str
=
str
||
_
.
str
;
var
Alert
=
SystemFeedbackView
.
extend
({
options
:
$
.
extend
({},
SystemFeedbackView
.
prototype
.
options
,
{
type
:
"alert"
}),
slide_speed
:
900
,
show
:
function
()
{
SystemFeedbackView
.
prototype
.
show
.
apply
(
this
,
arguments
);
this
.
$el
.
hide
();
this
.
$el
.
slideDown
(
this
.
slide_speed
);
return
this
;
},
hide
:
function
()
{
this
.
$el
.
slideUp
({
duration
:
this
.
slide_speed
});
setTimeout
(
_
.
bind
(
SystemFeedbackView
.
prototype
.
hide
,
this
,
arguments
),
this
.
slideSpeed
);
}
});
// create Alert.Warning, Alert.Confirmation, etc
var
capitalCamel
,
intents
;
capitalCamel
=
_
.
compose
(
str
.
capitalize
,
str
.
camelize
);
intents
=
[
"warning"
,
"error"
,
"confirmation"
,
"announcement"
,
"step-required"
,
"help"
,
"mini"
];
_
.
each
(
intents
,
function
(
intent
)
{
var
subclass
;
subclass
=
Alert
.
extend
({
options
:
$
.
extend
({},
Alert
.
prototype
.
options
,
{
intent
:
intent
})
// create Alert.Warning, Alert.Confirmation, etc
var
capitalCamel
,
intents
;
capitalCamel
=
_
.
compose
(
str
.
capitalize
,
str
.
camelize
);
intents
=
[
"warning"
,
"error"
,
"confirmation"
,
"announcement"
,
"step-required"
,
"help"
,
"mini"
];
_
.
each
(
intents
,
function
(
intent
)
{
var
subclass
;
subclass
=
Alert
.
extend
({
options
:
$
.
extend
({},
Alert
.
prototype
.
options
,
{
intent
:
intent
})
});
Alert
[
capitalCamel
(
intent
)]
=
subclass
;
});
Alert
[
capitalCamel
(
intent
)]
=
subclass
;
});
return
Alert
;
});
return
Alert
;
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
common/static/common/js/components/views/feedback_notification.js
View file @
d8b419c6
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"js/views/feedback"
],
function
(
$
,
_
,
str
,
SystemFeedbackView
)
{
var
Notification
=
SystemFeedbackView
.
extend
({
options
:
$
.
extend
({},
SystemFeedbackView
.
prototype
.
options
,
{
type
:
"notification"
,
closeIcon
:
false
})
});
// create Notification.Warning, Notification.Confirmation, etc
var
capitalCamel
,
intents
;
capitalCamel
=
_
.
compose
(
str
.
capitalize
,
str
.
camelize
);
intents
=
[
"warning"
,
"error"
,
"confirmation"
,
"announcement"
,
"step-required"
,
"help"
,
"mini"
];
_
.
each
(
intents
,
function
(
intent
)
{
var
subclass
;
subclass
=
Notification
.
extend
({
options
:
$
.
extend
({},
Notification
.
prototype
.
options
,
{
intent
:
intent
;(
function
(
define
)
{
'use strict'
;
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"common/js/components/views/feedback"
],
function
(
$
,
_
,
str
,
SystemFeedbackView
)
{
str
=
str
||
_
.
str
;
var
Notification
=
SystemFeedbackView
.
extend
({
options
:
$
.
extend
({},
SystemFeedbackView
.
prototype
.
options
,
{
type
:
"notification"
,
closeIcon
:
false
})
});
Notification
[
capitalCamel
(
intent
)]
=
subclass
;
});
// set more sensible defaults for Notification.Mini views
var
miniOptions
=
Notification
.
Mini
.
prototype
.
options
;
miniOptions
.
minShown
=
1250
;
miniOptions
.
closeIcon
=
false
;
// create Notification.Warning, Notification.Confirmation, etc
var
capitalCamel
,
intents
;
capitalCamel
=
_
.
compose
(
str
.
capitalize
,
str
.
camelize
);
intents
=
[
"warning"
,
"error"
,
"confirmation"
,
"announcement"
,
"step-required"
,
"help"
,
"mini"
];
_
.
each
(
intents
,
function
(
intent
)
{
var
subclass
;
subclass
=
Notification
.
extend
({
options
:
$
.
extend
({},
Notification
.
prototype
.
options
,
{
intent
:
intent
})
});
Notification
[
capitalCamel
(
intent
)]
=
subclass
;
});
// set more sensible defaults for Notification.Mini views
var
miniOptions
=
Notification
.
Mini
.
prototype
.
options
;
miniOptions
.
minShown
=
1250
;
miniOptions
.
closeIcon
=
false
;
return
Notification
;
});
return
Notification
;
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
common/static/common/js/components/views/feedback_prompt.js
View file @
d8b419c6
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"js/views/feedback"
],
function
(
$
,
_
,
str
,
SystemFeedbackView
)
{
var
Prompt
=
SystemFeedbackView
.
extend
({
options
:
$
.
extend
({},
SystemFeedbackView
.
prototype
.
options
,
{
type
:
"prompt"
,
closeIcon
:
false
,
icon
:
false
}),
render
:
function
()
{
if
(
!
window
.
$body
)
{
window
.
$body
=
$
(
document
.
body
);
}
if
(
this
.
options
.
shown
)
{
$body
.
addClass
(
'prompt-is-shown'
);
}
else
{
$body
.
removeClass
(
'prompt-is-shown'
);
}
// super() in Javascript has awkward syntax :(
return
SystemFeedbackView
.
prototype
.
render
.
apply
(
this
,
arguments
);
}
});
;(
function
(
define
)
{
'use strict'
;
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"common/js/components/views/feedback"
],
function
(
$
,
_
,
str
,
SystemFeedbackView
)
{
str
=
str
||
_
.
str
;
var
Prompt
=
SystemFeedbackView
.
extend
({
options
:
$
.
extend
({},
SystemFeedbackView
.
prototype
.
options
,
{
type
:
"prompt"
,
closeIcon
:
false
,
icon
:
false
}),
render
:
function
()
{
if
(
!
window
.
$body
)
{
window
.
$body
=
$
(
document
.
body
);
}
if
(
this
.
options
.
shown
)
{
$body
.
addClass
(
'prompt-is-shown'
);
}
else
{
$body
.
removeClass
(
'prompt-is-shown'
);
}
// super() in Javascript has awkward syntax :(
return
SystemFeedbackView
.
prototype
.
render
.
apply
(
this
,
arguments
);
}
});
// create Prompt.Warning, Prompt.Confirmation, etc
var
capitalCamel
,
intents
;
capitalCamel
=
_
.
compose
(
str
.
capitalize
,
str
.
camelize
);
intents
=
[
"warning"
,
"error"
,
"confirmation"
,
"announcement"
,
"step-required"
,
"help"
,
"mini"
];
_
.
each
(
intents
,
function
(
intent
)
{
var
subclass
;
subclass
=
Prompt
.
extend
({
options
:
$
.
extend
({},
Prompt
.
prototype
.
options
,
{
intent
:
intent
})
});
Prompt
[
capitalCamel
(
intent
)]
=
subclass
;
});
// create Prompt.Warning, Prompt.Confirmation, etc
var
capitalCamel
,
intents
;
capitalCamel
=
_
.
compose
(
str
.
capitalize
,
str
.
camelize
);
intents
=
[
"warning"
,
"error"
,
"confirmation"
,
"announcement"
,
"step-required"
,
"help"
,
"mini"
];
_
.
each
(
intents
,
function
(
intent
)
{
var
subclass
;
subclass
=
Prompt
.
extend
({
options
:
$
.
extend
({},
Prompt
.
prototype
.
options
,
{
intent
:
intent
})
});
Prompt
[
capitalCamel
(
intent
)]
=
subclass
;
});
return
Prompt
;
});
return
Prompt
;
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
common/static/common/js/spec/components/feedback_spec.js
0 → 100644
View file @
d8b419c6
// Generated by CoffeeScript 1.6.1
(
function
()
{
define
([
"jquery"
,
"common/js/components/views/feedback"
,
"common/js/components/views/feedback_notification"
,
"common/js/components/views/feedback_alert"
,
"common/js/components/views/feedback_prompt"
,
"sinon"
],
function
(
$
,
SystemFeedback
,
NotificationView
,
AlertView
,
PromptView
,
sinon
)
{
var
tpl
;
tpl
=
readFixtures
(
'system-feedback.underscore'
);
beforeEach
(
function
()
{
setFixtures
(
sandbox
({
id
:
"page-alert"
}));
appendSetFixtures
(
sandbox
({
id
:
"page-notification"
}));
appendSetFixtures
(
sandbox
({
id
:
"page-prompt"
}));
appendSetFixtures
(
$
(
"<script>"
,
{
id
:
"system-feedback-tpl"
,
type
:
"text/template"
}).
text
(
tpl
));
return
this
.
addMatchers
({
toBeShown
:
function
()
{
return
this
.
actual
.
hasClass
(
"is-shown"
)
&&
!
this
.
actual
.
hasClass
(
"is-hiding"
);
},
toBeHiding
:
function
()
{
return
this
.
actual
.
hasClass
(
"is-hiding"
)
&&
!
this
.
actual
.
hasClass
(
"is-shown"
);
},
toContainText
:
function
(
text
)
{
var
trimmedText
;
trimmedText
=
$
.
trim
(
this
.
actual
.
text
());
if
(
text
&&
$
.
isFunction
(
text
.
test
))
{
return
text
.
test
(
trimmedText
);
}
else
{
return
trimmedText
.
indexOf
(
text
)
!==
-
1
;
}
},
toHaveBeenPrevented
:
function
()
{
var
eventName
,
selector
;
eventName
=
this
.
actual
.
eventName
;
selector
=
this
.
actual
.
selector
;
this
.
message
=
function
()
{
return
[
"Expected event "
+
eventName
+
" to have been prevented on "
+
selector
,
"Expected event "
+
eventName
+
" not to have been prevented on "
+
selector
];
};
return
jasmine
.
JQuery
.
events
.
wasPrevented
(
selector
,
eventName
);
}
});
});
describe
(
"SystemFeedback"
,
function
()
{
beforeEach
(
function
()
{
this
.
options
=
{
title
:
"Portal"
,
message
:
"Welcome to the Aperture Science Computer-Aided Enrichment Center"
};
this
.
renderSpy
=
spyOn
(
AlertView
.
Confirmation
.
prototype
,
'render'
).
andCallThrough
();
this
.
showSpy
=
spyOn
(
AlertView
.
Confirmation
.
prototype
,
'show'
).
andCallThrough
();
this
.
hideSpy
=
spyOn
(
AlertView
.
Confirmation
.
prototype
,
'hide'
).
andCallThrough
();
return
this
.
clock
=
sinon
.
useFakeTimers
();
});
afterEach
(
function
()
{
return
this
.
clock
.
restore
();
});
it
(
"requires a type and an intent"
,
function
()
{
var
both
,
neither
,
noIntent
,
noType
,
_this
=
this
;
neither
=
function
()
{
return
new
SystemFeedback
(
_this
.
options
);
};
noType
=
function
()
{
var
options
;
options
=
$
.
extend
({},
_this
.
options
);
options
.
intent
=
"confirmation"
;
return
new
SystemFeedback
(
options
);
};
noIntent
=
function
()
{
var
options
;
options
=
$
.
extend
({},
_this
.
options
);
options
.
type
=
"alert"
;
return
new
SystemFeedback
(
options
);
};
both
=
function
()
{
var
options
;
options
=
$
.
extend
({},
_this
.
options
);
options
.
type
=
"alert"
;
options
.
intent
=
"confirmation"
;
return
new
SystemFeedback
(
options
);
};
expect
(
neither
).
toThrow
();
expect
(
noType
).
toThrow
();
expect
(
noIntent
).
toThrow
();
return
expect
(
both
).
not
.
toThrow
();
});
it
(
"does not show on initalize"
,
function
()
{
var
view
;
view
=
new
AlertView
.
Confirmation
(
this
.
options
);
expect
(
this
.
renderSpy
).
not
.
toHaveBeenCalled
();
return
expect
(
this
.
showSpy
).
not
.
toHaveBeenCalled
();
});
xit
(
"renders the template"
,
function
()
{
var
view
;
view
=
new
AlertView
.
Confirmation
(
this
.
options
);
view
.
show
();
expect
(
view
.
$
(
".action-close"
)).
toBeDefined
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
expect
(
view
.
$el
).
toContainText
(
this
.
options
.
title
);
return
expect
(
view
.
$el
).
toContainText
(
this
.
options
.
message
);
});
return
xit
(
"close button sends a .hide() message"
,
function
()
{
var
view
;
view
=
new
AlertView
.
Confirmation
(
this
.
options
).
show
();
view
.
$
(
".action-close"
).
click
();
expect
(
this
.
hideSpy
).
toHaveBeenCalled
();
this
.
clock
.
tick
(
900
);
return
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
});
});
describe
(
"PromptView"
,
function
()
{
return
it
(
"changes class on body"
,
function
()
{
var
view
;
view
=
new
PromptView
.
Confirmation
({
title
:
"Portal"
,
message
:
"Welcome to the Aperture Science Computer-Aided Enrichment Center"
});
return
view
.
hide
();
});
});
describe
(
"NotificationView.Mini"
,
function
()
{
beforeEach
(
function
()
{
return
this
.
view
=
new
NotificationView
.
Mini
();
});
it
(
"should have minShown set to 1250 by default"
,
function
()
{
return
expect
(
this
.
view
.
options
.
minShown
).
toEqual
(
1250
);
});
return
it
(
"should have closeIcon set to false by default"
,
function
()
{
return
expect
(
this
.
view
.
options
.
closeIcon
).
toBeFalsy
();
});
});
xdescribe
(
"SystemFeedback click events"
,
function
()
{
beforeEach
(
function
()
{
this
.
primaryClickSpy
=
jasmine
.
createSpy
(
'primaryClick'
);
this
.
secondaryClickSpy
=
jasmine
.
createSpy
(
'secondaryClick'
);
this
.
view
=
new
NotificationView
.
Warning
({
title
:
"Unsaved"
,
message
:
"Your content is currently Unsaved."
,
actions
:
{
primary
:
{
text
:
"Save"
,
"class"
:
"save-button"
,
click
:
this
.
primaryClickSpy
},
secondary
:
{
text
:
"Revert"
,
"class"
:
"cancel-button"
,
click
:
this
.
secondaryClickSpy
}
}
});
return
this
.
view
.
show
();
});
it
(
"should trigger the primary event on a primary click"
,
function
()
{
this
.
view
.
$
(
".action-primary"
).
click
();
expect
(
this
.
primaryClickSpy
).
toHaveBeenCalled
();
return
expect
(
this
.
secondaryClickSpy
).
not
.
toHaveBeenCalled
();
});
it
(
"should trigger the secondary event on a secondary click"
,
function
()
{
this
.
view
.
$
(
".action-secondary"
).
click
();
expect
(
this
.
secondaryClickSpy
).
toHaveBeenCalled
();
return
expect
(
this
.
primaryClickSpy
).
not
.
toHaveBeenCalled
();
});
it
(
"should apply class to primary action"
,
function
()
{
return
expect
(
this
.
view
.
$
(
".action-primary"
)).
toHaveClass
(
"save-button"
);
});
it
(
"should apply class to secondary action"
,
function
()
{
return
expect
(
this
.
view
.
$
(
".action-secondary"
)).
toHaveClass
(
"cancel-button"
);
});
it
(
"should preventDefault on primary action"
,
function
()
{
spyOnEvent
(
".action-primary"
,
"click"
);
this
.
view
.
$
(
".action-primary"
).
click
();
return
expect
(
"click"
).
toHaveBeenPreventedOn
(
".action-primary"
);
});
return
it
(
"should preventDefault on secondary action"
,
function
()
{
spyOnEvent
(
".action-secondary"
,
"click"
);
this
.
view
.
$
(
".action-secondary"
).
click
();
return
expect
(
"click"
).
toHaveBeenPreventedOn
(
".action-secondary"
);
});
});
xdescribe
(
"SystemFeedback not preventing events"
,
function
()
{
beforeEach
(
function
()
{
this
.
clickSpy
=
jasmine
.
createSpy
(
'clickSpy'
);
this
.
view
=
new
AlertView
.
Confirmation
({
title
:
"It's all good"
,
message
:
"No reason for this alert"
,
actions
:
{
primary
:
{
text
:
"Whatever"
,
click
:
this
.
clickSpy
,
preventDefault
:
false
}
}
});
return
this
.
view
.
show
();
});
return
it
(
"should not preventDefault"
,
function
()
{
spyOnEvent
(
".action-primary"
,
"click"
);
this
.
view
.
$
(
".action-primary"
).
click
();
expect
(
"click"
).
not
.
toHaveBeenPreventedOn
(
".action-primary"
);
return
expect
(
this
.
clickSpy
).
toHaveBeenCalled
();
});
});
xdescribe
(
"SystemFeedback multiple secondary actions"
,
function
()
{
beforeEach
(
function
()
{
this
.
secondarySpyOne
=
jasmine
.
createSpy
(
'secondarySpyOne'
);
this
.
secondarySpyTwo
=
jasmine
.
createSpy
(
'secondarySpyTwo'
);
this
.
view
=
new
NotificationView
.
Warning
({
title
:
"No Primary"
,
message
:
"Pick a secondary action"
,
actions
:
{
secondary
:
[
{
text
:
"Option One"
,
"class"
:
"option-one"
,
click
:
this
.
secondarySpyOne
},
{
text
:
"Option Two"
,
"class"
:
"option-two"
,
click
:
this
.
secondarySpyTwo
}
]
}
});
return
this
.
view
.
show
();
});
it
(
"should render both"
,
function
()
{
expect
(
this
.
view
.
el
).
toContain
(
".action-secondary.option-one"
);
expect
(
this
.
view
.
el
).
toContain
(
".action-secondary.option-two"
);
expect
(
this
.
view
.
el
).
not
.
toContain
(
".action-secondary.option-one.option-two"
);
expect
(
this
.
view
.
$
(
".action-secondary.option-one"
)).
toContainText
(
"Option One"
);
return
expect
(
this
.
view
.
$
(
".action-secondary.option-two"
)).
toContainText
(
"Option Two"
);
});
it
(
"should differentiate clicks (1)"
,
function
()
{
this
.
view
.
$
(
".option-one"
).
click
();
expect
(
this
.
secondarySpyOne
).
toHaveBeenCalled
();
return
expect
(
this
.
secondarySpyTwo
).
not
.
toHaveBeenCalled
();
});
return
it
(
"should differentiate clicks (2)"
,
function
()
{
this
.
view
.
$
(
".option-two"
).
click
();
expect
(
this
.
secondarySpyOne
).
not
.
toHaveBeenCalled
();
return
expect
(
this
.
secondarySpyTwo
).
toHaveBeenCalled
();
});
});
return
describe
(
"NotificationView minShown and maxShown"
,
function
()
{
beforeEach
(
function
()
{
this
.
showSpy
=
spyOn
(
NotificationView
.
Confirmation
.
prototype
,
'show'
);
this
.
showSpy
.
andCallThrough
();
this
.
hideSpy
=
spyOn
(
NotificationView
.
Confirmation
.
prototype
,
'hide'
);
this
.
hideSpy
.
andCallThrough
();
return
this
.
clock
=
sinon
.
useFakeTimers
();
});
afterEach
(
function
()
{
return
this
.
clock
.
restore
();
});
xit
(
"should not have minShown or maxShown by default"
,
function
()
{
var
view
;
view
=
new
NotificationView
.
Confirmation
();
expect
(
view
.
options
.
minShown
).
toEqual
(
0
);
return
expect
(
view
.
options
.
maxShown
).
toEqual
(
Infinity
);
});
xit
(
"a minShown view should not hide too quickly"
,
function
()
{
var
view
;
view
=
new
NotificationView
.
Confirmation
({
minShown
:
1000
});
view
.
show
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
view
.
hide
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
this
.
clock
.
tick
(
1001
);
return
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
});
xit
(
"a maxShown view should hide by itself"
,
function
()
{
var
view
;
view
=
new
NotificationView
.
Confirmation
({
maxShown
:
1000
});
view
.
show
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
this
.
clock
.
tick
(
1001
);
return
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
});
xit
(
"a minShown view can stay visible longer"
,
function
()
{
var
view
;
view
=
new
NotificationView
.
Confirmation
({
minShown
:
1000
});
view
.
show
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
this
.
clock
.
tick
(
1001
);
expect
(
this
.
hideSpy
).
not
.
toHaveBeenCalled
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
view
.
hide
();
return
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
});
xit
(
"a maxShown view can hide early"
,
function
()
{
var
view
;
view
=
new
NotificationView
.
Confirmation
({
maxShown
:
1000
});
view
.
show
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
this
.
clock
.
tick
(
50
);
view
.
hide
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
this
.
clock
.
tick
(
1000
);
return
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
});
return
it
(
"a view can have both maxShown and minShown"
,
function
()
{
var
view
;
view
=
new
NotificationView
.
Confirmation
({
minShown
:
1000
,
maxShown
:
2000
});
view
.
show
();
this
.
clock
.
tick
(
50
);
view
.
hide
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
this
.
clock
.
tick
(
1000
);
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
view
.
show
();
this
.
clock
.
tick
(
1050
);
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
this
.
clock
.
tick
(
1000
);
return
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
});
});
});
}).
call
(
this
);
common/static/common/js/spec/components/view_utils_spec.js
View file @
d8b419c6
define
([
"jquery"
,
"underscore"
,
"js/views/baseview"
,
"js/views/utils/view_utils"
,
"js/spec_helpers/edit_helpers"
],
function
(
$
,
_
,
BaseView
,
ViewUtils
,
ViewHelpers
)
{
;(
function
(
define
)
{
'use strict'
;
define
([
"jquery"
,
"underscore"
,
"common/js/components/utils/view_utils"
,
"common/js/spec_helpers/view_helpers"
,
'jasmine-stealth'
],
function
(
$
,
_
,
ViewUtils
,
ViewHelpers
)
{
describe
(
"ViewUtils"
,
function
()
{
describe
(
"disabled element while running"
,
function
()
{
...
...
@@ -90,3 +92,4 @@ define(["jquery", "underscore", "js/views/baseview", "js/views/utils/view_utils"
});
});
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
\ No newline at end of file
common/static/common/js/spec_helpers/view_helpers.js
View file @
d8b419c6
/**
* Provides helper methods for invoking Studio modal windows in Jasmine tests.
*/
define
([
"jquery"
,
"js/views/feedback_notification"
,
"js/views/feedback_prompt"
,
'common/js/spec_helpers/ajax_helpers'
,
"common/js/spec_helpers/template_helpers"
],
function
(
$
,
NotificationView
,
Prompt
,
AjaxHelpers
,
TemplateHelpers
)
{
;(
function
(
define
)
{
'use strict'
;
define
([
"jquery"
,
"common/js/components/views/feedback_notification"
,
"common/js/components/views/feedback_prompt"
,
'common/js/spec_helpers/ajax_helpers'
],
function
(
$
,
NotificationView
,
Prompt
,
AjaxHelpers
)
{
var
installViewTemplates
,
createFeedbackSpy
,
verifyFeedbackShowing
,
verifyFeedbackHidden
,
createNotificationSpy
,
verifyNotificationShowing
,
verifyNotificationHidden
,
createPromptSpy
,
confirmPrompt
,
inlineEdit
,
verifyInlineEditChange
,
installMockAnalytics
,
removeMockAnalytics
,
verifyPromptShowing
,
verifyPromptHidden
;
installMockAnalytics
,
removeMockAnalytics
,
verifyPromptShowing
,
verifyPromptHidden
,
clickDeleteItem
,
patchAndVerifyRequest
,
submitAndVerifyFormSuccess
,
submitAndVerifyFormError
;
installViewTemplates
=
function
(
append
)
{
TemplateHelpers
.
installTemplate
(
'system-feedback'
,
!
append
);
installViewTemplates
=
function
()
{
appendSetFixtures
(
'<div id="page-notification"></div>'
);
};
...
...
@@ -144,3 +146,4 @@ define(["jquery", "js/views/feedback_notification", "js/views/feedback_prompt",
'submitAndVerifyFormError'
:
submitAndVerifyFormError
};
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
common/static/common/templates/components/system-feedback.underscore
View file @
d8b419c6
...
...
@@ -21,17 +21,16 @@
<% if(obj.actions) { %>
<nav class="nav-actions">
<h3 class="sr"><%= type %> Actions</h3>
<ul>
<% if(actions.primary) { %>
<li class="nav-item">
<
a href="#" class="button action-primary <%= actions.primary.class %>"><%= actions.primary.text %></a
>
<
button class="action-primary <%= actions.primary.class %>"><%= actions.primary.text %></button
>
</li>
<% } %>
<% if(actions.secondary) {
_.each(actions.secondary, function(secondary) { %>
<li class="nav-item">
<
a href="#" class="button action-secondary <%= secondary.class %>"><%= secondary.text %></a
>
<
button class="action-secondary <%= secondary.class %>"><%= secondary.text %></button
>
</li>
<% });
} %>
...
...
lms/djangoapps/teams/static/teams/js/spec/views/team_profile_spec.js
View file @
d8b419c6
...
...
@@ -74,13 +74,13 @@ define([
return
profileView
;
};
clickLeaveTeam
=
function
(
requests
,
view
,
confirmLeave
)
{
clickLeaveTeam
=
function
(
requests
,
view
,
options
)
{
expect
(
view
.
$
(
leaveTeamLinkSelector
).
length
).
toBe
(
1
);
// click on Leave Team link under Team Details
view
.
$
(
leaveTeamLinkSelector
).
click
();
if
(
confirmLeave
)
{
if
(
!
options
.
cancel
)
{
// click on Confirm button on dialog
$
(
'.prompt.warning .action-primary'
).
click
();
...
...
@@ -121,7 +121,7 @@ define([
view
=
createTeamProfileView
(
requests
,
{
membership
:
DEFAULT_MEMBERSHIP
});
expect
(
view
.
$
(
'.new-post-btn'
).
length
).
toEqual
(
1
);
clickLeaveTeam
(
requests
,
view
,
true
);
clickLeaveTeam
(
requests
,
view
,
{
cancel
:
false
}
);
expect
(
view
.
$
(
'.new-post-btn'
).
length
).
toEqual
(
0
);
});
});
...
...
@@ -188,7 +188,7 @@ define([
requests
,
{
country
:
'US'
,
language
:
'en'
,
membership
:
DEFAULT_MEMBERSHIP
}
);
assertTeamDetails
(
view
,
1
,
true
);
clickLeaveTeam
(
requests
,
view
,
true
);
clickLeaveTeam
(
requests
,
view
,
{
cancel
:
false
}
);
assertTeamDetails
(
view
,
0
,
false
);
});
...
...
@@ -199,7 +199,7 @@ define([
requests
,
{
country
:
'US'
,
language
:
'en'
,
membership
:
DEFAULT_MEMBERSHIP
}
);
assertTeamDetails
(
view
,
1
,
true
);
clickLeaveTeam
(
requests
,
view
,
false
);
clickLeaveTeam
(
requests
,
view
,
{
cancel
:
true
}
);
assertTeamDetails
(
view
,
1
,
true
);
});
...
...
lms/static/sass/_build-lms.scss
View file @
d8b419c6
...
...
@@ -81,4 +81,4 @@
// overrides
@import
'developer'
;
// used for any developer-created scss that needs further polish/refactoring
@import
'shame'
;
//
used
for
any
bad-form
/
orphaned
scss
\ No newline at end of file
@import
'shame'
;
// used for any bad-form/orphaned scss
lms/static/sass/_mixins-inherited.scss
0 → 120000
View file @
d8b419c6
..
/
..
/
..
/
common
/
static
/
sass
/
_mixins-inherited
.scss
\ No newline at end of file
lms/static/sass/_mixins.scss
0 → 120000
View file @
d8b419c6
..
/
..
/
..
/
common
/
static
/
sass
/
_mixins
.scss
\ No newline at end of file
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