/* * Spreed WebRTC. * Copyright (C) 2013-2015 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 . * */ "use strict"; define(['require', 'underscore', 'jquery'], function(require, _, $) { return ["$window", "$compile", "$http", "translation", "safeApply", "restURL", "sandbox", function($window, $compile, $http, translation, safeApply, restURL, sandbox) { var DOCUMENT_TYPE_PRESENTATION = "presentation"; var DOCUMENT_TYPE_SPREADSHEET = "spreadsheet"; var DOCUMENT_TYPE_TEXT = "text"; var controller = ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { var container = $($element); var odfCanvas; var url = restURL.sandbox("odfcanvas"); var sandboxApi = sandbox.createSandbox(container, null, url, "allow-scripts", null, { allowfullscreen: true, mozallowfullscreen: true, webkitallowfullscreen: true }); sandboxApi.e.on("message", function(event, message) { var msg = message.data; var data = msg[msg.type] || {}; switch (msg.type) { case "ready": break; case "webodf.loading": $scope.$apply(function(scope) { scope.$emit("presentationLoading", data.source); container.hide(); }); break; case "webodf.loaded": odfCanvas._odfLoaded(data.url, data.type, data.numPages); break; case "webodf.keyUp": $scope.$apply(function(scope) { scope.$emit("keyUp", data.key); }); break; default: console.log("Unknown message received", message); break; } }); var ODFCanvas = function(scope, container) { this.scope = scope; this.container = container; this.doc = null; this.maxPageNumber = -1; this.currentPageNumber = -1; this.pendingPageNumber = null; }; ODFCanvas.prototype.close = function() { sandboxApi.postMessage("closeFile", {"close": true}); this.maxPageNumber = -1; this.currentPageNumber = -1; this.pendingPageNumber = null; this.doc = null; }; ODFCanvas.prototype.open = function(presentation) { this.scope.$emit("presentationOpening", presentation); presentation.open(_.bind(function(source) { console.log("Loading ODF from", source); this.close(); if (typeof source === "string") { // got a url this._openFile(source); return; } var fp = source.file || source; if (typeof URL !== "undefined" && URL.createObjectURL) { this.url = URL.createObjectURL(fp); this._openFile(this.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); } }, this)); }; ODFCanvas.prototype._odfLoaded = function(url, document_type, numPages) { this.scope.$apply(_.bind(function(scope) { this.document_type = document_type; switch (document_type) { case DOCUMENT_TYPE_PRESENTATION: this.container.addClass("showonepage"); break; default: this.container.removeClass("showonepage"); break; } this.maxPageNumber = numPages; this.currentPageNumber = -1; this.doc = { numPages: this.maxPageNumber }; scope.$emit("presentationLoaded", url, this.doc); if (this.pendingPageNumber !== null) { this._showPage(this.pendingPageNumber); this.pendingPageNumber = null; } }, this)); }; ODFCanvas.prototype._openFile = function(source) { if (typeof(source) === "string") { // we can't load urls from inside the sandbox, do so here and transmit the contents $http.get(source, { responseType: "arraybuffer" }).then(_.bind(function(response) { this._openFile(response.data); }, this)); return; } console.log("Opening file", source); sandboxApi.postMessage("openFile", {"source": source}); }; ODFCanvas.prototype._showPage = function(page) { if (page === this.currentPageNumber) { return; } console.log("Showing page", page, "/", this.maxPageNumber); this.scope.$emit("presentationPageLoading", page); this.scope.$emit("presentationPageLoaded", page, null); // actual rendering of first page must happen after the // previously hidden DOM elements are visible again to // make initial scaling work, so defer it _.defer(_.bind(function() { this.scope.$apply(_.bind(function() { if (this.currentPageNumber === -1) { this.container.show(); this.redrawPage(); } this.currentPageNumber = page; sandboxApi.postMessage("showPage", {"page": page}); this.scope.$emit("presentationPageRendering", page); this.scope.$emit("presentationPageRendered", page, this.maxPageNumber); }, this)); }, this)); }; ODFCanvas.prototype.redrawPage = function() { sandboxApi.postMessage("redrawPage", {"redraw": true}); }; ODFCanvas.prototype.showPage = function(page) { if (page >= 1 && page <= this.maxPageNumber) { if (!this.doc) { this.pendingPageNumber = page; } else { this._showPage(page); } } }; odfCanvas = new ODFCanvas($scope, container); $scope.$watch("currentPresentation", function(presentation, previousPresentation) { if (presentation) { safeApply($scope, function(scope) { odfCanvas.open(presentation); }); } else { if (previousPresentation) { previousPresentation.close(); } odfCanvas.close(); } }); $scope.$on("$destroy", function() { odfCanvas.close(); odfCanvas = null; sandboxApi.destroy(); }); $scope.$watch("currentPageNumber", function(page, oldValue) { if (page === oldValue) { // no change return; } odfCanvas.showPage(page); }); $($window).on("resize", function() { $scope.$apply(function(scope) { odfCanvas.redrawPage(); }); }); }]; return { restrict: 'E', replace: true, template: '
', controller: controller }; }]; });