Merge branch 'master' of github.com:sharelatex/web-sharelatex

This commit is contained in:
Henry Oswald 2014-04-08 20:52:06 +01:00
commit 811859a4a1
10 changed files with 246 additions and 6 deletions

View file

@ -35,6 +35,9 @@ module.exports = CompileController =
getFileFromClsi: (req, res, next = (error) ->) ->
CompileController.proxyToClsi("/project/#{req.params.Project_id}/output/#{req.params.file}", req, res, next)
proxySync: (req, res, next = (error) ->) ->
CompileController.proxyToClsi(req.url, req, res, next)
proxyToClsi: (url, req, res, next = (error) ->) ->
logger.log url: url, "proxying to CLSI"
url = "#{Settings.apis.clsi.url}#{url}"

View file

@ -109,6 +109,9 @@ module.exports = class Router
next()
), SecurityManager.requestCanAccessProject, CompileController.getFileFromClsi
app.del "/project/:Project_id/output", SecurityManager.requestCanAccessProject, CompileController.deleteAuxFiles
app.get "/project/:Project_id/sync/code", SecurityManager.requestCanAccessProject, CompileController.proxySync
app.get "/project/:Project_id/sync/pdf", SecurityManager.requestCanAccessProject, CompileController.proxySync
app.del '/Project/:Project_id', SecurityManager.requestIsOwner, ProjectController.deleteProject
app.post '/Project/:Project_id/clone', SecurityManager.requestCanAccessProject, ProjectController.cloneProject

View file

