mirror of
https://github.com/overleaf/overleaf.git
synced 2024-09-16 02:52:31 -04: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)
|
Backbone.View::undelegateEvents.apply(this, arguments)
|
||||||
@pdfView.undelegateEvents()
|
@pdfView.undelegateEvents()
|
||||||
|
|
||||||
setPdfPosition: (args...) ->
|
highlightInPdf: (args...) ->
|
||||||
@pdfView.setPdfPosition?(args...)
|
@pdfView.highlightInPdf?(args...)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,18 @@ define [
|
||||||
"libs/pdfListView/PdfListView"
|
"libs/pdfListView/PdfListView"
|
||||||
"libs/pdfListView/TextLayerBuilder"
|
"libs/pdfListView/TextLayerBuilder"
|
||||||
"libs/pdfListView/AnnotationsLayerBuilder"
|
"libs/pdfListView/AnnotationsLayerBuilder"
|
||||||
|
"libs/pdfListView/HighlightsLayerBuilder"
|
||||||
"text!libs/pdfListView/TextLayer.css"
|
"text!libs/pdfListView/TextLayer.css"
|
||||||
"text!libs/pdfListView/AnnotationsLayer.css"
|
"text!libs/pdfListView/AnnotationsLayer.css"
|
||||||
|
"text!libs/pdfListView/HighlightsLayer.css"
|
||||||
"libs/backbone"
|
"libs/backbone"
|
||||||
"libs/jquery.storage"
|
"libs/jquery.storage"
|
||||||
], (PDFListView, TextLayerBuilder, AnnotationsLayerBuilder, textLayerCss, annotationsLayerCss) ->
|
], (PDFListView, TextLayerBuilder, AnnotationsLayerBuilder, HighlightsLayerBuilder, textLayerCss, annotationsLayerCss, highlightsLayerCss) ->
|
||||||
if PDFJS?
|
if PDFJS?
|
||||||
PDFJS.workerSrc = "#{window.sharelatex.pdfJsWorkerPath}"
|
PDFJS.workerSrc = "#{window.sharelatex.pdfJsWorkerPath}"
|
||||||
|
|
||||||
style = $("<style/>")
|
style = $("<style/>")
|
||||||
style.text(textLayerCss + "\n" + annotationsLayerCss)
|
style.text(textLayerCss + "\n" + annotationsLayerCss + "\n" + highlightsLayerCss)
|
||||||
$("body").append(style)
|
$("body").append(style)
|
||||||
|
|
||||||
PDFjsView = Backbone.View.extend
|
PDFjsView = Backbone.View.extend
|
||||||
|
@ -33,6 +35,7 @@ define [
|
||||||
@pdfListView = new PDFListView @$(".pdfjs-list-view")[0],
|
@pdfListView = new PDFListView @$(".pdfjs-list-view")[0],
|
||||||
textLayerBuilder: TextLayerBuilder
|
textLayerBuilder: TextLayerBuilder
|
||||||
annotationsLayerBuilder: AnnotationsLayerBuilder
|
annotationsLayerBuilder: AnnotationsLayerBuilder
|
||||||
|
highlightsLayerBuilder: HighlightsLayerBuilder
|
||||||
ondblclick: (e) =>
|
ondblclick: (e) =>
|
||||||
@trigger "dblclick", e
|
@trigger "dblclick", e
|
||||||
#logLevel: PDFListView.Logger.DEBUG
|
#logLevel: PDFListView.Logger.DEBUG
|
||||||
|
@ -123,11 +126,35 @@ define [
|
||||||
onResize: () ->
|
onResize: () ->
|
||||||
@pdfListView.onResize()
|
@pdfListView.onResize()
|
||||||
|
|
||||||
setPdfPosition: (page, top, left) ->
|
highlightInPdf: (areas) ->
|
||||||
@pdfListView.setPdfPosition({
|
highlights = for area in (areas or [])
|
||||||
page: page
|
{
|
||||||
offset:
|
page: area.page - 1
|
||||||
left: left
|
highlight:
|
||||||
top: top
|
left: area.h
|
||||||
}, true)
|
top: area.v
|
||||||
|
height: area.height
|
||||||
|
width: area.width
|
||||||
|
}
|
||||||
|
|
||||||
|
if highlights.length > 0
|
||||||
|
first = highlights[0]
|
||||||
|
@pdfListView.setPdfPosition({
|
||||||
|
page: first.page
|
||||||
|
offset:
|
||||||
|
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"
|
type: "GET"
|
||||||
success: (response) =>
|
success: (response) =>
|
||||||
data = JSON.parse(response)
|
data = JSON.parse(response)
|
||||||
if data.pdf and data.pdf.length > 0
|
@view.highlightInPdf(data.pdf or [])
|
||||||
page = data.pdf[0].page - 1
|
|
||||||
h = data.pdf[0].h
|
|
||||||
v = data.pdf[0].v
|
|
||||||
@view.setPdfPosition page, v - 100, h
|
|
||||||
}
|
}
|
||||||
|
|
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);
|
var position = pageView.getPdfPositionInViewer(offset.left, offset.top);
|
||||||
this.dom.scrollTop = position.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);
|
var pdfOffset = this.viewport.convertToPdfPoint(0, canvasOffset);
|
||||||
return pdfOffset[1];
|
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 = {
|
renderContext = {
|
||||||
canvasContext: pageView.getCanvasContext(),
|
canvasContext: pageView.getCanvasContext(),
|
||||||
viewport: viewport,
|
viewport: viewport,
|
||||||
|
@ -886,7 +927,15 @@ PDFListView.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
setPdfPosition: function(pdfPosition, fromTop) {
|
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;
|
PDFListView.Logger = Logger;
|
||||||
|
|
Loading…
Reference in a new issue