mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-26 07:22:34 +00:00
Pdf viewer (#5574)
* [pdf viewer] use the latest PDFjs(v3.8.162) * [pdf viewer] redesigned it: added side panel(thumbnail panel) and bottom bar(includes side panel toggle, 'file page manager', and 'zoom manager') * [pdf file view] added 'print' to the top-right toolbar
This commit is contained in:
@@ -6,6 +6,7 @@ body {
|
||||
}
|
||||
.file-view-header {
|
||||
padding: 4px 10px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #c9c9c9;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
@@ -1,47 +1,43 @@
|
||||
.pdf-file-view {
|
||||
overflow:hidden;
|
||||
position:relative;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* for pdf online file view */
|
||||
.pdf-file-view.file-view-content {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.sf-hide {
|
||||
height:0;
|
||||
overflow:hidden;
|
||||
}
|
||||
.hidden {
|
||||
display: none !important;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#outerContainer,
|
||||
#mainContainer,
|
||||
#viewerContainer {
|
||||
position:absolute;
|
||||
top:0;
|
||||
bottom:0;
|
||||
left:0;
|
||||
right:0;
|
||||
}
|
||||
#viewerContainer {
|
||||
padding: 30px 0 15px;
|
||||
overflow: auto;
|
||||
}
|
||||
#viewerContainer:focus {
|
||||
outline:none;
|
||||
}
|
||||
|
||||
#zoom-toolbar {
|
||||
position: absolute;
|
||||
right: 2rem;
|
||||
bottom: 2rem;
|
||||
z-index: 1030;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
#zoom-toolbar .btn-icon {
|
||||
box-shadow: 0 2px 4px 0 rgba(0,0,0, 0.1);
|
||||
#viewerContainer {
|
||||
padding: 10px 0 32px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.page {
|
||||
#viewerContainer:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.pdfViewer .page {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border: none;
|
||||
box-shadow: 0 0 6px #ccc;
|
||||
margin: 0 auto 20px;
|
||||
margin: 0 auto 10px;
|
||||
}
|
||||
|
||||
.page .loading-icon {
|
||||
@@ -50,290 +46,23 @@
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
#fileInput {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*
|
||||
* the following lines are copied from web/viewer.css
|
||||
* modification:
|
||||
* - replaced `var(...)` with its result
|
||||
* - modified some 'z-index'
|
||||
*/
|
||||
|
||||
/* textLayer starts */
|
||||
.textLayer {
|
||||
position: absolute;
|
||||
text-align: initial;
|
||||
left: 0;
|
||||
top: 0;
|
||||
/* the following lines overwrite lines from web/viewer.css */
|
||||
#toolbarViewerMiddle {
|
||||
left: auto;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0.2;
|
||||
line-height: 1;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.textLayer span,
|
||||
.textLayer br {
|
||||
color: transparent;
|
||||
position: absolute;
|
||||
white-space: pre;
|
||||
cursor: text;
|
||||
transform-origin: 0% 0%;
|
||||
select#scaleSelect {
|
||||
background: #fff;
|
||||
height: 24px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.textLayer .highlight {
|
||||
margin: -1px;
|
||||
padding: 1px;
|
||||
background-color: rgba(180, 0, 170, 1);
|
||||
border-radius: 4px;
|
||||
#scaleSelectContainer::after {
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
.textLayer .highlight.appended {
|
||||
position: initial;
|
||||
}
|
||||
|
||||
.textLayer .highlight.begin {
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
.textLayer .highlight.end {
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
|
||||
.textLayer .highlight.middle {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.textLayer .highlight.selected {
|
||||
background-color: rgba(0, 100, 0, 1);
|
||||
}
|
||||
|
||||
.textLayer ::-moz-selection {
|
||||
background: rgba(0, 0, 255, 1);
|
||||
}
|
||||
|
||||
.textLayer ::selection {
|
||||
background: rgba(0, 0, 255, 1);
|
||||
}
|
||||
|
||||
.textLayer .endOfContent {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
cursor: default;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.textLayer .endOfContent.active {
|
||||
top: 0;
|
||||
}
|
||||
/* textLayer ends */
|
||||
|
||||
/* annotationLayer starts */
|
||||
.annotationLayer section {
|
||||
position: absolute;
|
||||
text-align: initial;
|
||||
}
|
||||
|
||||
.annotationLayer .linkAnnotation > a,
|
||||
.annotationLayer .buttonWidgetAnnotation.pushButton > a {
|
||||
position: absolute;
|
||||
font-size: 1em;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.annotationLayer .linkAnnotation > a:hover,
|
||||
.annotationLayer .buttonWidgetAnnotation.pushButton > a:hover {
|
||||
opacity: 0.2;
|
||||
background: rgba(255, 255, 0, 1);
|
||||
box-shadow: 0 2px 10px rgba(255, 255, 0, 1);
|
||||
}
|
||||
|
||||
.annotationLayer .textAnnotation img {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation input,
|
||||
.annotationLayer .textWidgetAnnotation textarea,
|
||||
.annotationLayer .choiceWidgetAnnotation select,
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input,
|
||||
.annotationLayer .buttonWidgetAnnotation.radioButton input {
|
||||
background-color: rgba(0, 54, 255, 0.13);
|
||||
border: 1px solid transparent;
|
||||
box-sizing: border-box;
|
||||
font-size: 9px;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0 3px;
|
||||
vertical-align: top;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.annotationLayer .choiceWidgetAnnotation select option {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.radioButton input {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation textarea {
|
||||
font: message-box;
|
||||
font-size: 9px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation input[disabled],
|
||||
.annotationLayer .textWidgetAnnotation textarea[disabled],
|
||||
.annotationLayer .choiceWidgetAnnotation select[disabled],
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input[disabled],
|
||||
.annotationLayer .buttonWidgetAnnotation.radioButton input[disabled] {
|
||||
background: none;
|
||||
border: 1px solid transparent;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation input:hover,
|
||||
.annotationLayer .textWidgetAnnotation textarea:hover,
|
||||
.annotationLayer .choiceWidgetAnnotation select:hover,
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:hover,
|
||||
.annotationLayer .buttonWidgetAnnotation.radioButton input:hover {
|
||||
border: 1px solid rgba(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation input:focus,
|
||||
.annotationLayer .textWidgetAnnotation textarea:focus,
|
||||
.annotationLayer .choiceWidgetAnnotation select:focus {
|
||||
background: none;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:before,
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:after,
|
||||
.annotationLayer .buttonWidgetAnnotation.radioButton input:checked:before {
|
||||
background-color: rgba(0, 0, 0, 1);
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:before,
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:after {
|
||||
height: 80%;
|
||||
left: 45%;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:before {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:after {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.radioButton input:checked:before {
|
||||
border-radius: 50%;
|
||||
height: 50%;
|
||||
left: 30%;
|
||||
top: 20%;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation input.comb {
|
||||
font-family: monospace;
|
||||
padding-left: 2px;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.annotationLayer .textWidgetAnnotation input.comb:focus {
|
||||
/*
|
||||
* Letter spacing is placed on the right side of each character. Hence, the
|
||||
* letter spacing of the last character may be placed outside the visible
|
||||
* area, causing horizontal scrolling. We avoid this by extending the width
|
||||
* when the element has focus and revert this when it loses focus.
|
||||
*/
|
||||
width: 103%;
|
||||
}
|
||||
|
||||
.annotationLayer .buttonWidgetAnnotation.checkBox input,
|
||||
.annotationLayer .buttonWidgetAnnotation.radioButton input {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.annotationLayer .popupWrapper {
|
||||
position: absolute;
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
.annotationLayer .popup {
|
||||
position: absolute;
|
||||
z-index: 200;
|
||||
max-width: 20em;
|
||||
background-color: rgba(255, 255, 153, 1);
|
||||
box-shadow: 0 2px 5px rgba(136, 136, 136, 1);
|
||||
border-radius: 2px;
|
||||
padding: 6px;
|
||||
margin-left: 5px;
|
||||
cursor: pointer;
|
||||
font: message-box;
|
||||
font-size: 9px;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.annotationLayer .popup > * {
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.annotationLayer .popup h1 {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.annotationLayer .popup span {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.annotationLayer .popup p {
|
||||
border-top: 1px solid rgba(51, 51, 51, 1);
|
||||
margin-top: 2px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.annotationLayer .highlightAnnotation,
|
||||
.annotationLayer .underlineAnnotation,
|
||||
.annotationLayer .squigglyAnnotation,
|
||||
.annotationLayer .strikeoutAnnotation,
|
||||
.annotationLayer .freeTextAnnotation,
|
||||
.annotationLayer .lineAnnotation svg line,
|
||||
.annotationLayer .squareAnnotation svg rect,
|
||||
.annotationLayer .circleAnnotation svg ellipse,
|
||||
.annotationLayer .polylineAnnotation svg polyline,
|
||||
.annotationLayer .polygonAnnotation svg polygon,
|
||||
.annotationLayer .caretAnnotation,
|
||||
.annotationLayer .inkAnnotation svg polyline,
|
||||
.annotationLayer .stampAnnotation,
|
||||
.annotationLayer .fileAttachmentAnnotation {
|
||||
cursor: pointer;
|
||||
}
|
||||
/* annotationLayer ends */
|
||||
|
||||
/* errorWrapper starts */
|
||||
#errorWrapper {
|
||||
background: #ff6e6e;
|
||||
@@ -345,135 +74,125 @@
|
||||
z-index: 998; /* for seahub */
|
||||
padding: 3px 6px;
|
||||
}
|
||||
|
||||
#errorMessageLeft {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#errorMessageRight {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#errorMoreInfo {
|
||||
background-color: #fff;
|
||||
color: #060606;
|
||||
border: 1px solid #bbbbbc;
|
||||
padding: 3px;
|
||||
margin: 3px;
|
||||
width: 98%;
|
||||
}
|
||||
|
||||
.clearBoth {
|
||||
clear: both;
|
||||
}
|
||||
/* errorWrapper ends */
|
||||
|
||||
/* toolbar, which contains 'loadingBar' */
|
||||
/* toolbar */
|
||||
.toolbar {
|
||||
position: relative;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
/*z-index: 9999;*/
|
||||
z-index: 998; /* 1048: for seahub 'file view' */
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#toolbarContainer {
|
||||
width: 100%;
|
||||
box-shadow: none;
|
||||
border-top: 1px solid #c9c9c9;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
#loadingBar {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
input#pageNumber {
|
||||
font-size: 12px;
|
||||
height: 20px;
|
||||
padding: 0 5px;
|
||||
margin: 0 0 0 9px;
|
||||
}
|
||||
|
||||
#numPages.toolbarLabel {
|
||||
margin: 0;
|
||||
padding: 0 7px;
|
||||
}
|
||||
|
||||
/* toolbar ends */
|
||||
|
||||
/* loadingBar starts */
|
||||
#loadingBar {
|
||||
position: absolute;
|
||||
/*height: 4px;*/
|
||||
height: 0; /* for seahub */
|
||||
|
||||
background-color: #ededf0;
|
||||
border-bottom: 1px solid #ccc;
|
||||
|
||||
transition-duration: 200ms;
|
||||
transition-timing-function: ease;
|
||||
}
|
||||
html[dir="ltr"] #loadingBar {
|
||||
transition-property: left;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
html[dir="rtl"] #loadingBar {
|
||||
transition-property: right;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
#loadingBar .loading-icon {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
}
|
||||
#loadingBar .progress {
|
||||
/* sidebar starts */
|
||||
#sidebarContainer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
background-color: #0a84ff;
|
||||
overflow: hidden;
|
||||
transition: width 200ms;
|
||||
bottom: 0;
|
||||
border-top: none;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
@-webkit-keyframes progressIndeterminate {
|
||||
0% {
|
||||
left: -142px;
|
||||
}
|
||||
100% {
|
||||
left: 0;
|
||||
}
|
||||
#toolbarSidebar {
|
||||
height: auto;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
@keyframes progressIndeterminate {
|
||||
0% {
|
||||
left: -142px;
|
||||
}
|
||||
100% {
|
||||
left: 0;
|
||||
}
|
||||
#thumbnailView {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#loadingBar .progress.indeterminate {
|
||||
background-color: #ddddde;
|
||||
transition: none;
|
||||
#thumbnails-header {
|
||||
}
|
||||
|
||||
#loadingBar .progress.indeterminate .glimmer {
|
||||
#thumbnails-header .title {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
#thumbnails-header .sf2-icon-x3 {
|
||||
font-family: 'seafile-font2';
|
||||
}
|
||||
|
||||
#thumbnails-header .close-thumbnail-panel {
|
||||
font-size: 1rem;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
#thumbnails-header .close-thumbnail-panel:hover {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
#thumbnailView .thumbnail {
|
||||
float: none;
|
||||
max-width: unset;
|
||||
max-height: unset;
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 10px 0;
|
||||
border: none;
|
||||
border-radius: unset;
|
||||
margin: 0 1px 0 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#thumbnailView .thumbnail.selected {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
#thumbnailView .thumbnail .thumbnail-page-number {
|
||||
font-size: .875rem;
|
||||
color: #999;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: calc(100% + 150px);
|
||||
background: repeating-linear-gradient(
|
||||
135deg,
|
||||
#74b1ef 0,
|
||||
#28282b 5px,
|
||||
#28282b 45px,
|
||||
#0a84ff 55px,
|
||||
#0a84ff 95px,
|
||||
#74b1ef 100px
|
||||
);
|
||||
-webkit-animation: progressIndeterminate 1s linear infinite;
|
||||
animation: progressIndeterminate 1s linear infinite;
|
||||
right: 100%;
|
||||
bottom: 0;
|
||||
}
|
||||
/* loadingBar ends */
|
||||
|
||||
#thumbnailView .thumbnail .thumbnailImage {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#thumbnailView .thumbnail.selected .thumbnailImage {
|
||||
border: 2px solid #ff9800;
|
||||
}
|
||||
|
||||
#sidebarContent {
|
||||
inset-block: 51.5px 0;
|
||||
}
|
||||
|
||||
.splitToolbarButton > .toolbarButton {
|
||||
float: none;
|
||||
}
|
||||
/* sidebar ends */
|
||||
|
||||
/* overlay, passwordOverlay */
|
||||
.overlayButton {
|
||||
width: auto;
|
||||
margin: 3px 4px 2px !important;
|
||||
padding: 2px 11px;
|
||||
color: #0c0c0d;
|
||||
background-color: rgba(12, 12, 13, 0.1);
|
||||
border: 0 none !important;
|
||||
}
|
||||
|
||||
#overlayContainer {
|
||||
display: table;
|
||||
position: absolute;
|
||||
@@ -484,64 +203,8 @@ html[dir="rtl"] #loadingBar {
|
||||
z-index: 999; /* 1049: for seahub 'share' dialog */
|
||||
}
|
||||
|
||||
#overlayContainer > * {
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
@media print {
|
||||
#wrapper {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#overlayContainer > .container {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#overlayContainer > .container > .dialog {
|
||||
display: inline-block;
|
||||
padding: 15px;
|
||||
border-spacing: 4px;
|
||||
color: #0c0c0d;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
background-color: #fff;
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.dialog > .row {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.dialog > .row > * {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.dialog .toolbarField {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.dialog .separator {
|
||||
display: block;
|
||||
margin: 4px 0;
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.dialog .buttonRow {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.dialog :link {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
#passwordOverlay > .dialog {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#passwordOverlay .toolbarField {
|
||||
width: 200px;
|
||||
}
|
||||
/* overlay ends */
|
||||
|
@@ -21,8 +21,9 @@
|
||||
|
||||
.shared-file-view-head {
|
||||
width: 950px;
|
||||
margin: 0 auto;
|
||||
height: 60px;
|
||||
background: #fff;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items:center;
|
||||
justify-content: space-between;
|
||||
|
Reference in New Issue
Block a user