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
ad1cf355
Commit
ad1cf355
authored
Feb 18, 2015
by
Will Daly
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7007 from edx/will/ecom-859-take-three
ECOM-859: Add support for an input image capture.
parents
9cf9f05a
a29662cd
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
396 additions
and
98 deletions
+396
-98
lms/envs/common.py
+1
-0
lms/static/js/spec/main.js
+11
-0
lms/static/js/spec/verify_student/image_input_spec.js
+156
-0
lms/static/js/spec/verify_student/pay_and_verify_view_spec.js
+2
-1
lms/static/js/spec/verify_student/webcam_photo_view_spec.js
+6
-28
lms/static/js/verify_student/views/error_view.js
+1
-1
lms/static/js/verify_student/views/face_photo_step_view.js
+1
-1
lms/static/js/verify_student/views/id_photo_step_view.js
+1
-1
lms/static/js/verify_student/views/image_input_view.js
+112
-0
lms/static/js/verify_student/views/webcam_photo_view.js
+77
-60
lms/static/sass/views/_verification.scss
+5
-0
lms/templates/verify_student/image_input.underscore
+5
-0
lms/templates/verify_student/pay_and_verify.html
+1
-1
lms/templates/verify_student/webcam_photo.underscore
+17
-5
No files found.
lms/envs/common.py
View file @
ad1cf355
...
...
@@ -1141,6 +1141,7 @@ verify_student_js = [
'js/src/string_utils.js'
,
'js/verify_student/models/verification_model.js'
,
'js/verify_student/views/error_view.js'
,
'js/verify_student/views/image_input_view.js'
,
'js/verify_student/views/webcam_photo_view.js'
,
'js/verify_student/views/step_view.js'
,
'js/verify_student/views/intro_step_view.js'
,
...
...
lms/static/js/spec/main.js
View file @
ad1cf355
...
...
@@ -423,6 +423,16 @@
},
'js/verify_student/views/webcam_photo_view'
:
{
exports
:
'edx.verify_student.WebcamPhotoView'
,
deps
:
[
'jquery'
,
'underscore'
,
'backbone'
,
'gettext'
,
'js/verify_student/views/image_input_view'
]
},
'js/verify_student/views/image_input_view'
:
{
exports
:
'edx.verify_student.ImageInputView'
,
deps
:
[
'jquery'
,
'underscore'
,
'backbone'
,
'gettext'
]
},
'js/verify_student/views/step_view'
:
{
...
...
@@ -540,6 +550,7 @@
'lms/include/js/spec/student_profile/profile_spec.js'
,
'lms/include/js/spec/verify_student/pay_and_verify_view_spec.js'
,
'lms/include/js/spec/verify_student/webcam_photo_view_spec.js'
,
'lms/include/js/spec/verify_student/image_input_spec.js'
,
'lms/include/js/spec/verify_student/review_photos_step_view_spec.js'
,
'lms/include/js/spec/verify_student/make_payment_step_view_spec.js'
,
'lms/include/js/spec/edxnotes/utils/logger_spec.js'
,
...
...
lms/static/js/spec/verify_student/image_input_spec.js
0 → 100644
View file @
ad1cf355
define
([
'jquery'
,
'backbone'
,
'js/common_helpers/template_helpers'
,
'js/common_helpers/ajax_helpers'
,
'js/verify_student/views/image_input_view'
,
'js/verify_student/models/verification_model'
],
function
(
$
,
Backbone
,
TemplateHelpers
,
AjaxHelpers
,
ImageInputView
,
VerificationModel
)
{
'use strict'
;
describe
(
'edx.verify_student.ImageInputView'
,
function
()
{
var
IMAGE_DATA
=
'abcd1234'
;
var
createView
=
function
()
{
return
new
ImageInputView
({
el
:
$
(
'#current-step-container'
),
model
:
new
VerificationModel
({}),
modelAttribute
:
'faceImage'
,
errorModel
:
new
(
Backbone
.
Model
.
extend
({})
)(),
submitButton
:
$
(
'#submit_button'
),
}).
render
();
};
var
uploadImage
=
function
(
view
,
fileType
,
callback
)
{
var
imageCapturedEvent
=
false
,
errorEvent
=
false
;
// Since image upload is an asynchronous process,
// we need to wait for the upload to complete
// before checking the outcome.
runs
(
function
()
{
var
fakeFile
,
fakeEvent
=
{
target
:
{
files
:
[]
}
};
// If no file type is specified, don't add any files.
// This simulates what happens when the user clicks
// "cancel" after clicking the input.
if
(
fileType
!==
null
)
{
fakeFile
=
new
Blob
(
[
IMAGE_DATA
],
{
type
:
'image/'
+
fileType
}
);
fakeEvent
.
target
.
files
=
[
fakeFile
];
}
// Wait for either a successful upload or an error
view
.
on
(
'imageCaptured'
,
function
()
{
imageCapturedEvent
=
true
;
});
view
.
on
(
'error'
,
function
()
{
errorEvent
=
true
;
});
// Trigger the file input change
// It's impossible to trigger this directly due
// to browser security restrictions, so we call
// the handler instead.
view
.
handleInputChange
(
fakeEvent
);
});
// Check that the image upload has completed,
// either successfully or with an error.
waitsFor
(
function
()
{
return
(
imageCapturedEvent
||
errorEvent
);
});
// Execute the callback to check expectations.
runs
(
callback
);
};
var
expectPreview
=
function
(
view
,
fileType
)
{
var
previewImage
=
view
.
$preview
.
attr
(
'src'
);
if
(
fileType
)
{
expect
(
previewImage
).
toContain
(
'data:image/'
+
fileType
);
}
else
{
expect
(
previewImage
).
toEqual
(
''
);
}
};
var
expectSubmitEnabled
=
function
(
isEnabled
)
{
var
appearsDisabled
=
$
(
'#submit_button'
).
hasClass
(
'is-disabled'
),
isDisabled
=
$
(
'#submit_button'
).
prop
(
'disabled'
);
expect
(
!
appearsDisabled
).
toEqual
(
isEnabled
);
expect
(
!
isDisabled
).
toEqual
(
isEnabled
);
};
var
expectImageData
=
function
(
view
,
fileType
)
{
var
imageData
=
view
.
model
.
get
(
view
.
modelAttribute
);
if
(
fileType
)
{
expect
(
imageData
).
toContain
(
'data:image/'
+
fileType
);
}
else
{
expect
(
imageData
).
toEqual
(
''
);
}
};
var
expectError
=
function
(
view
)
{
expect
(
view
.
errorModel
.
get
(
'shown'
)
).
toBe
(
true
);
};
beforeEach
(
function
()
{
setFixtures
(
'<div id="current-step-container"></div>'
+
'<input type="button" id="submit_button"></input>'
);
TemplateHelpers
.
installTemplate
(
'templates/verify_student/image_input'
);
});
it
(
'initially disables the submit button'
,
function
()
{
createView
();
expectSubmitEnabled
(
false
);
});
it
(
'uploads a png image'
,
function
()
{
var
view
=
createView
();
uploadImage
(
view
,
'png'
,
function
()
{
expectPreview
(
view
,
'png'
);
expectSubmitEnabled
(
true
);
expectImageData
(
view
,
'png'
);
});
});
it
(
'uploads a jpeg image'
,
function
()
{
var
view
=
createView
();
uploadImage
(
view
,
'jpeg'
,
function
()
{
expectPreview
(
view
,
'jpeg'
);
expectSubmitEnabled
(
true
);
expectImageData
(
view
,
'jpeg'
);
}
);
});
it
(
'hides the preview when the user cancels the upload'
,
function
()
{
var
view
=
createView
();
uploadImage
(
view
,
null
,
function
()
{
expectPreview
(
view
,
null
);
expectSubmitEnabled
(
false
);
expectImageData
(
view
,
null
);
}
);
});
it
(
'shows an error if the file type is not supported'
,
function
()
{
var
view
=
createView
();
uploadImage
(
view
,
'txt'
,
function
()
{
expectPreview
(
view
,
null
);
expectError
(
view
);
expectSubmitEnabled
(
false
);
expectImageData
(
view
,
null
);
}
);
});
});
});
lms/static/js/spec/verify_student/pay_and_verify_view_spec.js
View file @
ad1cf355
...
...
@@ -13,7 +13,8 @@ define(['jquery', 'js/common_helpers/template_helpers', 'js/verify_student/views
'make_payment_step'
,
'payment_confirmation_step'
,
'review_photos_step'
,
'webcam_photo'
'webcam_photo'
,
'image_input'
];
var
INTRO_STEP
=
{
...
...
lms/static/js/spec/verify_student/webcam_photo_view_spec.js
View file @
ad1cf355
...
...
@@ -45,14 +45,14 @@ define([
};
};
var
createView
=
function
(
backend
s
)
{
var
createView
=
function
(
backend
Stub
)
{
return
new
WebcamPhotoView
({
el
:
$
(
'#current-step-container'
),
model
:
new
VerificationModel
({}),
modelAttribute
:
'faceImage'
,
errorModel
:
new
(
Backbone
.
Model
.
extend
({})
)(),
submitButton
:
$
(
'#submit_button'
),
backend
s
:
backends
backend
:
backendStub
}).
render
();
};
...
...
@@ -91,7 +91,7 @@ define([
});
it
(
'takes a snapshot'
,
function
()
{
var
view
=
createView
(
[
StubBackend
(
"html5"
)
]
);
var
view
=
createView
(
new
StubBackend
(
"html5"
)
);
// Spy on the backend
spyOn
(
view
.
backend
,
'snapshot'
).
andCallThrough
();
...
...
@@ -122,7 +122,7 @@ define([
});
it
(
'resets the camera'
,
function
()
{
var
view
=
createView
(
[
StubBackend
(
"html5"
)
]
);
var
view
=
createView
(
new
StubBackend
(
"html5"
)
);
// Spy on the backend
spyOn
(
view
.
backend
,
'reset'
).
andCallThrough
();
...
...
@@ -145,30 +145,8 @@ define([
expect
(
view
.
model
.
get
(
'faceImage'
)
).
toEqual
(
""
);
});
it
(
'falls back to a second video capture backend'
,
function
()
{
var
backends
=
[
StubBackend
(
"html5"
,
false
),
StubBackend
(
"flash"
,
true
)
],
view
=
createView
(
backends
);
// Expect that the second backend is chosen
expect
(
view
.
backend
.
name
).
toEqual
(
backends
[
1
].
name
);
});
it
(
'displays an error if no video backend is supported'
,
function
()
{
var
backends
=
[
StubBackend
(
"html5"
,
false
),
StubBackend
(
"flash"
,
false
)
],
view
=
createView
(
backends
);
// Expect an error
expect
(
view
.
errorModel
.
get
(
'errorTitle'
)
).
toEqual
(
'Flash Not Detected'
);
expect
(
view
.
errorModel
.
get
(
'errorMsg'
)
).
toContain
(
'Get Flash'
);
expect
(
view
.
errorModel
.
get
(
'shown'
)
).
toBe
(
true
);
// Expect that submission is disabled
expectSubmitEnabled
(
false
);
});
it
(
'displays an error if the snapshot fails'
,
function
()
{
var
backends
=
[
StubBackend
(
"html5"
,
true
,
false
)
],
view
=
createView
(
backends
);
var
view
=
createView
(
new
StubBackend
(
"html5"
,
true
,
false
)
);
// Take a snapshot
takeSnapshot
();
...
...
@@ -189,7 +167,7 @@ define([
});
it
(
'displays an error triggered by the backend'
,
function
()
{
var
view
=
createView
(
[
StubBackend
(
"html5"
)
]
);
var
view
=
createView
(
new
StubBackend
(
"html5"
)
);
// Simulate an error triggered by the backend
// This could occur at any point, including
...
...
lms/static/js/verify_student/views/error_view.js
View file @
ad1cf355
...
...
@@ -17,7 +17,7 @@
errorMsg
:
""
,
shown
:
false
});
this
.
listenTo
Once
(
this
.
model
,
'change'
,
this
.
render
);
this
.
listenTo
(
this
.
model
,
'change'
,
this
.
render
);
},
render
:
function
()
{
...
...
lms/static/js/verify_student/views/face_photo_step_view.js
View file @
ad1cf355
...
...
@@ -17,7 +17,7 @@ var edx = edx || {};
},
postRender
:
function
()
{
var
webcam
=
new
edx
.
verify_student
.
WebcamPhoto
View
({
var
webcam
=
edx
.
verify_student
.
getSupportedWebcam
View
({
el
:
$
(
'#facecam'
),
model
:
this
.
model
,
modelAttribute
:
'faceImage'
,
...
...
lms/static/js/verify_student/views/id_photo_step_view.js
View file @
ad1cf355
...
...
@@ -17,7 +17,7 @@ var edx = edx || {};
},
postRender
:
function
()
{
var
webcam
=
new
edx
.
verify_student
.
WebcamPhoto
View
({
var
webcam
=
edx
.
verify_student
.
getSupportedWebcam
View
({
el
:
$
(
'#idcam'
),
model
:
this
.
model
,
modelAttribute
:
'identificationImage'
,
...
...
lms/static/js/verify_student/views/image_input_view.js
0 → 100644
View file @
ad1cf355
/**
* Allow users to upload an image using a file input.
*
* This uses HTML Media Capture so that iOS will
* allow users to use their camera instead of choosing
* a file.
*/
var
edx
=
edx
||
{};
(
function
(
$
,
_
,
Backbone
,
gettext
)
{
'use strict'
;
edx
.
verify_student
=
edx
.
verify_student
||
{};
edx
.
verify_student
.
ImageInputView
=
Backbone
.
View
.
extend
({
template
:
'#image_input-tpl'
,
initialize
:
function
(
obj
)
{
this
.
$submitButton
=
obj
.
submitButton
?
$
(
obj
.
submitButton
)
:
''
;
this
.
modelAttribute
=
obj
.
modelAttribute
||
''
;
this
.
errorModel
=
obj
.
errorModel
||
null
;
},
render
:
function
()
{
var
renderedHtml
=
_
.
template
(
$
(
this
.
template
).
html
(),
{}
);
$
(
this
.
el
).
html
(
renderedHtml
);
// Set the submit button to disabled by default
this
.
setSubmitButtonEnabled
(
false
);
this
.
$input
=
$
(
'input.image-upload'
);
this
.
$preview
=
$
(
'img.preview'
);
this
.
$input
.
on
(
'change'
,
_
.
bind
(
this
.
handleInputChange
,
this
)
);
// Initially hide the preview
this
.
displayImage
(
false
);
return
this
;
},
handleInputChange
:
function
(
event
)
{
var
files
=
event
.
target
.
files
,
reader
=
new
FileReader
();
if
(
files
[
0
]
&&
files
[
0
].
type
.
match
(
'image.[png|jpg|jpeg]'
)
)
{
reader
.
onload
=
_
.
bind
(
this
.
handleImageUpload
,
this
);
reader
.
onerror
=
_
.
bind
(
this
.
handleUploadError
,
this
);
reader
.
readAsDataURL
(
files
[
0
]
);
}
else
if
(
files
.
length
===
0
)
{
this
.
handleUploadError
(
false
);
}
else
{
this
.
handleUploadError
(
true
);
}
},
handleImageUpload
:
function
(
event
)
{
var
imageData
=
event
.
target
.
result
;
this
.
model
.
set
(
this
.
modelAttribute
,
imageData
);
this
.
displayImage
(
imageData
);
this
.
setSubmitButtonEnabled
(
true
);
// Hide any errors we may have displayed previously
if
(
this
.
errorModel
)
{
this
.
errorModel
.
set
({
shown
:
false
});
}
this
.
trigger
(
'imageCaptured'
);
},
displayImage
:
function
(
imageData
)
{
if
(
imageData
)
{
this
.
$preview
.
attr
(
'src'
,
imageData
)
.
removeClass
(
'is-hidden'
)
.
attr
(
'aria-hidden'
,
'false'
);
}
else
{
this
.
$preview
.
attr
(
'src'
,
''
)
.
addClass
(
'is-hidden'
)
.
attr
(
'aria-hidden'
,
'true'
);
}
},
handleUploadError
:
function
(
displayError
)
{
this
.
displayImage
(
null
);
this
.
setSubmitButtonEnabled
(
false
);
if
(
this
.
errorModel
)
{
if
(
displayError
)
{
this
.
errorModel
.
set
({
errorTitle
:
gettext
(
'Image Upload Error'
),
errorMsg
:
gettext
(
'Please verify that you have uploaded a valid image (PNG and JPEG).'
),
shown
:
true
});
}
else
{
this
.
errorModel
.
set
({
shown
:
false
});
}
}
this
.
trigger
(
'error'
);
},
setSubmitButtonEnabled
:
function
(
isEnabled
)
{
this
.
$submitButton
.
toggleClass
(
'is-disabled'
,
!
isEnabled
)
.
prop
(
'disabled'
,
!
isEnabled
)
.
attr
(
'aria-disabled'
,
!
isEnabled
);
}
});
})(
jQuery
,
_
,
Backbone
,
gettext
);
lms/static/js/verify_student/views/webcam_photo_view.js
View file @
ad1cf355
/**
* Interface for retrieving webcam photos.
* Supports
both
HTML5 and Flash.
* Supports HTML5 and Flash.
*/
var
edx
=
edx
||
{};
...
...
@@ -13,8 +13,8 @@
template
:
"#webcam_photo-tpl"
,
backends
:
[
{
backends
:
{
"html5"
:
{
name
:
"html5"
,
initialize
:
function
(
obj
)
{
...
...
@@ -24,18 +24,21 @@
this
.
stream
=
null
;
// Start the capture
this
.
getUserMediaFunc
()(
{
video
:
true
,
// Specify the `fake` constraint if we detect we are running in a test
// environment. In Chrome, this will do nothing, but in Firefox, it will
// instruct the browser to use a fake video device.
fake
:
window
.
location
.
hostname
===
'localhost'
},
_
.
bind
(
this
.
getUserMediaCallback
,
this
),
_
.
bind
(
this
.
handleVideoFailure
,
this
)
);
var
getUserMedia
=
this
.
getUserMediaFunc
();
if
(
getUserMedia
)
{
getUserMedia
(
{
video
:
true
,
// Specify the `fake` constraint if we detect we are running in a test
// environment. In Chrome, this will do nothing, but in Firefox, it will
// instruct the browser to use a fake video device.
fake
:
window
.
location
.
hostname
===
'localhost'
},
_
.
bind
(
this
.
getUserMediaCallback
,
this
),
_
.
bind
(
this
.
handleVideoFailure
,
this
)
);
}
},
isSupported
:
function
()
{
...
...
@@ -98,16 +101,14 @@
}
},
{
"flash"
:
{
name
:
"flash"
,
initialize
:
function
(
obj
)
{
this
.
wrapper
=
obj
.
wrapper
||
""
;
this
.
imageData
=
""
;
// Replace the camera section with the flash object
$
(
this
.
wrapper
).
html
(
this
.
flashObjectTag
()
);
// Wait for the player to load, then verify camera support
// Trigger an error if no camera is available.
this
.
checkCameraSupported
();
...
...
@@ -203,36 +204,26 @@
// so we don't need to keep checking.
}
}
]
,
}
,
initialize
:
function
(
obj
)
{
this
.
submitButton
=
obj
.
submitButton
||
""
;
this
.
modelAttribute
=
obj
.
modelAttribute
||
""
;
this
.
errorModel
=
obj
.
errorModel
||
null
;
this
.
backend
=
_
.
find
(
obj
.
backends
||
this
.
backends
,
function
(
backend
)
{
return
backend
.
isSupported
();
}
);
this
.
backend
=
this
.
backends
[
obj
.
backendName
]
||
obj
.
backend
;
if
(
!
this
.
backend
)
{
this
.
handleError
(
gettext
(
"Flash Not Detected"
),
gettext
(
"You don't seem to have Flash installed."
)
+
" "
+
_
.
sprintf
(
gettext
(
"%(a_start)s Get Flash %(a_end)s to continue your enrollment."
),
{
a_start
:
'<a rel="external" href="http://get.adobe.com/flashplayer/">'
,
a_end
:
'</a>'
}
)
);
}
else
{
_
.
extend
(
this
.
backend
,
Backbone
.
Events
);
this
.
listenTo
(
this
.
backend
,
'error'
,
this
.
handleError
);
}
this
.
backend
.
initialize
({
wrapper
:
"#camera"
,
video
:
'#photo_id_video'
,
canvas
:
'#photo_id_canvas'
});
_
.
extend
(
this
.
backend
,
Backbone
.
Events
);
this
.
listenTo
(
this
.
backend
,
'error'
,
this
.
handleError
);
},
isSupported
:
function
()
{
return
this
.
backend
.
isSupported
();
},
render
:
function
()
{
...
...
@@ -242,26 +233,18 @@
this
.
setSubmitButtonEnabled
(
false
);
// Load the template for the webcam into the DOM
renderedHtml
=
_
.
template
(
$
(
this
.
template
).
html
(),
{}
);
renderedHtml
=
_
.
template
(
$
(
this
.
template
).
html
(),
{
backendName
:
this
.
backend
.
name
}
);
$
(
this
.
el
).
html
(
renderedHtml
);
// Initialize the video capture backend
// We need to do this after rendering the template
// so that the backend has the opportunity to modify the DOM.
if
(
this
.
backend
)
{
this
.
backend
.
initialize
({
wrapper
:
"#camera"
,
video
:
'#photo_id_video'
,
canvas
:
'#photo_id_canvas'
});
// Install event handlers
$
(
"#webcam_reset_button"
,
this
.
el
).
on
(
'click'
,
_
.
bind
(
this
.
reset
,
this
)
);
$
(
"#webcam_capture_button"
,
this
.
el
).
on
(
'click'
,
_
.
bind
(
this
.
capture
,
this
)
);
// Install event handlers
$
(
"#webcam_reset_button"
,
this
.
el
).
on
(
'click'
,
_
.
bind
(
this
.
reset
,
this
)
);
$
(
"#webcam_capture_button"
,
this
.
el
).
on
(
'click'
,
_
.
bind
(
this
.
capture
,
this
)
);
// Show the capture button
$
(
"#webcam_capture_button"
,
this
.
el
).
removeClass
(
'is-hidden'
);
}
// Show the capture button
$
(
"#webcam_capture_button"
,
this
.
el
).
removeClass
(
'is-hidden'
);
return
this
;
},
...
...
@@ -325,4 +308,38 @@
}
});
/**
* Retrieve a supported webcam view implementation.
*
* The priority order from most to least preferable is:
* 1) HTML5
* 2) Flash
* 3) File input
*
* @param {Object} obj Parameters to the webcam view.
* @return {Object} A Backbone view.
*/
edx
.
verify_student
.
getSupportedWebcamView
=
function
(
obj
)
{
var
view
=
null
;
// First choice is HTML5, supported by most web browsers
obj
.
backendName
=
"html5"
;
view
=
new
edx
.
verify_student
.
WebcamPhotoView
(
obj
);
if
(
view
.
isSupported
()
)
{
return
view
;
}
// Second choice is Flash, required for older versions of IE
obj
.
backendName
=
"flash"
;
view
=
new
edx
.
verify_student
.
WebcamPhotoView
(
obj
);
if
(
view
.
isSupported
()
)
{
return
view
;
}
// Last resort is HTML file input with image capture.
// This will work everywhere, and on iOS it will
// allow users to take a photo with the camera.
return
new
edx
.
verify_student
.
ImageInputView
(
obj
);
};
})(
jQuery
,
_
,
Backbone
,
gettext
);
lms/static/sass/views/_verification.scss
View file @
ad1cf355
...
...
@@ -973,6 +973,11 @@
.controls
{
height
:
(
$baseline
*
4
);
}
.preview
{
width
:
100%
;
height
:
100%
;
}
}
// ====================
...
...
lms/templates/verify_student/image_input.underscore
0 → 100644
View file @
ad1cf355
<img class="preview" alt="<%- gettext("Preview of uploaded image") %>"/>
<label>
<span class="sr"><%- gettext("Upload an image or capture one with your web or phone camera.") %></span>
<input class="image-upload" type="file" accept="image/*;capture=camera">
</label>
lms/templates/verify_student/pay_and_verify.html
View file @
ad1cf355
...
...
@@ -23,7 +23,7 @@ from verify_student.views import PayAndVerifyView
<
%
block
name=
"header_extras"
>
<
%
template_names =
(
["
webcam_photo
",
"
error
"]
+
["
webcam_photo
",
"
image_input
",
"
error
"]
+
[
step
['
templateName
']
for
step
in
display_steps
]
)
%
>
...
...
lms/templates/verify_student/webcam_photo.underscore
View file @
ad1cf355
<div class="placeholder-cam" id="camera">
<div class="placeholder-art">
<p class="copy"><%- gettext( "Don't see your picture? Make sure to allow your browser to use your camera when it asks for permission." ) %></p>
</div>
<% if ( backendName === 'html5' ) { %>
<div class="placeholder-art">
<p class="copy"><%- gettext( "Don't see your picture? Make sure to allow your browser to use your camera when it asks for permission." ) %></p>
</div>
<video id="photo_id_video" aria-label="<%- gettext( 'Live view of webcam' ) %>" autoplay></video><br/>
<canvas id="photo_id_canvas" style="display:none;" width="640" height="480"></canvas>
<video id="photo_id_video" aria-label="<%- gettext( 'Live view of webcam' ) %>" autoplay></video><br/>
<canvas id="photo_id_canvas" style="display:none;" width="640" height="480"></canvas>
<% } else if ( backendName === 'flash' ) { %>
<object type="application/x-shockwave-flash"
id="flash_video"
name="flash_video"
data="/static/js/verify_student/CameraCapture.swf"
width="500"
height="375">
<param name="quality" value="high">
<param name="allowscriptaccess" value="sameDomain">
</object>
<% } %>
</div>
<div class="controls photo-controls">
...
...
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