Просмотр исходного кода

Add highlighting when syncing from code to pdf

James Allen 12 лет назад
Родитель
Сommit
ef7a3788b4

+ 2 - 2
services/web/public/coffee/pdf/CompiledView.coffee

@@ -215,7 +215,7 @@ define [
 			Backbone.View::undelegateEvents.apply(this, arguments)
 			@pdfView.undelegateEvents()
 
-		setPdfPosition: (args...) ->
-			@pdfView.setPdfPosition?(args...)
+		highlightInPdf: (args...) ->
+			@pdfView.highlightInPdf?(args...)
 
 			

+ 36 - 9
services/web/public/coffee/pdf/PDFjsView.coffee

@@ -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) ->
-			@pdfListView.setPdfPosition({
-				page: page
-				offset:
-					left: left
-					top: top
-			}, true)
+		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: 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
+
+
+
+			
 

+ 1 - 5
services/web/public/coffee/pdf/PdfManager.coffee

@@ -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 - 0
services/web/public/js/libs/pdfListView/HighlightsLayer.css

@@ -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;
+}

+ 39 - 0
services/web/public/js/libs/pdfListView/HighlightsLayerBuilder.js

@@ -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;
+
+});

+ 50 - 1
services/web/public/js/libs/pdfListView/PdfListView.js

@@ -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;