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
8429897c
Commit
8429897c
authored
Jun 02, 2014
by
lduarte1991
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Text Annotation Tool: Added Instructor Filter and Clear Search
parent
2eae8b83
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
116 additions
and
23 deletions
+116
-23
common/lib/xmodule/xmodule/textannotation_module.py
+21
-0
common/static/js/vendor/ova/catch/css/main.css
+15
-5
common/static/js/vendor/ova/catch/js/catch.js
+68
-16
lms/templates/textannotation.html
+12
-2
No files found.
common/lib/xmodule/xmodule/textannotation_module.py
View file @
8429897c
...
@@ -65,6 +65,24 @@ class AnnotatableFields(object):
...
@@ -65,6 +65,24 @@ class AnnotatableFields(object):
scope
=
Scope
.
settings
,
scope
=
Scope
.
settings
,
default
=
''
,
default
=
''
,
)
)
default_tab
=
String
(
display_name
=
_
(
"Default Annotations Tab"
),
help
=
_
(
"Select which tab will be the default in the annotations table: myNotes, Instructor, or Public."
),
scope
=
Scope
.
settings
,
default
=
"myNotes"
,
)
instructor_username
=
String
(
display_name
=
_
(
"Username for 'Instructor' Annotations"
),
help
=
_
(
"Username that will be attached to all annotations that will be found in 'Instructor' tab."
),
scope
=
Scope
.
settings
,
default
=
""
,
)
annotation_mode
=
String
(
display_name
=
_
(
"Mode for Annotation Tool"
),
help
=
_
(
"Type in number corresponding to following modes: 1 = only instructor can annotate , 2 = Everyone can annotate"
),
scope
=
Scope
.
settings
,
default
=
"2"
,
)
class
TextAnnotationModule
(
AnnotatableFields
,
XModule
):
class
TextAnnotationModule
(
AnnotatableFields
,
XModule
):
...
@@ -101,6 +119,9 @@ class TextAnnotationModule(AnnotatableFields, XModule):
...
@@ -101,6 +119,9 @@ class TextAnnotationModule(AnnotatableFields, XModule):
'annotation_storage'
:
self
.
annotation_storage_url
,
'annotation_storage'
:
self
.
annotation_storage_url
,
'token'
:
retrieve_token
(
self
.
user_email
,
self
.
annotation_token_secret
),
'token'
:
retrieve_token
(
self
.
user_email
,
self
.
annotation_token_secret
),
'diacritic_marks'
:
self
.
diacritics
,
'diacritic_marks'
:
self
.
diacritics
,
'default_tab'
:
self
.
default_tab
,
'instructor_username'
:
self
.
instructor_username
,
'annotation_mode'
:
self
.
annotation_mode
,
}
}
fragment
=
Fragment
(
self
.
system
.
render_template
(
'textannotation.html'
,
context
))
fragment
=
Fragment
(
self
.
system
.
render_template
(
'textannotation.html'
,
context
))
fragment
.
add_javascript_url
(
"/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js"
)
fragment
.
add_javascript_url
(
"/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js"
)
...
...
common/static/js/vendor/ova/catch/css/main.css
View file @
8429897c
...
@@ -379,14 +379,14 @@
...
@@ -379,14 +379,14 @@
display
:
inline-block
;
display
:
inline-block
;
color
:
#302f2f
;
color
:
#302f2f
;
font-family
:
arial
;
font-family
:
arial
;
font-size
:
1
5
px
;
font-size
:
1
4
px
;
font-weight
:
bold
;
font-weight
:
bold
;
padding
:
6px
24px
;
padding
:
6px
24px
;
text-decoration
:
none
;
text-decoration
:
none
;
margin
:
0px
0px
10px
0px
;
margin
:
0px
0px
10px
0px
;
cursor
:
pointer
;
cursor
:
pointer
;
width
:
1
40
px
;
width
:
1
15
px
;
text-align
:
center
;
text-align
:
center
;
}
}
...
@@ -468,7 +468,7 @@
...
@@ -468,7 +468,7 @@
#mainCatch
.searchbox
input
{
#mainCatch
.searchbox
input
{
margin
:
0
;
margin
:
0
;
padding
:
0
;
padding
:
0
;
width
:
6
0%
;
width
:
5
0%
;
margin-left
:
10px
;
margin-left
:
10px
;
display
:
inline
;
display
:
inline
;
float
:
left
;
float
:
left
;
...
@@ -493,19 +493,28 @@
...
@@ -493,19 +493,28 @@
cursor
:
pointer
;
cursor
:
pointer
;
}
}
#mainCatch
.searchbox
.clear-search-icon
{
font-size
:
12px
;
text-decoration
:
underline
;
float
:
right
;
margin-top
:
10px
;
padding-right
:
3px
;
cursor
:
pointer
;
}
#mainCatch
.searchbox
.search-icon
:hover
{
#mainCatch
.searchbox
.search-icon
:hover
{
opacity
:
0.5
;
opacity
:
0.5
;
box-shadow
:
2px
4px
5px
#888888
;
box-shadow
:
2px
4px
5px
#888888
;
}
}
#mainCatch
.selectors
{
#mainCatch
.selectors
{
width
:
4
0
%
;
width
:
4
5
%
;
position
:
relative
;
position
:
relative
;
float
:
left
;
float
:
left
;
}
}
#mainCatch
.searchbox
{
#mainCatch
.searchbox
{
width
:
60
%
;
width
:
52
%
;
position
:
relative
;
position
:
relative
;
float
:
right
;
float
:
right
;
}
}
...
@@ -515,6 +524,7 @@
...
@@ -515,6 +524,7 @@
position
:
relative
;
position
:
relative
;
padding-right
:
5px
;
padding-right
:
5px
;
margin-top
:
8px
;
margin-top
:
8px
;
font-size
:
14px
;
}
}
#mainCatch
.replies
.replyItem
.deleteReply
{
#mainCatch
.replies
.replyItem
.deleteReply
{
...
...
common/static/js/vendor/ova/catch/js/catch.js
View file @
8429897c
...
@@ -76,6 +76,17 @@ annotationList:
...
@@ -76,6 +76,17 @@ annotationList:
'<div class="moreButtonCatch">More</div>'
+
'<div class="moreButtonCatch">More</div>'
+
'</div>'
,
'</div>'
,
//Main->PublicPrivateInstructor
annotationPublicPrivateInstructor
:
'<div class="selectors"><div class="PublicPrivate myNotes active">My Notes<span class="action">myNotes</span></div>'
+
'<div class="PublicPrivate instructor"> Instructor<span class="action">instructor</span></div>'
+
'<div class="PublicPrivate public"> Public<span class="action">public</span></div></div>'
+
'<div class="searchbox"><div class="searchinst">Search</div><select class="dropdown-list">'
+
'<option>Users</option>'
+
'<option>Tags</option>'
+
'<option>Annotation Text</option>'
+
'</select><input type="text" name="search"/><div class="search-icon" alt="Run search."></div><div class="clear-search-icon" alt="Clear search.">Clear</div></div>'
,
//Main->PublicPrivate
//Main->PublicPrivate
annotationPublicPrivate
:
annotationPublicPrivate
:
'<div class="selectors"><div class="PublicPrivate myNotes active">My Notes<span class="action">myNotes</span></div>'
+
'<div class="selectors"><div class="PublicPrivate myNotes active">My Notes<span class="action">myNotes</span></div>'
+
...
@@ -84,7 +95,7 @@ annotationPublicPrivate:
...
@@ -84,7 +95,7 @@ annotationPublicPrivate:
'<option>Users</option>'
+
'<option>Users</option>'
+
'<option>Tags</option>'
+
'<option>Tags</option>'
+
'<option>Annotation Text</option>'
+
'<option>Annotation Text</option>'
+
'</select><input type="text" name="search"/><div class="search-icon" alt="Run search."></div></div>'
,
'</select><input type="text" name="search"/><div class="search-icon" alt="Run search."></div><
div class="clear-search-icon" alt="Clear search.">Clear</div><
/div>'
,
//Main->MediaSelector
//Main->MediaSelector
annotationMediaSelector
:
annotationMediaSelector
:
...
@@ -290,14 +301,14 @@ CatchAnnotation = function (element, options) {
...
@@ -290,14 +301,14 @@ CatchAnnotation = function (element, options) {
//Reset element an create a new element div
//Reset element an create a new element div
element
.
html
(
'<div id="mainCatch" class="annotationListContainer"></div>'
);
element
.
html
(
'<div id="mainCatch" class="annotationListContainer"></div>'
);
this
.
current_tab
=
this
.
options
.
default_tab
;
//INIT
//INIT
var
self
=
this
;
var
self
=
this
;
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
self
.
init
();
self
.
init
();
self
.
refreshCatch
(
true
);
self
.
refreshCatch
(
true
);
var
moreBut
=
self
.
element
.
find
(
'.annotationListButtons .moreButtonCatch'
);
var
moreBut
=
self
.
element
.
find
(
'.annotationListButtons .moreButtonCatch'
);
moreBut
.
hide
();
moreBut
.
hide
();
});
});
return
this
;
return
this
;
...
@@ -310,6 +321,7 @@ CatchAnnotation.prototype = {
...
@@ -310,6 +321,7 @@ CatchAnnotation.prototype = {
this
.
TEMPLATENAMES
=
[
this
.
TEMPLATENAMES
=
[
"annotationList"
,
//Main
"annotationList"
,
//Main
"annotationPublicPrivate"
,
//Main->PublicPrivate
"annotationPublicPrivate"
,
//Main->PublicPrivate
"annotationPublicPrivateInstructor"
,
//Main->PublicPrivateInstructor
"annotationMediaSelector"
,
//Main->MediaSelector
"annotationMediaSelector"
,
//Main->MediaSelector
"annotationItem"
,
//Main->ContainerRow
"annotationItem"
,
//Main->ContainerRow
"annotationReply"
,
//Main->ContainerRow->Reply
"annotationReply"
,
//Main->ContainerRow->Reply
...
@@ -317,8 +329,8 @@ CatchAnnotation.prototype = {
...
@@ -317,8 +329,8 @@ CatchAnnotation.prototype = {
"annotationDetail"
,
//Main->ContainerRow->DetailRow
"annotationDetail"
,
//Main->ContainerRow->DetailRow
];
];
//annotator
//annotator
var
wrapper
=
$
(
'.annotator-wrapper'
).
parent
()[
0
]
,
var
wrapper
=
$
(
'.annotator-wrapper'
).
parent
()[
0
]
;
annotator
=
$
.
data
(
wrapper
,
'annotator'
);
var
annotator
=
$
.
data
(
wrapper
,
'annotator'
);
this
.
annotator
=
annotator
;
this
.
annotator
=
annotator
;
//Subscribe to annotator
//Subscribe to annotator
...
@@ -336,6 +348,10 @@ CatchAnnotation.prototype = {
...
@@ -336,6 +348,10 @@ CatchAnnotation.prototype = {
this
.
HTMLTEMPLATES
=
CatchSources
.
HTMLTEMPLATES
(
this
.
options
.
imageUrlRoot
);
this
.
HTMLTEMPLATES
=
CatchSources
.
HTMLTEMPLATES
(
this
.
options
.
imageUrlRoot
);
this
.
TEMPLATES
=
{};
this
.
TEMPLATES
=
{};
this
.
_compileTemplates
();
this
.
_compileTemplates
();
if
(
this
.
options
.
default_tab
.
toLowerCase
()
==
'instructor'
){
this
.
options
.
userId
=
this
.
options
.
instructor_username
;
this
.
_refresh
(
''
,
''
);
}
},
},
//
//
// GLOBAL UTILITIES
// GLOBAL UTILITIES
...
@@ -380,10 +396,18 @@ CatchAnnotation.prototype = {
...
@@ -380,10 +396,18 @@ CatchAnnotation.prototype = {
if
(
newInstance
){
if
(
newInstance
){
var
videoFormat
=
(
mediaType
===
"video"
)
?
true
:
false
;
var
videoFormat
=
(
mediaType
===
"video"
)
?
true
:
false
;
var
publicprivatetemplate
=
''
;
if
(
self
.
options
.
showPublicPrivate
)
{
if
(
self
.
options
.
instructor_username
!=
''
){
publicprivatetemplate
=
self
.
TEMPLATES
.
annotationPublicPrivateInstructor
();
}
else
{
publicprivatetemplate
=
self
.
TEMPLATES
.
annotationPublicPrivate
();
}
}
el
.
html
(
self
.
TEMPLATES
.
annotationList
({
el
.
html
(
self
.
TEMPLATES
.
annotationList
({
annotationItems
:
annotationItems
,
annotationItems
:
annotationItems
,
videoFormat
:
videoFormat
,
videoFormat
:
videoFormat
,
PublicPrivate
:
self
.
options
.
showPublicPrivate
?
self
.
TEMPLATES
.
annotationPublicPrivate
():
''
,
PublicPrivate
:
publicprivatetemplate
,
MediaSelector
:
self
.
options
.
showMediaSelector
?
self
.
TEMPLATES
.
annotationMediaSelector
():
''
,
MediaSelector
:
self
.
options
.
showMediaSelector
?
self
.
TEMPLATES
.
annotationMediaSelector
():
''
,
}));
}));
}
else
{
}
else
{
...
@@ -402,10 +426,21 @@ CatchAnnotation.prototype = {
...
@@ -402,10 +426,21 @@ CatchAnnotation.prototype = {
//Set PublicPrivate
//Set PublicPrivate
var
PublicPrivateButtons
=
el
.
find
(
'.annotationListButtons .PublicPrivate'
).
removeClass
(
'active'
);
//reset
var
PublicPrivateButtons
=
el
.
find
(
'.annotationListButtons .PublicPrivate'
).
removeClass
(
'active'
);
//reset
for
(
var
index
=
0
;
index
<
PublicPrivateButtons
.
length
;
index
++
)
{
for
(
var
index
=
0
;
index
<
PublicPrivateButtons
.
length
;
index
++
)
{
var
span
=
$
(
PublicPrivateButtons
[
index
]).
find
(
'span'
),
var
span
=
$
(
PublicPrivateButtons
[
index
]).
find
(
'span'
);
isUser
=
(
typeof
self
.
options
.
userId
!=
'undefined'
&&
self
.
options
.
userId
!=
''
&&
self
.
options
.
userId
!=
null
);
if
(
span
.
html
().
toLowerCase
()
==
self
.
current_tab
.
toLowerCase
())
{
if
(
isUser
&&
span
.
html
()
==
"myNotes"
)
$
(
PublicPrivateButtons
[
index
]).
addClass
(
'active'
);
switch
(
self
.
current_tab
.
toLowerCase
()){
else
if
(
!
isUser
&&
span
.
html
()
==
"public"
)
$
(
PublicPrivateButtons
[
index
]).
addClass
(
'active'
);
case
'public'
:
self
.
options
.
userId
=
''
;
break
;
case
'instructor'
:
self
.
options
.
userId
=
this
.
options
.
instructor_username
;
break
;
default
:
self
.
options
.
userId
=
this
.
annotator
.
plugins
.
Permissions
.
user
.
id
;
break
;
}
$
(
PublicPrivateButtons
[
index
]).
addClass
(
'active'
);
}
}
}
//reset all old events
//reset all old events
...
@@ -423,6 +458,7 @@ CatchAnnotation.prototype = {
...
@@ -423,6 +458,7 @@ CatchAnnotation.prototype = {
onControlRepliesClick
=
this
.
__bind
(
this
.
_onControlRepliesClick
,
this
),
onControlRepliesClick
=
this
.
__bind
(
this
.
_onControlRepliesClick
,
this
),
onMoreButtonClick
=
this
.
__bind
(
this
.
_onMoreButtonClick
,
this
),
onMoreButtonClick
=
this
.
__bind
(
this
.
_onMoreButtonClick
,
this
),
onSearchButtonClick
=
this
.
__bind
(
this
.
_onSearchButtonClick
,
this
),
onSearchButtonClick
=
this
.
__bind
(
this
.
_onSearchButtonClick
,
this
),
onClearSearchButtonClick
=
this
.
__bind
(
this
.
_onClearSearchButtonClick
,
this
),
onDeleteReplyButtonClick
=
this
.
__bind
(
this
.
_onDeleteReplyButtonClick
,
this
),
onDeleteReplyButtonClick
=
this
.
__bind
(
this
.
_onDeleteReplyButtonClick
,
this
),
onZoomToImageBoundsButtonClick
=
this
.
__bind
(
this
.
_onZoomToImageBoundsButtonClick
,
this
);
onZoomToImageBoundsButtonClick
=
this
.
__bind
(
this
.
_onZoomToImageBoundsButtonClick
,
this
);
...
@@ -463,6 +499,9 @@ CatchAnnotation.prototype = {
...
@@ -463,6 +499,9 @@ CatchAnnotation.prototype = {
//Search Button
//Search Button
el
.
on
(
"click"
,
".searchbox .search-icon"
,
onSearchButtonClick
);
el
.
on
(
"click"
,
".searchbox .search-icon"
,
onSearchButtonClick
);
//Clear Search Button
el
.
on
(
"click"
,
".searchbox .clear-search-icon"
,
onClearSearchButtonClick
);
//Delete Reply Button
//Delete Reply Button
el
.
on
(
"click"
,
".replies .replyItem .deleteReply"
,
onDeleteReplyButtonClick
);
el
.
on
(
"click"
,
".replies .replyItem .deleteReply"
,
onDeleteReplyButtonClick
);
...
@@ -471,16 +510,16 @@ CatchAnnotation.prototype = {
...
@@ -471,16 +510,16 @@ CatchAnnotation.prototype = {
changeMedia
:
function
(
media
)
{
changeMedia
:
function
(
media
)
{
var
media
=
media
||
'text'
;
var
media
=
media
||
'text'
;
this
.
options
.
media
=
media
;
this
.
options
.
media
=
media
;
this
.
_refresh
();
this
.
_refresh
();
this
.
refreshCatch
(
true
);
this
.
refreshCatch
(
true
);
this
.
checkTotAnnotations
();
this
.
checkTotAnnotations
();
},
},
changeUserId
:
function
(
userId
)
{
changeUserId
:
function
(
userId
)
{
var
userId
=
userId
||
''
;
var
userId
=
userId
||
''
;
this
.
options
.
userId
=
userId
;
this
.
options
.
userId
=
userId
;
this
.
_refresh
();
this
.
_refresh
();
this
.
refreshCatch
(
true
);
this
.
refreshCatch
(
true
);
this
.
checkTotAnnotations
();
this
.
checkTotAnnotations
();
},
},
loadAnnotations
:
function
()
{
loadAnnotations
:
function
()
{
var
annotator
=
this
.
annotator
,
var
annotator
=
this
.
annotator
,
...
@@ -1011,8 +1050,18 @@ CatchAnnotation.prototype = {
...
@@ -1011,8 +1050,18 @@ CatchAnnotation.prototype = {
userId
=
''
;
userId
=
''
;
//Get userI
//Get userI
userId
=
(
action
.
html
()
==
"myNotes"
)?
this
.
annotator
.
plugins
.
Permissions
.
user
.
id
:
''
;
switch
(
action
.
html
()){
case
'public'
:
userId
=
''
;
break
;
case
'instructor'
:
userId
=
this
.
options
.
instructor_username
;
break
;
default
:
userId
=
this
.
annotator
.
plugins
.
Permissions
.
user
.
id
;
break
;
}
this
.
current_tab
=
action
.
html
();
//Change userid and refresh
//Change userid and refresh
this
.
changeUserId
(
userId
);
this
.
changeUserId
(
userId
);
},
},
...
@@ -1069,6 +1118,9 @@ CatchAnnotation.prototype = {
...
@@ -1069,6 +1118,9 @@ CatchAnnotation.prototype = {
this
.
_refresh
(
searchtype
,
searchInput
);
this
.
_refresh
(
searchtype
,
searchInput
);
},
},
_onClearSearchButtonClick
:
function
(
evt
){
this
.
_refresh
(
""
,
""
);
},
_clearAnnotator
:
function
(){
_clearAnnotator
:
function
(){
var
annotator
=
this
.
annotator
,
var
annotator
=
this
.
annotator
,
store
=
annotator
.
plugins
.
Store
,
store
=
annotator
.
plugins
.
Store
,
...
...
lms/templates/textannotation.html
View file @
8429897c
...
@@ -177,6 +177,13 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)}
...
@@ -177,6 +177,13 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)}
//Load the plugin Video/Text Annotation
//Load the plugin Video/Text Annotation
var
ova
=
new
OpenVideoAnnotation
.
Annotator
(
$
(
'#textHolder'
),
options
);
var
ova
=
new
OpenVideoAnnotation
.
Annotator
(
$
(
'#textHolder'
),
options
);
var
userId
=
'${user.email}'
;
if
(
'${default_tab}'
.
toLowerCase
()
==
'instructor'
){
userId
=
'${instructor_username}'
;
}
console
.
log
(
"${user.is_staff}"
);
//Catch
//Catch
var
annotator
=
ova
.
annotator
,
var
annotator
=
ova
.
annotator
,
catchOptions
=
{
catchOptions
=
{
...
@@ -185,9 +192,12 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)}
...
@@ -185,9 +192,12 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)}
imageUrlRoot
:
imgURLRoot
,
imageUrlRoot
:
imgURLRoot
,
showMediaSelector
:
false
,
showMediaSelector
:
false
,
showPublicPrivate
:
true
,
showPublicPrivate
:
true
,
userId
:
'${user.email}'
,
userId
:
userId
,
pagination
:
pagination
,
//Number of Annotations per load in the pagination,
pagination
:
pagination
,
//Number of Annotations per load in the pagination,
flags
:
is_staff
flags
:
is_staff
,
default_tab
:
"${default_tab}"
,
instructor_username
:
"${instructor_username}"
,
annotation_mode
:
"${annotation_mode}"
,
},
},
Catch
=
new
CatchAnnotation
(
$
(
'#catchDIV'
),
catchOptions
);
Catch
=
new
CatchAnnotation
(
$
(
'#catchDIV'
),
catchOptions
);
</script>
</script>
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