diff options
Diffstat (limited to 'lib/viewers/odf/viewer')
15 files changed, 1039 insertions, 0 deletions
diff --git a/lib/viewers/odf/viewer/ODFViewerPlugin.js b/lib/viewers/odf/viewer/ODFViewerPlugin.js new file mode 100644 index 0000000..0b1808f --- /dev/null +++ b/lib/viewers/odf/viewer/ODFViewerPlugin.js @@ -0,0 +1,162 @@ +/** + * @license + * Copyright (C) 2012 KO GmbH <copyright@kogmbh.com> + * + * @licstart + * The JavaScript code in this page is free software: you can redistribute it + * and/or modify it under the terms of the GNU Affero General Public License + * (GNU AGPL) as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. The code is distributed + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this code. If not, see <http://www.gnu.org/licenses/>. + * + * As additional permission under GNU AGPL version 3 section 7, you + * may distribute non-source (e.g., minimized or compacted) forms of + * that code without the copy of the GNU GPL normally required by + * section 4, provided you include this license notice and a URL + * through which recipients can access the Corresponding Source. + * + * As a special exception to the AGPL, any HTML file which merely makes function + * calls to this code, and for that purpose includes it by reference shall be + * deemed a separate work for copyright law purposes. In addition, the copyright + * holders of this code give you permission to combine this code with free + * software libraries that are released under the GNU LGPL. You may copy and + * distribute such a system following the terms of the GNU AGPL for this code + * and the LGPL for the libraries. If you modify this code, you may extend this + * exception to your version of the code, but you are not obligated to do so. + * If you do not wish to do so, delete this exception statement from your + * version. + * + * This license applies to this entire compilation. + * @licend + * @source: http://www.webodf.org/ + * @source: https://github.com/kogmbh/WebODF/ + */ + +/*global runtime, document, odf, console*/ + +function ODFViewerPlugin() { + "use strict"; + + function init(callback) { + var lib = document.createElement('script'); + lib.async = false; + lib.src = './webodf.js'; + lib.type = 'text/javascript'; + lib.onload = function () { + runtime.currentDirectory = function () { + return "../../webodf/lib"; + }; + runtime.libraryPaths = function () { + return [ runtime.currentDirectory() ]; + }; + + runtime.loadClass('odf.OdfCanvas'); + callback(); + }; + + document.getElementsByTagName('head')[0].appendChild(lib); + } + + // that should probably be provided by webodf + function nsResolver(prefix) { + var ns = { + 'draw' : "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0", + 'presentation' : "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0", + 'text' : "urn:oasis:names:tc:opendocument:xmlns:text:1.0", + 'office' : "urn:oasis:names:tc:opendocument:xmlns:office:1.0" + }; + return ns[prefix] || console.log('prefix [' + prefix + '] unknown.'); + } + + var self = this, + odfCanvas = null, + odfElement = null, + initialized = false, + root = null, + documentType = null, + pages = [], + currentPage = null; + + this.initialize = function (viewerElement, documentUrl) { + // If the URL has a fragment (#...), try to load the file it represents + init(function () { + odfElement = document.getElementById('canvas'); + odfCanvas = new odf.OdfCanvas(odfElement); + odfCanvas.load(documentUrl); + + odfCanvas.addListener('statereadychange', function () { + root = odfCanvas.odfContainer().rootElement; + initialized = true; + documentType = odfCanvas.odfContainer().getDocumentType(root); + if (documentType === 'text') { + odfCanvas.enableAnnotations(true); + } + self.onLoad(); + }); + }); + }; + + this.isSlideshow = function () { + return documentType === 'presentation'; + }; + + this.onLoad = function () {}; + + this.getWidth = function () { + return odfElement.clientWidth; + }; + + this.getHeight = function () { + return odfElement.clientHeight; + }; + + this.fitToWidth = function (width) { + odfCanvas.fitToWidth(width); + }; + + this.fitToHeight = function (height) { + odfCanvas.fitToHeight(height); + }; + + this.fitToPage = function (width, height) { + odfCanvas.fitToContainingElement(width, height); + }; + + this.fitSmart = function (width) { + odfCanvas.fitSmart(width); + }; + + this.getZoomLevel = function () { + return odfCanvas.getZoomLevel(); + }; + + this.setZoomLevel = function (value) { + odfCanvas.setZoomLevel(value); + }; + + // return a list of tuples (pagename, pagenode) + this.getPages = function () { + var pageNodes = Array.prototype.slice.call(root.getElementsByTagNameNS(nsResolver('draw'), 'page')), + pages = [], + i, + tuple; + + for (i = 0; i < pageNodes.length; i += 1) { + tuple = [ + pageNodes[i].getAttribute('draw:name'), + pageNodes[i] + ]; + pages.push(tuple); + } + return pages; + }; + + this.showPage = function (n) { + odfCanvas.showPage(n); + }; + +} diff --git a/lib/viewers/odf/viewer/PluginLoader.js b/lib/viewers/odf/viewer/PluginLoader.js new file mode 100644 index 0000000..23fede5 --- /dev/null +++ b/lib/viewers/odf/viewer/PluginLoader.js @@ -0,0 +1,80 @@ +/** + * @license + * Copyright (C) 2012 KO GmbH <copyright@kogmbh.com> + * + * @licstart + * The JavaScript code in this page is free software: you can redistribute it + * and/or modify it under the terms of the GNU Affero General Public License + * (GNU AGPL) as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. The code is distributed + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this code. If not, see <http://www.gnu.org/licenses/>. + * + * As additional permission under GNU AGPL version 3 section 7, you + * may distribute non-source (e.g., minimized or compacted) forms of + * that code without the copy of the GNU GPL normally required by + * section 4, provided you include this license notice and a URL + * through which recipients can access the Corresponding Source. + * + * As a special exception to the AGPL, any HTML file which merely makes function + * calls to this code, and for that purpose includes it by reference shall be + * deemed a separate work for copyright law purposes. In addition, the copyright + * holders of this code give you permission to combine this code with free + * software libraries that are released under the GNU LGPL. You may copy and + * distribute such a system following the terms of the GNU AGPL for this code + * and the LGPL for the libraries. If you modify this code, you may extend this + * exception to your version of the code, but you are not obligated to do so. + * If you do not wish to do so, delete this exception statement from your + * version. + * + * This license applies to this entire compilation. + * @licend + * @source: http://www.webodf.org/ + * @source: https://github.com/kogmbh/WebODF/ + */ + +/*global document, window, Viewer, ODFViewerPlugin*/ + +var viewer; + +function loadPlugin(pluginName, callback) { + "use strict"; + var script, style; + + // Load script + script = document.createElement('script'); + script.async = false; + script.onload = callback; + script.src = pluginName + '.js'; + script.type = 'text/javascript'; + document.getElementsByTagName('head')[0].appendChild(script); +} + +function loadDocument(documentUrl) { + "use strict"; + + if (documentUrl) { + var extension = documentUrl.split('.').pop(), + Plugin; + + switch (extension) { + case 'odt': + case 'odp': + case 'ods': + case 'fodt': + loadPlugin('./ODFViewerPlugin', function () { + Plugin = ODFViewerPlugin; + }); + break; + } + + window.onload = function () { + if (Plugin) { + viewer = new Viewer(new Plugin()); + } + }; + } +} diff --git a/lib/viewers/odf/viewer/example.local.css b/lib/viewers/odf/viewer/example.local.css new file mode 100644 index 0000000..e5e03b7 --- /dev/null +++ b/lib/viewers/odf/viewer/example.local.css @@ -0,0 +1,27 @@ +/* This is just a sample file with CSS rules. You should write your own @font-face declarations + * to add support for your desired fonts. + */ + +@font-face { + font-family: 'Novecentowide Book'; + src: url("/Viewer.js/fonts/Novecentowide-Bold-webfont.eot"); + src: url("/Viewer.js/fonts/Novecentowide-Bold-webfont.eot?#iefix") format("embedded-opentype"), + url("/Viewer.js/fonts/Novecentowide-Bold-webfont.woff") format("woff"), + url("/fonts/Novecentowide-Bold-webfont.ttf") format("truetype"), + url("/fonts/Novecentowide-Bold-webfont.svg#NovecentowideBookBold") format("svg"); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: 'exotica'; + src: url('/Viewer.js/fonts/Exotica-webfont.eot'); + src: url('/Viewer.js/fonts/Exotica-webfont.eot?#iefix') format('embedded-opentype'), + url('/Viewer.js/fonts/Exotica-webfont.woff') format('woff'), + url('/Viewer.js/fonts/Exotica-webfont.ttf') format('truetype'), + url('/Viewer.js/fonts/Exotica-webfont.svg#exoticamedium') format('svg'); + font-weight: normal; + font-style: normal; + +} + diff --git a/lib/viewers/odf/viewer/images/texture.png b/lib/viewers/odf/viewer/images/texture.png Binary files differnew file mode 100644 index 0000000..df00864 --- /dev/null +++ b/lib/viewers/odf/viewer/images/texture.png diff --git a/lib/viewers/odf/viewer/images/toolbarButton-download.png b/lib/viewers/odf/viewer/images/toolbarButton-download.png Binary files differnew file mode 100644 index 0000000..8676d8e --- /dev/null +++ b/lib/viewers/odf/viewer/images/toolbarButton-download.png diff --git a/lib/viewers/odf/viewer/images/toolbarButton-fullscreen.png b/lib/viewers/odf/viewer/images/toolbarButton-fullscreen.png Binary files differnew file mode 100644 index 0000000..fa73095 --- /dev/null +++ b/lib/viewers/odf/viewer/images/toolbarButton-fullscreen.png diff --git a/lib/viewers/odf/viewer/images/toolbarButton-menuArrows.png b/lib/viewers/odf/viewer/images/toolbarButton-menuArrows.png Binary files differnew file mode 100644 index 0000000..31b06b5 --- /dev/null +++ b/lib/viewers/odf/viewer/images/toolbarButton-menuArrows.png diff --git a/lib/viewers/odf/viewer/images/toolbarButton-pageDown.png b/lib/viewers/odf/viewer/images/toolbarButton-pageDown.png Binary files differnew file mode 100644 index 0000000..762ac43 --- /dev/null +++ b/lib/viewers/odf/viewer/images/toolbarButton-pageDown.png diff --git a/lib/viewers/odf/viewer/images/toolbarButton-pageUp.png b/lib/viewers/odf/viewer/images/toolbarButton-pageUp.png Binary files differnew file mode 100644 index 0000000..3155b8b --- /dev/null +++ b/lib/viewers/odf/viewer/images/toolbarButton-pageUp.png diff --git a/lib/viewers/odf/viewer/images/toolbarButton-presentation.png b/lib/viewers/odf/viewer/images/toolbarButton-presentation.png Binary files differnew file mode 100644 index 0000000..0f22423 --- /dev/null +++ b/lib/viewers/odf/viewer/images/toolbarButton-presentation.png diff --git a/lib/viewers/odf/viewer/images/toolbarButton-zoomIn.png b/lib/viewers/odf/viewer/images/toolbarButton-zoomIn.png Binary files differnew file mode 100644 index 0000000..670acd9 --- /dev/null +++ b/lib/viewers/odf/viewer/images/toolbarButton-zoomIn.png diff --git a/lib/viewers/odf/viewer/images/toolbarButton-zoomOut.png b/lib/viewers/odf/viewer/images/toolbarButton-zoomOut.png Binary files differnew file mode 100644 index 0000000..810fbf9 --- /dev/null +++ b/lib/viewers/odf/viewer/images/toolbarButton-zoomOut.png diff --git a/lib/viewers/odf/viewer/index.html b/lib/viewers/odf/viewer/index.html new file mode 100644 index 0000000..96bc805 --- /dev/null +++ b/lib/viewers/odf/viewer/index.html @@ -0,0 +1,78 @@ +<html dir="ltr" lang="en-US"> + <head> + <!-- If you want to use custom CSS (@font-face rules, for example) you should uncomment + the following reference and use a local.css file for that. See the example.local.css + file for a sample. + <link rel="stylesheet" type="text/css" href="local.css" media="screen"/> + --> + <link rel="stylesheet" type="text/css" href="viewer.css" media="screen"/> + <script src="viewer.js" type="text/javascript" charset="utf-8"></script> + <script src="PluginLoader.js" type="text/javascript" charset="utf-8"></script> + <script> + loadDocument(window.location.hash); + </script> + </head> + + <body> + <div id = "viewer"> + <div id = "titlebar"> + <div id = "documentName"></div> + <div id = "toolbarRight"> + <button id = "presentation" class = "toolbarButton presentation" title = "Presentation"></button> + <button id = "fullscreen" class = "toolbarButton fullscreen" title = "Fullscreen"></button> + <button id = "download" class = "toolbarButton download" title = "Download"></button> + </div> + </div> + <div id = "toolbarContainer"> + <div id = "toolbar"> + <div id = "toolbarLeft"> + <div id = "navButtons" class = "splitToolbarButton"> + <button id = "previous" class = "toolbarButton pageUp" title = "Previous Page"></button> + <div class="splitToolbarButtonSeparator"></div> + <button id = "next" class = "toolbarButton pageDown" title = "Next Page"></button> + </div> + <label id = "pageNumberLabel" class = "toolbarLabel" for = "pageNumber">Page:</label> + <input type = "number" id = "pageNumber" class = "toolbarField pageNumber"></input> + <span id = "numPages" class = "toolbarLabel"></span> + </div> + <div id = "toolbarMiddleContainer" class = "outerCenter"> + <div id = "toolbarMiddle" class = "innerCenter"> + <div id = 'zoomButtons' class = "splitToolbarButton"> + <button id = "zoomOut" class = "toolbarButton zoomOut" title = "Zoom Out"></button> + <div class="splitToolbarButtonSeparator"></div> + <button id = "zoomIn" class = "toolbarButton zoomIn" title = "Zoom In"></button> + </div> + <span id="scaleSelectContainer" class="dropdownToolbarButton"> + <select id="scaleSelect" title="Zoom" oncontextmenu="return false;"> + <option id="pageAutoOption" value="auto" selected>Automatic</option> + <option id="pageActualOption" value="page-actual">Actual Size</option> + <option id="pageWidthOption" value="page-width">Full Width</option> + <option id="customScaleOption" value="custom"></option> + <option value="0.5">50%</option> + <option value="0.75">75%</option> + <option value="1">100%</option> + <option value="1.25">125%</option> + <option value="1.5">150%</option> + <option value="2">200%</option> + </select> + </span> + <div id = "sliderContainer"> + <div id = "slider"></div> + </div> + </div> + </div> + </div> + </div> + <div id = "canvasContainer"> + <div id = "canvas"></div> + </div> + <div id = "overlayNavigator"> + <div id = "previousPage"></div> + <div id = "nextPage"></div> + </div> + <div id = "overlayCloseButton"> + ✖ + </div> + </div> + </body> +</html> diff --git a/lib/viewers/odf/viewer/viewer.css b/lib/viewers/odf/viewer/viewer.css new file mode 100644 index 0000000..f05de20 --- /dev/null +++ b/lib/viewers/odf/viewer/viewer.css @@ -0,0 +1,643 @@ +* { + padding: 0; + margin: 0; +} + +body { + font-family: sans-serif; +} + +.titlebar > span, +.toolbarLabel, +input, +button, +select { + font: message-box; +} + +#titlebar { + position: absolute; + z-index: 2; + top: 0px; + left: 0px; + height: 32px; + width: 100%; + overflow: hidden; + + -webkit-box-shadow: 0px 1px 3px rgba(50, 50, 50, 0.75); + -moz-box-shadow: 0px 1px 3px rgba(50, 50, 50, 0.75); + box-shadow: 0px 1px 3px rgba(50, 50, 50, 0.75); + + background-image: url(images/texture.png), linear-gradient(rgba(69, 69, 69, .95), rgba(82, 82, 82, .99)); + background-image: url(images/texture.png), -webkit-linear-gradient(rgba(69, 69, 69, .95), rgba(82, 82, 82, .99)); + background-image: url(images/texture.png), -moz-linear-gradient(rgba(69, 69, 69, .95), rgba(82, 82, 82, .99)); + background-image: url(images/texture.png), -ms-linear-gradient(rgba(69, 69, 69, .95), rgba(82, 82, 82, .99)); + background-image: url(images/texture.png), -o-linear-gradient(rgba(69, 69, 69, .95), rgba(82, 82, 82, .99)); +} + +#documentName { + margin-left: 10px; + margin-top: 8px; + color: #F2F2F2; + font-size: 14px; + line-height: 14px; + font-family: sans-serif; +} + +#toolbarContainer { + position: absolute; + z-index: 2; + bottom: 0px; + left: 0px; + height: 32px; + width: 100%; + overflow: hidden; + + -webkit-box-shadow: 0px -1px 3px rgba(50, 50, 50, 0.75); + -moz-box-shadow: 0px -1px 3px rgba(50, 50, 50, 0.75); + box-shadow: 0px -1px 3px rgba(50, 50, 50, 0.75); + + background-image: url(images/texture.png), linear-gradient(rgba(82, 82, 82, .99), rgba(69, 69, 69, .95)); + background-image: url(images/texture.png), -webkit-linear-gradient(rgba(82, 82, 82, .99), rgba(69, 69, 69, .95)); + background-image: url(images/texture.png), -moz-linear-gradient(rgba(82, 82, 82, .99), rgba(69, 69, 69, .95)); + background-image: url(images/texture.png), -ms-linear-gradient(rgba(82, 82, 82, .99), rgba(69, 69, 69, .95)); + background-image: url(images/texture.png), -o-linear-gradient(rgba(82, 82, 82, .99), rgba(69, 69, 69, .95)); +} + +#toolbar { + position: relative; +} + +#toolbarMiddleContainer, #toolbarLeft { + visibility: hidden; +} + +html[dir='ltr'] #toolbarLeft { + margin-left: -1px; +} +html[dir='rtl'] #toolbarRight { + margin-left: -1px; +} +html[dir='ltr'] #toolbarLeft, +html[dir='rtl'] #toolbarRight { + position: absolute; + top: 0; + left: 0; +} +html[dir='ltr'] #toolbarRight, +html[dir='rtl'] #toolbarLeft { + position: absolute; + top: 0; + right: 0; +} +html[dir='ltr'] #toolbarLeft > *, +html[dir='ltr'] #toolbarMiddle > *, +html[dir='ltr'] #toolbarRight > * { + float: left; +} +html[dir='rtl'] #toolbarLeft > *, +html[dir='rtl'] #toolbarMiddle > *, +html[dir='rtl'] #toolbarRight > * { + float: right; +} + +/* outer/inner center provides horizontal center */ +html[dir='ltr'] .outerCenter { + float: right; + position: relative; + right: 50%; +} +html[dir='rtl'] .outerCenter { + float: left; + position: relative; + left: 50%; +} +html[dir='ltr'] .innerCenter { + float: right; + position: relative; + right: -50%; +} +html[dir='rtl'] .innerCenter { + float: left; + position: relative; + left: -50%; +} + +html[dir='ltr'] .splitToolbarButton { + margin: 3px 2px 4px 0; + display: inline-block; +} +html[dir='rtl'] .splitToolbarButton { + margin: 3px 0 4px 2px; + display: inline-block; +} +html[dir='ltr'] .splitToolbarButton > .toolbarButton { + border-radius: 0; + float: left; +} +html[dir='rtl'] .splitToolbarButton > .toolbarButton { + border-radius: 0; + float: right; +} + +.splitToolbarButton.toggled .toolbarButton { + margin: 0; +} + +.toolbarButton { + border: 0 none; + background-color: rgba(0, 0, 0, 0); + width: 32px; + height: 25px; + border-radius: 2px; + background-image: none; +} + +html[dir='ltr'] .toolbarButton, +html[dir='ltr'] .dropdownToolbarButton { + margin: 3px 2px 4px 0; +} +html[dir='rtl'] .toolbarButton, +html[dir='rtl'] .dropdownToolbarButton { + margin: 3px 0 4px 2px; +} + +.toolbarButton:hover, +.toolbarButton:focus, +.dropdownToolbarButton { + background-color: hsla(0,0%,0%,.12); + background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-clip: padding-box; + border: 1px solid hsla(0,0%,0%,.35); + border-color: hsla(0,0%,0%,.32) hsla(0,0%,0%,.38) hsla(0,0%,0%,.42); + box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, + 0 0 1px hsla(0,0%,100%,.15) inset, + 0 1px 0 hsla(0,0%,100%,.05); +} + +.toolbarButton:hover:active, +.dropdownToolbarButton:hover:active { + background-color: hsla(0,0%,0%,.2); + background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + border-color: hsla(0,0%,0%,.35) hsla(0,0%,0%,.4) hsla(0,0%,0%,.45); + box-shadow: 0 1px 1px hsla(0,0%,0%,.1) inset, + 0 0 1px hsla(0,0%,0%,.2) inset, + 0 1px 0 hsla(0,0%,100%,.05); +} + +.splitToolbarButton:hover > .toolbarButton, +.splitToolbarButton:focus > .toolbarButton, +.splitToolbarButton.toggled > .toolbarButton, +.toolbarButton.textButton { + background-color: hsla(0,0%,0%,.12); + background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-clip: padding-box; + border: 1px solid hsla(0,0%,0%,.35); + border-color: hsla(0,0%,0%,.32) hsla(0,0%,0%,.38) hsla(0,0%,0%,.42); + box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, + 0 0 1px hsla(0,0%,100%,.15) inset, + 0 1px 0 hsla(0,0%,100%,.05); + -webkit-transition-property: background-color, border-color, box-shadow; + -webkit-transition-duration: 150ms; + -webkit-transition-timing-function: ease; + -moz-transition-property: background-color, border-color, box-shadow; + -moz-transition-duration: 150ms; + -moz-transition-timing-function: ease; + -ms-transition-property: background-color, border-color, box-shadow; + -ms-transition-duration: 150ms; + -ms-transition-timing-function: ease; + -o-transition-property: background-color, border-color, box-shadow; + -o-transition-duration: 150ms; + -o-transition-timing-function: ease; + transition-property: background-color, border-color, box-shadow; + transition-duration: 150ms; + transition-timing-function: ease; + +} +.splitToolbarButton > .toolbarButton:hover, +.splitToolbarButton > .toolbarButton:focus, +.dropdownToolbarButton:hover, +.toolbarButton.textButton:hover, +.toolbarButton.textButton:focus { + background-color: hsla(0,0%,0%,.2); + box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, + 0 0 1px hsla(0,0%,100%,.15) inset, + 0 0 1px hsla(0,0%,0%,.05); + z-index: 199; +} + + +.splitToolbarButton:hover > .toolbarButton, +.splitToolbarButton:focus > .toolbarButton, +.splitToolbarButton.toggled > .toolbarButton, +.toolbarButton.textButton { + background-color: hsla(0,0%,0%,.12); + background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -ms-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: -o-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-image: linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-clip: padding-box; + border: 1px solid hsla(0,0%,0%,.35); + border-color: hsla(0,0%,0%,.32) hsla(0,0%,0%,.38) hsla(0,0%,0%,.42); + box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, + 0 0 1px hsla(0,0%,100%,.15) inset, + 0 1px 0 hsla(0,0%,100%,.05); + -webkit-transition-property: background-color, border-color, box-shadow; + -webkit-transition-duration: 150ms; + -webkit-transition-timing-function: ease; + -moz-transition-property: background-color, border-color, box-shadow; + -moz-transition-duration: 150ms; + -moz-transition-timing-function: ease; + -ms-transition-property: background-color, border-color, box-shadow; + -ms-transition-duration: 150ms; + -ms-transition-timing-function: ease; + -o-transition-property: background-color, border-color, box-shadow; + -o-transition-duration: 150ms; + -o-transition-timing-function: ease; + transition-property: background-color, border-color, box-shadow; + transition-duration: 150ms; + transition-timing-function: ease; + +} +.splitToolbarButton > .toolbarButton:hover, +.splitToolbarButton > .toolbarButton:focus, +.dropdownToolbarButton:hover, +.toolbarButton.textButton:hover, +.toolbarButton.textButton:focus { + background-color: hsla(0,0%,0%,.2); + box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, + 0 0 1px hsla(0,0%,100%,.15) inset, + 0 0 1px hsla(0,0%,0%,.05); + z-index: 199; +} + +.dropdownToolbarButton { + border: 1px solid #333 !important; +} + +.toolbarButton, +.dropdownToolbarButton { + min-width: 16px; + padding: 2px 6px 2px; + border: 1px solid transparent; + border-radius: 2px; + color: hsl(0,0%,95%); + font-size: 12px; + line-height: 14px; + -webkit-user-select:none; + -moz-user-select:none; + -ms-user-select:none; + /* Opera does not support user-select, use <... unselectable="on"> instead */ + cursor: default; + -webkit-transition-property: background-color, border-color, box-shadow; + -webkit-transition-duration: 150ms; + -webkit-transition-timing-function: ease; + -moz-transition-property: background-color, border-color, box-shadow; + -moz-transition-duration: 150ms; + -moz-transition-timing-function: ease; + -ms-transition-property: background-color, border-color, box-shadow; + -ms-transition-duration: 150ms; + -ms-transition-timing-function: ease; + -o-transition-property: background-color, border-color, box-shadow; + -o-transition-duration: 150ms; + -o-transition-timing-function: ease; + transition-property: background-color, border-color, box-shadow; + transition-duration: 150ms; + transition-timing-function: ease; +} + +html[dir='ltr'] .toolbarButton, +html[dir='ltr'] .dropdownToolbarButton { + margin: 3px 2px 4px 0; +} +html[dir='rtl'] .toolbarButton, +html[dir='rtl'] .dropdownToolbarButton { + margin: 3px 0 4px 2px; +} + +.splitToolbarButton:hover > .splitToolbarButtonSeparator, +.splitToolbarButton.toggled > .splitToolbarButtonSeparator { + padding: 12px 0; + margin: 0; + box-shadow: 0 0 0 1px hsla(0,0%,100%,.03); + -webkit-transition-property: padding; + -webkit-transition-duration: 10ms; + -webkit-transition-timing-function: ease; + -moz-transition-property: padding; + -moz-transition-duration: 10ms; + -moz-transition-timing-function: ease; + -ms-transition-property: padding; + -ms-transition-duration: 10ms; + -ms-transition-timing-function: ease; + -o-transition-property: padding; + -o-transition-duration: 10ms; + -o-transition-timing-function: ease; + transition-property: padding; + transition-duration: 10ms; + transition-timing-function: ease; +} + +.toolbarButton.toggled:hover:active, +.splitToolbarButton > .toolbarButton:hover:active { + background-color: hsla(0,0%,0%,.4); + border-color: hsla(0,0%,0%,.4) hsla(0,0%,0%,.5) hsla(0,0%,0%,.55); + box-shadow: 0 1px 1px hsla(0,0%,0%,.2) inset, + 0 0 1px hsla(0,0%,0%,.3) inset, + 0 1px 0 hsla(0,0%,100%,.05); +} + +html[dir='ltr'] .splitToolbarButton > .toolbarButton:first-child, +html[dir='rtl'] .splitToolbarButton > .toolbarButton:last-child { + position: relative; + margin: 0; + margin-left: 4px; + margin-right: -1px; + border-top-left-radius: 2px; + border-bottom-left-radius: 2px; + border-right-color: transparent; +} +html[dir='ltr'] .splitToolbarButton > .toolbarButton:last-child, +html[dir='rtl'] .splitToolbarButton > .toolbarButton:first-child { + position: relative; + margin: 0; + margin-left: -1px; + border-top-right-radius: 2px; + border-bottom-right-radius: 2px; + border-left-color: transparent; +} +.splitToolbarButtonSeparator { + padding: 8px 0; + width: 1px; + background-color: hsla(0,0%,00%,.5); + z-index: 99; + box-shadow: 0 0 0 1px hsla(0,0%,100%,.08); + display: inline-block; + margin: 5px 0; +} +html[dir='ltr'] .splitToolbarButtonSeparator { + float:left; +} +html[dir='rtl'] .splitToolbarButtonSeparator { + float:right; +} + +.dropdownToolbarButton { + min-width: 120px; + max-width: 120px; + padding: 4px 2px 4px; + overflow: hidden; + background: url(images/toolbarButton-menuArrows.png) no-repeat; +} + +.dropdownToolbarButton > select { + -webkit-appearance: none; + -moz-appearance: none; /* in the future this might matter, see bugzilla bug #649849 */ + min-width: 140px; + font-size: 12px; + color: hsl(0,0%,95%); + margin:0; + padding:0; + border:none; + background: rgba(0,0,0,0); /* Opera does not support 'transparent' <select> background */ +} + +.dropdownToolbarButton > select > option { + background: hsl(0,0%,24%); +} + +#pageWidthOption { + border-bottom: 1px rgba(255, 255, 255, .5) solid; +} + + +html[dir='ltr'] .dropdownToolbarButton { + background-position: 95%; +} +html[dir='rtl'] .dropdownToolbarButton { + background-position: 5%; +} + + +.toolbarButton.fullscreen::before { + display: inline-block; + content: url(images/toolbarButton-fullscreen.png); +} + +.toolbarButton.presentation::before { + display: inline-block; + content: url(images/toolbarButton-presentation.png); +} + +.toolbarButton.download::before { + display: inline-block; + content: url(images/toolbarButton-download.png); +} + +.toolbarButton.zoomOut::before { + display: inline-block; + content: url(images/toolbarButton-zoomOut.png); +} + +.toolbarButton.zoomIn::before { + display: inline-block; + content: url(images/toolbarButton-zoomIn.png); +} + +.toolbarButton.pageUp::before { + display: inline-block; + content: url(images/toolbarButton-pageUp.png); +} + +.toolbarButton.pageDown::before { + display: inline-block; + content: url(images/toolbarButton-pageDown.png); +} + +.toolbarField.pageNumber { + min-width: 16px; + text-align: right; + width: 40px; +} + +.toolbarField { + padding: 3px 6px; + margin: 4px 0 4px 0; + border: 1px solid transparent; + border-radius: 2px; + background-color: hsla(0,0%,100%,.09); + background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0)); + background-clip: padding-box; + border: 1px solid hsla(0,0%,0%,.35); + border-color: hsla(0,0%,0%,.32) hsla(0,0%,0%,.38) hsla(0,0%,0%,.42); + box-shadow: 0 1px 0 hsla(0,0%,0%,.05) inset, + 0 1px 0 hsla(0,0%,100%,.05); + color: hsl(0,0%,95%); + font-size: 12px; + line-height: 14px; + outline-style: none; + -moz-transition-property: background-color, border-color, box-shadow; + -moz-transition-duration: 150ms; + -moz-transition-timing-function: ease; +} + +.toolbarField.pageNumber::-webkit-inner-spin-button, +.toolbarField.pageNumber::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} + +.toolbarField:hover { + background-color: hsla(0,0%,100%,.11); + border-color: hsla(0,0%,0%,.4) hsla(0,0%,0%,.43) hsla(0,0%,0%,.45); +} + +.toolbarField:focus { + background-color: hsla(0,0%,100%,.15); + border-color: hsla(204,100%,65%,.8) hsla(204,100%,65%,.85) hsla(204,100%,65%,.9); +} + +.toolbarLabel { + min-width: 16px; + padding: 3px 6px 3px 2px; + margin: 4px 2px 4px 0; + border: 1px solid transparent; + border-radius: 2px; + color: hsl(0,0%,85%); + font-size: 12px; + line-height: 14px; + text-align: left; + -webkit-user-select:none; + -moz-user-select:none; + cursor: default; +} + +#canvasContainer { + overflow: auto; + padding-top: 6px; + padding-bottom: 6px; + position: absolute; + top: 32px; + right: 0; + bottom: 32px; + left: 0; + + text-align: center; + + background-color: #888; + background-image: url(images/texture.png); +} + +.presentationMode { + top: 0 !important; + bottom: 0 !important; + background-color: black !important; + cursor: default !important; +} + +#canvas { + overflow: hidden; + box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.75); + -webkit-box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.75); + -moz-box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.75); + -ms-box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.75); + -o-box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.75); +} + +#sliderContainer { + visibility: hidden; +} + +#overlayNavigator { + position: absolute; + width: 100%; + height: 0; + top: calc(50% - 50px); + background-color: rgba(0, 0, 0, 0); + z-index: 3; + opacity: 0; + -webkit-transition: opacity 1s ease-out; + -moz-transition: opacity 1s ease-out; + transition: opacity 1s ease-out; +} +#previousPage { + float: left; + margin-left: 10px; + + /* CSS triangle */ + border-top: 50px solid transparent; + border-bottom: 50px solid transparent; + border-right: 50px solid black; + + opacity: 0.5; +} +#nextPage { + float: right; + margin-right: 10px; + + /* CSS triangle */ + border-top: 50px solid transparent; + border-bottom: 50px solid transparent; + border-left: 50px solid black; + + opacity: 0.5; +} +#previousPage:active { + opacity: 0.8; +} +#nextPage:active { + opacity: 0.8; +} +#overlayCloseButton { + position: absolute; + top: 10px; + right: 10px; + z-index: 3; + font-size: 35px; + color: white; + background-color: black; + opacity: 0.5; + + width: 40px; + height: 40px; + -webkit-border-radius: 20px; + -moz-border-radius: 20px; + border-radius: 20px; + text-align: center; + cursor: pointer; + display: none; +} +#overlayCloseButton:active { + background-color: red; +} + +@media only screen and (max-width: 600px) and (max-height: 1000px) { + #canvasContainer { + top: 0; + bottom: 0; + } + #titlebar, #toolbarContainer { + background-color: rgba(0, 0, 0, 0.6); + background-image: none; + } + #overlayNavigator.touched { + display: block; + opacity: 1; + height: 100px; + } + #next, #previous { + display: none; + } +} diff --git a/lib/viewers/odf/viewer/viewer.js b/lib/viewers/odf/viewer/viewer.js new file mode 100644 index 0000000..b942d2f --- /dev/null +++ b/lib/viewers/odf/viewer/viewer.js @@ -0,0 +1,49 @@ +/* + + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + You should have received a copy of the GNU Affero General Public License + along with this code. If not, see <http://www.gnu.org/licenses/>. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +function Viewer(c){function p(){return document.isFullScreen||document.mozFullScreen||document.webkitIsFullScreen}function u(a){var b=E.options,c,f=!1,d;for(d=0;d<b.length;d+=1)c=b[d],c.value!==a?c.selected=!1:f=c.selected=!0;return f}function v(a,c,d){a!==b.getZoomLevel()&&(b.setZoomLevel(a),d=document.createEvent("UIEvents"),d.initUIEvent("scalechange",!1,!1,window,0),d.scale=a,d.resetAutoSettings=c,window.dispatchEvent(d))}function w(){var a;if(c.onScroll)c.onScroll();c.getPageInView&&(a=c.getPageInView())&& +(e=a,document.getElementById("pageNumber").value=a)}function x(a){window.clearTimeout(y);y=window.setTimeout(function(){w()},a)}function g(a,b,g){var f,e;if(f="custom"===a?parseFloat(document.getElementById("customScaleOption").textContent)/100:parseFloat(a))v(f,!0,g);else{f=d.clientWidth-k;e=d.clientHeight-k;switch(a){case "page-actual":v(1,b,g);break;case "page-width":c.fitToWidth(f);break;case "page-height":c.fitToHeight(e);break;case "page-fit":c.fitToPage(f,e);break;case "auto":c.isSlideshow()? +c.fitToPage(f+k,e+k):c.fitSmart(f)}u(a)}x(300)}function q(){l&&!p()&&b.togglePresentationMode()}function r(){m&&(s.className="touched",window.clearTimeout(z),z=window.setTimeout(function(){s.className=""},2E3))}var b=this,k=40,l=!1,A=!1,m=!1,t,B,d=document.getElementById("canvasContainer"),s=document.getElementById("overlayNavigator"),C=document.getElementById("toolbarLeft"),F=document.getElementById("toolbarMiddleContainer"),E=document.getElementById("scaleSelect"),D,n=[],e,y,z;this.initialize=function(){var a= +String(document.location),h=a.indexOf("#"),a=a.substr(h+1);-1===h||0===a.length?console.log("Could not parse file path argument."):(B=document.getElementById("viewer"),t=a,D=t.replace(/^.*[\\\/]/,""),document.title=D,document.getElementById("documentName").innerHTML=document.title,c.onLoad=function(){(m=c.isSlideshow())?(d.style.padding=0,C.style.visibility="visible"):(F.style.visibility="visible",c.getPageInView&&(C.style.visibility="visible"));A=!0;n=c.getPages();document.getElementById("numPages").innerHTML= +"of "+n.length;b.showPage(1);g("auto");d.onscroll=w;x()},c.initialize(d,a))};this.showPage=function(a){0>=a?a=1:a>n.length&&(a=n.length);c.showPage(a);e=a;document.getElementById("pageNumber").value=e};this.showNextPage=function(){b.showPage(e+1)};this.showPreviousPage=function(){b.showPage(e-1)};this.download=function(){var a=t.split("#")[0];window.open(a+"#viewer.action=download","_parent")};this.toggleFullScreen=function(){var a=B;p()?document.cancelFullScreen?document.cancelFullScreen():document.mozCancelFullScreen? +document.mozCancelFullScreen():document.webkitCancelFullScreen&&document.webkitCancelFullScreen():a.requestFullScreen?a.requestFullScreen():a.mozRequestFullScreen?a.mozRequestFullScreen():a.webkitRequestFullScreen&&a.webkitRequestFullScreen()};this.togglePresentationMode=function(){var a=document.getElementById("titlebar"),h=document.getElementById("toolbarContainer"),e=document.getElementById("overlayCloseButton");l?(a.style.display=h.style.display="block",e.style.display="none",d.className="",d.onmouseup= +function(){},d.oncontextmenu=function(){},d.onmousedown=function(){},g("auto"),m=c.isSlideshow()):(a.style.display=h.style.display="none",e.style.display="block",d.className="presentationMode",m=!0,d.onmousedown=function(a){a.preventDefault()},d.oncontextmenu=function(a){a.preventDefault()},d.onmouseup=function(a){a.preventDefault();1===a.which?b.showNextPage():b.showPreviousPage()},g("page-fit"));l=!l};this.getZoomLevel=function(){return c.getZoomLevel()};this.setZoomLevel=function(a){c.setZoomLevel(a)}; +this.zoomOut=function(){var a=(b.getZoomLevel()/1.1).toFixed(2),a=Math.max(0.25,a);g(a,!0)};this.zoomIn=function(){var a=(1.1*b.getZoomLevel()).toFixed(2),a=Math.min(4,a);g(a,!0)};(function(){b.initialize();document.cancelFullScreen||document.mozCancelFullScreen||document.webkitCancelFullScreen||(document.getElementById("fullscreen").style.visibility="hidden");document.getElementById("overlayCloseButton").addEventListener("click",b.toggleFullScreen);document.getElementById("fullscreen").addEventListener("click", +b.toggleFullScreen);document.getElementById("presentation").addEventListener("click",function(){p()||b.toggleFullScreen();b.togglePresentationMode()});document.addEventListener("fullscreenchange",q);document.addEventListener("webkitfullscreenchange",q);document.addEventListener("mozfullscreenchange",q);document.getElementById("download").addEventListener("click",function(){b.download()});document.getElementById("zoomOut").addEventListener("click",function(){b.zoomOut()});document.getElementById("zoomIn").addEventListener("click", +function(){b.zoomIn()});document.getElementById("previous").addEventListener("click",function(){b.showPreviousPage()});document.getElementById("next").addEventListener("click",function(){b.showNextPage()});document.getElementById("previousPage").addEventListener("click",function(){b.showPreviousPage()});document.getElementById("nextPage").addEventListener("click",function(){b.showNextPage()});document.getElementById("pageNumber").addEventListener("change",function(){b.showPage(this.value)});document.getElementById("scaleSelect").addEventListener("change", +function(){g(this.value)});d.addEventListener("click",r);s.addEventListener("click",r);window.addEventListener("scalechange",function(a){var b=document.getElementById("customScaleOption"),c=u(String(a.scale));b.selected=!1;c||(b.textContent=Math.round(1E4*a.scale)/100+"%",b.selected=!0)},!0);window.addEventListener("resize",function(a){A&&(document.getElementById("pageWidthOption").selected||document.getElementById("pageAutoOption").selected)&&g(document.getElementById("scaleSelect").value);r()}); +window.addEventListener("keydown",function(a){var c=a.shiftKey;switch(a.keyCode){case 33:case 38:case 37:b.showPreviousPage();break;case 34:case 40:case 39:b.showNextPage();break;case 32:c?b.showPreviousPage():b.showNextPage()}})})()}; |