diff --git a/static/js/directives/directives.js b/static/js/directives/directives.js
index 98667aff..de78b0a8 100644
--- a/static/js/directives/directives.js
+++ b/static/js/directives/directives.js
@@ -38,7 +38,8 @@ define([
'directives/page',
'directives/contactrequest',
'directives/defaultdialog',
- 'directives/pdfviewer'], function(_, onEnter, onEscape, statusMessage, buddyList, buddyPicture, settings, chat, audioVideo, usability, audioLevel, fileInfo, screenshare, roomBar, socialShare, page, contactRequest, defaultDialog, pdfviewer) {
+ 'directives/pdfcanvas',
+ 'directives/pdfviewer'], function(_, onEnter, onEscape, statusMessage, buddyList, buddyPicture, settings, chat, audioVideo, usability, audioLevel, fileInfo, screenshare, roomBar, socialShare, page, contactRequest, defaultDialog, pdfcanvas, pdfviewer) {
var directives = {
onEnter: onEnter,
@@ -58,6 +59,7 @@ define([
page: page,
contactRequest: contactRequest,
defaultDialog: defaultDialog,
+ pdfcanvas: pdfcanvas,
pdfviewer: pdfviewer
};
diff --git a/static/js/directives/pdfcanvas.js b/static/js/directives/pdfcanvas.js
new file mode 100644
index 00000000..7028f7ad
--- /dev/null
+++ b/static/js/directives/pdfcanvas.js
@@ -0,0 +1,209 @@
+/*
+ * Spreed WebRTC.
+ * Copyright (C) 2013-2014 struktur AG
+ *
+ * This file is part of Spreed WebRTC.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+define(['require', 'underscore', 'jquery', 'pdf'], function(require, _, $, pdf) {
+
+ pdf.workerSrc = require.toUrl('pdf.worker') + ".js";
+
+ return ["$compile", function($compile) {
+
+ var controller = ['$scope', '$element', '$attrs', function($scope, $element, $attrs) {
+
+ var PDFCanvas = function(scope, scale, canvases) {
+ this.scope = scope;
+ this.canvases = canvases;
+ this.doc = null;
+ this.rendering = false;
+ this.scale = scale;
+ this.currentPage = null;
+ this.pendingPageNumber = null;
+ };
+
+ PDFCanvas.prototype.close = function() {
+ if (this.currentPage) {
+ this.currentPage.destroy();
+ this.currentPage = null;
+ }
+ if (this.doc) {
+ this.doc.cleanup();
+ this.doc.destroy();
+ this.doc = null;
+ }
+ this.rendering = false;
+ this.pendingPageNumber = null;
+ this.scope.currentPageNumber = -1;
+ this.scope.maxPageNumber = -1;
+ // clear visible canvas so it's empty when we show the next document
+ var canvas = this.canvases[this.scope.canvasIndex];
+ canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
+ this.scope.$emit("pdfClosed");
+ };
+
+ PDFCanvas.prototype.open = function(file) {
+ console.log("Loading PDF from", file);
+ if (typeof file === "string") {
+ // got a url
+ this._openFile(file);
+ return;
+ }
+
+ var fp = file.file || file;
+ if (typeof URL !== "undefined" && URL.createObjectURL) {
+ var url = URL.createObjectURL(fp);
+ this._openFile(url);
+ } else {
+ var fileReader = new FileReader();
+ fileReader.onload = _.bind(function(evt) {
+ var buffer = evt.target.result;
+ var uint8Array = new Uint8Array(buffer);
+ this._openFile(uint8Array);
+ }, this);
+ fileReader.readAsArrayBuffer(fp);
+ }
+ };
+
+ PDFCanvas.prototype._openFile = function(source) {
+ this.scope.$emit("pdfLoading", source);
+ pdf.getDocument(source).then(_.bind(function(doc) {
+ this.scope.$apply(_.bind(function(scope) {
+ this.doc = doc;
+ scope.maxPageNumber = doc.numPages;
+ scope.currentPageNumber = -1;
+ console.log("PDF loaded", doc);
+ scope.$emit("pdfLoaded", source, doc);
+ }, this));
+ }, this));
+ };
+
+ PDFCanvas.prototype._showPage = function(page) {
+ console.log("Showing page", page, "/", this.scope.maxPageNumber);
+ if (this.currentPage) {
+ this.currentPage.destroy();
+ this.currentPage = null;
+ }
+ this.rendering = true;
+ this.scope.currentPageNumber = page;
+ this.scope.$emit("pdfPageLoading", page);
+ this.doc.getPage(page).then(_.bind(function(pageObject) {
+ console.log("Got page", pageObject);
+ this.scope.$emit("pdfPageLoaded", page, pageObject);
+ this.currentPage = pageObject;
+ var viewport = pageObject.getViewport(this.scale);
+ // use double-buffering to avoid flickering while
+ // the new page is rendered...
+ var canvas = this.canvases[1 - this.scope.canvasIndex];
+ canvas.width = viewport.width;
+ canvas.height = viewport.height;
+ var renderContext = {
+ canvasContext: canvas.getContext("2d"),
+ viewport: viewport
+ };
+
+ console.log("Rendering page", pageObject);
+ this.scope.$emit("pdfPageRendering", page);
+ // TODO(fancycode): also render images in different resolutions for subscribed peers and send to them when ready
+ var renderTask = pageObject.render(renderContext);
+ renderTask.promise.then(_.bind(function() {
+ this.scope.$apply(_.bind(function(scope) {
+ console.log("Rendered page", page);
+ this.scope.$emit("pdfPageRendered", page, scope.maxPageNumber);
+ this.rendering = false;
+ // ...and flip the buffers...
+ scope.canvasIndex = 1 - scope.canvasIndex;
+ this.showQueuedPage();
+ }, this));
+ }, this));
+ }, this));
+ };
+
+ PDFCanvas.prototype.showPage = function(page) {
+ if (page >= 1 && page <= this.scope.maxPageNumber) {
+ if (!this.doc || this.rendering) {
+ this.pendingPageNumber = page;
+ } else {
+ this._showPage(page);
+ }
+ }
+ };
+
+ PDFCanvas.prototype.prevPage = function() {
+ this.showPage(this.scope.currentPageNumber - 1);
+ };
+
+ PDFCanvas.prototype.nextPage = function() {
+ this.showPage(this.scope.currentPageNumber + 1);
+ };
+
+ PDFCanvas.prototype.showQueuedPage = function() {
+ if (this.pendingPageNumber !== null) {
+ this._showPage(this.pendingPageNumber);
+ this.pendingPageNumber = null;
+ }
+ };
+
+ $scope.currentPageNumber = -1;
+ $scope.maxPageNumber = -1;
+ $scope.canvasIndex = 0;
+
+ var canvases = $element.find("canvas");
+ var scale = 0.8;
+ var pdfCanvas = new PDFCanvas($scope, scale, canvases);
+
+ $scope.$on("openPdf", function(event, source) {
+ pdfCanvas.open(source);
+ });
+
+ $scope.$on("closePdf", function() {
+ pdfCanvas.close();
+ });
+
+ $scope.$on("$destroy", function() {
+ pdfCanvas.close();
+ pdfCanvas = null;
+ });
+
+ $scope.$on("showPdfPage", function(event, page) {
+ pdfCanvas.showPage(page);
+ });
+
+ $scope.$on("showQueuedPdfPage", function() {
+ pdfCanvas.showQueuedPage();
+ });
+
+ $scope.prevPage = function() {
+ pdfCanvas.prevPage();
+ };
+
+ $scope.nextPage = function() {
+ pdfCanvas.nextPage();
+ };
+
+ }];
+
+ return {
+ restrict: 'E',
+ replace: true,
+ template: '',
+ controller: controller
+ };
+
+ }];
+
+});
diff --git a/static/js/directives/pdfviewer.js b/static/js/directives/pdfviewer.js
index cf1ed855..52742d25 100644
--- a/static/js/directives/pdfviewer.js
+++ b/static/js/directives/pdfviewer.js
@@ -18,9 +18,7 @@
* along with this program. If not, see .
*
*/
-define(['require', 'jquery', 'underscore', 'text!partials/pdfviewer.html', 'pdf'], function(require, $, _, template, pdf) {
-
- pdf.workerSrc = require.toUrl('pdf.worker') + ".js";
+define(['jquery', 'underscore', 'text!partials/pdfviewer.html'], function($, _, template) {
return ["$window", "mediaStream", "fileUpload", "fileDownload", "alertify", "translation", "randomGen", function($window, mediaStream, fileUpload, fileDownload, alertify, translation, randomGen) {
@@ -28,20 +26,18 @@ define(['require', 'jquery', 'underscore', 'text!partials/pdfviewer.html', 'pdf'
var pdfViewerCount = 0;
var pane = $element.find(".pdfviewerpane");
- var canvases = $element.find(".pdfviewercanvas");
- $scope.canvasIndex = 0;
$scope.layout.pdfviewer = false;
$scope.isPresenter = false;
$scope.hideControlsBar = false;
- $scope.doc = null;
- $scope.rendering = false;
- $scope.scale = 0.8;
- $scope.currentPage = null;
- $scope.currentPageNumber = -1;
- $scope.maxPageNumber = -1;
- $scope.pendingPageNumber = null;
+ $scope.$on("pdfLoaded", function(event, source, doc) {
+ if ($scope.isPresenter) {
+ $scope.$emit("showPdfPage", 1);
+ } else {
+ $scope.$emit("showQueuedPdfPage");
+ }
+ });
var handleRequest = function(event, currenttoken, to, data, type, to2, from, peerpdfviewer) {
console.log("PdfViewer answer message", currenttoken, data, type);
@@ -71,10 +67,10 @@ define(['require', 'jquery', 'underscore', 'text!partials/pdfviewer.html', 'pdf'
subscope.$on("writeComplete", function(event, url, fileInfo) {
event.stopPropagation();
if (url.indexOf("blob:") === 0) {
- $scope.doOpenFile(url);
+ $scope.$emit("openPdf", url);
} else {
fileInfo.file.file(function(fp) {
- $scope.openFile(fp);
+ $scope.$emit("openPdf", fp);
});
}
});
@@ -86,7 +82,7 @@ define(['require', 'jquery', 'underscore', 'text!partials/pdfviewer.html', 'pdf'
break;
case "Page":
- $scope.$emit("queuePageRendering", data.Page);
+ $scope.$emit("showPdfPage", data.Page);
break;
default:
@@ -95,104 +91,6 @@ define(['require', 'jquery', 'underscore', 'text!partials/pdfviewer.html', 'pdf'
}
});
- $scope.showPage = function(page) {
- console.log("Showing page", page, "/", $scope.maxPageNumber);
- if ($scope.currentPage) {
- $scope.currentPage.destroy();
- $scope.currentPage = null;
- }
- $scope.rendering = true;
- $scope.currentPageNumber = page;
- $scope.doc.getPage(page).then(function(page) {
- console.log("Got page", page);
- $scope.currentPage = page;
- var viewport = page.getViewport($scope.scale);
- // use double-buffering to avoid flickering while
- // the new page is rendered...
- var canvas = canvases[1 - $scope.canvasIndex];
- canvas.width = viewport.width;
- canvas.height = viewport.height;
- var renderContext = {
- canvasContext: canvas.getContext("2d"),
- viewport: viewport
- };
-
- console.log("Rendering page", page);
- // TODO(fancycode): also render images in different resolutions for subscribed peers and send to them when ready
- var renderTask = page.render(renderContext);
- renderTask.promise.then(function() {
- $scope.$apply(function(scope) {
- console.log("Rendered page", page);
- scope.rendering = false;
- // ...and flip the buffers...
- scope.canvasIndex = 1 - scope.canvasIndex;
- console.log("Done");
- scope.showQueuedPage();
- });
- });
- });
- };
-
- $scope.$on("queuePageRendering", function(event, page) {
- if (!$scope.doc || $scope.rendering) {
- $scope.pendingPageNumber = page;
- } else {
- $scope.showPage(page);
- }
- });
-
- $scope.prevPage = function() {
- if ($scope.currentPageNumber > 1) {
- $scope.$emit("queuePageRendering", $scope.currentPageNumber - 1);
- }
- };
-
- $scope.nextPage = function() {
- if ($scope.currentPageNumber < $scope.maxPageNumber) {
- $scope.$emit("queuePageRendering", $scope.currentPageNumber + 1);
- }
- };
-
- $scope.showQueuedPage = function() {
- if ($scope.pendingPageNumber !== null) {
- $scope.showPage($scope.pendingPageNumber);
- $scope.pendingPageNumber = null;
- }
- };
-
- $scope.doOpenFile = function(source) {
- pdf.getDocument(source).then(function(doc) {
- $scope.$apply(function(scope) {
- scope.doc = doc;
- scope.maxPageNumber = doc.numPages;
- scope.currentPageNumber = -1;
- console.log("PDF loaded", doc);
- if ($scope.isPresenter) {
- scope.$emit("queuePageRendering", 1);
- } else {
- scope.showQueuedPage();
- }
- });
- });
- };
-
- $scope.openFile = function(file) {
- console.log("Loading PDF from", file);
- var fp = file.file || file;
- if (typeof URL !== "undefined" && URL.createObjectURL) {
- var url = URL.createObjectURL(fp);
- $scope.doOpenFile(url);
- } else {
- var fileReader = new FileReader();
- fileReader.onload = function webViewerChangeFileReaderOnload(evt) {
- var buffer = evt.target.result;
- var uint8Array = new Uint8Array(buffer);
- $scope.doOpenFile(uint8Array);
- };
- fileReader.readAsArrayBuffer(fp);
- }
- };
-
$scope.showPDFViewer = function() {
console.log("PDF viewer active");
if ($scope.layout.pdfviewer) {
@@ -257,7 +155,7 @@ define(['require', 'jquery', 'underscore', 'text!partials/pdfviewer.html', 'pdf'
// Catch later calls too.
mediaStream.webrtc.e.on("statechange", updater);
- $scope.$on("queuePageRendering", function(event, page) {
+ $scope.$on("pdfPageLoading", function(event, page) {
_.each(peers, function(ignore, peerId) {
var peercall = mediaStream.webrtc.findTargetCall(peerId);
mediaStream.api.apply("sendPdfViewer", {
@@ -311,7 +209,7 @@ define(['require', 'jquery', 'underscore', 'text!partials/pdfviewer.html', 'pdf'
session.handleRequest(subscope, xfer, data);
}, "xfer");
$scope.isPresenter = true;
- $scope.openFile(f);
+ $scope.$emit("openPdf", f);
}, this));
}, this));
binder.namespace = function() {
@@ -323,14 +221,7 @@ define(['require', 'jquery', 'underscore', 'text!partials/pdfviewer.html', 'pdf'
$scope.hidePDFViewer = function() {
console.log("PDF viewer disabled");
- if ($scope.doc) {
- $scope.doc.cleanup();
- $scope.doc.destroy();
- $scope.doc = null;
- }
- // clear visible canvas so it's empty when we show the next document
- var canvas = canvases[$scope.canvasIndex];
- canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
+ $scope.$emit("closePdf");
$scope.layout.pdfviewer = false;
$scope.isPresenter = false;
$scope.$emit("mainview", "pdfviewer", false);
diff --git a/static/partials/pdfviewer.html b/static/partials/pdfviewer.html
index f2545169..81ec03bf 100644
--- a/static/partials/pdfviewer.html
+++ b/static/partials/pdfviewer.html
@@ -1,7 +1,6 @@