@ -304,6 +304,12 @@ define [
gotoLine: (line) ->
@aceEditor.gotoLine(line)
getCurrentLine: () ->
@aceEditor.selection?.getCursor()?.row
getCurrentColumn: () ->
@aceEditor.selection?.getCursor()?.column
getLines: (from, to) ->
if from? and to?
@getSession().doc.getLines(from, to)

View file

@ -64,6 +64,7 @@ define [
PdfView = PdfjsView
@pdfjs = true
@pdfView = new PdfView(manager: @)
@pdfView.on "dblclick", (e) => @trigger "dblclick", e
render: () ->
@setElement(@templates.pdfPanel)
@ -214,4 +215,7 @@ define [
Backbone.View::undelegateEvents.apply(this, arguments)
@pdfView.undelegateEvents()
highlightInPdf: (args...) ->
@pdfView.highlightInPdf?(args...)

View file

@ -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,9 @@ define [
@pdfListView = new PDFListView @$(".pdfjs-list-view")[0],
textLayerBuilder: TextLayerBuilder
annotationsLayerBuilder: AnnotationsLayerBuilder
highlightsLayerBuilder: HighlightsLayerBuilder
ondblclick: (e) =>
@trigger "dblclick", e
#logLevel: PDFListView.Logger.DEBUG
@pdfListView.listView.pageWidthOffset = 20
@pdfListView.listView.pageHeightOffset = 20
@ -121,3 +126,35 @@ define [
onResize: () ->
@pdfListView.onResize()
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

View file

@ -24,6 +24,7 @@ define [
createPdfPanel: () ->
@view = new CompiledView manager: @, ide: @ide
@view.on "dblclick", (e) => @syncToCode(e)
@view.render()
if $.localStorage("layout.pdf") == "flat"
@switchToFlatView()
@ -210,3 +211,37 @@ define [
})
}]
syncToCode: (e) ->
$.ajax {
url: "/project/#{@ide.project_id}/sync/pdf"
data:
page: e.page + 1
h: e.x.toFixed(2)
v: e.y.toFixed(2)
type: "GET"
success: (response) =>
data = JSON.parse(response)
if data.code and data.code.length > 0
file = data.code[0].file
line = data.code[0].line
@ide.fileTreeManager.openDocByPath(file, line)
}
syncToPdf: () ->
entity_id = @ide.editor.getCurrentDocId()
file = @ide.fileTreeManager.getPathOfEntityId(entity_id)
line = @ide.editor.getCurrentLine()
column = @ide.editor.getCurrentColumn()
$.ajax {
url: "/project/#{@ide.project_id}/sync/code"
data:
file: file
line: line + 1
column: column
type: "GET"
success: (response) =>
data = JSON.parse(response)
@view.highlightInPdf(data.pdf or [])
}

View 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;
}

View file

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

View file

@ -215,6 +215,16 @@ ListView.prototype = {
// per pageContainer.
this.pdfDoc.pages.map(function(page) {
var pageView = new PageView(page, this);
// TODO: Switch over to a proper event handler
var that = this;
var index = that.pageViews.length;
pageView.ondblclick = function(e) {
e.page = index;
if (that.ondblclick) {
that.ondblclick.call(that, e);
}
}
this.pageViews.push(pageView);
var container = new PageContainerView(this);
@ -378,14 +388,31 @@ ListView.prototype = {
return pdfPosition;
},
setPdfPosition: function(pdfPosition) {
setPdfPosition: function(pdfPosition, fromTop) {
if (typeof pdfPosition !== "undefined" && pdfPosition != null) {
var offset = pdfPosition.offset;
var page_index = pdfPosition.page;
var pageView = this.pageViews[page_index];
if (fromTop) {
offset.top = pageView.normalHeight - offset.top;
}
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();
}
}
};
@ -462,6 +489,27 @@ function PageView(page, listView) {
var dom = this.dom = document.createElement('div');
dom.className = "plv-page-view page-view";
var that = this;
dom.ondblclick = function(e) {
var layerX = e.layerX;
var layerY = e.layerY;
var element = e.target;
while (element.offsetParent && element.offsetParent !== dom) {
layerX = layerX + element.offsetLeft;
layerY = layerY + element.offsetTop;
element = element.offsetParent;
}
var pdfPoint = that.viewport.convertToPdfPoint(layerX, layerY);
var event = {
x: pdfPoint[0],
y: that.normalHeight - pdfPoint[1]
};
if (that.ondblclick) {
that.ondblclick.call(that.listView, event)
}
}
this.createNewCanvas();
}
@ -560,6 +608,7 @@ PageView.prototype = {
scaled: pixelRatio != 1
};
},
createNewCanvas: function() {
if (this.canvas) {
this.dom.removeChild(this.canvas);
@ -628,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);
}
}
};
@ -716,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,
@ -766,13 +842,19 @@ function PDFListView(mainDiv, options) {
}
logger.logLevel = options.logLevel;
var self = this;
this.listView = new ListView(mainDiv, options);
this.listView.ondblclick = function(e) {
if (options.ondblclick) {
options.ondblclick.call(self, e);
}
}
this.renderController = new RenderController();
this.renderController.addListView(this.listView);
this.renderController.updateRenderList();
var self = this;
mainDiv.addEventListener('scroll', function() {
// This will update the list AND start rendering if needed.
@ -844,8 +926,16 @@ PDFListView.prototype = {
return this.listView.getPdfPosition();
},
setPdfPosition: function(pdfPosition) {
this.listView.setPdfPosition(pdfPosition)
setPdfPosition: function(pdfPosition, fromTop) {
this.listView.setPdfPosition(pdfPosition, fromTop);
},
setHighlights: function(highlights, fromTop) {
this.listView.setHighlights(highlights, fromTop);
},
clearHighlights: function() {
this.listView.clearHighlights();
}
};
PDFListView.Logger = Logger;

View file

@ -84,6 +84,13 @@ TextLayerBuilder.prototype = {
textDiv.style.left = geom.x + 'px';
textDiv.style.top = (geom.y - fontHeight) + 'px';
textDiv.ondblclick = function(e) {
if (window.getSelection)
window.getSelection().removeAllRanges();
else if (document.selection)
document.selection.empty();
}
// The content of the div is set in the `setTextContent` function.
this.textDivs.push(textDiv);