Commit 51a863bd by David Ormsbee

Merge pull request #1557 from MITx/feature/brian/pdfchapter

Feature/brian/pdfchapter
parents df01064e 310073dd
...@@ -85,13 +85,16 @@ select { ...@@ -85,13 +85,16 @@ select {
} }
#viewerContainer { #viewerContainer {
overflow: auto; /* overflow: auto; */
box-shadow: inset 1px 0 0 hsla(0,0%,100%,.05); box-shadow: inset 1px 0 0 hsla(0,0%,100%,.05);
/* position: absolute; /* position: absolute;
top: 32px; top: 32px;
right: 0; right: 0;
bottom: 0; bottom: 0;
left: 0; */ left: 0; */
/* switch to using these instead: */
position: relative;
overflow: hidden;
} }
.toolbar { .toolbar {
......
...@@ -27,12 +27,28 @@ PDFJS.disableWorker = true; ...@@ -27,12 +27,28 @@ PDFJS.disableWorker = true;
var pdfViewer = this; var pdfViewer = this;
var pdfDocument = null; var pdfDocument = null;
var url = options['url']; var urlToLoad = null;
var pageNum = 1; if (options.url) {
urlToLoad = options.url;
}
var chapterUrls = null;
if (options.chapters) {
chapterUrls = options.chapters;
}
var chapterToLoad = 1;
if (options.chapterNum) {
// TODO: this should only be specified if there are
// chapters, and it should be in-bounds.
chapterToLoad = options.chapterNum;
}
var pageToLoad = 1;
if (options.pageNum) { if (options.pageNum) {
pageNum = options.pageNum; pageToLoad = options.pageNum;
} }
var chapterNum = 1;
var pageNum = 1;
var viewerElement = document.getElementById('viewer'); var viewerElement = document.getElementById('viewer');
var ANNOT_MIN_SIZE = 10; var ANNOT_MIN_SIZE = 10;
var DEFAULT_SCALE_DELTA = 1.1; var DEFAULT_SCALE_DELTA = 1.1;
...@@ -44,31 +60,28 @@ PDFJS.disableWorker = true; ...@@ -44,31 +60,28 @@ PDFJS.disableWorker = true;
var currentScaleValue = "0"; var currentScaleValue = "0";
var DEFAULT_SCALE_VALUE = "1"; var DEFAULT_SCALE_VALUE = "1";
// TESTING:
var destinations = null;
var setupText = function setupText(textdiv, content, viewport) { var setupText = function setupText(textdiv, content, viewport) {
function getPageNumberFromDest(dest) { function getPageNumberFromDest(dest) {
var destPage = 1; var destPage = 1;
if (dest instanceof Array) { if (dest instanceof Array) {
var destRef = dest[0]; var destRef = dest[0];
if (destRef instanceof Object) { if (destRef instanceof Object) {
// we would need to look this up in the // we would need to look this up in the
// list of all pages that have been loaded, // list of all pages that have been loaded,
// but we're trying to not have to load all the pages // but we're trying to not have to load all the pages
// right now. // right now.
// destPage = this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R']; // destPage = this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'];
} else { } else {
destPage = (destRef + 1); destPage = (destRef + 1);
} }
} }
return destPage; return destPage;
} }
function bindLink(link, dest) { function bindLink(link, dest) {
// get page number from dest: // get page number from dest:
destPage = getPageNumberFromDest(dest); destPage = getPageNumberFromDest(dest);
link.href = '#page=' + destPage; link.href = '#page=' + destPage;
link.onclick = function pageViewSetupLinksOnclick() { link.onclick = function pageViewSetupLinksOnclick() {
if (dest && dest instanceof Array ) if (dest && dest instanceof Array )
...@@ -138,10 +151,10 @@ PDFJS.disableWorker = true; ...@@ -138,10 +151,10 @@ PDFJS.disableWorker = true;
// Get page info from document, resize canvas accordingly, and render page // Get page info from document, resize canvas accordingly, and render page
// //
renderPage = function(num) { renderPage = function(num) {
// don't try to render a page that cannot be rendered // don't try to render a page that cannot be rendered
if (num < 1 || num > pdfDocument.numPages) { if (num < 1 || num > pdfDocument.numPages) {
return; return;
} }
// Update logging: // Update logging:
log_event("book", { "type" : "gotopage", "old" : pageNum, "new" : num }); log_event("book", { "type" : "gotopage", "old" : pageNum, "new" : num });
...@@ -270,18 +283,37 @@ PDFJS.disableWorker = true; ...@@ -270,18 +283,37 @@ PDFJS.disableWorker = true;
// //
// Asynchronously download PDF as an ArrayBuffer // Asynchronously download PDF as an ArrayBuffer
// //
PDFJS.getDocument(url).then( loadUrl = function pdfViewLoadUrl(url, page) {
function getDocument(_pdfDocument) { PDFJS.getDocument(url).then(
pdfDocument = _pdfDocument; function getDocument(_pdfDocument) {
// display the current page with a default scale value: pdfDocument = _pdfDocument;
parseScale(DEFAULT_SCALE_VALUE); pageNum = page;
}, // if the scale has not been set before, set it now.
function getDocumentError(message, exception) { // Otherwise, don't change the current scale,
// placeholder: don't expect errors :) // but make sure it gets refreshed.
}, if (currentScale == UNKNOWN_SCALE) {
function getDocumentProgress(progressData) { parseScale(DEFAULT_SCALE_VALUE);
// placeholder: not yet ready to display loading progress } else {
}); var preservedScale = currentScale;
currentScale = UNKNOWN_SCALE;
parseScale(preservedScale);
}
},
function getDocumentError(message, exception) {
// placeholder: don't expect errors :)
},
function getDocumentProgress(progressData) {
// placeholder: not yet ready to display loading progress
});
};
loadChapterUrl = function pdfViewLoadChapterUrl(chapterNum, pageVal) {
if (chapterNum < 1 || chapterNum > chapterUrls.length) {
return;
}
var chapterUrl = chapterUrls[chapterNum-1];
loadUrl(chapterUrl, pageVal);
}
$("#previous").click(function(event) { $("#previous").click(function(event) {
prevPage(); prevPage();
...@@ -302,11 +334,34 @@ PDFJS.disableWorker = true; ...@@ -302,11 +334,34 @@ PDFJS.disableWorker = true;
parseScale(this.value); parseScale(this.value);
}); });
$('#pageNumber').change(function(event) { $('#pageNumber').change(function(event) {
var newPageVal = parseInt(this.value); var newPageVal = parseInt(this.value);
if (newPageVal) { if (newPageVal) {
renderPage(newPageVal); renderPage(newPageVal);
} }
}); });
// define navigation links for chapters:
if (chapterUrls != null) {
var loadChapterUrlHelper = function(i) {
return function(event) {
// when opening a new chapter, always open the first page:
loadChapterUrl(i, 1);
};
};
for (var index = 1; index <= chapterUrls.length; index += 1) {
$("#pdfchapter-" + index).click(loadChapterUrlHelper(index));
}
}
// finally, load the appropriate url/page
if (urlToLoad != null) {
loadUrl(urlToLoad, pageToLoad);
} else {
loadChapterUrl(chapterToLoad, pageToLoad);
}
return pdfViewer;
} }
})(jQuery); })(jQuery);
...@@ -52,13 +52,18 @@ def pdf_index(request, course_id, book_index, chapter=None, page=None): ...@@ -52,13 +52,18 @@ def pdf_index(request, course_id, book_index, chapter=None, page=None):
# strip off the quotes again... # strip off the quotes again...
return output_url[1:-1] return output_url[1:-1]
textbook['url'] = remap_static_url(textbook['url'], course) if 'url' in textbook:
textbook['url'] = remap_static_url(textbook['url'], course)
# then remap all the chapter URLs as well, if they are provided. # then remap all the chapter URLs as well, if they are provided.
if 'chapters' in textbook:
for entry in textbook['chapters']:
entry['url'] = remap_static_url(entry['url'], course)
return render_to_response('static_pdfbook.html', return render_to_response('static_pdfbook.html',
{'book_index': book_index, {'book_index': book_index,
'course': course, 'course': course,
'textbook': textbook, 'textbook': textbook,
'page': page,
'chapter': chapter, 'chapter': chapter,
'page': page,
'staff_access': staff_access}) 'staff_access': staff_access})
...@@ -102,6 +102,7 @@ div.book-wrapper { ...@@ -102,6 +102,7 @@ div.book-wrapper {
position: absolute; position: absolute;
height: 100%; height: 100%;
width: flex-grid(2, 8); width: flex-grid(2, 8);
z-index: 1;
a { a {
background-color: rgba(#000, .7); background-color: rgba(#000, .7);
......
...@@ -17,37 +17,39 @@ ...@@ -17,37 +17,39 @@
<%block name="js_extra"> <%block name="js_extra">
<script type="text/javascript"> <script type="text/javascript">
var url = "${textbook['url']}";
$(document).ready(function() { $(document).ready(function() {
$('#outerContainer').PDFViewer( { var options = {};
% if page is not None: %if 'url' in textbook:
'pageNum' : ${page}, options.url = "${textbook['url']}";
% endif %endif
'url' : url %if 'chapters' in textbook:
}); var chptrs = [];
%for chap in textbook['chapters']:
chptrs.push("${chap['url']}");
%endfor
options.chapters = chptrs;
%endif
%if chapter is not None:
options.chapterNum = ${chapter};
%endif
%if page is not None:
options.pageNum = ${page};
%endif
$('#outerContainer').PDFViewer(options);
}); });
</script> </script>
</%block> </%block>
<%include file="/courseware/course_navigation.html" args="active_page='pdftextbook/{0}'.format(book_index)" /> <%include file="/courseware/course_navigation.html" args="active_page='pdftextbook/{0}'.format(book_index)" />
<div id="outerContainer"> <div id="outerContainer">
<div id="mainContainer"> <div id="mainContainer" class="book-wrapper">
<div class="toolbar"> <div class="toolbar">
<div id="toolbarContainer"> <div id="toolbarContainer">
<div id="toolbarViewer"> <div id="toolbarViewer">
<div id="toolbarViewerLeft"> <div id="toolbarViewerLeft">
<div class="splitToolbarButton">
<button class="toolbarButton pageUp" title="Previous Page" id="previous" tabindex="5">
<span>Previous</span>
</button>
<div class="splitToolbarButtonSeparator"></div>
<button class="toolbarButton pageDown" title="Next Page" id="next" tabindex="6">
<span>Next</span>
</button>
</div>
<label id="pageNumberLabel" class="toolbarLabel" for="pageNumber">Page: </label> <label id="pageNumberLabel" class="toolbarLabel" for="pageNumber">Page: </label>
<input type="number" id="pageNumber" class="toolbarField pageNumber" value="1" size="4" min="1" tabindex="7"> <input type="number" id="pageNumber" class="toolbarField pageNumber" value="1" size="4" min="1" tabindex="7">
</input> </input>
...@@ -88,7 +90,38 @@ ...@@ -88,7 +90,38 @@
</div> </div>
</div> </div>
<div id="viewerContainer"> %if 'chapters' in textbook:
<section aria-label="Textbook Navigation" class="book-sidebar">
<ul id="booknav" class="treeview-booknav">
<%def name="print_entry(entry, index_value)">
<li id="pdfchapter-${index_value}">
<a class="chapter">
${entry.get('title')}
</a>
</li>
</%def>
% for (index, entry) in enumerate(textbook['chapters']):
${print_entry(entry, index+1)}
% endfor
</ul>
</section>
%endif
<section id="viewerContainer" class="book">
<!-- use same page-turning as used in image-based textbooks -->
<nav>
<ul>
<li class="last">
<a id="previous">Previous page</a>
</li>
<li class="next">
<a id="next">Next page</a>
</li>
</ul>
</nav>
<div id="viewer" contextmenu="viewerContextMenu"></div> <div id="viewer" contextmenu="viewerContextMenu"></div>
</div> </div>
......
...@@ -280,11 +280,10 @@ if settings.COURSEWARE_ENABLED: ...@@ -280,11 +280,10 @@ if settings.COURSEWARE_ENABLED:
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/pdfbook/(?P<book_index>[^/]*)/(?P<page>[^/]*)$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/pdfbook/(?P<book_index>[^/]*)/(?P<page>[^/]*)$',
'staticbook.views.pdf_index'), 'staticbook.views.pdf_index'),
# Doesn't yet support loading individual chapters... url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/pdfbook/(?P<book_index>[^/]*)/chapter/(?P<chapter>[^/]*)/$',
# url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/pdfbook/(?P<book_index>[^/]*)/chapter/(?P<chapter>[^/]*)/$', 'staticbook.views.pdf_index'),
# 'staticbook.views.pdf_index'), url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/pdfbook/(?P<book_index>[^/]*)/chapter/(?P<chapter>[^/]*)/(?P<page>[^/]*)$',
# url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/pdfbook/(?P<book_index>[^/]*)/chapter/(?P<chapter>[^/]*)/(?P<page>[^/]*)$', 'staticbook.views.pdf_index'),
# 'staticbook.views.pdf_index'),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/?$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/?$',
'courseware.views.index', name="courseware"), 'courseware.views.index', name="courseware"),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment