Revision c1f9b687

b/webodf/CMakeLists.txt
4 4
  message(FATAL_ERROR "You should point CMake to the parent directory.")
5 5
endif(WRONGCMAKEDIR)
6 6

  
7
set(LIBJSFILES lib/packages.js lib/runtime.js lib/core/Base64.js lib/core/RawDeflate.js lib/core/ByteArray.js lib/core/ByteArrayWriter.js lib/core/RawInflate.js lib/core/Cursor.js lib/core/UnitTester.js lib/core/PointWalker.js lib/core/Async.js lib/core/Zip.js
8
    lib/gui/Caret.js lib/gui/SelectionMover.js lib/gui/XMLEdit.js
9
    lib/xmldom/LSSerializerFilter.js lib/xmldom/LSSerializer.js lib/xmldom/RelaxNGParser.js lib/xmldom/RelaxNG.js lib/xmldom/RelaxNG2.js lib/xmldom/OperationalTransformInterface.js lib/xmldom/OperationalTransformDOM.js
10
    lib/odf/StyleInfo.js lib/odf/Style2CSS.js lib/odf/FontLoader.js lib/odf/OdfContainer.js lib/odf/Formatting.js lib/odf/OdfCanvas.js)
7
set(LIBJSFILES lib/packages.js lib/runtime.js lib/core/Base64.js
8
    lib/core/RawDeflate.js lib/core/ByteArray.js
9
    lib/core/ByteArrayWriter.js lib/core/RawInflate.js
10
    lib/core/Cursor.js lib/core/UnitTester.js
11
    lib/core/PointWalker.js lib/core/Async.js
12
    lib/core/Zip.js
13

  
14
    lib/xmldom/LSSerializerFilter.js lib/xmldom/LSSerializer.js
15
    lib/xmldom/RelaxNGParser.js lib/xmldom/RelaxNG.js
16
    lib/xmldom/RelaxNG2.js lib/xmldom/OperationalTransformInterface.js
17
    lib/xmldom/OperationalTransformDOM.js
18

  
19
    lib/odf/StyleInfo.js lib/odf/Style2CSS.js
20
    lib/odf/FontLoader.js lib/odf/OdfContainer.js
21
    lib/odf/Formatting.js lib/odf/OdfCanvas.js
22

  
23
    lib/gui/PresenterUI.js lib/gui/Caret.js
24
    lib/gui/SelectionMover.js lib/gui/XMLEdit.js
25
)
11 26

  
12 27
set(TESTJSFILES tests/core/ZipTests.js
13 28
    tests/core/Base64Tests.js
b/webodf/lib/gui/PresenterUI.js
1
/**
2
 * Copyright (C) 2011 KO GmbH - Tobias Hintze
3
 * @licstart
4
 * The JavaScript code in this page is free software: you can redistribute it
5
 * and/or modify it under the terms of the GNU Affero General Public License
6
 * (GNU AGPL) as published by the Free Software Foundation, either version 3 of
7
 * the License, or (at your option) any later version.  The code is distributed
8
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU AGPL for more details.
10
 *
11
 * As additional permission under GNU AGPL version 3 section 7, you
12
 * may distribute non-source (e.g., minimized or compacted) forms of
13
 * that code without the copy of the GNU GPL normally required by
14
 * section 4, provided you include this license notice and a URL
15
 * through which recipients can access the Corresponding Source.
16
 *
17
 * As a special exception to the AGPL, any HTML file which merely makes function
18
 * calls to this code, and for that purpose includes it by reference shall be
19
 * deemed a separate work for copyright law purposes. In addition, the copyright
20
 * holders of this code give you permission to combine this code with free
21
 * software libraries that are released under the GNU LGPL. You may copy and
22
 * distribute such a system following the terms of the GNU AGPL for this code
23
 * and the LGPL for the libraries. If you modify this code, you may extend this
24
 * exception to your version of the code, but you are not obligated to do so.
25
 * If you do not wish to do so, delete this exception statement from your
26
 * version.
27
 *
28
 * This license applies to this entire compilation.
29
 * @licend
30
 * @source: http://www.webodf.org/
31
 * @source: http://gitorious.org/odfkit/webodf/
32
 */
33

  
34

  
35
/*global runtime: true, gui: true, odf: true, XPathResult: true, core: true, document: true, window: true*/
36

  
37
gui.PresenterUI = (function () {
38
	"use strict";
39
	var s2css = new odf.Style2CSS(),
40
		nsResolver = s2css.namespaceResolver;
41

  
42
	return function PresenterUI(odf_element) {
43
	    var self = this;
44

  
45
		self.setInitialSlideMode = function () {
46
			self.startSlideMode('single');
47
		};
48

  
49
		self.keyDownHandler = function (ev) {
50
			if (ev.target.isContentEditable) { return; }
51
			if (ev.target.nodeName === 'input') { return; }
52
			switch (ev.keyCode) {
53
				case 84: // t - hide/show toolbar
54
					self.toggleToolbar();
55
					break;
56
				case 37: // left
57
				case 8: // left
58
					self.prevSlide();
59
					break;
60
				case 39:  // right
61
				case 32:  // space
62
					self.nextSlide();
63
					break;
64
				case 36: // pos1
65
					self.firstSlide();
66
					break;
67
				case 35: // end
68
					self.lastSlide();
69
					break;
70
			}
71
		};
72

  
73
		self.root = function () { return self.odf_canvas.odfContainer().rootElement; };
74

  
75
		self.firstSlide = function () { self.slideChange(function(old,pc) { return 0; }); };
76
		self.lastSlide = function () { self.slideChange(function(old,pc) { return pc-1; }); };
77

  
78
		self.nextSlide = function () {
79
			self.slideChange(function(old,pc) { return old+1 < pc ? old+1 : -1; });
80
		};
81
		self.prevSlide = function () {
82
			self.slideChange(function(old,pc) { return old<1 ? -1 : old-1; });
83
		};
84
		// indexChanger gets (idx,pagecount) as parameter and returns the new index
85
		self.slideChange = function (indexChanger) {
86
			var pages = self.getPages(self.odf_canvas.odfContainer().rootElement),
87
				last = -1,
88
				i = 0,
89
				newidx, pagelist;
90
			pages.forEach(function(tuple) {
91
				var name = tuple[0],
92
					node = tuple[1];
93
				if (node.hasAttribute('slide_current')) {
94
					last = i;
95
					node.removeAttribute('slide_current');
96
				}
97
				i += 1;
98
			});
99
			newidx = indexChanger(last, pages.length);
100
			if (newidx === -1) { newidx = last; }
101
			pages[newidx][1].setAttribute('slide_current', '1');
102
			pagelist = document.getElementById('pagelist');
103
			pagelist.selectedIndex = newidx;
104
			// FIXME this needs to become a sane callback/listener mechanism
105
			// (and the mode probably a class/instance..)
106
			if (self.slide_mode === 'cont') {
107
				window.scrollBy(0,pages[newidx][1].getBoundingClientRect().top - 30);
108
			}
109
		};
110

  
111
		self.selectSlide = function (idx) {
112
			self.slideChange(function(old,pc) {
113
				if (idx >= pc) { return -1; }
114
				if (idx < 0) { return -1; }
115
				return idx;
116
			});
117
		};
118

  
119
		// make one specific slide visible in cont-mode
120
		self.scrollIntoContView = function (idx) {
121
			var pages = self.getPages(self.odf_canvas.odfContainer().rootElement);
122
			if ( pages.length === 0 ) { return; }
123
			/*
124
			if (false) {
125
				// works in chrome
126
				pages[idx][1].scrollIntoView();
127
			} else {
128
			*/
129
				// works in ff
130
				window.scrollBy(0,pages[idx][1].getBoundingClientRect().top - 30);
131
			/*}*/
132
		};
133

  
134
		// return a list of tuples (pagename, pagenode)
135
		self.getPages = function (root) {
136
			var pagenodes = root.getElementsByTagNameNS(nsResolver('draw'), 'page'),
137
				pages  = [],
138
				i;
139
			for (i=0 ; i < pagenodes.length ; i += 1) {
140
				pages.push(
141
					[
142
					pagenodes[i].getAttribute('draw:name'),
143
					pagenodes[i]
144
					]);
145
			}
146
			return pages;
147
		};
148

  
149
		// fill a html-select with options, one option per page in odf (odp)
150
		self.fillPageList = function (odfdom_root, html_select) {
151
			var pages = self.getPages(odfdom_root),
152
				i,
153
				html_option,
154
				res,
155
				page_denom;
156

  
157
			// empty the pagelist
158
			while ( html_select.firstChild ) { html_select.removeChild(html_select.firstChild); }
159

  
160
			// populate it
161
			for (i=0 ; i< pages.length ; i += 1) {
162
				html_option = document.createElement('option');
163
				res = document.evaluate( './draw:frame[@presentation:class="title"]//draw:text-box/text:p',
164
				  pages[i][1], nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE , null);
165
				page_denom = res.singleNodeValue ? res.singleNodeValue.textContent : pages[i][0];
166
				html_option.textContent = (i+1)+": "+page_denom;
167
				html_select.appendChild(html_option);
168
			}
169
		};
170

  
171
		self.startSlideMode = function (mode) {
172
			var pagelist = document.getElementById('pagelist'),
173
				css = self.odf_canvas.slidevisibilitycss().sheet;
174
			self.slide_mode=mode;
175
			while (css.cssRules.length > 0) { css.deleteRule(0); }
176
			// start on slide 0
177
			self.selectSlide(0);
178
			if (self.slide_mode === 'single') {
179
				css.insertRule( "draw|page { position:fixed; left:0px;top:30px; z-index:1; }", 0);
180
				css.insertRule( "draw|page[slide_current]  { z-index:2;}", 1);
181
				css.insertRule( "draw|page  { -webkit-transform: scale(1);}", 2);
182
				self.fitToWindow();
183
				window.addEventListener('resize', self.fitToWindow, false);
184

  
185
			} else if (self.slide_mode === 'cont') {
186
				window.removeEventListener('resize', self.fitToWindow, false);
187
			}
188

  
189
			self.fillPageList(self.odf_canvas.odfContainer().rootElement, pagelist);
190
		};
191

  
192
		// toggle (show/hide) toolbar
193
		self.toggleToolbar = function () {
194
			var css, found, i;
195
			css = self.odf_canvas.slidevisibilitycss().sheet;
196
			found = -1;
197
			for (i=0 ; i< css.cssRules.length ; i += 1) {
198
				if (css.cssRules[i].cssText.substring(0,8) === ".toolbar") {
199
					found = i;
200
					break;
201
				}
202
			}
203
			if (found > -1) {
204
				css.deleteRule(found);
205
			} else {
206
				css.insertRule( ".toolbar { position:fixed; left:0px;top:-200px; z-index:0; }", 0);
207
			}
208
		};
209

  
210
		// adapt css-transform to window-size
211
		self.fitToWindow = function () {
212
			function ruleByFactor(f) {
213
				return "draw|page { \n" +
214
				"-moz-transform: scale("+f+"); \n" +
215
					"-moz-transform-origin: 0% 0%; "+
216
					"-webkit-transform-origin: 0% 0%; -webkit-transform: scale("+f+"); " +
217
					"-o-transform-origin: 0% 0%; -o-transform: scale("+f+"); " +
218
					"-ms-transform-origin: 0% 0%; -ms-transform: scale("+f+"); " +
219
					"}";
220
			}
221
			var pages = self.getPages(self.root()),
222
				factorVert = ((window.innerHeight-40) / pages[0][1].clientHeight),
223
				factorHoriz = ((window.innerWidth-10) / pages[0][1].clientWidth),
224
				factor = factorVert < factorHoriz ? factorVert : factorHoriz,
225
				css = self.odf_canvas.slidevisibilitycss().sheet;
226
			css.deleteRule(2);
227
			css.insertRule( ruleByFactor(factor), 2);
228
		};
229

  
230
		self.load = function (url) {
231
			self.odf_canvas.load(url);
232
		};
233

  
234
		self.odf_element = odf_element;
235
		self.odf_canvas = new odf.OdfCanvas(self.odf_element);
236
		self.odf_canvas.addListener("statereadychange", self.setInitialSlideMode);
237
		self.slide_mode = 'undefined';
238
		document.addEventListener('keydown', self.keyDownHandler, false);
239
	};
240
}());
241

  
b/webodf/lib/manifest.js
15 15
        "gui/Caret.js",
16 16
        "gui/SelectionMover.js",
17 17
        "gui/XMLEdit.js",
18
        "gui/PresenterUI.js",
18 19
        "odf/FontLoader.js",
19 20
        "odf/Formatting.js",
20 21
        "odf/OdfCanvas.js",
b/webodf/lib/odf/OdfCanvas.js
455 455
            /**@type{!odf.Formatting}*/ formatting = new odf.Formatting(),
456 456
            selectionWatcher = new SelectionWatcher(element),
457 457
            slidecssindex = 0,
458
            slidevisibilitycss = addStyleSheet(document),
458 459
            stylesxmlcss = addStyleSheet(document),
459 460
            positioncss = addStyleSheet(document),
460 461
            editable = false;
......
472 473
                'office|presentation draw|page:nth-child(1n) { display:block; }',
473 474
                css.cssRules.length);
474 475

  
476
            // FIXME: this is a hack to have a defined background now
477
            // should be removed as soon as we have sane background
478
            // handling for pages
479
            slidecssindex = css.insertRule(
480
                'draw|page { background-color:#fff; }',
481
                css.cssRules.length);
482

  
483

  
475 484
            // only append the content at the end
476 485
            clear(element);
477 486
            element.appendChild(odfnode);
......
512 521
            return odfcontainer;
513 522
        };
514 523

  
524
        this.slidevisibilitycss = function() {
525
            return slidevisibilitycss;
526
        };
527

  
515 528
        /**
516 529
         * @param {!string} url
517 530
         * @return {undefined}

Also available in: Unified diff