mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Add highlighting when syncing from code to pdf
This commit is contained in:
parent
1444db4fd6
commit
ef7a3788b4
6 changed files with 144 additions and 17 deletions
|
@ -215,7 +215,7 @@ define [
|
|||
Backbone.View::undelegateEvents.apply(this, arguments)
|
||||
@pdfView.undelegateEvents()
|
||||
|
||||
setPdfPosition: (args...) ->
|
||||
@pdfView.setPdfPosition?(args...)
|
||||
highlightInPdf: (args...) ->
|
||||
@pdfView.highlightInPdf?(args...)
|
||||
|
||||
|
||||
|
|
|
@ -2,16 +2,18 @@ define [
|
|||
"libs/pdfListView/PdfListView"
|
||||
"libs/pdfListView/TextLayerBuilder"
|
||||
"libs/pdfListView/AnnotationsLayerBuilder"
|
||||
"libs/pdfListView/HighlightsLayerBuilder"
|
||||
"text!libs/pdfListView/TextLayer.css"
|
||||
"text!libs/pdfListView/AnnotationsLayer.css"
|
||||
"text!libs/pdfListView/HighlightsLayer.css"
|
||||
"libs/backbone"
|
||||
"libs/jquery.storage"
|
||||
], (PDFListView, TextLayerBuilder, AnnotationsLayerBuilder, textLayerCss, annotationsLayerCss) ->
|
||||
], (PDFListView, TextLayerBuilder, AnnotationsLayerBuilder, HighlightsLayerBuilder, textLayerCss, annotationsLayerCss, highlightsLayerCss) ->
|
||||
if PDFJS?
|
||||
PDFJS.workerSrc = "#{window.sharelatex.pdfJsWorkerPath}"
|
||||
|
||||
style = $("<style/>")
|
||||
style.text(textLayerCss + "\n" + annotationsLayerCss)
|
||||
style.text(textLayerCss + "\n" + annotationsLayerCss + "\n" + highlightsLayerCss)
|
||||
$("body").append(style)
|
||||
|
||||
PDFjsView = Backbone.View.extend
|
||||
|
@ -33,6 +35,7 @@ define [
|
|||
@pdfListView = new PDFListView @$(".pdfjs-list-view")[0],
|
||||
textLayerBuilder: TextLayerBuilder
|
||||
annotationsLayerBuilder: AnnotationsLayerBuilder
|
||||
highlightsLayerBuilder: HighlightsLayerBuilder
|
||||
ondblclick: (e) =>
|
||||
@trigger "dblclick", e
|
||||
#logLevel: PDFListView.Logger.DEBUG
|
||||
|
@ -123,11 +126,35 @@ define [
|
|||
onResize: () ->
|
||||
@pdfListView.onResize()
|
||||
|
||||
setPdfPosition: (page, top, left) ->
|
||||
highlightInPdf: (areas) ->
|
||||
highlights = for area in (areas or [])
|
||||
{
|
||||
page: area.page - 1
|
||||
highlight:
|
||||
left: area.h
|
||||
top: area.v
|
||||
height: area.height
|
||||
width: area.width
|
||||
}
|
||||
|
||||
if highlights.length > 0
|
||||
first = highlights[0]
|
||||
@pdfListView.setPdfPosition({
|
||||
page: page
|
||||
page: first.page
|
||||
offset:
|
||||
left: left
|
||||
top: top
|
||||
left: first.highlight.left
|
||||
top: first.highlight.top - 100
|
||||
}, true)
|
||||
|
||||
@pdfListView.clearHighlights()
|
||||
@pdfListView.setHighlights(highlights, true)
|
||||
|
||||
setTimeout () =>
|
||||
@$(".pdfjs-list-view .plv-highlights-layer > div").fadeOut "slow", () =>
|
||||
@pdfListView.clearHighlights()
|
||||
, 1000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -243,9 +243,5 @@ define [
|
|||
type: "GET"
|
||||
success: (response) =>
|
||||
data = JSON.parse(response)
|
||||
if data.pdf and data.pdf.length > 0
|
||||
page = data.pdf[0].page - 1
|
||||
h = data.pdf[0].h
|
||||
v = data.pdf[0].v
|
||||
@view.setPdfPosition page, v - 100, h
|
||||
@view.highlightInPdf(data.pdf or [])
|
||||
}
|
||||
|
|
16
services/web/public/js/libs/pdfListView/HighlightsLayer.css
Normal file
16
services/web/public/js/libs/pdfListView/HighlightsLayer.css
Normal file
|
@ -0,0 +1,16 @@
|
|||
.plv-highlights-layer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
.plv-highlights-layer > div {
|
||||
display: block;
|
||||
position: absolute;
|
||||
pointer-events: auto;
|
||||
background-color: yellow;
|
||||
opacity: 0.4;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
(function (name, context, definition) {
|
||||
if (typeof module != 'undefined' && module.exports) module.exports = definition()
|
||||
else if (typeof define == 'function' && define.amd) define(definition)
|
||||
else context[name] = definition()
|
||||
})('HighlightsLayerBuilder', this, function (name, context) {
|
||||
|
||||
function HighlightsLayerBuilder(pageView, highlightsLayerDiv) {
|
||||
this.highlightsLayerDiv = highlightsLayerDiv;
|
||||
this.pageView = pageView;
|
||||
this.highlightElements = [];
|
||||
};
|
||||
|
||||
HighlightsLayerBuilder.EXTERNAL_LINK_TARGET = "_blank";
|
||||
|
||||
HighlightsLayerBuilder.prototype = {
|
||||
addHighlight: function(left, top, width, height) {
|
||||
rect = this.pageView.viewport.convertToViewportRectangle([left, top, left + width, top + height]);
|
||||
rect = PDFJS.Util.normalizeRect(rect);
|
||||
var element = document.createElement("div");
|
||||
element.style.left = Math.floor(rect[0]) + 'px';
|
||||
element.style.top = Math.floor(rect[1]) + 'px';
|
||||
element.style.width = Math.ceil(rect[2] - rect[0]) + 'px';
|
||||
element.style.height = Math.ceil(rect[3] - rect[1]) + 'px';
|
||||
this.highlightElements.push(element);
|
||||
this.highlightsLayerDiv.appendChild(element);
|
||||
return element;
|
||||
},
|
||||
|
||||
clearHighlights: function() {
|
||||
for (var i = 0; i < this.highlightElements.length; i++) {
|
||||
this.highlightElements[i].remove();
|
||||
}
|
||||
this.highlightElements = [];
|
||||
}
|
||||
}
|
||||
|
||||
return HighlightsLayerBuilder;
|
||||
|
||||
});
|
|
@ -399,6 +399,20 @@ ListView.prototype = {
|
|||
var position = pageView.getPdfPositionInViewer(offset.left, offset.top);
|
||||
this.dom.scrollTop = position.top;
|
||||
}
|
||||
},
|
||||
|
||||
setHighlights: function(highlights, fromTop) {
|
||||
for (i = 0; i < highlights.length; i++) {
|
||||
var pageIndex = highlights[i].page;
|
||||
var pageView = this.pageViews[pageIndex];
|
||||
pageView.addHighlight(highlights[i].highlight, fromTop);
|
||||
}
|
||||
},
|
||||
|
||||
clearHighlights: function() {
|
||||
for (var i = 0; i < this.pageViews.length; i++) {
|
||||
var pageView = this.pageViews[i].clearHighlights();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -663,6 +677,25 @@ PageView.prototype = {
|
|||
}
|
||||
var pdfOffset = this.viewport.convertToPdfPoint(0, canvasOffset);
|
||||
return pdfOffset[1];
|
||||
},
|
||||
|
||||
clearHighlights: function() {
|
||||
if (this.highlightsLayer) {
|
||||
this.highlightsLayer.clearHighlights();
|
||||
}
|
||||
},
|
||||
|
||||
addHighlight: function(highlight, fromTop) {
|
||||
if (this.highlightsLayer) {
|
||||
var top = highlight.top;
|
||||
var left = highlight.left;
|
||||
var width = highlight.width;
|
||||
var height = highlight.height;
|
||||
if (fromTop) {
|
||||
top = this.normalHeight - top;
|
||||
}
|
||||
this.highlightsLayer.addHighlight(left, top, width, height);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -751,6 +784,14 @@ Page.prototype = {
|
|||
);
|
||||
}
|
||||
|
||||
var highlightsLayerBuilder = pageView.listView.options.highlightsLayerBuilder;
|
||||
if (highlightsLayerBuilder) {
|
||||
var highlightsLayerDiv = pageView.highlightsLayerDiv = document.createElement("div");
|
||||
highlightsLayerDiv.className = 'plv-highlights-layer highlights-layer';
|
||||
pageView.dom.appendChild(highlightsLayerDiv);
|
||||
pageView.highlightsLayer = new highlightsLayerBuilder(pageView, highlightsLayerDiv);
|
||||
}
|
||||
|
||||
renderContext = {
|
||||
canvasContext: pageView.getCanvasContext(),
|
||||
viewport: viewport,
|
||||
|
@ -886,7 +927,15 @@ PDFListView.prototype = {
|
|||
},
|
||||
|
||||
setPdfPosition: function(pdfPosition, fromTop) {
|
||||
this.listView.setPdfPosition(pdfPosition, fromTop)
|
||||
this.listView.setPdfPosition(pdfPosition, fromTop);
|
||||
},
|
||||
|
||||
setHighlights: function(highlights, fromTop) {
|
||||
this.listView.setHighlights(highlights, fromTop);
|
||||
},
|
||||
|
||||
clearHighlights: function() {
|
||||
this.listView.clearHighlights();
|
||||
}
|
||||
};
|
||||
PDFListView.Logger = Logger;
|
||||
|
|
Loading…
Reference in a new issue