From 5315adbb0ea3cd64b4390fbd8d7acd682844887a Mon Sep 17 00:00:00 2001 From: intellisense Date: Sat, 11 Apr 2015 05:15:20 +0500 Subject: [PATCH] adding gui similar to pdf.js --- share/base.css.in | 168 ++++++++++++++++++++++++++++++++- share/build_js.sh | 32 ++++--- share/manifest | 43 +++++++++ share/navbar.js.in | 209 +++++++++++++++++++++++++++++++++++++++++ share/pdf2htmlEX.js.in | 10 +- 5 files changed, 442 insertions(+), 20 deletions(-) create mode 100644 share/navbar.js.in diff --git a/share/base.css.in b/share/base.css.in index 7f6150773..a867a2f57 100644 --- a/share/base.css.in +++ b/share/base.css.in @@ -7,17 +7,18 @@ /* Part 1: Web Page Layout: Free to modify, except for a few of them which are required by pdf2htmlEX.js, see the comments */ #sidebar { /* Sidebar */ position:absolute; - top:0; + top:32px; left:0; bottom:0; width:250px; padding:0; margin:0px; overflow:auto; + display:none; /* we will show it when user toggle the sidebar from navbar */ } #page-container { /* PDF container */ position:absolute; /* required for calculating relative positions of pages in pdf2htmlEX.js */ - top:0; + top:32px; left:0px; margin:0; padding:0; @@ -79,7 +80,7 @@ position:relative; background-color:white; overflow: hidden; - margin:0; + margin:0 auto; border:0; /* required by pdf2htmlEX.js for page visibility test */ } .@CSS_PAGE_CONTENT_BOX_CN@ { /* content of a page */ @@ -190,4 +191,165 @@ -ms-transform-origin:0% 100%; -webkit-transform-origin:0% 100%; } +/* Nav Bar CSS START */ +/* Mostly taken from the pdf.js styling */ +.pull-left { + float: left +} +.pull-right { + float: right; +} +.hide { + display: none !important; +} +.show { + display: inline-block !important; +} +nav.fixed-nav-bar { + box-shadow: 1px 0 0 hsla(0, 0%, 100%, 0.08) inset, 0 1px 1px hsla(0, 0%, 0%, 0.15) inset, 0 -1px 0 hsla(0, 0%, 100%, 0.05) inset, 0 1px 0 hsla(0, 0%, 0%, 0.15), 0 1px 1px hsla(0, 0%, 0%, 0.1); + height: 32px; + left: 0; + position: fixed; + top: 0; + width: 100%; + z-index: 9999; +} +nav.fixed-nav-bar ul { + list-style: none; + margin-top: 4px; +} +nav.fixed-nav-bar .splitToolbarButton { + display: inline-block; + margin: 0 2px 0 15px; +} +nav.fixed-nav-bar .splitToolbarButtonSeparator { + background-color: hsla(0, 0%, 0%, 0.5); + box-shadow: 0 0 0 1px hsla(0, 0%, 100%, 0.08); + display: inline-block; + padding: 8px 0; + width: 1px; + z-index: 99; +} +nav.fixed-nav-bar .toolbarButton { + background: none repeat scroll 0 0 rgba(0, 0, 0, 0); + border: 0 none; + height: 25px; + width: 32px; + cursor: default; +} +nav.fixed-nav-bar .toolbarButton:hover, nav.fixed-nav-bar .toolbarButton.active { + background-color: hsla(0,0%,0%,.12); + background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-clip: padding-box; + border: 1px solid hsla(0,0%,0%,.35); + border-color: hsla(0,0%,0%,.32) hsla(0,0%,0%,.38) hsla(0,0%,0%,.42); + box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, + 0 0 1px hsla(0,0%,100%,.15) inset, + 0 1px 0 hsla(0,0%,100%,.05); + -webkit-transition-property: background-color, border-color, box-shadow; + -webkit-transition-duration: 150ms; + -webkit-transition-timing-function: ease; + transition-property: background-color, border-color, box-shadow; + transition-duration: 150ms; + transition-timing-function: ease; +} +nav.fixed-nav-bar .toolbarButton[disabled] { + opacity: 0.5; +} + +nav.fixed-nav-bar .toolbarButton.sidebarToggle::before { + content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAqElEQVR4Aa3QoQrCUBSH8W/3JdZtIqgPZPIxVoaGYVpcNwoGm0bBRxh2rZchw7C0e64Xxk7RYdn/FwYL34Fr+DMD/uxfAy4e42FBM2AOBmiR4ykpkgKJVr3tBqEFAwgyu2VlViL+2ksPSIABHG7aAODQ+Tcu6E4EAOgX6P5rAbSgG6cw5onJV2GJFiRYswuEu9rrQ9kHQk0VCJWqEfu0GEucR+lvcR7zAZWDlG3B7eMJAAAAAElFTkSuQmCC'); +} + +nav.fixed-nav-bar .toolbarButton.pageUp::before { + content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAvUlEQVR4AZXPMcrCQBDF8WksLHMCz2Bh6YfgLSwtvIp4BFsLWwmRxMJGVFAQBAshEPkkBNEDJE2K54PssktcC/ObZtg/hJEfP6xIbAJbhAdF34IQGVLKELqCJZ/uSsqtFgT4x83gFtiBjwRxTQJfBwuuV4eYLyKctvSEcDG4E1/sD2fDfebJ0nQE5Q4HLe/kUuFozzn2WjEppMLRpgNssFWO6H/8Qrzx8DUr18yIyQieCVTCw7rqxD9pSUPkDcScIefy5+KaAAAAAElFTkSuQmCC'); +} +nav.fixed-nav-bar .toolbarButton.pageDown::before { + content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAtUlEQVR4AY3KQQqCQBTG8QdBJ6hFq+7gCTpEB4k6ULQQEUQYqBNI0CIIWgRFgZSFONLehX3F1PON2aL5LebB96c/HrqYIMXdSDDHACQIRG3qT8e4IHm54vZI7YS/zsHFmRWLglh1zIaIWXksiVXHqIeThZgcLeyFHYidqAcKsbG1xIYyATlaYdOkFTn0eU4eYl2XhzKbJAuwElnAs5VoH8s37duznXiIEGlP5mbialfmn8n3/ATF/vfFQRwIrAAAAABJRU5ErkJggg=='); +} +nav.fixed-nav-bar .toolbarButton.search::before { + content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAA/ElEQVQYGZ3Bv0oCAQDH8d8QNCrkJm0NTunQmGtYtPQCprj1AG05mDnW2hM4BKVjCkXYP5SDAz0kRQfxEHuCrPPu26J4UQ31+Uh/Q4ISAwaU2dZ3HDHGZsgQmzHH+ootbLdXyW/s7O5V8m4Pm4T8JiX61ZzCWtKywtc5+pOy/FyLTiqimVSEjmvJzzFpd8Kaqa/Qdkz5vV7SfMto5iNNc3wlv8dDTK9FkgABkl4L8yKjBaLTBgYGFl26WBjmqUKaI+o1qE/vq9lR0ak5tVHx/EBrmmOdZ56md4W0VhVTXHHFFNKCd8ODc3uSUlA/ezl7rxT2FdSvItpUUP/zCZK2jEiR7TfaAAAAAElFTkSuQmCC'); +} +nav.fixed-nav-bar .toolbarButton.presentationMode::before { + content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAABCElEQVQoU2NgIAz+v4PCOrhIHUwMwn0CgpfmMijB9ShdnA0RhSh4BILfjvwXhpvA920PRBTCfXBp1sfD/x/+OwBR8p/v3/b/j76cvDzn/wOwgtOTGVTcnD4c/H/vRzqI/z3p//3Px0M8GVSBMhAbgZjVzWlHE4MMmC+1pxUozQ6VgQNWqDQIyIKlSQT/ef8Hwdlh/4WQpdJB0v/W/L/6PxIqffXfFpCS/+kQBRf/5/5b9f/Mp60NeiB+jsb7Df9P/9v8v+D/RYiCo//P/T/5abO/O9RprPaO79f9PwkUPQpRcBgEzzQjuZz1dANEFKLgIBie/J8Md1Xy/1MQUQjfAQrl4CbIwcUYAPaYrBx6Om1JAAAAAElFTkSuQmCC'); +} +nav.fixed-nav-bar .toolbarButton.zoomOut::before { + content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAH0lEQVR4AWMYUeD/OyyQAQSBCAwvYUIUBQwOWOAwAgBbHjPhdhuBHAAAAABJRU5ErkJggg=='); +} +nav.fixed-nav-bar .toolbarButton.zoomIn::before { + content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAT0lEQVR4AWOgO/j/DggZkCHLf1QV39C1sKDx/5CsgBFqxWMo/wsQ80DZssgmvAcRGGyEAsY8qC/6gOwifN48CYRo3qTUFwyoBjI4ACGVAQCo9CsjniAahgAAAABJRU5ErkJggg=='); +} +nav.fixed-nav-bar .toolbarLabel { + -moz-user-select: none; + border: 1px solid transparent; + border-radius: 2px; + color: hsl(0, 0%, 85%); + cursor: default; + font-size: 12px; + line-height: 14px; + min-width: 16px; + padding-left: 5px; + text-align: left; + font: message-box; +} +nav.fixed-nav-bar .toolbarField.pageNumber { + -moz-appearance: textfield; + min-width: 16px; + text-align: right; + width: 40px; +} +nav.fixed-nav-bar .toolbarField { + -moz-border-bottom-colors: none; + -moz-border-left-colors: none; + -moz-border-right-colors: none; + -moz-border-top-colors: none; + background-clip: padding-box; + background-color: hsla(0, 0%, 100%, 0.09); + background-image: linear-gradient(hsla(0, 0%, 100%, 0.05), hsla(0, 0%, 100%, 0)); + border-color: hsla(0, 0%, 0%, 0.32) hsla(0, 0%, 0%, 0.38) hsla(0, 0%, 0%, 0.42); + border-image: none; + border-radius: 2px; + border-style: solid; + border-width: 1px; + box-shadow: 0 1px 0 hsla(0, 0%, 0%, 0.05) inset, 0 1px 0 hsla(0, 0%, 100%, 0.05); + color: hsl(0, 0%, 95%); + font-size: 12px; + line-height: 14px; + outline-style: none; + padding: 3px 6px; + transition-duration: 150ms; + transition-property: background-color, border-color, box-shadow; + transition-timing-function: ease; +} +nav.fixed-nav-bar .left-menu { + float: left; + margin-left: 5px; + padding: 0px; +} +nav.fixed-nav-bar .right-menu { + float: right; + margin-right: 5px; + padding: 0px; +} +nav.fixed-nav-bar .middle-menu { + float: right; + margin-right: 50%; + padding: 0px; +} +nav.fixed-nav-bar .left-menu li { + float: left; +} +nav.fixed-nav-bar .right-menu li { + float: right; +} +.sbl_active{ + color: #0cf !important; +} +/* disable text input type=number spin button */ +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} +/* Nav Bar CSS END */ /* Base CSS END */ diff --git a/share/build_js.sh b/share/build_js.sh index c03eba35c..694ffe168 100755 --- a/share/build_js.sh +++ b/share/build_js.sh @@ -9,19 +9,23 @@ BASEDIR=$(dirname $0) CLOSURE_COMPILER_DIR="$BASEDIR/../3rdparty/closure-compiler" CLOSURE_COMPILER_JAR="$CLOSURE_COMPILER_DIR/compiler.jar" -INPUT="$BASEDIR/pdf2htmlEX.js" -OUTPUT_FN="pdf2htmlEX.min.js" -OUTPUT="$BASEDIR/$OUTPUT_FN" +build () { + INPUT="$BASEDIR/$1" + OUTPUT_FN="$2" + OUTPUT="$BASEDIR/$OUTPUT_FN" -(echo "Building $OUTPUT_FN with closure-compiler..." && \ - java -jar "$CLOSURE_COMPILER_JAR" \ - --compilation_level ADVANCED_OPTIMIZATIONS \ - --warning_level VERBOSE \ - --output_wrapper "(function(){%output%})();" \ - --js "$INPUT" \ - --js_output_file "$OUTPUT" && \ - echo 'Done.') || \ -(echo 'Failed. Read `3rdparty/closure-compiler/README` for more detail.' && \ -echo 'Using the uncompressed version.' && \ -cat "$INPUT" > "$OUTPUT") + (echo "Building $OUTPUT_FN with closure-compiler..." && \ + java -jar "$CLOSURE_COMPILER_JAR" \ + --compilation_level $3 \ + --warning_level VERBOSE \ + --output_wrapper "(function(){%output%})();" \ + --js "$INPUT" \ + --js_output_file "$OUTPUT" && \ + echo 'Done.') || \ + (echo 'Failed. Read `3rdparty/closure-compiler/README` for more detail.' && \ + echo 'Using the uncompressed version.' && \ + cat "$INPUT" > "$OUTPUT") +} +build "pdf2htmlEX.js.in" "pdf2htmlEX.min.js" "ADVANCED_OPTIMIZATIONS" +build "navbar.js.in" "navbar.min.js" "SIMPLE_OPTIMIZATIONS" diff --git a/share/manifest b/share/manifest index 74088d1ea..231898d63 100644 --- a/share/manifest +++ b/share/manifest @@ -30,6 +30,14 @@ @base.min.css # fancy CSS styles - Optional @fancy.min.css +""" + +""" # PDF specific CSS styles - Do not modify $css @@ -56,6 +64,8 @@ try{ }catch(e){} """ +# must be included after @pdf2htmlEX.min.js and initialization of pdf2htmlEX.Viewer +@navbar.min.js ############# # Do not modify @@ -63,6 +73,39 @@ try{ + """ ############# diff --git a/share/navbar.js.in b/share/navbar.js.in new file mode 100644 index 000000000..e4ca6f452 --- /dev/null +++ b/share/navbar.js.in @@ -0,0 +1,209 @@ +var pdf2htmlEX = window.pdf2htmlEX; +function get(id){ + return document.getElementById(id); +} +function isFullScreen(){ + return document.fullscreen || + document.mozFullScreen || + document.webkitIsFullScreen || + false; +} +function hasClass(element, cls) { + return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1; +} +function enableBtn(id){ + get(id).disabled = false; +} +function disableBtn(id){ + get(id).disabled = true; +} +function addClass(element, cls){ + if (!hasClass(element, cls)){ + element.className = element.className + ' ' + cls; + } +} +function removeClass(element, cls) { + element.className = element.className.replace(new RegExp('(?:^|\\s)'+cls+'(?!\\S)'), ''); +} +function getPage(seq, pages){ + for (var i=0; i pdf2htmlEX.defaultViewer.pages.length){ + //pass + }else{ + if (p !== pdf2htmlEX.defaultViewer.cur_page_idx + 1){ + pdf2htmlEX.defaultViewer.scroll_to(p-1); + return true; + } + } + return false; +} +function togglePresentationModeIconState(){ + var presentationMode = get('presentationMode'); + if (isFullScreen()){ + addClass(presentationMode, 'active'); + }else { + removeClass(presentationMode, 'active'); + } +} + +document.addEventListener('DOMContentLoaded', function() { + var pageNumber = get('pageNumber'); + // set/enable/disable navbar pages + pdf2htmlEX.defaultViewer.init_after_loading_content(); + pdf2htmlEX.defaultViewer.update_page_idx(); + var pages = pdf2htmlEX.defaultViewer.pages; + var pages_length = pages.length; + var cur_page_idx = pdf2htmlEX.defaultViewer.cur_page_idx + 1; + if (pages_length > 0){ + pageNumber.max = pages_length; + get('numPages').innerHTML = 'of ' + pages_length; + if (pages_length === 1){ + disableBtn('next'); + } + } + else { + disableBtn('next'); + } + + //if user directly lands on e.g. 6th page update showing page counter instead of default `1` + if (cur_page_idx > 1){ + pageNumber.value = cur_page_idx; + updateOutLine(cur_page_idx); + }else{ + updateOutLine(1); + } + + //if user scroll update current page number in navbar + get(pdf2htmlEX.defaultViewer.config['container_id']).addEventListener('scroll', function(){ + if (pdf2htmlEX.defaultViewer.cur_page_idx + 1 !== cur_page_idx){ + cur_page_idx = pdf2htmlEX.defaultViewer.cur_page_idx + 1; + pageNumber.value = cur_page_idx; + updateOutLine(cur_page_idx); + if (cur_page_idx > 0){ + if (cur_page_idx === 1){ + if (cur_page_idx !== pages_length){ + enableBtn('next'); + disableBtn('previous'); + }else{ + disableBtn('next'); + disableBtn('previous'); + } + }else if (cur_page_idx > 1 && cur_page_idx < pages_length){ + enableBtn('next'); + enableBtn('previous'); + }else { + disableBtn('next'); + enableBtn('previous'); + } + } + } + }, false); + + //if user jump on page by changing paging number, show page + pageNumber.addEventListener('change', function(){ + var ok = jumpToPage(pageNumber.value); + if (ok === false){ + pageNumber.value = cur_page_idx; + } + }, false); + + pageNumber.addEventListener('keyup', function(e){ + var keyCode = e.keyCode || e.which; + if (keyCode == 13) { + var ok = jumpToPage(pageNumber.value); + if (ok === false){ + pageNumber.value = cur_page_idx; + } + } + }, false); + + get('next').addEventListener('click', function() { + jumpToPage(parseInt(pageNumber.value) + 1); + }, false); + get('previous').addEventListener('click', function() { + jumpToPage(parseInt(pageNumber.value) - 1); + }, false); + get('zoomOut').addEventListener('click', function() { + pdf2htmlEX.defaultViewer.rescale(pdf2htmlEX.defaultViewer.config['scale_step'], true); + }, false); + get('zoomIn').addEventListener('click', function() { + pdf2htmlEX.defaultViewer.rescale(1.0 / pdf2htmlEX.defaultViewer.config['scale_step'], true); + }, false); + + var sidebarToggle = get('sidebarToggle'); + var sidebar = get('sidebar'); + sidebarToggle.addEventListener('click', function() { + if (!hasClass(sidebarToggle, 'active')) { + removeClass(sidebar, 'hide'); + addClass(sidebar, 'show'); + addClass(sidebar, 'opened'); + addClass(sidebarToggle, 'active'); + } + else { + removeClass(sidebar, 'show'); + removeClass(sidebar, 'opened'); + addClass(sidebar, 'hide'); + removeClass(sidebarToggle, 'active'); + } + }, false); + + var presentationMode = get('presentationMode'); + presentationMode.addEventListener('click', function() { + if (!document.fullscreenElement && // alternative standard method + !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) { // current working methods + if (document.documentElement.requestFullscreen) { + document.documentElement.requestFullscreen(); + } else if (document.documentElement.msRequestFullscreen) { + document.documentElement.msRequestFullscreen(); + } else if (document.documentElement.mozRequestFullScreen) { + document.documentElement.mozRequestFullScreen(); + } else if (document.documentElement.webkitRequestFullscreen) { + document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); + } + } else { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.msExitFullscreen) { + document.msExitFullscreen(); + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen(); + } + } + togglePresentationModeIconState(); + }, false); + + document.addEventListener('webkitfullscreenchange', function(){ + togglePresentationModeIconState(); + }, false); + document.addEventListener('mozfullscreenchange', function(){ + togglePresentationModeIconState(); + }, false); + document.addEventListener('fullscreenchange', function(){ + togglePresentationModeIconState(); + }, false); + document.addEventListener('MSFullscreenChange', function(){ + togglePresentationModeIconState(); + }, false); +}, false); \ No newline at end of file diff --git a/share/pdf2htmlEX.js.in b/share/pdf2htmlEX.js.in index ae6a68843..023b63681 100644 --- a/share/pdf2htmlEX.js.in +++ b/share/pdf2htmlEX.js.in @@ -65,6 +65,7 @@ var DEFAULT_CONFIG = { 'key_handler' : true, // register hashchange handler 'hashchange_handler' : true, + 'sidebar_toggle_button_id': 'sidebarToggle', '__dummy__' : 'no comma' }; @@ -264,11 +265,12 @@ Viewer.prototype = { this.sidebar = document.getElementById(this.config['sidebar_id']); this.outline = document.getElementById(this.config['outline_id']); this.container = document.getElementById(this.config['container_id']); + this.sidebar_toggle_btn = document.getElementById(this.config['sidebar_toggle_button_id']); this.loading_indicator = document.getElementsByClassName(this.config['loading_indicator_cls'])[0]; { - // Open the outline if nonempty + // show the toggle sidebar button if outline not empty var empty = true; var nodes = this.outline.childNodes; for (var i = 0, l = nodes.length; i < l; ++i) { @@ -278,8 +280,10 @@ Viewer.prototype = { break; } } - if (!empty) - this.sidebar.classList.add('opened'); + if (!empty){ + this.sidebar_toggle_btn.classList.remove('hide'); + this.sidebar_toggle_btn.classList.add('show'); + } } this.find_pages();