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
5a44f391
Commit
5a44f391
authored
Jul 09, 2015
by
Nimisha Asthagiri
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MA-977 Use "supports" decorator on XBlocks for multi-device support
parent
56da2852
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
69 additions
and
36 deletions
+69
-36
common/lib/capa/capa/capa_problem.py
+5
-3
common/lib/capa/capa/responsetypes.py
+7
-7
common/lib/xmodule/xmodule/capa_module.py
+11
-7
common/lib/xmodule/xmodule/html_module.py
+3
-2
lms/djangoapps/course_structure_api/v0/tests.py
+27
-4
lms/djangoapps/course_structure_api/v0/views.py
+15
-12
requirements/edx/github.txt
+1
-1
No files found.
common/lib/capa/capa/capa_problem.py
View file @
5a44f391
...
...
@@ -575,11 +575,13 @@ class LoncapaProblem(object):
return
{}
@property
def
has_
responsive_ui
(
self
):
def
has_
multi_device_support
(
self
):
"""
Returns whether this capa problem has
support for responsive UI
.
Returns whether this capa problem has
multi-device support
.
"""
return
all
(
responder
.
has_responsive_ui
for
responder
in
self
.
responders
.
values
())
return
all
(
responder
.
multi_device_support
for
responder
in
self
.
responders
.
values
()
)
# ======= Private Methods Below ========
...
...
common/lib/capa/capa/responsetypes.py
View file @
5a44f391
...
...
@@ -145,9 +145,9 @@ class LoncapaResponse(object):
required_attributes
=
[]
# Overridable field that specifies whether this capa response type has support for
#
responsive UI,
for rendering on devices of different sizes and shapes.
# for rendering on devices of different sizes and shapes.
# By default, we set this to False, allowing subclasses to override as appropriate.
has_responsive_ui
=
False
multi_device_support
=
False
def
__init__
(
self
,
xml
,
inputfields
,
context
,
system
,
capa_module
):
"""
...
...
@@ -808,7 +808,7 @@ class ChoiceResponse(LoncapaResponse):
max_inputfields
=
1
allowed_inputfields
=
[
'checkboxgroup'
,
'radiogroup'
]
correct_choices
=
None
has_responsive_ui
=
True
multi_device_support
=
True
def
setup_response
(
self
):
self
.
assign_choice_names
()
...
...
@@ -993,7 +993,7 @@ class MultipleChoiceResponse(LoncapaResponse):
max_inputfields
=
1
allowed_inputfields
=
[
'choicegroup'
]
correct_choices
=
None
has_responsive_ui
=
True
multi_device_support
=
True
def
setup_response
(
self
):
# call secondary setup for MultipleChoice questions, to set name
...
...
@@ -1346,7 +1346,7 @@ class OptionResponse(LoncapaResponse):
hint_tag
=
'optionhint'
allowed_inputfields
=
[
'optioninput'
]
answer_fields
=
None
has_responsive_ui
=
True
multi_device_support
=
True
def
setup_response
(
self
):
self
.
answer_fields
=
self
.
inputfields
...
...
@@ -1421,7 +1421,7 @@ class NumericalResponse(LoncapaResponse):
allowed_inputfields
=
[
'textline'
,
'formulaequationinput'
]
required_attributes
=
[
'answer'
]
max_inputfields
=
1
has_responsive_ui
=
True
multi_device_support
=
True
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
correct_answer
=
''
...
...
@@ -1645,7 +1645,7 @@ class StringResponse(LoncapaResponse):
required_attributes
=
[
'answer'
]
max_inputfields
=
1
correct_answer
=
[]
has_responsive_ui
=
True
multi_device_support
=
True
def
setup_response_backward
(
self
):
self
.
correct_answer
=
[
...
...
common/lib/xmodule/xmodule/capa_module.py
View file @
5a44f391
...
...
@@ -189,13 +189,6 @@ class CapaDescriptor(CapaFields, RawDescriptor):
registered_tags
=
responsetypes
.
registry
.
registered_tags
()
return
set
([
node
.
tag
for
node
in
tree
.
iter
()
if
node
.
tag
in
registered_tags
])
@property
def
has_responsive_ui
(
self
):
"""
Returns whether this module has support for responsive UI.
"""
return
self
.
lcp
.
has_responsive_ui
def
index_dictionary
(
self
):
"""
Return dictionary prepared with module content and type for indexing.
...
...
@@ -211,6 +204,17 @@ class CapaDescriptor(CapaFields, RawDescriptor):
result
.
update
(
index
)
return
result
def
has_support
(
self
,
view
,
functionality
):
"""
Override the XBlock.has_support method to return appropriate
value for the multi-device functionality.
Returns whether the given view has support for the given functionality.
"""
if
functionality
==
"multi_device"
:
return
self
.
lcp
.
has_multi_device_support
else
:
return
False
# Proxy to CapaModule for access to any of its attributes
answer_available
=
module_attr
(
'answer_available'
)
check_button_name
=
module_attr
(
'check_button_name'
)
...
...
common/lib/xmodule/xmodule/html_module.py
View file @
5a44f391
...
...
@@ -84,7 +84,9 @@ class HtmlModule(HtmlModuleMixin):
"""
Module for putting raw html in a course
"""
pass
@XBlock.supports
(
"multi_device"
)
def
student_view
(
self
,
context
):
return
super
(
HtmlModule
,
self
)
.
student_view
(
context
)
class
HtmlDescriptor
(
HtmlFields
,
XmlDescriptor
,
EditingDescriptor
):
# pylint: disable=abstract-method
...
...
@@ -95,7 +97,6 @@ class HtmlDescriptor(HtmlFields, XmlDescriptor, EditingDescriptor): # pylint: d
module_class
=
HtmlModule
filename_extension
=
"xml"
template_dir_name
=
"html"
has_responsive_ui
=
True
show_in_read_only_mode
=
True
js
=
{
'coffee'
:
[
resource_string
(
__name__
,
'js/src/html/edit.coffee'
)]}
...
...
lms/djangoapps/course_structure_api/v0/tests.py
View file @
5a44f391
...
...
@@ -80,7 +80,7 @@ class CourseViewTestsMixin(object):
factory
=
MultipleChoiceResponseXMLFactory
()
args
=
{
'choices'
:
[
False
,
True
,
False
]}
problem_xml
=
factory
.
build_xml
(
**
args
)
ItemFactory
.
create
(
self
.
problem
=
ItemFactory
.
create
(
category
=
"problem"
,
parent_location
=
self
.
sequential
.
location
,
display_name
=
"Problem 1"
,
...
...
@@ -94,6 +94,12 @@ class CourseViewTestsMixin(object):
display_name
=
"Video 1"
,
)
self
.
html
=
ItemFactory
.
create
(
category
=
"html"
,
parent_location
=
self
.
sequential
.
location
,
display_name
=
"HTML 1"
,
)
self
.
empty_course
=
CourseFactory
.
create
(
start
=
datetime
(
2014
,
6
,
16
,
14
,
30
),
end
=
datetime
(
2015
,
1
,
16
),
...
...
@@ -457,7 +463,7 @@ class CourseBlocksOrNavigationTestMixin(CourseDetailTestMixin, CourseViewTestsMi
blocks
=
response
.
data
[
self
.
block_navigation_view_type
]
# verify number of blocks
self
.
assertEquals
(
len
(
blocks
),
4
)
self
.
assertEquals
(
len
(
blocks
),
5
)
# verify fields in blocks
for
field
,
block
in
product
(
self
.
block_fields
,
blocks
.
values
()):
...
...
@@ -519,6 +525,23 @@ class CourseBlocksTestMixin(object):
self
.
assertIn
(
'problem'
,
root_block
[
'block_count'
])
self
.
assertEquals
(
root_block
[
'block_count'
][
'problem'
],
1
)
def
test_multi_device_support
(
self
):
"""
Verifies the view's response when multi_device support is requested.
"""
response
=
self
.
http_get_for_course
(
data
=
{
'fields'
:
'multi_device'
}
)
self
.
assertEquals
(
response
.
status_code
,
200
)
for
block
,
expected_multi_device_support
in
(
(
self
.
problem
,
True
),
(
self
.
html
,
True
),
(
self
.
video
,
False
)
):
block_response
=
response
.
data
[
self
.
block_navigation_view_type
][
unicode
(
block
.
location
)]
self
.
assertEquals
(
block_response
[
'multi_device'
],
expected_multi_device_support
)
class
CourseNavigationTestMixin
(
object
):
"""
...
...
@@ -535,7 +558,7 @@ class CourseNavigationTestMixin(object):
)
root_block
=
response
.
data
[
self
.
block_navigation_view_type
][
unicode
(
self
.
course
.
location
)]
self
.
assertIn
(
'descendants'
,
root_block
)
self
.
assertEquals
(
len
(
root_block
[
'descendants'
]),
3
)
self
.
assertEquals
(
len
(
root_block
[
'descendants'
]),
4
)
def
test_depth
(
self
):
"""
...
...
@@ -545,7 +568,7 @@ class CourseNavigationTestMixin(object):
container_descendants
=
(
(
self
.
course
.
location
,
1
),
(
self
.
sequential
.
location
,
2
),
(
self
.
sequential
.
location
,
3
),
)
for
container_location
,
expected_num_descendants
in
container_descendants
:
block
=
response
.
data
[
self
.
block_navigation_view_type
][
unicode
(
container_location
)]
...
...
lms/djangoapps/course_structure_api/v0/views.py
View file @
5a44f391
...
...
@@ -321,7 +321,7 @@ class CourseBlocksAndNavigation(ListAPIView):
GET api/course_structure/v0/courses/{course_id}/blocks+navigation/
&block_count=video
&block_json={"video":{"profiles":["mobile_low"]}}
&fields=graded,format,
responsive_ui
&fields=graded,format,
multi_device
**Parameters**:
...
...
@@ -335,9 +335,9 @@ class CourseBlocksAndNavigation(ListAPIView):
Example: block_count="video,problem"
* fields: (list) Indicates which additional fields to return for each block.
Default is "children,graded,format,
responsive_ui
"
Default is "children,graded,format,
multi_device
"
Example: fields=graded,format,
responsive_ui
Example: fields=graded,format,
multi_device
* navigation_depth (integer) Indicates how far deep to traverse into the course hierarchy before bundling
all the descendants.
...
...
@@ -387,8 +387,9 @@ class CourseBlocksAndNavigation(ListAPIView):
Possible values can be "Homework", "Lab", "Midterm Exam", and "Final Exam".
Returned only if "format" is included in the "fields" parameter.
* responsive_ui: (boolean) Whether or not the block's rendering obtained via block_url is responsive.
Returned only if "responsive_ui" is included in the "fields" parameter.
* multi_device: (boolean) Whether or not the block's rendering obtained via block_url has support
for multiple devices.
Returned only if "multi_device" is included in the "fields" parameter.
* navigation: A dictionary that maps block IDs to a collection of navigation information about each block.
Each block contains the following fields. Returned only if using the "navigation" endpoint.
...
...
@@ -405,7 +406,7 @@ class CourseBlocksAndNavigation(ListAPIView):
"""
A class for encapsulating the request information, including what optional fields are requested.
"""
DEFAULT_FIELDS
=
"children,graded,format,
responsive_ui
"
DEFAULT_FIELDS
=
"children,graded,format,
multi_device
"
def
__init__
(
self
,
request
,
course
):
self
.
request
=
request
...
...
@@ -417,10 +418,6 @@ class CourseBlocksAndNavigation(ListAPIView):
# fields
self
.
fields
=
set
(
request
.
GET
.
get
(
'fields'
,
self
.
DEFAULT_FIELDS
)
.
split
(
","
))
# children
self
.
children
=
'children'
in
self
.
fields
self
.
fields
.
discard
(
'children'
)
# block_count
self
.
block_count
=
request
.
GET
.
get
(
'block_count'
,
""
)
self
.
block_count
=
(
...
...
@@ -489,7 +486,7 @@ class CourseBlocksAndNavigation(ListAPIView):
self
.
descendants_of_parent
=
parent_block_info
.
descendants_of_self
# add ourselves to the parent's children, if requested.
if
request_info
.
children
:
if
'children'
in
request_info
.
fields
:
parent_block_info
.
value
.
setdefault
(
"children"
,
[])
.
append
(
unicode
(
block
.
location
))
# the block's data to include in the response
...
...
@@ -592,6 +589,13 @@ class CourseBlocksAndNavigation(ListAPIView):
# block JSON data
self
.
add_block_json
(
request_info
,
block_info
)
# multi-device support
if
'multi_device'
in
request_info
.
fields
:
block_info
.
value
[
'multi_device'
]
=
block_info
.
block
.
has_support
(
getattr
(
block_info
.
block
,
'student_view'
,
None
),
'multi_device'
)
# additional fields
self
.
add_additional_fields
(
request_info
,
block_info
)
...
...
@@ -667,7 +671,6 @@ class CourseBlocksAndNavigation(ListAPIView):
FIELD_MAP
=
{
'graded'
:
BlockApiField
(
block_field_name
=
'graded'
,
api_field_default
=
False
),
'format'
:
BlockApiField
(
block_field_name
=
'format'
,
api_field_default
=
None
),
'responsive_ui'
:
BlockApiField
(
block_field_name
=
'has_responsive_ui'
,
api_field_default
=
False
),
}
def
add_additional_fields
(
self
,
request_info
,
block_info
):
...
...
requirements/edx/github.txt
View file @
5a44f391
...
...
@@ -34,7 +34,7 @@ git+https://github.com/hmarr/django-debug-toolbar-mongo.git@b0686a76f1ce3532088c
git+https://github.com/edx/rfc6266.git@v0.0.5-edx#egg=rfc6266==0.0.5-edx
# Our libraries:
-e git+https://github.com/edx/XBlock.git@
017b46b80e712b1318379912257cf1cc1b68eb0e
#egg=XBlock
-e git+https://github.com/edx/XBlock.git@
d1ff8cf31a9b94916ce06ba06d4176bd72e15768
#egg=XBlock
-e git+https://github.com/edx/codejail.git@6b17c33a89bef0ac510926b1d7fea2748b73aadd#egg=codejail
-e git+https://github.com/edx/js-test-tool.git@v0.1.6#egg=js_test_tool
-e git+https://github.com/edx/event-tracking.git@0.2.0#egg=event-tracking
...
...
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