diff options
-rw-r--r-- | css/3rdparty/webodf/editor.css | 24 | ||||
-rw-r--r-- | js/3rdparty/webodf/editor/Editor.js | 74 | ||||
-rw-r--r-- | js/3rdparty/webodf/editor/EditorSession.js | 68 | ||||
-rw-r--r-- | js/3rdparty/webodf/editor/Tools.js | 16 | ||||
-rw-r--r-- | js/3rdparty/webodf/editor/server/pullbox/OperationRouter.js | 14 | ||||
-rw-r--r-- | js/3rdparty/webodf/editor/widgets/dialogWidgets/alignmentPane.js | 5 | ||||
-rw-r--r-- | js/3rdparty/webodf/editor/widgets/dialogWidgets/editHyperlinkPane.html | 30 | ||||
-rw-r--r-- | js/3rdparty/webodf/editor/widgets/dialogWidgets/editHyperlinkPane.js | 110 | ||||
-rw-r--r-- | js/3rdparty/webodf/editor/widgets/editHyperlinks.js | 181 | ||||
-rw-r--r-- | js/3rdparty/webodf/editor/widgets/paragraphAlignment.js | 34 | ||||
-rw-r--r-- | js/3rdparty/webodf/editor/widgets/simpleStyles.js | 38 | ||||
-rw-r--r-- | js/3rdparty/webodf/editor/widgets/undoRedoMenu.js | 92 | ||||
-rw-r--r-- | js/3rdparty/webodf/editor/widgets/zoomSlider.js | 35 | ||||
-rw-r--r-- | js/3rdparty/webodf/webodf-debug.js | 16541 | ||||
-rw-r--r-- | js/3rdparty/webodf/webodf.js | 1828 |
15 files changed, 9648 insertions, 9442 deletions
diff --git a/css/3rdparty/webodf/editor.css b/css/3rdparty/webodf/editor.css index 23f86ee9..6f23a0c8 100644 --- a/css/3rdparty/webodf/editor.css +++ b/css/3rdparty/webodf/editor.css @@ -25,13 +25,18 @@ body.claro, #mainContainer { #toolbar { overflow: hidden; + top: 0; + left: 0; + right: 0; + position: absolute; + z-index: 5; + box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25); } #container { text-align: center; background-color: #ddd; overflow: auto; - position: absolute; top: 30px; bottom: 0; @@ -40,7 +45,6 @@ body.claro, #mainContainer { } #canvas { - box-shadow: 0px 0px 20px #aaa; margin-top: 30px; margin-left: 10px; margin-right: 10px; @@ -50,8 +54,16 @@ body.claro, #mainContainer { -webkit-transform-origin: top center; -moz-transform-origin: top center; -o-transform-origin: top center; - overflow: hidden; + overflow: visible; +} +/* Add shadow to the sizer and not the canvas, + * so that it will follow the smooth zooming + * of the slider and not have to be updated + * every time a gesture ends + */ +#canvas > div { + box-shadow: 0px 0px 20px #aaa; border: 1px solid #ccc; } @@ -241,7 +253,7 @@ div.memberListLabel[fullname]:before { text-align: center; } -cursor div { +cursor .handle { margin-top: 5px; padding-top: 3px; margin-left: auto; @@ -269,11 +281,11 @@ cursor img { margin: auto; } -cursor div.active { +cursor .handle.active { opacity: 0.8; } -cursor div:after { +cursor .handle:after { content: ' '; position: absolute; width: 0px; diff --git a/js/3rdparty/webodf/editor/Editor.js b/js/3rdparty/webodf/editor/Editor.js index 86840e2f..ce2d1b92 100644 --- a/js/3rdparty/webodf/editor/Editor.js +++ b/js/3rdparty/webodf/editor/Editor.js @@ -317,6 +317,7 @@ define("webodf/editor/Editor", [ runtime.assert(editorSession, "editorSession should exist here."); tools.setEditorSession(editorSession); + editorSession.sessionController.insertLocalCursor(); editorSession.sessionController.startEditing(); }; @@ -330,6 +331,7 @@ define("webodf/editor/Editor", [ tools.setEditorSession(undefined); editorSession.sessionController.endEditing(); + editorSession.sessionController.removeLocalCursor(); }; /** @@ -365,12 +367,51 @@ define("webodf/editor/Editor", [ }; /** + * Applies a CSS transformation to the toolbar + * to ensure that if there is a body-scroll, + * the toolbar remains visible at the top of + * the screen. + * The bodyscroll quirk has been observed on + * iOS, generally when the keyboard appears. + * But this workaround should function on + * other platforms that exhibit this behaviour + * as well. + * @return {undefined} + */ + function translateToolbar() { + var bar = document.getElementById('toolbar'), + y = document.body.scrollTop; + + bar.style.WebkitTransformOrigin = "center top"; + bar.style.WebkitTransform = 'translateY(' + y + 'px)'; + } + + /** + * FIXME: At the moment both the toolbar and the canvas + * container are absolutely positioned. Changing them to + * relative positioning to ensure that they do not overlap + * causes scrollbars *within* the container to disappear. + * Not sure why this happens, and a proper CSS fix has not + * been found yet, so for now we need to reposition + * the container using Js. + * @return {undefined} + */ + function repositionContainer() { + document.getElementById('container').style.top = document.getElementById('toolbar').getBoundingClientRect().height + 'px'; + } + + /** * @param {!function(!Object=)} callback, passing an error object in case of error * @return {undefined} */ this.destroy = function (callback) { var destroyMemberListView = memberListView ? memberListView.destroy : function(cb) { cb(); }; + window.removeEventListener('scroll', translateToolbar); + window.removeEventListener('focusout', translateToolbar); + window.removeEventListener('touchmove', translateToolbar); + window.removeEventListener('resize', repositionContainer); + // TODO: decide if some forced close should be done here instead of enforcing proper API usage runtime.assert(!session, "session should not exist here."); @@ -407,10 +448,12 @@ define("webodf/editor/Editor", [ var editorPane, memberListPane, inviteButton, canvasElement = document.getElementById("canvas"), + container = document.getElementById('container'), memberListElement = document.getElementById('memberList'), collabEditing = Boolean(server), directParagraphStylingEnabled = (! collabEditing) || args.unstableFeaturesEnabled, imageInsertingEnabled = (! collabEditing) || args.unstableFeaturesEnabled, + hyperlinkEditingEnabled = (! collabEditing) || args.unstableFeaturesEnabled, // annotations not yet properly supported for OT annotationsEnabled = (! collabEditing) || args.unstableFeaturesEnabled, // undo manager is not yet integrated with collaboration @@ -471,18 +514,19 @@ define("webodf/editor/Editor", [ } tools = new Tools({ - onToolDone: setFocusToOdfCanvas, - loadOdtFile: loadOdtFile, - saveOdtFile: saveOdtFile, - close: close, - directParagraphStylingEnabled: directParagraphStylingEnabled, - imageInsertingEnabled: imageInsertingEnabled, - annotationsEnabled: annotationsEnabled, - undoRedoEnabled: undoRedoEnabled - }); + onToolDone: setFocusToOdfCanvas, + loadOdtFile: loadOdtFile, + saveOdtFile: saveOdtFile, + close: close, + directParagraphStylingEnabled: directParagraphStylingEnabled, + imageInsertingEnabled: imageInsertingEnabled, + hyperlinkEditingEnabled: hyperlinkEditingEnabled, + annotationsEnabled: annotationsEnabled, + undoRedoEnabled: undoRedoEnabled + }); odfCanvas = new odf.OdfCanvas(canvasElement); - odfCanvas.enableAnnotations(annotationsEnabled); + odfCanvas.enableAnnotations(annotationsEnabled, true); odfCanvas.addListener("statereadychange", function () { var viewOptions = { @@ -496,7 +540,8 @@ define("webodf/editor/Editor", [ editorSession = new EditorSession(session, pendingMemberId, { viewOptions: viewOptions, directParagraphStylingEnabled: directParagraphStylingEnabled, - imageInsertingEnabled: imageInsertingEnabled + imageInsertingEnabled: imageInsertingEnabled, + hyperlinkEditingEnabled: hyperlinkEditingEnabled }); if (undoRedoEnabled) { editorSession.sessionController.setUndoManager(new gui.TrivialUndoManager()); @@ -512,6 +557,13 @@ define("webodf/editor/Editor", [ pendingEditorReadyCallback = null; pendingMemberId = null; }); + + repositionContainer(); + + window.addEventListener('scroll', translateToolbar); + window.addEventListener('focusout', translateToolbar); + window.addEventListener('touchmove', translateToolbar); + window.addEventListener('resize', repositionContainer); } init(); diff --git a/js/3rdparty/webodf/editor/EditorSession.js b/js/3rdparty/webodf/editor/EditorSession.js index 91d28b43..5c33e5af 100644 --- a/js/3rdparty/webodf/editor/EditorSession.js +++ b/js/3rdparty/webodf/editor/EditorSession.js @@ -43,10 +43,6 @@ define("webodf/editor/EditorSession", [ ], function (fontsCSS) { // fontsCSS is retrieved as a string, using dojo's text retrieval AMD plugin "use strict"; - runtime.libraryPaths = function () { - return [ "../../webodf/lib" ]; - }; - runtime.loadClass("core.DomUtils"); runtime.loadClass("odf.OdfUtils"); runtime.loadClass("ops.OdtDocument"); @@ -54,11 +50,13 @@ define("webodf/editor/EditorSession", [ runtime.loadClass("ops.Session"); runtime.loadClass("odf.Namespaces"); runtime.loadClass("odf.OdfCanvas"); + runtime.loadClass("odf.OdfUtils"); runtime.loadClass("gui.CaretManager"); runtime.loadClass("gui.Caret"); runtime.loadClass("gui.SessionController"); runtime.loadClass("gui.SessionView"); runtime.loadClass("gui.TrivialUndoManager"); + runtime.loadClass("gui.SvgSelectionView"); runtime.loadClass("gui.SelectionViewManager"); runtime.loadClass("core.EventNotifier"); runtime.loadClass("gui.ShadowCursor"); @@ -208,7 +206,7 @@ define("webodf/editor/EditorSession", [ function trackCurrentParagraph(info) { var cursor = odtDocument.getCursor(localMemberId), range = cursor && cursor.getSelectedRange(), - paragraphRange = odtDocument.getDOM().createRange(); + paragraphRange = odtDocument.getDOMDocument().createRange(); paragraphRange.selectNode(info.paragraphElement); if ((range && domUtils.rangesIntersect(range, paragraphRange)) || info.paragraphElement === currentParagraphNode) { self.emit(EditorSession.signalParagraphChanged, info); @@ -312,7 +310,7 @@ define("webodf/editor/EditorSession", [ /** * Round the step up to the next step * @param {!number} step - * @returns {!boolean} + * @return {!boolean} */ function roundUp(step) { return step === ops.StepsTranslator.NEXT_STEP; @@ -387,14 +385,14 @@ define("webodf/editor/EditorSession", [ return formatting.isStyleUsed(styleElement); }; - function getDefaultParagraphStyleAttributes () { + function getDefaultParagraphStyleAttributes() { var styleNode = formatting.getDefaultStyleElement('paragraph'); if (styleNode) { return formatting.getInheritedStyleAttributes(styleNode); } return null; - }; + } /** * Returns the attributes of a given paragraph style name @@ -522,22 +520,30 @@ define("webodf/editor/EditorSession", [ return array; }; + this.getSelectedHyperlinks = function () { + var cursor = odtDocument.getCursor(localMemberId); + // no own cursor yet/currently added? + if (!cursor) { + return []; + } + return odfUtils.getHyperlinkElements(cursor.getSelectedRange()); + }; + + this.getSelectedRange = function () { + var cursor = odtDocument.getCursor(localMemberId); + return cursor && cursor.getSelectedRange(); + }; + function undoStackModified(e) { self.emit(EditorSession.signalUndoStackChanged, e); } - this.hasUndoManager = function () { - return Boolean(self.sessionController.getUndoManager()); - }; - this.undo = function () { - var undoManager = self.sessionController.getUndoManager(); - undoManager.moveBackward(1); + self.sessionController.undo(); }; this.redo = function () { - var undoManager = self.sessionController.getUndoManager(); - undoManager.moveForward(1); + self.sessionController.redo(); }; /** @@ -548,8 +554,8 @@ define("webodf/editor/EditorSession", [ * @param {!number} height */ this.insertImage = function (mimetype, content, width, height) { - self.sessionController.getTextManipulator().removeCurrentSelection(); - self.sessionController.getImageManager().insertImage(mimetype, content, width, height); + self.sessionController.getTextController().removeCurrentSelection(); + self.sessionController.getImageController().insertImage(mimetype, content, width, height); }; /** @@ -569,12 +575,12 @@ define("webodf/editor/EditorSession", [ head.removeChild(fontStyles); - odtDocument.unsubscribe(ops.OdtDocument.signalMemberAdded, onMemberAdded); - odtDocument.unsubscribe(ops.OdtDocument.signalMemberUpdated, onMemberUpdated); - odtDocument.unsubscribe(ops.OdtDocument.signalMemberRemoved, onMemberRemoved); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); + odtDocument.unsubscribe(ops.Document.signalMemberAdded, onMemberAdded); + odtDocument.unsubscribe(ops.Document.signalMemberUpdated, onMemberUpdated); + odtDocument.unsubscribe(ops.Document.signalMemberRemoved, onMemberRemoved); + odtDocument.unsubscribe(ops.Document.signalCursorAdded, onCursorAdded); + odtDocument.unsubscribe(ops.Document.signalCursorRemoved, onCursorRemoved); + odtDocument.unsubscribe(ops.Document.signalCursorMoved, onCursorMoved); odtDocument.unsubscribe(ops.OdtDocument.signalCommonStyleCreated, onStyleCreated); odtDocument.unsubscribe(ops.OdtDocument.signalCommonStyleDeleted, onStyleDeleted); odtDocument.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified); @@ -623,17 +629,17 @@ define("webodf/editor/EditorSession", [ directParagraphStylingEnabled: config.directParagraphStylingEnabled }); caretManager = new gui.CaretManager(self.sessionController); - selectionViewManager = new gui.SelectionViewManager(); + selectionViewManager = new gui.SelectionViewManager(gui.SvgSelectionView); self.sessionView = new gui.SessionView(config.viewOptions, localMemberId, session, caretManager, selectionViewManager); self.availableFonts = getAvailableFonts(); selectionViewManager.registerCursor(shadowCursor, true); // Custom signals, that make sense in the Editor context. We do not want to expose webodf's ops signals to random bits of the editor UI. - odtDocument.subscribe(ops.OdtDocument.signalMemberAdded, onMemberAdded); - odtDocument.subscribe(ops.OdtDocument.signalMemberUpdated, onMemberUpdated); - odtDocument.subscribe(ops.OdtDocument.signalMemberRemoved, onMemberRemoved); - odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); - odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); - odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); + odtDocument.subscribe(ops.Document.signalMemberAdded, onMemberAdded); + odtDocument.subscribe(ops.Document.signalMemberUpdated, onMemberUpdated); + odtDocument.subscribe(ops.Document.signalMemberRemoved, onMemberRemoved); + odtDocument.subscribe(ops.Document.signalCursorAdded, onCursorAdded); + odtDocument.subscribe(ops.Document.signalCursorRemoved, onCursorRemoved); + odtDocument.subscribe(ops.Document.signalCursorMoved, onCursorMoved); odtDocument.subscribe(ops.OdtDocument.signalCommonStyleCreated, onStyleCreated); odtDocument.subscribe(ops.OdtDocument.signalCommonStyleDeleted, onStyleDeleted); odtDocument.subscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified); diff --git a/js/3rdparty/webodf/editor/Tools.js b/js/3rdparty/webodf/editor/Tools.js index 8ab50b2b..c0aa4dad 100644 --- a/js/3rdparty/webodf/editor/Tools.js +++ b/js/3rdparty/webodf/editor/Tools.js @@ -49,11 +49,12 @@ define("webodf/editor/Tools", [ "webodf/editor/widgets/undoRedoMenu", "webodf/editor/widgets/toolbarWidgets/currentStyle", "webodf/editor/widgets/annotation", - "webodf/editor/widgets/paragraphStylesDialog", + "webodf/editor/widgets/editHyperlinks", "webodf/editor/widgets/imageInserter", + "webodf/editor/widgets/paragraphStylesDialog", "webodf/editor/widgets/zoomSlider", "webodf/editor/EditorSession"], - function (ready, MenuItem, DropDownMenu, Button, DropDownButton, Toolbar, ParagraphAlignment, SimpleStyles, UndoRedoMenu, CurrentStyle, AnnotationControl, ParagraphStylesDialog, ImageInserter, ZoomSlider, EditorSession) { + function (ready, MenuItem, DropDownMenu, Button, DropDownButton, Toolbar, ParagraphAlignment, SimpleStyles, UndoRedoMenu, CurrentStyle, AnnotationControl, EditHyperlinks, ImageInserter, ParagraphStylesDialog, ZoomSlider, EditorSession) { "use strict"; return function Tools(args) { @@ -72,6 +73,7 @@ define("webodf/editor/Tools", [ paragraphAlignment, imageInserter, annotationControl, + editHyperlinks, sessionSubscribers = []; function handleCursorMoved(cursor) { @@ -128,6 +130,7 @@ define("webodf/editor/Tools", [ widget.startup(); }); sessionSubscribers.push(undoRedoMenu); + undoRedoMenu.onToolDone = onToolDone; } // Add annotation @@ -226,6 +229,15 @@ define("webodf/editor/Tools", [ sessionSubscribers.push(paragraphStylesDialog); paragraphStylesDialog.onToolDone = onToolDone; + if (args.hyperlinkEditingEnabled) { + editHyperlinks = new EditHyperlinks(function (widget) { + widget.placeAt(toolbar); + widget.startup(); + }); + sessionSubscribers.push(editHyperlinks); + editHyperlinks.onToolDone = onToolDone; + } + formatMenuButton = new DropDownButton({ dropDown: formatDropDownMenu, label: tr('Format'), diff --git a/js/3rdparty/webodf/editor/server/pullbox/OperationRouter.js b/js/3rdparty/webodf/editor/server/pullbox/OperationRouter.js index a6cf8d61..de24b50f 100644 --- a/js/3rdparty/webodf/editor/server/pullbox/OperationRouter.js +++ b/js/3rdparty/webodf/editor/server/pullbox/OperationRouter.js @@ -94,7 +94,9 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () { EVENT_BEFORESAVETOFILE, EVENT_SAVEDTOFILE, EVENT_HASLOCALUNSYNCEDOPERATIONSCHANGED, - EVENT_HASSESSIONHOSTCONNECTIONCHANGED + EVENT_HASSESSIONHOSTCONNECTIONCHANGED, + ops.OperationRouter.signalProcessingBatchStart, + ops.OperationRouter.signalProcessingBatchEnd ]), /**@type{!boolean} tells if any local ops have been modifying ops */ hasPushedModificationOps = false, @@ -150,6 +152,8 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () { // take start time startTime = (new Date()).getTime(); + eventNotifier.emit(ops.OperationRouter.signalProcessingBatchStart, {}); + // apply as much as possible in the given time while (unplayedServerOpspecQueue.length > 0) { // time over? @@ -164,11 +168,13 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () { runtime.log(" op in: "+runtime.toJson(opspec)); if (op !== null) { if (!playbackFunction(op)) { + eventNotifier.emit(ops.OperationRouter.signalProcessingBatchEnd, {}); hasError = true; errorCallback("opExecutionFailure"); return; } } else { + eventNotifier.emit(ops.OperationRouter.signalProcessingBatchEnd, {}); hasError = true; runtime.log("ignoring invalid incoming opspec: " + opspec); errorCallback("unknownOpReceived"); @@ -176,6 +182,8 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () { } } + eventNotifier.emit(ops.OperationRouter.signalProcessingBatchEnd, {}); + // still unplayed opspecs? if (unplayedServerOpspecQueue.length > 0) { // let other events be handled. then continue @@ -493,6 +501,8 @@ runtime.log("OperationRouter: instant opsSync requested"); return; } + eventNotifier.emit(ops.OperationRouter.signalProcessingBatchStart, {}); + for (i = 0; i < operations.length; i += 1) { op = operations[i]; opspec = op.spec(); @@ -518,6 +528,8 @@ runtime.log("OperationRouter: instant opsSync requested"); triggerPushingOps(); updateHasLocalUnsyncedOpsState(); + + eventNotifier.emit(ops.OperationRouter.signalProcessingBatchEnd, {}); }; /** diff --git a/js/3rdparty/webodf/editor/widgets/dialogWidgets/alignmentPane.js b/js/3rdparty/webodf/editor/widgets/dialogWidgets/alignmentPane.js index 9e9a149f..24136f05 100644 --- a/js/3rdparty/webodf/editor/widgets/dialogWidgets/alignmentPane.js +++ b/js/3rdparty/webodf/editor/widgets/dialogWidgets/alignmentPane.js @@ -38,10 +38,11 @@ /*global runtime,core,define,require,dijit */ -runtime.loadClass("core.CSSUnits"); - define("webodf/editor/widgets/dialogWidgets/alignmentPane", [], function () { "use strict"; + + runtime.loadClass("core.CSSUnits"); + var AlignmentPane = function (callback) { var self = this, editorSession, diff --git a/js/3rdparty/webodf/editor/widgets/dialogWidgets/editHyperlinkPane.html b/js/3rdparty/webodf/editor/widgets/dialogWidgets/editHyperlinkPane.html new file mode 100644 index 00000000..ad6b5a11 --- /dev/null +++ b/js/3rdparty/webodf/editor/widgets/dialogWidgets/editHyperlinkPane.html @@ -0,0 +1,30 @@ +<html> + <head></head> + <body> + <div data-dojo-type="dijit/form/Form" id="editHyperlinkPaneForm" data-dojo-id="editHyperlinkPaneForm"> + <div> + <label text-i18n="Display Text" for="linkDisplayText"></label><br/> + <input data-dojo-type="dijit/form/TextBox" id="linkDisplayText" + value="" + data-dojo-props="trim:true" + name="linkDisplayText" /> + <input data-dojo-type="dijit/form/TextBox" id="isReadOnlyText" + type ="hidden" + value="" + data-dojo-props="trim:true" + name="isReadOnlyText" /> + </div> + <div> + <label text-i18n="URL" for="linkUrl"></label><br/> + <input data-dojo-type="dijit/form/TextBox" id="linkUrl" + value="http://" + data-dojo-props="trim:true" + name="linkUrl" /> + </div> + <div> + <button data-dojo-type="dijit/form/Button" id="saveHyperlinkChangeButton" type="submit">Ok</button> + <button data-dojo-type="dijit/form/Button" id="cancelHyperlinkChangeButton" data-dojo-id="cancelHyperlinkChangeButton">Cancel</button> + </div> + </div> + </body> +</html> diff --git a/js/3rdparty/webodf/editor/widgets/dialogWidgets/editHyperlinkPane.js b/js/3rdparty/webodf/editor/widgets/dialogWidgets/editHyperlinkPane.js new file mode 100644 index 00000000..d696e787 --- /dev/null +++ b/js/3rdparty/webodf/editor/widgets/dialogWidgets/editHyperlinkPane.js @@ -0,0 +1,110 @@ +/** + * @license + * 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/ + */ + +/*global runtime,core,define,require,document,dijit */ + +define("webodf/editor/widgets/dialogWidgets/editHyperlinkPane", [ + "dojo", + "dijit/layout/ContentPane"], + + function (dojo, ContentPane) { + "use strict"; + + runtime.loadClass("core.CSSUnits"); + + var EditHyperlinkPane = function () { + var self = this, + editorBase = dojo.config && dojo.config.paths && dojo.config.paths['webodf/editor'], + contentPane, + form, + displayTextField, + initialValue; + + runtime.assert(editorBase, "webodf/editor path not defined in dojoConfig"); + + function onSave() { + if (self.onSave) { + self.onSave(); + } + return false; + } + + function onCancel() { + form.set('value', initialValue); + if (self.onCancel) { + self.onCancel(); + } + } + + contentPane = new ContentPane({ + title: runtime.tr("editLink"), + href: editorBase+"/widgets/dialogWidgets/editHyperlinkPane.html", + preload: true, + onLoad : function () { + form = dijit.byId('editHyperlinkPaneForm'); + form.onSubmit = onSave; + dijit.byId('cancelHyperlinkChangeButton').onClick = onCancel; + displayTextField = dijit.byId('linkDisplayText'); + runtime.translateContent(form.domNode); + if (initialValue) { + form.set('value', initialValue); + displayTextField.set('disabled', initialValue.isReadOnlyText); + initialValue = undefined; + } + } + }); + + this.widget = function () { + return contentPane; + }; + + this.value = function () { + return form && form.get('value'); + }; + + this.set = function (value) { + initialValue = value; + if (form) { + form.set('value', value); + displayTextField.set('disabled', value.isReadOnlyText); + } + }; + }; + + return EditHyperlinkPane; +}); diff --git a/js/3rdparty/webodf/editor/widgets/editHyperlinks.js b/js/3rdparty/webodf/editor/widgets/editHyperlinks.js new file mode 100644 index 00000000..c1fc8401 --- /dev/null +++ b/js/3rdparty/webodf/editor/widgets/editHyperlinks.js @@ -0,0 +1,181 @@ +/** + * @license + * 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/ + */ + +/*global define,require,document,odf */ + +define("webodf/editor/widgets/editHyperlinks", [ + "webodf/editor/EditorSession", + "webodf/editor/widgets/dialogWidgets/editHyperlinkPane", + "dijit/form/Button", + "dijit/form/DropDownButton", + "dijit/TooltipDialog"], + + function (EditorSession, EditHyperlinkPane, Button, DropDownButton, TooltipDialog) { + "use strict"; + + runtime.loadClass("odf.OdfUtils"); + + var EditHyperlinks = function (callback) { + var self = this, + widget = {}, + editorSession, + hyperlinkController, + linkEditorContent, + editHyperlinkButton, + removeHyperlinkButton, + odfUtils = new odf.OdfUtils(), + dialog; + + linkEditorContent = new EditHyperlinkPane(); + dialog = new TooltipDialog({ + title: runtime.tr("Edit link"), + content: linkEditorContent.widget() + }); + + editHyperlinkButton = new DropDownButton({ + label: runtime.tr('Edit link'), + showLabel: false, + iconClass: 'dijitEditorIcon dijitEditorIconCreateLink', + dropDown: dialog + }); + + removeHyperlinkButton = new Button({ + label: runtime.tr('Remove link'), + showLabel: false, + disabled: true, + iconClass: 'dijitEditorIcon dijitEditorIconUnlink', + onClick: function () { + hyperlinkController.removeHyperlinks(); + self.onToolDone(); + } + }); + + linkEditorContent.onSave = function () { + var hyperlinkData = linkEditorContent.value(); + editHyperlinkButton.closeDropDown(false); + if (hyperlinkData.isReadOnlyText == "true") { + hyperlinkController.removeHyperlinks(); + hyperlinkController.addHyperlink(hyperlinkData.linkUrl); + } else { + hyperlinkController.addHyperlink(hyperlinkData.linkUrl, hyperlinkData.linkDisplayText); + } + self.onToolDone(); + }; + + linkEditorContent.onCancel = function () { + editHyperlinkButton.closeDropDown(false); + self.onToolDone(); + }; + + widget.children = [editHyperlinkButton, removeHyperlinkButton]; + widget.startup = function () { + widget.children.forEach(function (element) { + element.startup(); + }); + }; + + widget.placeAt = function (container) { + widget.children.forEach(function (element) { + element.placeAt(container); + }); + return widget; + }; + + function checkHyperlinkButtons() { + var selection = editorSession.getSelectedRange(), + textContent, + linksInSelection = editorSession.getSelectedHyperlinks(), + linkTarget = linksInSelection[0] ? odfUtils.getHyperlinkTarget(linksInSelection[0]) : "http://"; + + if (selection && selection.collapsed && linksInSelection.length === 1) { + // Selection is collapsed within a single hyperlink. Assume user is modifying the hyperlink + textContent = selection.cloneRange(); + textContent.selectNodeContents(linksInSelection[0]); + linkEditorContent.set({ + linkDisplayText: textContent.toString(), + linkUrl: linkTarget, + isReadOnlyText: true + }); + textContent.detach(); + } else if (selection && !selection.collapsed) { + // User has selected part of a hyperlink or a block of text. Assume user is attempting to modify the + // existing hyperlink, or wants to convert the selection into a hyperlink + linkEditorContent.set({ + linkDisplayText: selection.toString(), + linkUrl: linkTarget, + isReadOnlyText: true + }); + } else { + // Selection is collapsed and is not in an existing hyperlink + linkEditorContent.set({ + linkDisplayText: "", + linkUrl: linkTarget, + isReadOnlyText: false + }); + } + + // The 3rd parameter is false to avoid firing onChange when setting the value programmatically. + removeHyperlinkButton.set('disabled', linksInSelection.length === 0, false); + } + + this.setEditorSession = function (session) { + if (editorSession) { + editorSession.unsubscribe(EditorSession.signalCursorMoved, checkHyperlinkButtons); + editorSession.unsubscribe(EditorSession.signalParagraphChanged, checkHyperlinkButtons); + editorSession.unsubscribe(EditorSession.signalParagraphStyleModified, checkHyperlinkButtons); + } + editorSession = session; + hyperlinkController = session && session.sessionController.getHyperlinkController(); + widget.children.forEach(function (element) { + element.setAttribute('disabled', !hyperlinkController); + }); + if (editorSession) { + editorSession.subscribe(EditorSession.signalCursorMoved, checkHyperlinkButtons); + editorSession.subscribe(EditorSession.signalParagraphChanged, checkHyperlinkButtons); + editorSession.subscribe(EditorSession.signalParagraphStyleModified, checkHyperlinkButtons); + checkHyperlinkButtons(); + } + }; + + this.onToolDone = function () {}; + + callback(widget); + }; + + return EditHyperlinks; +}); diff --git a/js/3rdparty/webodf/editor/widgets/paragraphAlignment.js b/js/3rdparty/webodf/editor/widgets/paragraphAlignment.js index ae833b04..afc7958f 100644 --- a/js/3rdparty/webodf/editor/widgets/paragraphAlignment.js +++ b/js/3rdparty/webodf/editor/widgets/paragraphAlignment.js @@ -50,7 +50,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ var self = this, editorSession, widget = {}, - directParagraphStyler, + directFormattingController, justifyLeft, justifyCenter, justifyRight, @@ -65,7 +65,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ checked: false, iconClass: "dijitEditorIcon dijitEditorIconJustifyLeft", onChange: function () { - directParagraphStyler.alignParagraphLeft(); + directFormattingController.alignParagraphLeft(); self.onToolDone(); } }); @@ -77,7 +77,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ checked: false, iconClass: "dijitEditorIcon dijitEditorIconJustifyCenter", onChange: function () { - directParagraphStyler.alignParagraphCenter(); + directFormattingController.alignParagraphCenter(); self.onToolDone(); } }); @@ -89,7 +89,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ checked: false, iconClass: "dijitEditorIcon dijitEditorIconJustifyRight", onChange: function () { - directParagraphStyler.alignParagraphRight(); + directFormattingController.alignParagraphRight(); self.onToolDone(); } }); @@ -101,7 +101,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ checked: false, iconClass: "dijitEditorIcon dijitEditorIconJustifyFull", onChange: function () { - directParagraphStyler.alignParagraphJustified(); + directFormattingController.alignParagraphJustified(); self.onToolDone(); } }); @@ -112,7 +112,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ showLabel: false, iconClass: "dijitEditorIcon dijitEditorIconOutdent", onClick: function () { - directParagraphStyler.outdent(); + directFormattingController.outdent(); self.onToolDone(); } }); @@ -123,7 +123,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ showLabel: false, iconClass: "dijitEditorIcon dijitEditorIconIndent", onClick: function () { - directParagraphStyler.indent(); + directFormattingController.indent(); self.onToolDone(); } }); @@ -174,21 +174,21 @@ define("webodf/editor/widgets/paragraphAlignment", [ } this.setEditorSession = function (session) { - if (directParagraphStyler) { - directParagraphStyler.unsubscribe(gui.DirectParagraphStyler.paragraphStylingChanged, updateStyleButtons); + if (directFormattingController) { + directFormattingController.unsubscribe(gui.DirectFormattingController.paragraphStylingChanged, updateStyleButtons); } - directParagraphStyler = session && session.sessionController.getDirectParagraphStyler(); - if (directParagraphStyler) { - directParagraphStyler.subscribe(gui.DirectParagraphStyler.paragraphStylingChanged, updateStyleButtons); + directFormattingController = session && session.sessionController.getDirectFormattingController(); + if (directFormattingController) { + directFormattingController.subscribe(gui.DirectFormattingController.paragraphStylingChanged, updateStyleButtons); } widget.children.forEach(function (element) { - element.setAttribute('disabled', !directParagraphStyler); + element.setAttribute('disabled', !directFormattingController); }); updateStyleButtons({ - isAlignedLeft: directParagraphStyler ? directParagraphStyler.isAlignedLeft() : false, - isAlignedCenter: directParagraphStyler ? directParagraphStyler.isAlignedCenter() : false, - isAlignedRight: directParagraphStyler ? directParagraphStyler.isAlignedRight() : false, - isAlignedJustified: directParagraphStyler ? directParagraphStyler.isAlignedJustified() : false + isAlignedLeft: directFormattingController ? directFormattingController.isAlignedLeft() : false, + isAlignedCenter: directFormattingController ? directFormattingController.isAlignedCenter() : false, + isAlignedRight: directFormattingController ? directFormattingController.isAlignedRight() : false, + isAlignedJustified: directFormattingController ? directFormattingController.isAlignedJustified() : false }); if (editorSession) { diff --git a/js/3rdparty/webodf/editor/widgets/simpleStyles.js b/js/3rdparty/webodf/editor/widgets/simpleStyles.js index 10a6a107..00595750 100644 --- a/js/3rdparty/webodf/editor/widgets/simpleStyles.js +++ b/js/3rdparty/webodf/editor/widgets/simpleStyles.js @@ -51,7 +51,7 @@ define("webodf/editor/widgets/simpleStyles", [ var self = this, editorSession, widget = {}, - directTextStyler, + directFormattingController, boldButton, italicButton, underlineButton, @@ -67,7 +67,7 @@ define("webodf/editor/widgets/simpleStyles", [ checked: false, iconClass: "dijitEditorIcon dijitEditorIconBold", onChange: function (checked) { - directTextStyler.setBold(checked); + directFormattingController.setBold(checked); self.onToolDone(); } }); @@ -79,7 +79,7 @@ define("webodf/editor/widgets/simpleStyles", [ checked: false, iconClass: "dijitEditorIcon dijitEditorIconItalic", onChange: function (checked) { - directTextStyler.setItalic(checked); + directFormattingController.setItalic(checked); self.onToolDone(); } }); @@ -91,7 +91,7 @@ define("webodf/editor/widgets/simpleStyles", [ checked: false, iconClass: "dijitEditorIcon dijitEditorIconUnderline", onChange: function (checked) { - directTextStyler.setHasUnderline(checked); + directFormattingController.setHasUnderline(checked); self.onToolDone(); } }); @@ -103,7 +103,7 @@ define("webodf/editor/widgets/simpleStyles", [ checked: false, iconClass: "dijitEditorIcon dijitEditorIconStrikethrough", onChange: function (checked) { - directTextStyler.setHasStrikethrough(checked); + directFormattingController.setHasStrikethrough(checked); self.onToolDone(); } }); @@ -117,7 +117,7 @@ define("webodf/editor/widgets/simpleStyles", [ constraints: {min:6, max:96}, intermediateChanges: true, onChange: function (value) { - directTextStyler.setFontSize(value); + directFormattingController.setFontSize(value); }, onClick: function () { self.onToolDone(); @@ -134,7 +134,7 @@ define("webodf/editor/widgets/simpleStyles", [ fontPickerWidget = fontPicker.widget(); fontPickerWidget.setAttribute('disabled', true); fontPickerWidget.onChange = function(value) { - directTextStyler.setFontName(value); + directFormattingController.setFontName(value); self.onToolDone(); }; @@ -183,24 +183,24 @@ define("webodf/editor/widgets/simpleStyles", [ } this.setEditorSession = function(session) { - if (directTextStyler) { - directTextStyler.unsubscribe(gui.DirectTextStyler.textStylingChanged, updateStyleButtons); + if (directFormattingController) { + directFormattingController.unsubscribe(gui.DirectFormattingController.textStylingChanged, updateStyleButtons); } - directTextStyler = session && session.sessionController.getDirectTextStyler(); + directFormattingController = session && session.sessionController.getDirectFormattingController(); fontPicker.setEditorSession(session); - if (directTextStyler) { - directTextStyler.subscribe(gui.DirectTextStyler.textStylingChanged, updateStyleButtons); + if (directFormattingController) { + directFormattingController.subscribe(gui.DirectFormattingController.textStylingChanged, updateStyleButtons); } widget.children.forEach(function (element) { - element.setAttribute('disabled', !directTextStyler); + element.setAttribute('disabled', !directFormattingController); }); updateStyleButtons({ - isBold: directTextStyler ? directTextStyler.isBold() : false, - isItalic: directTextStyler ? directTextStyler.isItalic() : false, - hasUnderline: directTextStyler ? directTextStyler.hasUnderline() : false, - hasStrikeThrough: directTextStyler ? directTextStyler.hasStrikeThrough() : false, - fontSize: directTextStyler ? directTextStyler.fontSize() : undefined, - fontName: directTextStyler ? directTextStyler.fontName() : undefined + isBold: directFormattingController ? directFormattingController.isBold() : false, + isItalic: directFormattingController ? directFormattingController.isItalic() : false, + hasUnderline: directFormattingController ? directFormattingController.hasUnderline() : false, + hasStrikeThrough: directFormattingController ? directFormattingController.hasStrikeThrough() : false, + fontSize: directFormattingController ? directFormattingController.fontSize() : undefined, + fontName: directFormattingController ? directFormattingController.fontName() : undefined }); if (editorSession) { diff --git a/js/3rdparty/webodf/editor/widgets/undoRedoMenu.js b/js/3rdparty/webodf/editor/widgets/undoRedoMenu.js index cf1a57cd..e266615e 100644 --- a/js/3rdparty/webodf/editor/widgets/undoRedoMenu.js +++ b/js/3rdparty/webodf/editor/widgets/undoRedoMenu.js @@ -39,61 +39,57 @@ /*global define,require*/ define("webodf/editor/widgets/undoRedoMenu", - ["webodf/editor/EditorSession"], + ["webodf/editor/EditorSession", "dijit/form/Button"], - function (EditorSession) { + function (EditorSession, Button) { "use strict"; return function UndoRedoMenu(callback) { - var editorSession, + var self = this, + editorSession, undoButton, - redoButton; + redoButton, + widget = {}; - function makeWidget(callback) { - require(["dijit/form/Button"], function (Button) { - var widget = {}; - - undoButton = new Button({ - label: runtime.tr('Undo'), - showLabel: false, - disabled: true, // TODO: get current session state - iconClass: "dijitEditorIcon dijitEditorIconUndo", - onClick: function () { - if (editorSession) { - editorSession.undo(); - } - } - }); - - redoButton = new Button({ - label: runtime.tr('Redo'), - showLabel: false, - disabled: true, // TODO: get current session state - iconClass: "dijitEditorIcon dijitEditorIconRedo", - onClick: function () { - if (editorSession) { - editorSession.redo(); - } - } - }); + undoButton = new Button({ + label: runtime.tr('Undo'), + showLabel: false, + disabled: true, // TODO: get current session state + iconClass: "dijitEditorIcon dijitEditorIconUndo", + onClick: function () { + if (editorSession) { + editorSession.undo(); + self.onToolDone(); + } + } + }); - widget.children = [undoButton, redoButton]; - widget.startup = function () { - widget.children.forEach(function (element) { - element.startup(); - }); - }; + redoButton = new Button({ + label: runtime.tr('Redo'), + showLabel: false, + disabled: true, // TODO: get current session state + iconClass: "dijitEditorIcon dijitEditorIconRedo", + onClick: function () { + if (editorSession) { + editorSession.redo(); + self.onToolDone(); + } + } + }); - widget.placeAt = function (container) { - widget.children.forEach(function (element) { - element.placeAt(container); - }); - return widget; - }; + widget.children = [undoButton, redoButton]; + widget.startup = function () { + widget.children.forEach(function (element) { + element.startup(); + }); + }; - return callback(widget); + widget.placeAt = function (container) { + widget.children.forEach(function (element) { + element.placeAt(container); }); - } + return widget; + }; function checkUndoButtons(e) { if (undoButton) { @@ -115,9 +111,9 @@ define("webodf/editor/widgets/undoRedoMenu", } }; + this.onToolDone = function () {}; + // init - makeWidget(function (widget) { - return callback(widget); - }); + callback(widget); }; }); diff --git a/js/3rdparty/webodf/editor/widgets/zoomSlider.js b/js/3rdparty/webodf/editor/widgets/zoomSlider.js index b445211e..a5e1e370 100644 --- a/js/3rdparty/webodf/editor/widgets/zoomSlider.js +++ b/js/3rdparty/webodf/editor/widgets/zoomSlider.js @@ -38,24 +38,29 @@ /*global define,require*/ -define("webodf/editor/widgets/zoomSlider", [], function () { +define("webodf/editor/widgets/zoomSlider", [ + "webodf/editor/EditorSession"], + function (EditorSession) { "use strict"; return function ZoomSlider(callback) { var self = this, editorSession, - slider; + slider, + extremeZoomFactor = 4; + // The slider zooms from -1 to +1, which corresponds + // to zoom levels of 1/extremeZoomFactor to extremeZoomFactor. function makeWidget(callback) { require(["dijit/form/HorizontalSlider", "dijit/form/NumberTextBox", "dojo"], function (HorizontalSlider, NumberTextBox, dojo) { var widget = {}; slider = new HorizontalSlider({ name: 'zoomSlider', - value: 100, - minimum: 30, - maximum: 150, - discreteValues: 100, + value: 0, + minimum: -1, + maximum: 1, + discreteValues: 0.01, intermediateChanges: true, style: { width: '150px', @@ -66,7 +71,7 @@ define("webodf/editor/widgets/zoomSlider", [], function () { slider.onChange = function (value) { if (editorSession) { - editorSession.getOdfCanvas().setZoomLevel(value / 100.0); + editorSession.getOdfCanvas().getZoomHelper().setZoomLevel(Math.pow(extremeZoomFactor, value)); } self.onToolDone(); }; @@ -75,9 +80,23 @@ define("webodf/editor/widgets/zoomSlider", [], function () { }); } + function updateSlider(zoomLevel) { + if (slider) { + slider.set('value', Math.log(zoomLevel) / Math.log(extremeZoomFactor), false); + } + } + this.setEditorSession = function(session) { + var zoomHelper; + if (editorSession) { + editorSession.getOdfCanvas().getZoomHelper().unsubscribe(gui.ZoomHelper.signalZoomChanged, updateSlider); + } editorSession = session; -// if (slider) { slider.setValue(editorSession.getOdfCanvas().getZoomLevel() ); TODO! + if (editorSession) { + zoomHelper = editorSession.getOdfCanvas().getZoomHelper(); + zoomHelper.subscribe(gui.ZoomHelper.signalZoomChanged, updateSlider); + updateSlider(zoomHelper.getZoomLevel()); + } }; this.onToolDone = function () {}; diff --git a/js/3rdparty/webodf/webodf-debug.js b/js/3rdparty/webodf/webodf-debug.js index 4bb2eff2..fcebfe47 100644 --- a/js/3rdparty/webodf/webodf-debug.js +++ b/js/3rdparty/webodf/webodf-debug.js @@ -1,4 +1,4 @@ -var webodf_version = "0.4.2-1579-gfc3a4e6"; +var webodf_version = "0.4.2-2010-ge06842f"; function Runtime() { } Runtime.prototype.getVariable = function(name) { @@ -49,6 +49,10 @@ Runtime.prototype.exit = function(exitCode) { }; Runtime.prototype.getWindow = function() { }; +Runtime.prototype.requestAnimationFrame = function(callback) { +}; +Runtime.prototype.cancelAnimationFrame = function(requestId) { +}; Runtime.prototype.assert = function(condition, message, callback) { }; var IS_COMPILED_CODE = true; @@ -128,14 +132,29 @@ Runtime.getFunctionName = function getFunctionName(f) { }; function BrowserRuntime(logoutput) { var self = this, cache = {}; - function utf8ByteArrayFromString(string) { - var l = string.length, bytearray, i, n, j = 0; + function getUtf8LengthForString(string) { + var l = string.length, i, n, j = 0; for(i = 0;i < l;i += 1) { n = string.charCodeAt(i); - j += 1 + (n > 128) + (n > 2048) + j += 1 + (n > 128) + (n > 2048); + if(n > 55040 && n < 57344) { + j += 1; + i += 1 + } + } + return j + } + function utf8ByteArrayFromString(string, length, addBOM) { + var l = string.length, bytearray, i, n, j; + bytearray = new Uint8Array(new ArrayBuffer(length)); + if(addBOM) { + bytearray[0] = 239; + bytearray[1] = 187; + bytearray[2] = 191; + j = 3 + }else { + j = 0 } - bytearray = new Uint8Array(new ArrayBuffer(j)); - j = 0; for(i = 0;i < l;i += 1) { n = string.charCodeAt(i); if(n < 128) { @@ -147,15 +166,36 @@ function BrowserRuntime(logoutput) { bytearray[j + 1] = 128 | n & 63; j += 2 }else { - bytearray[j] = 224 | n >>> 12 & 15; - bytearray[j + 1] = 128 | n >>> 6 & 63; - bytearray[j + 2] = 128 | n & 63; - j += 3 + if(n <= 55040 || n >= 57344) { + bytearray[j] = 224 | n >>> 12 & 15; + bytearray[j + 1] = 128 | n >>> 6 & 63; + bytearray[j + 2] = 128 | n & 63; + j += 3 + }else { + i += 1; + n = (n - 55296 << 10 | string.charCodeAt(i) - 56320) + 65536; + bytearray[j] = 240 | n >>> 18 & 7; + bytearray[j + 1] = 128 | n >>> 12 & 63; + bytearray[j + 2] = 128 | n >>> 6 & 63; + bytearray[j + 3] = 128 | n & 63; + j += 4 + } } } } return bytearray } + function utf8ByteArrayFromXHRString(string, wishLength) { + var addBOM = false, length = getUtf8LengthForString(string); + if(typeof wishLength === "number") { + if(wishLength !== length && wishLength !== length + 3) { + return undefined + } + addBOM = length + 3 === wishLength; + length = wishLength + } + return utf8ByteArrayFromString(string, length, addBOM) + } function byteArrayFromString(string) { var l = string.length, a = new Uint8Array(new ArrayBuffer(l)), i; for(i = 0;i < l;i += 1) { @@ -166,7 +206,7 @@ function BrowserRuntime(logoutput) { this.byteArrayFromString = function(string, encoding) { var result; if(encoding === "utf8") { - result = utf8ByteArrayFromString(string) + result = utf8ByteArrayFromString(string, getUtf8LengthForString(string), false) }else { if(encoding !== "binary") { self.log("unknown encoding: " + encoding) @@ -228,8 +268,22 @@ function BrowserRuntime(logoutput) { } return a } + function stringToBinaryWorkaround(xhr) { + var cl, data; + cl = xhr.getResponseHeader("Content-Length"); + if(cl) { + cl = parseInt(cl, 10) + } + if(cl && cl !== xhr.responseText.length) { + data = utf8ByteArrayFromXHRString(xhr.responseText, cl) + } + if(data === undefined) { + data = byteArrayFromString(xhr.responseText) + } + return data + } function handleXHRResult(path, encoding, xhr) { - var data, r, d, a; + var r, d, a, data; if(xhr.status === 0 && !xhr.responseText) { r = {err:"File " + path + " is empty.", data:null} }else { @@ -247,7 +301,7 @@ function BrowserRuntime(logoutput) { a = (new VBArray(xhr.responseBody)).toArray(); data = arrayToUint8Array(a) }else { - data = self.byteArrayFromString(xhr.responseText, "binary") + data = stringToBinaryWorkaround(xhr) } }else { data = xhr.responseText @@ -468,6 +522,25 @@ function BrowserRuntime(logoutput) { }; this.getWindow = function() { return window + }; + this.requestAnimationFrame = function(callback) { + var rAF = window.requestAnimationFrame || (window.webkitRequestAnimationFrame || (window.mozRequestAnimationFrame || window.msRequestAnimationFrame)), requestId = 0; + if(rAF) { + rAF.bind(window); + requestId = (rAF)(callback) + }else { + return setTimeout(callback, 15) + } + return requestId + }; + this.cancelAnimationFrame = function(requestId) { + var cAF = window.cancelAnimationFrame || (window.webkitCancelAnimationFrame || (window.mozCancelAnimationFrame || window.msCancelAnimationFrame)); + if(cAF) { + cAF.bind(window); + (cAF)(requestId) + }else { + clearTimeout(requestId) + } } } function NodeJSRuntime() { @@ -637,6 +710,12 @@ function NodeJSRuntime() { this.getWindow = function() { return null }; + this.requestAnimationFrame = function(callback) { + return setTimeout(callback, 15) + }; + this.cancelAnimationFrame = function(requestId) { + clearTimeout(requestId) + }; function init() { var DOMParser = require("xmldom").DOMParser; parser = new DOMParser; @@ -821,6 +900,12 @@ function RhinoRuntime() { this.exit = quit; this.getWindow = function() { return null + }; + this.requestAnimationFrame = function(callback) { + callback(); + return 0 + }; + this.cancelAnimationFrame = function() { } } Runtime.create = function create() { @@ -843,162 +928,124 @@ var xmldom = {}; var odf = {}; var ops = {}; (function() { - var dependencies = {}, loadedFiles = {}; - function loadManifest(dir, manifests) { + function loadDependenciesFromManifest(dir, dependencies, expectFail) { var path = dir + "/manifest.json", content, list, manifest, m; - if(loadedFiles.hasOwnProperty(path)) { - return - } - loadedFiles[path] = 1; + runtime.log("Loading manifest: " + path); try { content = runtime.readFileSync(path, "utf-8") }catch(e) { - console.log(String(e)); + if(expectFail) { + runtime.log("No loadable manifest found.") + }else { + console.log(String(e)); + throw e; + } return } list = JSON.parse((content)); manifest = (list); for(m in manifest) { if(manifest.hasOwnProperty(m)) { - manifests[m] = {dir:dir, deps:manifest[m]} + dependencies[m] = {dir:dir, deps:manifest[m]} } } } - function expandPathDependencies(path, manifests, allDeps) { - var d = manifests[path].deps, deps = {}; - allDeps[path] = deps; - d.forEach(function(dp) { - deps[dp] = 1 - }); - d.forEach(function(dp) { - if(!allDeps[dp]) { - expandPathDependencies(dp, manifests, allDeps) - } - }); - d.forEach(function(dp) { - Object.keys(allDeps[dp]).forEach(function(k) { - deps[k] = 1 - }) - }) - } - function sortDeps(deps, allDeps) { - var i, sorted = []; - function add(path, stack) { - var j, d = allDeps[path]; - if(sorted.indexOf(path) === -1 && stack.indexOf(path) === -1) { - stack.push(path); - for(j = 0;j < deps.length;j += 1) { - if(d[deps[j]]) { - add(deps[j], stack) - } - } - stack.pop(); - sorted.push(path) - } + function loadDependenciesFromManifests() { + var dependencies = [], paths = runtime.libraryPaths(), i; + if(runtime.currentDirectory() && paths.indexOf(runtime.currentDirectory()) === -1) { + loadDependenciesFromManifest(runtime.currentDirectory(), dependencies, true) } - for(i = 0;i < deps.length;i += 1) { - add(deps[i], []) + for(i = 0;i < paths.length;i += 1) { + loadDependenciesFromManifest(paths[i], dependencies) } - return sorted + return dependencies + } + function getPath(dir, className) { + return dir + "/" + className.replace(".", "/") + ".js" } - function expandDependencies(manifests) { - var path, deps, allDeps = {}; - for(path in manifests) { - if(manifests.hasOwnProperty(path)) { - expandPathDependencies(path, manifests, allDeps) + function getLoadList(classNames, dependencies, isDefined) { + var loadList = [], stack = {}, visited = {}; + function visit(n) { + if(visited[n] || isDefined(n)) { + return } - } - for(path in manifests) { - if(manifests.hasOwnProperty(path)) { - deps = (Object.keys(allDeps[path])); - manifests[path].deps = sortDeps(deps, allDeps); - manifests[path].deps.push(path) + if(stack[n]) { + throw"Circular dependency detected for " + n + "."; + } + stack[n] = true; + if(!dependencies[n]) { + throw"Missing dependency information for class " + n + "."; } + var d = dependencies[n], deps = d.deps, i, l = deps.length; + for(i = 0;i < l;i += 1) { + visit(deps[i]) + } + stack[n] = false; + visited[n] = true; + loadList.push(getPath(d.dir, n)) } - dependencies = manifests + classNames.forEach(visit); + return loadList } - function loadManifests() { - if(Object.keys(dependencies).length > 0) { - return - } - var paths = runtime.libraryPaths(), manifests = {}, i; - if(runtime.currentDirectory()) { - loadManifest(runtime.currentDirectory(), manifests) - } + function addContent(path, content) { + content += "\n//# sourceURL=" + path; + content += "\n//@ sourceURL=" + path; + return content + } + function loadFiles(paths) { + var i, content; for(i = 0;i < paths.length;i += 1) { - loadManifest(paths[i], manifests) + content = runtime.readFileSync(paths[i], "utf-8"); + content = addContent(paths[i], (content)); + eval(content) } - expandDependencies(manifests) - } - function classPath(classname) { - return classname.replace(".", "/") + ".js" } - function getDependencies(classname) { - var classpath = classPath(classname), deps = [], d = dependencies[classpath].deps, i; - for(i = 0;i < d.length;i += 1) { - if(!loadedFiles.hasOwnProperty(d[i])) { - deps.push(d[i]) - } + function loadFilesInBrowser(paths, callback) { + var e = document.currentScript || document.documentElement.lastChild, df = document.createDocumentFragment(), script, i; + for(i = 0;i < paths.length;i += 1) { + script = document.createElement("script"); + script.type = "text/javascript"; + script.charset = "utf-8"; + script.async = false; + script.setAttribute("src", paths[i]); + df.appendChild(script) } - return deps + if(callback) { + script.onload = callback + } + e.parentNode.insertBefore(df, e) } - function evalArray(paths, contents) { - var i = 0; - while(i < paths.length && contents[i] !== undefined) { - if(contents[i] !== null) { - eval((contents[i])); - contents[i] = null + var dependencies, packages = {core:core, gui:gui, xmldom:xmldom, odf:odf, ops:ops}; + function isDefined(classname) { + var parts = classname.split("."), i, p = packages, l = parts.length; + for(i = 0;i < l;i += 1) { + if(!p.hasOwnProperty(parts[i])) { + return false } - i += 1 + p = (p[parts[i]]) } + return true } - function loadFiles(paths) { - var contents = [], i, p, c, async = false; - contents.length = paths.length; - function addContent(pos, path, content) { - content += "\n//# sourceURL=" + path; - content += "\n//@ sourceURL=" + path; - contents[pos] = content - } - function loadFile(pos) { - var path = dependencies[paths[pos]].dir + "/" + paths[pos]; - runtime.readFile(path, "utf8", function(err, content) { - if(err) { - throw err; - } - if(contents[pos] === undefined) { - addContent(pos, path, (content)) - } - }) + runtime.loadClasses = function(classnames, callback) { + if(IS_COMPILED_CODE || classnames.length === 0) { + return callback && callback() } - if(async) { - for(i = 0;i < paths.length;i += 1) { - loadedFiles[paths[i]] = 1; - loadFile(i) - } + dependencies = dependencies || loadDependenciesFromManifests(); + classnames = getLoadList(classnames, dependencies, isDefined); + if(classnames.length === 0) { + return callback && callback() } - for(i = paths.length - 1;i >= 0;i -= 1) { - loadedFiles[paths[i]] = 1; - if(contents[i] === undefined) { - p = paths[i]; - p = dependencies[p].dir + "/" + p; - c = runtime.readFileSync(p, "utf-8"); - addContent(i, p, (c)) + if(runtime.type() === "BrowserRuntime" && callback) { + loadFilesInBrowser(classnames, callback) + }else { + loadFiles(classnames); + if(callback) { + callback() } } - evalArray(paths, contents) - } - runtime.loadClass = function(classname) { - if(IS_COMPILED_CODE) { - return - } - var classpath = classPath(classname), paths; - if(loadedFiles.hasOwnProperty(classpath)) { - return - } - loadManifests(); - paths = getDependencies(classname); - loadFiles(paths) + }; + runtime.loadClass = function(classname, callback) { + runtime.loadClasses([classname], callback) } })(); (function() { @@ -1032,9 +1079,11 @@ var ops = {}; } var script = argv[0]; runtime.readFile(script, "utf8", function(err, code) { - var path = "", codestring = (code); - if(script.indexOf("/") !== -1) { - path = script.substring(0, script.indexOf("/")) + var path = "", pathEndIndex = script.lastIndexOf("/"), codestring = (code); + if(pathEndIndex !== -1) { + path = script.substring(0, pathEndIndex) + }else { + path = "." } runtime.setCurrentDirectory(path); function inner_run() { @@ -1451,11 +1500,13 @@ core.CSSUnits = function CSSUnits() { (function() { var browserQuirks; function getBrowserQuirks() { - var range, directBoundingRect, rangeBoundingRect, testContainer, testElement, detectedQuirks, window, document; + var range, directBoundingRect, rangeBoundingRect, testContainer, testElement, detectedQuirks, window, document, docElement, body, docOverflow, bodyOverflow, bodyHeight, bodyScroll; if(browserQuirks === undefined) { window = runtime.getWindow(); document = window && window.document; - browserQuirks = {rangeBCRIgnoresElementBCR:false, unscaledRangeClientRects:false}; + docElement = document.documentElement; + body = document.body; + browserQuirks = {rangeBCRIgnoresElementBCR:false, unscaledRangeClientRects:false, elementBCRIgnoresBodyScroll:false}; if(document) { testContainer = document.createElement("div"); testContainer.style.position = "absolute"; @@ -1464,7 +1515,7 @@ core.CSSUnits = function CSSUnits() { testContainer.style["-webkit-transform"] = "scale(2)"; testElement = document.createElement("div"); testContainer.appendChild(testElement); - document.body.appendChild(testContainer); + body.appendChild(testContainer); range = document.createRange(); range.selectNode(testElement); browserQuirks.rangeBCRIgnoresElementBCR = range.getClientRects().length === 0; @@ -1472,8 +1523,23 @@ core.CSSUnits = function CSSUnits() { directBoundingRect = testElement.getBoundingClientRect(); rangeBoundingRect = range.getBoundingClientRect(); browserQuirks.unscaledRangeClientRects = Math.abs(directBoundingRect.height - rangeBoundingRect.height) > 2; + testContainer.style.transform = ""; + testContainer.style["-webkit-transform"] = ""; + docOverflow = docElement.style.overflow; + bodyOverflow = body.style.overflow; + bodyHeight = body.style.height; + bodyScroll = body.scrollTop; + docElement.style.overflow = "visible"; + body.style.overflow = "visible"; + body.style.height = "200%"; + body.scrollTop = body.scrollHeight; + browserQuirks.elementBCRIgnoresBodyScroll = range.getBoundingClientRect().top !== testElement.getBoundingClientRect().top; + body.scrollTop = bodyScroll; + body.style.height = bodyHeight; + body.style.overflow = bodyOverflow; + docElement.style.overflow = docOverflow; range.detach(); - document.body.removeChild(testContainer); + body.removeChild(testContainer); detectedQuirks = Object.keys(browserQuirks).map(function(quirk) { return quirk + ":" + String(browserQuirks[quirk]) }).join(", "); @@ -1509,10 +1575,28 @@ core.CSSUnits = function CSSUnits() { } return{container:c, offset:offset} } + function getPositionInContainingNode(node, container) { + var offset = 0, n; + while(node.parentNode !== container) { + runtime.assert(node.parentNode !== null, "parent is null"); + node = (node.parentNode) + } + n = container.firstChild; + while(n !== node) { + offset += 1; + n = n.nextSibling + } + return offset + } function splitBoundaries(range) { - var modifiedNodes = [], end, splitStart, node, text; + var modifiedNodes = [], originalEndContainer, resetToContainerLength, end, splitStart, node, text, offset; if(range.startContainer.nodeType === Node.TEXT_NODE || range.endContainer.nodeType === Node.TEXT_NODE) { - end = range.endContainer && findStablePoint(range.endContainer, range.endOffset); + originalEndContainer = range.endContainer; + resetToContainerLength = range.endContainer.nodeType !== Node.TEXT_NODE ? range.endOffset === range.endContainer.childNodes.length : false; + end = findStablePoint(range.endContainer, range.endOffset); + if(end.container === originalEndContainer) { + originalEndContainer = null + } range.setEnd(end.container, end.offset); node = range.endContainer; if(range.endOffset !== 0 && node.nodeType === Node.TEXT_NODE) { @@ -1532,6 +1616,18 @@ core.CSSUnits = function CSSUnits() { range.setStart(splitStart, 0) } } + if(originalEndContainer !== null) { + node = range.endContainer; + while(node.parentNode && node.parentNode !== originalEndContainer) { + node = node.parentNode + } + if(resetToContainerLength) { + offset = originalEndContainer.childNodes.length + }else { + offset = getPositionInContainingNode(node, originalEndContainer) + } + range.setEnd(originalEndContainer, offset) + } } return modifiedNodes } @@ -1544,26 +1640,43 @@ core.CSSUnits = function CSSUnits() { return range1.compareBoundaryPoints(Range.END_TO_START, range2) <= 0 && range1.compareBoundaryPoints(Range.START_TO_END, range2) >= 0 } this.rangesIntersect = rangesIntersect; - function getNodesInRange(range, nodeFilter) { - var document = range.startContainer.ownerDocument, elements = [], rangeRoot = range.commonAncestorContainer, root = (rangeRoot.nodeType === Node.TEXT_NODE ? rangeRoot.parentNode : rangeRoot), n, filterResult, treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ALL, nodeFilter, false); - treeWalker.currentNode = range.startContainer; - n = range.startContainer; - while(n) { - filterResult = nodeFilter(n); - if(filterResult === NodeFilter.FILTER_ACCEPT) { - elements.push(n) + function maximumOffset(node) { + return node.nodeType === Node.TEXT_NODE ? (node).length : node.childNodes.length + } + function getNodesInRange(range, nodeFilter, whatToShow) { + var document = range.startContainer.ownerDocument, elements = [], rangeRoot = range.commonAncestorContainer, root = (rangeRoot.nodeType === Node.TEXT_NODE ? rangeRoot.parentNode : rangeRoot), treeWalker = document.createTreeWalker(root, whatToShow, nodeFilter, false), currentNode, lastNodeInRange, endNodeCompareFlags, comparePositionResult; + if(range.endContainer.childNodes[range.endOffset - 1]) { + lastNodeInRange = (range.endContainer.childNodes[range.endOffset - 1]); + endNodeCompareFlags = Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_CONTAINED_BY + }else { + lastNodeInRange = (range.endContainer); + endNodeCompareFlags = Node.DOCUMENT_POSITION_PRECEDING + } + if(range.startContainer.childNodes[range.startOffset]) { + currentNode = (range.startContainer.childNodes[range.startOffset]); + treeWalker.currentNode = currentNode + }else { + if(range.startOffset === maximumOffset(range.startContainer)) { + currentNode = (range.startContainer); + treeWalker.currentNode = currentNode; + treeWalker.lastChild(); + currentNode = treeWalker.nextNode() }else { - if(filterResult === NodeFilter.FILTER_REJECT) { - break - } + currentNode = (range.startContainer); + treeWalker.currentNode = currentNode } - n = n.parentNode } - elements.reverse(); - n = treeWalker.nextNode(); - while(n) { - elements.push(n); - n = treeWalker.nextNode() + if(currentNode && nodeFilter(currentNode) === NodeFilter.FILTER_ACCEPT) { + elements.push(currentNode) + } + currentNode = treeWalker.nextNode(); + while(currentNode) { + comparePositionResult = lastNodeInRange.compareDocumentPosition(currentNode); + if(comparePositionResult !== 0 && (comparePositionResult & endNodeCompareFlags) === 0) { + break + } + elements.push(currentNode); + currentNode = treeWalker.nextNode() } return elements } @@ -1624,8 +1737,8 @@ core.CSSUnits = function CSSUnits() { removeUnwantedNodes(node, shouldRemove); node = next } - if(shouldRemove(targetNode)) { - parent = mergeIntoParent(targetNode) + if(parent && shouldRemove(targetNode)) { + mergeIntoParent(targetNode) } return parent } @@ -1640,14 +1753,6 @@ core.CSSUnits = function CSSUnits() { return e } this.getElementsByTagNameNS = getElementsByTagNameNS; - function rangeIntersectsNode(range, node) { - var nodeRange = node.ownerDocument.createRange(), result; - nodeRange.selectNodeContents(node); - result = rangesIntersect(range, nodeRange); - nodeRange.detach(); - return result - } - this.rangeIntersectsNode = rangeIntersectsNode; function containsNode(parent, descendant) { return parent === descendant || (parent).contains((descendant)) } @@ -1655,19 +1760,6 @@ core.CSSUnits = function CSSUnits() { function containsNodeForBrokenWebKit(parent, descendant) { return parent === descendant || Boolean(parent.compareDocumentPosition(descendant) & Node.DOCUMENT_POSITION_CONTAINED_BY) } - function getPositionInContainingNode(node, container) { - var offset = 0, n; - while(node.parentNode !== container) { - runtime.assert(node.parentNode !== null, "parent is null"); - node = (node.parentNode) - } - n = container.firstChild; - while(n !== node) { - offset += 1; - n = n.nextSibling - } - return offset - } function comparePoints(c1, o1, c2, o2) { if(c1 === c2) { return o2 - o1 @@ -1699,11 +1791,15 @@ core.CSSUnits = function CSSUnits() { } this.adaptRangeDifferenceToZoomLevel = adaptRangeDifferenceToZoomLevel; function getBoundingClientRect(node) { - var doc = (node.ownerDocument), quirks = getBrowserQuirks(), range, element; + var doc = (node.ownerDocument), quirks = getBrowserQuirks(), range, element, rect, body = doc.body; if(quirks.unscaledRangeClientRects === false || quirks.rangeBCRIgnoresElementBCR) { if(node.nodeType === Node.ELEMENT_NODE) { element = (node); - return element.getBoundingClientRect() + rect = element.getBoundingClientRect(); + if(quirks.elementBCRIgnoresBodyScroll) { + return({left:rect.left + body.scrollLeft, right:rect.right + body.scrollLeft, top:rect.top + body.scrollTop, bottom:rect.bottom + body.scrollTop}) + } + return rect } } range = getSharedRange(doc); @@ -1757,17 +1853,20 @@ core.CSSUnits = function CSSUnits() { this.getKeyValRepresentationOfNode = getKeyValRepresentationOfNode; function mapObjOntoNode(node, properties, nsResolver) { Object.keys(properties).forEach(function(key) { - var parts = key.split(":"), prefix = parts[0], localName = parts[1], ns = nsResolver(prefix), value = properties[key], element; - if(typeof value === "object" && Object.keys((value)).length) { - if(ns) { - element = (node.getElementsByTagNameNS(ns, localName)[0]) || node.ownerDocument.createElementNS(ns, key) - }else { - element = (node.getElementsByTagName(localName)[0]) || node.ownerDocument.createElement(key) + var parts = key.split(":"), prefix = parts[0], localName = parts[1], ns = nsResolver(prefix), value = properties[key], valueType = typeof value, element; + if(valueType === "object") { + if(Object.keys((value)).length) { + if(ns) { + element = (node.getElementsByTagNameNS(ns, localName)[0]) || node.ownerDocument.createElementNS(ns, key) + }else { + element = (node.getElementsByTagName(localName)[0]) || node.ownerDocument.createElement(key) + } + node.appendChild(element); + mapObjOntoNode(element, (value), nsResolver) } - node.appendChild(element); - mapObjOntoNode(element, (value), nsResolver) }else { if(ns) { + runtime.assert(valueType === "number" || valueType === "string", "attempting to map unsupported type '" + valueType + "' (key: " + key + ")"); node.setAttributeNS(ns, key, String(value)) } } @@ -1790,6 +1889,139 @@ core.CSSUnits = function CSSUnits() { }; return core.DomUtils })(); +core.Cursor = function Cursor(document, memberId) { + var cursorns = "urn:webodf:names:cursor", cursorNode = document.createElementNS(cursorns, "cursor"), anchorNode = document.createElementNS(cursorns, "anchor"), forwardSelection, recentlyModifiedNodes = [], selectedRange = (document.createRange()), isCollapsed, domUtils = new core.DomUtils; + function putIntoTextNode(node, container, offset) { + runtime.assert(Boolean(container), "putCursorIntoTextNode: invalid container"); + var parent = container.parentNode; + runtime.assert(Boolean(parent), "putCursorIntoTextNode: container without parent"); + runtime.assert(offset >= 0 && offset <= container.length, "putCursorIntoTextNode: offset is out of bounds"); + if(offset === 0) { + parent.insertBefore(node, container) + }else { + if(offset === container.length) { + parent.insertBefore(node, container.nextSibling) + }else { + container.splitText(offset); + parent.insertBefore(node, container.nextSibling) + } + } + } + function removeNode(node) { + if(node.parentNode) { + recentlyModifiedNodes.push(node.previousSibling); + recentlyModifiedNodes.push(node.nextSibling); + node.parentNode.removeChild(node) + } + } + function putNode(node, container, offset) { + if(container.nodeType === Node.TEXT_NODE) { + putIntoTextNode(node, (container), offset) + }else { + if(container.nodeType === Node.ELEMENT_NODE) { + container.insertBefore(node, container.childNodes.item(offset)) + } + } + recentlyModifiedNodes.push(node.previousSibling); + recentlyModifiedNodes.push(node.nextSibling) + } + function getStartNode() { + return forwardSelection ? anchorNode : cursorNode + } + function getEndNode() { + return forwardSelection ? cursorNode : anchorNode + } + this.getNode = function() { + return cursorNode + }; + this.getAnchorNode = function() { + return anchorNode.parentNode ? anchorNode : cursorNode + }; + this.getSelectedRange = function() { + if(isCollapsed) { + selectedRange.setStartBefore(cursorNode); + selectedRange.collapse(true) + }else { + selectedRange.setStartAfter(getStartNode()); + selectedRange.setEndBefore(getEndNode()) + } + return selectedRange + }; + this.setSelectedRange = function(range, isForwardSelection) { + if(selectedRange && selectedRange !== range) { + selectedRange.detach() + } + selectedRange = range; + forwardSelection = isForwardSelection !== false; + isCollapsed = range.collapsed; + if(range.collapsed) { + removeNode(anchorNode); + removeNode(cursorNode); + putNode(cursorNode, (range.startContainer), range.startOffset) + }else { + removeNode(anchorNode); + removeNode(cursorNode); + putNode(getEndNode(), (range.endContainer), range.endOffset); + putNode(getStartNode(), (range.startContainer), range.startOffset) + } + recentlyModifiedNodes.forEach(domUtils.normalizeTextNodes); + recentlyModifiedNodes.length = 0 + }; + this.hasForwardSelection = function() { + return forwardSelection + }; + this.remove = function() { + removeNode(cursorNode); + recentlyModifiedNodes.forEach(domUtils.normalizeTextNodes); + recentlyModifiedNodes.length = 0 + }; + function init() { + cursorNode.setAttributeNS(cursorns, "memberId", memberId); + anchorNode.setAttributeNS(cursorns, "memberId", memberId) + } + init() +}; +/* + + Copyright (C) 2012-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/ +*/ +core.Destroyable = function Destroyable() { +}; +core.Destroyable.prototype.destroy = function(callback) { +}; /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -1839,8 +2071,7 @@ core.EventNotifier = function EventNotifier(eventIds) { }; this.subscribe = function(eventId, cb) { runtime.assert(eventListener.hasOwnProperty(eventId), 'tried to subscribe to unknown event "' + eventId + '"'); - eventListener[eventId].push(cb); - runtime.log('event "' + eventId + '" subscribed.') + eventListener[eventId].push(cb) }; this.unsubscribe = function(eventId, cb) { var cbIndex; @@ -1850,7 +2081,6 @@ core.EventNotifier = function EventNotifier(eventIds) { if(cbIndex !== -1) { eventListener[eventId].splice(cbIndex, 1) } - runtime.log('event "' + eventId + '" unsubscribed.') }; function init() { var i, eventId; @@ -2076,9 +2306,43 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa walker.currentNode = currentNode; return sibling }; + function moveToAcceptedNode() { + var node = walker.currentNode, filterResult, moveResult; + filterResult = nodeFilter(node); + if(node !== root) { + node = node.parentNode; + while(node && node !== root) { + if(nodeFilter(node) === FILTER_REJECT) { + walker.currentNode = node; + filterResult = FILTER_REJECT + } + node = node.parentNode + } + } + if(filterResult === FILTER_REJECT) { + currentPos = 1; + moveResult = self.nextPosition() + }else { + if(filterResult === FILTER_ACCEPT) { + moveResult = true + }else { + moveResult = self.nextPosition() + } + } + if(moveResult) { + runtime.assert(nodeFilter(walker.currentNode) === FILTER_ACCEPT, "moveToAcceptedNode did not result in walker being on an accepted node") + } + return moveResult + } + this.setPositionBeforeElement = function(element) { + runtime.assert(Boolean(element), "setPositionBeforeElement called without element"); + walker.currentNode = element; + currentPos = 0; + return moveToAcceptedNode() + }; this.setUnfilteredPosition = function(container, offset) { - var filterResult, node, text; - runtime.assert(container !== null && container !== undefined, "PositionIterator.setUnfilteredPosition called without container"); + var text; + runtime.assert(Boolean(container), "PositionIterator.setUnfilteredPosition called without container"); walker.currentNode = container; if(container.nodeType === TEXT_NODE) { currentPos = offset; @@ -2098,30 +2362,13 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa } return true } - filterResult = nodeFilter(container); - node = container.parentNode; - while(node && (node !== root && filterResult === FILTER_ACCEPT)) { - filterResult = nodeFilter(node); - if(filterResult !== FILTER_ACCEPT) { - walker.currentNode = node - } - node = node.parentNode - } - if(offset < container.childNodes.length && filterResult !== NodeFilter.FILTER_REJECT) { + if(offset < container.childNodes.length) { walker.currentNode = (container.childNodes.item(offset)); - filterResult = nodeFilter(walker.currentNode); currentPos = 0 }else { currentPos = 1 } - if(filterResult === NodeFilter.FILTER_REJECT) { - currentPos = 1 - } - if(filterResult !== FILTER_ACCEPT) { - return self.nextPosition() - } - runtime.assert(nodeFilter(walker.currentNode) === FILTER_ACCEPT, "PositionIterater.setUnfilteredPosition call resulted in an non-visible node being set"); - return true + return moveToAcceptedNode() }; this.moveToEnd = function() { walker.currentNode = root; @@ -2137,6 +2384,9 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa currentPos = 1 } }; + this.isBeforeNode = function() { + return currentPos === 0 + }; this.getNodeFilter = function() { return nodeFilter }; @@ -2149,7 +2399,7 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa } nodeFilter = (f.acceptNode); nodeFilter.acceptNode = nodeFilter; - whatToShow = whatToShow || 4294967295; + whatToShow = whatToShow || NodeFilter.SHOW_ALL; runtime.assert(root.nodeType !== Node.TEXT_NODE, "Internet Explorer doesn't allow tree walker roots to be text nodes"); walker = root.ownerDocument.createTreeWalker(root, whatToShow, nodeFilter, expandEntityReferences); currentPos = 0; @@ -2159,6 +2409,29 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa } init() }; +core.PositionFilter = function PositionFilter() { +}; +core.PositionFilter.FilterResult = {FILTER_ACCEPT:1, FILTER_REJECT:2, FILTER_SKIP:3}; +core.PositionFilter.prototype.acceptPosition = function(point) { +}; +(function() { + return core.PositionFilter +})(); +core.PositionFilterChain = function PositionFilterChain() { + var filterChain = [], FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT; + this.acceptPosition = function(iterator) { + var i; + for(i = 0;i < filterChain.length;i += 1) { + if(filterChain[i].acceptPosition(iterator) === FILTER_REJECT) { + return FILTER_REJECT + } + } + return FILTER_ACCEPT + }; + this.addFilter = function(filterInstance) { + filterChain.push(filterInstance) + } +}; core.zip_HuftNode = function() { this.e = 0; this.b = 0; @@ -2780,8 +3053,126 @@ core.ScheduledTask = function ScheduledTask(fn, delay) { callback() } }; -core.NamedFunction; -core.NamedAsyncFunction; +/* + + Copyright (C) 2014 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/ +*/ +core.StepIterator = function StepIterator(filter, iterator) { + var FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, cachedContainer, cachedOffset, cachedFilterResult; + function resetCache() { + cachedContainer = null; + cachedOffset = undefined; + cachedFilterResult = undefined + } + function isStep() { + if(cachedFilterResult === undefined) { + cachedFilterResult = filter.acceptPosition(iterator) === FILTER_ACCEPT + } + return(cachedFilterResult) + } + this.isStep = isStep; + function setPosition(newContainer, newOffset) { + resetCache(); + return iterator.setUnfilteredPosition(newContainer, newOffset) + } + this.setPosition = setPosition; + function container() { + if(!cachedContainer) { + cachedContainer = iterator.container() + } + return cachedContainer + } + this.container = container; + function offset() { + if(cachedOffset === undefined) { + cachedOffset = iterator.unfilteredDomOffset() + } + return(cachedOffset) + } + this.offset = offset; + function nextStep() { + resetCache(); + while(iterator.nextPosition()) { + resetCache(); + if(isStep()) { + return true + } + } + return false + } + this.nextStep = nextStep; + function previousStep() { + resetCache(); + while(iterator.previousPosition()) { + resetCache(); + if(isStep()) { + return true + } + } + return false + } + this.previousStep = previousStep; + this.roundToClosestStep = function() { + var currentContainer = container(), currentOffset = offset(), isAtStep = isStep(); + if(!isAtStep) { + isAtStep = previousStep(); + if(!isAtStep) { + setPosition(currentContainer, currentOffset); + isAtStep = nextStep() + } + } + return isAtStep + }; + this.roundToPreviousStep = function() { + var isAtStep = isStep(); + if(!isAtStep) { + isAtStep = previousStep() + } + return isAtStep + }; + this.roundToNextStep = function() { + var isAtStep = isStep(); + if(!isAtStep) { + isAtStep = nextStep() + } + return isAtStep + } +}; +core.TestData; +core.AsyncTestData; core.UnitTest = function UnitTest() { }; core.UnitTest.prototype.setUp = function() { @@ -2818,17 +3209,61 @@ core.UnitTest.createOdtDocument = function(xml, namespaceMap) { xmlDoc += "</office:document>"; return runtime.parseXML(xmlDoc) }; -core.UnitTestRunner = function UnitTestRunner() { - var failedTests = 0, areObjectsEqual; +core.UnitTestLogger = function UnitTestLogger() { + var messages = [], errors = 0, start = 0, suite = "", test = ""; + this.startTest = function(suiteName, testName) { + messages = []; + errors = 0; + suite = suiteName; + test = testName; + start = (new Date).getTime() + }; + this.endTest = function() { + var end = (new Date).getTime(); + return{description:test, suite:[suite, test], success:errors === 0, log:messages, time:end - start} + }; + this.debug = function(msg) { + messages.push({category:"debug", message:msg}) + }; + this.fail = function(msg) { + errors += 1; + messages.push({category:"fail", message:msg}) + }; + this.pass = function(msg) { + messages.push({category:"pass", message:msg}) + } +}; +core.UnitTestRunner = function UnitTestRunner(resourcePrefix, logger) { + var failedTests = 0, failedTestsOnBeginExpectFail, areObjectsEqual, expectFail = false; + this.resourcePrefix = function() { + return resourcePrefix + }; + this.beginExpectFail = function() { + failedTestsOnBeginExpectFail = failedTests; + expectFail = true + }; + this.endExpectFail = function() { + var hasNoFailedTests = failedTestsOnBeginExpectFail === failedTests; + expectFail = false; + failedTests = failedTestsOnBeginExpectFail; + if(hasNoFailedTests) { + failedTests += 1; + logger.fail("Expected at least one failed test, but none registered.") + } + }; function debug(msg) { - runtime.log(msg) + logger.debug(msg) } function testFailed(msg) { failedTests += 1; - runtime.log("fail", msg) + if(!expectFail) { + logger.fail(msg) + }else { + logger.debug(msg) + } } function testPassed(msg) { - runtime.log("pass", msg) + logger.pass(msg) } function areArraysEqual(a, b) { var i; @@ -2917,6 +3352,9 @@ core.UnitTestRunner = function UnitTestRunner() { if(actual === expected) { return true } + if(actual === null || expected === null) { + return false + } if(typeof expected === "number" && isNaN(expected)) { return typeof actual === "number" && isNaN(actual) } @@ -2925,9 +3363,9 @@ core.UnitTestRunner = function UnitTestRunner() { } if(typeof expected === "object" && typeof actual === "object") { if((expected).constructor === Element || (expected).constructor === Node) { - return areNodesEqual((expected), (actual)) + return areNodesEqual((actual), (expected)) } - return areObjectsEqual((expected), (actual)) + return areObjectsEqual((actual), (expected)) } return false } @@ -2999,6 +3437,7 @@ core.UnitTestRunner = function UnitTestRunner() { this.shouldBeNull = shouldBeNull; this.shouldBeNonNull = shouldBeNonNull; this.shouldBe = shouldBe; + this.testFailed = testFailed; this.countFailedTests = function() { return failedTests }; @@ -3016,12 +3455,32 @@ core.UnitTestRunner = function UnitTestRunner() { } }; core.UnitTester = function UnitTester() { - var failedTests = 0, results = {}; + var self = this, failedTests = 0, logger = new core.UnitTestLogger, results = {}, inBrowser = runtime.type() === "BrowserRuntime"; + this.resourcePrefix = ""; function link(text, code) { return"<span style='color:blue;cursor:pointer' onclick='" + code + "'>" + text + "</span>" } + this.reporter = function(r) { + var i, m; + if(inBrowser) { + runtime.log("<span>Running " + link(r.description, 'runTest("' + r.suite[0] + '","' + r.description + '")') + "</span>") + }else { + runtime.log("Running " + r.description) + } + if(!r.success) { + for(i = 0;i < r.log.length;i += 1) { + m = r.log[i]; + runtime.log(m.category, m.message) + } + } + }; + function report(r) { + if(self.reporter) { + self.reporter(r) + } + } this.runTests = function(TestClass, callback, testNames) { - var testName = Runtime.getFunctionName(TestClass) || "", tname, runner = new core.UnitTestRunner, test = new TestClass(runner), testResults = {}, i, t, tests, lastFailCount, inBrowser = runtime.type() === "BrowserRuntime"; + var testName = Runtime.getFunctionName(TestClass) || "", tname, runner = new core.UnitTestRunner(self.resourcePrefix, logger), test = new TestClass(runner), testResults = {}, i, t, tests, texpectFail, lastFailCount; if(results.hasOwnProperty(testName)) { runtime.log("Test " + testName + " has already run."); return @@ -3035,17 +3494,25 @@ core.UnitTester = function UnitTester() { for(i = 0;i < tests.length;i += 1) { t = tests[i].f; tname = tests[i].name; + texpectFail = tests[i].expectFail === true; if(testNames.length && testNames.indexOf(tname) === -1) { continue } - if(inBrowser) { - runtime.log("<span>Running " + link(tname, 'runTest("' + testName + '","' + tname + '")') + "</span>") - }else { - runtime.log("Running " + tname) - } lastFailCount = runner.countFailedTests(); test.setUp(); - t(); + logger.startTest(testName, tname); + if(texpectFail) { + runner.beginExpectFail() + } + try { + t() + }catch(e) { + runner.testFailed("Unexpected exception encountered: " + e.toString() + "\n" + e.stack) + } + if(texpectFail) { + runner.endExpectFail() + } + report(logger.endTest()); test.tearDown(); testResults[tname] = lastFailCount === runner.countFailedTests() } @@ -3057,15 +3524,26 @@ core.UnitTester = function UnitTester() { return } t = todo[0].f; - var fname = todo[0].name; - runtime.log("Running " + fname); + var fname = todo[0].name, expectFail = todo[0].expectFail === true; lastFailCount = runner.countFailedTests(); - test.setUp(); - t(function() { - test.tearDown(); - testResults[fname] = lastFailCount === runner.countFailedTests(); + if(testNames.length && testNames.indexOf(fname) === -1) { runAsyncTests(todo.slice(1)) - }) + }else { + test.setUp(); + logger.startTest(testName, fname); + if(expectFail) { + runner.beginExpectFail() + } + t(function() { + if(expectFail) { + runner.endExpectFail() + } + report(logger.endTest()); + test.tearDown(); + testResults[fname] = lastFailCount === runner.countFailedTests(); + runAsyncTests(todo.slice(1)) + }) + } } runAsyncTests(test.asyncTests()) }; @@ -3127,10 +3605,6 @@ core.Utils = function Utils() { Project home: http://www.webodf.org/ */ -runtime.loadClass("core.RawInflate"); -runtime.loadClass("core.ByteArray"); -runtime.loadClass("core.ByteArrayWriter"); -runtime.loadClass("core.Base64"); core.Zip = function Zip(url, entriesReadCallback) { var entries, filesize, nEntries, inflate = (new core.RawInflate).inflate, zip = this, base64 = new core.Base64; function crc32(data) { @@ -3504,104 +3978,13 @@ core.Zip = function Zip(url, entriesReadCallback) { } }) }; -gui.Avatar = function Avatar(parentElement, avatarInitiallyVisible) { - var self = this, handle, image, pendingImageUrl, displayShown = "block", displayHidden = "none"; - this.setColor = function(color) { - image.style.borderColor = color - }; - this.setImageUrl = function(url) { - if(self.isVisible()) { - image.src = url - }else { - pendingImageUrl = url - } - }; - this.isVisible = function() { - return handle.style.display === displayShown - }; - this.show = function() { - if(pendingImageUrl) { - image.src = pendingImageUrl; - pendingImageUrl = undefined - } - handle.style.display = displayShown - }; - this.hide = function() { - handle.style.display = displayHidden - }; - this.markAsFocussed = function(isFocussed) { - handle.className = isFocussed ? "active" : "" - }; - this.destroy = function(callback) { - parentElement.removeChild(handle); - callback() - }; - function init() { - var document = (parentElement.ownerDocument), htmlns = document.documentElement.namespaceURI; - handle = (document.createElementNS(htmlns, "div")); - image = (document.createElementNS(htmlns, "img")); - image.width = 64; - image.height = 64; - handle.appendChild(image); - handle.style.width = "64px"; - handle.style.height = "70px"; - handle.style.position = "absolute"; - handle.style.top = "-80px"; - handle.style.left = "-34px"; - handle.style.display = avatarInitiallyVisible ? displayShown : displayHidden; - parentElement.appendChild(handle) - } - init() +xmldom.LSSerializerFilter = function LSSerializerFilter() { }; -gui.EditInfoHandle = function EditInfoHandle(parentElement) { - var edits = [], handle, document = (parentElement.ownerDocument), htmlns = document.documentElement.namespaceURI, editinfons = "urn:webodf:names:editinfo"; - function renderEdits() { - var i, infoDiv, colorSpan, authorSpan, timeSpan; - handle.innerHTML = ""; - for(i = 0;i < edits.length;i += 1) { - infoDiv = document.createElementNS(htmlns, "div"); - infoDiv.className = "editInfo"; - colorSpan = document.createElementNS(htmlns, "span"); - colorSpan.className = "editInfoColor"; - colorSpan.setAttributeNS(editinfons, "editinfo:memberid", edits[i].memberid); - authorSpan = document.createElementNS(htmlns, "span"); - authorSpan.className = "editInfoAuthor"; - authorSpan.setAttributeNS(editinfons, "editinfo:memberid", edits[i].memberid); - timeSpan = document.createElementNS(htmlns, "span"); - timeSpan.className = "editInfoTime"; - timeSpan.setAttributeNS(editinfons, "editinfo:memberid", edits[i].memberid); - timeSpan.innerHTML = edits[i].time; - infoDiv.appendChild(colorSpan); - infoDiv.appendChild(authorSpan); - infoDiv.appendChild(timeSpan); - handle.appendChild(infoDiv) - } - } - this.setEdits = function(editArray) { - edits = editArray; - renderEdits() - }; - this.show = function() { - handle.style.display = "block" - }; - this.hide = function() { - handle.style.display = "none" - }; - this.destroy = function(callback) { - parentElement.removeChild(handle); - callback() - }; - function init() { - handle = (document.createElementNS(htmlns, "div")); - handle.setAttribute("class", "editInfoHandle"); - handle.style.display = "none"; - parentElement.appendChild(handle) - } - init() +xmldom.LSSerializerFilter.prototype.acceptNode = function(node) { }; /* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -3636,69 +4019,21 @@ gui.EditInfoHandle = function EditInfoHandle(parentElement) { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -gui.KeyboardHandler = function KeyboardHandler() { - var modifier = gui.KeyboardHandler.Modifier, defaultBinding = null, bindings = {}; - function getModifiers(e) { - var modifiers = modifier.None; - if(e.metaKey) { - modifiers |= modifier.Meta - } - if(e.ctrlKey) { - modifiers |= modifier.Ctrl - } - if(e.altKey) { - modifiers |= modifier.Alt - } - if(e.shiftKey) { - modifiers |= modifier.Shift - } - return modifiers - } - function getKeyCombo(keyCode, modifiers) { - if(!modifiers) { - modifiers = modifier.None - } - return keyCode + ":" + modifiers - } - this.setDefault = function(callback) { - defaultBinding = callback - }; - this.bind = function(keyCode, modifiers, callback) { - var keyCombo = getKeyCombo(keyCode, modifiers); - runtime.assert(bindings.hasOwnProperty(keyCombo) === false, "tried to overwrite the callback handler of key combo: " + keyCombo); - bindings[keyCombo] = callback - }; - this.unbind = function(keyCode, modifiers) { - var keyCombo = getKeyCombo(keyCode, modifiers); - delete bindings[keyCombo] - }; - this.reset = function() { - defaultBinding = null; - bindings = {} - }; - this.handleEvent = function(e) { - var keyCombo = getKeyCombo(e.keyCode, getModifiers(e)), callback = bindings[keyCombo], handled = false; - if(callback) { - handled = callback() +odf.OdfNodeFilter = function OdfNodeFilter() { + this.acceptNode = function(node) { + var result; + if(node.namespaceURI === "http://www.w3.org/1999/xhtml") { + result = NodeFilter.FILTER_SKIP }else { - if(defaultBinding !== null) { - handled = defaultBinding(e) - } - } - if(handled) { - if(e.preventDefault) { - e.preventDefault() + if(node.namespaceURI && node.namespaceURI.match(/^urn:webodf:/)) { + result = NodeFilter.FILTER_REJECT }else { - e.returnValue = false + result = NodeFilter.FILTER_ACCEPT } } + return result } }; -gui.KeyboardHandler.Modifier = {None:0, Meta:1, Ctrl:2, Alt:4, CtrlAlt:6, Shift:8, MetaShift:9, CtrlShift:10, AltShift:12}; -gui.KeyboardHandler.KeyCode = {Backspace:8, Tab:9, Clear:12, Enter:13, End:35, Home:36, Left:37, Up:38, Right:39, Down:40, Delete:46, A:65, B:66, C:67, D:68, E:69, F:70, G:71, H:72, I:73, J:74, K:75, L:76, M:77, N:78, O:79, P:80, Q:81, R:82, S:83, T:84, U:85, V:86, W:87, X:88, Y:89, Z:90}; -(function() { - return gui.KeyboardHandler -})(); /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -3768,559 +4103,6 @@ odf.Namespaces.lookupPrefix = function lookupPrefix(namespaceURI) { return map.hasOwnProperty(namespaceURI) ? map[namespaceURI] : null }; odf.Namespaces.lookupNamespaceURI.lookupNamespaceURI = odf.Namespaces.lookupNamespaceURI; -/* - - Copyright (C) 2012-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/ -*/ -runtime.loadClass("core.DomUtils"); -runtime.loadClass("odf.Namespaces"); -odf.OdfUtils = function OdfUtils() { - var textns = odf.Namespaces.textns, drawns = odf.Namespaces.drawns, whitespaceOnly = /^\s*$/, domUtils = new core.DomUtils; - function isImage(e) { - var name = e && e.localName; - return name === "image" && e.namespaceURI === drawns - } - this.isImage = isImage; - function isCharacterFrame(e) { - return e !== null && (e.nodeType === Node.ELEMENT_NODE && (e.localName === "frame" && (e.namespaceURI === drawns && (e).getAttributeNS(textns, "anchor-type") === "as-char"))) - } - this.isCharacterFrame = isCharacterFrame; - function isAnnotation(e) { - var name = e && e.localName; - return name === "annotation" && e.namespaceURI === odf.Namespaces.officens - } - function isAnnotationWrapper(e) { - var name = e && e.localName; - return name === "div" && (e).className === "annotationWrapper" - } - function isInlineRoot(e) { - return isAnnotation(e) || isAnnotationWrapper(e) - } - this.isInlineRoot = isInlineRoot; - this.isTextSpan = function(e) { - var name = e && e.localName; - return name === "span" && e.namespaceURI === textns - }; - function isParagraph(e) { - var name = e && e.localName; - return(name === "p" || name === "h") && e.namespaceURI === textns - } - this.isParagraph = isParagraph; - function getParagraphElement(node) { - while(node && !isParagraph(node)) { - node = node.parentNode - } - return node - } - this.getParagraphElement = getParagraphElement; - this.isWithinTrackedChanges = function(node, container) { - while(node && node !== container) { - if(node.namespaceURI === textns && node.localName === "tracked-changes") { - return true - } - node = node.parentNode - } - return false - }; - this.isListItem = function(e) { - var name = e && e.localName; - return name === "list-item" && e.namespaceURI === textns - }; - this.isLineBreak = function(e) { - var name = e && e.localName; - return name === "line-break" && e.namespaceURI === textns - }; - function isODFWhitespace(text) { - return/^[ \t\r\n]+$/.test(text) - } - this.isODFWhitespace = isODFWhitespace; - function isGroupingElement(n) { - if(n === null || n.nodeType !== Node.ELEMENT_NODE) { - return false - } - var e = (n), localName = e.localName; - return/^(span|p|h|a|meta)$/.test(localName) && e.namespaceURI === textns || localName === "span" && e.className === "annotationHighlight" - } - this.isGroupingElement = isGroupingElement; - function isCharacterElement(e) { - var n = e && e.localName, ns, r = false; - if(n) { - ns = e.namespaceURI; - if(ns === textns) { - r = n === "s" || (n === "tab" || n === "line-break") - } - } - return r - } - this.isCharacterElement = isCharacterElement; - function isAnchoredAsCharacterElement(e) { - return isCharacterElement(e) || (isCharacterFrame(e) || isInlineRoot(e)) - } - this.isAnchoredAsCharacterElement = isAnchoredAsCharacterElement; - function isSpaceElement(e) { - var n = e && e.localName, ns, r = false; - if(n) { - ns = e.namespaceURI; - if(ns === textns) { - r = n === "s" - } - } - return r - } - this.isSpaceElement = isSpaceElement; - function firstChild(node) { - while(node.firstChild !== null && isGroupingElement(node)) { - node = node.firstChild - } - return node - } - this.firstChild = firstChild; - function lastChild(node) { - while(node.lastChild !== null && isGroupingElement(node)) { - node = node.lastChild - } - return node - } - this.lastChild = lastChild; - function previousNode(node) { - while(!isParagraph(node) && node.previousSibling === null) { - node = (node.parentNode) - } - return isParagraph(node) ? null : lastChild((node.previousSibling)) - } - this.previousNode = previousNode; - function nextNode(node) { - while(!isParagraph(node) && node.nextSibling === null) { - node = (node.parentNode) - } - return isParagraph(node) ? null : firstChild((node.nextSibling)) - } - this.nextNode = nextNode; - function scanLeftForNonSpace(node) { - var r = false, text; - while(node) { - if(node.nodeType === Node.TEXT_NODE) { - text = (node); - if(text.length === 0) { - node = previousNode(text) - }else { - return!isODFWhitespace(text.data.substr(text.length - 1, 1)) - } - }else { - if(isAnchoredAsCharacterElement(node)) { - r = isSpaceElement(node) === false; - node = null - }else { - node = previousNode(node) - } - } - } - return r - } - this.scanLeftForNonSpace = scanLeftForNonSpace; - function lookLeftForCharacter(node) { - var text, r = 0, tl = 0; - if(node.nodeType === Node.TEXT_NODE) { - tl = (node).length - } - if(tl > 0) { - text = (node).data; - if(!isODFWhitespace(text.substr(tl - 1, 1))) { - r = 1 - }else { - if(tl === 1) { - r = scanLeftForNonSpace(previousNode(node)) ? 2 : 0 - }else { - r = isODFWhitespace(text.substr(tl - 2, 1)) ? 0 : 2 - } - } - }else { - if(isAnchoredAsCharacterElement(node)) { - r = 1 - } - } - return r - } - this.lookLeftForCharacter = lookLeftForCharacter; - function lookRightForCharacter(node) { - var r = false, l = 0; - if(node && node.nodeType === Node.TEXT_NODE) { - l = (node).length - } - if(l > 0) { - r = !isODFWhitespace((node).data.substr(0, 1)) - }else { - if(isAnchoredAsCharacterElement(node)) { - r = true - } - } - return r - } - this.lookRightForCharacter = lookRightForCharacter; - function scanLeftForAnyCharacter(node) { - var r = false, l; - node = node && lastChild(node); - while(node) { - if(node.nodeType === Node.TEXT_NODE) { - l = (node).length - }else { - l = 0 - } - if(l > 0 && !isODFWhitespace((node).data)) { - r = true; - break - } - if(isAnchoredAsCharacterElement(node)) { - r = true; - break - } - node = previousNode(node) - } - return r - } - this.scanLeftForAnyCharacter = scanLeftForAnyCharacter; - function scanRightForAnyCharacter(node) { - var r = false, l; - node = node && firstChild(node); - while(node) { - if(node.nodeType === Node.TEXT_NODE) { - l = (node).length - }else { - l = 0 - } - if(l > 0 && !isODFWhitespace((node).data)) { - r = true; - break - } - if(isAnchoredAsCharacterElement(node)) { - r = true; - break - } - node = nextNode(node) - } - return r - } - this.scanRightForAnyCharacter = scanRightForAnyCharacter; - function isTrailingWhitespace(textnode, offset) { - if(!isODFWhitespace(textnode.data.substr(offset))) { - return false - } - return!scanRightForAnyCharacter(nextNode(textnode)) - } - this.isTrailingWhitespace = isTrailingWhitespace; - function isSignificantWhitespace(textNode, offset) { - var text = textNode.data, result; - if(!isODFWhitespace(text[offset])) { - return false - } - if(isAnchoredAsCharacterElement(textNode.parentNode)) { - return false - } - if(offset > 0) { - if(!isODFWhitespace(text[offset - 1])) { - result = true - } - }else { - if(scanLeftForNonSpace(previousNode(textNode))) { - result = true - } - } - if(result === true) { - return isTrailingWhitespace(textNode, offset) ? false : true - } - return false - } - this.isSignificantWhitespace = isSignificantWhitespace; - this.isDowngradableSpaceElement = function(node) { - if(node.namespaceURI === textns && node.localName === "s") { - return scanLeftForNonSpace(previousNode(node)) && scanRightForAnyCharacter(nextNode(node)) - } - return false - }; - function getFirstNonWhitespaceChild(node) { - var child = node && node.firstChild; - while(child && (child.nodeType === Node.TEXT_NODE && whitespaceOnly.test(child.nodeValue))) { - child = child.nextSibling - } - return child - } - this.getFirstNonWhitespaceChild = getFirstNonWhitespaceChild; - function parseLength(length) { - var re = /(-?[0-9]*[0-9][0-9]*(\.[0-9]*)?|0+\.[0-9]*[1-9][0-9]*|\.[0-9]*[1-9][0-9]*)((cm)|(mm)|(in)|(pt)|(pc)|(px)|(%))/, m = re.exec(length); - if(!m) { - return null - } - return{value:parseFloat(m[1]), unit:m[3]} - } - this.parseLength = parseLength; - function parsePositiveLength(length) { - var result = parseLength(length); - if(result && (result.value <= 0 || result.unit === "%")) { - return null - } - return result - } - function parseNonNegativeLength(length) { - var result = parseLength(length); - if(result && (result.value < 0 || result.unit === "%")) { - return null - } - return result - } - this.parseNonNegativeLength = parseNonNegativeLength; - function parsePercentage(length) { - var result = parseLength(length); - if(result && result.unit !== "%") { - return null - } - return result - } - function parseFoFontSize(fontSize) { - return parsePositiveLength(fontSize) || parsePercentage(fontSize) - } - this.parseFoFontSize = parseFoFontSize; - function parseFoLineHeight(lineHeight) { - return parseNonNegativeLength(lineHeight) || parsePercentage(lineHeight) - } - this.parseFoLineHeight = parseFoLineHeight; - function item(a, i) { - return a[i] - } - function getImpactedParagraphs(range) { - var i, l, e, outerContainer = (range.commonAncestorContainer), impactedParagraphs = [], filtered = []; - if(outerContainer.nodeType === Node.ELEMENT_NODE) { - impactedParagraphs = domUtils.getElementsByTagNameNS(outerContainer, textns, "p").concat(domUtils.getElementsByTagNameNS(outerContainer, textns, "h")) - } - while(outerContainer && !isParagraph(outerContainer)) { - outerContainer = outerContainer.parentNode - } - if(outerContainer) { - impactedParagraphs.push(outerContainer) - } - l = impactedParagraphs.length; - for(i = 0;i < l;i += 1) { - e = item(impactedParagraphs, i); - if(domUtils.rangeIntersectsNode(range, e)) { - filtered.push(e) - } - } - return filtered - } - this.getImpactedParagraphs = getImpactedParagraphs; - function isAcceptedNode(node) { - switch(node.namespaceURI) { - case odf.Namespaces.drawns: - ; - case odf.Namespaces.svgns: - ; - case odf.Namespaces.dr3dns: - return false; - case odf.Namespaces.textns: - switch(node.localName) { - case "note-body": - ; - case "ruby-text": - return false - } - break; - case odf.Namespaces.officens: - switch(node.localName) { - case "annotation": - ; - case "binary-data": - ; - case "event-listeners": - return false - } - break; - default: - switch(node.localName) { - case "editinfo": - return false - } - break - } - return true - } - function isSignificantTextContent(textNode) { - return Boolean(getParagraphElement(textNode) && (!isODFWhitespace(textNode.textContent) || isSignificantWhitespace(textNode, 0))) - } - function includeNode(range, nodeRange, includePartial) { - return includePartial && domUtils.rangesIntersect(range, nodeRange) || domUtils.containsRange(range, nodeRange) - } - function getTextNodes(range, includePartial) { - var document = range.startContainer.ownerDocument, nodeRange = document.createRange(), textNodes; - function nodeFilter(node) { - nodeRange.selectNodeContents(node); - if(node.nodeType === Node.TEXT_NODE) { - if(includeNode(range, nodeRange, includePartial)) { - return isSignificantTextContent((node)) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT - } - }else { - if(domUtils.rangesIntersect(range, nodeRange)) { - if(isAcceptedNode(node)) { - return NodeFilter.FILTER_SKIP - } - } - } - return NodeFilter.FILTER_REJECT - } - textNodes = domUtils.getNodesInRange(range, nodeFilter); - nodeRange.detach(); - return textNodes - } - this.getTextNodes = getTextNodes; - this.getTextElements = function(range, includePartial, includeInsignificantWhitespace) { - var document = range.startContainer.ownerDocument, nodeRange = document.createRange(), elements; - function nodeFilter(node) { - nodeRange.selectNodeContents(node); - if(isCharacterElement(node.parentNode)) { - return NodeFilter.FILTER_REJECT - } - if(node.nodeType === Node.TEXT_NODE) { - if(includeNode(range, nodeRange, includePartial)) { - if(includeInsignificantWhitespace || isSignificantTextContent((node))) { - return NodeFilter.FILTER_ACCEPT - } - } - }else { - if(isAnchoredAsCharacterElement(node)) { - if(includeNode(range, nodeRange, includePartial)) { - return NodeFilter.FILTER_ACCEPT - } - }else { - if(isAcceptedNode(node) || isGroupingElement(node)) { - return NodeFilter.FILTER_SKIP - } - } - } - return NodeFilter.FILTER_REJECT - } - elements = domUtils.getNodesInRange(range, nodeFilter); - nodeRange.detach(); - return elements - }; - this.getParagraphElements = function(range) { - var document = range.startContainer.ownerDocument, nodeRange = document.createRange(), elements; - function nodeFilter(node) { - nodeRange.selectNodeContents(node); - if(isParagraph(node)) { - if(domUtils.rangesIntersect(range, nodeRange)) { - return NodeFilter.FILTER_ACCEPT - } - }else { - if(isAcceptedNode(node) || isGroupingElement(node)) { - return NodeFilter.FILTER_SKIP - } - } - return NodeFilter.FILTER_REJECT - } - elements = domUtils.getNodesInRange(range, nodeFilter); - nodeRange.detach(); - return elements - }; - this.getImageElements = function(range) { - var document = range.startContainer.ownerDocument, nodeRange = document.createRange(), elements; - function nodeFilter(node) { - nodeRange.selectNodeContents(node); - if(isImage(node) && domUtils.containsRange(range, nodeRange)) { - return NodeFilter.FILTER_ACCEPT - } - return NodeFilter.FILTER_SKIP - } - elements = domUtils.getNodesInRange(range, nodeFilter); - nodeRange.detach(); - return elements - } -}; -/* - - 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/ -*/ -ops.Server = function Server() { -}; -ops.Server.prototype.connect = function(timeout, cb) { -}; -ops.Server.prototype.networkStatus = function() { -}; -ops.Server.prototype.login = function(login, password, successCb, failCb) { -}; -ops.Server.prototype.joinSession = function(userId, sessionId, successCb, failCb) { -}; -ops.Server.prototype.leaveSession = function(sessionId, memberId, successCb, failCb) { -}; -ops.Server.prototype.getGenesisUrl = function(sessionId) { -}; -xmldom.LSSerializerFilter = function LSSerializerFilter() { -}; -xmldom.LSSerializerFilter.prototype.acceptNode = function(node) { -}; xmldom.XPathIterator = function XPathIterator() { }; xmldom.XPathIterator.prototype.next = function() { @@ -4563,308 +4345,6 @@ function createXPathSingleton() { return{getODFElementsWithXPath:getODFElementsWithXPath} } xmldom.XPath = createXPathSingleton(); -runtime.loadClass("core.DomUtils"); -core.Cursor = function Cursor(document, memberId) { - var cursorns = "urn:webodf:names:cursor", cursorNode = document.createElementNS(cursorns, "cursor"), anchorNode = document.createElementNS(cursorns, "anchor"), forwardSelection, recentlyModifiedNodes = [], selectedRange = (document.createRange()), isCollapsed, domUtils = new core.DomUtils; - function putIntoTextNode(node, container, offset) { - runtime.assert(Boolean(container), "putCursorIntoTextNode: invalid container"); - var parent = container.parentNode; - runtime.assert(Boolean(parent), "putCursorIntoTextNode: container without parent"); - runtime.assert(offset >= 0 && offset <= container.length, "putCursorIntoTextNode: offset is out of bounds"); - if(offset === 0) { - parent.insertBefore(node, container) - }else { - if(offset === container.length) { - parent.insertBefore(node, container.nextSibling) - }else { - container.splitText(offset); - parent.insertBefore(node, container.nextSibling) - } - } - } - function removeNode(node) { - if(node.parentNode) { - recentlyModifiedNodes.push(node.previousSibling); - recentlyModifiedNodes.push(node.nextSibling); - node.parentNode.removeChild(node) - } - } - function putNode(node, container, offset) { - if(container.nodeType === Node.TEXT_NODE) { - putIntoTextNode(node, (container), offset) - }else { - if(container.nodeType === Node.ELEMENT_NODE) { - container.insertBefore(node, container.childNodes.item(offset)) - } - } - recentlyModifiedNodes.push(node.previousSibling); - recentlyModifiedNodes.push(node.nextSibling) - } - function getStartNode() { - return forwardSelection ? anchorNode : cursorNode - } - function getEndNode() { - return forwardSelection ? cursorNode : anchorNode - } - this.getNode = function() { - return cursorNode - }; - this.getAnchorNode = function() { - return anchorNode.parentNode ? anchorNode : cursorNode - }; - this.getSelectedRange = function() { - if(isCollapsed) { - selectedRange.setStartBefore(cursorNode); - selectedRange.collapse(true) - }else { - selectedRange.setStartAfter(getStartNode()); - selectedRange.setEndBefore(getEndNode()) - } - return selectedRange - }; - this.setSelectedRange = function(range, isForwardSelection) { - if(selectedRange && selectedRange !== range) { - selectedRange.detach() - } - selectedRange = range; - forwardSelection = isForwardSelection !== false; - isCollapsed = range.collapsed; - if(range.collapsed) { - removeNode(anchorNode); - removeNode(cursorNode); - putNode(cursorNode, (range.startContainer), range.startOffset) - }else { - removeNode(anchorNode); - removeNode(cursorNode); - putNode(getEndNode(), (range.endContainer), range.endOffset); - putNode(getStartNode(), (range.startContainer), range.startOffset) - } - recentlyModifiedNodes.forEach(domUtils.normalizeTextNodes); - recentlyModifiedNodes.length = 0 - }; - this.hasForwardSelection = function() { - return forwardSelection - }; - this.remove = function() { - removeNode(cursorNode); - recentlyModifiedNodes.forEach(domUtils.normalizeTextNodes); - recentlyModifiedNodes.length = 0 - }; - function init() { - cursorNode.setAttributeNS(cursorns, "memberId", memberId); - anchorNode.setAttributeNS(cursorns, "memberId", memberId) - } - init() -}; -runtime.loadClass("core.PositionIterator"); -core.PositionFilter = function PositionFilter() { -}; -core.PositionFilter.FilterResult = {FILTER_ACCEPT:1, FILTER_REJECT:2, FILTER_SKIP:3}; -core.PositionFilter.prototype.acceptPosition = function(point) { -}; -(function() { - return core.PositionFilter -})(); -runtime.loadClass("core.PositionFilter"); -core.PositionFilterChain = function PositionFilterChain() { - var filterChain = {}, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT; - this.acceptPosition = function(iterator) { - var filterName; - for(filterName in filterChain) { - if(filterChain.hasOwnProperty(filterName)) { - if(filterChain[filterName].acceptPosition(iterator) === FILTER_REJECT) { - return FILTER_REJECT - } - } - } - return FILTER_ACCEPT - }; - this.addFilter = function(filterName, filterInstance) { - filterChain[filterName] = filterInstance - }; - this.removeFilter = function(filterName) { - delete filterChain[filterName] - } -}; -/* - - Copyright (C) 2012-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/ -*/ -gui.AnnotatableCanvas = function AnnotatableCanvas() { -}; -gui.AnnotatableCanvas.prototype.refreshSize = function() { -}; -gui.AnnotatableCanvas.prototype.getZoomLevel = function() { -}; -gui.AnnotatableCanvas.prototype.getSizer = function() { -}; -gui.AnnotationViewManager = function AnnotationViewManager(canvas, odfFragment, annotationsPane) { - var annotations = [], doc = odfFragment.ownerDocument, odfUtils = new odf.OdfUtils, CONNECTOR_MARGIN = 30, NOTE_MARGIN = 20, window = runtime.getWindow(); - runtime.assert(Boolean(window), "Expected to be run in an environment which has a global window, like a browser."); - function wrapAnnotation(annotation) { - var annotationWrapper = doc.createElement("div"), annotationNote = doc.createElement("div"), connectorHorizontal = doc.createElement("div"), connectorAngular = doc.createElement("div"), removeButton = doc.createElement("div"), annotationNode = annotation.node; - annotationWrapper.className = "annotationWrapper"; - annotationNode.parentNode.insertBefore(annotationWrapper, annotationNode); - annotationNote.className = "annotationNote"; - annotationNote.appendChild(annotationNode); - removeButton.className = "annotationRemoveButton"; - annotationNote.appendChild(removeButton); - connectorHorizontal.className = "annotationConnector horizontal"; - connectorAngular.className = "annotationConnector angular"; - annotationWrapper.appendChild(annotationNote); - annotationWrapper.appendChild(connectorHorizontal); - annotationWrapper.appendChild(connectorAngular) - } - function unwrapAnnotation(annotation) { - var annotationNode = annotation.node, annotationWrapper = annotationNode.parentNode.parentNode; - if(annotationWrapper.localName === "div") { - annotationWrapper.parentNode.insertBefore(annotationNode, annotationWrapper); - annotationWrapper.parentNode.removeChild(annotationWrapper) - } - } - function highlightAnnotation(annotation) { - var annotationNode = annotation.node, annotationEnd = annotation.end, range = doc.createRange(), textNodes; - if(annotationEnd) { - range.setStart(annotationNode, annotationNode.childNodes.length); - range.setEnd(annotationEnd, 0); - textNodes = odfUtils.getTextNodes(range, false); - textNodes.forEach(function(n) { - var container = doc.createElement("span"), v = annotationNode.getAttributeNS(odf.Namespaces.officens, "name"); - container.className = "annotationHighlight"; - container.setAttribute("annotation", v); - n.parentNode.insertBefore(container, n); - container.appendChild(n) - }) - } - range.detach() - } - function unhighlightAnnotation(annotation) { - var annotationName = annotation.node.getAttributeNS(odf.Namespaces.officens, "name"), highlightSpans = doc.querySelectorAll('span.annotationHighlight[annotation="' + annotationName + '"]'), i, container; - for(i = 0;i < highlightSpans.length;i += 1) { - container = highlightSpans.item(i); - while(container.firstChild) { - container.parentNode.insertBefore(container.firstChild, container) - } - container.parentNode.removeChild(container) - } - } - function lineDistance(point1, point2) { - var xs = 0, ys = 0; - xs = point2.x - point1.x; - xs = xs * xs; - ys = point2.y - point1.y; - ys = ys * ys; - return Math.sqrt(xs + ys) - } - function renderAnnotation(annotation) { - var annotationNote = annotation.node.parentElement, connectorHorizontal = annotationNote.nextElementSibling, connectorAngular = connectorHorizontal.nextElementSibling, annotationWrapper = annotationNote.parentElement, connectorAngle = 0, previousAnnotation = annotations[annotations.indexOf(annotation) - 1], previousRect, zoomLevel = canvas.getZoomLevel(); - annotationNote.style.left = (annotationsPane.getBoundingClientRect().left - annotationWrapper.getBoundingClientRect().left) / zoomLevel + "px"; - annotationNote.style.width = annotationsPane.getBoundingClientRect().width / zoomLevel + "px"; - connectorHorizontal.style.width = parseFloat(annotationNote.style.left) - CONNECTOR_MARGIN + "px"; - if(previousAnnotation) { - previousRect = previousAnnotation.node.parentElement.getBoundingClientRect(); - if((annotationWrapper.getBoundingClientRect().top - previousRect.bottom) / zoomLevel <= NOTE_MARGIN) { - annotationNote.style.top = Math.abs(annotationWrapper.getBoundingClientRect().top - previousRect.bottom) / zoomLevel + NOTE_MARGIN + "px" - }else { - annotationNote.style.top = "0px" - } - } - connectorAngular.style.left = connectorHorizontal.getBoundingClientRect().width / zoomLevel + "px"; - connectorAngular.style.width = lineDistance({x:connectorAngular.getBoundingClientRect().left / zoomLevel, y:connectorAngular.getBoundingClientRect().top / zoomLevel}, {x:annotationNote.getBoundingClientRect().left / zoomLevel, y:annotationNote.getBoundingClientRect().top / zoomLevel}) + "px"; - connectorAngle = Math.asin((annotationNote.getBoundingClientRect().top - connectorAngular.getBoundingClientRect().top) / (zoomLevel * parseFloat(connectorAngular.style.width))); - connectorAngular.style.transform = "rotate(" + connectorAngle + "rad)"; - connectorAngular.style.MozTransform = "rotate(" + connectorAngle + "rad)"; - connectorAngular.style.WebkitTransform = "rotate(" + connectorAngle + "rad)"; - connectorAngular.style.msTransform = "rotate(" + connectorAngle + "rad)" - } - function showAnnotationsPane(show) { - var sizer = canvas.getSizer(); - if(show) { - annotationsPane.style.display = "inline-block"; - sizer.style.paddingRight = window.getComputedStyle(annotationsPane).width - }else { - annotationsPane.style.display = "none"; - sizer.style.paddingRight = 0 - } - canvas.refreshSize() - } - function sortAnnotations() { - annotations.sort(function(a, b) { - if(a.node.compareDocumentPosition(b.node) === Node.DOCUMENT_POSITION_FOLLOWING) { - return-1 - } - return 1 - }) - } - function rerenderAnnotations() { - var i; - for(i = 0;i < annotations.length;i += 1) { - renderAnnotation(annotations[i]) - } - } - this.rerenderAnnotations = rerenderAnnotations; - function addAnnotation(annotation) { - showAnnotationsPane(true); - annotations.push({node:annotation.node, end:annotation.end}); - sortAnnotations(); - wrapAnnotation(annotation); - if(annotation.end) { - highlightAnnotation(annotation) - } - rerenderAnnotations() - } - this.addAnnotation = addAnnotation; - function forgetAnnotation(annotation) { - var index = annotations.indexOf(annotation); - unwrapAnnotation(annotation); - unhighlightAnnotation(annotation); - if(index !== -1) { - annotations.splice(index, 1) - } - if(annotations.length === 0) { - showAnnotationsPane(false) - } - } - function forgetAnnotations() { - while(annotations.length) { - forgetAnnotation(annotations[0]) - } - } - this.forgetAnnotations = forgetAnnotations -}; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -4902,1024 +4382,6 @@ gui.AnnotationViewManager = function AnnotationViewManager(canvas, odfFragment, @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.Cursor"); -runtime.loadClass("core.DomUtils"); -runtime.loadClass("core.PositionIterator"); -runtime.loadClass("core.PositionFilter"); -runtime.loadClass("core.LoopWatchDog"); -runtime.loadClass("odf.OdfUtils"); -gui.SelectionMover = function SelectionMover(cursor, rootNode) { - var odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils, positionIterator, cachedXOffset, timeoutHandle, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT; - function getIteratorAtCursor() { - positionIterator.setUnfilteredPosition(cursor.getNode(), 0); - return positionIterator - } - function getMaximumNodePosition(node) { - return node.nodeType === Node.TEXT_NODE ? node.textContent.length : node.childNodes.length - } - function getClientRect(clientRectangles, useRightEdge) { - var rectangle, simplifiedRectangle = null; - if(clientRectangles && clientRectangles.length > 0) { - rectangle = useRightEdge ? clientRectangles.item(clientRectangles.length - 1) : clientRectangles.item(0) - } - if(rectangle) { - simplifiedRectangle = {top:rectangle.top, left:useRightEdge ? rectangle.right : rectangle.left, bottom:rectangle.bottom} - } - return simplifiedRectangle - } - function getVisibleRect(container, offset, range, useRightEdge) { - var rectangle, nodeType = container.nodeType; - range.setStart(container, offset); - range.collapse(!useRightEdge); - rectangle = getClientRect(range.getClientRects(), useRightEdge === true); - if(!rectangle && offset > 0) { - range.setStart(container, offset - 1); - range.setEnd(container, offset); - rectangle = getClientRect(range.getClientRects(), true) - } - if(!rectangle) { - if(nodeType === Node.ELEMENT_NODE && (offset > 0 && (container).childNodes.length >= offset)) { - rectangle = getVisibleRect(container, offset - 1, range, true) - }else { - if(container.nodeType === Node.TEXT_NODE && offset > 0) { - rectangle = getVisibleRect(container, offset - 1, range, true) - }else { - if(container.previousSibling) { - rectangle = getVisibleRect(container.previousSibling, getMaximumNodePosition(container.previousSibling), range, true) - }else { - if(container.parentNode && container.parentNode !== rootNode) { - rectangle = getVisibleRect(container.parentNode, 0, range, false) - }else { - range.selectNode(rootNode); - rectangle = getClientRect(range.getClientRects(), false) - } - } - } - } - } - runtime.assert(Boolean(rectangle), "No visible rectangle found"); - return(rectangle) - } - function doMove(positions, extend, move) { - var left = positions, iterator = getIteratorAtCursor(), initialRect, range = (rootNode.ownerDocument.createRange()), selectionRange = cursor.getSelectedRange().cloneRange(), newRect, horizontalMovement, o, c, isForwardSelection; - initialRect = getVisibleRect(iterator.container(), iterator.unfilteredDomOffset(), range); - while(left > 0 && move()) { - left -= 1 - } - if(extend) { - c = iterator.container(); - o = iterator.unfilteredDomOffset(); - if(domUtils.comparePoints((selectionRange.startContainer), selectionRange.startOffset, c, o) === -1) { - selectionRange.setStart(c, o); - isForwardSelection = false - }else { - selectionRange.setEnd(c, o) - } - }else { - selectionRange.setStart(iterator.container(), iterator.unfilteredDomOffset()); - selectionRange.collapse(true) - } - cursor.setSelectedRange(selectionRange, isForwardSelection); - iterator = getIteratorAtCursor(); - newRect = getVisibleRect(iterator.container(), iterator.unfilteredDomOffset(), range); - horizontalMovement = newRect.top === initialRect.top ? true : false; - if(horizontalMovement || cachedXOffset === undefined) { - cachedXOffset = newRect.left - } - runtime.clearTimeout(timeoutHandle); - timeoutHandle = runtime.setTimeout(function() { - cachedXOffset = undefined - }, 2E3); - range.detach(); - return positions - left - } - this.movePointForward = function(positions, extend) { - return doMove(positions, extend || false, positionIterator.nextPosition) - }; - this.movePointBackward = function(positions, extend) { - return doMove(positions, extend || false, positionIterator.previousPosition) - }; - function isPositionWalkable(filter) { - var iterator = getIteratorAtCursor(); - if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { - iterator.setUnfilteredPosition(cursor.getAnchorNode(), 0); - if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { - return true - } - } - return false - } - function countSteps(iterator, steps, filter) { - var watch = new core.LoopWatchDog(1E4), positions = 0, positionsCount = 0, increment = steps >= 0 ? 1 : -1, delegate = (steps >= 0 ? iterator.nextPosition : iterator.previousPosition); - while(steps !== 0 && delegate()) { - watch.check(); - positionsCount += increment; - if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { - steps -= increment; - positions += positionsCount; - positionsCount = 0 - } - } - return positions - } - function convertForwardStepsBetweenFilters(stepsFilter1, filter1, filter2) { - var iterator = getIteratorAtCursor(), watch = new core.LoopWatchDog(1E4), pendingStepsFilter2 = 0, stepsFilter2 = 0; - while(stepsFilter1 > 0 && iterator.nextPosition()) { - watch.check(); - if(filter2.acceptPosition(iterator) === FILTER_ACCEPT) { - pendingStepsFilter2 += 1; - if(filter1.acceptPosition(iterator) === FILTER_ACCEPT) { - stepsFilter2 += pendingStepsFilter2; - pendingStepsFilter2 = 0; - stepsFilter1 -= 1 - } - } - } - return stepsFilter2 - } - function convertBackwardStepsBetweenFilters(stepsFilter1, filter1, filter2) { - var iterator = getIteratorAtCursor(), watch = new core.LoopWatchDog(1E4), pendingStepsFilter2 = 0, stepsFilter2 = 0; - while(stepsFilter1 > 0 && iterator.previousPosition()) { - watch.check(); - if(filter2.acceptPosition(iterator) === FILTER_ACCEPT) { - pendingStepsFilter2 += 1; - if(filter1.acceptPosition(iterator) === FILTER_ACCEPT) { - stepsFilter2 += pendingStepsFilter2; - pendingStepsFilter2 = 0; - stepsFilter1 -= 1 - } - } - } - return stepsFilter2 - } - function countStepsPublic(steps, filter) { - var iterator = getIteratorAtCursor(); - return countSteps(iterator, steps, filter) - } - function countPositionsToClosestStep(container, offset, filter) { - var iterator = getIteratorAtCursor(), paragraphNode = odfUtils.getParagraphElement(iterator.getCurrentNode()), count = 0; - iterator.setUnfilteredPosition(container, offset); - if(filter.acceptPosition(iterator) !== FILTER_ACCEPT) { - count = countSteps(iterator, -1, filter); - if(count === 0 || paragraphNode && paragraphNode !== odfUtils.getParagraphElement(iterator.getCurrentNode())) { - iterator.setUnfilteredPosition(container, offset); - count = countSteps(iterator, 1, filter) - } - } - return count - } - function countLineSteps(filter, direction, iterator) { - var c = iterator.container(), steps = 0, bestContainer = null, bestOffset, bestXDiff = 10, xDiff, bestCount = 0, top, left, lastTop, rect, range = (rootNode.ownerDocument.createRange()), watch = new core.LoopWatchDog(1E4); - rect = getVisibleRect(c, iterator.unfilteredDomOffset(), range); - top = rect.top; - if(cachedXOffset === undefined) { - left = rect.left - }else { - left = cachedXOffset - } - lastTop = top; - while((direction < 0 ? iterator.previousPosition() : iterator.nextPosition()) === true) { - watch.check(); - if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { - steps += 1; - c = iterator.container(); - rect = getVisibleRect(c, iterator.unfilteredDomOffset(), range); - if(rect.top !== top) { - if(rect.top !== lastTop && lastTop !== top) { - break - } - lastTop = rect.top; - xDiff = Math.abs(left - rect.left); - if(bestContainer === null || xDiff < bestXDiff) { - bestContainer = c; - bestOffset = iterator.unfilteredDomOffset(); - bestXDiff = xDiff; - bestCount = steps - } - } - } - } - if(bestContainer !== null) { - iterator.setUnfilteredPosition(bestContainer, (bestOffset)); - steps = bestCount - }else { - steps = 0 - } - range.detach(); - return steps - } - function countLinesSteps(lines, filter) { - var iterator = getIteratorAtCursor(), stepCount = 0, steps = 0, direction = lines < 0 ? -1 : 1; - lines = Math.abs(lines); - while(lines > 0) { - stepCount += countLineSteps(filter, direction, iterator); - if(stepCount === 0) { - break - } - steps += stepCount; - lines -= 1 - } - return steps * direction - } - function countStepsToLineBoundary(direction, filter) { - var fnNextPos, increment, lastRect, rect, onSameLine, iterator = getIteratorAtCursor(), paragraphNode = odfUtils.getParagraphElement(iterator.getCurrentNode()), steps = 0, range = (rootNode.ownerDocument.createRange()); - if(direction < 0) { - fnNextPos = iterator.previousPosition; - increment = -1 - }else { - fnNextPos = iterator.nextPosition; - increment = 1 - } - lastRect = getVisibleRect(iterator.container(), iterator.unfilteredDomOffset(), range); - while(fnNextPos.call(iterator)) { - if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { - if(odfUtils.getParagraphElement(iterator.getCurrentNode()) !== paragraphNode) { - break - } - rect = getVisibleRect(iterator.container(), iterator.unfilteredDomOffset(), range); - if(rect.bottom !== lastRect.bottom) { - onSameLine = rect.top >= lastRect.top && rect.bottom < lastRect.bottom || rect.top <= lastRect.top && rect.bottom > lastRect.bottom; - if(!onSameLine) { - break - } - } - steps += increment; - lastRect = rect - } - } - range.detach(); - return steps - } - function countStepsToPosition(targetNode, targetOffset, filter) { - runtime.assert(targetNode !== null, "SelectionMover.countStepsToPosition called with element===null"); - var iterator = getIteratorAtCursor(), c = iterator.container(), o = iterator.unfilteredDomOffset(), steps = 0, watch = new core.LoopWatchDog(1E4), comparison; - iterator.setUnfilteredPosition(targetNode, targetOffset); - while(filter.acceptPosition(iterator) !== FILTER_ACCEPT && iterator.previousPosition()) { - watch.check() - } - targetNode = iterator.container(); - runtime.assert(Boolean(targetNode), "SelectionMover.countStepsToPosition: positionIterator.container() returned null"); - targetOffset = iterator.unfilteredDomOffset(); - iterator.setUnfilteredPosition(c, o); - while(filter.acceptPosition(iterator) !== FILTER_ACCEPT && iterator.previousPosition()) { - watch.check() - } - comparison = domUtils.comparePoints(targetNode, targetOffset, iterator.container(), iterator.unfilteredDomOffset()); - if(comparison < 0) { - while(iterator.nextPosition()) { - watch.check(); - if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { - steps += 1 - } - if(iterator.container() === targetNode && iterator.unfilteredDomOffset() === targetOffset) { - return steps - } - } - }else { - if(comparison > 0) { - while(iterator.previousPosition()) { - watch.check(); - if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { - steps -= 1; - if(iterator.container() === targetNode && iterator.unfilteredDomOffset() === targetOffset) { - break - } - } - } - } - } - return steps - } - this.getStepCounter = function() { - return{countSteps:countStepsPublic, convertForwardStepsBetweenFilters:convertForwardStepsBetweenFilters, convertBackwardStepsBetweenFilters:convertBackwardStepsBetweenFilters, countLinesSteps:countLinesSteps, countStepsToLineBoundary:countStepsToLineBoundary, countStepsToPosition:countStepsToPosition, isPositionWalkable:isPositionWalkable, countPositionsToNearestStep:countPositionsToClosestStep} - }; - function init() { - positionIterator = gui.SelectionMover.createPositionIterator(rootNode); - var range = rootNode.ownerDocument.createRange(); - range.setStart(positionIterator.container(), positionIterator.unfilteredDomOffset()); - range.collapse(true); - cursor.setSelectedRange(range) - } - init() -}; -gui.SelectionMover.createPositionIterator = function(rootNode) { - function CursorFilter() { - this.acceptNode = function(node) { - if(!node || (node.namespaceURI === "urn:webodf:names:cursor" || node.namespaceURI === "urn:webodf:names:editinfo")) { - return NodeFilter.FILTER_REJECT - } - return NodeFilter.FILTER_ACCEPT - } - } - var filter = new CursorFilter; - return new core.PositionIterator(rootNode, 5, filter, false) -}; -(function() { - return gui.SelectionMover -})(); -/* - - 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/ -*/ -odf.OdfNodeFilter = function OdfNodeFilter() { - this.acceptNode = function(node) { - var result; - if(node.namespaceURI === "http://www.w3.org/1999/xhtml") { - result = NodeFilter.FILTER_SKIP - }else { - if(node.namespaceURI && node.namespaceURI.match(/^urn:webodf:/)) { - result = NodeFilter.FILTER_REJECT - }else { - result = NodeFilter.FILTER_ACCEPT - } - } - return result - } -}; -/* - - Copyright (C) 2012-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/ -*/ -runtime.loadClass("odf.Namespaces"); -runtime.loadClass("odf.OdfUtils"); -runtime.loadClass("xmldom.XPath"); -runtime.loadClass("core.CSSUnits"); -odf.StyleTreeNode = function StyleTreeNode(element) { - this.derivedStyles = {}; - this.element = element -}; -odf.Style2CSS = function Style2CSS() { - var drawns = odf.Namespaces.drawns, fons = odf.Namespaces.fons, officens = odf.Namespaces.officens, stylens = odf.Namespaces.stylens, svgns = odf.Namespaces.svgns, tablens = odf.Namespaces.tablens, textns = odf.Namespaces.textns, xlinkns = odf.Namespaces.xlinkns, presentationns = odf.Namespaces.presentationns, familynamespaceprefixes = {"graphic":"draw", "drawing-page":"draw", "paragraph":"text", "presentation":"presentation", "ruby":"text", "section":"text", "table":"table", "table-cell":"table", - "table-column":"table", "table-row":"table", "text":"text", "list":"text", "page":"office"}, familytagnames = {"graphic":["circle", "connected", "control", "custom-shape", "ellipse", "frame", "g", "line", "measure", "page", "page-thumbnail", "path", "polygon", "polyline", "rect", "regular-polygon"], "paragraph":["alphabetical-index-entry-template", "h", "illustration-index-entry-template", "index-source-style", "object-index-entry-template", "p", "table-index-entry-template", "table-of-content-entry-template", - "user-index-entry-template"], "presentation":["caption", "circle", "connector", "control", "custom-shape", "ellipse", "frame", "g", "line", "measure", "page-thumbnail", "path", "polygon", "polyline", "rect", "regular-polygon"], "drawing-page":["caption", "circle", "connector", "control", "page", "custom-shape", "ellipse", "frame", "g", "line", "measure", "page-thumbnail", "path", "polygon", "polyline", "rect", "regular-polygon"], "ruby":["ruby", "ruby-text"], "section":["alphabetical-index", "bibliography", - "illustration-index", "index-title", "object-index", "section", "table-of-content", "table-index", "user-index"], "table":["background", "table"], "table-cell":["body", "covered-table-cell", "even-columns", "even-rows", "first-column", "first-row", "last-column", "last-row", "odd-columns", "odd-rows", "table-cell"], "table-column":["table-column"], "table-row":["table-row"], "text":["a", "index-entry-chapter", "index-entry-link-end", "index-entry-link-start", "index-entry-page-number", "index-entry-span", - "index-entry-tab-stop", "index-entry-text", "index-title-template", "linenumbering-configuration", "list-level-style-number", "list-level-style-bullet", "outline-level-style", "span"], "list":["list-item"]}, textPropertySimpleMapping = [[fons, "color", "color"], [fons, "background-color", "background-color"], [fons, "font-weight", "font-weight"], [fons, "font-style", "font-style"]], bgImageSimpleMapping = [[stylens, "repeat", "background-repeat"]], paragraphPropertySimpleMapping = [[fons, "background-color", - "background-color"], [fons, "text-align", "text-align"], [fons, "text-indent", "text-indent"], [fons, "padding", "padding"], [fons, "padding-left", "padding-left"], [fons, "padding-right", "padding-right"], [fons, "padding-top", "padding-top"], [fons, "padding-bottom", "padding-bottom"], [fons, "border-left", "border-left"], [fons, "border-right", "border-right"], [fons, "border-top", "border-top"], [fons, "border-bottom", "border-bottom"], [fons, "margin", "margin"], [fons, "margin-left", "margin-left"], - [fons, "margin-right", "margin-right"], [fons, "margin-top", "margin-top"], [fons, "margin-bottom", "margin-bottom"], [fons, "border", "border"]], graphicPropertySimpleMapping = [[fons, "background-color", "background-color"], [fons, "min-height", "min-height"], [drawns, "stroke", "border"], [svgns, "stroke-color", "border-color"], [svgns, "stroke-width", "border-width"], [fons, "border", "border"], [fons, "border-left", "border-left"], [fons, "border-right", "border-right"], [fons, "border-top", - "border-top"], [fons, "border-bottom", "border-bottom"]], tablecellPropertySimpleMapping = [[fons, "background-color", "background-color"], [fons, "border-left", "border-left"], [fons, "border-right", "border-right"], [fons, "border-top", "border-top"], [fons, "border-bottom", "border-bottom"], [fons, "border", "border"]], tablecolumnPropertySimpleMapping = [[stylens, "column-width", "width"]], tablerowPropertySimpleMapping = [[stylens, "row-height", "height"], [fons, "keep-together", null]], tablePropertySimpleMapping = - [[stylens, "width", "width"], [fons, "margin-left", "margin-left"], [fons, "margin-right", "margin-right"], [fons, "margin-top", "margin-top"], [fons, "margin-bottom", "margin-bottom"]], pageContentPropertySimpleMapping = [[fons, "background-color", "background-color"], [fons, "padding", "padding"], [fons, "padding-left", "padding-left"], [fons, "padding-right", "padding-right"], [fons, "padding-top", "padding-top"], [fons, "padding-bottom", "padding-bottom"], [fons, "border", "border"], [fons, - "border-left", "border-left"], [fons, "border-right", "border-right"], [fons, "border-top", "border-top"], [fons, "border-bottom", "border-bottom"], [fons, "margin", "margin"], [fons, "margin-left", "margin-left"], [fons, "margin-right", "margin-right"], [fons, "margin-top", "margin-top"], [fons, "margin-bottom", "margin-bottom"]], pageSizePropertySimpleMapping = [[fons, "page-width", "width"], [fons, "page-height", "height"]], borderPropertyMap = {"border":true, "border-left":true, "border-right":true, - "border-top":true, "border-bottom":true, "stroke-width":true}, fontFaceDeclsMap = {}, utils = new odf.OdfUtils, documentType, odfRoot, defaultFontSize, xpath = xmldom.XPath, cssUnits = new core.CSSUnits; - function getStyleMap(stylesnode) { - var node, name, family, style, stylemap = {}; - if(!stylesnode) { - return stylemap - } - node = stylesnode.firstElementChild; - while(node) { - if(node.namespaceURI === stylens && (node.localName === "style" || node.localName === "default-style")) { - family = node.getAttributeNS(stylens, "family") - }else { - if(node.namespaceURI === textns && node.localName === "list-style") { - family = "list" - }else { - if(node.namespaceURI === stylens && (node.localName === "page-layout" || node.localName === "default-page-layout")) { - family = "page" - }else { - family = undefined - } - } - } - if(family) { - name = node.getAttributeNS(stylens, "name"); - if(!name) { - name = "" - } - if(stylemap.hasOwnProperty(family)) { - style = stylemap[family] - }else { - stylemap[family] = style = {} - } - style[name] = node - } - node = node.nextElementSibling - } - return stylemap - } - function findStyle(stylestree, name) { - if(stylestree.hasOwnProperty(name)) { - return stylestree[name] - } - var n, style = null; - for(n in stylestree) { - if(stylestree.hasOwnProperty(n)) { - style = findStyle(stylestree[n].derivedStyles, name); - if(style) { - break - } - } - } - return style - } - function addStyleToStyleTree(stylename, stylesmap, stylestree) { - var style, parentname, parentstyle; - if(!stylesmap.hasOwnProperty(stylename)) { - return null - } - style = new odf.StyleTreeNode(stylesmap[stylename]); - parentname = style.element.getAttributeNS(stylens, "parent-style-name"); - parentstyle = null; - if(parentname) { - parentstyle = findStyle(stylestree, parentname) || addStyleToStyleTree(parentname, stylesmap, stylestree) - } - if(parentstyle) { - parentstyle.derivedStyles[stylename] = style - }else { - stylestree[stylename] = style - } - delete stylesmap[stylename]; - return style - } - function addStyleMapToStyleTree(stylesmap, stylestree) { - var name; - for(name in stylesmap) { - if(stylesmap.hasOwnProperty(name)) { - addStyleToStyleTree(name, stylesmap, stylestree) - } - } - } - function createSelector(family, name) { - var prefix = familynamespaceprefixes[family], namepart, selector; - if(prefix === undefined) { - return null - } - if(name) { - namepart = "[" + prefix + '|style-name="' + name + '"]' - }else { - namepart = "" - } - if(prefix === "presentation") { - prefix = "draw"; - if(name) { - namepart = '[presentation|style-name="' + name + '"]' - }else { - namepart = "" - } - } - selector = prefix + "|" + familytagnames[family].join(namepart + "," + prefix + "|") + namepart; - return selector - } - function getSelectors(family, name, node) { - var selectors = [], ss, derivedStyles = node.derivedStyles, n; - ss = createSelector(family, name); - if(ss !== null) { - selectors.push(ss) - } - for(n in derivedStyles) { - if(derivedStyles.hasOwnProperty(n)) { - ss = getSelectors(family, n, derivedStyles[n]); - selectors = selectors.concat(ss) - } - } - return selectors - } - function getDirectChild(node, ns, name) { - var e = node && node.firstElementChild; - while(e) { - if(e.namespaceURI === ns && e.localName === name) { - break - } - e = e.nextElementSibling - } - return e - } - function fixBorderWidth(value) { - var index = value.indexOf(" "), width, theRestOfBorderAttributes; - if(index !== -1) { - width = value.substring(0, index); - theRestOfBorderAttributes = value.substring(index) - }else { - width = value; - theRestOfBorderAttributes = "" - } - width = utils.parseLength(width); - if(width && (width.unit === "pt" && width.value < 0.75)) { - value = "0.75pt" + theRestOfBorderAttributes - } - return value - } - function applySimpleMapping(props, mapping) { - var rule = "", i, r, value; - for(i = 0;i < mapping.length;i += 1) { - r = mapping[i]; - value = props.getAttributeNS(r[0], r[1]); - if(value) { - value = value.trim(); - if(borderPropertyMap.hasOwnProperty(r[1])) { - value = fixBorderWidth(value) - } - if(r[2]) { - rule += r[2] + ":" + value + ";" - } - } - } - return rule - } - function getFontSize(styleNode) { - var props = getDirectChild(styleNode, stylens, "text-properties"); - if(props) { - return utils.parseFoFontSize(props.getAttributeNS(fons, "font-size")) - } - return null - } - function getParentStyleNode(styleNode) { - var parentStyleName = "", parentStyleFamily = "", parentStyleNode = null, xp; - if(styleNode.localName === "default-style") { - return null - } - parentStyleName = styleNode.getAttributeNS(stylens, "parent-style-name"); - parentStyleFamily = styleNode.getAttributeNS(stylens, "family"); - if(parentStyleName) { - xp = "//style:*[@style:name='" + parentStyleName + "'][@style:family='" + parentStyleFamily + "']" - }else { - xp = "//style:default-style[@style:family='" + parentStyleFamily + "']" - } - parentStyleNode = xpath.getODFElementsWithXPath((odfRoot), xp, odf.Namespaces.lookupNamespaceURI)[0]; - return parentStyleNode - } - function getTextProperties(props) { - var rule = "", fontName, fontSize, value, textDecoration = "", fontSizeRule = "", sizeMultiplier = 1, parentStyle; - rule += applySimpleMapping(props, textPropertySimpleMapping); - value = props.getAttributeNS(stylens, "text-underline-style"); - if(value === "solid") { - textDecoration += " underline" - } - value = props.getAttributeNS(stylens, "text-line-through-style"); - if(value === "solid") { - textDecoration += " line-through" - } - if(textDecoration.length) { - textDecoration = "text-decoration:" + textDecoration + ";"; - rule += textDecoration - } - fontName = props.getAttributeNS(stylens, "font-name") || props.getAttributeNS(fons, "font-family"); - if(fontName) { - value = fontFaceDeclsMap[fontName]; - rule += "font-family: " + (value || fontName) + ";" - } - parentStyle = props.parentElement; - fontSize = getFontSize(parentStyle); - if(!fontSize) { - return rule - } - while(parentStyle) { - fontSize = getFontSize(parentStyle); - if(fontSize) { - if(fontSize.unit !== "%") { - fontSizeRule = "font-size: " + fontSize.value * sizeMultiplier + fontSize.unit + ";"; - break - } - sizeMultiplier *= fontSize.value / 100 - } - parentStyle = getParentStyleNode(parentStyle) - } - if(!fontSizeRule) { - fontSizeRule = "font-size: " + parseFloat(defaultFontSize) * sizeMultiplier + cssUnits.getUnits(defaultFontSize) + ";" - } - rule += fontSizeRule; - return rule - } - function getParagraphProperties(props) { - var rule = "", bgimage, url, lineHeight; - rule += applySimpleMapping(props, paragraphPropertySimpleMapping); - bgimage = getDirectChild(props, stylens, "background-image"); - if(bgimage) { - url = bgimage.getAttributeNS(xlinkns, "href"); - if(url) { - rule += "background-image: url('odfkit:" + url + "');"; - rule += applySimpleMapping(bgimage, bgImageSimpleMapping) - } - } - lineHeight = props.getAttributeNS(fons, "line-height"); - if(lineHeight && lineHeight !== "normal") { - lineHeight = utils.parseFoLineHeight(lineHeight); - if(lineHeight.unit !== "%") { - rule += "line-height: " + lineHeight.value + lineHeight.unit + ";" - }else { - rule += "line-height: " + lineHeight.value / 100 + ";" - } - } - return rule - } - function matchToRgb(m, r, g, b) { - return r + r + g + g + b + b - } - function hexToRgb(hex) { - var result, shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - hex = hex.replace(shorthandRegex, matchToRgb); - result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - return result ? {r:parseInt(result[1], 16), g:parseInt(result[2], 16), b:parseInt(result[3], 16)} : null - } - function isNumber(n) { - return!isNaN(parseFloat(n)) - } - function getGraphicProperties(props) { - var rule = "", alpha, bgcolor, fill; - rule += applySimpleMapping(props, graphicPropertySimpleMapping); - alpha = props.getAttributeNS(drawns, "opacity"); - fill = props.getAttributeNS(drawns, "fill"); - bgcolor = props.getAttributeNS(drawns, "fill-color"); - if(fill === "solid" || fill === "hatch") { - if(bgcolor && bgcolor !== "none") { - alpha = isNumber(alpha) ? parseFloat(alpha) / 100 : 1; - bgcolor = hexToRgb(bgcolor); - if(bgcolor) { - rule += "background-color: rgba(" + bgcolor.r + "," + bgcolor.g + "," + bgcolor.b + "," + alpha + ");" - } - }else { - rule += "background: none;" - } - }else { - if(fill === "none") { - rule += "background: none;" - } - } - return rule - } - function getDrawingPageProperties(props) { - var rule = ""; - rule += applySimpleMapping(props, graphicPropertySimpleMapping); - if(props.getAttributeNS(presentationns, "background-visible") === "true") { - rule += "background: none;" - } - return rule - } - function getTableCellProperties(props) { - var rule = ""; - rule += applySimpleMapping(props, tablecellPropertySimpleMapping); - return rule - } - function getTableRowProperties(props) { - var rule = ""; - rule += applySimpleMapping(props, tablerowPropertySimpleMapping); - return rule - } - function getTableColumnProperties(props) { - var rule = ""; - rule += applySimpleMapping(props, tablecolumnPropertySimpleMapping); - return rule - } - function getTableProperties(props) { - var rule = "", borderModel; - rule += applySimpleMapping(props, tablePropertySimpleMapping); - borderModel = props.getAttributeNS(tablens, "border-model"); - if(borderModel === "collapsing") { - rule += "border-collapse:collapse;" - }else { - if(borderModel === "separating") { - rule += "border-collapse:separate;" - } - } - return rule - } - function addStyleRule(sheet, family, name, node) { - var selectors = getSelectors(family, name, node), selector = selectors.join(","), rule = "", properties; - properties = getDirectChild(node.element, stylens, "text-properties"); - if(properties) { - rule += getTextProperties(properties) - } - properties = getDirectChild(node.element, stylens, "paragraph-properties"); - if(properties) { - rule += getParagraphProperties(properties) - } - properties = getDirectChild(node.element, stylens, "graphic-properties"); - if(properties) { - rule += getGraphicProperties(properties) - } - properties = getDirectChild(node.element, stylens, "drawing-page-properties"); - if(properties) { - rule += getDrawingPageProperties(properties) - } - properties = getDirectChild(node.element, stylens, "table-cell-properties"); - if(properties) { - rule += getTableCellProperties(properties) - } - properties = getDirectChild(node.element, stylens, "table-row-properties"); - if(properties) { - rule += getTableRowProperties(properties) - } - properties = getDirectChild(node.element, stylens, "table-column-properties"); - if(properties) { - rule += getTableColumnProperties(properties) - } - properties = getDirectChild(node.element, stylens, "table-properties"); - if(properties) { - rule += getTableProperties(properties) - } - if(rule.length === 0) { - return - } - rule = selector + "{" + rule + "}"; - try { - sheet.insertRule(rule, sheet.cssRules.length) - }catch(e) { - throw e; - } - } - function getNumberRule(node) { - var style = node.getAttributeNS(stylens, "num-format"), suffix = node.getAttributeNS(stylens, "num-suffix") || "", prefix = node.getAttributeNS(stylens, "num-prefix") || "", stylemap = {1:"decimal", "a":"lower-latin", "A":"upper-latin", "i":"lower-roman", "I":"upper-roman"}, content = ""; - if(prefix) { - content += ' "' + prefix + '"' - } - if(stylemap.hasOwnProperty(style)) { - content += " counter(list, " + stylemap[style] + ")" - }else { - if(style) { - content += ' "' + style + '"' - }else { - content += " ''" - } - } - return"content:" + content + ' "' + suffix + '"' - } - function getImageRule() { - return"content: none;" - } - function getBulletRule(node) { - var bulletChar = node.getAttributeNS(textns, "bullet-char"); - return"content: '" + bulletChar + "';" - } - function addListStyleRule(sheet, name, node, itemrule) { - var selector = 'text|list[text|style-name="' + name + '"]', level = node.getAttributeNS(textns, "level"), itemSelector, listItemRule, listLevelProps = getDirectChild(node, stylens, "list-level-properties"), listLevelLabelAlign = getDirectChild(listLevelProps, stylens, "list-level-label-alignment"), bulletIndent, listIndent, bulletWidth, rule; - if(listLevelLabelAlign) { - bulletIndent = listLevelLabelAlign.getAttributeNS(fons, "text-indent"); - listIndent = listLevelLabelAlign.getAttributeNS(fons, "margin-left") - } - if(!bulletIndent) { - bulletIndent = "-0.6cm" - } - if(bulletIndent.charAt(0) === "-") { - bulletWidth = bulletIndent.substring(1) - }else { - bulletWidth = "-" + bulletIndent - } - level = level && parseInt(level, 10); - while(level > 1) { - selector += " > text|list-item > text|list"; - level -= 1 - } - if(listIndent) { - itemSelector = selector; - itemSelector += " > text|list-item > *:not(text|list):first-child"; - listItemRule = itemSelector + "{"; - listItemRule += "margin-left:" + listIndent + ";"; - listItemRule += "}"; - try { - sheet.insertRule(listItemRule, sheet.cssRules.length) - }catch(e1) { - runtime.log("cannot load rule: " + listItemRule) - } - } - selector += " > text|list-item > *:not(text|list):first-child:before"; - rule = selector + "{" + itemrule + ";"; - rule += "counter-increment:list;"; - rule += "margin-left:" + bulletIndent + ";"; - rule += "width:" + bulletWidth + ";"; - rule += "display:inline-block}"; - try { - sheet.insertRule(rule, sheet.cssRules.length) - }catch(e2) { - runtime.log("cannot load rule: " + rule) - } - } - function addPageStyleRules(sheet, node) { - var rule = "", imageProps, url, contentLayoutRule = "", pageSizeRule = "", props = getDirectChild(node, stylens, "page-layout-properties"), stylename, masterStyles, e, masterStyleName; - if(!props) { - return - } - stylename = node.getAttributeNS(stylens, "name"); - rule += applySimpleMapping(props, pageContentPropertySimpleMapping); - imageProps = getDirectChild(props, stylens, "background-image"); - if(imageProps) { - url = imageProps.getAttributeNS(xlinkns, "href"); - if(url) { - rule += "background-image: url('odfkit:" + url + "');"; - rule += applySimpleMapping(imageProps, bgImageSimpleMapping) - } - } - if(documentType === "presentation") { - masterStyles = getDirectChild(node.parentNode.parentElement, officens, "master-styles"); - e = masterStyles && masterStyles.firstElementChild; - while(e) { - if(e.namespaceURI === stylens && (e.localName === "master-page" && e.getAttributeNS(stylens, "page-layout-name") === stylename)) { - masterStyleName = e.getAttributeNS(stylens, "name"); - contentLayoutRule = "draw|page[draw|master-page-name=" + masterStyleName + "] {" + rule + "}"; - pageSizeRule = "office|body, draw|page[draw|master-page-name=" + masterStyleName + "] {" + applySimpleMapping(props, pageSizePropertySimpleMapping) + " }"; - try { - sheet.insertRule(contentLayoutRule, sheet.cssRules.length); - sheet.insertRule(pageSizeRule, sheet.cssRules.length) - }catch(e1) { - throw e1; - } - } - e = e.nextElementSibling - } - }else { - if(documentType === "text") { - contentLayoutRule = "office|text {" + rule + "}"; - rule = ""; - pageSizeRule = "office|body {" + "width: " + props.getAttributeNS(fons, "page-width") + ";" + "}"; - try { - sheet.insertRule(contentLayoutRule, sheet.cssRules.length); - sheet.insertRule(pageSizeRule, sheet.cssRules.length) - }catch(e2) { - throw e2; - } - } - } - } - function addListStyleRules(sheet, name, node) { - var n = node.firstChild, e, itemrule; - while(n) { - if(n.namespaceURI === textns) { - e = (n); - if(n.localName === "list-level-style-number") { - itemrule = getNumberRule(e); - addListStyleRule(sheet, name, e, itemrule) - }else { - if(n.localName === "list-level-style-image") { - itemrule = getImageRule(); - addListStyleRule(sheet, name, e, itemrule) - }else { - if(n.localName === "list-level-style-bullet") { - itemrule = getBulletRule(e); - addListStyleRule(sheet, name, e, itemrule) - } - } - } - } - n = n.nextSibling - } - } - function addRule(sheet, family, name, node) { - if(family === "list") { - addListStyleRules(sheet, name, node.element) - }else { - if(family === "page") { - addPageStyleRules(sheet, node.element) - }else { - addStyleRule(sheet, family, name, node) - } - } - } - function addRules(sheet, family, name, node) { - addRule(sheet, family, name, node); - var n; - for(n in node.derivedStyles) { - if(node.derivedStyles.hasOwnProperty(n)) { - addRules(sheet, family, n, node.derivedStyles[n]) - } - } - } - this.style2css = function(doctype, stylesheet, fontFaceMap, styles, autostyles) { - var doc, styletree, tree, rule, name, family, stylenodes, styleautonodes; - while(stylesheet.cssRules.length) { - stylesheet.deleteRule(stylesheet.cssRules.length - 1) - } - doc = null; - if(styles) { - doc = styles.ownerDocument; - odfRoot = styles.parentNode - } - if(autostyles) { - doc = autostyles.ownerDocument; - odfRoot = autostyles.parentNode - } - if(!doc) { - return - } - odf.Namespaces.forEachPrefix(function(prefix, ns) { - rule = "@namespace " + prefix + " url(" + ns + ");"; - try { - stylesheet.insertRule(rule, stylesheet.cssRules.length) - }catch(ignore) { - } - }); - fontFaceDeclsMap = fontFaceMap; - documentType = doctype; - defaultFontSize = runtime.getWindow().getComputedStyle(document.body, null).getPropertyValue("font-size") || "12pt"; - stylenodes = getStyleMap(styles); - styleautonodes = getStyleMap(autostyles); - styletree = {}; - for(family in familynamespaceprefixes) { - if(familynamespaceprefixes.hasOwnProperty(family)) { - tree = styletree[family] = {}; - addStyleMapToStyleTree(stylenodes[family], tree); - addStyleMapToStyleTree(styleautonodes[family], tree); - for(name in tree) { - if(tree.hasOwnProperty(name)) { - addRules(stylesheet, family, name, tree[name]) - } - } - } - } - } -}; -/* - - Copyright (C) 2012-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/ -*/ -runtime.loadClass("xmldom.XPath"); -runtime.loadClass("odf.Namespaces"); odf.StyleInfo = function StyleInfo() { var chartns = odf.Namespaces.chartns, dbns = odf.Namespaces.dbns, dr3dns = odf.Namespaces.dr3dns, drawns = odf.Namespaces.drawns, formns = odf.Namespaces.formns, numberns = odf.Namespaces.numberns, officens = odf.Namespaces.officens, presentationns = odf.Namespaces.presentationns, stylens = odf.Namespaces.stylens, tablens = odf.Namespaces.tablens, textns = odf.Namespaces.textns, nsprefixes = {"urn:oasis:names:tc:opendocument:xmlns:chart:1.0":"chart:", "urn:oasis:names:tc:opendocument:xmlns:database:1.0":"db:", "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0":"dr3d:", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0":"draw:", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0":"fo:", "urn:oasis:names:tc:opendocument:xmlns:form:1.0":"form:", "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0":"number:", "urn:oasis:names:tc:opendocument:xmlns:office:1.0":"office:", "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0":"presentation:", "urn:oasis:names:tc:opendocument:xmlns:style:1.0":"style:", @@ -6259,205 +4721,6 @@ odf.StyleInfo = function StyleInfo() { this.determineStylesForNode = determineStylesForNode; elements = inverse() }; -/* - - 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/ -*/ -runtime.loadClass("odf.OdfUtils"); -odf.TextSerializer = function TextSerializer() { - var self = this, odfUtils = new odf.OdfUtils; - function serializeNode(node) { - var s = "", accept = self.filter ? self.filter.acceptNode(node) : NodeFilter.FILTER_ACCEPT, nodeType = node.nodeType, child; - if(accept === NodeFilter.FILTER_ACCEPT || accept === NodeFilter.FILTER_SKIP) { - child = node.firstChild; - while(child) { - s += serializeNode(child); - child = child.nextSibling - } - } - if(accept === NodeFilter.FILTER_ACCEPT) { - if(nodeType === Node.ELEMENT_NODE && odfUtils.isParagraph(node)) { - s += "\n" - }else { - if(nodeType === Node.TEXT_NODE && node.textContent) { - s += node.textContent - } - } - } - return s - } - this.filter = null; - this.writeToString = function(node) { - var plainText; - if(!node) { - return"" - } - plainText = serializeNode(node); - if(plainText[plainText.length - 1] === "\n") { - plainText = plainText.substr(0, plainText.length - 1) - } - return plainText - } -}; -/* - - Copyright (C) 2012-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/ -*/ -runtime.loadClass("core.PositionFilter"); -runtime.loadClass("odf.OdfUtils"); -ops.TextPositionFilter = function TextPositionFilter(getRootNode) { - var odfUtils = new odf.OdfUtils, ELEMENT_NODE = Node.ELEMENT_NODE, TEXT_NODE = Node.TEXT_NODE, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT; - function checkLeftRight(container, leftNode, rightNode) { - var r, firstPos, rightOfChar; - if(leftNode) { - if(odfUtils.isInlineRoot(leftNode) && odfUtils.isGroupingElement(rightNode)) { - return FILTER_REJECT - } - r = odfUtils.lookLeftForCharacter(leftNode); - if(r === 1) { - return FILTER_ACCEPT - } - if(r === 2 && (odfUtils.scanRightForAnyCharacter(rightNode) || odfUtils.scanRightForAnyCharacter(odfUtils.nextNode(container)))) { - return FILTER_ACCEPT - } - } - firstPos = leftNode === null && odfUtils.isParagraph(container); - rightOfChar = odfUtils.lookRightForCharacter(rightNode); - if(firstPos) { - if(rightOfChar) { - return FILTER_ACCEPT - } - return odfUtils.scanRightForAnyCharacter(rightNode) ? FILTER_REJECT : FILTER_ACCEPT - } - if(!rightOfChar) { - return FILTER_REJECT - } - leftNode = leftNode || odfUtils.previousNode(container); - return odfUtils.scanLeftForAnyCharacter(leftNode) ? FILTER_REJECT : FILTER_ACCEPT - } - this.acceptPosition = function(iterator) { - var container = iterator.container(), nodeType = container.nodeType, offset, text, leftChar, rightChar, leftNode, rightNode, r; - if(nodeType !== ELEMENT_NODE && nodeType !== TEXT_NODE) { - return FILTER_REJECT - } - if(nodeType === TEXT_NODE) { - if(!odfUtils.isGroupingElement(container.parentNode) || odfUtils.isWithinTrackedChanges(container.parentNode, getRootNode())) { - return FILTER_REJECT - } - offset = iterator.unfilteredDomOffset(); - text = container.data; - runtime.assert(offset !== text.length, "Unexpected offset."); - if(offset > 0) { - leftChar = (text[offset - 1]); - if(!odfUtils.isODFWhitespace(leftChar)) { - return FILTER_ACCEPT - } - if(offset > 1) { - leftChar = (text[offset - 2]); - if(!odfUtils.isODFWhitespace(leftChar)) { - r = FILTER_ACCEPT - }else { - if(!odfUtils.isODFWhitespace(text.substr(0, offset))) { - return FILTER_REJECT - } - } - }else { - leftNode = odfUtils.previousNode(container); - if(odfUtils.scanLeftForNonSpace(leftNode)) { - r = FILTER_ACCEPT - } - } - if(r === FILTER_ACCEPT) { - return odfUtils.isTrailingWhitespace((container), offset) ? FILTER_REJECT : FILTER_ACCEPT - } - rightChar = (text[offset]); - if(odfUtils.isODFWhitespace(rightChar)) { - return FILTER_REJECT - } - return odfUtils.scanLeftForAnyCharacter(odfUtils.previousNode(container)) ? FILTER_REJECT : FILTER_ACCEPT - } - leftNode = iterator.leftNode(); - rightNode = container; - container = (container.parentNode); - r = checkLeftRight(container, leftNode, rightNode) - }else { - if(!odfUtils.isGroupingElement(container) || odfUtils.isWithinTrackedChanges(container, getRootNode())) { - r = FILTER_REJECT - }else { - leftNode = iterator.leftNode(); - rightNode = iterator.rightNode(); - r = checkLeftRight(container, leftNode, rightNode) - } - } - return r - } -}; if(typeof Object.create !== "function") { Object["create"] = function(o) { var F = function() { @@ -6593,76 +4856,6 @@ xmldom.LSSerializer = function LSSerializer() { }; /* - 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/ -*/ -runtime.loadClass("odf.Namespaces"); -runtime.loadClass("xmldom.LSSerializer"); -runtime.loadClass("odf.OdfNodeFilter"); -runtime.loadClass("odf.TextSerializer"); -gui.Clipboard = function Clipboard() { - var xmlSerializer, textSerializer, filter; - this.setDataFromRange = function(e, range) { - var result = true, setDataResult, clipboard = e.clipboardData, window = runtime.getWindow(), document = range.startContainer.ownerDocument, fragmentContainer; - if(!clipboard && window) { - clipboard = window.clipboardData - } - if(clipboard) { - fragmentContainer = document.createElement("span"); - fragmentContainer.appendChild(range.cloneContents()); - setDataResult = clipboard.setData("text/plain", textSerializer.writeToString(fragmentContainer)); - result = result && setDataResult; - setDataResult = clipboard.setData("text/html", xmlSerializer.writeToString(fragmentContainer, odf.Namespaces.namespaceMap)); - result = result && setDataResult; - e.preventDefault() - }else { - result = false - } - return result - }; - function init() { - xmlSerializer = new xmldom.LSSerializer; - textSerializer = new odf.TextSerializer; - filter = new odf.OdfNodeFilter; - xmlSerializer.filter = filter; - textSerializer.filter = filter - } - init() -}; -/* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart @@ -6698,13 +4891,6 @@ gui.Clipboard = function Clipboard() { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.Base64"); -runtime.loadClass("core.Zip"); -runtime.loadClass("core.DomUtils"); -runtime.loadClass("xmldom.LSSerializer"); -runtime.loadClass("odf.StyleInfo"); -runtime.loadClass("odf.Namespaces"); -runtime.loadClass("odf.OdfNodeFilter"); (function() { var styleInfo = new odf.StyleInfo, domUtils = new core.DomUtils, officens = "urn:oasis:names:tc:opendocument:xmlns:office:1.0", manifestns = "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0", webodfns = "urn:webodf:names:scope", stylens = odf.Namespaces.stylens, nodeorder = ["meta", "settings", "scripts", "font-face-decls", "styles", "automatic-styles", "master-styles", "body"], automaticStylePrefix = (new Date).getTime() + "_webodf_", base64 = new core.Base64, documentStylesScope = "document-styles", documentContentScope = "document-content"; @@ -6784,6 +4970,9 @@ runtime.loadClass("odf.OdfNodeFilter"); odf.ODFDocumentElement.prototype.styles; odf.ODFDocumentElement.namespaceURI = officens; odf.ODFDocumentElement.localName = "document"; + odf.AnnotationElement = function AnnotationElement() { + }; + odf.AnnotationElement.prototype.annotationEndElement; odf.OdfPart = function OdfPart(name, mimetype, container, zip) { var self = this; this.size = 0; @@ -6848,6 +5037,43 @@ runtime.loadClass("odf.OdfNodeFilter"); n = next } } + function linkAnnotationStartAndEndElements(rootElement) { + var document = rootElement.ownerDocument, annotationStarts = {}, n, name, annotationStart, nodeIterator = document.createNodeIterator(rootElement, NodeFilter.SHOW_ELEMENT, null, false); + n = (nodeIterator.nextNode()); + while(n) { + if(n.namespaceURI === officens) { + if(n.localName === "annotation") { + name = n.getAttributeNS(officens, "name"); + if(name) { + if(annotationStarts.hasOwnProperty(name)) { + runtime.log("Warning: annotation name used more than once with <office:annotation/>: '" + name + "'") + }else { + annotationStarts[name] = n + } + } + }else { + if(n.localName === "annotation-end") { + name = n.getAttributeNS(officens, "name"); + if(name) { + if(annotationStarts.hasOwnProperty(name)) { + annotationStart = (annotationStarts[name]); + if(!annotationStart.annotationEndElement) { + annotationStart.annotationEndElement = n + }else { + runtime.log("Warning: annotation name used more than once with <office:annotation-end/>: '" + name + "'") + } + }else { + runtime.log("Warning: annotation end without an annotation start, name: '" + name + "'") + } + }else { + runtime.log("Warning: annotation end without a name found") + } + } + } + } + n = (nodeIterator.nextNode()) + } + } function setAutomaticStylesScope(stylesRootElement, scope) { var n = stylesRootElement && stylesRootElement.firstChild; while(n) { @@ -6994,7 +5220,8 @@ runtime.loadClass("odf.OdfNodeFilter"); root.automaticStyles = getDirectChild(root, officens, "automatic-styles"); root.masterStyles = getDirectChild(root, officens, "master-styles"); root.body = getDirectChild(root, officens, "body"); - root.meta = getDirectChild(root, officens, "meta") + root.meta = getDirectChild(root, officens, "meta"); + linkAnnotationStartAndEndElements(root) } function handleFlatXml(xmldoc) { var root = importRootNode(xmldoc); @@ -7109,6 +5336,7 @@ runtime.loadClass("odf.OdfNodeFilter"); loadNextComponent(remainingComponents) }) }else { + linkAnnotationStartAndEndElements(self.rootElement); setState(OdfContainer.DONE) } } @@ -7150,7 +5378,9 @@ runtime.loadClass("odf.OdfNodeFilter"); function serializeSettingsXml() { var serializer = new xmldom.LSSerializer, s = createDocumentElement("document-settings"); serializer.filter = new odf.OdfNodeFilter; - s += serializer.writeToString(self.rootElement.settings, odf.Namespaces.namespaceMap); + if(self.rootElement.settings.firstElementChild) { + s += serializer.writeToString(self.rootElement.settings, odf.Namespaces.namespaceMap) + } s += "</office:document-settings>"; return s } @@ -7265,6 +5495,11 @@ runtime.loadClass("odf.OdfNodeFilter"); addToplevelElement("masterStyles", "master-styles"); addToplevelElement("body"); root.body.appendChild(text); + partMimetypes["/"] = "application/vnd.oasis.opendocument.text"; + partMimetypes["settings.xml"] = "text/xml"; + partMimetypes["meta.xml"] = "text/xml"; + partMimetypes["styles.xml"] = "text/xml"; + partMimetypes["content.xml"] = "text/xml"; setState(OdfContainer.DONE); return emptyzip } @@ -7381,9 +5616,959 @@ runtime.loadClass("odf.OdfNodeFilter"); @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.Base64"); -runtime.loadClass("xmldom.XPath"); -runtime.loadClass("odf.OdfContainer"); +odf.OdfUtils = function OdfUtils() { + var textns = odf.Namespaces.textns, drawns = odf.Namespaces.drawns, xlinkns = odf.Namespaces.xlinkns, whitespaceOnly = /^\s*$/, domUtils = new core.DomUtils; + function isImage(e) { + var name = e && e.localName; + return name === "image" && e.namespaceURI === drawns + } + this.isImage = isImage; + function isCharacterFrame(e) { + return e !== null && (e.nodeType === Node.ELEMENT_NODE && (e.localName === "frame" && (e.namespaceURI === drawns && (e).getAttributeNS(textns, "anchor-type") === "as-char"))) + } + this.isCharacterFrame = isCharacterFrame; + function isAnnotation(e) { + var name = e && e.localName; + return name === "annotation" && e.namespaceURI === odf.Namespaces.officens + } + function isAnnotationWrapper(e) { + var name = e && e.localName; + return name === "div" && (e).className === "annotationWrapper" + } + function isInlineRoot(e) { + return isAnnotation(e) || isAnnotationWrapper(e) + } + this.isInlineRoot = isInlineRoot; + this.isTextSpan = function(e) { + var name = e && e.localName; + return name === "span" && e.namespaceURI === textns + }; + function isHyperlink(node) { + var name = node && node.localName; + return name === "a" && node.namespaceURI === textns + } + this.isHyperlink = isHyperlink; + this.getHyperlinkTarget = function(element) { + return element.getAttributeNS(xlinkns, "href") + }; + function isParagraph(e) { + var name = e && e.localName; + return(name === "p" || name === "h") && e.namespaceURI === textns + } + this.isParagraph = isParagraph; + function getParagraphElement(node) { + while(node && !isParagraph(node)) { + node = node.parentNode + } + return(node) + } + this.getParagraphElement = getParagraphElement; + this.isWithinTrackedChanges = function(node, container) { + while(node && node !== container) { + if(node.namespaceURI === textns && node.localName === "tracked-changes") { + return true + } + node = node.parentNode + } + return false + }; + this.isListItem = function(e) { + var name = e && e.localName; + return name === "list-item" && e.namespaceURI === textns + }; + this.isLineBreak = function(e) { + var name = e && e.localName; + return name === "line-break" && e.namespaceURI === textns + }; + function isODFWhitespace(text) { + return/^[ \t\r\n]+$/.test(text) + } + this.isODFWhitespace = isODFWhitespace; + function isGroupingElement(n) { + if(n === null || n.nodeType !== Node.ELEMENT_NODE) { + return false + } + var e = (n), localName = e.localName; + return/^(span|p|h|a|meta)$/.test(localName) && e.namespaceURI === textns || localName === "span" && e.className === "annotationHighlight" + } + this.isGroupingElement = isGroupingElement; + function isCharacterElement(e) { + var n = e && e.localName, ns, r = false; + if(n) { + ns = e.namespaceURI; + if(ns === textns) { + r = n === "s" || (n === "tab" || n === "line-break") + } + } + return r + } + this.isCharacterElement = isCharacterElement; + function isAnchoredAsCharacterElement(e) { + return isCharacterElement(e) || (isCharacterFrame(e) || isInlineRoot(e)) + } + this.isAnchoredAsCharacterElement = isAnchoredAsCharacterElement; + function isSpaceElement(e) { + var n = e && e.localName, ns, r = false; + if(n) { + ns = e.namespaceURI; + if(ns === textns) { + r = n === "s" + } + } + return r + } + this.isSpaceElement = isSpaceElement; + function firstChild(node) { + while(node.firstChild !== null && isGroupingElement(node)) { + node = node.firstChild + } + return node + } + this.firstChild = firstChild; + function lastChild(node) { + while(node.lastChild !== null && isGroupingElement(node)) { + node = node.lastChild + } + return node + } + this.lastChild = lastChild; + function previousNode(node) { + while(!isParagraph(node) && node.previousSibling === null) { + node = (node.parentNode) + } + return isParagraph(node) ? null : lastChild((node.previousSibling)) + } + this.previousNode = previousNode; + function nextNode(node) { + while(!isParagraph(node) && node.nextSibling === null) { + node = (node.parentNode) + } + return isParagraph(node) ? null : firstChild((node.nextSibling)) + } + this.nextNode = nextNode; + function scanLeftForNonSpace(node) { + var r = false, text; + while(node) { + if(node.nodeType === Node.TEXT_NODE) { + text = (node); + if(text.length === 0) { + node = previousNode(text) + }else { + return!isODFWhitespace(text.data.substr(text.length - 1, 1)) + } + }else { + if(isAnchoredAsCharacterElement(node)) { + r = isSpaceElement(node) === false; + node = null + }else { + node = previousNode(node) + } + } + } + return r + } + this.scanLeftForNonSpace = scanLeftForNonSpace; + function lookLeftForCharacter(node) { + var text, r = 0, tl = 0; + if(node.nodeType === Node.TEXT_NODE) { + tl = (node).length + } + if(tl > 0) { + text = (node).data; + if(!isODFWhitespace(text.substr(tl - 1, 1))) { + r = 1 + }else { + if(tl === 1) { + r = scanLeftForNonSpace(previousNode(node)) ? 2 : 0 + }else { + r = isODFWhitespace(text.substr(tl - 2, 1)) ? 0 : 2 + } + } + }else { + if(isAnchoredAsCharacterElement(node)) { + r = 1 + } + } + return r + } + this.lookLeftForCharacter = lookLeftForCharacter; + function lookRightForCharacter(node) { + var r = false, l = 0; + if(node && node.nodeType === Node.TEXT_NODE) { + l = (node).length + } + if(l > 0) { + r = !isODFWhitespace((node).data.substr(0, 1)) + }else { + if(isAnchoredAsCharacterElement(node)) { + r = true + } + } + return r + } + this.lookRightForCharacter = lookRightForCharacter; + function scanLeftForAnyCharacter(node) { + var r = false, l; + node = node && lastChild(node); + while(node) { + if(node.nodeType === Node.TEXT_NODE) { + l = (node).length + }else { + l = 0 + } + if(l > 0 && !isODFWhitespace((node).data)) { + r = true; + break + } + if(isAnchoredAsCharacterElement(node)) { + r = true; + break + } + node = previousNode(node) + } + return r + } + this.scanLeftForAnyCharacter = scanLeftForAnyCharacter; + function scanRightForAnyCharacter(node) { + var r = false, l; + node = node && firstChild(node); + while(node) { + if(node.nodeType === Node.TEXT_NODE) { + l = (node).length + }else { + l = 0 + } + if(l > 0 && !isODFWhitespace((node).data)) { + r = true; + break + } + if(isAnchoredAsCharacterElement(node)) { + r = true; + break + } + node = nextNode(node) + } + return r + } + this.scanRightForAnyCharacter = scanRightForAnyCharacter; + function isTrailingWhitespace(textnode, offset) { + if(!isODFWhitespace(textnode.data.substr(offset))) { + return false + } + return!scanRightForAnyCharacter(nextNode(textnode)) + } + this.isTrailingWhitespace = isTrailingWhitespace; + function isSignificantWhitespace(textNode, offset) { + var text = textNode.data, result; + if(!isODFWhitespace(text[offset])) { + return false + } + if(isAnchoredAsCharacterElement(textNode.parentNode)) { + return false + } + if(offset > 0) { + if(!isODFWhitespace(text[offset - 1])) { + result = true + } + }else { + if(scanLeftForNonSpace(previousNode(textNode))) { + result = true + } + } + if(result === true) { + return isTrailingWhitespace(textNode, offset) ? false : true + } + return false + } + this.isSignificantWhitespace = isSignificantWhitespace; + this.isDowngradableSpaceElement = function(node) { + if(node.namespaceURI === textns && node.localName === "s") { + return scanLeftForNonSpace(previousNode(node)) && scanRightForAnyCharacter(nextNode(node)) + } + return false + }; + function getFirstNonWhitespaceChild(node) { + var child = node && node.firstChild; + while(child && (child.nodeType === Node.TEXT_NODE && whitespaceOnly.test(child.nodeValue))) { + child = child.nextSibling + } + return child + } + this.getFirstNonWhitespaceChild = getFirstNonWhitespaceChild; + function parseLength(length) { + var re = /(-?[0-9]*[0-9][0-9]*(\.[0-9]*)?|0+\.[0-9]*[1-9][0-9]*|\.[0-9]*[1-9][0-9]*)((cm)|(mm)|(in)|(pt)|(pc)|(px)|(%))/, m = re.exec(length); + if(!m) { + return null + } + return{value:parseFloat(m[1]), unit:m[3]} + } + this.parseLength = parseLength; + function parsePositiveLength(length) { + var result = parseLength(length); + if(result && (result.value <= 0 || result.unit === "%")) { + return null + } + return result + } + function parseNonNegativeLength(length) { + var result = parseLength(length); + if(result && (result.value < 0 || result.unit === "%")) { + return null + } + return result + } + this.parseNonNegativeLength = parseNonNegativeLength; + function parsePercentage(length) { + var result = parseLength(length); + if(result && result.unit !== "%") { + return null + } + return result + } + function parseFoFontSize(fontSize) { + return parsePositiveLength(fontSize) || parsePercentage(fontSize) + } + this.parseFoFontSize = parseFoFontSize; + function parseFoLineHeight(lineHeight) { + return parseNonNegativeLength(lineHeight) || parsePercentage(lineHeight) + } + this.parseFoLineHeight = parseFoLineHeight; + function isTextContentContainingNode(node) { + switch(node.namespaceURI) { + case odf.Namespaces.drawns: + ; + case odf.Namespaces.svgns: + ; + case odf.Namespaces.dr3dns: + return false; + case odf.Namespaces.textns: + switch(node.localName) { + case "note-body": + ; + case "ruby-text": + return false + } + break; + case odf.Namespaces.officens: + switch(node.localName) { + case "annotation": + ; + case "binary-data": + ; + case "event-listeners": + return false + } + break; + default: + switch(node.localName) { + case "cursor": + ; + case "editinfo": + return false + } + break + } + return true + } + this.isTextContentContainingNode = isTextContentContainingNode; + function isSignificantTextContent(textNode) { + return Boolean(getParagraphElement(textNode) && (!isODFWhitespace(textNode.textContent) || isSignificantWhitespace(textNode, 0))) + } + function removePartiallyContainedNodes(range, nodes) { + while(nodes.length > 0 && !domUtils.rangeContainsNode(range, (nodes[0]))) { + nodes.shift() + } + while(nodes.length > 0 && !domUtils.rangeContainsNode(range, (nodes[nodes.length - 1]))) { + nodes.pop() + } + } + function getTextNodes(range, includePartial) { + var textNodes; + function nodeFilter(node) { + var result = NodeFilter.FILTER_REJECT; + if(node.nodeType === Node.TEXT_NODE) { + if(isSignificantTextContent((node))) { + result = NodeFilter.FILTER_ACCEPT + } + }else { + if(isTextContentContainingNode(node)) { + result = NodeFilter.FILTER_SKIP + } + } + return result + } + textNodes = domUtils.getNodesInRange(range, nodeFilter, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT); + if(!includePartial) { + removePartiallyContainedNodes(range, textNodes) + } + return textNodes + } + this.getTextNodes = getTextNodes; + function getTextElements(range, includePartial, includeInsignificantWhitespace) { + var elements; + function nodeFilter(node) { + var result = NodeFilter.FILTER_REJECT; + if(isCharacterElement(node.parentNode) || isInlineRoot(node)) { + result = NodeFilter.FILTER_REJECT + }else { + if(node.nodeType === Node.TEXT_NODE) { + if(includeInsignificantWhitespace || isSignificantTextContent((node))) { + result = NodeFilter.FILTER_ACCEPT + } + }else { + if(isAnchoredAsCharacterElement(node)) { + result = NodeFilter.FILTER_ACCEPT + }else { + if(isTextContentContainingNode(node) || isGroupingElement(node)) { + result = NodeFilter.FILTER_SKIP + } + } + } + } + return result + } + elements = domUtils.getNodesInRange(range, nodeFilter, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT); + if(!includePartial) { + removePartiallyContainedNodes(range, elements) + } + return elements + } + this.getTextElements = getTextElements; + function prependParentContainers(startContainer, elements, filter) { + var container = startContainer; + while(container) { + if(filter(container)) { + if(elements[0] !== container) { + elements.unshift(container) + } + break + } + if(isInlineRoot(container)) { + break + } + container = container.parentNode + } + } + this.getParagraphElements = function(range) { + var elements; + function nodeFilter(node) { + var result = NodeFilter.FILTER_REJECT; + if(isParagraph(node)) { + result = NodeFilter.FILTER_ACCEPT + }else { + if(isTextContentContainingNode(node) || isGroupingElement(node)) { + result = NodeFilter.FILTER_SKIP + } + } + return result + } + elements = domUtils.getNodesInRange(range, nodeFilter, NodeFilter.SHOW_ELEMENT); + prependParentContainers((range.startContainer), elements, isParagraph); + return elements + }; + this.getImageElements = function(range) { + var elements; + function nodeFilter(node) { + var result = NodeFilter.FILTER_SKIP; + if(isImage(node)) { + result = NodeFilter.FILTER_ACCEPT + } + return result + } + elements = domUtils.getNodesInRange(range, nodeFilter, NodeFilter.SHOW_ELEMENT); + prependParentContainers((range.startContainer), elements, isImage); + return elements + }; + function getRightNode(container, offset) { + var node = container; + if(offset < node.childNodes.length - 1) { + node = (node.childNodes[offset + 1]) + }else { + while(!node.nextSibling) { + node = node.parentNode + } + node = node.nextSibling + } + while(node.firstChild) { + node = node.firstChild + } + return node + } + this.getHyperlinkElements = function(range) { + var links = [], newRange = (range.cloneRange()), node, textNodes; + if(range.collapsed && range.endContainer.nodeType === Node.ELEMENT_NODE) { + node = getRightNode(range.endContainer, range.endOffset); + if(node.nodeType === Node.TEXT_NODE) { + newRange.setEnd(node, 1) + } + } + textNodes = getTextElements(newRange, true, false); + textNodes.forEach(function(node) { + var parent = node.parentNode; + while(!isParagraph(parent)) { + if(isHyperlink(parent) && links.indexOf(parent) === -1) { + links.push(parent); + break + } + parent = parent.parentNode + } + }); + newRange.detach(); + return links + } +}; +/* + + Copyright (C) 2012-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/ +*/ +gui.AnnotatableCanvas = function AnnotatableCanvas() { +}; +gui.AnnotatableCanvas.prototype.refreshSize = function() { +}; +gui.AnnotatableCanvas.prototype.getZoomLevel = function() { +}; +gui.AnnotatableCanvas.prototype.getSizer = function() { +}; +gui.AnnotationViewManager = function AnnotationViewManager(canvas, odfFragment, annotationsPane, showAnnotationRemoveButton) { + var annotations = [], doc = odfFragment.ownerDocument, odfUtils = new odf.OdfUtils, CONNECTOR_MARGIN = 30, NOTE_MARGIN = 20, window = runtime.getWindow(); + runtime.assert(Boolean(window), "Expected to be run in an environment which has a global window, like a browser."); + function wrapAnnotation(annotation) { + var annotationWrapper = doc.createElement("div"), annotationNote = doc.createElement("div"), connectorHorizontal = doc.createElement("div"), connectorAngular = doc.createElement("div"), removeButton; + annotationWrapper.className = "annotationWrapper"; + annotation.parentNode.insertBefore(annotationWrapper, annotation); + annotationNote.className = "annotationNote"; + annotationNote.appendChild(annotation); + if(showAnnotationRemoveButton) { + removeButton = doc.createElement("div"); + removeButton.className = "annotationRemoveButton"; + annotationNote.appendChild(removeButton) + } + connectorHorizontal.className = "annotationConnector horizontal"; + connectorAngular.className = "annotationConnector angular"; + annotationWrapper.appendChild(annotationNote); + annotationWrapper.appendChild(connectorHorizontal); + annotationWrapper.appendChild(connectorAngular) + } + function unwrapAnnotation(annotation) { + var annotationWrapper = annotation.parentNode.parentNode; + if(annotationWrapper.localName === "div") { + annotationWrapper.parentNode.insertBefore(annotation, annotationWrapper); + annotationWrapper.parentNode.removeChild(annotationWrapper) + } + } + function highlightAnnotation(annotation) { + var annotationEnd = annotation.annotationEndElement, range = doc.createRange(), annotationName = annotation.getAttributeNS(odf.Namespaces.officens, "name"), textNodes; + if(annotationEnd) { + range.setStart(annotation, annotation.childNodes.length); + range.setEnd(annotationEnd, 0); + textNodes = odfUtils.getTextNodes(range, false); + textNodes.forEach(function(n) { + var container = doc.createElement("span"); + container.className = "annotationHighlight"; + container.setAttribute("annotation", annotationName); + n.parentNode.insertBefore(container, n); + container.appendChild(n) + }) + } + range.detach() + } + function unhighlightAnnotation(annotation) { + var annotationName = annotation.getAttributeNS(odf.Namespaces.officens, "name"), highlightSpans = doc.querySelectorAll('span.annotationHighlight[annotation="' + annotationName + '"]'), i, container; + for(i = 0;i < highlightSpans.length;i += 1) { + container = highlightSpans.item(i); + while(container.firstChild) { + container.parentNode.insertBefore(container.firstChild, container) + } + container.parentNode.removeChild(container) + } + } + function lineDistance(point1, point2) { + var xs = 0, ys = 0; + xs = point2.x - point1.x; + xs = xs * xs; + ys = point2.y - point1.y; + ys = ys * ys; + return Math.sqrt(xs + ys) + } + function renderAnnotation(annotation) { + var annotationNote = (annotation.parentNode), connectorHorizontal = annotationNote.nextElementSibling, connectorAngular = connectorHorizontal.nextElementSibling, annotationWrapper = (annotationNote.parentNode), connectorAngle = 0, previousAnnotation = annotations[annotations.indexOf(annotation) - 1], previousRect, zoomLevel = canvas.getZoomLevel(); + annotationNote.style.left = (annotationsPane.getBoundingClientRect().left - annotationWrapper.getBoundingClientRect().left) / zoomLevel + "px"; + annotationNote.style.width = annotationsPane.getBoundingClientRect().width / zoomLevel + "px"; + connectorHorizontal.style.width = parseFloat(annotationNote.style.left) - CONNECTOR_MARGIN + "px"; + if(previousAnnotation) { + previousRect = (previousAnnotation.parentNode).getBoundingClientRect(); + if((annotationWrapper.getBoundingClientRect().top - previousRect.bottom) / zoomLevel <= NOTE_MARGIN) { + annotationNote.style.top = Math.abs(annotationWrapper.getBoundingClientRect().top - previousRect.bottom) / zoomLevel + NOTE_MARGIN + "px" + }else { + annotationNote.style.top = "0px" + } + } + connectorAngular.style.left = connectorHorizontal.getBoundingClientRect().width / zoomLevel + "px"; + connectorAngular.style.width = lineDistance({x:connectorAngular.getBoundingClientRect().left / zoomLevel, y:connectorAngular.getBoundingClientRect().top / zoomLevel}, {x:annotationNote.getBoundingClientRect().left / zoomLevel, y:annotationNote.getBoundingClientRect().top / zoomLevel}) + "px"; + connectorAngle = Math.asin((annotationNote.getBoundingClientRect().top - connectorAngular.getBoundingClientRect().top) / (zoomLevel * parseFloat(connectorAngular.style.width))); + connectorAngular.style.transform = "rotate(" + connectorAngle + "rad)"; + connectorAngular.style.MozTransform = "rotate(" + connectorAngle + "rad)"; + connectorAngular.style.WebkitTransform = "rotate(" + connectorAngle + "rad)"; + connectorAngular.style.msTransform = "rotate(" + connectorAngle + "rad)" + } + function showAnnotationsPane(show) { + var sizer = canvas.getSizer(); + if(show) { + annotationsPane.style.display = "inline-block"; + sizer.style.paddingRight = window.getComputedStyle(annotationsPane).width + }else { + annotationsPane.style.display = "none"; + sizer.style.paddingRight = 0 + } + canvas.refreshSize() + } + function sortAnnotations() { + annotations.sort(function(a, b) { + if((a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0) { + return-1 + } + return 1 + }) + } + function rerenderAnnotations() { + var i; + for(i = 0;i < annotations.length;i += 1) { + renderAnnotation(annotations[i]) + } + } + this.rerenderAnnotations = rerenderAnnotations; + function getMinimumHeightForAnnotationPane() { + if(annotationsPane.style.display !== "none" && annotations.length > 0) { + return((annotations[annotations.length - 1].parentNode).getBoundingClientRect().bottom - annotationsPane.getBoundingClientRect().top) / canvas.getZoomLevel() + "px" + } + return null + } + this.getMinimumHeightForAnnotationPane = getMinimumHeightForAnnotationPane; + function addAnnotation(annotation) { + showAnnotationsPane(true); + annotations.push(annotation); + sortAnnotations(); + wrapAnnotation(annotation); + if(annotation.annotationEndElement) { + highlightAnnotation(annotation) + } + rerenderAnnotations() + } + this.addAnnotation = addAnnotation; + function forgetAnnotation(annotation) { + var index = annotations.indexOf(annotation); + unwrapAnnotation(annotation); + unhighlightAnnotation(annotation); + if(index !== -1) { + annotations.splice(index, 1) + } + if(annotations.length === 0) { + showAnnotationsPane(false) + } + } + function forgetAnnotations() { + while(annotations.length) { + forgetAnnotation(annotations[0]) + } + } + this.forgetAnnotations = forgetAnnotations +}; +/* + + Copyright (C) 2014 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +(function() { + function Point(x, y) { + var self = this; + this.getDistance = function(point) { + var xOffset = self.x - point.x, yOffset = self.y - point.y; + return Math.sqrt(xOffset * xOffset + yOffset * yOffset) + }; + this.getCenter = function(point) { + return new Point((self.x + point.x) / 2, (self.y + point.y) / 2) + }; + this.x; + this.y; + function init() { + self.x = x; + self.y = y + } + init() + } + gui.ZoomHelper = function() { + var zoomableElement, panPoint, previousPanPoint, firstPinchDistance, zoom, previousZoom, maxZoom = 4, offsetParent, events = new core.EventNotifier([gui.ZoomHelper.signalZoomChanged]), gestures = {NONE:0, SCROLL:1, PINCH:2}, currentGesture = gestures.NONE, requiresCustomScrollBars = runtime.getWindow().hasOwnProperty("ontouchstart"); + function applyCSSTransform(x, y, scale, is3D) { + var transformCommand; + if(is3D) { + transformCommand = "translate3d(" + x + "px, " + y + "px, 0) scale3d(" + scale + ", " + scale + ", 1)" + }else { + transformCommand = "translate(" + x + "px, " + y + "px) scale(" + scale + ")" + } + zoomableElement.style.WebkitTransform = transformCommand; + zoomableElement.style.MozTransform = transformCommand; + zoomableElement.style.msTransform = transformCommand; + zoomableElement.style.OTransform = transformCommand; + zoomableElement.style.transform = transformCommand + } + function applyTransform(is3D) { + if(is3D) { + applyCSSTransform(-panPoint.x, -panPoint.y, zoom, true) + }else { + applyCSSTransform(0, 0, zoom, true); + applyCSSTransform(0, 0, zoom, false) + } + } + function applyFastTransform() { + applyTransform(true) + } + function applyDetailedTransform() { + applyTransform(false) + } + function enableScrollBars(enable) { + if(!offsetParent || !requiresCustomScrollBars) { + return + } + var initialOverflow = offsetParent.style.overflow, enabled = offsetParent.classList.contains("customScrollbars"); + if(enable && enabled || !enable && !enabled) { + return + } + if(enable) { + offsetParent.classList.add("customScrollbars"); + offsetParent.style.overflow = "hidden"; + runtime.requestAnimationFrame(function() { + offsetParent.style.overflow = initialOverflow + }) + }else { + offsetParent.classList.remove("customScrollbars") + } + } + function removeScroll() { + applyCSSTransform(-panPoint.x, -panPoint.y, zoom, true); + offsetParent.scrollLeft = 0; + offsetParent.scrollTop = 0; + enableScrollBars(false) + } + function restoreScroll() { + applyCSSTransform(0, 0, zoom, true); + offsetParent.scrollLeft = panPoint.x; + offsetParent.scrollTop = panPoint.y; + enableScrollBars(true) + } + function getPoint(touch) { + return new Point(touch.pageX - zoomableElement.offsetLeft, touch.pageY - zoomableElement.offsetTop) + } + function sanitizePointForPan(point) { + return new Point(Math.min(Math.max(point.x, zoomableElement.offsetLeft), (zoomableElement.offsetLeft + zoomableElement.offsetWidth) * zoom - offsetParent.clientWidth), Math.min(Math.max(point.y, zoomableElement.offsetTop), (zoomableElement.offsetTop + zoomableElement.offsetHeight) * zoom - offsetParent.clientHeight)) + } + function processPan(point) { + if(previousPanPoint) { + panPoint.x -= point.x - previousPanPoint.x; + panPoint.y -= point.y - previousPanPoint.y; + panPoint = sanitizePointForPan(panPoint) + } + previousPanPoint = point + } + function processZoom(zoomPoint, incrementalZoom) { + var originalZoom = zoom, actuallyIncrementedZoom, minZoom = Math.min(maxZoom, zoomableElement.offsetParent.clientWidth / zoomableElement.offsetWidth); + zoom = previousZoom * incrementalZoom; + zoom = Math.min(Math.max(zoom, minZoom), maxZoom); + actuallyIncrementedZoom = zoom / originalZoom; + panPoint.x += (actuallyIncrementedZoom - 1) * (zoomPoint.x + panPoint.x); + panPoint.y += (actuallyIncrementedZoom - 1) * (zoomPoint.y + panPoint.y) + } + function processPinch(point1, point2) { + var zoomPoint = point1.getCenter(point2), pinchDistance = point1.getDistance(point2), incrementalZoom = pinchDistance / firstPinchDistance; + processPan(zoomPoint); + processZoom(zoomPoint, incrementalZoom) + } + function prepareGesture(event) { + var fingers = event.touches.length, point1 = fingers > 0 ? getPoint(event.touches[0]) : null, point2 = fingers > 1 ? getPoint(event.touches[1]) : null; + if(point1 && point2) { + firstPinchDistance = point1.getDistance(point2); + previousZoom = zoom; + previousPanPoint = point1.getCenter(point2); + removeScroll(); + currentGesture = gestures.PINCH + }else { + if(point1) { + previousPanPoint = point1; + currentGesture = gestures.SCROLL + } + } + } + function processGesture(event) { + var fingers = event.touches.length, point1 = fingers > 0 ? getPoint(event.touches[0]) : null, point2 = fingers > 1 ? getPoint(event.touches[1]) : null; + if(point1 && point2) { + event.preventDefault(); + if(currentGesture === gestures.SCROLL) { + currentGesture = gestures.PINCH; + removeScroll(); + firstPinchDistance = point1.getDistance(point2); + return + } + processPinch(point1, point2); + applyFastTransform() + }else { + if(point1) { + if(currentGesture === gestures.PINCH) { + currentGesture = gestures.SCROLL; + restoreScroll(); + return + } + processPan(point1) + } + } + } + function sanitizeGesture() { + if(currentGesture === gestures.PINCH) { + events.emit(gui.ZoomHelper.signalZoomChanged, zoom); + restoreScroll(); + applyDetailedTransform() + } + currentGesture = gestures.NONE + } + this.subscribe = function(eventid, cb) { + events.subscribe(eventid, cb) + }; + this.unsubscribe = function(eventid, cb) { + events.unsubscribe(eventid, cb) + }; + this.getZoomLevel = function() { + return zoom + }; + this.setZoomLevel = function(zoomLevel) { + if(zoomableElement) { + zoom = zoomLevel; + applyDetailedTransform(); + events.emit(gui.ZoomHelper.signalZoomChanged, zoom) + } + }; + function registerGestureListeners() { + if(offsetParent) { + offsetParent.addEventListener("touchstart", (prepareGesture), false); + offsetParent.addEventListener("touchmove", (processGesture), false); + offsetParent.addEventListener("touchend", (sanitizeGesture), false) + } + } + function unregisterGestureListeners() { + if(offsetParent) { + offsetParent.removeEventListener("touchstart", (prepareGesture), false); + offsetParent.removeEventListener("touchmove", (processGesture), false); + offsetParent.removeEventListener("touchend", (sanitizeGesture), false) + } + } + this.destroy = function(callback) { + unregisterGestureListeners(); + enableScrollBars(false); + callback() + }; + this.setZoomableElement = function(element) { + unregisterGestureListeners(); + zoomableElement = element; + offsetParent = (zoomableElement.offsetParent); + applyDetailedTransform(); + registerGestureListeners(); + enableScrollBars(true) + }; + function init() { + zoom = 1; + previousZoom = 1; + panPoint = new Point(0, 0) + } + init() + }; + gui.ZoomHelper.signalZoomChanged = "zoomChanged" +})(); +/* + + Copyright (C) 2012-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() { var xpath = xmldom.XPath, base64 = new core.Base64; function getEmbeddedFontDeclarations(fontFaceDecls) { @@ -7496,114 +6681,6 @@ runtime.loadClass("odf.OdfContainer"); @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils"); -runtime.loadClass("core.Utils"); -odf.ObjectNameGenerator = function ObjectNameGenerator(odfContainer, memberId) { - var stylens = odf.Namespaces.stylens, drawns = odf.Namespaces.drawns, xlinkns = odf.Namespaces.xlinkns, domUtils = new core.DomUtils, utils = new core.Utils, memberIdHash = utils.hashString(memberId), styleNameGenerator = null, frameNameGenerator = null, imageNameGenerator = null, existingFrameNames = {}, existingImageNames = {}; - function NameGenerator(prefix, findExistingNames) { - var reportedNames = {}; - this.generateName = function() { - var existingNames = findExistingNames(), startIndex = 0, name; - do { - name = prefix + startIndex; - startIndex += 1 - }while(reportedNames[name] || existingNames[name]); - reportedNames[name] = true; - return name - } - } - function getAllStyleNames() { - var styleElements = [odfContainer.rootElement.automaticStyles, odfContainer.rootElement.styles], styleNames = {}; - function getStyleNames(styleListElement) { - var e = styleListElement.firstElementChild; - while(e) { - if(e.namespaceURI === stylens && e.localName === "style") { - styleNames[e.getAttributeNS(stylens, "name")] = true - } - e = e.nextElementSibling - } - } - styleElements.forEach(getStyleNames); - return styleNames - } - this.generateStyleName = function() { - if(styleNameGenerator === null) { - styleNameGenerator = new NameGenerator("auto" + memberIdHash + "_", function() { - return getAllStyleNames() - }) - } - return styleNameGenerator.generateName() - }; - this.generateFrameName = function() { - if(frameNameGenerator === null) { - var nodes = domUtils.getElementsByTagNameNS(odfContainer.rootElement.body, drawns, "frame"); - nodes.forEach(function(frame) { - existingFrameNames[frame.getAttributeNS(drawns, "name")] = true - }); - frameNameGenerator = new NameGenerator("fr" + memberIdHash + "_", function() { - return existingFrameNames - }) - } - return frameNameGenerator.generateName() - }; - this.generateImageName = function() { - if(imageNameGenerator === null) { - var nodes = domUtils.getElementsByTagNameNS(odfContainer.rootElement.body, drawns, "image"); - nodes.forEach(function(image) { - var path = image.getAttributeNS(xlinkns, "href"); - path = path.substring("Pictures/".length, path.lastIndexOf(".")); - existingImageNames[path] = true - }); - imageNameGenerator = new NameGenerator("img" + memberIdHash + "_", function() { - return existingImageNames - }) - } - return imageNameGenerator.generateName() - } -}; -/* - - Copyright (C) 2012-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/ -*/ -runtime.loadClass("core.Utils"); -runtime.loadClass("odf.ObjectNameGenerator"); -runtime.loadClass("odf.Namespaces"); -runtime.loadClass("odf.OdfContainer"); -runtime.loadClass("odf.StyleInfo"); -runtime.loadClass("odf.OdfUtils"); odf.Formatting = function Formatting() { var odfContainer, styleInfo = new odf.StyleInfo, svgns = odf.Namespaces.svgns, stylens = odf.Namespaces.stylens, textns = odf.Namespaces.textns, numberns = odf.Namespaces.numberns, fons = odf.Namespaces.fons, odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils, utils = new core.Utils, builtInDefaultStyleAttributesByFamily = {"paragraph":{"style:paragraph-properties":{"fo:text-align":"left"}}}, defaultPageFormatSettings = {width:21.001, height:29.7, margin:2, padding:0}; function getSystemDefaultStyleAttributes(styleFamily) { @@ -7741,11 +6818,9 @@ odf.Formatting = function Formatting() { propertiesMap = getStyleAttributes(node); inheritedPropertiesMap = utils.mergeObjects(propertiesMap, inheritedPropertiesMap) } - if(includeSystemDefault) { + if(includeSystemDefault !== false) { propertiesMap = getSystemDefaultStyleAttributes(styleFamily); - if(propertiesMap) { - inheritedPropertiesMap = utils.mergeObjects(propertiesMap, inheritedPropertiesMap) - } + inheritedPropertiesMap = utils.mergeObjects(propertiesMap, inheritedPropertiesMap) } return inheritedPropertiesMap } @@ -7776,7 +6851,7 @@ odf.Formatting = function Formatting() { if(nodeStyles) { appliedStyles.push(nodeStyles) } - parent = parent.parentElement + parent = (parent.parentNode) } function chainStyles(usedStyleMap) { Object.keys(usedStyleMap).forEach(function(styleFamily) { @@ -7793,38 +6868,47 @@ odf.Formatting = function Formatting() { } return foundContainer ? appliedStyles : undefined } + function isCommonStyleElement(styleNode) { + return styleNode.parentNode === odfContainer.rootElement.styles + } function calculateAppliedStyle(styleChain) { var mergedChildStyle = {orderedStyles:[]}; styleChain.forEach(function(elementStyleSet) { Object.keys((elementStyleSet)).forEach(function(styleFamily) { - var styleName = Object.keys(elementStyleSet[styleFamily])[0], styleElement, parentStyle, displayName; + var styleName = Object.keys(elementStyleSet[styleFamily])[0], styleSummary = {name:styleName, family:styleFamily, displayName:undefined, isCommonStyle:false}, styleElement, parentStyle; styleElement = getStyleElement(styleName, styleFamily); if(styleElement) { parentStyle = getInheritedStyleAttributes((styleElement)); mergedChildStyle = utils.mergeObjects(parentStyle, mergedChildStyle); - displayName = styleElement.getAttributeNS(stylens, "display-name") + styleSummary.displayName = styleElement.getAttributeNS(stylens, "display-name"); + styleSummary.isCommonStyle = isCommonStyleElement(styleElement) }else { runtime.log("No style element found for '" + styleName + "' of family '" + styleFamily + "'") } - mergedChildStyle.orderedStyles.push({name:styleName, family:styleFamily, displayName:displayName}) + mergedChildStyle.orderedStyles.push(styleSummary) }) }); return mergedChildStyle } - this.getAppliedStyles = function(textNodes) { + function getAppliedStyles(nodes, calculatedStylesCache) { var styleChains = {}, styles = []; - textNodes.forEach(function(n) { + if(!calculatedStylesCache) { + calculatedStylesCache = {} + } + nodes.forEach(function(n) { buildStyleChain(n, styleChains) }); Object.keys(styleChains).forEach(function(key) { - styles.push(calculateAppliedStyle(styleChains[key])) + if(!calculatedStylesCache[key]) { + calculatedStylesCache[key] = calculateAppliedStyle(styleChains[key]) + } + styles.push(calculatedStylesCache[key]) }); return styles - }; - this.getAppliedStylesForElement = function(node) { - var styleChain; - styleChain = buildStyleChain(node); - return styleChain ? calculateAppliedStyle(styleChain) : undefined + } + this.getAppliedStyles = getAppliedStyles; + this.getAppliedStylesForElement = function(node, calculatedStylesCache) { + return getAppliedStyles([node], calculatedStylesCache)[0] }; this.updateStyle = function(styleNode, properties) { var fontName, fontFaceNode; @@ -7837,16 +6921,13 @@ odf.Formatting = function Formatting() { odfContainer.rootElement.fontFaceDecls.appendChild(fontFaceNode) } }; - function isAutomaticStyleElement(styleNode) { - return styleNode.parentNode === odfContainer.rootElement.automaticStyles - } this.createDerivedStyleObject = function(parentStyleName, family, overrides) { var originalStyleElement = (getStyleElement(parentStyleName, family)), newStyleObject; runtime.assert(Boolean(originalStyleElement), "No style element found for '" + parentStyleName + "' of family '" + family + "'"); - if(isAutomaticStyleElement(originalStyleElement)) { - newStyleObject = getStyleAttributes(originalStyleElement) - }else { + if(isCommonStyleElement(originalStyleElement)) { newStyleObject = {"style:parent-style-name":parentStyleName} + }else { + newStyleObject = getStyleAttributes(originalStyleElement) } newStyleObject["style:family"] = family; utils.mergeObjects(newStyleObject, overrides); @@ -7994,14 +7075,657 @@ odf.Formatting = function Formatting() { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils"); -runtime.loadClass("odf.OdfContainer"); -runtime.loadClass("odf.Formatting"); -runtime.loadClass("xmldom.XPath"); -runtime.loadClass("odf.FontLoader"); -runtime.loadClass("odf.Style2CSS"); -runtime.loadClass("odf.OdfUtils"); -runtime.loadClass("gui.AnnotationViewManager"); +odf.StyleTreeNode = function StyleTreeNode(element) { + this.derivedStyles = {}; + this.element = element +}; +odf.Style2CSS = function Style2CSS() { + var drawns = odf.Namespaces.drawns, fons = odf.Namespaces.fons, officens = odf.Namespaces.officens, stylens = odf.Namespaces.stylens, svgns = odf.Namespaces.svgns, tablens = odf.Namespaces.tablens, textns = odf.Namespaces.textns, xlinkns = odf.Namespaces.xlinkns, presentationns = odf.Namespaces.presentationns, familynamespaceprefixes = {"graphic":"draw", "drawing-page":"draw", "paragraph":"text", "presentation":"presentation", "ruby":"text", "section":"text", "table":"table", "table-cell":"table", + "table-column":"table", "table-row":"table", "text":"text", "list":"text", "page":"office"}, familytagnames = {"graphic":["circle", "connected", "control", "custom-shape", "ellipse", "frame", "g", "line", "measure", "page", "page-thumbnail", "path", "polygon", "polyline", "rect", "regular-polygon"], "paragraph":["alphabetical-index-entry-template", "h", "illustration-index-entry-template", "index-source-style", "object-index-entry-template", "p", "table-index-entry-template", "table-of-content-entry-template", + "user-index-entry-template"], "presentation":["caption", "circle", "connector", "control", "custom-shape", "ellipse", "frame", "g", "line", "measure", "page-thumbnail", "path", "polygon", "polyline", "rect", "regular-polygon"], "drawing-page":["caption", "circle", "connector", "control", "page", "custom-shape", "ellipse", "frame", "g", "line", "measure", "page-thumbnail", "path", "polygon", "polyline", "rect", "regular-polygon"], "ruby":["ruby", "ruby-text"], "section":["alphabetical-index", "bibliography", + "illustration-index", "index-title", "object-index", "section", "table-of-content", "table-index", "user-index"], "table":["background", "table"], "table-cell":["body", "covered-table-cell", "even-columns", "even-rows", "first-column", "first-row", "last-column", "last-row", "odd-columns", "odd-rows", "table-cell"], "table-column":["table-column"], "table-row":["table-row"], "text":["a", "index-entry-chapter", "index-entry-link-end", "index-entry-link-start", "index-entry-page-number", "index-entry-span", + "index-entry-tab-stop", "index-entry-text", "index-title-template", "linenumbering-configuration", "list-level-style-number", "list-level-style-bullet", "outline-level-style", "span"], "list":["list-item"]}, textPropertySimpleMapping = [[fons, "color", "color"], [fons, "background-color", "background-color"], [fons, "font-weight", "font-weight"], [fons, "font-style", "font-style"]], bgImageSimpleMapping = [[stylens, "repeat", "background-repeat"]], paragraphPropertySimpleMapping = [[fons, "background-color", + "background-color"], [fons, "text-align", "text-align"], [fons, "text-indent", "text-indent"], [fons, "padding", "padding"], [fons, "padding-left", "padding-left"], [fons, "padding-right", "padding-right"], [fons, "padding-top", "padding-top"], [fons, "padding-bottom", "padding-bottom"], [fons, "border-left", "border-left"], [fons, "border-right", "border-right"], [fons, "border-top", "border-top"], [fons, "border-bottom", "border-bottom"], [fons, "margin", "margin"], [fons, "margin-left", "margin-left"], + [fons, "margin-right", "margin-right"], [fons, "margin-top", "margin-top"], [fons, "margin-bottom", "margin-bottom"], [fons, "border", "border"]], graphicPropertySimpleMapping = [[fons, "background-color", "background-color"], [fons, "min-height", "min-height"], [drawns, "stroke", "border"], [svgns, "stroke-color", "border-color"], [svgns, "stroke-width", "border-width"], [fons, "border", "border"], [fons, "border-left", "border-left"], [fons, "border-right", "border-right"], [fons, "border-top", + "border-top"], [fons, "border-bottom", "border-bottom"]], tablecellPropertySimpleMapping = [[fons, "background-color", "background-color"], [fons, "border-left", "border-left"], [fons, "border-right", "border-right"], [fons, "border-top", "border-top"], [fons, "border-bottom", "border-bottom"], [fons, "border", "border"]], tablecolumnPropertySimpleMapping = [[stylens, "column-width", "width"]], tablerowPropertySimpleMapping = [[stylens, "row-height", "height"], [fons, "keep-together", null]], tablePropertySimpleMapping = + [[stylens, "width", "width"], [fons, "margin-left", "margin-left"], [fons, "margin-right", "margin-right"], [fons, "margin-top", "margin-top"], [fons, "margin-bottom", "margin-bottom"]], pageContentPropertySimpleMapping = [[fons, "background-color", "background-color"], [fons, "padding", "padding"], [fons, "padding-left", "padding-left"], [fons, "padding-right", "padding-right"], [fons, "padding-top", "padding-top"], [fons, "padding-bottom", "padding-bottom"], [fons, "border", "border"], [fons, + "border-left", "border-left"], [fons, "border-right", "border-right"], [fons, "border-top", "border-top"], [fons, "border-bottom", "border-bottom"], [fons, "margin", "margin"], [fons, "margin-left", "margin-left"], [fons, "margin-right", "margin-right"], [fons, "margin-top", "margin-top"], [fons, "margin-bottom", "margin-bottom"]], pageSizePropertySimpleMapping = [[fons, "page-width", "width"], [fons, "page-height", "height"]], borderPropertyMap = {"border":true, "border-left":true, "border-right":true, + "border-top":true, "border-bottom":true, "stroke-width":true}, fontFaceDeclsMap = {}, utils = new odf.OdfUtils, documentType, odfRoot, defaultFontSize, xpath = xmldom.XPath, cssUnits = new core.CSSUnits; + function getStyleMap(stylesnode) { + var node, name, family, style, stylemap = {}; + if(!stylesnode) { + return stylemap + } + node = stylesnode.firstElementChild; + while(node) { + if(node.namespaceURI === stylens && (node.localName === "style" || node.localName === "default-style")) { + family = node.getAttributeNS(stylens, "family") + }else { + if(node.namespaceURI === textns && node.localName === "list-style") { + family = "list" + }else { + if(node.namespaceURI === stylens && (node.localName === "page-layout" || node.localName === "default-page-layout")) { + family = "page" + }else { + family = undefined + } + } + } + if(family) { + name = node.getAttributeNS(stylens, "name"); + if(!name) { + name = "" + } + if(stylemap.hasOwnProperty(family)) { + style = stylemap[family] + }else { + stylemap[family] = style = {} + } + style[name] = node + } + node = node.nextElementSibling + } + return stylemap + } + function findStyle(stylestree, name) { + if(stylestree.hasOwnProperty(name)) { + return stylestree[name] + } + var n, style = null; + for(n in stylestree) { + if(stylestree.hasOwnProperty(n)) { + style = findStyle(stylestree[n].derivedStyles, name); + if(style) { + break + } + } + } + return style + } + function addStyleToStyleTree(stylename, stylesmap, stylestree) { + var style, parentname, parentstyle; + if(!stylesmap.hasOwnProperty(stylename)) { + return null + } + style = new odf.StyleTreeNode(stylesmap[stylename]); + parentname = style.element.getAttributeNS(stylens, "parent-style-name"); + parentstyle = null; + if(parentname) { + parentstyle = findStyle(stylestree, parentname) || addStyleToStyleTree(parentname, stylesmap, stylestree) + } + if(parentstyle) { + parentstyle.derivedStyles[stylename] = style + }else { + stylestree[stylename] = style + } + delete stylesmap[stylename]; + return style + } + function addStyleMapToStyleTree(stylesmap, stylestree) { + var name; + for(name in stylesmap) { + if(stylesmap.hasOwnProperty(name)) { + addStyleToStyleTree(name, stylesmap, stylestree) + } + } + } + function createSelector(family, name) { + var prefix = familynamespaceprefixes[family], namepart, selector; + if(prefix === undefined) { + return null + } + if(name) { + namepart = "[" + prefix + '|style-name="' + name + '"]' + }else { + namepart = "" + } + if(prefix === "presentation") { + prefix = "draw"; + if(name) { + namepart = '[presentation|style-name="' + name + '"]' + }else { + namepart = "" + } + } + selector = prefix + "|" + familytagnames[family].join(namepart + "," + prefix + "|") + namepart; + return selector + } + function getSelectors(family, name, node) { + var selectors = [], ss, derivedStyles = node.derivedStyles, n; + ss = createSelector(family, name); + if(ss !== null) { + selectors.push(ss) + } + for(n in derivedStyles) { + if(derivedStyles.hasOwnProperty(n)) { + ss = getSelectors(family, n, derivedStyles[n]); + selectors = selectors.concat(ss) + } + } + return selectors + } + function getDirectChild(node, ns, name) { + var e = node && node.firstElementChild; + while(e) { + if(e.namespaceURI === ns && e.localName === name) { + break + } + e = e.nextElementSibling + } + return e + } + function fixBorderWidth(value) { + var index = value.indexOf(" "), width, theRestOfBorderAttributes; + if(index !== -1) { + width = value.substring(0, index); + theRestOfBorderAttributes = value.substring(index) + }else { + width = value; + theRestOfBorderAttributes = "" + } + width = utils.parseLength(width); + if(width && (width.unit === "pt" && width.value < 0.75)) { + value = "0.75pt" + theRestOfBorderAttributes + } + return value + } + function applySimpleMapping(props, mapping) { + var rule = "", i, r, value; + for(i = 0;i < mapping.length;i += 1) { + r = mapping[i]; + value = props.getAttributeNS(r[0], r[1]); + if(value) { + value = value.trim(); + if(borderPropertyMap.hasOwnProperty(r[1])) { + value = fixBorderWidth(value) + } + if(r[2]) { + rule += r[2] + ":" + value + ";" + } + } + } + return rule + } + function getFontSize(styleNode) { + var props = getDirectChild(styleNode, stylens, "text-properties"); + if(props) { + return utils.parseFoFontSize(props.getAttributeNS(fons, "font-size")) + } + return null + } + function getParentStyleNode(styleNode) { + var parentStyleName = "", parentStyleFamily = "", parentStyleNode = null, xp; + if(styleNode.localName === "default-style") { + return null + } + parentStyleName = styleNode.getAttributeNS(stylens, "parent-style-name"); + parentStyleFamily = styleNode.getAttributeNS(stylens, "family"); + if(parentStyleName) { + xp = "//style:*[@style:name='" + parentStyleName + "'][@style:family='" + parentStyleFamily + "']" + }else { + xp = "//style:default-style[@style:family='" + parentStyleFamily + "']" + } + parentStyleNode = xpath.getODFElementsWithXPath((odfRoot), xp, odf.Namespaces.lookupNamespaceURI)[0]; + return parentStyleNode + } + function getTextProperties(props) { + var rule = "", fontName, fontSize, value, textDecoration = "", fontSizeRule = "", sizeMultiplier = 1, parentStyle; + rule += applySimpleMapping(props, textPropertySimpleMapping); + value = props.getAttributeNS(stylens, "text-underline-style"); + if(value === "solid") { + textDecoration += " underline" + } + value = props.getAttributeNS(stylens, "text-line-through-style"); + if(value === "solid") { + textDecoration += " line-through" + } + if(textDecoration.length) { + textDecoration = "text-decoration:" + textDecoration + ";"; + rule += textDecoration + } + fontName = props.getAttributeNS(stylens, "font-name") || props.getAttributeNS(fons, "font-family"); + if(fontName) { + value = fontFaceDeclsMap[fontName]; + rule += "font-family: " + (value || fontName) + ";" + } + parentStyle = (props.parentNode); + fontSize = getFontSize(parentStyle); + if(!fontSize) { + return rule + } + while(parentStyle) { + fontSize = getFontSize(parentStyle); + if(fontSize) { + if(fontSize.unit !== "%") { + fontSizeRule = "font-size: " + fontSize.value * sizeMultiplier + fontSize.unit + ";"; + break + } + sizeMultiplier *= fontSize.value / 100 + } + parentStyle = getParentStyleNode(parentStyle) + } + if(!fontSizeRule) { + fontSizeRule = "font-size: " + parseFloat(defaultFontSize) * sizeMultiplier + cssUnits.getUnits(defaultFontSize) + ";" + } + rule += fontSizeRule; + return rule + } + function getParagraphProperties(props) { + var rule = "", bgimage, url, lineHeight; + rule += applySimpleMapping(props, paragraphPropertySimpleMapping); + bgimage = getDirectChild(props, stylens, "background-image"); + if(bgimage) { + url = bgimage.getAttributeNS(xlinkns, "href"); + if(url) { + rule += "background-image: url('odfkit:" + url + "');"; + rule += applySimpleMapping(bgimage, bgImageSimpleMapping) + } + } + lineHeight = props.getAttributeNS(fons, "line-height"); + if(lineHeight && lineHeight !== "normal") { + lineHeight = utils.parseFoLineHeight(lineHeight); + if(lineHeight.unit !== "%") { + rule += "line-height: " + lineHeight.value + lineHeight.unit + ";" + }else { + rule += "line-height: " + lineHeight.value / 100 + ";" + } + } + return rule + } + function matchToRgb(m, r, g, b) { + return r + r + g + g + b + b + } + function hexToRgb(hex) { + var result, shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; + hex = hex.replace(shorthandRegex, matchToRgb); + result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? {r:parseInt(result[1], 16), g:parseInt(result[2], 16), b:parseInt(result[3], 16)} : null + } + function isNumber(n) { + return!isNaN(parseFloat(n)) + } + function getGraphicProperties(props) { + var rule = "", alpha, bgcolor, fill; + rule += applySimpleMapping(props, graphicPropertySimpleMapping); + alpha = props.getAttributeNS(drawns, "opacity"); + fill = props.getAttributeNS(drawns, "fill"); + bgcolor = props.getAttributeNS(drawns, "fill-color"); + if(fill === "solid" || fill === "hatch") { + if(bgcolor && bgcolor !== "none") { + alpha = isNumber(alpha) ? parseFloat(alpha) / 100 : 1; + bgcolor = hexToRgb(bgcolor); + if(bgcolor) { + rule += "background-color: rgba(" + bgcolor.r + "," + bgcolor.g + "," + bgcolor.b + "," + alpha + ");" + } + }else { + rule += "background: none;" + } + }else { + if(fill === "none") { + rule += "background: none;" + } + } + return rule + } + function getDrawingPageProperties(props) { + var rule = ""; + rule += applySimpleMapping(props, graphicPropertySimpleMapping); + if(props.getAttributeNS(presentationns, "background-visible") === "true") { + rule += "background: none;" + } + return rule + } + function getTableCellProperties(props) { + var rule = ""; + rule += applySimpleMapping(props, tablecellPropertySimpleMapping); + return rule + } + function getTableRowProperties(props) { + var rule = ""; + rule += applySimpleMapping(props, tablerowPropertySimpleMapping); + return rule + } + function getTableColumnProperties(props) { + var rule = ""; + rule += applySimpleMapping(props, tablecolumnPropertySimpleMapping); + return rule + } + function getTableProperties(props) { + var rule = "", borderModel; + rule += applySimpleMapping(props, tablePropertySimpleMapping); + borderModel = props.getAttributeNS(tablens, "border-model"); + if(borderModel === "collapsing") { + rule += "border-collapse:collapse;" + }else { + if(borderModel === "separating") { + rule += "border-collapse:separate;" + } + } + return rule + } + function addStyleRule(sheet, family, name, node) { + var selectors = getSelectors(family, name, node), selector = selectors.join(","), rule = "", properties; + properties = getDirectChild(node.element, stylens, "text-properties"); + if(properties) { + rule += getTextProperties(properties) + } + properties = getDirectChild(node.element, stylens, "paragraph-properties"); + if(properties) { + rule += getParagraphProperties(properties) + } + properties = getDirectChild(node.element, stylens, "graphic-properties"); + if(properties) { + rule += getGraphicProperties(properties) + } + properties = getDirectChild(node.element, stylens, "drawing-page-properties"); + if(properties) { + rule += getDrawingPageProperties(properties) + } + properties = getDirectChild(node.element, stylens, "table-cell-properties"); + if(properties) { + rule += getTableCellProperties(properties) + } + properties = getDirectChild(node.element, stylens, "table-row-properties"); + if(properties) { + rule += getTableRowProperties(properties) + } + properties = getDirectChild(node.element, stylens, "table-column-properties"); + if(properties) { + rule += getTableColumnProperties(properties) + } + properties = getDirectChild(node.element, stylens, "table-properties"); + if(properties) { + rule += getTableProperties(properties) + } + if(rule.length === 0) { + return + } + rule = selector + "{" + rule + "}"; + try { + sheet.insertRule(rule, sheet.cssRules.length) + }catch(e) { + throw e; + } + } + function getNumberRule(node) { + var style = node.getAttributeNS(stylens, "num-format"), suffix = node.getAttributeNS(stylens, "num-suffix") || "", prefix = node.getAttributeNS(stylens, "num-prefix") || "", stylemap = {1:"decimal", "a":"lower-latin", "A":"upper-latin", "i":"lower-roman", "I":"upper-roman"}, content = ""; + if(prefix) { + content += ' "' + prefix + '"' + } + if(stylemap.hasOwnProperty(style)) { + content += " counter(list, " + stylemap[style] + ")" + }else { + if(style) { + content += ' "' + style + '"' + }else { + content += " ''" + } + } + return"content:" + content + ' "' + suffix + '"' + } + function getImageRule() { + return"content: none;" + } + function getBulletRule(node) { + var bulletChar = node.getAttributeNS(textns, "bullet-char"); + return"content: '" + bulletChar + "';" + } + function addListStyleRule(sheet, name, node, itemrule) { + var selector = 'text|list[text|style-name="' + name + '"]', level = node.getAttributeNS(textns, "level"), itemSelector, listItemRule, listLevelProps = getDirectChild(node, stylens, "list-level-properties"), listLevelLabelAlign = getDirectChild(listLevelProps, stylens, "list-level-label-alignment"), bulletIndent, listIndent, bulletWidth, rule; + if(listLevelLabelAlign) { + bulletIndent = listLevelLabelAlign.getAttributeNS(fons, "text-indent"); + listIndent = listLevelLabelAlign.getAttributeNS(fons, "margin-left") + } + if(!bulletIndent) { + bulletIndent = "-0.6cm" + } + if(bulletIndent.charAt(0) === "-") { + bulletWidth = bulletIndent.substring(1) + }else { + bulletWidth = "-" + bulletIndent + } + level = level && parseInt(level, 10); + while(level > 1) { + selector += " > text|list-item > text|list"; + level -= 1 + } + if(listIndent) { + itemSelector = selector; + itemSelector += " > text|list-item > *:not(text|list):first-child"; + listItemRule = itemSelector + "{"; + listItemRule += "margin-left:" + listIndent + ";"; + listItemRule += "}"; + try { + sheet.insertRule(listItemRule, sheet.cssRules.length) + }catch(e1) { + runtime.log("cannot load rule: " + listItemRule) + } + } + selector += " > text|list-item > *:not(text|list):first-child:before"; + rule = selector + "{" + itemrule + ";"; + rule += "counter-increment:list;"; + rule += "margin-left:" + bulletIndent + ";"; + rule += "width:" + bulletWidth + ";"; + rule += "display:inline-block}"; + try { + sheet.insertRule(rule, sheet.cssRules.length) + }catch(e2) { + runtime.log("cannot load rule: " + rule) + } + } + function addPageStyleRules(sheet, node) { + var rule = "", imageProps, url, contentLayoutRule = "", pageSizeRule = "", props = getDirectChild(node, stylens, "page-layout-properties"), stylename, masterStyles, e, masterStyleName; + if(!props) { + return + } + stylename = node.getAttributeNS(stylens, "name"); + rule += applySimpleMapping(props, pageContentPropertySimpleMapping); + imageProps = getDirectChild(props, stylens, "background-image"); + if(imageProps) { + url = imageProps.getAttributeNS(xlinkns, "href"); + if(url) { + rule += "background-image: url('odfkit:" + url + "');"; + rule += applySimpleMapping(imageProps, bgImageSimpleMapping) + } + } + if(documentType === "presentation") { + masterStyles = getDirectChild((node.parentNode.parentNode), officens, "master-styles"); + e = masterStyles && masterStyles.firstElementChild; + while(e) { + if(e.namespaceURI === stylens && (e.localName === "master-page" && e.getAttributeNS(stylens, "page-layout-name") === stylename)) { + masterStyleName = e.getAttributeNS(stylens, "name"); + contentLayoutRule = "draw|page[draw|master-page-name=" + masterStyleName + "] {" + rule + "}"; + pageSizeRule = "office|body, draw|page[draw|master-page-name=" + masterStyleName + "] {" + applySimpleMapping(props, pageSizePropertySimpleMapping) + " }"; + try { + sheet.insertRule(contentLayoutRule, sheet.cssRules.length); + sheet.insertRule(pageSizeRule, sheet.cssRules.length) + }catch(e1) { + throw e1; + } + } + e = e.nextElementSibling + } + }else { + if(documentType === "text") { + contentLayoutRule = "office|text {" + rule + "}"; + rule = ""; + pageSizeRule = "office|body {" + "width: " + props.getAttributeNS(fons, "page-width") + ";" + "}"; + try { + sheet.insertRule(contentLayoutRule, sheet.cssRules.length); + sheet.insertRule(pageSizeRule, sheet.cssRules.length) + }catch(e2) { + throw e2; + } + } + } + } + function addListStyleRules(sheet, name, node) { + var n = node.firstChild, e, itemrule; + while(n) { + if(n.namespaceURI === textns) { + e = (n); + if(n.localName === "list-level-style-number") { + itemrule = getNumberRule(e); + addListStyleRule(sheet, name, e, itemrule) + }else { + if(n.localName === "list-level-style-image") { + itemrule = getImageRule(); + addListStyleRule(sheet, name, e, itemrule) + }else { + if(n.localName === "list-level-style-bullet") { + itemrule = getBulletRule(e); + addListStyleRule(sheet, name, e, itemrule) + } + } + } + } + n = n.nextSibling + } + } + function addRule(sheet, family, name, node) { + if(family === "list") { + addListStyleRules(sheet, name, node.element) + }else { + if(family === "page") { + addPageStyleRules(sheet, node.element) + }else { + addStyleRule(sheet, family, name, node) + } + } + } + function addRules(sheet, family, name, node) { + addRule(sheet, family, name, node); + var n; + for(n in node.derivedStyles) { + if(node.derivedStyles.hasOwnProperty(n)) { + addRules(sheet, family, n, node.derivedStyles[n]) + } + } + } + this.style2css = function(doctype, stylesheet, fontFaceMap, styles, autostyles) { + var doc, styletree, tree, rule, name, family, stylenodes, styleautonodes; + while(stylesheet.cssRules.length) { + stylesheet.deleteRule(stylesheet.cssRules.length - 1) + } + doc = null; + if(styles) { + doc = styles.ownerDocument; + odfRoot = styles.parentNode + } + if(autostyles) { + doc = autostyles.ownerDocument; + odfRoot = autostyles.parentNode + } + if(!doc) { + return + } + odf.Namespaces.forEachPrefix(function(prefix, ns) { + rule = "@namespace " + prefix + " url(" + ns + ");"; + try { + stylesheet.insertRule(rule, stylesheet.cssRules.length) + }catch(ignore) { + } + }); + fontFaceDeclsMap = fontFaceMap; + documentType = doctype; + defaultFontSize = runtime.getWindow().getComputedStyle(document.body, null).getPropertyValue("font-size") || "12pt"; + stylenodes = getStyleMap(styles); + styleautonodes = getStyleMap(autostyles); + styletree = {}; + for(family in familynamespaceprefixes) { + if(familynamespaceprefixes.hasOwnProperty(family)) { + tree = styletree[family] = {}; + addStyleMapToStyleTree(stylenodes[family], tree); + addStyleMapToStyleTree(styleautonodes[family], tree); + for(name in tree) { + if(tree.hasOwnProperty(name)) { + addRules(stylesheet, family, name, tree[name]) + } + } + } + } + } +}; +/* + + Copyright (C) 2012-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/ +*/ +ops.Canvas = function Canvas() { +}; +ops.Canvas.prototype.getZoomLevel = function() { +}; +ops.Canvas.prototype.getElement = function() { +}; +/* + + Copyright (C) 2012-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() { function LoadingQueue() { var queue = [], taskRunning = false; @@ -8084,6 +7808,12 @@ runtime.loadClass("gui.AnnotationViewManager"); element.removeChild(element.firstChild) } } + function clearCSSStyleSheet(style) { + var stylesheet = (style.sheet), cssRules = stylesheet.cssRules; + while(cssRules.length) { + stylesheet.deleteRule(cssRules.length - 1) + } + } function handleStyles(odfcontainer, formatting, stylesxmlcss) { var style2css = new odf.Style2CSS; style2css.style2css(odfcontainer.getDocumentType(), (stylesxmlcss.sheet), formatting.getFontMap(), odfcontainer.rootElement.styles, odfcontainer.rootElement.automaticStyles) @@ -8096,20 +7826,21 @@ runtime.loadClass("gui.AnnotationViewManager"); if(!masterPageName) { return null } - var masterStyles = odfContainer.rootElement.masterStyles, masterPageElement = masterStyles.firstElementChild; - while(masterPageElement) { - if(masterPageElement.getAttributeNS(stylens, "name") === masterPageName && (masterPageElement.localName === "master-page" && masterPageElement.namespaceURI === stylens)) { + var masterStyles = odfContainer.rootElement.masterStyles, masterStylesChild = masterStyles.firstElementChild; + while(masterStylesChild) { + if(masterStylesChild.getAttributeNS(stylens, "name") === masterPageName && (masterStylesChild.localName === "master-page" && masterStylesChild.namespaceURI === stylens)) { break } + masterStylesChild = masterStylesChild.nextElementSibling } - return masterPageElement + return masterStylesChild } function dropTemplateDrawFrames(clonedNode) { var i, element, presentationClass, clonedDrawFrameElements = clonedNode.getElementsByTagNameNS(drawns, "frame"); for(i = 0;i < clonedDrawFrameElements.length;i += 1) { element = (clonedDrawFrameElements[i]); presentationClass = element.getAttributeNS(presentationns, "class"); - if(presentationClass && !/^(date-time|footer|header|page-number')$/.test(presentationClass)) { + if(presentationClass && !/^(date-time|footer|header|page-number)$/.test(presentationClass)) { element.parentNode.removeChild(element) } } @@ -8237,39 +7968,6 @@ runtime.loadClass("gui.AnnotationViewManager"); modifyTableCell(node) } } - function modifyLinks(odffragment) { - var i, links, node; - function modifyLink(node) { - var url, clickHandler; - if(!node.hasAttributeNS(xlinkns, "href")) { - return - } - url = node.getAttributeNS(xlinkns, "href"); - if(url[0] === "#") { - url = url.substring(1); - clickHandler = function() { - var bookmarks = xpath.getODFElementsWithXPath(odffragment, "//text:bookmark-start[@text:name='" + url + "']", odf.Namespaces.lookupNamespaceURI); - if(bookmarks.length === 0) { - bookmarks = xpath.getODFElementsWithXPath(odffragment, "//text:bookmark[@text:name='" + url + "']", odf.Namespaces.lookupNamespaceURI) - } - if(bookmarks.length > 0) { - bookmarks[0].scrollIntoView(true) - } - return false - } - }else { - clickHandler = function() { - window.open(url) - } - } - node.onclick = clickHandler - } - links = odffragment.getElementsByTagNameNS(textns, "a"); - for(i = 0;i < links.length;i += 1) { - node = (links.item(i)); - modifyLink(node) - } - } function modifyLineBreakElements(odffragment) { var document = odffragment.ownerDocument, lineBreakElements = domUtils.getElementsByTagNameNS(odffragment, textns, "line-break"); lineBreakElements.forEach(function(lineBreak) { @@ -8315,7 +8013,7 @@ runtime.loadClass("gui.AnnotationViewManager"); node = node.firstElementChild }else { while(node && (node !== odfbody && !node.nextElementSibling)) { - node = node.parentElement + node = (node.parentNode) } if(node && node.nextElementSibling) { node = node.nextElementSibling @@ -8497,24 +8195,49 @@ runtime.loadClass("gui.AnnotationViewManager"); } } } + function findWebODFStyleSheet(head) { + var style = head.firstElementChild; + while(style && !(style.localName === "style" && style.hasAttribute("webodfcss"))) { + style = style.nextElementSibling + } + return(style) + } function addWebODFStyleSheet(document) { - var head = (document.getElementsByTagName("head")[0]), style, href; - if(String(typeof webodf_css) !== "undefined") { - style = document.createElementNS(head.namespaceURI, "style"); - style.setAttribute("media", "screen, print, handheld, projection"); - style.appendChild(document.createTextNode(webodf_css)) + var head = (document.getElementsByTagName("head")[0]), css, style, href, count = document.styleSheets.length; + style = findWebODFStyleSheet(head); + if(style) { + count = parseInt(style.getAttribute("webodfcss"), 10); + style.setAttribute("webodfcss", count + 1); + return style + } + if(String(typeof webodf_css) === "string") { + css = (webodf_css) }else { - style = document.createElementNS(head.namespaceURI, "link"); href = "webodf.css"; if(runtime.currentDirectory) { - href = runtime.currentDirectory() + "/../" + href + href = runtime.currentDirectory(); + if(href.length > 0 && href.substr(-1) !== "/") { + href += "/" + } + href += "../webodf.css" } - style.setAttribute("href", href); - style.setAttribute("rel", "stylesheet") + css = (runtime.readFileSync(href, "utf-8")) } + style = (document.createElementNS(head.namespaceURI, "style")); + style.setAttribute("media", "screen, print, handheld, projection"); style.setAttribute("type", "text/css"); + style.setAttribute("webodfcss", "1"); + style.appendChild(document.createTextNode(css)); head.appendChild(style); - return(style) + return style + } + function removeWebODFStyleSheet(webodfcss) { + var count = parseInt(webodfcss.getAttribute("webodfcss"), 10); + if(count === 1) { + webodfcss.parentNode.removeChild(webodfcss) + }else { + webodfcss.setAttribute("count", count - 1) + } } function addStyleSheet(document) { var head = (document.getElementsByTagName("head")[0]), style = document.createElementNS(head.namespaceURI, "style"), text = ""; @@ -8531,7 +8254,8 @@ runtime.loadClass("gui.AnnotationViewManager"); odf.OdfCanvas = function OdfCanvas(element) { runtime.assert(element !== null && element !== undefined, "odf.OdfCanvas constructor needs DOM element"); runtime.assert(element.ownerDocument !== null && element.ownerDocument !== undefined, "odf.OdfCanvas constructor needs DOM"); - var self = this, doc = (element.ownerDocument), odfcontainer, formatting = new odf.Formatting, pageSwitcher, sizer = null, annotationsPane = null, allowAnnotations = false, annotationViewManager = null, webodfcss, fontcss, stylesxmlcss, positioncss, shadowContent, zoomLevel = 1, eventHandlers = {}, loadingQueue = new LoadingQueue; + var self = this, doc = (element.ownerDocument), async = new core.Async, odfcontainer, formatting = new odf.Formatting, pageSwitcher, sizer = null, annotationsPane = null, allowAnnotations = false, showAnnotationRemoveButton = false, annotationViewManager = null, webodfcss, fontcss, stylesxmlcss, positioncss, shadowContent, eventHandlers = {}, waitingForDoneTimeoutId, redrawContainerTask, shouldRefreshCss = false, shouldRerenderAnnotations = false, loadingQueue = new LoadingQueue, zoomHelper = + new gui.ZoomHelper; function loadImages(container, odffragment, stylesheet) { var i, images, node; function loadImage(name, container, node, stylesheet) { @@ -8579,34 +8303,46 @@ runtime.loadClass("gui.AnnotationViewManager"); } } function fixContainerSize() { - var odfdoc = sizer.firstChild; + var minHeight, odfdoc = sizer.firstChild, zoomLevel = zoomHelper.getZoomLevel(); if(!odfdoc) { return } - if(zoomLevel > 1) { - sizer.style.MozTransformOrigin = "center top"; - sizer.style.WebkitTransformOrigin = "center top"; - sizer.style.OTransformOrigin = "center top"; - sizer.style.msTransformOrigin = "center top" - }else { - sizer.style.MozTransformOrigin = "left top"; - sizer.style.WebkitTransformOrigin = "left top"; - sizer.style.OTransformOrigin = "left top"; - sizer.style.msTransformOrigin = "left top" - } - sizer.style.WebkitTransform = "scale(" + zoomLevel + ")"; - sizer.style.MozTransform = "scale(" + zoomLevel + ")"; - sizer.style.OTransform = "scale(" + zoomLevel + ")"; - sizer.style.msTransform = "scale(" + zoomLevel + ")"; + sizer.style.WebkitTransformOrigin = "0% 0%"; + sizer.style.MozTransformOrigin = "0% 0%"; + sizer.style.msTransformOrigin = "0% 0%"; + sizer.style.OTransformOrigin = "0% 0%"; + sizer.style.transformOrigin = "0% 0%"; + if(annotationViewManager) { + minHeight = annotationViewManager.getMinimumHeightForAnnotationPane(); + if(minHeight) { + sizer.style.minHeight = minHeight + }else { + sizer.style.removeProperty("min-height") + } + } element.style.width = Math.round(zoomLevel * sizer.offsetWidth) + "px"; element.style.height = Math.round(zoomLevel * sizer.offsetHeight) + "px" } + function redrawContainer() { + if(shouldRefreshCss) { + handleStyles(odfcontainer, formatting, stylesxmlcss); + shouldRefreshCss = false + } + if(shouldRerenderAnnotations) { + if(annotationViewManager) { + annotationViewManager.rerenderAnnotations() + } + shouldRerenderAnnotations = false + } + fixContainerSize() + } function handleContent(container, odfnode) { var css = (positioncss.sheet); clear(element); sizer = (doc.createElementNS(element.namespaceURI, "div")); sizer.style.display = "inline-block"; sizer.style.background = "white"; + sizer.style.setProperty("float", "left", "important"); sizer.appendChild(odfnode); element.appendChild(sizer); annotationsPane = (doc.createElementNS(element.namespaceURI, "div")); @@ -8620,7 +8356,6 @@ runtime.loadClass("gui.AnnotationViewManager"); modifyDrawElements(odfnode.body, css); cloneMasterPages(container, shadowContent, odfnode.body, css); modifyTables(odfnode.body, element.namespaceURI); - modifyLinks(odfnode.body); modifyLineBreakElements(odfnode.body); expandSpaceElements(odfnode.body); expandTabElements(odfnode.body); @@ -8628,30 +8363,24 @@ runtime.loadClass("gui.AnnotationViewManager"); loadVideos(container, odfnode.body); loadLists(odfnode.body, css, element.namespaceURI); sizer.insertBefore(shadowContent, sizer.firstChild); - fixContainerSize() + zoomHelper.setZoomableElement(sizer) } function modifyAnnotations(odffragment) { - var annotationNodes = domUtils.getElementsByTagNameNS(odffragment, officens, "annotation"), annotationEnds = domUtils.getElementsByTagNameNS(odffragment, officens, "annotation-end"), currentAnnotationName, i; - function matchAnnotationEnd(element) { - return currentAnnotationName === element.getAttributeNS(officens, "name") - } - for(i = 0;i < annotationNodes.length;i += 1) { - currentAnnotationName = annotationNodes[i].getAttributeNS(officens, "name"); - annotationViewManager.addAnnotation({node:annotationNodes[i], end:annotationEnds.filter(matchAnnotationEnd)[0] || null}) - } + var annotationNodes = (domUtils.getElementsByTagNameNS(odffragment, officens, "annotation")); + annotationNodes.forEach(annotationViewManager.addAnnotation); annotationViewManager.rerenderAnnotations() } function handleAnnotations(odfnode) { if(allowAnnotations) { if(!annotationsPane.parentNode) { - sizer.appendChild(annotationsPane); - fixContainerSize() + sizer.appendChild(annotationsPane) } if(annotationViewManager) { annotationViewManager.forgetAnnotations() } - annotationViewManager = new gui.AnnotationViewManager(self, odfnode.body, annotationsPane); - modifyAnnotations(odfnode.body) + annotationViewManager = new gui.AnnotationViewManager(self, odfnode.body, annotationsPane, showAnnotationRemoveButton); + modifyAnnotations(odfnode.body); + fixContainerSize() }else { if(annotationsPane.parentNode) { sizer.removeChild(annotationsPane); @@ -8662,6 +8391,9 @@ runtime.loadClass("gui.AnnotationViewManager"); } function refreshOdf(suppressEvent) { function callback() { + clearCSSStyleSheet(fontcss); + clearCSSStyleSheet(stylesxmlcss); + clearCSSStyleSheet(positioncss); clear(element); element.style.display = "inline-block"; var odfnode = odfcontainer.rootElement; @@ -8679,22 +8411,22 @@ runtime.loadClass("gui.AnnotationViewManager"); callback() }else { runtime.log("WARNING: refreshOdf called but ODF was not DONE."); - runtime.setTimeout(function later_cb() { + waitingForDoneTimeoutId = runtime.setTimeout(function later_cb() { if(odfcontainer.state === odf.OdfContainer.DONE) { callback() }else { runtime.log("will be back later..."); - runtime.setTimeout(later_cb, 500) + waitingForDoneTimeoutId = runtime.setTimeout(later_cb, 500) } }, 100) } } this.refreshCSS = function() { - handleStyles(odfcontainer, formatting, stylesxmlcss); - fixContainerSize() + shouldRefreshCss = true; + redrawContainerTask.trigger() }; this.refreshSize = function() { - fixContainerSize() + redrawContainerTask.trigger() }; this.odfContainer = function() { return odfcontainer @@ -8738,15 +8470,17 @@ runtime.loadClass("gui.AnnotationViewManager"); }; this.rerenderAnnotations = function() { if(annotationViewManager) { - annotationViewManager.rerenderAnnotations() + shouldRerenderAnnotations = true; + redrawContainerTask.trigger() } }; this.getSizer = function() { - return sizer + return(sizer) }; - this.enableAnnotations = function(allow) { + this.enableAnnotations = function(allow, showRemoveButton) { if(allow !== allowAnnotations) { allowAnnotations = allow; + showAnnotationRemoveButton = showRemoveButton; if(odfcontainer) { handleAnnotations(odfcontainer.rootElement) } @@ -8754,36 +8488,39 @@ runtime.loadClass("gui.AnnotationViewManager"); }; this.addAnnotation = function(annotation) { if(annotationViewManager) { - annotationViewManager.addAnnotation(annotation) + annotationViewManager.addAnnotation(annotation); + fixContainerSize() } }; this.forgetAnnotations = function() { if(annotationViewManager) { - annotationViewManager.forgetAnnotations() + annotationViewManager.forgetAnnotations(); + fixContainerSize() } }; + this.getZoomHelper = function() { + return zoomHelper + }; this.setZoomLevel = function(zoom) { - zoomLevel = zoom; - fixContainerSize() + zoomHelper.setZoomLevel(zoom) }; this.getZoomLevel = function() { - return zoomLevel + return zoomHelper.getZoomLevel() }; this.fitToContainingElement = function(width, height) { - var realWidth = element.offsetWidth / zoomLevel, realHeight = element.offsetHeight / zoomLevel; - zoomLevel = width / realWidth; - if(height / realHeight < zoomLevel) { - zoomLevel = height / realHeight + var zoomLevel = zoomHelper.getZoomLevel(), realWidth = element.offsetWidth / zoomLevel, realHeight = element.offsetHeight / zoomLevel, zoom; + zoom = width / realWidth; + if(height / realHeight < zoom) { + zoom = height / realHeight } - fixContainerSize() + zoomHelper.setZoomLevel(zoom) }; this.fitToWidth = function(width) { - var realWidth = element.offsetWidth / zoomLevel; - zoomLevel = width / realWidth; - fixContainerSize() + var realWidth = element.offsetWidth / zoomHelper.getZoomLevel(); + zoomHelper.setZoomLevel(width / realWidth) }; this.fitSmart = function(width, height) { - var realWidth, realHeight, newScale; + var realWidth, realHeight, newScale, zoomLevel = zoomHelper.getZoomLevel(); realWidth = element.offsetWidth / zoomLevel; realHeight = element.offsetHeight / zoomLevel; newScale = width / realWidth; @@ -8792,13 +8529,11 @@ runtime.loadClass("gui.AnnotationViewManager"); newScale = height / realHeight } } - zoomLevel = Math.min(1, newScale); - fixContainerSize() + zoomHelper.setZoomLevel(Math.min(1, newScale)) }; this.fitToHeight = function(height) { - var realHeight = element.offsetHeight / zoomLevel; - zoomLevel = height / realHeight; - fixContainerSize() + var realHeight = element.offsetHeight / zoomHelper.getZoomLevel(); + zoomHelper.setZoomLevel(height / realHeight) }; this.showFirstPage = function() { pageSwitcher.showFirstPage() @@ -8824,32 +8559,105 @@ runtime.loadClass("gui.AnnotationViewManager"); } }; this.destroy = function(callback) { - var head = (doc.getElementsByTagName("head")[0]); + var head = (doc.getElementsByTagName("head")[0]), cleanup = [pageSwitcher.destroy, redrawContainerTask.destroy]; + runtime.clearTimeout(waitingForDoneTimeoutId); if(annotationsPane && annotationsPane.parentNode) { annotationsPane.parentNode.removeChild(annotationsPane) } - if(sizer) { - element.removeChild(sizer); - sizer = null - } - head.removeChild(webodfcss); + zoomHelper.destroy(function() { + if(sizer) { + element.removeChild(sizer); + sizer = null + } + }); + removeWebODFStyleSheet(webodfcss); head.removeChild(fontcss); head.removeChild(stylesxmlcss); head.removeChild(positioncss); - pageSwitcher.destroy(callback) + async.destroyAll(cleanup, callback) }; function init() { webodfcss = addWebODFStyleSheet(doc); pageSwitcher = new PageSwitcher(addStyleSheet(doc)); fontcss = addStyleSheet(doc); stylesxmlcss = addStyleSheet(doc); - positioncss = addStyleSheet(doc) + positioncss = addStyleSheet(doc); + redrawContainerTask = new core.ScheduledTask(redrawContainer, 0); + zoomHelper.subscribe(gui.ZoomHelper.signalZoomChanged, fixContainerSize) } init() } })(); /* + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +ops.MemberProperties = function() { + this.fullName; + this.color; + this.imageUrl +}; +ops.Member = function Member(memberId, properties) { + var props = new ops.MemberProperties; + function getMemberId() { + return memberId + } + function getProperties() { + return props + } + function setProperties(newProperties) { + Object.keys(newProperties).forEach(function(key) { + props[key] = newProperties[key] + }) + } + function removeProperties(removedProperties) { + Object.keys(removedProperties).forEach(function(key) { + if(key !== "fullName" && (key !== "color" && (key !== "imageUrl" && props.hasOwnProperty(key)))) { + delete props[key] + } + }) + } + this.getMemberId = getMemberId; + this.getProperties = getProperties; + this.setProperties = setProperties; + this.removeProperties = removeProperties; + function init() { + runtime.assert(Boolean(memberId), "No memberId was supplied!"); + if(!properties.fullName) { + properties.fullName = runtime.tr("Unknown Author") + } + if(!properties.color) { + properties.color = "black" + } + if(!properties.imageUrl) { + properties.imageUrl = "avatar-joe.png" + } + props = properties + } + init() +}; +/* + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart @@ -8885,109 +8693,194 @@ runtime.loadClass("gui.AnnotationViewManager"); @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils"); -runtime.loadClass("core.LoopWatchDog"); -runtime.loadClass("odf.Namespaces"); -odf.TextStyleApplicator = function TextStyleApplicator(objectNameGenerator, formatting, automaticStyles) { - var domUtils = new core.DomUtils, textns = odf.Namespaces.textns, stylens = odf.Namespaces.stylens, textProperties = "style:text-properties", webodfns = "urn:webodf:names:scope"; - function StyleLookup(info) { - function compare(expected, actual) { - if(typeof expected === "object" && typeof actual === "object") { - return Object.keys(expected).every(function(key) { - return compare(expected[key], actual[key]) - }) - } - return expected === actual +gui.StepCounter; +gui.SelectionMover = function SelectionMover(cursor, rootNode) { + var odfUtils = new odf.OdfUtils, positionIterator, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT; + function getIteratorAtCursor() { + positionIterator.setUnfilteredPosition(cursor.getNode(), 0); + return positionIterator + } + function getMaximumNodePosition(node) { + return node.nodeType === Node.TEXT_NODE ? node.textContent.length : node.childNodes.length + } + function getClientRect(clientRectangles, useRightEdge) { + var rectangle, simplifiedRectangle = null; + if(clientRectangles && clientRectangles.length > 0) { + rectangle = useRightEdge ? clientRectangles.item(clientRectangles.length - 1) : clientRectangles.item(0) } - this.isStyleApplied = function(textNode) { - var appliedStyle = formatting.getAppliedStylesForElement(textNode); - return compare(info, appliedStyle) + if(rectangle) { + simplifiedRectangle = {top:rectangle.top, left:useRightEdge ? rectangle.right : rectangle.left, bottom:rectangle.bottom} } + return simplifiedRectangle } - function StyleManager(info) { - var createdStyles = {}; - function createDirectFormat(existingStyleName, document) { - var derivedStyleInfo, derivedStyleNode; - derivedStyleInfo = existingStyleName ? formatting.createDerivedStyleObject(existingStyleName, "text", info) : info; - derivedStyleNode = document.createElementNS(stylens, "style:style"); - formatting.updateStyle(derivedStyleNode, derivedStyleInfo); - derivedStyleNode.setAttributeNS(stylens, "style:name", objectNameGenerator.generateStyleName()); - derivedStyleNode.setAttributeNS(stylens, "style:family", "text"); - derivedStyleNode.setAttributeNS(webodfns, "scope", "document-content"); - automaticStyles.appendChild(derivedStyleNode); - return derivedStyleNode + function getVisibleRect(container, offset, range, useRightEdge) { + var rectangle, nodeType = container.nodeType; + range.setStart(container, offset); + range.collapse(!useRightEdge); + rectangle = getClientRect(range.getClientRects(), useRightEdge === true); + if(!rectangle && offset > 0) { + range.setStart(container, offset - 1); + range.setEnd(container, offset); + rectangle = getClientRect(range.getClientRects(), true) } - function getDirectStyle(existingStyleName, document) { - existingStyleName = existingStyleName || ""; - if(!createdStyles.hasOwnProperty(existingStyleName)) { - createdStyles[existingStyleName] = createDirectFormat(existingStyleName, document) + if(!rectangle) { + if(nodeType === Node.ELEMENT_NODE && (offset > 0 && (container).childNodes.length >= offset)) { + rectangle = getVisibleRect(container, offset - 1, range, true) + }else { + if(container.nodeType === Node.TEXT_NODE && offset > 0) { + rectangle = getVisibleRect(container, offset - 1, range, true) + }else { + if(container.previousSibling) { + rectangle = getVisibleRect(container.previousSibling, getMaximumNodePosition(container.previousSibling), range, true) + }else { + if(container.parentNode && container.parentNode !== rootNode) { + rectangle = getVisibleRect(container.parentNode, 0, range, false) + }else { + range.selectNode(rootNode); + rectangle = getClientRect(range.getClientRects(), false) + } + } + } } - return createdStyles[existingStyleName].getAttributeNS(stylens, "name") } - this.applyStyleToContainer = function(container) { - var name = getDirectStyle(container.getAttributeNS(textns, "style-name"), container.ownerDocument); - container.setAttributeNS(textns, "text:style-name", name) + runtime.assert(Boolean(rectangle), "No visible rectangle found"); + return(rectangle) + } + function convertForwardStepsBetweenFilters(stepsFilter1, filter1, filter2) { + var iterator = getIteratorAtCursor(), watch = new core.LoopWatchDog(1E4), pendingStepsFilter2 = 0, stepsFilter2 = 0; + while(stepsFilter1 > 0 && iterator.nextPosition()) { + watch.check(); + if(filter2.acceptPosition(iterator) === FILTER_ACCEPT) { + pendingStepsFilter2 += 1; + if(filter1.acceptPosition(iterator) === FILTER_ACCEPT) { + stepsFilter2 += pendingStepsFilter2; + pendingStepsFilter2 = 0; + stepsFilter1 -= 1 + } + } } + return stepsFilter2 } - function isTextSpan(node) { - return node.localName === "span" && node.namespaceURI === textns + function convertBackwardStepsBetweenFilters(stepsFilter1, filter1, filter2) { + var iterator = getIteratorAtCursor(), watch = new core.LoopWatchDog(1E4), pendingStepsFilter2 = 0, stepsFilter2 = 0; + while(stepsFilter1 > 0 && iterator.previousPosition()) { + watch.check(); + if(filter2.acceptPosition(iterator) === FILTER_ACCEPT) { + pendingStepsFilter2 += 1; + if(filter1.acceptPosition(iterator) === FILTER_ACCEPT) { + stepsFilter2 += pendingStepsFilter2; + pendingStepsFilter2 = 0; + stepsFilter1 -= 1 + } + } + } + return stepsFilter2 } - function moveToNewSpan(startNode, limits) { - var document = startNode.ownerDocument, originalContainer = (startNode.parentNode), styledContainer, trailingContainer, moveTrailing, node, nextNode, loopGuard = new core.LoopWatchDog(1E4), styledNodes = []; - if(!isTextSpan(originalContainer)) { - styledContainer = document.createElementNS(textns, "text:span"); - originalContainer.insertBefore(styledContainer, startNode); - moveTrailing = false - }else { - if(startNode.previousSibling && !domUtils.rangeContainsNode(limits, (originalContainer.firstChild))) { - styledContainer = originalContainer.cloneNode(false); - originalContainer.parentNode.insertBefore(styledContainer, originalContainer.nextSibling); - moveTrailing = true - }else { - styledContainer = originalContainer; - moveTrailing = true + function countLineSteps(filter, direction, iterator) { + var c = iterator.container(), steps = 0, bestContainer = null, bestOffset, bestXDiff = 10, xDiff, bestCount = 0, top, left, lastTop, rect, range = (rootNode.ownerDocument.createRange()), watch = new core.LoopWatchDog(1E4); + rect = getVisibleRect(c, iterator.unfilteredDomOffset(), range); + top = rect.top; + left = rect.left; + lastTop = top; + while((direction < 0 ? iterator.previousPosition() : iterator.nextPosition()) === true) { + watch.check(); + if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { + steps += 1; + c = iterator.container(); + rect = getVisibleRect(c, iterator.unfilteredDomOffset(), range); + if(rect.top !== top) { + if(rect.top !== lastTop && lastTop !== top) { + break + } + lastTop = rect.top; + xDiff = Math.abs(left - rect.left); + if(bestContainer === null || xDiff < bestXDiff) { + bestContainer = c; + bestOffset = iterator.unfilteredDomOffset(); + bestXDiff = xDiff; + bestCount = steps + } + } } } - styledNodes.push(startNode); - node = startNode.nextSibling; - while(node && domUtils.rangeContainsNode(limits, node)) { - loopGuard.check(); - styledNodes.push(node); - node = node.nextSibling + if(bestContainer !== null) { + iterator.setUnfilteredPosition(bestContainer, (bestOffset)); + steps = bestCount + }else { + steps = 0 } - styledNodes.forEach(function(n) { - if(n.parentNode !== styledContainer) { - styledContainer.appendChild(n) + range.detach(); + return steps + } + function countLinesSteps(lines, filter) { + var iterator = getIteratorAtCursor(), stepCount = 0, steps = 0, direction = lines < 0 ? -1 : 1; + lines = Math.abs(lines); + while(lines > 0) { + stepCount += countLineSteps(filter, direction, iterator); + if(stepCount === 0) { + break } - }); - if(node && moveTrailing) { - trailingContainer = styledContainer.cloneNode(false); - styledContainer.parentNode.insertBefore(trailingContainer, styledContainer.nextSibling); - while(node) { - loopGuard.check(); - nextNode = node.nextSibling; - trailingContainer.appendChild(node); - node = nextNode + steps += stepCount; + lines -= 1 + } + return steps * direction + } + function countStepsToLineBoundary(direction, filter) { + var fnNextPos, increment, lastRect, rect, onSameLine, iterator = getIteratorAtCursor(), paragraphNode = odfUtils.getParagraphElement(iterator.getCurrentNode()), steps = 0, range = (rootNode.ownerDocument.createRange()); + if(direction < 0) { + fnNextPos = iterator.previousPosition; + increment = -1 + }else { + fnNextPos = iterator.nextPosition; + increment = 1 + } + lastRect = getVisibleRect(iterator.container(), iterator.unfilteredDomOffset(), range); + while(fnNextPos.call(iterator)) { + if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { + if(odfUtils.getParagraphElement(iterator.getCurrentNode()) !== paragraphNode) { + break + } + rect = getVisibleRect(iterator.container(), iterator.unfilteredDomOffset(), range); + if(rect.bottom !== lastRect.bottom) { + onSameLine = rect.top >= lastRect.top && rect.bottom < lastRect.bottom || rect.top <= lastRect.top && rect.bottom > lastRect.bottom; + if(!onSameLine) { + break + } + } + steps += increment; + lastRect = rect } } - return(styledContainer) + range.detach(); + return steps } - this.applyStyle = function(textNodes, limits, info) { - var textPropsOnly = {}, isStyled, container, styleCache, styleLookup; - runtime.assert(info && info.hasOwnProperty(textProperties), "applyStyle without any text properties"); - textPropsOnly[textProperties] = info[textProperties]; - styleCache = new StyleManager(textPropsOnly); - styleLookup = new StyleLookup(textPropsOnly); - function apply(n) { - isStyled = styleLookup.isStyleApplied(n); - if(isStyled === false) { - container = moveToNewSpan(n, limits); - styleCache.applyStyleToContainer(container) + this.getStepCounter = function() { + return{convertForwardStepsBetweenFilters:convertForwardStepsBetweenFilters, convertBackwardStepsBetweenFilters:convertBackwardStepsBetweenFilters, countLinesSteps:countLinesSteps, countStepsToLineBoundary:countStepsToLineBoundary} + }; + function init() { + positionIterator = gui.SelectionMover.createPositionIterator(rootNode); + var range = rootNode.ownerDocument.createRange(); + range.setStart(positionIterator.container(), positionIterator.unfilteredDomOffset()); + range.collapse(true); + cursor.setSelectedRange(range) + } + init() +}; +gui.SelectionMover.createPositionIterator = function(rootNode) { + function CursorFilter() { + this.acceptNode = function(node) { + if(!node || (node.namespaceURI === "urn:webodf:names:cursor" || node.namespaceURI === "urn:webodf:names:editinfo")) { + return NodeFilter.FILTER_REJECT } + return NodeFilter.FILTER_ACCEPT } - textNodes.forEach(apply) } + var filter = new CursorFilter; + return new core.PositionIterator(rootNode, 5, filter, false) }; +(function() { + return gui.SelectionMover +})(); /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -9025,1276 +8918,100 @@ odf.TextStyleApplicator = function TextStyleApplicator(objectNameGenerator, form @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces"); -runtime.loadClass("odf.OdfUtils"); -gui.StyleHelper = function StyleHelper(formatting) { - var odfUtils = new odf.OdfUtils, textns = odf.Namespaces.textns; - function getAppliedStyles(range) { - var container, nodes; - if(range.collapsed) { - container = range.startContainer; - if(container.hasChildNodes() && range.startOffset < container.childNodes.length) { - container = container.childNodes.item(range.startOffset) - } - nodes = [container] - }else { - nodes = odfUtils.getTextNodes(range, true) - } - return formatting.getAppliedStyles(nodes) - } - this.getAppliedStyles = getAppliedStyles; - function hasTextPropertyValue(appliedStyles, propertyName, propertyValue) { - var hasOtherValue = true, properties, i; - for(i = 0;i < appliedStyles.length;i += 1) { - properties = appliedStyles[i]["style:text-properties"]; - hasOtherValue = !properties || properties[propertyName] !== propertyValue; - if(hasOtherValue) { - break - } - } - return!hasOtherValue - } - this.isBold = function(appliedStyles) { - return hasTextPropertyValue(appliedStyles, "fo:font-weight", "bold") - }; - this.isItalic = function(appliedStyles) { - return hasTextPropertyValue(appliedStyles, "fo:font-style", "italic") - }; - this.hasUnderline = function(appliedStyles) { - return hasTextPropertyValue(appliedStyles, "style:text-underline-style", "solid") - }; - this.hasStrikeThrough = function(appliedStyles) { - return hasTextPropertyValue(appliedStyles, "style:text-line-through-style", "solid") - }; - function hasParagraphPropertyValue(range, propertyName, propertyValues) { - var paragraphStyleName, paragraphStyleElement, paragraphStyleAttributes, properties, nodes = odfUtils.getParagraphElements(range), isStyleChecked = {}, isDefaultParagraphStyleChecked = false; - function pickDefaultParagraphStyleElement() { - isDefaultParagraphStyleChecked = true; - paragraphStyleElement = formatting.getDefaultStyleElement("paragraph"); - if(!paragraphStyleElement) { - paragraphStyleElement = null - } - } - while(nodes.length > 0) { - paragraphStyleName = nodes[0].getAttributeNS(textns, "style-name"); - if(paragraphStyleName) { - if(!isStyleChecked[paragraphStyleName]) { - paragraphStyleElement = formatting.getStyleElement(paragraphStyleName, "paragraph"); - isStyleChecked[paragraphStyleName] = true; - if(!paragraphStyleElement && !isDefaultParagraphStyleChecked) { - pickDefaultParagraphStyleElement() - } - } - }else { - if(!isDefaultParagraphStyleChecked) { - pickDefaultParagraphStyleElement() - }else { - paragraphStyleElement = undefined - } - } - if(paragraphStyleElement !== undefined) { - if(paragraphStyleElement === null) { - paragraphStyleAttributes = formatting.getSystemDefaultStyleAttributes("paragraph") - }else { - paragraphStyleAttributes = formatting.getInheritedStyleAttributes((paragraphStyleElement), true) - } - properties = paragraphStyleAttributes["style:paragraph-properties"]; - if(properties && propertyValues.indexOf(properties[propertyName]) === -1) { - return false - } - } - nodes.pop() - } - return true - } - this.isAlignedLeft = function(range) { - return hasParagraphPropertyValue(range, "fo:text-align", ["left", "start"]) - }; - this.isAlignedCenter = function(range) { - return hasParagraphPropertyValue(range, "fo:text-align", ["center"]) - }; - this.isAlignedRight = function(range) { - return hasParagraphPropertyValue(range, "fo:text-align", ["right", "end"]) - }; - this.isAlignedJustified = function(range) { - return hasParagraphPropertyValue(range, "fo:text-align", ["justify"]) - } +ops.Document = function Document() { }; -core.RawDeflate = function() { - var zip_WSIZE = 32768, zip_STORED_BLOCK = 0, zip_STATIC_TREES = 1, zip_DYN_TREES = 2, zip_DEFAULT_LEVEL = 6, zip_FULL_SEARCH = true, zip_INBUFSIZ = 32768, zip_INBUF_EXTRA = 64, zip_OUTBUFSIZ = 1024 * 8, zip_window_size = 2 * zip_WSIZE, zip_MIN_MATCH = 3, zip_MAX_MATCH = 258, zip_BITS = 16, zip_LIT_BUFSIZE = 8192, zip_HASH_BITS = 13, zip_DIST_BUFSIZE = zip_LIT_BUFSIZE, zip_HASH_SIZE = 1 << zip_HASH_BITS, zip_HASH_MASK = zip_HASH_SIZE - 1, zip_WMASK = zip_WSIZE - 1, zip_NIL = 0, zip_TOO_FAR = 4096, - zip_MIN_LOOKAHEAD = zip_MAX_MATCH + zip_MIN_MATCH + 1, zip_MAX_DIST = zip_WSIZE - zip_MIN_LOOKAHEAD, zip_SMALLEST = 1, zip_MAX_BITS = 15, zip_MAX_BL_BITS = 7, zip_LENGTH_CODES = 29, zip_LITERALS = 256, zip_END_BLOCK = 256, zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES, zip_D_CODES = 30, zip_BL_CODES = 19, zip_REP_3_6 = 16, zip_REPZ_3_10 = 17, zip_REPZ_11_138 = 18, zip_HEAP_SIZE = 2 * zip_L_CODES + 1, zip_H_SHIFT = parseInt((zip_HASH_BITS + zip_MIN_MATCH - 1) / zip_MIN_MATCH, 10), zip_free_queue, - zip_qhead, zip_qtail, zip_initflag, zip_outbuf = null, zip_outcnt, zip_outoff, zip_complete, zip_window, zip_d_buf, zip_l_buf, zip_prev, zip_bi_buf, zip_bi_valid, zip_block_start, zip_ins_h, zip_hash_head, zip_prev_match, zip_match_available, zip_match_length, zip_prev_length, zip_strstart, zip_match_start, zip_eofile, zip_lookahead, zip_max_chain_length, zip_max_lazy_match, zip_compr_level, zip_good_match, zip_nice_match, zip_dyn_ltree, zip_dyn_dtree, zip_static_ltree, zip_static_dtree, zip_bl_tree, - zip_l_desc, zip_d_desc, zip_bl_desc, zip_bl_count, zip_heap, zip_heap_len, zip_heap_max, zip_depth, zip_length_code, zip_dist_code, zip_base_length, zip_base_dist, zip_flag_buf, zip_last_lit, zip_last_dist, zip_last_flags, zip_flags, zip_flag_bit, zip_opt_len, zip_static_len, zip_deflate_data, zip_deflate_pos, zip_extra_lbits = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0], zip_extra_dbits = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, - 9, 10, 10, 11, 11, 12, 12, 13, 13], zip_extra_blbits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7], zip_bl_order = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15], zip_configuration_table; - if(zip_LIT_BUFSIZE > zip_INBUFSIZ) { - runtime.log("error: zip_INBUFSIZ is too small") - } - if(zip_WSIZE << 1 > 1 << zip_BITS) { - runtime.log("error: zip_WSIZE is too large") - } - if(zip_HASH_BITS > zip_BITS - 1) { - runtime.log("error: zip_HASH_BITS is too large") - } - if(zip_HASH_BITS < 8 || zip_MAX_MATCH !== 258) { - runtime.log("error: Code too clever") - } - function Zip_DeflateCT() { - this.fc = 0; - this.dl = 0 - } - function Zip_DeflateTreeDesc() { - this.dyn_tree = null; - this.static_tree = null; - this.extra_bits = null; - this.extra_base = 0; - this.elems = 0; - this.max_length = 0; - this.max_code = 0 - } - function Zip_DeflateConfiguration(a, b, c, d) { - this.good_length = a; - this.max_lazy = b; - this.nice_length = c; - this.max_chain = d - } - function Zip_DeflateBuffer() { - this.next = null; - this.len = 0; - this.ptr = []; - this.ptr.length = zip_OUTBUFSIZ; - this.off = 0 - } - zip_configuration_table = [new Zip_DeflateConfiguration(0, 0, 0, 0), new Zip_DeflateConfiguration(4, 4, 8, 4), new Zip_DeflateConfiguration(4, 5, 16, 8), new Zip_DeflateConfiguration(4, 6, 32, 32), new Zip_DeflateConfiguration(4, 4, 16, 16), new Zip_DeflateConfiguration(8, 16, 32, 32), new Zip_DeflateConfiguration(8, 16, 128, 128), new Zip_DeflateConfiguration(8, 32, 128, 256), new Zip_DeflateConfiguration(32, 128, 258, 1024), new Zip_DeflateConfiguration(32, 258, 258, 4096)]; - function zip_deflate_start(level) { - var i; - if(!level) { - level = zip_DEFAULT_LEVEL - }else { - if(level < 1) { - level = 1 - }else { - if(level > 9) { - level = 9 - } - } - } - zip_compr_level = level; - zip_initflag = false; - zip_eofile = false; - if(zip_outbuf !== null) { - return - } - zip_free_queue = zip_qhead = zip_qtail = null; - zip_outbuf = []; - zip_outbuf.length = zip_OUTBUFSIZ; - zip_window = []; - zip_window.length = zip_window_size; - zip_d_buf = []; - zip_d_buf.length = zip_DIST_BUFSIZE; - zip_l_buf = []; - zip_l_buf.length = zip_INBUFSIZ + zip_INBUF_EXTRA; - zip_prev = []; - zip_prev.length = 1 << zip_BITS; - zip_dyn_ltree = []; - zip_dyn_ltree.length = zip_HEAP_SIZE; - for(i = 0;i < zip_HEAP_SIZE;i++) { - zip_dyn_ltree[i] = new Zip_DeflateCT - } - zip_dyn_dtree = []; - zip_dyn_dtree.length = 2 * zip_D_CODES + 1; - for(i = 0;i < 2 * zip_D_CODES + 1;i++) { - zip_dyn_dtree[i] = new Zip_DeflateCT - } - zip_static_ltree = []; - zip_static_ltree.length = zip_L_CODES + 2; - for(i = 0;i < zip_L_CODES + 2;i++) { - zip_static_ltree[i] = new Zip_DeflateCT - } - zip_static_dtree = []; - zip_static_dtree.length = zip_D_CODES; - for(i = 0;i < zip_D_CODES;i++) { - zip_static_dtree[i] = new Zip_DeflateCT - } - zip_bl_tree = []; - zip_bl_tree.length = 2 * zip_BL_CODES + 1; - for(i = 0;i < 2 * zip_BL_CODES + 1;i++) { - zip_bl_tree[i] = new Zip_DeflateCT - } - zip_l_desc = new Zip_DeflateTreeDesc; - zip_d_desc = new Zip_DeflateTreeDesc; - zip_bl_desc = new Zip_DeflateTreeDesc; - zip_bl_count = []; - zip_bl_count.length = zip_MAX_BITS + 1; - zip_heap = []; - zip_heap.length = 2 * zip_L_CODES + 1; - zip_depth = []; - zip_depth.length = 2 * zip_L_CODES + 1; - zip_length_code = []; - zip_length_code.length = zip_MAX_MATCH - zip_MIN_MATCH + 1; - zip_dist_code = []; - zip_dist_code.length = 512; - zip_base_length = []; - zip_base_length.length = zip_LENGTH_CODES; - zip_base_dist = []; - zip_base_dist.length = zip_D_CODES; - zip_flag_buf = []; - zip_flag_buf.length = parseInt(zip_LIT_BUFSIZE / 8, 10) - } - var zip_reuse_queue = function(p) { - p.next = zip_free_queue; - zip_free_queue = p - }; - var zip_new_queue = function() { - var p; - if(zip_free_queue !== null) { - p = zip_free_queue; - zip_free_queue = zip_free_queue.next - }else { - p = new Zip_DeflateBuffer - } - p.next = null; - p.len = p.off = 0; - return p - }; - var zip_head1 = function(i) { - return zip_prev[zip_WSIZE + i] - }; - var zip_head2 = function(i, val) { - zip_prev[zip_WSIZE + i] = val; - return val - }; - var zip_qoutbuf = function() { - var q, i; - if(zip_outcnt !== 0) { - q = zip_new_queue(); - if(zip_qhead === null) { - zip_qhead = zip_qtail = q - }else { - zip_qtail = zip_qtail.next = q - } - q.len = zip_outcnt - zip_outoff; - for(i = 0;i < q.len;i++) { - q.ptr[i] = zip_outbuf[zip_outoff + i] - } - zip_outcnt = zip_outoff = 0 - } - }; - var zip_put_byte = function(c) { - zip_outbuf[zip_outoff + zip_outcnt++] = c; - if(zip_outoff + zip_outcnt === zip_OUTBUFSIZ) { - zip_qoutbuf() - } - }; - var zip_put_short = function(w) { - w &= 65535; - if(zip_outoff + zip_outcnt < zip_OUTBUFSIZ - 2) { - zip_outbuf[zip_outoff + zip_outcnt++] = w & 255; - zip_outbuf[zip_outoff + zip_outcnt++] = w >>> 8 - }else { - zip_put_byte(w & 255); - zip_put_byte(w >>> 8) - } - }; - var zip_INSERT_STRING = function() { - zip_ins_h = (zip_ins_h << zip_H_SHIFT ^ zip_window[zip_strstart + zip_MIN_MATCH - 1] & 255) & zip_HASH_MASK; - zip_hash_head = zip_head1(zip_ins_h); - zip_prev[zip_strstart & zip_WMASK] = zip_hash_head; - zip_head2(zip_ins_h, zip_strstart) - }; - var zip_Buf_size = 16; - var zip_send_bits = function(value, length) { - if(zip_bi_valid > zip_Buf_size - length) { - zip_bi_buf |= value << zip_bi_valid; - zip_put_short(zip_bi_buf); - zip_bi_buf = value >> zip_Buf_size - zip_bi_valid; - zip_bi_valid += length - zip_Buf_size - }else { - zip_bi_buf |= value << zip_bi_valid; - zip_bi_valid += length - } - }; - var zip_SEND_CODE = function(c, tree) { - zip_send_bits(tree[c].fc, tree[c].dl) - }; - var zip_D_CODE = function(dist) { - return(dist < 256 ? zip_dist_code[dist] : zip_dist_code[256 + (dist >> 7)]) & 255 - }; - var zip_SMALLER = function(tree, n, m) { - return tree[n].fc < tree[m].fc || tree[n].fc === tree[m].fc && zip_depth[n] <= zip_depth[m] - }; - var zip_read_buff = function(buff, offset, n) { - var i; - for(i = 0;i < n && zip_deflate_pos < zip_deflate_data.length;i++) { - buff[offset + i] = zip_deflate_data.charCodeAt(zip_deflate_pos++) & 255 - } - return i - }; - var zip_fill_window = function() { - var n, m; - var more = zip_window_size - zip_lookahead - zip_strstart; - if(more === -1) { - more-- - }else { - if(zip_strstart >= zip_WSIZE + zip_MAX_DIST) { - for(n = 0;n < zip_WSIZE;n++) { - zip_window[n] = zip_window[n + zip_WSIZE] - } - zip_match_start -= zip_WSIZE; - zip_strstart -= zip_WSIZE; - zip_block_start -= zip_WSIZE; - for(n = 0;n < zip_HASH_SIZE;n++) { - m = zip_head1(n); - zip_head2(n, m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL) - } - for(n = 0;n < zip_WSIZE;n++) { - m = zip_prev[n]; - zip_prev[n] = m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL - } - more += zip_WSIZE - } - } - if(!zip_eofile) { - n = zip_read_buff(zip_window, zip_strstart + zip_lookahead, more); - if(n <= 0) { - zip_eofile = true - }else { - zip_lookahead += n - } - } - }; - var zip_lm_init = function() { - var j; - for(j = 0;j < zip_HASH_SIZE;j++) { - zip_prev[zip_WSIZE + j] = 0 - } - zip_max_lazy_match = zip_configuration_table[zip_compr_level].max_lazy; - zip_good_match = zip_configuration_table[zip_compr_level].good_length; - if(!zip_FULL_SEARCH) { - zip_nice_match = zip_configuration_table[zip_compr_level].nice_length - } - zip_max_chain_length = zip_configuration_table[zip_compr_level].max_chain; - zip_strstart = 0; - zip_block_start = 0; - zip_lookahead = zip_read_buff(zip_window, 0, 2 * zip_WSIZE); - if(zip_lookahead <= 0) { - zip_eofile = true; - zip_lookahead = 0; - return - } - zip_eofile = false; - while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) { - zip_fill_window() - } - zip_ins_h = 0; - for(j = 0;j < zip_MIN_MATCH - 1;j++) { - zip_ins_h = (zip_ins_h << zip_H_SHIFT ^ zip_window[j] & 255) & zip_HASH_MASK - } - }; - var zip_longest_match = function(cur_match) { - var chain_length = zip_max_chain_length; - var scanp = zip_strstart; - var matchp; - var len; - var best_len = zip_prev_length; - var limit = zip_strstart > zip_MAX_DIST ? zip_strstart - zip_MAX_DIST : zip_NIL; - var strendp = zip_strstart + zip_MAX_MATCH; - var scan_end1 = zip_window[scanp + best_len - 1]; - var scan_end = zip_window[scanp + best_len]; - if(zip_prev_length >= zip_good_match) { - chain_length >>= 2 - } - do { - matchp = cur_match; - if(zip_window[matchp + best_len] !== scan_end || (zip_window[matchp + best_len - 1] !== scan_end1 || (zip_window[matchp] !== zip_window[scanp] || zip_window[++matchp] !== zip_window[scanp + 1]))) { - continue - } - scanp += 2; - matchp++; - do { - ++scanp - }while(zip_window[scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && scanp < strendp)))))))); - len = zip_MAX_MATCH - (strendp - scanp); - scanp = strendp - zip_MAX_MATCH; - if(len > best_len) { - zip_match_start = cur_match; - best_len = len; - if(zip_FULL_SEARCH) { - if(len >= zip_MAX_MATCH) { - break - } - }else { - if(len >= zip_nice_match) { - break - } - } - scan_end1 = zip_window[scanp + best_len - 1]; - scan_end = zip_window[scanp + best_len] - } - cur_match = zip_prev[cur_match & zip_WMASK] - }while(cur_match > limit && --chain_length !== 0); - return best_len - }; - var zip_ct_tally = function(dist, lc) { - zip_l_buf[zip_last_lit++] = lc; - if(dist === 0) { - zip_dyn_ltree[lc].fc++ - }else { - dist--; - zip_dyn_ltree[zip_length_code[lc] + zip_LITERALS + 1].fc++; - zip_dyn_dtree[zip_D_CODE(dist)].fc++; - zip_d_buf[zip_last_dist++] = dist; - zip_flags |= zip_flag_bit - } - zip_flag_bit <<= 1; - if((zip_last_lit & 7) === 0) { - zip_flag_buf[zip_last_flags++] = zip_flags; - zip_flags = 0; - zip_flag_bit = 1 - } - if(zip_compr_level > 2 && (zip_last_lit & 4095) === 0) { - var out_length = zip_last_lit * 8; - var in_length = zip_strstart - zip_block_start; - var dcode; - for(dcode = 0;dcode < zip_D_CODES;dcode++) { - out_length += zip_dyn_dtree[dcode].fc * (5 + zip_extra_dbits[dcode]) - } - out_length >>= 3; - if(zip_last_dist < parseInt(zip_last_lit / 2, 10) && out_length < parseInt(in_length / 2, 10)) { - return true - } - } - return zip_last_lit === zip_LIT_BUFSIZE - 1 || zip_last_dist === zip_DIST_BUFSIZE - }; - var zip_pqdownheap = function(tree, k) { - var v = zip_heap[k]; - var j = k << 1; - while(j <= zip_heap_len) { - if(j < zip_heap_len && zip_SMALLER(tree, zip_heap[j + 1], zip_heap[j])) { - j++ - } - if(zip_SMALLER(tree, v, zip_heap[j])) { - break - } - zip_heap[k] = zip_heap[j]; - k = j; - j <<= 1 - } - zip_heap[k] = v - }; - var zip_gen_bitlen = function(desc) { - var tree = desc.dyn_tree; - var extra = desc.extra_bits; - var base = desc.extra_base; - var max_code = desc.max_code; - var max_length = desc.max_length; - var stree = desc.static_tree; - var h; - var n, m; - var bits; - var xbits; - var f; - var overflow = 0; - for(bits = 0;bits <= zip_MAX_BITS;bits++) { - zip_bl_count[bits] = 0 - } - tree[zip_heap[zip_heap_max]].dl = 0; - for(h = zip_heap_max + 1;h < zip_HEAP_SIZE;h++) { - n = zip_heap[h]; - bits = tree[tree[n].dl].dl + 1; - if(bits > max_length) { - bits = max_length; - overflow++ - } - tree[n].dl = bits; - if(n > max_code) { - continue - } - zip_bl_count[bits]++; - xbits = 0; - if(n >= base) { - xbits = extra[n - base] - } - f = tree[n].fc; - zip_opt_len += f * (bits + xbits); - if(stree !== null) { - zip_static_len += f * (stree[n].dl + xbits) - } - } - if(overflow === 0) { - return - } - do { - bits = max_length - 1; - while(zip_bl_count[bits] === 0) { - bits-- - } - zip_bl_count[bits]--; - zip_bl_count[bits + 1] += 2; - zip_bl_count[max_length]--; - overflow -= 2 - }while(overflow > 0); - for(bits = max_length;bits !== 0;bits--) { - n = zip_bl_count[bits]; - while(n !== 0) { - m = zip_heap[--h]; - if(m > max_code) { - continue - } - if(tree[m].dl !== bits) { - zip_opt_len += (bits - tree[m].dl) * tree[m].fc; - tree[m].fc = bits - } - n-- - } - } - }; - var zip_bi_reverse = function(code, len) { - var res = 0; - do { - res |= code & 1; - code >>= 1; - res <<= 1 - }while(--len > 0); - return res >> 1 - }; - var zip_gen_codes = function(tree, max_code) { - var next_code = []; - next_code.length = zip_MAX_BITS + 1; - var code = 0; - var bits; - var n; - for(bits = 1;bits <= zip_MAX_BITS;bits++) { - code = code + zip_bl_count[bits - 1] << 1; - next_code[bits] = code - } - var len; - for(n = 0;n <= max_code;n++) { - len = tree[n].dl; - if(len === 0) { - continue - } - tree[n].fc = zip_bi_reverse(next_code[len]++, len) - } - }; - var zip_build_tree = function(desc) { - var tree = desc.dyn_tree; - var stree = desc.static_tree; - var elems = desc.elems; - var n, m; - var max_code = -1; - var node = elems; - zip_heap_len = 0; - zip_heap_max = zip_HEAP_SIZE; - for(n = 0;n < elems;n++) { - if(tree[n].fc !== 0) { - zip_heap[++zip_heap_len] = max_code = n; - zip_depth[n] = 0 - }else { - tree[n].dl = 0 - } - } - var xnew; - while(zip_heap_len < 2) { - xnew = zip_heap[++zip_heap_len] = max_code < 2 ? ++max_code : 0; - tree[xnew].fc = 1; - zip_depth[xnew] = 0; - zip_opt_len--; - if(stree !== null) { - zip_static_len -= stree[xnew].dl - } - } - desc.max_code = max_code; - for(n = zip_heap_len >> 1;n >= 1;n--) { - zip_pqdownheap(tree, n) - } - do { - n = zip_heap[zip_SMALLEST]; - zip_heap[zip_SMALLEST] = zip_heap[zip_heap_len--]; - zip_pqdownheap(tree, zip_SMALLEST); - m = zip_heap[zip_SMALLEST]; - zip_heap[--zip_heap_max] = n; - zip_heap[--zip_heap_max] = m; - tree[node].fc = tree[n].fc + tree[m].fc; - if(zip_depth[n] > zip_depth[m] + 1) { - zip_depth[node] = zip_depth[n] - }else { - zip_depth[node] = zip_depth[m] + 1 - } - tree[n].dl = tree[m].dl = node; - zip_heap[zip_SMALLEST] = node++; - zip_pqdownheap(tree, zip_SMALLEST) - }while(zip_heap_len >= 2); - zip_heap[--zip_heap_max] = zip_heap[zip_SMALLEST]; - zip_gen_bitlen(desc); - zip_gen_codes(tree, max_code) +ops.Document.prototype.getMemberIds = function() { +}; +ops.Document.prototype.removeCursor = function(memberid) { +}; +ops.Document.prototype.getDocumentElement = function() { +}; +ops.Document.prototype.getRootNode = function() { +}; +ops.Document.prototype.getDOMDocument = function() { +}; +ops.Document.prototype.cloneDocumentElement = function() { +}; +ops.Document.prototype.setDocumentElement = function(element) { +}; +ops.Document.prototype.subscribe = function(eventid, cb) { +}; +ops.Document.prototype.unsubscribe = function(eventid, cb) { +}; +ops.Document.prototype.getCanvas = function() { +}; +ops.Document.prototype.createRootFilter = function(inputMemberId) { +}; +ops.Document.signalCursorAdded = "cursor/added"; +ops.Document.signalCursorRemoved = "cursor/removed"; +ops.Document.signalCursorMoved = "cursor/moved"; +ops.Document.signalMemberAdded = "member/added"; +ops.Document.signalMemberUpdated = "member/updated"; +ops.Document.signalMemberRemoved = "member/removed"; +ops.OdtCursor = function OdtCursor(memberId, document) { + var self = this, validSelectionTypes = {}, selectionType, selectionMover, cursor, events = new core.EventNotifier([ops.OdtCursor.signalCursorUpdated]); + this.removeFromDocument = function() { + cursor.remove() }; - var zip_scan_tree = function(tree, max_code) { - var n; - var prevlen = -1; - var curlen; - var nextlen = tree[0].dl; - var count = 0; - var max_count = 7; - var min_count = 4; - if(nextlen === 0) { - max_count = 138; - min_count = 3 - } - tree[max_code + 1].dl = 65535; - for(n = 0;n <= max_code;n++) { - curlen = nextlen; - nextlen = tree[n + 1].dl; - if(++count < max_count && curlen === nextlen) { - continue - } - if(count < min_count) { - zip_bl_tree[curlen].fc += count - }else { - if(curlen !== 0) { - if(curlen !== prevlen) { - zip_bl_tree[curlen].fc++ - } - zip_bl_tree[zip_REP_3_6].fc++ - }else { - if(count <= 10) { - zip_bl_tree[zip_REPZ_3_10].fc++ - }else { - zip_bl_tree[zip_REPZ_11_138].fc++ - } - } - } - count = 0; - prevlen = curlen; - if(nextlen === 0) { - max_count = 138; - min_count = 3 - }else { - if(curlen === nextlen) { - max_count = 6; - min_count = 3 - }else { - max_count = 7; - min_count = 4 - } - } - } + this.subscribe = function(eventid, cb) { + events.subscribe(eventid, cb) }; - var zip_build_bl_tree = function() { - var max_blindex; - zip_scan_tree(zip_dyn_ltree, zip_l_desc.max_code); - zip_scan_tree(zip_dyn_dtree, zip_d_desc.max_code); - zip_build_tree(zip_bl_desc); - for(max_blindex = zip_BL_CODES - 1;max_blindex >= 3;max_blindex--) { - if(zip_bl_tree[zip_bl_order[max_blindex]].dl !== 0) { - break - } - } - zip_opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; - return max_blindex + this.unsubscribe = function(eventid, cb) { + events.unsubscribe(eventid, cb) }; - var zip_bi_windup = function() { - if(zip_bi_valid > 8) { - zip_put_short(zip_bi_buf) - }else { - if(zip_bi_valid > 0) { - zip_put_byte(zip_bi_buf) - } - } - zip_bi_buf = 0; - zip_bi_valid = 0 - }; - var zip_compress_block = function(ltree, dtree) { - var dist; - var lc; - var lx = 0; - var dx = 0; - var fx = 0; - var flag = 0; - var code; - var extra; - if(zip_last_lit !== 0) { - do { - if((lx & 7) === 0) { - flag = zip_flag_buf[fx++] - } - lc = zip_l_buf[lx++] & 255; - if((flag & 1) === 0) { - zip_SEND_CODE(lc, ltree) - }else { - code = zip_length_code[lc]; - zip_SEND_CODE(code + zip_LITERALS + 1, ltree); - extra = zip_extra_lbits[code]; - if(extra !== 0) { - lc -= zip_base_length[code]; - zip_send_bits(lc, extra) - } - dist = zip_d_buf[dx++]; - code = zip_D_CODE(dist); - zip_SEND_CODE(code, dtree); - extra = zip_extra_dbits[code]; - if(extra !== 0) { - dist -= zip_base_dist[code]; - zip_send_bits(dist, extra) - } - } - flag >>= 1 - }while(lx < zip_last_lit) - } - zip_SEND_CODE(zip_END_BLOCK, ltree) + this.getStepCounter = function() { + return selectionMover.getStepCounter() }; - var zip_send_tree = function(tree, max_code) { - var n; - var prevlen = -1; - var curlen; - var nextlen = tree[0].dl; - var count = 0; - var max_count = 7; - var min_count = 4; - if(nextlen === 0) { - max_count = 138; - min_count = 3 - } - for(n = 0;n <= max_code;n++) { - curlen = nextlen; - nextlen = tree[n + 1].dl; - if(++count < max_count && curlen === nextlen) { - continue - } - if(count < min_count) { - do { - zip_SEND_CODE(curlen, zip_bl_tree) - }while(--count !== 0) - }else { - if(curlen !== 0) { - if(curlen !== prevlen) { - zip_SEND_CODE(curlen, zip_bl_tree); - count-- - } - zip_SEND_CODE(zip_REP_3_6, zip_bl_tree); - zip_send_bits(count - 3, 2) - }else { - if(count <= 10) { - zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree); - zip_send_bits(count - 3, 3) - }else { - zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree); - zip_send_bits(count - 11, 7) - } - } - } - count = 0; - prevlen = curlen; - if(nextlen === 0) { - max_count = 138; - min_count = 3 - }else { - if(curlen === nextlen) { - max_count = 6; - min_count = 3 - }else { - max_count = 7; - min_count = 4 - } - } - } + this.getMemberId = function() { + return memberId }; - var zip_send_all_trees = function(lcodes, dcodes, blcodes) { - var rank; - zip_send_bits(lcodes - 257, 5); - zip_send_bits(dcodes - 1, 5); - zip_send_bits(blcodes - 4, 4); - for(rank = 0;rank < blcodes;rank++) { - zip_send_bits(zip_bl_tree[zip_bl_order[rank]].dl, 3) - } - zip_send_tree(zip_dyn_ltree, lcodes - 1); - zip_send_tree(zip_dyn_dtree, dcodes - 1) + this.getNode = function() { + return cursor.getNode() }; - var zip_init_block = function() { - var n; - for(n = 0;n < zip_L_CODES;n++) { - zip_dyn_ltree[n].fc = 0 - } - for(n = 0;n < zip_D_CODES;n++) { - zip_dyn_dtree[n].fc = 0 - } - for(n = 0;n < zip_BL_CODES;n++) { - zip_bl_tree[n].fc = 0 - } - zip_dyn_ltree[zip_END_BLOCK].fc = 1; - zip_opt_len = zip_static_len = 0; - zip_last_lit = zip_last_dist = zip_last_flags = 0; - zip_flags = 0; - zip_flag_bit = 1 - }; - var zip_flush_block = function(eof) { - var opt_lenb, static_lenb; - var max_blindex; - var stored_len; - stored_len = zip_strstart - zip_block_start; - zip_flag_buf[zip_last_flags] = zip_flags; - zip_build_tree(zip_l_desc); - zip_build_tree(zip_d_desc); - max_blindex = zip_build_bl_tree(); - opt_lenb = zip_opt_len + 3 + 7 >> 3; - static_lenb = zip_static_len + 3 + 7 >> 3; - if(static_lenb <= opt_lenb) { - opt_lenb = static_lenb - } - if(stored_len + 4 <= opt_lenb && zip_block_start >= 0) { - var i; - zip_send_bits((zip_STORED_BLOCK << 1) + eof, 3); - zip_bi_windup(); - zip_put_short(stored_len); - zip_put_short(~stored_len); - for(i = 0;i < stored_len;i++) { - zip_put_byte(zip_window[zip_block_start + i]) - } - }else { - if(static_lenb === opt_lenb) { - zip_send_bits((zip_STATIC_TREES << 1) + eof, 3); - zip_compress_block(zip_static_ltree, zip_static_dtree) - }else { - zip_send_bits((zip_DYN_TREES << 1) + eof, 3); - zip_send_all_trees(zip_l_desc.max_code + 1, zip_d_desc.max_code + 1, max_blindex + 1); - zip_compress_block(zip_dyn_ltree, zip_dyn_dtree) - } - } - zip_init_block(); - if(eof !== 0) { - zip_bi_windup() - } + this.getAnchorNode = function() { + return cursor.getAnchorNode() }; - var zip_deflate_fast = function() { - var flush; - while(zip_lookahead !== 0 && zip_qhead === null) { - zip_INSERT_STRING(); - if(zip_hash_head !== zip_NIL && zip_strstart - zip_hash_head <= zip_MAX_DIST) { - zip_match_length = zip_longest_match(zip_hash_head); - if(zip_match_length > zip_lookahead) { - zip_match_length = zip_lookahead - } - } - if(zip_match_length >= zip_MIN_MATCH) { - flush = zip_ct_tally(zip_strstart - zip_match_start, zip_match_length - zip_MIN_MATCH); - zip_lookahead -= zip_match_length; - if(zip_match_length <= zip_max_lazy_match) { - zip_match_length--; - do { - zip_strstart++; - zip_INSERT_STRING() - }while(--zip_match_length !== 0); - zip_strstart++ - }else { - zip_strstart += zip_match_length; - zip_match_length = 0; - zip_ins_h = zip_window[zip_strstart] & 255; - zip_ins_h = (zip_ins_h << zip_H_SHIFT ^ zip_window[zip_strstart + 1] & 255) & zip_HASH_MASK - } - }else { - flush = zip_ct_tally(0, zip_window[zip_strstart] & 255); - zip_lookahead--; - zip_strstart++ - } - if(flush) { - zip_flush_block(0); - zip_block_start = zip_strstart - } - while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) { - zip_fill_window() - } - } + this.getSelectedRange = function() { + return cursor.getSelectedRange() }; - var zip_deflate_better = function() { - var flush; - while(zip_lookahead !== 0 && zip_qhead === null) { - zip_INSERT_STRING(); - zip_prev_length = zip_match_length; - zip_prev_match = zip_match_start; - zip_match_length = zip_MIN_MATCH - 1; - if(zip_hash_head !== zip_NIL && (zip_prev_length < zip_max_lazy_match && zip_strstart - zip_hash_head <= zip_MAX_DIST)) { - zip_match_length = zip_longest_match(zip_hash_head); - if(zip_match_length > zip_lookahead) { - zip_match_length = zip_lookahead - } - if(zip_match_length === zip_MIN_MATCH && zip_strstart - zip_match_start > zip_TOO_FAR) { - zip_match_length-- - } - } - if(zip_prev_length >= zip_MIN_MATCH && zip_match_length <= zip_prev_length) { - flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match, zip_prev_length - zip_MIN_MATCH); - zip_lookahead -= zip_prev_length - 1; - zip_prev_length -= 2; - do { - zip_strstart++; - zip_INSERT_STRING() - }while(--zip_prev_length !== 0); - zip_match_available = 0; - zip_match_length = zip_MIN_MATCH - 1; - zip_strstart++; - if(flush) { - zip_flush_block(0); - zip_block_start = zip_strstart - } - }else { - if(zip_match_available !== 0) { - if(zip_ct_tally(0, zip_window[zip_strstart - 1] & 255)) { - zip_flush_block(0); - zip_block_start = zip_strstart - } - zip_strstart++; - zip_lookahead-- - }else { - zip_match_available = 1; - zip_strstart++; - zip_lookahead-- - } - } - while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) { - zip_fill_window() - } - } + this.setSelectedRange = function(range, isForwardSelection) { + cursor.setSelectedRange(range, isForwardSelection); + events.emit(ops.OdtCursor.signalCursorUpdated, self) }; - var zip_ct_init = function() { - var n; - var bits; - var length; - var code; - var dist; - if(zip_static_dtree[0].dl !== 0) { - return - } - zip_l_desc.dyn_tree = zip_dyn_ltree; - zip_l_desc.static_tree = zip_static_ltree; - zip_l_desc.extra_bits = zip_extra_lbits; - zip_l_desc.extra_base = zip_LITERALS + 1; - zip_l_desc.elems = zip_L_CODES; - zip_l_desc.max_length = zip_MAX_BITS; - zip_l_desc.max_code = 0; - zip_d_desc.dyn_tree = zip_dyn_dtree; - zip_d_desc.static_tree = zip_static_dtree; - zip_d_desc.extra_bits = zip_extra_dbits; - zip_d_desc.extra_base = 0; - zip_d_desc.elems = zip_D_CODES; - zip_d_desc.max_length = zip_MAX_BITS; - zip_d_desc.max_code = 0; - zip_bl_desc.dyn_tree = zip_bl_tree; - zip_bl_desc.static_tree = null; - zip_bl_desc.extra_bits = zip_extra_blbits; - zip_bl_desc.extra_base = 0; - zip_bl_desc.elems = zip_BL_CODES; - zip_bl_desc.max_length = zip_MAX_BL_BITS; - zip_bl_desc.max_code = 0; - length = 0; - for(code = 0;code < zip_LENGTH_CODES - 1;code++) { - zip_base_length[code] = length; - for(n = 0;n < 1 << zip_extra_lbits[code];n++) { - zip_length_code[length++] = code - } - } - zip_length_code[length - 1] = code; - dist = 0; - for(code = 0;code < 16;code++) { - zip_base_dist[code] = dist; - for(n = 0;n < 1 << zip_extra_dbits[code];n++) { - zip_dist_code[dist++] = code - } - } - dist >>= 7; - n = code; - for(code = n;code < zip_D_CODES;code++) { - zip_base_dist[code] = dist << 7; - for(n = 0;n < 1 << zip_extra_dbits[code] - 7;n++) { - zip_dist_code[256 + dist++] = code - } - } - for(bits = 0;bits <= zip_MAX_BITS;bits++) { - zip_bl_count[bits] = 0 - } - n = 0; - while(n <= 143) { - zip_static_ltree[n++].dl = 8; - zip_bl_count[8]++ - } - while(n <= 255) { - zip_static_ltree[n++].dl = 9; - zip_bl_count[9]++ - } - while(n <= 279) { - zip_static_ltree[n++].dl = 7; - zip_bl_count[7]++ - } - while(n <= 287) { - zip_static_ltree[n++].dl = 8; - zip_bl_count[8]++ - } - zip_gen_codes(zip_static_ltree, zip_L_CODES + 1); - for(n = 0;n < zip_D_CODES;n++) { - zip_static_dtree[n].dl = 5; - zip_static_dtree[n].fc = zip_bi_reverse(n, 5) - } - zip_init_block() + this.hasForwardSelection = function() { + return cursor.hasForwardSelection() }; - var zip_init_deflate = function() { - if(zip_eofile) { - return - } - zip_bi_buf = 0; - zip_bi_valid = 0; - zip_ct_init(); - zip_lm_init(); - zip_qhead = null; - zip_outcnt = 0; - zip_outoff = 0; - if(zip_compr_level <= 3) { - zip_prev_length = zip_MIN_MATCH - 1; - zip_match_length = 0 - }else { - zip_match_length = zip_MIN_MATCH - 1; - zip_match_available = 0 - } - zip_complete = false + this.getDocument = function() { + return document }; - var zip_qcopy = function(buff, off, buff_size) { - var n, i, j, p; - n = 0; - while(zip_qhead !== null && n < buff_size) { - i = buff_size - n; - if(i > zip_qhead.len) { - i = zip_qhead.len - } - for(j = 0;j < i;j++) { - buff[off + n + j] = zip_qhead.ptr[zip_qhead.off + j] - } - zip_qhead.off += i; - zip_qhead.len -= i; - n += i; - if(zip_qhead.len === 0) { - p = zip_qhead; - zip_qhead = zip_qhead.next; - zip_reuse_queue(p) - } - } - if(n === buff_size) { - return n - } - if(zip_outoff < zip_outcnt) { - i = buff_size - n; - if(i > zip_outcnt - zip_outoff) { - i = zip_outcnt - zip_outoff - } - for(j = 0;j < i;j++) { - buff[off + n + j] = zip_outbuf[zip_outoff + j] - } - zip_outoff += i; - n += i; - if(zip_outcnt === zip_outoff) { - zip_outcnt = zip_outoff = 0 - } - } - return n + this.getSelectionType = function() { + return selectionType }; - var zip_deflate_internal = function(buff, off, buff_size) { - var n; - if(!zip_initflag) { - zip_init_deflate(); - zip_initflag = true; - if(zip_lookahead === 0) { - zip_complete = true; - return 0 - } - } - n = zip_qcopy(buff, off, buff_size); - if(n === buff_size) { - return buff_size - } - if(zip_complete) { - return n - } - if(zip_compr_level <= 3) { - zip_deflate_fast() + this.setSelectionType = function(value) { + if(validSelectionTypes.hasOwnProperty(value)) { + selectionType = value }else { - zip_deflate_better() - } - if(zip_lookahead === 0) { - if(zip_match_available !== 0) { - zip_ct_tally(0, zip_window[zip_strstart - 1] & 255) - } - zip_flush_block(1); - zip_complete = true - } - return n + zip_qcopy(buff, n + off, buff_size - n) - }; - var zip_deflate = function(str, level) { - var i, j; - zip_deflate_data = str; - zip_deflate_pos = 0; - if(String(typeof level) === "undefined") { - level = zip_DEFAULT_LEVEL - } - zip_deflate_start(level); - var buff = new Array(1024); - var aout = [], cbuf = []; - i = zip_deflate_internal(buff, 0, buff.length); - while(i > 0) { - cbuf.length = i; - for(j = 0;j < i;j++) { - cbuf[j] = String.fromCharCode(buff[j]) - } - aout[aout.length] = cbuf.join(""); - i = zip_deflate_internal(buff, 0, buff.length) - } - zip_deflate_data = ""; - return aout.join("") - }; - this.deflate = zip_deflate -}; -runtime.loadClass("odf.Namespaces"); -gui.ImageSelector = function ImageSelector(odfCanvas) { - var svgns = odf.Namespaces.svgns, imageSelectorId = "imageSelector", selectorBorderWidth = 1, squareClassNames = ["topLeft", "topRight", "bottomRight", "bottomLeft", "topMiddle", "rightMiddle", "bottomMiddle", "leftMiddle"], document = odfCanvas.getElement().ownerDocument, hasSelection = false; - function createSelectorElement() { - var sizerElement = odfCanvas.getSizer(), selectorElement, squareElement; - selectorElement = document.createElement("div"); - selectorElement.id = "imageSelector"; - selectorElement.style.borderWidth = selectorBorderWidth + "px"; - sizerElement.appendChild(selectorElement); - squareClassNames.forEach(function(className) { - squareElement = document.createElement("div"); - squareElement.className = className; - selectorElement.appendChild(squareElement) - }); - return selectorElement - } - function getPosition(element, referenceElement) { - var rect = element.getBoundingClientRect(), refRect = referenceElement.getBoundingClientRect(), zoomLevel = odfCanvas.getZoomLevel(); - return{left:(rect.left - refRect.left) / zoomLevel - selectorBorderWidth, top:(rect.top - refRect.top) / zoomLevel - selectorBorderWidth} - } - this.select = function(frameElement) { - var selectorElement = document.getElementById(imageSelectorId), position; - if(!selectorElement) { - selectorElement = createSelectorElement() - } - hasSelection = true; - position = getPosition(frameElement, (selectorElement.parentNode)); - selectorElement.style.display = "block"; - selectorElement.style.left = position.left + "px"; - selectorElement.style.top = position.top + "px"; - selectorElement.style.width = frameElement.getAttributeNS(svgns, "width"); - selectorElement.style.height = frameElement.getAttributeNS(svgns, "height") - }; - this.clearSelection = function() { - var selectorElement; - if(hasSelection) { - selectorElement = document.getElementById(imageSelectorId); - if(selectorElement) { - selectorElement.style.display = "none" - } + runtime.log("Invalid selection type: " + value) } - hasSelection = false }; - this.isSelectorElement = function(node) { - var selectorElement = document.getElementById(imageSelectorId); - if(!selectorElement) { - return false - } - return node === selectorElement || node.parentNode === selectorElement - } -}; -runtime.loadClass("odf.OdfCanvas"); -odf.CommandLineTools = function CommandLineTools() { - this.roundTrip = function(inputfilepath, outputfilepath, callback) { - function onready(odfcontainer) { - if(odfcontainer.state === odf.OdfContainer.INVALID) { - return callback("Document " + inputfilepath + " is invalid.") - } - if(odfcontainer.state === odf.OdfContainer.DONE) { - odfcontainer.saveAs(outputfilepath, function(err) { - callback(err) - }) - }else { - callback("Document was not completely loaded.") - } - } - var odfcontainer = new odf.OdfContainer(inputfilepath, onready); - return odfcontainer + this.resetSelectionType = function() { + self.setSelectionType(ops.OdtCursor.RangeSelection) }; - this.render = function(inputfilepath, document, callback) { - var body = document.getElementsByTagName("body")[0], odfcanvas; - while(body.firstChild) { - body.removeChild(body.firstChild) - } - odfcanvas = new odf.OdfCanvas(body); - odfcanvas.addListener("statereadychange", function(err) { - callback(err) - }); - odfcanvas.load(inputfilepath) - } -}; -/* - - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> - - @licstart - This file is part of WebODF. - - WebODF 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. - - WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. - @licend - - @source: http://www.webodf.org/ - @source: https://github.com/kogmbh/WebODF/ -*/ -ops.Member = function Member(memberId, properties) { - var props = {}; - function getMemberId() { - return memberId - } - function getProperties() { - return props - } - function setProperties(newProperties) { - Object.keys(newProperties).forEach(function(key) { - props[key] = newProperties[key] - }) - } - function removeProperties(removedProperties) { - delete removedProperties.fullName; - delete removedProperties.color; - delete removedProperties.imageUrl; - Object.keys(removedProperties).forEach(function(key) { - if(props.hasOwnProperty(key)) { - delete props[key] - } - }) - } - this.getMemberId = getMemberId; - this.getProperties = getProperties; - this.setProperties = setProperties; - this.removeProperties = removeProperties; function init() { - runtime.assert(Boolean(memberId), "No memberId was supplied!"); - if(!properties.fullName) { - properties.fullName = runtime.tr("Unknown Author") - } - if(!properties.color) { - properties.color = "black" - } - if(!properties.imageUrl) { - properties.imageUrl = "avatar-joe.png" - } - props = properties + cursor = new core.Cursor(document.getDOMDocument(), memberId); + selectionMover = new gui.SelectionMover(cursor, document.getRootNode()); + validSelectionTypes[ops.OdtCursor.RangeSelection] = true; + validSelectionTypes[ops.OdtCursor.RegionSelection] = true; + self.resetSelectionType() } init() }; +ops.OdtCursor.RangeSelection = "Range"; +ops.OdtCursor.RegionSelection = "Region"; +ops.OdtCursor.signalCursorUpdated = "cursorUpdated"; +(function() { + return ops.OdtCursor +})(); /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -10332,26 +9049,52 @@ ops.Member = function Member(memberId, properties) { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils"); -runtime.loadClass("core.PositionFilter"); -runtime.loadClass("odf.OdfUtils"); +ops.Operation = function Operation() { +}; +ops.Operation.prototype.init = function(data) { +}; +ops.Operation.prototype.isEdit; +ops.Operation.prototype.group; +ops.Operation.prototype.execute = function(document) { +}; +ops.Operation.prototype.spec = function() { +}; +/* + + Copyright (C) 2010-2014 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ (function() { - var nextNodeId = 0, PREVIOUS_STEP = 0, NEXT_STEP = 1; - function StepsCache(rootNode, filter, bucketSize) { - var coordinatens = "urn:webodf:names:steps", stepToDomPoint = {}, nodeToBookmark = {}, odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils, basePoint, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT; - function ParagraphBookmark(steps, paragraphNode) { + var nextNodeId = 0; + ops.StepsCache = function StepsCache(rootElement, filter, bucketSize) { + var coordinatens = "urn:webodf:names:steps", stepToDomPoint = {}, nodeToBookmark = {}, odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils, basePoint, lastUndamagedCacheStep, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, verifyCache; + function ParagraphBookmark(nodeId, steps, paragraphNode) { + this.nodeId = nodeId; this.steps = steps; this.node = paragraphNode; - function positionInContainer(node) { - var position = 0; - while(node && node.previousSibling) { - position += 1; - node = node.previousSibling - } - return position - } + this.nextBookmark = null; + this.previousBookmark = null; this.setIteratorPosition = function(iterator) { - iterator.setUnfilteredPosition(paragraphNode.parentNode, positionInContainer(paragraphNode)); + iterator.setPositionBeforeElement(paragraphNode); do { if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { break @@ -10359,9 +9102,12 @@ runtime.loadClass("odf.OdfUtils"); }while(iterator.nextPosition()) } } - function RootBookmark(steps, rootNode) { + function RootBookmark(nodeId, steps, rootNode) { + this.nodeId = nodeId; this.steps = steps; this.node = rootNode; + this.nextBookmark = null; + this.previousBookmark = null; this.setIteratorPosition = function(iterator) { iterator.setUnfilteredPosition(rootNode, 0); do { @@ -10371,6 +9117,47 @@ runtime.loadClass("odf.OdfUtils"); }while(iterator.nextPosition()) } } + function inspectBookmarks(bookmark1, bookmark2) { + var parts = "[" + bookmark1.nodeId; + if(bookmark2) { + parts += " => " + bookmark2.nodeId + } + return parts + "]" + } + function isUndamagedBookmark(bookmark) { + return lastUndamagedCacheStep === undefined || bookmark.steps <= lastUndamagedCacheStep + } + function verifyCacheImpl() { + var bookmark = basePoint, previousBookmark, nextBookmark, documentPosition, loopCheck = new core.LoopWatchDog(0, 1E5); + while(bookmark) { + loopCheck.check(); + previousBookmark = bookmark.previousBookmark; + if(previousBookmark) { + runtime.assert(previousBookmark.nextBookmark === bookmark, "Broken bookmark link to previous @" + inspectBookmarks(previousBookmark, bookmark)) + }else { + runtime.assert(bookmark === basePoint, "Broken bookmark link @" + inspectBookmarks(bookmark)); + runtime.assert(isUndamagedBookmark(basePoint), "Base point is damaged @" + inspectBookmarks(bookmark)) + } + nextBookmark = bookmark.nextBookmark; + if(nextBookmark) { + runtime.assert(nextBookmark.previousBookmark === bookmark, "Broken bookmark link to next @" + inspectBookmarks(bookmark, nextBookmark)) + } + if(isUndamagedBookmark(bookmark)) { + runtime.assert(domUtils.containsNode(rootElement, bookmark.node), "Disconnected node is being reported as undamaged @" + inspectBookmarks(bookmark)); + if(previousBookmark) { + documentPosition = bookmark.node.compareDocumentPosition(previousBookmark.node); + runtime.assert(documentPosition === 0 || (documentPosition & Node.DOCUMENT_POSITION_PRECEDING) !== 0, "Bookmark order with previous does not reflect DOM order @" + inspectBookmarks(previousBookmark, bookmark)) + } + if(nextBookmark) { + if(domUtils.containsNode(rootElement, nextBookmark.node)) { + documentPosition = bookmark.node.compareDocumentPosition(nextBookmark.node); + runtime.assert(documentPosition === 0 || (documentPosition & Node.DOCUMENT_POSITION_FOLLOWING) !== 0, "Bookmark order with next does not reflect DOM order @" + inspectBookmarks(bookmark, nextBookmark)) + } + } + } + bookmark = bookmark.nextBookmark + } + } function getBucket(steps) { return Math.floor(steps / bucketSize) * bucketSize } @@ -10381,11 +9168,15 @@ runtime.loadClass("odf.OdfUtils"); node.removeAttributeNS(coordinatens, "nodeId") } function getNodeId(node) { - return node.nodeType === Node.ELEMENT_NODE && node.getAttributeNS(coordinatens, "nodeId") + var id = ""; + if(node.nodeType === Node.ELEMENT_NODE) { + id = (node).getAttributeNS(coordinatens, "nodeId") + } + return id } function setNodeId(node) { - var nodeId = nextNodeId; - node.setAttributeNS(coordinatens, "nodeId", nodeId.toString()); + var nodeId = nextNodeId.toString(); + node.setAttributeNS(coordinatens, "nodeId", nodeId); nextNodeId += 1; return nodeId } @@ -10396,159 +9187,258 @@ runtime.loadClass("odf.OdfUtils"); var nodeId = getNodeId(node) || setNodeId(node), existingBookmark; existingBookmark = nodeToBookmark[nodeId]; if(!existingBookmark) { - existingBookmark = nodeToBookmark[nodeId] = new ParagraphBookmark(steps, node) + existingBookmark = nodeToBookmark[nodeId] = new ParagraphBookmark(nodeId, steps, node) }else { if(!isValidBookmarkForNode(node, existingBookmark)) { runtime.log("Cloned node detected. Creating new bookmark"); nodeId = setNodeId(node); - existingBookmark = nodeToBookmark[nodeId] = new ParagraphBookmark(steps, node) + existingBookmark = nodeToBookmark[nodeId] = new ParagraphBookmark(nodeId, steps, node) }else { existingBookmark.steps = steps } } return existingBookmark } - function isFirstPositionInParagraph(node, offset) { - return offset === 0 && odfUtils.isParagraph(node) + function getClosestBookmark(steps) { + var cacheBucket, cachePoint, loopGuard = new core.LoopWatchDog(0, 1E4); + if(lastUndamagedCacheStep !== undefined && steps > lastUndamagedCacheStep) { + steps = lastUndamagedCacheStep + } + cacheBucket = getBucket(steps); + while(!cachePoint && cacheBucket !== 0) { + cachePoint = stepToDomPoint[cacheBucket]; + cacheBucket -= bucketSize + } + cachePoint = cachePoint || basePoint; + while(cachePoint.nextBookmark && cachePoint.nextBookmark.steps <= steps) { + loopGuard.check(); + cachePoint = cachePoint.nextBookmark + } + return cachePoint } - this.updateCache = function(steps, node, offset, isWalkable) { - var stablePoint, cacheBucket, existingCachePoint, bookmark; - if(isFirstPositionInParagraph(node, offset)) { - stablePoint = true; - if(!isWalkable) { - steps += 1 - } - }else { - if(node.hasChildNodes() && node.childNodes[offset]) { - node = node.childNodes[offset]; - offset = 0; - stablePoint = isFirstPositionInParagraph(node, offset); - if(stablePoint) { - steps += 1 + function getUndamagedBookmark(bookmark) { + if(lastUndamagedCacheStep !== undefined && bookmark.steps > lastUndamagedCacheStep) { + bookmark = getClosestBookmark(lastUndamagedCacheStep) + } + return bookmark + } + function removeBookmark(currentBookmark) { + if(currentBookmark.previousBookmark) { + currentBookmark.previousBookmark.nextBookmark = currentBookmark.nextBookmark + } + if(currentBookmark.nextBookmark) { + currentBookmark.nextBookmark.previousBookmark = currentBookmark.previousBookmark + } + } + function insertBookmark(previousBookmark, newBookmark) { + var nextBookmark; + if(previousBookmark !== newBookmark && previousBookmark.nextBookmark !== newBookmark) { + removeBookmark(newBookmark); + nextBookmark = previousBookmark.nextBookmark; + newBookmark.nextBookmark = previousBookmark.nextBookmark; + newBookmark.previousBookmark = previousBookmark; + previousBookmark.nextBookmark = newBookmark; + if(nextBookmark) { + nextBookmark.previousBookmark = newBookmark + } + } + } + function repairCacheUpToStep(currentIteratorStep) { + var damagedBookmark, undamagedBookmark, nextBookmark, stepsBucket; + if(lastUndamagedCacheStep !== undefined && lastUndamagedCacheStep < currentIteratorStep) { + undamagedBookmark = getClosestBookmark(lastUndamagedCacheStep); + damagedBookmark = undamagedBookmark.nextBookmark; + while(damagedBookmark && damagedBookmark.steps <= currentIteratorStep) { + nextBookmark = damagedBookmark.nextBookmark; + stepsBucket = getDestinationBucket(damagedBookmark.steps); + if(stepToDomPoint[stepsBucket] === damagedBookmark) { + delete stepToDomPoint[stepsBucket] } + if(!domUtils.containsNode(rootElement, damagedBookmark.node)) { + removeBookmark(damagedBookmark); + delete nodeToBookmark[damagedBookmark.nodeId] + }else { + damagedBookmark.steps = currentIteratorStep + 1 + } + damagedBookmark = nextBookmark } + lastUndamagedCacheStep = currentIteratorStep + }else { + undamagedBookmark = getClosestBookmark(currentIteratorStep) } - if(stablePoint) { - bookmark = getNodeBookmark(node, steps); + return undamagedBookmark + } + this.updateCache = function(steps, iterator, isStep) { + var cacheBucket, existingCachePoint, bookmark, closestPriorBookmark, node = iterator.getCurrentNode(); + if(iterator.isBeforeNode() && odfUtils.isParagraph(node)) { + if(!isStep) { + steps += 1 + } + closestPriorBookmark = repairCacheUpToStep(steps); + bookmark = getNodeBookmark((node), steps); + insertBookmark(closestPriorBookmark, bookmark); cacheBucket = getDestinationBucket(bookmark.steps); existingCachePoint = stepToDomPoint[cacheBucket]; if(!existingCachePoint || bookmark.steps > existingCachePoint.steps) { stepToDomPoint[cacheBucket] = bookmark } + verifyCache() } }; this.setToClosestStep = function(steps, iterator) { - var cacheBucket = getBucket(steps), cachePoint; - while(!cachePoint && cacheBucket !== 0) { - cachePoint = stepToDomPoint[cacheBucket]; - cacheBucket -= bucketSize - } - cachePoint = cachePoint || basePoint; + var cachePoint; + verifyCache(); + cachePoint = getClosestBookmark(steps); cachePoint.setIteratorPosition(iterator); return cachePoint.steps }; - function findBookmarkedAncestor(node, offset) { - var nodeId, bookmark = null; - node = node.childNodes[offset] || node; - while(!bookmark && (node && node !== rootNode)) { - nodeId = getNodeId(node); + function findBookmarkedAncestor(node) { + var currentNode = node, nodeId, bookmark = null; + while(!bookmark && (currentNode && currentNode !== rootElement)) { + nodeId = getNodeId(currentNode); if(nodeId) { bookmark = nodeToBookmark[nodeId]; - if(bookmark && !isValidBookmarkForNode(node, bookmark)) { + if(bookmark && !isValidBookmarkForNode(currentNode, bookmark)) { runtime.log("Cloned node detected. Creating new bookmark"); bookmark = null; - clearNodeId(node) + clearNodeId((currentNode)) } } - node = node.parentNode + currentNode = currentNode.parentNode } return bookmark } this.setToClosestDomPoint = function(node, offset, iterator) { - var bookmark; - if(node === rootNode && offset === 0) { + var bookmark, b, key; + verifyCache(); + if(node === rootElement && offset === 0) { bookmark = basePoint }else { - if(node === rootNode && offset === rootNode.childNodes.length) { - bookmark = Object.keys(stepToDomPoint).map(function(cacheBucket) { - return stepToDomPoint[cacheBucket] - }).reduce(function(largestBookmark, bookmark) { - return bookmark.steps > largestBookmark.steps ? bookmark : largestBookmark - }, basePoint) + if(node === rootElement && offset === rootElement.childNodes.length) { + bookmark = basePoint; + for(key in stepToDomPoint) { + if(stepToDomPoint.hasOwnProperty(key)) { + b = stepToDomPoint[key]; + if(b.steps > bookmark.steps) { + bookmark = b + } + } + } }else { - bookmark = findBookmarkedAncestor(node, offset); + bookmark = findBookmarkedAncestor(node.childNodes.item(offset) || node); if(!bookmark) { iterator.setUnfilteredPosition(node, offset); while(!bookmark && iterator.previousNode()) { - bookmark = findBookmarkedAncestor(iterator.container(), iterator.unfilteredDomOffset()) + bookmark = findBookmarkedAncestor(iterator.getCurrentNode()) } } } } - bookmark = bookmark || basePoint; + bookmark = getUndamagedBookmark(bookmark || basePoint); bookmark.setIteratorPosition(iterator); return bookmark.steps }; - this.updateCacheAtPoint = function(inflectionStep, doUpdate) { - var affectedBookmarks, updatedBuckets = {}; - affectedBookmarks = Object.keys(nodeToBookmark).map(function(nodeId) { - return nodeToBookmark[nodeId] - }).filter(function(bookmark) { - return bookmark.steps > inflectionStep - }); - affectedBookmarks.forEach(function(bookmark) { - var originalCacheBucket = getDestinationBucket(bookmark.steps), newCacheBucket, existingBookmark; - if(domUtils.containsNode(rootNode, bookmark.node)) { - doUpdate(bookmark); - newCacheBucket = getDestinationBucket(bookmark.steps); - existingBookmark = updatedBuckets[newCacheBucket]; - if(!existingBookmark || bookmark.steps > existingBookmark.steps) { - updatedBuckets[newCacheBucket] = bookmark - } - }else { - delete nodeToBookmark[getNodeId(bookmark.node)] - } - if(stepToDomPoint[originalCacheBucket] === bookmark) { - delete stepToDomPoint[originalCacheBucket] + this.damageCacheAfterStep = function(inflectionStep) { + if(inflectionStep < 0) { + inflectionStep = 0 + } + if(lastUndamagedCacheStep === undefined) { + lastUndamagedCacheStep = inflectionStep + }else { + if(inflectionStep < lastUndamagedCacheStep) { + lastUndamagedCacheStep = inflectionStep } - }); - Object.keys(updatedBuckets).forEach(function(cacheBucket) { - stepToDomPoint[cacheBucket] = updatedBuckets[cacheBucket] - }) + } + verifyCache() }; function init() { - basePoint = new RootBookmark(0, rootNode) + var rootElementId = getNodeId(rootElement) || setNodeId(rootElement); + basePoint = new RootBookmark(rootElementId, 0, rootElement); + verifyCache = ops.StepsCache.ENABLE_CACHE_VERIFICATION ? verifyCacheImpl : function() { + } } init() + }; + ops.StepsCache.ENABLE_CACHE_VERIFICATION = false; + ops.StepsCache.Bookmark = function Bookmark() { + }; + ops.StepsCache.Bookmark.prototype.nodeId; + ops.StepsCache.Bookmark.prototype.node; + ops.StepsCache.Bookmark.prototype.steps; + ops.StepsCache.Bookmark.prototype.previousBookmark; + ops.StepsCache.Bookmark.prototype.nextBookmark; + ops.StepsCache.Bookmark.prototype.setIteratorPosition = function(iterator) { } +})(); +/* + + Copyright (C) 2012-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() { + var PREVIOUS_STEP = 0, NEXT_STEP = 1; ops.StepsTranslator = function StepsTranslator(getRootNode, newIterator, filter, bucketSize) { - var rootNode = getRootNode(), stepsCache = new StepsCache(rootNode, filter, bucketSize), domUtils = new core.DomUtils, iterator = newIterator(getRootNode()), FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT; + var rootNode = getRootNode(), stepsCache = new ops.StepsCache(rootNode, filter, bucketSize), domUtils = new core.DomUtils, iterator = newIterator(getRootNode()), FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT; function verifyRootNode() { var currentRootNode = getRootNode(); if(currentRootNode !== rootNode) { runtime.log("Undo detected. Resetting steps cache"); rootNode = currentRootNode; - stepsCache = new StepsCache(rootNode, filter, bucketSize); + stepsCache = new ops.StepsCache(rootNode, filter, bucketSize); iterator = newIterator(rootNode) } } this.convertStepsToDomPoint = function(steps) { - var stepsFromRoot, isWalkable; + var stepsFromRoot, isStep; + if(isNaN(steps)) { + throw new TypeError("Requested steps is not numeric (" + steps + ")"); + } if(steps < 0) { - runtime.log("warn", "Requested steps were negative (" + steps + ")"); - steps = 0 + throw new RangeError("Requested steps is negative (" + steps + ")"); } verifyRootNode(); stepsFromRoot = stepsCache.setToClosestStep(steps, iterator); while(stepsFromRoot < steps && iterator.nextPosition()) { - isWalkable = filter.acceptPosition(iterator) === FILTER_ACCEPT; - if(isWalkable) { + isStep = filter.acceptPosition(iterator) === FILTER_ACCEPT; + if(isStep) { stepsFromRoot += 1 } - stepsCache.updateCache(stepsFromRoot, iterator.container(), iterator.unfilteredDomOffset(), isWalkable) + stepsCache.updateCache(stepsFromRoot, iterator, isStep) } if(stepsFromRoot !== steps) { - runtime.log("warn", "Requested " + steps + " steps but only " + stepsFromRoot + " are available") + throw new RangeError("Requested steps (" + steps + ") exceeds available steps (" + stepsFromRoot + ")"); } return{node:iterator.container(), offset:iterator.unfilteredDomOffset()} }; @@ -10575,12 +9465,12 @@ runtime.loadClass("odf.OdfUtils"); return false } this.convertDomPointToSteps = function(node, offset, roundDirection) { - var stepsFromRoot, beforeRoot, destinationNode, destinationOffset, rounding = 0, isWalkable; + var stepsFromRoot, beforeRoot, destinationNode, destinationOffset, rounding = 0, isStep; verifyRootNode(); if(!domUtils.containsNode(rootNode, node)) { beforeRoot = domUtils.comparePoints(rootNode, 0, node, offset) < 0; - node = rootNode; - offset = beforeRoot ? 0 : rootNode.childNodes.length + node = (rootNode); + offset = beforeRoot ? 0 : (rootNode).childNodes.length } iterator.setUnfilteredPosition(node, offset); if(!roundToPreferredStep(iterator, roundDirection)) { @@ -10593,448 +9483,163 @@ runtime.loadClass("odf.OdfUtils"); return stepsFromRoot > 0 ? stepsFromRoot - 1 : stepsFromRoot } while(!(iterator.container() === destinationNode && iterator.unfilteredDomOffset() === destinationOffset) && iterator.nextPosition()) { - isWalkable = filter.acceptPosition(iterator) === FILTER_ACCEPT; - if(isWalkable) { + isStep = filter.acceptPosition(iterator) === FILTER_ACCEPT; + if(isStep) { stepsFromRoot += 1 } - stepsCache.updateCache(stepsFromRoot, iterator.container(), iterator.unfilteredDomOffset(), isWalkable) + stepsCache.updateCache(stepsFromRoot, iterator, isStep) } return stepsFromRoot + rounding }; this.prime = function() { - var stepsFromRoot, isWalkable; + var stepsFromRoot, isStep; verifyRootNode(); stepsFromRoot = stepsCache.setToClosestStep(0, iterator); while(iterator.nextPosition()) { - isWalkable = filter.acceptPosition(iterator) === FILTER_ACCEPT; - if(isWalkable) { + isStep = filter.acceptPosition(iterator) === FILTER_ACCEPT; + if(isStep) { stepsFromRoot += 1 } - stepsCache.updateCache(stepsFromRoot, iterator.container(), iterator.unfilteredDomOffset(), isWalkable) + stepsCache.updateCache(stepsFromRoot, iterator, isStep) } }; this.handleStepsInserted = function(eventArgs) { verifyRootNode(); - stepsCache.updateCacheAtPoint(eventArgs.position, function(bucket) { - bucket.steps += eventArgs.length - }) + stepsCache.damageCacheAfterStep(eventArgs.position) }; this.handleStepsRemoved = function(eventArgs) { verifyRootNode(); - stepsCache.updateCacheAtPoint(eventArgs.position, function(bucket) { - bucket.steps -= eventArgs.length; - if(bucket.steps < 0) { - bucket.steps = 0 - } - }) + stepsCache.damageCacheAfterStep(eventArgs.position - 1) } }; ops.StepsTranslator.PREVIOUS_STEP = PREVIOUS_STEP; ops.StepsTranslator.NEXT_STEP = NEXT_STEP; return ops.StepsTranslator })(); -xmldom.RNG = {}; -xmldom.RNG.Name; -xmldom.RNG.Attr; -xmldom.RNG.Element; -xmldom.RelaxNGParser = function RelaxNGParser() { - var self = this, rngns = "http://relaxng.org/ns/structure/1.0", xmlnsns = "http://www.w3.org/2000/xmlns/", start, nsmap = {"http://www.w3.org/XML/1998/namespace":"xml"}, parse; - function RelaxNGParseError(error, context) { - this.message = function() { - if(context) { - error += context.nodeType === 1 ? " Element " : " Node "; - error += context.nodeName; - if(context.nodeValue) { - error += " with value '" + context.nodeValue + "'" - } - error += "." - } - return error - } - } - function splitToDuos(e) { - if(e.e.length <= 2) { - return e - } - var o = {name:e.name, e:e.e.slice(0, 2)}; - return splitToDuos({name:e.name, e:[o].concat(e.e.slice(2))}) - } - function splitQName(name) { - var r = name.split(":", 2), prefix = "", i; - if(r.length === 1) { - r = ["", r[0]] - }else { - prefix = r[0] - } - for(i in nsmap) { - if(nsmap[i] === prefix) { - r[0] = i - } - } - return r - } - function splitQNames(def) { - var i, l = def.names ? def.names.length : 0, name, localnames = [], namespaces = []; - for(i = 0;i < l;i += 1) { - name = splitQName(def.names[i]); - namespaces[i] = name[0]; - localnames[i] = name[1] - } - def.localnames = localnames; - def.namespaces = namespaces - } - function trim(str) { - str = str.replace(/^\s\s*/, ""); - var ws = /\s/, i = str.length - 1; - while(ws.test(str.charAt(i))) { - i -= 1 - } - return str.slice(0, i + 1) - } - function copyAttributes(atts, name, names) { - var a = {}, i, att; - for(i = 0;atts && i < atts.length;i += 1) { - att = (atts.item(i)); - if(!att.namespaceURI) { - if(att.localName === "name" && (name === "element" || name === "attribute")) { - names.push(att.value) - } - if(att.localName === "name" || (att.localName === "combine" || att.localName === "type")) { - att.value = trim(att.value) - } - a[att.localName] = att.value - }else { - if(att.namespaceURI === xmlnsns) { - nsmap[att.value] = att.localName - } - } - } - return a - } - function parseChildren(c, e, elements, names) { - var text = "", ce; - while(c) { - if(c.nodeType === Node.ELEMENT_NODE && c.namespaceURI === rngns) { - ce = parse((c), elements, e); - if(ce) { - if(ce.name === "name") { - names.push(nsmap[ce.a.ns] + ":" + ce.text); - e.push(ce) - }else { - if(ce.name === "choice" && (ce.names && ce.names.length)) { - names = names.concat(ce.names); - delete ce.names; - e.push(ce) - }else { - e.push(ce) - } - } - } - }else { - if(c.nodeType === Node.TEXT_NODE) { - text += c.nodeValue - } - } - c = c.nextSibling - } - return text - } - function combineDefines(combine, name, e, siblings) { - var i, ce; - for(i = 0;siblings && i < siblings.length;i += 1) { - ce = siblings[i]; - if(ce.name === "define" && (ce.a && ce.a.name === name)) { - ce.e = [{name:combine, e:ce.e.concat(e)}]; - return ce - } - } - return null - } - parse = function parse(element, elements, siblings) { - var e = [], a, ce, i, text, name = element.localName, names = []; - a = copyAttributes(element.attributes, name, names); - a.combine = a.combine || undefined; - text = parseChildren(element.firstChild, e, elements, names); - if(name !== "value" && name !== "param") { - text = /^\s*([\s\S]*\S)?\s*$/.exec(text)[1] - } - if(name === "value" && a.type === undefined) { - a.type = "token"; - a.datatypeLibrary = "" - } - if((name === "attribute" || name === "element") && a.name !== undefined) { - i = splitQName(a.name); - e = [{name:"name", text:i[1], a:{ns:i[0]}}].concat(e); - delete a.name - } - if(name === "name" || (name === "nsName" || name === "value")) { - if(a.ns === undefined) { - a.ns = "" +/* + + Copyright (C) 2012-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/ +*/ +ops.TextPositionFilter = function TextPositionFilter(getRootNode) { + var odfUtils = new odf.OdfUtils, ELEMENT_NODE = Node.ELEMENT_NODE, TEXT_NODE = Node.TEXT_NODE, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT; + function checkLeftRight(container, leftNode, rightNode) { + var r, firstPos, rightOfChar; + if(leftNode) { + if(odfUtils.isInlineRoot(leftNode) && odfUtils.isGroupingElement(rightNode)) { + return FILTER_REJECT } - }else { - delete a.ns - } - if(name === "name") { - i = splitQName(text); - a.ns = i[0]; - text = i[1] - } - if(e.length > 1 && (name === "define" || (name === "oneOrMore" || (name === "zeroOrMore" || (name === "optional" || (name === "list" || name === "mixed")))))) { - e = [{name:"group", e:splitToDuos({name:"group", e:e}).e}] - } - if(e.length > 2 && name === "element") { - e = [e[0]].concat({name:"group", e:splitToDuos({name:"group", e:e.slice(1)}).e}) - } - if(e.length === 1 && name === "attribute") { - e.push({name:"text", text:text}) - } - if(e.length === 1 && (name === "choice" || (name === "group" || name === "interleave"))) { - name = e[0].name; - names = e[0].names; - a = e[0].a; - text = e[0].text; - e = e[0].e - }else { - if(e.length > 2 && (name === "choice" || (name === "group" || name === "interleave"))) { - e = splitToDuos({name:name, e:e}).e + r = odfUtils.lookLeftForCharacter(leftNode); + if(r === 1) { + return FILTER_ACCEPT } - } - if(name === "mixed") { - name = "interleave"; - e = [e[0], {name:"text"}] - } - if(name === "optional") { - name = "choice"; - e = [e[0], {name:"empty"}] - } - if(name === "zeroOrMore") { - name = "choice"; - e = [{name:"oneOrMore", e:[e[0]]}, {name:"empty"}] - } - if(name === "define" && a.combine) { - ce = combineDefines(a.combine, a.name, e, siblings); - if(ce) { - return null + if(r === 2 && (odfUtils.scanRightForAnyCharacter(rightNode) || odfUtils.scanRightForAnyCharacter(odfUtils.nextNode(container)))) { + return FILTER_ACCEPT } } - ce = {name:name}; - if(e && e.length > 0) { - ce.e = e - } - for(i in a) { - if(a.hasOwnProperty(i)) { - ce.a = a; - break + firstPos = leftNode === null && odfUtils.isParagraph(container); + rightOfChar = odfUtils.lookRightForCharacter(rightNode); + if(firstPos) { + if(rightOfChar) { + return FILTER_ACCEPT } + return odfUtils.scanRightForAnyCharacter(rightNode) ? FILTER_REJECT : FILTER_ACCEPT } - if(text !== undefined) { - ce.text = text - } - if(names && names.length > 0) { - ce.names = names - } - if(name === "element") { - ce.id = elements.length; - elements.push(ce); - ce = {name:"elementref", id:ce.id} + if(!rightOfChar) { + return FILTER_REJECT } - return ce - }; - function resolveDefines(def, defines) { - var i = 0, e, defs, end, name = def.name; - while(def.e && i < def.e.length) { - e = def.e[i]; - if(e.name === "ref") { - defs = defines[e.a.name]; - if(!defs) { - throw e.a.name + " was not defined."; - } - end = def.e.slice(i + 1); - def.e = def.e.slice(0, i); - def.e = def.e.concat(defs.e); - def.e = def.e.concat(end) - }else { - i += 1; - resolveDefines(e, defines) - } + leftNode = leftNode || odfUtils.previousNode(container); + return odfUtils.scanLeftForAnyCharacter(leftNode) ? FILTER_REJECT : FILTER_ACCEPT + } + this.acceptPosition = function(iterator) { + var container = iterator.container(), nodeType = container.nodeType, offset, text, leftChar, rightChar, leftNode, rightNode, r; + if(nodeType !== ELEMENT_NODE && nodeType !== TEXT_NODE) { + return FILTER_REJECT } - e = def.e; - if(name === "choice") { - if(!e || (!e[1] || e[1].name === "empty")) { - if(!e || (!e[0] || e[0].name === "empty")) { - delete def.e; - def.name = "empty" - }else { - e[1] = e[0]; - e[0] = {name:"empty"} - } + if(nodeType === TEXT_NODE) { + if(!odfUtils.isGroupingElement(container.parentNode) || odfUtils.isWithinTrackedChanges(container.parentNode, getRootNode())) { + return FILTER_REJECT } - } - if(name === "group" || name === "interleave") { - if(e[0].name === "empty") { - if(e[1].name === "empty") { - delete def.e; - def.name = "empty" - }else { - name = def.name = e[1].name; - def.names = e[1].names; - e = def.e = e[1].e - } - }else { - if(e[1].name === "empty") { - name = def.name = e[0].name; - def.names = e[0].names; - e = def.e = e[0].e + offset = iterator.unfilteredDomOffset(); + text = container.data; + runtime.assert(offset !== text.length, "Unexpected offset."); + if(offset > 0) { + leftChar = (text[offset - 1]); + if(!odfUtils.isODFWhitespace(leftChar)) { + return FILTER_ACCEPT } - } - } - if(name === "oneOrMore" && e[0].name === "empty") { - delete def.e; - def.name = "empty" - } - if(name === "attribute") { - splitQNames(def) - } - if(name === "interleave") { - if(e[0].name === "interleave") { - if(e[1].name === "interleave") { - e = def.e = e[0].e.concat(e[1].e) + if(offset > 1) { + leftChar = (text[offset - 2]); + if(!odfUtils.isODFWhitespace(leftChar)) { + r = FILTER_ACCEPT + }else { + if(!odfUtils.isODFWhitespace(text.substr(0, offset))) { + return FILTER_REJECT + } + } }else { - e = def.e = [e[1]].concat(e[0].e) - } - }else { - if(e[1].name === "interleave") { - e = def.e = [e[0]].concat(e[1].e) + leftNode = odfUtils.previousNode(container); + if(odfUtils.scanLeftForNonSpace(leftNode)) { + r = FILTER_ACCEPT + } } - } - } - } - function resolveElements(def, elements) { - var i = 0, e; - while(def.e && i < def.e.length) { - e = def.e[i]; - if(e.name === "elementref") { - e.id = e.id || 0; - def.e[i] = elements[e.id] - }else { - if(e.name !== "element") { - resolveElements(e, elements) + if(r === FILTER_ACCEPT) { + return odfUtils.isTrailingWhitespace((container), offset) ? FILTER_REJECT : FILTER_ACCEPT } - } - i += 1 - } - } - function main(dom, callback) { - var elements = [], grammar = parse(dom && dom.documentElement, elements, undefined), i, e, defines = {}; - for(i = 0;i < grammar.e.length;i += 1) { - e = grammar.e[i]; - if(e.name === "define") { - defines[e.a.name] = e - }else { - if(e.name === "start") { - start = e + rightChar = (text[offset]); + if(odfUtils.isODFWhitespace(rightChar)) { + return FILTER_REJECT } + return odfUtils.scanLeftForAnyCharacter(odfUtils.previousNode(container)) ? FILTER_REJECT : FILTER_ACCEPT } - } - if(!start) { - return[new RelaxNGParseError("No Relax NG start element was found.")] - } - resolveDefines(start, defines); - for(i in defines) { - if(defines.hasOwnProperty(i)) { - resolveDefines(defines[i], defines) - } - } - for(i = 0;i < elements.length;i += 1) { - resolveDefines(elements[i], defines) - } - if(callback) { - self.rootPattern = callback(start.e[0], elements) - } - resolveElements(start, elements); - for(i = 0;i < elements.length;i += 1) { - resolveElements(elements[i], elements) - } - self.start = start; - self.elements = elements; - self.nsmap = nsmap; - return null - } - this.parseRelaxNGDOM = main -}; -runtime.loadClass("core.Cursor"); -runtime.loadClass("gui.SelectionMover"); -ops.OdtCursor = function OdtCursor(memberId, odtDocument) { - var self = this, validSelectionTypes = {}, selectionType, selectionMover, cursor; - this.removeFromOdtDocument = function() { - cursor.remove() - }; - this.move = function(number, extend) { - var moved = 0; - if(number > 0) { - moved = selectionMover.movePointForward(number, extend) + leftNode = iterator.leftNode(); + rightNode = container; + container = (container.parentNode); + r = checkLeftRight(container, leftNode, rightNode) }else { - if(number <= 0) { - moved = -selectionMover.movePointBackward(-number, extend) + if(!odfUtils.isGroupingElement(container) || odfUtils.isWithinTrackedChanges(container, getRootNode())) { + r = FILTER_REJECT + }else { + leftNode = iterator.leftNode(); + rightNode = iterator.rightNode(); + r = checkLeftRight(container, leftNode, rightNode) } } - self.handleUpdate(); - return moved - }; - this.handleUpdate = function() { - }; - this.getStepCounter = function() { - return selectionMover.getStepCounter() - }; - this.getMemberId = function() { - return memberId - }; - this.getNode = function() { - return cursor.getNode() - }; - this.getAnchorNode = function() { - return cursor.getAnchorNode() - }; - this.getSelectedRange = function() { - return cursor.getSelectedRange() - }; - this.setSelectedRange = function(range, isForwardSelection) { - cursor.setSelectedRange(range, isForwardSelection); - self.handleUpdate() - }; - this.hasForwardSelection = function() { - return cursor.hasForwardSelection() - }; - this.getOdtDocument = function() { - return odtDocument - }; - this.getSelectionType = function() { - return selectionType - }; - this.setSelectionType = function(value) { - if(validSelectionTypes.hasOwnProperty(value)) { - selectionType = value - }else { - runtime.log("Invalid selection type: " + value) - } - }; - this.resetSelectionType = function() { - self.setSelectionType(ops.OdtCursor.RangeSelection) - }; - function init() { - cursor = new core.Cursor(odtDocument.getDOM(), memberId); - selectionMover = new gui.SelectionMover(cursor, odtDocument.getRootNode()); - validSelectionTypes[ops.OdtCursor.RangeSelection] = true; - validSelectionTypes[ops.OdtCursor.RegionSelection] = true; - self.resetSelectionType() + return r } - init() }; -ops.OdtCursor.RangeSelection = "Range"; -ops.OdtCursor.RegionSelection = "Region"; -(function() { - return ops.OdtCursor -})(); /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -11072,27 +9677,39 @@ ops.OdtCursor.RegionSelection = "Region"; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.EventNotifier"); -runtime.loadClass("core.DomUtils"); -runtime.loadClass("odf.OdfUtils"); -runtime.loadClass("odf.Namespaces"); -runtime.loadClass("gui.SelectionMover"); -runtime.loadClass("core.PositionFilterChain"); -runtime.loadClass("ops.StepsTranslator"); -runtime.loadClass("ops.TextPositionFilter"); -runtime.loadClass("ops.Member"); ops.OdtDocument = function OdtDocument(odfCanvas) { - var self = this, odfUtils, domUtils, cursors = {}, members = {}, eventNotifier = new core.EventNotifier([ops.OdtDocument.signalMemberAdded, ops.OdtDocument.signalMemberUpdated, ops.OdtDocument.signalMemberRemoved, ops.OdtDocument.signalCursorAdded, ops.OdtDocument.signalCursorRemoved, ops.OdtDocument.signalCursorMoved, ops.OdtDocument.signalParagraphChanged, ops.OdtDocument.signalParagraphStyleModified, ops.OdtDocument.signalCommonStyleCreated, ops.OdtDocument.signalCommonStyleDeleted, ops.OdtDocument.signalTableAdded, - ops.OdtDocument.signalOperationExecuted, ops.OdtDocument.signalUndoStackChanged, ops.OdtDocument.signalStepsInserted, ops.OdtDocument.signalStepsRemoved]), FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT, filter, stepsTranslator, lastEditingOp, unsupportedMetadataRemoved = false; + var self = this, odfUtils, domUtils, cursors = {}, members = {}, eventNotifier = new core.EventNotifier([ops.Document.signalMemberAdded, ops.Document.signalMemberUpdated, ops.Document.signalMemberRemoved, ops.Document.signalCursorAdded, ops.Document.signalCursorRemoved, ops.Document.signalCursorMoved, ops.OdtDocument.signalParagraphChanged, ops.OdtDocument.signalParagraphStyleModified, ops.OdtDocument.signalCommonStyleCreated, ops.OdtDocument.signalCommonStyleDeleted, ops.OdtDocument.signalTableAdded, + ops.OdtDocument.signalOperationStart, ops.OdtDocument.signalOperationEnd, ops.OdtDocument.signalProcessingBatchStart, ops.OdtDocument.signalProcessingBatchEnd, ops.OdtDocument.signalUndoStackChanged, ops.OdtDocument.signalStepsInserted, ops.OdtDocument.signalStepsRemoved]), FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT, filter, stepsTranslator, lastEditingOp, unsupportedMetadataRemoved = false; function getRootNode() { var element = odfCanvas.odfContainer().getContentElement(), localName = element && element.localName; runtime.assert(localName === "text", "Unsupported content element type '" + localName + "' for OdtDocument"); return element } - function getDOM() { - return(getRootNode().ownerDocument) + this.getDocumentElement = function() { + return odfCanvas.odfContainer().rootElement + }; + this.getDOMDocument = function() { + return(this.getDocumentElement().ownerDocument) + }; + this.cloneDocumentElement = function() { + var rootElement = self.getDocumentElement(), annotationViewManager = odfCanvas.getAnnotationViewManager(), initialDoc; + if(annotationViewManager) { + annotationViewManager.forgetAnnotations() + } + initialDoc = rootElement.cloneNode(true); + odfCanvas.refreshAnnotations(); + return initialDoc + }; + this.setDocumentElement = function(documentElement) { + var odfContainer = odfCanvas.odfContainer(); + odfContainer.setRootElement(documentElement); + odfCanvas.setOdfContainer(odfContainer, true); + odfCanvas.refreshCSS() + }; + function getDOMDocument() { + return(self.getDocumentElement().ownerDocument) } - this.getDOM = getDOM; + this.getDOMDocument = getDOMDocument; function isRoot(node) { if(node.namespaceURI === odf.Namespaces.officens && node.localName === "text" || node.namespaceURI === odf.Namespaces.officens && node.localName === "annotation") { return true @@ -11120,6 +9737,19 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { return FILTER_REJECT } } + function createStepIterator(container, offset, filters, subTree) { + var positionIterator = gui.SelectionMover.createPositionIterator(subTree), filterOrChain, stepIterator; + if(filters.length === 1) { + filterOrChain = filters[0] + }else { + filterOrChain = new core.PositionFilterChain; + filters.forEach(filterOrChain.addFilter) + } + stepIterator = new core.StepIterator(filterOrChain, positionIterator); + stepIterator.setPosition(container, offset); + return stepIterator + } + this.createStepIterator = createStepIterator; function getIteratorAtPosition(position) { var iterator = gui.SelectionMover.createPositionIterator(getRootNode()), point = stepsTranslator.convertStepsToDomPoint(position); iterator.setUnfilteredPosition(point.node, point.offset); @@ -11130,18 +9760,18 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { return stepsTranslator.convertDomPointToSteps(node, offset, roundDirection) }; this.convertDomToCursorRange = function(selection, constraint) { - var point1, point2, anchorConstraint = constraint(selection.anchorNode, selection.anchorOffset), focusConstraint; + var point1, point2, anchorConstraint = constraint && constraint(selection.anchorNode, selection.anchorOffset), focusConstraint; point1 = stepsTranslator.convertDomPointToSteps(selection.anchorNode, selection.anchorOffset, anchorConstraint); if(!constraint && (selection.anchorNode === selection.focusNode && selection.anchorOffset === selection.focusOffset)) { point2 = point1 }else { - focusConstraint = constraint(selection.focusNode, selection.focusOffset); + focusConstraint = constraint && constraint(selection.focusNode, selection.focusOffset); point2 = stepsTranslator.convertDomPointToSteps(selection.focusNode, selection.focusOffset, focusConstraint) } return{position:point1, length:point2 - point1} }; this.convertCursorToDomRange = function(position, length) { - var range = getDOM().createRange(), point1, point2; + var range = getDOMDocument().createRange(), point1, point2; point1 = stepsTranslator.convertStepsToDomPoint(position); if(length) { point2 = stepsTranslator.convertStepsToDomPoint(position + length); @@ -11158,7 +9788,7 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { return range }; function getTextNodeAtStep(steps, memberid) { - var iterator = getIteratorAtPosition(steps), node = iterator.container(), lastTextNode, nodeOffset = 0, cursorNode = null; + var iterator = getIteratorAtPosition(steps), node = iterator.container(), lastTextNode, nodeOffset = 0, cursorNode = null, text; if(node.nodeType === Node.TEXT_NODE) { lastTextNode = (node); nodeOffset = (iterator.unfilteredDomOffset()); @@ -11166,12 +9796,12 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { if(nodeOffset > 0) { lastTextNode = lastTextNode.splitText(nodeOffset) } - lastTextNode.parentNode.insertBefore(getDOM().createTextNode(""), lastTextNode); + lastTextNode.parentNode.insertBefore(getDOMDocument().createTextNode(""), lastTextNode); lastTextNode = (lastTextNode.previousSibling); nodeOffset = 0 } }else { - lastTextNode = getDOM().createTextNode(""); + lastTextNode = getDOMDocument().createTextNode(""); nodeOffset = 0; node.insertBefore(lastTextNode, iterator.rightNode()) } @@ -11182,7 +9812,7 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { cursorNode.parentNode.insertBefore(cursorNode.nextSibling, cursorNode) } if(lastTextNode.length > 0 && lastTextNode.nextSibling !== cursorNode) { - lastTextNode = getDOM().createTextNode(""); + lastTextNode = getDOMDocument().createTextNode(""); nodeOffset = 0 } cursorNode.parentNode.insertBefore(lastTextNode, cursorNode) @@ -11193,14 +9823,16 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { } } while(lastTextNode.previousSibling && lastTextNode.previousSibling.nodeType === Node.TEXT_NODE) { - lastTextNode.previousSibling.appendData(lastTextNode.data); - nodeOffset = (lastTextNode.previousSibling.length); - lastTextNode = (lastTextNode.previousSibling); + text = (lastTextNode.previousSibling); + text.appendData(lastTextNode.data); + nodeOffset = text.length; + lastTextNode = text; lastTextNode.parentNode.removeChild(lastTextNode.nextSibling) } while(lastTextNode.nextSibling && lastTextNode.nextSibling.nodeType === Node.TEXT_NODE) { - lastTextNode.appendData(lastTextNode.nextSibling.data); - lastTextNode.parentNode.removeChild(lastTextNode.nextSibling) + text = (lastTextNode.nextSibling); + lastTextNode.appendData(text.data); + lastTextNode.parentNode.removeChild(text) } return{textNode:lastTextNode, offset:nodeOffset} } @@ -11217,7 +9849,7 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { function getParagraphStyleAttributes(styleName) { var node = getParagraphStyleElement(styleName); if(node) { - return odfCanvas.getFormatting().getInheritedStyleAttributes(node) + return odfCanvas.getFormatting().getInheritedStyleAttributes(node, false) } return null } @@ -11237,13 +9869,20 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { } function upgradeWhitespaceToElement(textNode, offset) { runtime.assert(textNode.data[offset] === " ", "upgradeWhitespaceToElement: textNode.data[offset] should be a literal space"); - var space = textNode.ownerDocument.createElementNS(odf.Namespaces.textns, "text:s"); + var space = textNode.ownerDocument.createElementNS(odf.Namespaces.textns, "text:s"), container = textNode.parentNode, adjacentNode = textNode; space.appendChild(textNode.ownerDocument.createTextNode(" ")); - textNode.deleteData(offset, 1); - if(offset > 0) { - textNode = (textNode.splitText(offset)) + if(textNode.length === 1) { + container.replaceChild(space, textNode) + }else { + textNode.deleteData(offset, 1); + if(offset > 0) { + if(offset < textNode.length) { + textNode.splitText(offset) + } + adjacentNode = textNode.nextSibling + } + container.insertBefore(space, adjacentNode) } - textNode.parentNode.insertBefore(space, textNode); return space } function upgradeWhitespacesAtPosition(position) { @@ -11253,7 +9892,7 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { for(i = -1;i <= 1;i += 1) { container = iterator.container(); offset = iterator.unfilteredDomOffset(); - if(container.nodeType === Node.TEXT_NODE && (container.data[offset] === " " && odfUtils.isSignificantWhitespace(container, offset))) { + if(container.nodeType === Node.TEXT_NODE && (container.data[offset] === " " && odfUtils.isSignificantWhitespace((container), offset))) { container = upgradeWhitespaceToElement((container), offset); iterator.moveToEndOfNode(container) } @@ -11265,12 +9904,12 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { var iterator = getIteratorAtPosition(position), container, offset, firstSpaceElementChild, lastSpaceElementChild; container = iterator.container(); offset = iterator.unfilteredDomOffset(); - while(!odfUtils.isSpaceElement(container) && container.childNodes[offset]) { - container = container.childNodes[offset]; + while(!odfUtils.isSpaceElement(container) && container.childNodes.item(offset)) { + container = (container.childNodes.item(offset)); offset = 0 } if(container.nodeType === Node.TEXT_NODE) { - container = container.parentNode + container = (container.parentNode) } if(odfUtils.isDowngradableSpaceElement(container)) { firstSpaceElementChild = container.firstChild; @@ -11286,50 +9925,46 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { this.getParagraphElement = getParagraphElement; this.getParagraphStyleAttributes = getParagraphStyleAttributes; this.getTextNodeAtStep = getTextNodeAtStep; + function paragraphOrRoot(container, offset, root) { + var node = container.childNodes.item(offset) || container, paragraph = getParagraphElement(node); + if(paragraph && domUtils.containsNode(root, paragraph)) { + return(paragraph) + } + return root + } this.fixCursorPositions = function() { - var rootConstrainedFilter = new core.PositionFilterChain; - rootConstrainedFilter.addFilter("BaseFilter", filter); Object.keys(cursors).forEach(function(memberId) { - var cursor = cursors[memberId], stepCounter = cursor.getStepCounter(), stepsSelectionLength, positionsToAdjustFocus, positionsToAdjustAnchor, positionsToAnchor, cursorMoved = false; - rootConstrainedFilter.addFilter("RootFilter", self.createRootFilter(memberId)); - stepsSelectionLength = stepCounter.countStepsToPosition(cursor.getAnchorNode(), 0, rootConstrainedFilter); - if(!stepCounter.isPositionWalkable(rootConstrainedFilter)) { + var cursor = cursors[memberId], root = getRoot(cursor.getNode()), rootFilter = self.createRootFilter(root), subTree, startPoint, endPoint, selectedRange, cursorMoved = false; + selectedRange = cursor.getSelectedRange(); + subTree = paragraphOrRoot((selectedRange.startContainer), selectedRange.startOffset, root); + startPoint = createStepIterator((selectedRange.startContainer), selectedRange.startOffset, [filter, rootFilter], subTree); + if(!selectedRange.collapsed) { + subTree = paragraphOrRoot((selectedRange.endContainer), selectedRange.endOffset, root); + endPoint = createStepIterator((selectedRange.endContainer), selectedRange.endOffset, [filter, rootFilter], subTree) + }else { + endPoint = startPoint + } + if(!startPoint.isStep() || !endPoint.isStep()) { cursorMoved = true; - positionsToAdjustFocus = stepCounter.countPositionsToNearestStep(cursor.getNode(), 0, rootConstrainedFilter); - positionsToAdjustAnchor = stepCounter.countPositionsToNearestStep(cursor.getAnchorNode(), 0, rootConstrainedFilter); - cursor.move(positionsToAdjustFocus); - if(stepsSelectionLength !== 0) { - if(positionsToAdjustAnchor > 0) { - stepsSelectionLength += 1 - } - if(positionsToAdjustFocus > 0) { - stepsSelectionLength -= 1 - } - positionsToAnchor = stepCounter.countSteps(stepsSelectionLength, rootConstrainedFilter); - cursor.move(positionsToAnchor); - cursor.move(-positionsToAnchor, true) - } + runtime.assert(startPoint.roundToClosestStep(), "No walkable step found for cursor owned by " + memberId); + selectedRange.setStart(startPoint.container(), startPoint.offset()); + runtime.assert(endPoint.roundToClosestStep(), "No walkable step found for cursor owned by " + memberId); + selectedRange.setEnd(endPoint.container(), endPoint.offset()) }else { - if(stepsSelectionLength === 0) { - cursorMoved = true; - cursor.move(0) + if(startPoint.container() === endPoint.container() && startPoint.offset() === endPoint.offset()) { + if(!selectedRange.collapsed || cursor.getAnchorNode() !== cursor.getNode()) { + cursorMoved = true; + selectedRange.setStart(startPoint.container(), startPoint.offset()); + selectedRange.collapse(true) + } } } if(cursorMoved) { - self.emit(ops.OdtDocument.signalCursorMoved, cursor) + cursor.setSelectedRange(selectedRange, cursor.hasForwardSelection()); + self.emit(ops.Document.signalCursorMoved, cursor) } - rootConstrainedFilter.removeFilter("RootFilter") }) }; - this.getDistanceFromCursor = function(memberid, node, offset) { - var cursor = cursors[memberid], focusPosition, targetPosition; - runtime.assert(node !== null && node !== undefined, "OdtDocument.getDistanceFromCursor called without node"); - if(cursor) { - focusPosition = stepsTranslator.convertDomPointToSteps(cursor.getNode(), 0); - targetPosition = stepsTranslator.convertDomPointToSteps(node, offset) - } - return targetPosition - focusPosition - }; this.getCursorPosition = function(memberid) { var cursor = cursors[memberid]; return cursor ? stepsTranslator.convertDomPointToSteps(cursor.getNode(), 0) : 0 @@ -11348,6 +9983,9 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { this.getOdfCanvas = function() { return odfCanvas }; + this.getCanvas = function() { + return odfCanvas + }; this.getRootNode = getRootNode; this.addMember = function(member) { runtime.assert(members[member.getMemberId()] === undefined, "This member already exists"); @@ -11362,36 +10000,36 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { this.getCursor = function(memberid) { return cursors[memberid] }; - this.getCursors = function() { + this.getMemberIds = function() { var list = [], i; for(i in cursors) { if(cursors.hasOwnProperty(i)) { - list.push(cursors[i]) + list.push(cursors[i].getMemberId()) } } return list }; this.addCursor = function(cursor) { runtime.assert(Boolean(cursor), "OdtDocument::addCursor without cursor"); - var distanceToFirstTextNode = cursor.getStepCounter().countSteps(1, filter), memberid = cursor.getMemberId(); + var memberid = cursor.getMemberId(), initialSelection = self.convertCursorToDomRange(0, 0); runtime.assert(typeof memberid === "string", "OdtDocument::addCursor has cursor without memberid"); runtime.assert(!cursors[memberid], "OdtDocument::addCursor is adding a duplicate cursor with memberid " + memberid); - cursor.move(distanceToFirstTextNode); + cursor.setSelectedRange(initialSelection, true); cursors[memberid] = cursor }; this.removeCursor = function(memberid) { var cursor = cursors[memberid]; if(cursor) { - cursor.removeFromOdtDocument(); + cursor.removeFromDocument(); delete cursors[memberid]; - self.emit(ops.OdtDocument.signalCursorRemoved, memberid); + self.emit(ops.Document.signalCursorRemoved, memberid); return true } return false }; this.moveCursor = function(memberid, position, length, selectionType) { var cursor = cursors[memberid], selectionRange = self.convertCursorToDomRange(position, length); - if(cursor && selectionRange) { + if(cursor) { cursor.setSelectedRange(selectionRange, length >= 0); cursor.setSelectionType(selectionType || ops.OdtCursor.RangeSelection) } @@ -11424,22 +10062,19 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { stepsTranslator = new ops.StepsTranslator(getRootNode, gui.SelectionMover.createPositionIterator, filter, 500); eventNotifier.subscribe(ops.OdtDocument.signalStepsInserted, stepsTranslator.handleStepsInserted); eventNotifier.subscribe(ops.OdtDocument.signalStepsRemoved, stepsTranslator.handleStepsRemoved); - eventNotifier.subscribe(ops.OdtDocument.signalOperationExecuted, handleOperationExecuted) + eventNotifier.subscribe(ops.OdtDocument.signalOperationEnd, handleOperationExecuted) } init() }; -ops.OdtDocument.signalMemberAdded = "member/added"; -ops.OdtDocument.signalMemberUpdated = "member/updated"; -ops.OdtDocument.signalMemberRemoved = "member/removed"; -ops.OdtDocument.signalCursorAdded = "cursor/added"; -ops.OdtDocument.signalCursorRemoved = "cursor/removed"; -ops.OdtDocument.signalCursorMoved = "cursor/moved"; ops.OdtDocument.signalParagraphChanged = "paragraph/changed"; ops.OdtDocument.signalTableAdded = "table/added"; ops.OdtDocument.signalCommonStyleCreated = "style/created"; ops.OdtDocument.signalCommonStyleDeleted = "style/deleted"; ops.OdtDocument.signalParagraphStyleModified = "paragraphstyle/modified"; -ops.OdtDocument.signalOperationExecuted = "operation/executed"; +ops.OdtDocument.signalOperationStart = "operation/start"; +ops.OdtDocument.signalOperationEnd = "operation/end"; +ops.OdtDocument.signalProcessingBatchStart = "router/batchstart"; +ops.OdtDocument.signalProcessingBatchEnd = "router/batchend"; ops.OdtDocument.signalUndoStackChanged = "undo/changed"; ops.OdtDocument.signalStepsInserted = "steps/inserted"; ops.OdtDocument.signalStepsRemoved = "steps/removed"; @@ -11483,1415 +10118,6 @@ ops.OdtDocument.signalStepsRemoved = "steps/removed"; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.Operation = function Operation() { -}; -ops.Operation.prototype.init = function(data) { -}; -ops.Operation.prototype.isEdit; -ops.Operation.prototype.execute = function(odtDocument) { -}; -ops.Operation.prototype.spec = function() { -}; -runtime.loadClass("xmldom.RelaxNGParser"); -xmldom.RelaxNGItem; -xmldom.RelaxNG = function RelaxNG() { - var xmlnsns = "http://www.w3.org/2000/xmlns/", createChoice, createInterleave, createGroup, createAfter, createOneOrMore, createValue, createAttribute, createNameClass, createData, makePattern, applyAfter, childDeriv, rootPattern, notAllowed = {type:"notAllowed", nullable:false, hash:"notAllowed", nc:undefined, p:undefined, p1:undefined, p2:undefined, textDeriv:function() { - return notAllowed - }, startTagOpenDeriv:function() { - return notAllowed - }, attDeriv:function() { - return notAllowed - }, startTagCloseDeriv:function() { - return notAllowed - }, endTagDeriv:function() { - return notAllowed - }}, empty = {type:"empty", nullable:true, hash:"empty", nc:undefined, p:undefined, p1:undefined, p2:undefined, textDeriv:function() { - return notAllowed - }, startTagOpenDeriv:function() { - return notAllowed - }, attDeriv:function() { - return notAllowed - }, startTagCloseDeriv:function() { - return empty - }, endTagDeriv:function() { - return notAllowed - }}, text = {type:"text", nullable:true, hash:"text", nc:undefined, p:undefined, p1:undefined, p2:undefined, textDeriv:function() { - return text - }, startTagOpenDeriv:function() { - return notAllowed - }, attDeriv:function() { - return notAllowed - }, startTagCloseDeriv:function() { - return text - }, endTagDeriv:function() { - return notAllowed - }}; - function memoize0arg(func) { - function f() { - var cache; - function g() { - if(cache === undefined) { - cache = func() - } - return cache - } - return g - } - return f() - } - function memoize1arg(type, func) { - function f() { - var cache = {}, cachecount = 0; - function g(a) { - var ahash = a.hash || a.toString(), v; - if(cache.hasOwnProperty(ahash)) { - return cache[ahash] - } - cache[ahash] = v = func(a); - v.hash = type + cachecount.toString(); - cachecount += 1; - return v - } - return g - } - return f() - } - function memoizeNode(func) { - function f() { - var cache = {}; - function g(node) { - var v, m; - if(!cache.hasOwnProperty(node.localName)) { - cache[node.localName] = m = {} - }else { - m = cache[node.localName]; - v = m[node.namespaceURI]; - if(v !== undefined) { - return v - } - } - m[node.namespaceURI] = v = func(node); - return v - } - return g - } - return f() - } - function memoize2arg(type, fastfunc, func) { - function f() { - var cache = {}, cachecount = 0; - function g(a, b) { - var v = fastfunc && fastfunc(a, b), ahash, bhash, m; - if(v !== undefined) { - return v - } - ahash = a.hash || a.toString(); - bhash = b.hash || b.toString(); - if(!cache.hasOwnProperty(ahash)) { - cache[ahash] = m = {} - }else { - m = cache[ahash]; - if(m.hasOwnProperty(bhash)) { - return m[bhash] - } - } - m[bhash] = v = func(a, b); - v.hash = type + cachecount.toString(); - cachecount += 1; - return v - } - return g - } - return f() - } - function unorderedMemoize2arg(type, fastfunc, func) { - function f() { - var cache = {}, cachecount = 0; - function g(a, b) { - var v = fastfunc && fastfunc(a, b), ahash, bhash, hash, m; - if(v !== undefined) { - return v - } - ahash = a.hash || a.toString(); - bhash = b.hash || b.toString(); - if(ahash < bhash) { - hash = ahash; - ahash = bhash; - bhash = hash; - hash = a; - a = b; - b = hash - } - if(!cache.hasOwnProperty(ahash)) { - cache[ahash] = m = {} - }else { - m = cache[ahash]; - if(m.hasOwnProperty(bhash)) { - return m[bhash] - } - } - m[bhash] = v = func(a, b); - v.hash = type + cachecount.toString(); - cachecount += 1; - return v - } - return g - } - return f() - } - function getUniqueLeaves(leaves, pattern) { - if(pattern.p1.type === "choice") { - getUniqueLeaves(leaves, pattern.p1) - }else { - leaves[pattern.p1.hash] = pattern.p1 - } - if(pattern.p2.type === "choice") { - getUniqueLeaves(leaves, pattern.p2) - }else { - leaves[pattern.p2.hash] = pattern.p2 - } - } - createChoice = memoize2arg("choice", function(p1, p2) { - if(p1 === notAllowed) { - return p2 - } - if(p2 === notAllowed) { - return p1 - } - if(p1 === p2) { - return p1 - } - }, function(p1, p2) { - function makeChoice(p1, p2) { - return{type:"choice", nullable:p1.nullable || p2.nullable, hash:undefined, nc:undefined, p:undefined, p1:p1, p2:p2, textDeriv:function(context, text) { - return createChoice(p1.textDeriv(context, text), p2.textDeriv(context, text)) - }, startTagOpenDeriv:memoizeNode(function(node) { - return createChoice(p1.startTagOpenDeriv(node), p2.startTagOpenDeriv(node)) - }), attDeriv:function(context, attribute) { - return createChoice(p1.attDeriv(context, attribute), p2.attDeriv(context, attribute)) - }, startTagCloseDeriv:memoize0arg(function() { - return createChoice(p1.startTagCloseDeriv(), p2.startTagCloseDeriv()) - }), endTagDeriv:memoize0arg(function() { - return createChoice(p1.endTagDeriv(), p2.endTagDeriv()) - })} - } - var leaves = {}, i; - getUniqueLeaves(leaves, {p1:p1, p2:p2}); - p1 = undefined; - p2 = undefined; - for(i in leaves) { - if(leaves.hasOwnProperty(i)) { - if(p1 === undefined) { - p1 = leaves[i] - }else { - if(p2 === undefined) { - p2 = leaves[i] - }else { - p2 = createChoice(p2, leaves[i]) - } - } - } - } - return makeChoice(p1, p2) - }); - createInterleave = unorderedMemoize2arg("interleave", function(p1, p2) { - if(p1 === notAllowed || p2 === notAllowed) { - return notAllowed - } - if(p1 === empty) { - return p2 - } - if(p2 === empty) { - return p1 - } - }, function(p1, p2) { - return{type:"interleave", nullable:p1.nullable && p2.nullable, hash:undefined, p1:p1, p2:p2, textDeriv:function(context, text) { - return createChoice(createInterleave(p1.textDeriv(context, text), p2), createInterleave(p1, p2.textDeriv(context, text))) - }, startTagOpenDeriv:memoizeNode(function(node) { - return createChoice(applyAfter(function(p) { - return createInterleave(p, p2) - }, p1.startTagOpenDeriv(node)), applyAfter(function(p) { - return createInterleave(p1, p) - }, p2.startTagOpenDeriv(node))) - }), attDeriv:function(context, attribute) { - return createChoice(createInterleave(p1.attDeriv(context, attribute), p2), createInterleave(p1, p2.attDeriv(context, attribute))) - }, startTagCloseDeriv:memoize0arg(function() { - return createInterleave(p1.startTagCloseDeriv(), p2.startTagCloseDeriv()) - }), endTagDeriv:undefined} - }); - createGroup = memoize2arg("group", function(p1, p2) { - if(p1 === notAllowed || p2 === notAllowed) { - return notAllowed - } - if(p1 === empty) { - return p2 - } - if(p2 === empty) { - return p1 - } - }, function(p1, p2) { - return{type:"group", p1:p1, p2:p2, nullable:p1.nullable && p2.nullable, textDeriv:function(context, text) { - var p = createGroup(p1.textDeriv(context, text), p2); - if(p1.nullable) { - return createChoice(p, p2.textDeriv(context, text)) - } - return p - }, startTagOpenDeriv:function(node) { - var x = applyAfter(function(p) { - return createGroup(p, p2) - }, p1.startTagOpenDeriv(node)); - if(p1.nullable) { - return createChoice(x, p2.startTagOpenDeriv(node)) - } - return x - }, attDeriv:function(context, attribute) { - return createChoice(createGroup(p1.attDeriv(context, attribute), p2), createGroup(p1, p2.attDeriv(context, attribute))) - }, startTagCloseDeriv:memoize0arg(function() { - return createGroup(p1.startTagCloseDeriv(), p2.startTagCloseDeriv()) - })} - }); - createAfter = memoize2arg("after", function(p1, p2) { - if(p1 === notAllowed || p2 === notAllowed) { - return notAllowed - } - }, function(p1, p2) { - return{type:"after", p1:p1, p2:p2, nullable:false, textDeriv:function(context, text) { - return createAfter(p1.textDeriv(context, text), p2) - }, startTagOpenDeriv:memoizeNode(function(node) { - return applyAfter(function(p) { - return createAfter(p, p2) - }, p1.startTagOpenDeriv(node)) - }), attDeriv:function(context, attribute) { - return createAfter(p1.attDeriv(context, attribute), p2) - }, startTagCloseDeriv:memoize0arg(function() { - return createAfter(p1.startTagCloseDeriv(), p2) - }), endTagDeriv:memoize0arg(function() { - return p1.nullable ? p2 : notAllowed - })} - }); - createOneOrMore = memoize1arg("oneormore", function(p) { - if(p === notAllowed) { - return notAllowed - } - return{type:"oneOrMore", p:p, nullable:p.nullable, textDeriv:function(context, text) { - return createGroup(p.textDeriv(context, text), createChoice(this, empty)) - }, startTagOpenDeriv:function(node) { - var oneOrMore = this; - return applyAfter(function(pf) { - return createGroup(pf, createChoice(oneOrMore, empty)) - }, p.startTagOpenDeriv(node)) - }, attDeriv:function(context, attribute) { - var oneOrMore = this; - return createGroup(p.attDeriv(context, attribute), createChoice(oneOrMore, empty)) - }, startTagCloseDeriv:memoize0arg(function() { - return createOneOrMore(p.startTagCloseDeriv()) - })} - }); - function createElement(nc, p) { - return{type:"element", nc:nc, nullable:false, textDeriv:function() { - return notAllowed - }, startTagOpenDeriv:function(node) { - if(nc.contains(node)) { - return createAfter(p, empty) - } - return notAllowed - }, attDeriv:function() { - return notAllowed - }, startTagCloseDeriv:function() { - return this - }} - } - function valueMatch(context, pattern, text) { - return pattern.nullable && /^\s+$/.test(text) || pattern.textDeriv(context, text).nullable - } - createAttribute = memoize2arg("attribute", undefined, function(nc, p) { - return{type:"attribute", nullable:false, hash:undefined, nc:nc, p:p, p1:undefined, p2:undefined, textDeriv:undefined, startTagOpenDeriv:undefined, attDeriv:function(context, attribute) { - if(nc.contains(attribute) && valueMatch(context, p, attribute.nodeValue)) { - return empty - } - return notAllowed - }, startTagCloseDeriv:function() { - return notAllowed - }, endTagDeriv:undefined} - }); - function createList() { - return{type:"list", nullable:false, hash:"list", textDeriv:function() { - return empty - }} - } - createValue = memoize1arg("value", function(value) { - return{type:"value", nullable:false, value:value, textDeriv:function(context, text) { - return text === value ? empty : notAllowed - }, attDeriv:function() { - return notAllowed - }, startTagCloseDeriv:function() { - return this - }} - }); - createData = memoize1arg("data", function(type) { - return{type:"data", nullable:false, dataType:type, textDeriv:function() { - return empty - }, attDeriv:function() { - return notAllowed - }, startTagCloseDeriv:function() { - return this - }} - }); - applyAfter = function applyAfter(f, p) { - var result; - if(p.type === "after") { - result = createAfter(p.p1, f(p.p2)) - }else { - if(p.type === "choice") { - result = createChoice(applyAfter(f, p.p1), applyAfter(f, p.p2)) - }else { - result = p - } - } - return result - }; - function attsDeriv(context, pattern, attributes, position) { - if(pattern === notAllowed) { - return notAllowed - } - if(position >= attributes.length) { - return pattern - } - if(position === 0) { - position = 0 - } - var a = attributes.item(position); - while(a.namespaceURI === xmlnsns) { - position += 1; - if(position >= attributes.length) { - return pattern - } - a = attributes.item(position) - } - a = attsDeriv(context, pattern.attDeriv(context, attributes.item(position)), attributes, position + 1); - return a - } - function childrenDeriv(context, pattern, walker) { - var element = walker.currentNode, childNode = walker.firstChild(), childNodes = [], i, p; - while(childNode) { - if(childNode.nodeType === Node.ELEMENT_NODE) { - childNodes.push(childNode) - }else { - if(childNode.nodeType === Node.TEXT_NODE && !/^\s*$/.test(childNode.nodeValue)) { - childNodes.push(childNode.nodeValue) - } - } - childNode = walker.nextSibling() - } - if(childNodes.length === 0) { - childNodes = [""] - } - p = pattern; - for(i = 0;p !== notAllowed && i < childNodes.length;i += 1) { - childNode = childNodes[i]; - if(typeof childNode === "string") { - if(/^\s*$/.test(childNode)) { - p = createChoice(p, p.textDeriv(context, childNode)) - }else { - p = p.textDeriv(context, childNode) - } - }else { - walker.currentNode = childNode; - p = childDeriv(context, p, walker) - } - } - walker.currentNode = element; - return p - } - childDeriv = function childDeriv(context, pattern, walker) { - var childNode = walker.currentNode, p; - p = pattern.startTagOpenDeriv(childNode); - p = attsDeriv(context, p, childNode.attributes, 0); - p = p.startTagCloseDeriv(); - p = childrenDeriv(context, p, walker); - p = p.endTagDeriv(); - return p - }; - function addNames(name, ns, pattern) { - if(pattern.e[0].a) { - name.push(pattern.e[0].text); - ns.push(pattern.e[0].a.ns) - }else { - addNames(name, ns, pattern.e[0]) - } - if(pattern.e[1].a) { - name.push(pattern.e[1].text); - ns.push(pattern.e[1].a.ns) - }else { - addNames(name, ns, pattern.e[1]) - } - } - createNameClass = function createNameClass(pattern) { - var name, ns, hash, i, result; - if(pattern.name === "name") { - name = pattern.text; - ns = pattern.a.ns; - result = {name:name, ns:ns, hash:"{" + ns + "}" + name, contains:function(node) { - return node.namespaceURI === ns && node.localName === name - }} - }else { - if(pattern.name === "choice") { - name = []; - ns = []; - addNames(name, ns, pattern); - hash = ""; - for(i = 0;i < name.length;i += 1) { - hash += "{" + ns[i] + "}" + name[i] + "," - } - result = {hash:hash, contains:function(node) { - var j; - for(j = 0;j < name.length;j += 1) { - if(name[j] === node.localName && ns[j] === node.namespaceURI) { - return true - } - } - return false - }} - }else { - result = {hash:"anyName", contains:function() { - return true - }} - } - } - return result - }; - function resolveElement(pattern, elements) { - var element, p, i, hash; - hash = "element" + pattern.id.toString(); - p = elements[pattern.id] = {hash:hash}; - element = createElement(createNameClass(pattern.e[0]), makePattern(pattern.e[1], elements)); - for(i in element) { - if(element.hasOwnProperty(i)) { - p[i] = element[i] - } - } - return p - } - makePattern = function makePattern(pattern, elements) { - var p, i; - if(pattern.name === "elementref") { - p = pattern.id || 0; - pattern = elements[p]; - if(pattern.name !== undefined) { - return resolveElement(pattern, elements) - } - return pattern - } - switch(pattern.name) { - case "empty": - return empty; - case "notAllowed": - return notAllowed; - case "text": - return text; - case "choice": - return createChoice(makePattern(pattern.e[0], elements), makePattern(pattern.e[1], elements)); - case "interleave": - p = makePattern(pattern.e[0], elements); - for(i = 1;i < pattern.e.length;i += 1) { - p = createInterleave(p, makePattern(pattern.e[i], elements)) - } - return p; - case "group": - return createGroup(makePattern(pattern.e[0], elements), makePattern(pattern.e[1], elements)); - case "oneOrMore": - return createOneOrMore(makePattern(pattern.e[0], elements)); - case "attribute": - return createAttribute(createNameClass(pattern.e[0]), makePattern(pattern.e[1], elements)); - case "value": - return createValue(pattern.text); - case "data": - p = pattern.a && pattern.a.type; - if(p === undefined) { - p = "" - } - return createData(p); - case "list": - return createList() - } - throw"No support for " + pattern.name; - }; - this.makePattern = function(pattern, elements) { - var copy = {}, i; - for(i in elements) { - if(elements.hasOwnProperty(i)) { - copy[i] = elements[i] - } - } - i = makePattern(pattern, copy); - return i - }; - this.validate = function validate(walker, callback) { - var errors; - walker.currentNode = walker.root; - errors = childDeriv(null, rootPattern, walker); - if(!errors.nullable) { - runtime.log("Error in Relax NG validation: " + errors); - callback(["Error in Relax NG validation: " + errors]) - }else { - callback(null) - } - }; - this.init = function init(rootPattern1) { - rootPattern = rootPattern1 - } -}; -runtime.loadClass("xmldom.RelaxNGParser"); -xmldom.RelaxNG2 = function RelaxNG2() { - var start, validateNonEmptyPattern, nsmap; - function RelaxNGParseError(error, context) { - this.message = function() { - if(context) { - error += context.nodeType === Node.ELEMENT_NODE ? " Element " : " Node "; - error += context.nodeName; - if(context.nodeValue) { - error += " with value '" + context.nodeValue + "'" - } - error += "." - } - return error - } - } - function validateOneOrMore(elementdef, walker, element) { - var node, i = 0, err; - do { - node = walker.currentNode; - err = validateNonEmptyPattern(elementdef.e[0], walker, element); - i += 1 - }while(!err && node !== walker.currentNode); - if(i > 1) { - walker.currentNode = node; - return null - } - return err - } - function qName(node) { - return nsmap[node.namespaceURI] + ":" + node.localName - } - function isWhitespace(node) { - return node && (node.nodeType === Node.TEXT_NODE && /^\s+$/.test(node.nodeValue)) - } - function validatePattern(elementdef, walker, element, data) { - if(elementdef.name === "empty") { - return null - } - return validateNonEmptyPattern(elementdef, walker, element, data) - } - function validateAttribute(elementdef, walker, element) { - if(elementdef.e.length !== 2) { - throw"Attribute with wrong # of elements: " + elementdef.e.length; - } - var att, a, l = elementdef.localnames.length, i; - for(i = 0;i < l;i += 1) { - a = element.getAttributeNS(elementdef.namespaces[i], elementdef.localnames[i]); - if(a === "" && !element.hasAttributeNS(elementdef.namespaces[i], elementdef.localnames[i])) { - a = undefined - } - if(att !== undefined && a !== undefined) { - return[new RelaxNGParseError("Attribute defined too often.", element)] - } - att = a - } - if(att === undefined) { - return[new RelaxNGParseError("Attribute not found: " + elementdef.names, element)] - } - return validatePattern(elementdef.e[1], walker, element, att) - } - function validateTop(elementdef, walker, element) { - return validatePattern(elementdef, walker, element) - } - function validateElement(elementdef, walker) { - if(elementdef.e.length !== 2) { - throw"Element with wrong # of elements: " + elementdef.e.length; - } - var node = walker.currentNode, type = node ? node.nodeType : 0, error = null; - while(type > Node.ELEMENT_NODE) { - if(type !== Node.COMMENT_NODE && (type !== Node.TEXT_NODE || !/^\s+$/.test(walker.currentNode.nodeValue))) { - return[new RelaxNGParseError("Not allowed node of type " + type + ".")] - } - node = walker.nextSibling(); - type = node ? node.nodeType : 0 - } - if(!node) { - return[new RelaxNGParseError("Missing element " + elementdef.names)] - } - if(elementdef.names && elementdef.names.indexOf(qName(node)) === -1) { - return[new RelaxNGParseError("Found " + node.nodeName + " instead of " + elementdef.names + ".", node)] - } - if(walker.firstChild()) { - error = validateTop(elementdef.e[1], walker, node); - while(walker.nextSibling()) { - type = walker.currentNode.nodeType; - if(!isWhitespace(walker.currentNode) && type !== Node.COMMENT_NODE) { - return[new RelaxNGParseError("Spurious content.", walker.currentNode)] - } - } - if(walker.parentNode() !== node) { - return[new RelaxNGParseError("Implementation error.")] - } - }else { - error = validateTop(elementdef.e[1], walker, node) - } - node = walker.nextSibling(); - return error - } - function validateChoice(elementdef, walker, element, data) { - if(elementdef.e.length !== 2) { - throw"Choice with wrong # of options: " + elementdef.e.length; - } - var node = walker.currentNode, err; - if(elementdef.e[0].name === "empty") { - err = validateNonEmptyPattern(elementdef.e[1], walker, element, data); - if(err) { - walker.currentNode = node - } - return null - } - err = validatePattern(elementdef.e[0], walker, element, data); - if(err) { - walker.currentNode = node; - err = validateNonEmptyPattern(elementdef.e[1], walker, element, data) - } - return err - } - function validateInterleave(elementdef, walker, element) { - var l = elementdef.e.length, n = [l], err, i, todo = l, donethisround, node, subnode, e; - while(todo > 0) { - donethisround = 0; - node = walker.currentNode; - for(i = 0;i < l;i += 1) { - subnode = walker.currentNode; - if(n[i] !== true && n[i] !== subnode) { - e = elementdef.e[i]; - err = validateNonEmptyPattern(e, walker, element); - if(err) { - walker.currentNode = subnode; - if(n[i] === undefined) { - n[i] = false - } - }else { - if(subnode === walker.currentNode || (e.name === "oneOrMore" || e.name === "choice" && (e.e[0].name === "oneOrMore" || e.e[1].name === "oneOrMore"))) { - donethisround += 1; - n[i] = subnode - }else { - donethisround += 1; - n[i] = true - } - } - } - } - if(node === walker.currentNode && donethisround === todo) { - return null - } - if(donethisround === 0) { - for(i = 0;i < l;i += 1) { - if(n[i] === false) { - return[new RelaxNGParseError("Interleave does not match.", element)] - } - } - return null - } - todo = 0; - for(i = 0;i < l;i += 1) { - if(n[i] !== true) { - todo += 1 - } - } - } - return null - } - function validateGroup(elementdef, walker, element) { - if(elementdef.e.length !== 2) { - throw"Group with wrong # of members: " + elementdef.e.length; - } - return validateNonEmptyPattern(elementdef.e[0], walker, element) || validateNonEmptyPattern(elementdef.e[1], walker, element) - } - function validateText(elementdef, walker, element) { - var node = walker.currentNode, type = node ? node.nodeType : 0; - while(node !== element && type !== 3) { - if(type === 1) { - return[new RelaxNGParseError("Element not allowed here.", node)] - } - node = walker.nextSibling(); - type = node ? node.nodeType : 0 - } - walker.nextSibling(); - return null - } - validateNonEmptyPattern = function validateNonEmptyPattern(elementdef, walker, element, data) { - var name = elementdef.name, err = null; - if(name === "text") { - err = validateText(elementdef, walker, element) - }else { - if(name === "data") { - err = null - }else { - if(name === "value") { - if(data !== elementdef.text) { - err = [new RelaxNGParseError("Wrong value, should be '" + elementdef.text + "', not '" + data + "'", element)] - } - }else { - if(name === "list") { - err = null - }else { - if(name === "attribute") { - err = validateAttribute(elementdef, walker, element) - }else { - if(name === "element") { - err = validateElement(elementdef, walker) - }else { - if(name === "oneOrMore") { - err = validateOneOrMore(elementdef, walker, element) - }else { - if(name === "choice") { - err = validateChoice(elementdef, walker, element, data) - }else { - if(name === "group") { - err = validateGroup(elementdef, walker, element) - }else { - if(name === "interleave") { - err = validateInterleave(elementdef, walker, element) - }else { - throw name + " not allowed in nonEmptyPattern."; - } - } - } - } - } - } - } - } - } - } - return err - }; - this.validate = function validate(walker, callback) { - walker.currentNode = walker.root; - var errors = validatePattern(start.e[0], walker, (walker.root)); - callback(errors) - }; - this.init = function init(start1, nsmap1) { - start = start1; - nsmap = nsmap1 - } -}; -runtime.loadClass("core.DomUtils"); -runtime.loadClass("gui.Avatar"); -runtime.loadClass("ops.OdtCursor"); -gui.Caret = function Caret(cursor, avatarInitiallyVisible, blinkOnRangeSelect) { - var MIN_CARET_HEIGHT_PX = 8, DEFAULT_CARET_TOP = "5%", DEFAULT_CARET_HEIGHT = "1em", span, avatar, cursorNode, isShown = true, shouldBlink = false, blinking = false, blinkTimeout, domUtils = new core.DomUtils; - function blink(reset) { - if(!shouldBlink || !cursorNode.parentNode) { - return - } - if(!blinking || reset) { - if(reset && blinkTimeout !== undefined) { - runtime.clearTimeout(blinkTimeout) - } - blinking = true; - span.style.opacity = reset || span.style.opacity === "0" ? "1" : "0"; - blinkTimeout = runtime.setTimeout(function() { - blinking = false; - blink(false) - }, 500) - } - } - function getCaretClientRectWithMargin(caretElement, margin) { - var caretRect = caretElement.getBoundingClientRect(); - return{left:caretRect.left - margin.left, top:caretRect.top - margin.top, right:caretRect.right + margin.right, bottom:caretRect.bottom + margin.bottom} - } - function length(node) { - return node.nodeType === Node.TEXT_NODE ? node.textContent.length : node.childNodes.length - } - function verticalOverlap(cursorNode, rangeRect) { - var cursorRect = cursorNode.getBoundingClientRect(), intersectTop = 0, intersectBottom = 0; - if(cursorRect && rangeRect) { - intersectTop = Math.max(cursorRect.top, rangeRect.top); - intersectBottom = Math.min(cursorRect.bottom, rangeRect.bottom) - } - return intersectBottom - intersectTop - } - function getSelectionRect() { - var range = cursor.getSelectedRange().cloneRange(), node = cursor.getNode(), nextRectangle, selectionRectangle = null, nodeLength; - if(node.previousSibling) { - nodeLength = length(node.previousSibling); - range.setStart(node.previousSibling, nodeLength > 0 ? nodeLength - 1 : 0); - range.setEnd(node.previousSibling, nodeLength); - nextRectangle = range.getBoundingClientRect(); - if(nextRectangle && nextRectangle.height) { - selectionRectangle = nextRectangle - } - } - if(node.nextSibling) { - range.setStart(node.nextSibling, 0); - range.setEnd(node.nextSibling, length(node.nextSibling) > 0 ? 1 : 0); - nextRectangle = range.getBoundingClientRect(); - if(nextRectangle && nextRectangle.height) { - if(!selectionRectangle || verticalOverlap(node, nextRectangle) > verticalOverlap(node, selectionRectangle)) { - selectionRectangle = nextRectangle - } - } - } - return selectionRectangle - } - function handleUpdate() { - var selectionRect = getSelectionRect(), zoomLevel = cursor.getOdtDocument().getOdfCanvas().getZoomLevel(), caretRect; - if(isShown && cursor.getSelectionType() === ops.OdtCursor.RangeSelection) { - span.style.visibility = "visible" - }else { - span.style.visibility = "hidden" - } - if(selectionRect) { - span.style.top = "0"; - caretRect = domUtils.getBoundingClientRect(span); - if(selectionRect.height < MIN_CARET_HEIGHT_PX) { - selectionRect = {top:selectionRect.top - (MIN_CARET_HEIGHT_PX - selectionRect.height) / 2, height:MIN_CARET_HEIGHT_PX} - } - span.style.height = domUtils.adaptRangeDifferenceToZoomLevel(selectionRect.height, zoomLevel) + "px"; - span.style.top = domUtils.adaptRangeDifferenceToZoomLevel(selectionRect.top - caretRect.top, zoomLevel) + "px" - }else { - span.style.height = DEFAULT_CARET_HEIGHT; - span.style.top = DEFAULT_CARET_TOP - } - } - this.handleUpdate = handleUpdate; - this.refreshCursorBlinking = function() { - if(blinkOnRangeSelect || cursor.getSelectedRange().collapsed) { - shouldBlink = true; - blink(true) - }else { - shouldBlink = false; - span.style.opacity = "0" - } - }; - this.setFocus = function() { - shouldBlink = true; - avatar.markAsFocussed(true); - blink(true) - }; - this.removeFocus = function() { - shouldBlink = false; - avatar.markAsFocussed(false); - span.style.opacity = "1" - }; - this.show = function() { - isShown = true; - handleUpdate(); - avatar.markAsFocussed(true) - }; - this.hide = function() { - isShown = false; - handleUpdate(); - avatar.markAsFocussed(false) - }; - this.setAvatarImageUrl = function(url) { - avatar.setImageUrl(url) - }; - this.setColor = function(newColor) { - span.style.borderColor = newColor; - avatar.setColor(newColor) - }; - this.getCursor = function() { - return cursor - }; - this.getFocusElement = function() { - return span - }; - this.toggleHandleVisibility = function() { - if(avatar.isVisible()) { - avatar.hide() - }else { - avatar.show() - } - }; - this.showHandle = function() { - avatar.show() - }; - this.hideHandle = function() { - avatar.hide() - }; - this.ensureVisible = function() { - var canvasElement = cursor.getOdtDocument().getOdfCanvas().getElement(), canvasContainerElement = canvasElement.parentNode, caretRect, canvasContainerRect, horizontalMargin = canvasContainerElement.offsetWidth - canvasContainerElement.clientWidth + 5, verticalMargin = canvasContainerElement.offsetHeight - canvasContainerElement.clientHeight + 5; - caretRect = getCaretClientRectWithMargin(span, {top:verticalMargin, left:horizontalMargin, bottom:verticalMargin, right:horizontalMargin}); - canvasContainerRect = canvasContainerElement.getBoundingClientRect(); - if(caretRect.top < canvasContainerRect.top) { - canvasContainerElement.scrollTop -= canvasContainerRect.top - caretRect.top - }else { - if(caretRect.bottom > canvasContainerRect.bottom) { - canvasContainerElement.scrollTop += caretRect.bottom - canvasContainerRect.bottom - } - } - if(caretRect.left < canvasContainerRect.left) { - canvasContainerElement.scrollLeft -= canvasContainerRect.left - caretRect.left - }else { - if(caretRect.right > canvasContainerRect.right) { - canvasContainerElement.scrollLeft += caretRect.right - canvasContainerRect.right - } - } - handleUpdate() - }; - this.destroy = function(callback) { - avatar.destroy(function(err) { - if(err) { - callback(err) - }else { - cursorNode.removeChild(span); - callback() - } - }) - }; - function init() { - var dom = cursor.getOdtDocument().getDOM(), htmlns = dom.documentElement.namespaceURI; - span = (dom.createElementNS(htmlns, "span")); - span.style.top = DEFAULT_CARET_TOP; - cursorNode = cursor.getNode(); - cursorNode.appendChild(span); - avatar = new gui.Avatar(cursorNode, avatarInitiallyVisible); - handleUpdate() - } - init() -}; -gui.EventManager = function EventManager(odtDocument) { - var window = (runtime.getWindow()), bindToDirectHandler = {"beforecut":true, "beforepaste":true}, bindToWindow, eventTrap; - function getCanvasElement() { - return odtDocument.getOdfCanvas().getElement() - } - function EventDelegate() { - var self = this, recentEvents = []; - this.handlers = []; - this.isSubscribed = false; - this.handleEvent = function(e) { - if(recentEvents.indexOf(e) === -1) { - recentEvents.push(e); - self.handlers.forEach(function(handler) { - handler(e) - }); - runtime.setTimeout(function() { - recentEvents.splice(recentEvents.indexOf(e), 1) - }, 0) - } - } - } - function WindowScrollState(window) { - var x = window.scrollX, y = window.scrollY; - this.restore = function() { - if(window.scrollX !== x || window.scrollY !== y) { - window.scrollTo(x, y) - } - } - } - function ElementScrollState(element) { - var top = element.scrollTop, left = element.scrollLeft; - this.restore = function() { - if(element.scrollTop !== top || element.scrollLeft !== left) { - element.scrollTop = top; - element.scrollLeft = left - } - } - } - function listenEvent(eventTarget, eventType, eventHandler) { - var onVariant = "on" + eventType, bound = false; - if(eventTarget.attachEvent) { - bound = eventTarget.attachEvent(onVariant, eventHandler) - } - if(!bound && eventTarget.addEventListener) { - eventTarget.addEventListener(eventType, eventHandler, false); - bound = true - } - if((!bound || bindToDirectHandler[eventType]) && eventTarget.hasOwnProperty(onVariant)) { - eventTarget[onVariant] = eventHandler - } - } - function removeEvent(eventTarget, eventType, eventHandler) { - var onVariant = "on" + eventType; - if(eventTarget.detachEvent) { - eventTarget.detachEvent(onVariant, eventHandler) - } - if(eventTarget.removeEventListener) { - eventTarget.removeEventListener(eventType, eventHandler, false) - } - if(eventTarget[onVariant] === eventHandler) { - eventTarget[onVariant] = null - } - } - this.subscribe = function(eventName, handler) { - var delegate = bindToWindow[eventName], canvasElement = getCanvasElement(); - if(delegate) { - delegate.handlers.push(handler); - if(!delegate.isSubscribed) { - delegate.isSubscribed = true; - listenEvent((window), eventName, delegate.handleEvent); - listenEvent(canvasElement, eventName, delegate.handleEvent); - listenEvent(eventTrap, eventName, delegate.handleEvent) - } - }else { - listenEvent(canvasElement, eventName, handler) - } - }; - this.unsubscribe = function(eventName, handler) { - var delegate = bindToWindow[eventName], handlerIndex = delegate && delegate.handlers.indexOf(handler), canvasElement = getCanvasElement(); - if(delegate) { - if(handlerIndex !== -1) { - delegate.handlers.splice(handlerIndex, 1) - } - }else { - removeEvent(canvasElement, eventName, handler) - } - }; - function hasFocus() { - return odtDocument.getDOM().activeElement === getCanvasElement() - } - function findScrollableParent(element) { - while(element && (!element.scrollTop && !element.scrollLeft)) { - element = (element.parentNode) - } - if(element) { - return new ElementScrollState(element) - } - return new WindowScrollState(window) - } - this.focus = function() { - var scrollParent, canvasElement = getCanvasElement(), selection = window.getSelection(); - if(!hasFocus()) { - scrollParent = findScrollableParent(canvasElement); - canvasElement.focus(); - if(scrollParent) { - scrollParent.restore() - } - } - if(selection && selection.extend) { - if(eventTrap.parentNode !== canvasElement) { - canvasElement.appendChild(eventTrap) - } - selection.collapse(eventTrap.firstChild, 0); - selection.extend(eventTrap, eventTrap.childNodes.length) - } - }; - function init() { - var canvasElement = getCanvasElement(), doc = canvasElement.ownerDocument; - runtime.assert(Boolean(window), "EventManager requires a window object to operate correctly"); - bindToWindow = {"mousedown":new EventDelegate, "mouseup":new EventDelegate, "focus":new EventDelegate}; - eventTrap = doc.createElement("div"); - eventTrap.id = "eventTrap"; - eventTrap.setAttribute("contenteditable", "true"); - eventTrap.style.position = "absolute"; - eventTrap.style.left = "-10000px"; - eventTrap.appendChild(doc.createTextNode("dummy content")); - canvasElement.appendChild(eventTrap) - } - init() -}; -runtime.loadClass("gui.SelectionMover"); -gui.ShadowCursor = function ShadowCursor(odtDocument) { - var selectedRange = (odtDocument.getDOM().createRange()), forwardSelection = true; - this.removeFromOdtDocument = function() { - }; - this.getMemberId = function() { - return gui.ShadowCursor.ShadowCursorMemberId - }; - this.getSelectedRange = function() { - return selectedRange - }; - this.setSelectedRange = function(range, isForwardSelection) { - selectedRange = range; - forwardSelection = isForwardSelection !== false - }; - this.hasForwardSelection = function() { - return forwardSelection - }; - this.getOdtDocument = function() { - return odtDocument - }; - this.getSelectionType = function() { - return ops.OdtCursor.RangeSelection - }; - function init() { - selectedRange.setStart(odtDocument.getRootNode(), 0) - } - init() -}; -gui.ShadowCursor.ShadowCursorMemberId = ""; -(function() { - return gui.ShadowCursor -})(); -/* - - 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/ -*/ -gui.UndoManager = function UndoManager() { -}; -gui.UndoManager.prototype.subscribe = function(signal, callback) { -}; -gui.UndoManager.prototype.unsubscribe = function(signal, callback) { -}; -gui.UndoManager.prototype.setOdtDocument = function(newDocument) { -}; -gui.UndoManager.prototype.saveInitialState = function() { -}; -gui.UndoManager.prototype.resetInitialState = function() { -}; -gui.UndoManager.prototype.setPlaybackFunction = function(playback_func) { -}; -gui.UndoManager.prototype.hasUndoStates = function() { -}; -gui.UndoManager.prototype.hasRedoStates = function() { -}; -gui.UndoManager.prototype.moveForward = function(states) { -}; -gui.UndoManager.prototype.moveBackward = function(states) { -}; -gui.UndoManager.prototype.onOperationExecuted = function(op) { -}; -gui.UndoManager.signalUndoStackChanged = "undoStackChanged"; -gui.UndoManager.signalUndoStateCreated = "undoStateCreated"; -gui.UndoManager.signalUndoStateModified = "undoStateModified"; -(function() { - return gui.UndoManager -})(); -/* - - 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/ -*/ -gui.UndoStateRules = function UndoStateRules() { - function getOpType(op) { - return op.spec().optype - } - this.getOpType = getOpType; - function getOpPosition(op) { - return op.spec().position - } - function isEditOperation(op) { - return op.isEdit - } - this.isEditOperation = isEditOperation; - function canAggregateOperation(optype) { - switch(optype) { - case "RemoveText": - ; - case "InsertText": - return true; - default: - return false - } - } - function isSameDirectionOfTravel(recentEditOps, thisOp) { - var existing1 = getOpPosition(recentEditOps[recentEditOps.length - 2]), existing2 = getOpPosition(recentEditOps[recentEditOps.length - 1]), thisPos = getOpPosition(thisOp), direction = existing2 - existing1; - return existing2 === thisPos - direction - } - function isContinuousOperation(recentEditOps, thisOp) { - var optype = getOpType(thisOp); - if(canAggregateOperation(optype) && optype === getOpType(recentEditOps[0])) { - if(recentEditOps.length === 1) { - return true - } - if(isSameDirectionOfTravel(recentEditOps, thisOp)) { - return true - } - } - return false - } - function isPartOfOperationSet(operation, lastOperations) { - if(isEditOperation(operation)) { - if(lastOperations.length === 0) { - return true - } - return isEditOperation(lastOperations[lastOperations.length - 1]) && isContinuousOperation(lastOperations.filter(isEditOperation), operation) - } - return true - } - this.isPartOfOperationSet = isPartOfOperationSet -}; -/* - - Copyright (C) 2012 KO GmbH <aditya.bhatt@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/ -*/ -ops.EditInfo = function EditInfo(container, odtDocument) { - var editInfoNode, editHistory = {}; - function sortEdits() { - var arr = [], memberid; - for(memberid in editHistory) { - if(editHistory.hasOwnProperty(memberid)) { - arr.push({"memberid":memberid, "time":editHistory[memberid].time}) - } - } - arr.sort(function(a, b) { - return a.time - b.time - }); - return arr - } - this.getNode = function() { - return editInfoNode - }; - this.getOdtDocument = function() { - return odtDocument - }; - this.getEdits = function() { - return editHistory - }; - this.getSortedEdits = function() { - return sortEdits() - }; - this.addEdit = function(memberid, timestamp) { - editHistory[memberid] = {time:timestamp} - }; - this.clearEdits = function() { - editHistory = {} - }; - this.destroy = function(callback) { - if(container.parentNode) { - container.removeChild(editInfoNode) - } - callback() - }; - function init() { - var editInfons = "urn:webodf:names:editinfo", dom = odtDocument.getDOM(); - editInfoNode = dom.createElementNS(editInfons, "editinfo"); - container.insertBefore(editInfoNode, container.firstChild) - } - init() -}; -/* - - Copyright (C) 2012-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/ -*/ -runtime.loadClass("core.DomUtils"); ops.OpAddAnnotation = function OpAddAnnotation() { var memberid, timestamp, position, length, name, doc; this.init = function(data) { @@ -12902,9 +10128,10 @@ ops.OpAddAnnotation = function OpAddAnnotation() { name = data.name }; this.isEdit = true; + this.group = undefined; function createAnnotationNode(odtDocument, date) { var annotationNode, creatorNode, dateNode, listNode, listItemNode, paragraphNode; - annotationNode = doc.createElementNS(odf.Namespaces.officens, "office:annotation"); + annotationNode = (doc.createElementNS(odf.Namespaces.officens, "office:annotation")); annotationNode.setAttributeNS(odf.Namespaces.officens, "office:name", name); creatorNode = doc.createElementNS(odf.Namespaces.dcns, "dc:creator"); creatorNode.setAttributeNS("urn:webodf:names:editinfo", "editinfo:memberid", memberid); @@ -12941,28 +10168,23 @@ ops.OpAddAnnotation = function OpAddAnnotation() { } } } - this.execute = function(odtDocument) { - var annotation = {}, cursor = odtDocument.getCursor(memberid), selectedRange, paragraphElement, domUtils = new core.DomUtils; - doc = odtDocument.getDOM(); - annotation.node = createAnnotationNode(odtDocument, new Date(timestamp)); - if(!annotation.node) { - return false - } + this.execute = function(document) { + var odtDocument = (document), annotation, annotationEnd, cursor = odtDocument.getCursor(memberid), selectedRange, paragraphElement, domUtils = new core.DomUtils; + doc = odtDocument.getDOMDocument(); + annotation = createAnnotationNode(odtDocument, new Date(timestamp)); if(length) { - annotation.end = createAnnotationEnd(); - if(!annotation.end) { - return false - } - insertNodeAtPosition(odtDocument, annotation.end, position + length) + annotationEnd = createAnnotationEnd(); + annotation.annotationEndElement = annotationEnd; + insertNodeAtPosition(odtDocument, annotationEnd, position + length) } - insertNodeAtPosition(odtDocument, annotation.node, position); + insertNodeAtPosition(odtDocument, annotation, position); odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position:position, length:length}); if(cursor) { selectedRange = doc.createRange(); - paragraphElement = domUtils.getElementsByTagNameNS(annotation.node, odf.Namespaces.textns, "p")[0]; + paragraphElement = domUtils.getElementsByTagNameNS(annotation, odf.Namespaces.textns, "p")[0]; selectedRange.selectNodeContents(paragraphElement); - cursor.setSelectedRange(selectedRange); - odtDocument.emit(ops.OdtDocument.signalCursorMoved, cursor) + cursor.setSelectedRange(selectedRange, false); + odtDocument.emit(ops.Document.signalCursorMoved, cursor) } odtDocument.getOdfCanvas().addAnnotation(annotation); odtDocument.fixCursorPositions(); @@ -12972,6 +10194,8 @@ ops.OpAddAnnotation = function OpAddAnnotation() { return{optype:"AddAnnotation", memberid:memberid, timestamp:timestamp, position:position, length:length, name:name} } }; +ops.OpAddAnnotation.Spec; +ops.OpAddAnnotation.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -13016,20 +10240,23 @@ ops.OpAddCursor = function OpAddCursor() { timestamp = data.timestamp }; this.isEdit = false; - this.execute = function(odtDocument) { - var cursor = odtDocument.getCursor(memberid); + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document), cursor = odtDocument.getCursor(memberid); if(cursor) { return false } cursor = new ops.OdtCursor(memberid, odtDocument); odtDocument.addCursor(cursor); - odtDocument.emit(ops.OdtDocument.signalCursorAdded, cursor); + odtDocument.emit(ops.Document.signalCursorAdded, cursor); return true }; this.spec = function() { return{optype:"AddCursor", memberid:memberid, timestamp:timestamp} } }; +ops.OpAddCursor.Spec; +ops.OpAddCursor.InitSpec; /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -13054,7 +10281,6 @@ ops.OpAddCursor = function OpAddCursor() { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.Member"); ops.OpAddMember = function OpAddMember() { var memberid, timestamp, setProperties; this.init = function(data) { @@ -13063,19 +10289,23 @@ ops.OpAddMember = function OpAddMember() { setProperties = data.setProperties }; this.isEdit = false; - this.execute = function(odtDocument) { + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document), member; if(odtDocument.getMember(memberid)) { return false } - var member = new ops.Member(memberid, setProperties); + member = new ops.Member(memberid, setProperties); odtDocument.addMember(member); - odtDocument.emit(ops.OdtDocument.signalMemberAdded, member); + odtDocument.emit(ops.Document.signalMemberAdded, member); return true }; this.spec = function() { return{optype:"AddMember", memberid:memberid, timestamp:timestamp, setProperties:setProperties} } }; +ops.OpAddMember.Spec; +ops.OpAddMember.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -13113,7 +10343,6 @@ ops.OpAddMember = function OpAddMember() { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces"); ops.OpAddStyle = function OpAddStyle() { var memberid, timestamp, styleName, styleFamily, isAutomaticStyle, setProperties, stylens = odf.Namespaces.stylens; this.init = function(data) { @@ -13125,8 +10354,9 @@ ops.OpAddStyle = function OpAddStyle() { setProperties = data.setProperties }; this.isEdit = true; - this.execute = function(odtDocument) { - var odfContainer = odtDocument.getOdfCanvas().odfContainer(), formatting = odtDocument.getFormatting(), dom = odtDocument.getDOM(), styleNode = dom.createElementNS(stylens, "style:style"); + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document), odfContainer = odtDocument.getOdfCanvas().odfContainer(), formatting = odtDocument.getFormatting(), dom = odtDocument.getDOMDocument(), styleNode = dom.createElementNS(stylens, "style:style"); if(!styleNode) { return false } @@ -13151,6 +10381,245 @@ ops.OpAddStyle = function OpAddStyle() { } }; ops.OpAddStyle.Spec; +ops.OpAddStyle.InitSpec; +/* + + Copyright (C) 2012-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/ +*/ +odf.ObjectNameGenerator = function ObjectNameGenerator(odfContainer, memberId) { + var stylens = odf.Namespaces.stylens, drawns = odf.Namespaces.drawns, xlinkns = odf.Namespaces.xlinkns, domUtils = new core.DomUtils, utils = new core.Utils, memberIdHash = utils.hashString(memberId), styleNameGenerator = null, frameNameGenerator = null, imageNameGenerator = null, existingFrameNames = {}, existingImageNames = {}; + function NameGenerator(prefix, findExistingNames) { + var reportedNames = {}; + this.generateName = function() { + var existingNames = findExistingNames(), startIndex = 0, name; + do { + name = prefix + startIndex; + startIndex += 1 + }while(reportedNames[name] || existingNames[name]); + reportedNames[name] = true; + return name + } + } + function getAllStyleNames() { + var styleElements = [odfContainer.rootElement.automaticStyles, odfContainer.rootElement.styles], styleNames = {}; + function getStyleNames(styleListElement) { + var e = styleListElement.firstElementChild; + while(e) { + if(e.namespaceURI === stylens && e.localName === "style") { + styleNames[e.getAttributeNS(stylens, "name")] = true + } + e = e.nextElementSibling + } + } + styleElements.forEach(getStyleNames); + return styleNames + } + this.generateStyleName = function() { + if(styleNameGenerator === null) { + styleNameGenerator = new NameGenerator("auto" + memberIdHash + "_", function() { + return getAllStyleNames() + }) + } + return styleNameGenerator.generateName() + }; + this.generateFrameName = function() { + if(frameNameGenerator === null) { + var nodes = domUtils.getElementsByTagNameNS(odfContainer.rootElement.body, drawns, "frame"); + nodes.forEach(function(frame) { + existingFrameNames[frame.getAttributeNS(drawns, "name")] = true + }); + frameNameGenerator = new NameGenerator("fr" + memberIdHash + "_", function() { + return existingFrameNames + }) + } + return frameNameGenerator.generateName() + }; + this.generateImageName = function() { + if(imageNameGenerator === null) { + var nodes = domUtils.getElementsByTagNameNS(odfContainer.rootElement.body, drawns, "image"); + nodes.forEach(function(image) { + var path = image.getAttributeNS(xlinkns, "href"); + path = path.substring("Pictures/".length, path.lastIndexOf(".")); + existingImageNames[path] = true + }); + imageNameGenerator = new NameGenerator("img" + memberIdHash + "_", function() { + return existingImageNames + }) + } + return imageNameGenerator.generateName() + } +}; +/* + + Copyright (C) 2012-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/ +*/ +odf.TextStyleApplicator = function TextStyleApplicator(objectNameGenerator, formatting, automaticStyles) { + var domUtils = new core.DomUtils, textns = odf.Namespaces.textns, stylens = odf.Namespaces.stylens, textProperties = "style:text-properties", webodfns = "urn:webodf:names:scope"; + function StyleLookup(info) { + var cachedAppliedStyles = {}; + function compare(expected, actual) { + if(typeof expected === "object" && typeof actual === "object") { + return Object.keys(expected).every(function(key) { + return compare(expected[key], actual[key]) + }) + } + return expected === actual + } + this.isStyleApplied = function(textNode) { + var appliedStyle = formatting.getAppliedStylesForElement(textNode, cachedAppliedStyles); + return compare(info, appliedStyle) + } + } + function StyleManager(info) { + var createdStyles = {}; + function createDirectFormat(existingStyleName, document) { + var derivedStyleInfo, derivedStyleNode; + derivedStyleInfo = existingStyleName ? formatting.createDerivedStyleObject(existingStyleName, "text", info) : info; + derivedStyleNode = document.createElementNS(stylens, "style:style"); + formatting.updateStyle(derivedStyleNode, derivedStyleInfo); + derivedStyleNode.setAttributeNS(stylens, "style:name", objectNameGenerator.generateStyleName()); + derivedStyleNode.setAttributeNS(stylens, "style:family", "text"); + derivedStyleNode.setAttributeNS(webodfns, "scope", "document-content"); + automaticStyles.appendChild(derivedStyleNode); + return derivedStyleNode + } + function getDirectStyle(existingStyleName, document) { + existingStyleName = existingStyleName || ""; + if(!createdStyles.hasOwnProperty(existingStyleName)) { + createdStyles[existingStyleName] = createDirectFormat(existingStyleName, document) + } + return createdStyles[existingStyleName].getAttributeNS(stylens, "name") + } + this.applyStyleToContainer = function(container) { + var name = getDirectStyle(container.getAttributeNS(textns, "style-name"), container.ownerDocument); + container.setAttributeNS(textns, "text:style-name", name) + } + } + function isTextSpan(node) { + return node.localName === "span" && node.namespaceURI === textns + } + function moveToNewSpan(startNode, limits) { + var document = startNode.ownerDocument, originalContainer = (startNode.parentNode), styledContainer, trailingContainer, moveTrailing, node, nextNode, loopGuard = new core.LoopWatchDog(1E4), styledNodes = []; + if(!isTextSpan(originalContainer)) { + styledContainer = document.createElementNS(textns, "text:span"); + originalContainer.insertBefore(styledContainer, startNode); + moveTrailing = false + }else { + if(startNode.previousSibling && !domUtils.rangeContainsNode(limits, (originalContainer.firstChild))) { + styledContainer = originalContainer.cloneNode(false); + originalContainer.parentNode.insertBefore(styledContainer, originalContainer.nextSibling); + moveTrailing = true + }else { + styledContainer = originalContainer; + moveTrailing = true + } + } + styledNodes.push(startNode); + node = startNode.nextSibling; + while(node && domUtils.rangeContainsNode(limits, node)) { + loopGuard.check(); + styledNodes.push(node); + node = node.nextSibling + } + styledNodes.forEach(function(n) { + if(n.parentNode !== styledContainer) { + styledContainer.appendChild(n) + } + }); + if(node && moveTrailing) { + trailingContainer = styledContainer.cloneNode(false); + styledContainer.parentNode.insertBefore(trailingContainer, styledContainer.nextSibling); + while(node) { + loopGuard.check(); + nextNode = node.nextSibling; + trailingContainer.appendChild(node); + node = nextNode + } + } + return(styledContainer) + } + this.applyStyle = function(textNodes, limits, info) { + var textPropsOnly = {}, isStyled, container, styleCache, styleLookup; + runtime.assert(info && info.hasOwnProperty(textProperties), "applyStyle without any text properties"); + textPropsOnly[textProperties] = info[textProperties]; + styleCache = new StyleManager(textPropsOnly); + styleLookup = new StyleLookup(textPropsOnly); + function apply(n) { + isStyled = styleLookup.isStyleApplied(n); + if(isStyled === false) { + container = moveToNewSpan(n, limits); + styleCache.applyStyleToContainer(container) + } + } + textNodes.forEach(apply) + } +}; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -13188,9 +10657,6 @@ ops.OpAddStyle.Spec; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils"); -runtime.loadClass("odf.OdfUtils"); -runtime.loadClass("odf.TextStyleApplicator"); ops.OpApplyDirectStyling = function OpApplyDirectStyling() { var memberid, timestamp, position, length, setProperties, odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils; this.init = function(data) { @@ -13201,6 +10667,7 @@ ops.OpApplyDirectStyling = function OpApplyDirectStyling() { setProperties = data.setProperties }; this.isEdit = true; + this.group = undefined; function applyStyle(odtDocument, range, info) { var odfCanvas = odtDocument.getOdfCanvas(), odfContainer = odfCanvas.odfContainer(), nextTextNodes = domUtils.splitBoundaries(range), textNodes = odfUtils.getTextNodes(range, false), limits, textStyles; limits = {startContainer:range.startContainer, startOffset:range.startOffset, endContainer:range.endContainer, endOffset:range.endOffset}; @@ -13208,8 +10675,8 @@ ops.OpApplyDirectStyling = function OpApplyDirectStyling() { textStyles.applyStyle(textNodes, limits, info); nextTextNodes.forEach(domUtils.normalizeTextNodes) } - this.execute = function(odtDocument) { - var range = odtDocument.convertCursorToDomRange(position, length), impactedParagraphs = odfUtils.getImpactedParagraphs(range); + this.execute = function(document) { + var odtDocument = (document), range = odtDocument.convertCursorToDomRange(position, length), impactedParagraphs = odfUtils.getParagraphElements(range); applyStyle(odtDocument, range, setProperties); range.detach(); odtDocument.getOdfCanvas().refreshCSS(); @@ -13225,6 +10692,100 @@ ops.OpApplyDirectStyling = function OpApplyDirectStyling() { } }; ops.OpApplyDirectStyling.Spec; +ops.OpApplyDirectStyling.InitSpec; +/* + + Copyright (C) 2012-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/ +*/ +ops.OpApplyHyperlink = function OpApplyHyperlink() { + var memberid, timestamp, position, length, hyperlink, domUtils = new core.DomUtils, odfUtils = new odf.OdfUtils; + this.init = function(data) { + memberid = data.memberid; + timestamp = data.timestamp; + position = data.position; + length = data.length; + hyperlink = data.hyperlink + }; + this.isEdit = true; + this.group = undefined; + function createHyperlink(document, hyperlink) { + var node = document.createElementNS(odf.Namespaces.textns, "text:a"); + node.setAttributeNS(odf.Namespaces.xlinkns, "xlink:type", "simple"); + node.setAttributeNS(odf.Namespaces.xlinkns, "xlink:href", hyperlink); + return node + } + function isPartOfLink(node) { + while(node) { + if(odfUtils.isHyperlink(node)) { + return true + } + node = node.parentNode + } + return false + } + this.execute = function(document) { + var odtDocument = (document), ownerDocument = odtDocument.getDOMDocument(), range = odtDocument.convertCursorToDomRange(position, length), boundaryNodes = domUtils.splitBoundaries(range), modifiedParagraphs = [], textNodes = odfUtils.getTextNodes(range, false); + if(textNodes.length === 0) { + return false + } + textNodes.forEach(function(node) { + var linkNode, paragraph = odfUtils.getParagraphElement(node); + runtime.assert(isPartOfLink(node) === false, "The given range should not contain any link."); + linkNode = createHyperlink(ownerDocument, hyperlink); + node.parentNode.insertBefore(linkNode, node); + linkNode.appendChild(node); + if(modifiedParagraphs.indexOf(paragraph) === -1) { + modifiedParagraphs.push(paragraph) + } + }); + boundaryNodes.forEach(domUtils.normalizeTextNodes); + range.detach(); + odtDocument.getOdfCanvas().refreshSize(); + odtDocument.getOdfCanvas().rerenderAnnotations(); + modifiedParagraphs.forEach(function(paragraph) { + odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:paragraph, memberId:memberid, timeStamp:timestamp}) + }); + return true + }; + this.spec = function() { + return{optype:"ApplyHyperlink", memberid:memberid, timestamp:timestamp, position:position, length:length, hyperlink:hyperlink} + } +}; +ops.OpApplyHyperlink.Spec; +ops.OpApplyHyperlink.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -13275,6 +10836,7 @@ ops.OpInsertImage = function OpInsertImage() { frameName = data.frameName }; this.isEdit = true; + this.group = undefined; function createFrameElement(document) { var imageNode = document.createElementNS(drawns, "draw:image"), frameNode = document.createElementNS(drawns, "draw:frame"); imageNode.setAttributeNS(xlinkns, "xlink:href", filename); @@ -13289,15 +10851,15 @@ ops.OpInsertImage = function OpInsertImage() { frameNode.appendChild(imageNode); return frameNode } - this.execute = function(odtDocument) { - var odfCanvas = odtDocument.getOdfCanvas(), domPosition = odtDocument.getTextNodeAtStep(position, memberid), textNode, refNode, paragraphElement, frameElement; + this.execute = function(document) { + var odtDocument = (document), odfCanvas = odtDocument.getOdfCanvas(), domPosition = odtDocument.getTextNodeAtStep(position, memberid), textNode, refNode, paragraphElement, frameElement; if(!domPosition) { return false } textNode = domPosition.textNode; paragraphElement = odtDocument.getParagraphElement(textNode); refNode = domPosition.offset !== textNode.length ? textNode.splitText(domPosition.offset) : textNode.nextSibling; - frameElement = createFrameElement(odtDocument.getDOM()); + frameElement = createFrameElement(odtDocument.getDOMDocument()); textNode.parentNode.insertBefore(frameElement, refNode); odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position:position, length:1}); if(textNode.length === 0) { @@ -13313,6 +10875,8 @@ ops.OpInsertImage = function OpInsertImage() { return{optype:"InsertImage", memberid:memberid, timestamp:timestamp, filename:filename, position:position, frameWidth:frameWidth, frameHeight:frameHeight, frameStyleName:frameStyleName, frameName:frameName} } }; +ops.OpInsertImage.Spec; +ops.OpInsertImage.InitSpec; /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -13364,6 +10928,7 @@ ops.OpInsertTable = function OpInsertTable() { tableCellStyleMatrix = data.tableCellStyleMatrix }; this.isEdit = true; + this.group = undefined; function getCellStyleName(row, column) { var rowStyles; if(tableCellStyleMatrix.length === 1) { @@ -13429,10 +10994,10 @@ ops.OpInsertTable = function OpInsertTable() { } return tableNode } - this.execute = function(odtDocument) { - var domPosition = odtDocument.getTextNodeAtStep(position), rootNode = odtDocument.getRootNode(), previousSibling, tableNode; + this.execute = function(document) { + var odtDocument = (document), domPosition = odtDocument.getTextNodeAtStep(position), rootNode = odtDocument.getRootNode(), previousSibling, tableNode; if(domPosition) { - tableNode = createTableNode(odtDocument.getDOM()); + tableNode = createTableNode(odtDocument.getDOMDocument()); previousSibling = odtDocument.getParagraphElement(domPosition.textNode); rootNode.insertBefore(tableNode, previousSibling.nextSibling); odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position:position, length:initialColumns * initialRows + 1}); @@ -13447,6 +11012,8 @@ ops.OpInsertTable = function OpInsertTable() { return{optype:"InsertTable", memberid:memberid, timestamp:timestamp, position:position, initialRows:initialRows, initialColumns:initialColumns, tableName:tableName, tableStyleName:tableStyleName, tableColumnStyleName:tableColumnStyleName, tableCellStyleMatrix:tableCellStyleMatrix} } }; +ops.OpInsertTable.Spec; +ops.OpInsertTable.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -13485,7 +11052,7 @@ ops.OpInsertTable = function OpInsertTable() { @source: https://github.com/kogmbh/WebODF/ */ ops.OpInsertText = function OpInsertText() { - var space = " ", tab = "\t", memberid, timestamp, position, text, moveCursor; + var space = " ", tab = "\t", memberid, timestamp, position, moveCursor, text; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; @@ -13494,6 +11061,7 @@ ops.OpInsertText = function OpInsertText() { moveCursor = data.moveCursor === "true" || data.moveCursor === true }; this.isEdit = true; + this.group = undefined; function triggerLayoutInWebkit(textNode) { var parent = textNode.parentNode, next = textNode.nextSibling; parent.removeChild(textNode); @@ -13502,8 +11070,8 @@ ops.OpInsertText = function OpInsertText() { function requiresSpaceElement(text, index) { return text[index] === space && (index === 0 || (index === text.length - 1 || text[index - 1] === space)) } - this.execute = function(odtDocument) { - var domPosition, previousNode, parentElement, nextNode = null, ownerDocument = odtDocument.getDOM(), paragraphElement, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", toInsertIndex = 0, spaceTag, spaceElement, cursor = odtDocument.getCursor(memberid), i; + this.execute = function(document) { + var odtDocument = (document), domPosition, previousNode, parentElement, nextNode = null, ownerDocument = odtDocument.getDOMDocument(), paragraphElement, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", toInsertIndex = 0, spaceTag, spaceElement, cursor = odtDocument.getCursor(memberid), i; function insertTextNode(toInsertText) { parentElement.insertBefore(ownerDocument.createTextNode(toInsertText), nextNode) } @@ -13512,7 +11080,7 @@ ops.OpInsertText = function OpInsertText() { if(domPosition) { previousNode = domPosition.textNode; nextNode = previousNode.nextSibling; - parentElement = previousNode.parentNode; + parentElement = (previousNode.parentNode); paragraphElement = odtDocument.getParagraphElement(previousNode); for(i = 0;i < text.length;i += 1) { if(requiresSpaceElement(text, i) || text[i] === tab) { @@ -13549,7 +11117,7 @@ ops.OpInsertText = function OpInsertText() { odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position:position, length:text.length}); if(cursor && moveCursor) { odtDocument.moveCursor(memberid, position + text.length, 0); - odtDocument.emit(ops.OdtDocument.signalCursorMoved, cursor) + odtDocument.emit(ops.Document.signalCursorMoved, cursor) } if(position > 0) { if(position > 1) { @@ -13572,6 +11140,7 @@ ops.OpInsertText = function OpInsertText() { } }; ops.OpInsertText.Spec; +ops.OpInsertText.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -13619,15 +11188,16 @@ ops.OpMoveCursor = function OpMoveCursor() { selectionType = data.selectionType || ops.OdtCursor.RangeSelection }; this.isEdit = false; - this.execute = function(odtDocument) { - var cursor = odtDocument.getCursor(memberid), selectedRange; + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document), cursor = odtDocument.getCursor(memberid), selectedRange; if(!cursor) { return false } selectedRange = odtDocument.convertCursorToDomRange(position, length); cursor.setSelectedRange(selectedRange, length >= 0); cursor.setSelectionType(selectionType); - odtDocument.emit(ops.OdtDocument.signalCursorMoved, cursor); + odtDocument.emit(ops.Document.signalCursorMoved, cursor); return true }; this.spec = function() { @@ -13635,6 +11205,7 @@ ops.OpMoveCursor = function OpMoveCursor() { } }; ops.OpMoveCursor.Spec; +ops.OpMoveCursor.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -13672,8 +11243,6 @@ ops.OpMoveCursor.Spec; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces"); -runtime.loadClass("core.DomUtils"); ops.OpRemoveAnnotation = function OpRemoveAnnotation() { var memberid, timestamp, position, length, domUtils; this.init = function(data) { @@ -13684,26 +11253,23 @@ ops.OpRemoveAnnotation = function OpRemoveAnnotation() { domUtils = new core.DomUtils }; this.isEdit = true; - this.execute = function(odtDocument) { - var iterator = odtDocument.getIteratorAtPosition(position), container = iterator.container(), annotationName, annotationNode, annotationEnd, cursors; + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document), iterator = odtDocument.getIteratorAtPosition(position), container = iterator.container(), annotationNode, annotationEnd; while(!(container.namespaceURI === odf.Namespaces.officens && container.localName === "annotation")) { container = container.parentNode } if(container === null) { return false } - annotationNode = container; - annotationName = annotationNode.getAttributeNS(odf.Namespaces.officens, "name"); - if(annotationName) { - annotationEnd = domUtils.getElementsByTagNameNS(odtDocument.getRootNode(), odf.Namespaces.officens, "annotation-end").filter(function(element) { - return annotationName === element.getAttributeNS(odf.Namespaces.officens, "name") - })[0] || null - } + annotationNode = (container); + annotationEnd = annotationNode.annotationEndElement; odtDocument.getOdfCanvas().forgetAnnotations(); - cursors = domUtils.getElementsByTagNameNS(annotationNode, "urn:webodf:names:cursor", "cursor"); - while(cursors.length) { - annotationNode.parentNode.insertBefore(cursors.pop(), annotationNode) + function insert(node) { + (annotationNode).parentNode.insertBefore(node, annotationNode) } + domUtils.getElementsByTagNameNS(annotationNode, "urn:webodf:names:cursor", "cursor").forEach(insert); + domUtils.getElementsByTagNameNS(annotationNode, "urn:webodf:names:cursor", "anchor").forEach(insert); annotationNode.parentNode.removeChild(annotationNode); if(annotationEnd) { annotationEnd.parentNode.removeChild(annotationEnd) @@ -13717,6 +11283,8 @@ ops.OpRemoveAnnotation = function OpRemoveAnnotation() { return{optype:"RemoveAnnotation", memberid:memberid, timestamp:timestamp, position:position, length:length} } }; +ops.OpRemoveAnnotation.Spec; +ops.OpRemoveAnnotation.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -13762,7 +11330,9 @@ ops.OpRemoveBlob = function OpRemoveBlob() { filename = data.filename }; this.isEdit = true; - this.execute = function(odtDocument) { + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document); odtDocument.getOdfCanvas().odfContainer().removeBlob(filename); return true }; @@ -13770,6 +11340,8 @@ ops.OpRemoveBlob = function OpRemoveBlob() { return{optype:"RemoveBlob", memberid:memberid, timestamp:timestamp, filename:filename} } }; +ops.OpRemoveBlob.Spec; +ops.OpRemoveBlob.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -13814,7 +11386,9 @@ ops.OpRemoveCursor = function OpRemoveCursor() { timestamp = data.timestamp }; this.isEdit = false; - this.execute = function(odtDocument) { + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document); if(!odtDocument.removeCursor(memberid)) { return false } @@ -13825,6 +11399,70 @@ ops.OpRemoveCursor = function OpRemoveCursor() { } }; ops.OpRemoveCursor.Spec; +ops.OpRemoveCursor.InitSpec; +/* + + Copyright (C) 2012-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/ +*/ +ops.OpRemoveHyperlink = function OpRemoveHyperlink() { + var memberid, timestamp, position, length, domUtils = new core.DomUtils, odfUtils = new odf.OdfUtils; + this.init = function(data) { + memberid = data.memberid; + timestamp = data.timestamp; + position = data.position; + length = data.length + }; + this.isEdit = true; + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document), range = odtDocument.convertCursorToDomRange(position, length), links = odfUtils.getHyperlinkElements(range), node; + runtime.assert(links.length === 1, "The given range should only contain a single link."); + node = domUtils.mergeIntoParent((links[0])); + range.detach(); + odtDocument.getOdfCanvas().refreshSize(); + odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:odfUtils.getParagraphElement(node), memberId:memberid, timeStamp:timestamp}); + odtDocument.getOdfCanvas().rerenderAnnotations(); + return true + }; + this.spec = function() { + return{optype:"RemoveHyperlink", memberid:memberid, timestamp:timestamp, position:position, length:length} + } +}; +ops.OpRemoveHyperlink.Spec; +ops.OpRemoveHyperlink.InitSpec; /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -13849,7 +11487,6 @@ ops.OpRemoveCursor.Spec; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.Member"); ops.OpRemoveMember = function OpRemoveMember() { var memberid, timestamp; this.init = function(data) { @@ -13857,18 +11494,22 @@ ops.OpRemoveMember = function OpRemoveMember() { timestamp = parseInt(data.timestamp, 10) }; this.isEdit = false; - this.execute = function(odtDocument) { + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document); if(!odtDocument.getMember(memberid)) { return false } odtDocument.removeMember(memberid); - odtDocument.emit(ops.OdtDocument.signalMemberRemoved, memberid); + odtDocument.emit(ops.Document.signalMemberRemoved, memberid); return true }; this.spec = function() { return{optype:"RemoveMember", memberid:memberid, timestamp:timestamp} } }; +ops.OpRemoveMember.Spec; +ops.OpRemoveMember.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -13915,8 +11556,9 @@ ops.OpRemoveStyle = function OpRemoveStyle() { styleFamily = data.styleFamily }; this.isEdit = true; - this.execute = function(odtDocument) { - var styleNode = odtDocument.getStyleElement(styleName, styleFamily); + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document), styleNode = odtDocument.getStyleElement(styleName, styleFamily); if(!styleNode) { return false } @@ -13930,6 +11572,7 @@ ops.OpRemoveStyle = function OpRemoveStyle() { } }; ops.OpRemoveStyle.Spec; +ops.OpRemoveStyle.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -13967,9 +11610,6 @@ ops.OpRemoveStyle.Spec; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces"); -runtime.loadClass("odf.OdfUtils"); -runtime.loadClass("core.DomUtils"); ops.OpRemoveText = function OpRemoveText() { var memberid, timestamp, position, length, odfUtils, domUtils, editinfons = "urn:webodf:names:editinfo", odfNodeNamespaceMap = {}; this.init = function(data) { @@ -13995,6 +11635,7 @@ ops.OpRemoveText = function OpRemoveText() { odfNodeNamespaceMap[odf.Namespaces.textns] = true }; this.isEdit = true; + this.group = undefined; function CollapsingRules(rootNode) { function isOdfNode(node) { return odfNodeNamespaceMap.hasOwnProperty(node.namespaceURI) @@ -14031,7 +11672,7 @@ ops.OpRemoveText = function OpRemoveText() { }else { parent = domUtils.removeUnwantedNodes(targetNode, shouldRemove) } - if(isCollapsibleContainer(parent)) { + if(parent && isCollapsibleContainer(parent)) { return mergeChildrenIntoParent(parent) } return parent @@ -14039,19 +11680,18 @@ ops.OpRemoveText = function OpRemoveText() { this.mergeChildrenIntoParent = mergeChildrenIntoParent } function mergeParagraphs(first, second, collapseRules) { - var child, mergeForward = false, destination = first, source = second, secondParent, insertionPoint = null; + var child, destination = first, source = second, secondParent, insertionPoint = null; if(collapseRules.isEmpty(first)) { - mergeForward = true; if(second.parentNode !== first.parentNode) { secondParent = second.parentNode; first.parentNode.insertBefore(second, first.nextSibling) } source = first; destination = second; - insertionPoint = destination.getElementsByTagNameNS(editinfons, "editinfo")[0] || destination.firstChild + insertionPoint = destination.getElementsByTagNameNS(editinfons, "editinfo").item(0) || destination.firstChild } - while(source.hasChildNodes()) { - child = mergeForward ? source.lastChild : source.firstChild; + while(source.firstChild) { + child = source.firstChild; source.removeChild(child); if(child.localName !== "editinfo") { destination.insertBefore(child, insertionPoint) @@ -14063,8 +11703,8 @@ ops.OpRemoveText = function OpRemoveText() { collapseRules.mergeChildrenIntoParent(source); return destination } - this.execute = function(odtDocument) { - var paragraphElement, destinationParagraph, range, textNodes, paragraphs, cursor = odtDocument.getCursor(memberid), collapseRules = new CollapsingRules(odtDocument.getRootNode()); + this.execute = function(document) { + var odtDocument = (document), paragraphElement, destinationParagraph, range, textNodes, paragraphs, cursor = odtDocument.getCursor(memberid), collapseRules = new CollapsingRules(odtDocument.getRootNode()); odtDocument.upgradeWhitespacesAtPosition(position); odtDocument.upgradeWhitespacesAtPosition(position + length); range = odtDocument.convertCursorToDomRange(position, length); @@ -14076,9 +11716,10 @@ ops.OpRemoveText = function OpRemoveText() { textNodes.forEach(function(element) { collapseRules.mergeChildrenIntoParent(element) }); - destinationParagraph = paragraphs.reduce(function(destination, paragraph) { + function merge(destination, paragraph) { return mergeParagraphs(destination, paragraph, collapseRules) - }); + } + destinationParagraph = paragraphs.reduce(merge); odtDocument.emit(ops.OdtDocument.signalStepsRemoved, {position:position, length:length}); odtDocument.downgradeWhitespacesAtPosition(position); odtDocument.fixCursorPositions(); @@ -14086,7 +11727,7 @@ ops.OpRemoveText = function OpRemoveText() { odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:destinationParagraph || paragraphElement, memberId:memberid, timeStamp:timestamp}); if(cursor) { cursor.resetSelectionType(); - odtDocument.emit(ops.OdtDocument.signalCursorMoved, cursor) + odtDocument.emit(ops.Document.signalCursorMoved, cursor) } odtDocument.getOdfCanvas().rerenderAnnotations(); return true @@ -14096,6 +11737,7 @@ ops.OpRemoveText = function OpRemoveText() { } }; ops.OpRemoveText.Spec; +ops.OpRemoveText.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -14143,7 +11785,9 @@ ops.OpSetBlob = function OpSetBlob() { content = data.content }; this.isEdit = true; - this.execute = function(odtDocument) { + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document); odtDocument.getOdfCanvas().odfContainer().setBlob(filename, mimetype, content); return true }; @@ -14151,6 +11795,8 @@ ops.OpSetBlob = function OpSetBlob() { return{optype:"SetBlob", memberid:memberid, timestamp:timestamp, filename:filename, mimetype:mimetype, content:content} } }; +ops.OpSetBlob.Spec; +ops.OpSetBlob.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -14197,8 +11843,9 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() { styleName = data.styleName }; this.isEdit = true; - this.execute = function(odtDocument) { - var iterator, paragraphNode; + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document), iterator, paragraphNode; iterator = odtDocument.getIteratorAtPosition(position); paragraphNode = odtDocument.getParagraphElement(iterator.container()); if(paragraphNode) { @@ -14219,6 +11866,7 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() { } }; ops.OpSetParagraphStyle.Spec; +ops.OpSetParagraphStyle.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -14266,8 +11914,9 @@ ops.OpSplitParagraph = function OpSplitParagraph() { odfUtils = new odf.OdfUtils }; this.isEdit = true; - this.execute = function(odtDocument) { - var domPosition, paragraphNode, targetNode, node, splitNode, splitChildNode, keptChildNode, cursor = odtDocument.getCursor(memberid); + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document), domPosition, paragraphNode, targetNode, node, splitNode, splitChildNode, keptChildNode, cursor = odtDocument.getCursor(memberid); odtDocument.upgradeWhitespacesAtPosition(position); domPosition = odtDocument.getTextNodeAtStep(position); if(!domPosition) { @@ -14314,7 +11963,7 @@ ops.OpSplitParagraph = function OpSplitParagraph() { splitChildNode = splitNode } if(odfUtils.isListItem(splitChildNode)) { - splitChildNode = splitChildNode.childNodes[0] + splitChildNode = splitChildNode.childNodes.item(0) } if(domPosition.textNode.length === 0) { domPosition.textNode.parentNode.removeChild(domPosition.textNode) @@ -14322,7 +11971,7 @@ ops.OpSplitParagraph = function OpSplitParagraph() { odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position:position, length:1}); if(cursor && moveCursor) { odtDocument.moveCursor(memberid, position + 1, 0); - odtDocument.emit(ops.OdtDocument.signalCursorMoved, cursor) + odtDocument.emit(ops.Document.signalCursorMoved, cursor) } odtDocument.fixCursorPositions(); odtDocument.getOdfCanvas().refreshSize(); @@ -14336,6 +11985,7 @@ ops.OpSplitParagraph = function OpSplitParagraph() { } }; ops.OpSplitParagraph.Spec; +ops.OpSplitParagraph.InitSpec; /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -14360,10 +12010,8 @@ ops.OpSplitParagraph.Spec; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.Member"); -runtime.loadClass("xmldom.XPath"); ops.OpUpdateMember = function OpUpdateMember() { - var memberid, timestamp, setProperties, removedProperties, doc; + var memberid, timestamp, setProperties, removedProperties; this.init = function(data) { memberid = data.memberid; timestamp = parseInt(data.timestamp, 10); @@ -14371,7 +12019,8 @@ ops.OpUpdateMember = function OpUpdateMember() { removedProperties = data.removedProperties }; this.isEdit = false; - function updateCreators() { + this.group = undefined; + function updateCreators(doc) { var xpath = xmldom.XPath, xp = "//dc:creator[@editinfo:memberid='" + memberid + "']", creators = xpath.getODFElementsWithXPath(doc.getRootNode(), xp, function(prefix) { if(prefix === "editinfo") { return"urn:webodf:names:editinfo" @@ -14382,9 +12031,8 @@ ops.OpUpdateMember = function OpUpdateMember() { creators[i].textContent = setProperties.fullName } } - this.execute = function(odtDocument) { - doc = odtDocument; - var member = odtDocument.getMember(memberid); + this.execute = function(document) { + var odtDocument = (document), member = odtDocument.getMember(memberid); if(!member) { return false } @@ -14394,16 +12042,18 @@ ops.OpUpdateMember = function OpUpdateMember() { if(setProperties) { member.setProperties(setProperties); if(setProperties.fullName) { - updateCreators() + updateCreators(odtDocument) } } - odtDocument.emit(ops.OdtDocument.signalMemberUpdated, member); + odtDocument.emit(ops.Document.signalMemberUpdated, member); return true }; this.spec = function() { return{optype:"UpdateMember", memberid:memberid, timestamp:timestamp, setProperties:setProperties, removedProperties:removedProperties} } }; +ops.OpUpdateMember.Spec; +ops.OpUpdateMember.InitSpec; /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -14437,21 +12087,10 @@ ops.OpUpdateMetadata = function OpUpdateMetadata() { removedProperties = data.removedProperties }; this.isEdit = true; - this.execute = function(odtDocument) { - var odfContainer = odtDocument.getOdfCanvas().odfContainer(), removedPropertiesArray = [], blockedProperties = ["dc:date", "dc:creator", "meta:editing-cycles"]; - if(setProperties) { - blockedProperties.forEach(function(el) { - if(setProperties[el]) { - return false - } - }) - } + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document), odfContainer = odtDocument.getOdfCanvas().odfContainer(), removedPropertiesArray = []; if(removedProperties) { - blockedProperties.forEach(function(el) { - if(removedPropertiesArray.indexOf(el) !== -1) { - return false - } - }); removedPropertiesArray = removedProperties.attributes.split(",") } odfContainer.setMetadata(setProperties, removedPropertiesArray); @@ -14461,6 +12100,8 @@ ops.OpUpdateMetadata = function OpUpdateMetadata() { return{optype:"UpdateMetadata", memberid:memberid, timestamp:timestamp, setProperties:setProperties, removedProperties:removedProperties} } }; +ops.OpUpdateMetadata.Spec; +ops.OpUpdateMetadata.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -14498,14 +12139,13 @@ ops.OpUpdateMetadata = function OpUpdateMetadata() { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces"); ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { var memberid, timestamp, styleName, setProperties, removedProperties, paragraphPropertiesName = "style:paragraph-properties", textPropertiesName = "style:text-properties", stylens = odf.Namespaces.stylens; function removedAttributesFromStyleNode(node, removedAttributeNames) { var i, attributeNameParts, attributeNameList = removedAttributeNames ? removedAttributeNames.split(",") : []; for(i = 0;i < attributeNameList.length;i += 1) { attributeNameParts = attributeNameList[i].split(":"); - node.removeAttributeNS(odf.Namespaces.lookupNamespaceURI(attributeNameParts[0]), attributeNameParts[1]) + node.removeAttributeNS((odf.Namespaces.lookupNamespaceURI(attributeNameParts[0])), attributeNameParts[1]) } } this.init = function(data) { @@ -14516,28 +12156,31 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { removedProperties = data.removedProperties }; this.isEdit = true; - this.execute = function(odtDocument) { - var formatting = odtDocument.getFormatting(), styleNode, paragraphPropertiesNode, textPropertiesNode; + this.group = undefined; + this.execute = function(document) { + var odtDocument = (document), formatting = odtDocument.getFormatting(), styleNode, object, paragraphPropertiesNode, textPropertiesNode; if(styleName !== "") { styleNode = odtDocument.getParagraphStyleElement(styleName) }else { styleNode = formatting.getDefaultStyleElement("paragraph") } if(styleNode) { - paragraphPropertiesNode = styleNode.getElementsByTagNameNS(stylens, "paragraph-properties")[0]; - textPropertiesNode = styleNode.getElementsByTagNameNS(stylens, "text-properties")[0]; + paragraphPropertiesNode = (styleNode.getElementsByTagNameNS(stylens, "paragraph-properties").item(0)); + textPropertiesNode = (styleNode.getElementsByTagNameNS(stylens, "text-properties").item(0)); if(setProperties) { formatting.updateStyle(styleNode, setProperties) } if(removedProperties) { - if(removedProperties[paragraphPropertiesName]) { - removedAttributesFromStyleNode(paragraphPropertiesNode, removedProperties[paragraphPropertiesName].attributes); + object = (removedProperties[paragraphPropertiesName]); + if(paragraphPropertiesNode && object) { + removedAttributesFromStyleNode(paragraphPropertiesNode, object.attributes); if(paragraphPropertiesNode.attributes.length === 0) { styleNode.removeChild(paragraphPropertiesNode) } } - if(removedProperties[textPropertiesName]) { - removedAttributesFromStyleNode(textPropertiesNode, removedProperties[textPropertiesName].attributes); + object = (removedProperties[textPropertiesName]); + if(textPropertiesNode && object) { + removedAttributesFromStyleNode(textPropertiesNode, object.attributes); if(textPropertiesNode.attributes.length === 0) { styleNode.removeChild(textPropertiesNode) } @@ -14556,6 +12199,7 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { } }; ops.OpUpdateParagraphStyle.Spec; +ops.OpUpdateParagraphStyle.InitSpec; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -14593,48 +12237,22 @@ ops.OpUpdateParagraphStyle.Spec; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.OpAddMember"); -runtime.loadClass("ops.OpUpdateMember"); -runtime.loadClass("ops.OpRemoveMember"); -runtime.loadClass("ops.OpAddCursor"); -runtime.loadClass("ops.OpApplyDirectStyling"); -runtime.loadClass("ops.OpRemoveCursor"); -runtime.loadClass("ops.OpMoveCursor"); -runtime.loadClass("ops.OpSetBlob"); -runtime.loadClass("ops.OpRemoveBlob"); -runtime.loadClass("ops.OpInsertImage"); -runtime.loadClass("ops.OpInsertTable"); -runtime.loadClass("ops.OpInsertText"); -runtime.loadClass("ops.OpRemoveText"); -runtime.loadClass("ops.OpSplitParagraph"); -runtime.loadClass("ops.OpSetParagraphStyle"); -runtime.loadClass("ops.OpUpdateParagraphStyle"); -runtime.loadClass("ops.OpAddStyle"); -runtime.loadClass("ops.OpRemoveStyle"); -runtime.loadClass("ops.OpAddAnnotation"); -runtime.loadClass("ops.OpRemoveAnnotation"); -runtime.loadClass("ops.OpUpdateMetadata"); ops.OperationFactory = function OperationFactory() { var specs; this.register = function(specName, specConstructor) { specs[specName] = specConstructor }; this.create = function(spec) { - var op = null, specConstructor = specs[spec.optype]; - if(specConstructor) { - op = specConstructor(spec); + var op = null, Constructor = specs[spec.optype]; + if(Constructor) { + op = new Constructor; op.init(spec) } return op }; - function constructor(OperationType) { - return function() { - return new OperationType - } - } function init() { - specs = {AddMember:constructor(ops.OpAddMember), UpdateMember:constructor(ops.OpUpdateMember), RemoveMember:constructor(ops.OpRemoveMember), AddCursor:constructor(ops.OpAddCursor), ApplyDirectStyling:constructor(ops.OpApplyDirectStyling), SetBlob:constructor(ops.OpSetBlob), RemoveBlob:constructor(ops.OpRemoveBlob), InsertImage:constructor(ops.OpInsertImage), InsertTable:constructor(ops.OpInsertTable), InsertText:constructor(ops.OpInsertText), RemoveText:constructor(ops.OpRemoveText), SplitParagraph:constructor(ops.OpSplitParagraph), - SetParagraphStyle:constructor(ops.OpSetParagraphStyle), UpdateParagraphStyle:constructor(ops.OpUpdateParagraphStyle), AddStyle:constructor(ops.OpAddStyle), RemoveStyle:constructor(ops.OpRemoveStyle), MoveCursor:constructor(ops.OpMoveCursor), RemoveCursor:constructor(ops.OpRemoveCursor), AddAnnotation:constructor(ops.OpAddAnnotation), RemoveAnnotation:constructor(ops.OpRemoveAnnotation), UpdateMetadata:constructor(ops.OpUpdateMetadata)} + specs = {AddMember:ops.OpAddMember, UpdateMember:ops.OpUpdateMember, RemoveMember:ops.OpRemoveMember, AddCursor:ops.OpAddCursor, ApplyDirectStyling:ops.OpApplyDirectStyling, SetBlob:ops.OpSetBlob, RemoveBlob:ops.OpRemoveBlob, InsertImage:ops.OpInsertImage, InsertTable:ops.OpInsertTable, InsertText:ops.OpInsertText, RemoveText:ops.OpRemoveText, SplitParagraph:ops.OpSplitParagraph, SetParagraphStyle:ops.OpSetParagraphStyle, UpdateParagraphStyle:ops.OpUpdateParagraphStyle, AddStyle:ops.OpAddStyle, + RemoveStyle:ops.OpRemoveStyle, MoveCursor:ops.OpMoveCursor, RemoveCursor:ops.OpRemoveCursor, AddAnnotation:ops.OpAddAnnotation, RemoveAnnotation:ops.OpRemoveAnnotation, UpdateMetadata:ops.OpUpdateMetadata, ApplyHyperlink:ops.OpApplyHyperlink, RemoveHyperlink:ops.OpRemoveHyperlink} } init() }; @@ -14693,688 +12311,8 @@ ops.OperationRouter.prototype.hasLocalUnsyncedOps = function() { }; ops.OperationRouter.prototype.hasSessionHostConnection = function() { }; -/* - - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> - - @licstart - This file is part of WebODF. - - WebODF 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. - - WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. - @licend - - @source: http://www.webodf.org/ - @source: https://github.com/kogmbh/WebODF/ -*/ -ops.OperationTransformMatrix = function OperationTransformMatrix() { - function invertMoveCursorSpecRange(moveCursorSpec) { - moveCursorSpec.position = moveCursorSpec.position + moveCursorSpec.length; - moveCursorSpec.length *= -1 - } - function invertMoveCursorSpecRangeOnNegativeLength(moveCursorSpec) { - var isBackwards = moveCursorSpec.length < 0; - if(isBackwards) { - invertMoveCursorSpecRange(moveCursorSpec) - } - return isBackwards - } - function getStyleReferencingAttributes(setProperties, styleName) { - var attributes = []; - if(setProperties) { - ["style:parent-style-name", "style:next-style-name"].forEach(function(attributeName) { - if(setProperties[attributeName] === styleName) { - attributes.push(attributeName) - } - }) - } - return attributes - } - function dropStyleReferencingAttributes(setProperties, deletedStyleName) { - if(setProperties) { - ["style:parent-style-name", "style:next-style-name"].forEach(function(attributeName) { - if(setProperties[attributeName] === deletedStyleName) { - delete setProperties[attributeName] - } - }) - } - } - function cloneOpspec(opspec) { - var result = {}; - Object.keys(opspec).forEach(function(key) { - if(typeof opspec[key] === "object") { - result[key] = cloneOpspec(opspec[key]) - }else { - result[key] = opspec[key] - } - }); - return result - } - function dropOverruledAndUnneededAttributes(minorSetProperties, minorRemovedProperties, majorSetProperties, majorRemovedProperties) { - var value, i, name, majorChanged = false, minorChanged = false, overrulingPropertyValue, removedPropertyNames, majorRemovedPropertyNames = majorRemovedProperties && majorRemovedProperties.attributes ? majorRemovedProperties.attributes.split(",") : []; - if(minorSetProperties && (majorSetProperties || majorRemovedPropertyNames.length > 0)) { - Object.keys(minorSetProperties).forEach(function(key) { - value = minorSetProperties[key]; - if(typeof value !== "object") { - overrulingPropertyValue = majorSetProperties && majorSetProperties[key]; - if(overrulingPropertyValue !== undefined) { - delete minorSetProperties[key]; - minorChanged = true; - if(overrulingPropertyValue === value) { - delete majorSetProperties[key]; - majorChanged = true - } - }else { - if(majorRemovedPropertyNames && majorRemovedPropertyNames.indexOf(key) !== -1) { - delete minorSetProperties[key]; - minorChanged = true - } - } - } - }) - } - if(minorRemovedProperties && (minorRemovedProperties.attributes && (majorSetProperties || majorRemovedPropertyNames.length > 0))) { - removedPropertyNames = minorRemovedProperties.attributes.split(","); - for(i = 0;i < removedPropertyNames.length;i += 1) { - name = removedPropertyNames[i]; - if(majorSetProperties && majorSetProperties[name] !== undefined || majorRemovedPropertyNames && majorRemovedPropertyNames.indexOf(name) !== -1) { - removedPropertyNames.splice(i, 1); - i -= 1; - minorChanged = true - } - } - if(removedPropertyNames.length > 0) { - minorRemovedProperties.attributes = removedPropertyNames.join(",") - }else { - delete minorRemovedProperties.attributes - } - } - return{majorChanged:majorChanged, minorChanged:minorChanged} - } - function hasProperties(properties) { - var key; - for(key in properties) { - if(properties.hasOwnProperty(key)) { - return true - } - } - return false - } - function hasRemovedProperties(properties) { - var key; - for(key in properties) { - if(properties.hasOwnProperty(key)) { - if(key !== "attributes" || properties.attributes.length > 0) { - return true - } - } - } - return false - } - function dropOverruledAndUnneededProperties(minorOpspec, majorOpspec, propertiesName) { - var minorSP = minorOpspec.setProperties ? minorOpspec.setProperties[propertiesName] : null, minorRP = minorOpspec.removedProperties ? minorOpspec.removedProperties[propertiesName] : null, majorSP = majorOpspec.setProperties ? majorOpspec.setProperties[propertiesName] : null, majorRP = majorOpspec.removedProperties ? majorOpspec.removedProperties[propertiesName] : null, result; - result = dropOverruledAndUnneededAttributes(minorSP, minorRP, majorSP, majorRP); - if(minorSP && !hasProperties(minorSP)) { - delete minorOpspec.setProperties[propertiesName] - } - if(minorRP && !hasRemovedProperties(minorRP)) { - delete minorOpspec.removedProperties[propertiesName] - } - if(majorSP && !hasProperties(majorSP)) { - delete majorOpspec.setProperties[propertiesName] - } - if(majorRP && !hasRemovedProperties(majorRP)) { - delete majorOpspec.removedProperties[propertiesName] - } - return result - } - function transformAddStyleRemoveStyle(addStyleSpec, removeStyleSpec) { - var setAttributes, helperOpspec, addStyleSpecResult = [addStyleSpec], removeStyleSpecResult = [removeStyleSpec]; - if(addStyleSpec.styleFamily === removeStyleSpec.styleFamily) { - setAttributes = getStyleReferencingAttributes(addStyleSpec.setProperties, removeStyleSpec.styleName); - if(setAttributes.length > 0) { - helperOpspec = {optype:"UpdateParagraphStyle", memberid:removeStyleSpec.memberid, timestamp:removeStyleSpec.timestamp, styleName:addStyleSpec.styleName, removedProperties:{attributes:setAttributes.join(",")}}; - removeStyleSpecResult.unshift(helperOpspec) - } - dropStyleReferencingAttributes(addStyleSpec.setProperties, removeStyleSpec.styleName) - } - return{opSpecsA:addStyleSpecResult, opSpecsB:removeStyleSpecResult} - } - function transformApplyDirectStylingApplyDirectStyling(applyDirectStylingSpecA, applyDirectStylingSpecB, hasAPriority) { - var majorSpec, minorSpec, majorSpecResult, minorSpecResult, majorSpecEnd, minorSpecEnd, dropResult, originalMajorSpec, originalMinorSpec, helperOpspecBefore, helperOpspecAfter, applyDirectStylingSpecAResult = [applyDirectStylingSpecA], applyDirectStylingSpecBResult = [applyDirectStylingSpecB]; - if(!(applyDirectStylingSpecA.position + applyDirectStylingSpecA.length <= applyDirectStylingSpecB.position || applyDirectStylingSpecA.position >= applyDirectStylingSpecB.position + applyDirectStylingSpecB.length)) { - majorSpec = hasAPriority ? applyDirectStylingSpecA : applyDirectStylingSpecB; - minorSpec = hasAPriority ? applyDirectStylingSpecB : applyDirectStylingSpecA; - if(applyDirectStylingSpecA.position !== applyDirectStylingSpecB.position || applyDirectStylingSpecA.length !== applyDirectStylingSpecB.length) { - originalMajorSpec = cloneOpspec(majorSpec); - originalMinorSpec = cloneOpspec(minorSpec) - } - dropResult = dropOverruledAndUnneededProperties(minorSpec, majorSpec, "style:text-properties"); - if(dropResult.majorChanged || dropResult.minorChanged) { - majorSpecResult = []; - minorSpecResult = []; - majorSpecEnd = majorSpec.position + majorSpec.length; - minorSpecEnd = minorSpec.position + minorSpec.length; - if(minorSpec.position < majorSpec.position) { - if(dropResult.minorChanged) { - helperOpspecBefore = cloneOpspec((originalMinorSpec)); - helperOpspecBefore.length = majorSpec.position - minorSpec.position; - minorSpecResult.push(helperOpspecBefore); - minorSpec.position = majorSpec.position; - minorSpec.length = minorSpecEnd - minorSpec.position - } - }else { - if(majorSpec.position < minorSpec.position) { - if(dropResult.majorChanged) { - helperOpspecBefore = cloneOpspec((originalMajorSpec)); - helperOpspecBefore.length = minorSpec.position - majorSpec.position; - majorSpecResult.push(helperOpspecBefore); - majorSpec.position = minorSpec.position; - majorSpec.length = majorSpecEnd - majorSpec.position - } - } - } - if(minorSpecEnd > majorSpecEnd) { - if(dropResult.minorChanged) { - helperOpspecAfter = originalMinorSpec; - helperOpspecAfter.position = majorSpecEnd; - helperOpspecAfter.length = minorSpecEnd - majorSpecEnd; - minorSpecResult.push(helperOpspecAfter); - minorSpec.length = majorSpecEnd - minorSpec.position - } - }else { - if(majorSpecEnd > minorSpecEnd) { - if(dropResult.majorChanged) { - helperOpspecAfter = originalMajorSpec; - helperOpspecAfter.position = minorSpecEnd; - helperOpspecAfter.length = majorSpecEnd - minorSpecEnd; - majorSpecResult.push(helperOpspecAfter); - majorSpec.length = minorSpecEnd - majorSpec.position - } - } - } - if(majorSpec.setProperties && hasProperties(majorSpec.setProperties)) { - majorSpecResult.push(majorSpec) - } - if(minorSpec.setProperties && hasProperties(minorSpec.setProperties)) { - minorSpecResult.push(minorSpec) - } - if(hasAPriority) { - applyDirectStylingSpecAResult = majorSpecResult; - applyDirectStylingSpecBResult = minorSpecResult - }else { - applyDirectStylingSpecAResult = minorSpecResult; - applyDirectStylingSpecBResult = majorSpecResult - } - } - } - return{opSpecsA:applyDirectStylingSpecAResult, opSpecsB:applyDirectStylingSpecBResult} - } - function transformApplyDirectStylingInsertText(applyDirectStylingSpec, insertTextSpec) { - if(insertTextSpec.position <= applyDirectStylingSpec.position) { - applyDirectStylingSpec.position += insertTextSpec.text.length - }else { - if(insertTextSpec.position <= applyDirectStylingSpec.position + applyDirectStylingSpec.length) { - applyDirectStylingSpec.length += insertTextSpec.text.length - } - } - return{opSpecsA:[applyDirectStylingSpec], opSpecsB:[insertTextSpec]} - } - function transformApplyDirectStylingRemoveText(applyDirectStylingSpec, removeTextSpec) { - var applyDirectStylingSpecEnd = applyDirectStylingSpec.position + applyDirectStylingSpec.length, removeTextSpecEnd = removeTextSpec.position + removeTextSpec.length, applyDirectStylingSpecResult = [applyDirectStylingSpec], removeTextSpecResult = [removeTextSpec]; - if(removeTextSpecEnd <= applyDirectStylingSpec.position) { - applyDirectStylingSpec.position -= removeTextSpec.length - }else { - if(removeTextSpec.position < applyDirectStylingSpecEnd) { - if(applyDirectStylingSpec.position < removeTextSpec.position) { - if(removeTextSpecEnd < applyDirectStylingSpecEnd) { - applyDirectStylingSpec.length -= removeTextSpec.length - }else { - applyDirectStylingSpec.length = removeTextSpec.position - applyDirectStylingSpec.position - } - }else { - applyDirectStylingSpec.position = removeTextSpec.position; - if(removeTextSpecEnd < applyDirectStylingSpecEnd) { - applyDirectStylingSpec.length = applyDirectStylingSpecEnd - removeTextSpecEnd - }else { - applyDirectStylingSpecResult = [] - } - } - } - } - return{opSpecsA:applyDirectStylingSpecResult, opSpecsB:removeTextSpecResult} - } - function transformApplyDirectStylingSplitParagraph(applyDirectStylingSpec, splitParagraphSpec) { - if(splitParagraphSpec.position < applyDirectStylingSpec.position) { - applyDirectStylingSpec.position += 1 - }else { - if(splitParagraphSpec.position < applyDirectStylingSpec.position + applyDirectStylingSpec.length) { - applyDirectStylingSpec.length += 1 - } - } - return{opSpecsA:[applyDirectStylingSpec], opSpecsB:[splitParagraphSpec]} - } - function transformInsertTextInsertText(insertTextSpecA, insertTextSpecB, hasAPriority) { - if(insertTextSpecA.position < insertTextSpecB.position) { - insertTextSpecB.position += insertTextSpecA.text.length - }else { - if(insertTextSpecA.position > insertTextSpecB.position) { - insertTextSpecA.position += insertTextSpecB.text.length - }else { - if(hasAPriority) { - insertTextSpecB.position += insertTextSpecA.text.length - }else { - insertTextSpecA.position += insertTextSpecB.text.length - } - } - } - return{opSpecsA:[insertTextSpecA], opSpecsB:[insertTextSpecB]} - } - function transformInsertTextMoveCursor(insertTextSpec, moveCursorSpec) { - var isMoveCursorSpecRangeInverted = invertMoveCursorSpecRangeOnNegativeLength(moveCursorSpec); - if(insertTextSpec.position < moveCursorSpec.position) { - moveCursorSpec.position += insertTextSpec.text.length - }else { - if(insertTextSpec.position < moveCursorSpec.position + moveCursorSpec.length) { - moveCursorSpec.length += insertTextSpec.text.length - } - } - if(isMoveCursorSpecRangeInverted) { - invertMoveCursorSpecRange(moveCursorSpec) - } - return{opSpecsA:[insertTextSpec], opSpecsB:[moveCursorSpec]} - } - function transformInsertTextRemoveText(insertTextSpec, removeTextSpec) { - var helperOpspec, removeTextSpecEnd = removeTextSpec.position + removeTextSpec.length, insertTextSpecResult = [insertTextSpec], removeTextSpecResult = [removeTextSpec]; - if(removeTextSpecEnd <= insertTextSpec.position) { - insertTextSpec.position -= removeTextSpec.length - }else { - if(insertTextSpec.position <= removeTextSpec.position) { - removeTextSpec.position += insertTextSpec.text.length - }else { - removeTextSpec.length = insertTextSpec.position - removeTextSpec.position; - helperOpspec = {optype:"RemoveText", memberid:removeTextSpec.memberid, timestamp:removeTextSpec.timestamp, position:insertTextSpec.position + insertTextSpec.text.length, length:removeTextSpecEnd - insertTextSpec.position}; - removeTextSpecResult.unshift(helperOpspec); - insertTextSpec.position = removeTextSpec.position - } - } - return{opSpecsA:insertTextSpecResult, opSpecsB:removeTextSpecResult} - } - function transformInsertTextSplitParagraph(insertTextSpec, splitParagraphSpec, hasAPriority) { - if(insertTextSpec.position < splitParagraphSpec.position) { - splitParagraphSpec.position += insertTextSpec.text.length - }else { - if(insertTextSpec.position > splitParagraphSpec.position) { - insertTextSpec.position += 1 - }else { - if(hasAPriority) { - splitParagraphSpec.position += insertTextSpec.text.length - }else { - insertTextSpec.position += 1 - } - return null - } - } - return{opSpecsA:[insertTextSpec], opSpecsB:[splitParagraphSpec]} - } - function transformUpdateParagraphStyleUpdateParagraphStyle(updateParagraphStyleSpecA, updateParagraphStyleSpecB, hasAPriority) { - var majorSpec, minorSpec, updateParagraphStyleSpecAResult = [updateParagraphStyleSpecA], updateParagraphStyleSpecBResult = [updateParagraphStyleSpecB]; - if(updateParagraphStyleSpecA.styleName === updateParagraphStyleSpecB.styleName) { - majorSpec = hasAPriority ? updateParagraphStyleSpecA : updateParagraphStyleSpecB; - minorSpec = hasAPriority ? updateParagraphStyleSpecB : updateParagraphStyleSpecA; - dropOverruledAndUnneededProperties(minorSpec, majorSpec, "style:paragraph-properties"); - dropOverruledAndUnneededProperties(minorSpec, majorSpec, "style:text-properties"); - dropOverruledAndUnneededAttributes(minorSpec.setProperties || null, minorSpec.removedProperties || null, majorSpec.setProperties || null, majorSpec.removedProperties || null); - if(!(majorSpec.setProperties && hasProperties(majorSpec.setProperties)) && !(majorSpec.removedProperties && hasRemovedProperties(majorSpec.removedProperties))) { - if(hasAPriority) { - updateParagraphStyleSpecAResult = [] - }else { - updateParagraphStyleSpecBResult = [] - } - } - if(!(minorSpec.setProperties && hasProperties(minorSpec.setProperties)) && !(minorSpec.removedProperties && hasRemovedProperties(minorSpec.removedProperties))) { - if(hasAPriority) { - updateParagraphStyleSpecBResult = [] - }else { - updateParagraphStyleSpecAResult = [] - } - } - } - return{opSpecsA:updateParagraphStyleSpecAResult, opSpecsB:updateParagraphStyleSpecBResult} - } - function transformUpdateMetadataUpdateMetadata(updateMetadataSpecA, updateMetadataSpecB, hasAPriority) { - var majorSpec, minorSpec, updateMetadataSpecAResult = [updateMetadataSpecA], updateMetadataSpecBResult = [updateMetadataSpecB]; - majorSpec = hasAPriority ? updateMetadataSpecA : updateMetadataSpecB; - minorSpec = hasAPriority ? updateMetadataSpecB : updateMetadataSpecA; - dropOverruledAndUnneededAttributes(minorSpec.setProperties || null, minorSpec.removedProperties || null, majorSpec.setProperties || null, majorSpec.removedProperties || null); - if(!(majorSpec.setProperties && hasProperties(majorSpec.setProperties)) && !(majorSpec.removedProperties && hasRemovedProperties(majorSpec.removedProperties))) { - if(hasAPriority) { - updateMetadataSpecAResult = [] - }else { - updateMetadataSpecBResult = [] - } - } - if(!(minorSpec.setProperties && hasProperties(minorSpec.setProperties)) && !(minorSpec.removedProperties && hasRemovedProperties(minorSpec.removedProperties))) { - if(hasAPriority) { - updateMetadataSpecBResult = [] - }else { - updateMetadataSpecAResult = [] - } - } - return{opSpecsA:updateMetadataSpecAResult, opSpecsB:updateMetadataSpecBResult} - } - function transformSplitParagraphSplitParagraph(splitParagraphSpecA, splitParagraphSpecB, hasAPriority) { - if(splitParagraphSpecA.position < splitParagraphSpecB.position) { - splitParagraphSpecB.position += 1 - }else { - if(splitParagraphSpecA.position > splitParagraphSpecB.position) { - splitParagraphSpecA.position += 1 - }else { - if(splitParagraphSpecA.position === splitParagraphSpecB.position) { - if(hasAPriority) { - splitParagraphSpecB.position += 1 - }else { - splitParagraphSpecA.position += 1 - } - } - } - } - return{opSpecsA:[splitParagraphSpecA], opSpecsB:[splitParagraphSpecB]} - } - function transformMoveCursorRemoveCursor(moveCursorSpec, removeCursorSpec) { - var isSameCursorRemoved = moveCursorSpec.memberid === removeCursorSpec.memberid; - return{opSpecsA:isSameCursorRemoved ? [] : [moveCursorSpec], opSpecsB:[removeCursorSpec]} - } - function transformMoveCursorRemoveText(moveCursorSpec, removeTextSpec) { - var isMoveCursorSpecRangeInverted = invertMoveCursorSpecRangeOnNegativeLength(moveCursorSpec), moveCursorSpecEnd = moveCursorSpec.position + moveCursorSpec.length, removeTextSpecEnd = removeTextSpec.position + removeTextSpec.length; - if(removeTextSpecEnd <= moveCursorSpec.position) { - moveCursorSpec.position -= removeTextSpec.length - }else { - if(removeTextSpec.position < moveCursorSpecEnd) { - if(moveCursorSpec.position < removeTextSpec.position) { - if(removeTextSpecEnd < moveCursorSpecEnd) { - moveCursorSpec.length -= removeTextSpec.length - }else { - moveCursorSpec.length = removeTextSpec.position - moveCursorSpec.position - } - }else { - moveCursorSpec.position = removeTextSpec.position; - if(removeTextSpecEnd < moveCursorSpecEnd) { - moveCursorSpec.length = moveCursorSpecEnd - removeTextSpecEnd - }else { - moveCursorSpec.length = 0 - } - } - } - } - if(isMoveCursorSpecRangeInverted) { - invertMoveCursorSpecRange(moveCursorSpec) - } - return{opSpecsA:[moveCursorSpec], opSpecsB:[removeTextSpec]} - } - function transformMoveCursorSplitParagraph(moveCursorSpec, splitParagraphSpec) { - var isMoveCursorSpecRangeInverted = invertMoveCursorSpecRangeOnNegativeLength(moveCursorSpec); - if(splitParagraphSpec.position < moveCursorSpec.position) { - moveCursorSpec.position += 1 - }else { - if(splitParagraphSpec.position < moveCursorSpec.position + moveCursorSpec.length) { - moveCursorSpec.length += 1 - } - } - if(isMoveCursorSpecRangeInverted) { - invertMoveCursorSpecRange(moveCursorSpec) - } - return{opSpecsA:[moveCursorSpec], opSpecsB:[splitParagraphSpec]} - } - function transformRemoveCursorRemoveCursor(removeCursorSpecA, removeCursorSpecB) { - var isSameMemberid = removeCursorSpecA.memberid === removeCursorSpecB.memberid; - return{opSpecsA:isSameMemberid ? [] : [removeCursorSpecA], opSpecsB:isSameMemberid ? [] : [removeCursorSpecB]} - } - function transformRemoveStyleRemoveStyle(removeStyleSpecA, removeStyleSpecB) { - var isSameStyle = removeStyleSpecA.styleName === removeStyleSpecB.styleName && removeStyleSpecA.styleFamily === removeStyleSpecB.styleFamily; - return{opSpecsA:isSameStyle ? [] : [removeStyleSpecA], opSpecsB:isSameStyle ? [] : [removeStyleSpecB]} - } - function transformRemoveStyleSetParagraphStyle(removeStyleSpec, setParagraphStyleSpec) { - var helperOpspec, removeStyleSpecResult = [removeStyleSpec], setParagraphStyleSpecResult = [setParagraphStyleSpec]; - if(removeStyleSpec.styleFamily === "paragraph" && removeStyleSpec.styleName === setParagraphStyleSpec.styleName) { - helperOpspec = {optype:"SetParagraphStyle", memberid:removeStyleSpec.memberid, timestamp:removeStyleSpec.timestamp, position:setParagraphStyleSpec.position, styleName:""}; - removeStyleSpecResult.unshift(helperOpspec); - setParagraphStyleSpec.styleName = "" - } - return{opSpecsA:removeStyleSpecResult, opSpecsB:setParagraphStyleSpecResult} - } - function transformRemoveStyleUpdateParagraphStyle(removeStyleSpec, updateParagraphStyleSpec) { - var setAttributes, helperOpspec, removeStyleSpecResult = [removeStyleSpec], updateParagraphStyleSpecResult = [updateParagraphStyleSpec]; - if(removeStyleSpec.styleFamily === "paragraph") { - setAttributes = getStyleReferencingAttributes(updateParagraphStyleSpec.setProperties, removeStyleSpec.styleName); - if(setAttributes.length > 0) { - helperOpspec = {optype:"UpdateParagraphStyle", memberid:removeStyleSpec.memberid, timestamp:removeStyleSpec.timestamp, styleName:updateParagraphStyleSpec.styleName, removedProperties:{attributes:setAttributes.join(",")}}; - removeStyleSpecResult.unshift(helperOpspec) - } - if(removeStyleSpec.styleName === updateParagraphStyleSpec.styleName) { - updateParagraphStyleSpecResult = [] - }else { - dropStyleReferencingAttributes(updateParagraphStyleSpec.setProperties, removeStyleSpec.styleName) - } - } - return{opSpecsA:removeStyleSpecResult, opSpecsB:updateParagraphStyleSpecResult} - } - function transformRemoveTextRemoveText(removeTextSpecA, removeTextSpecB) { - var removeTextSpecAEnd = removeTextSpecA.position + removeTextSpecA.length, removeTextSpecBEnd = removeTextSpecB.position + removeTextSpecB.length, removeTextSpecAResult = [removeTextSpecA], removeTextSpecBResult = [removeTextSpecB]; - if(removeTextSpecBEnd <= removeTextSpecA.position) { - removeTextSpecA.position -= removeTextSpecB.length - }else { - if(removeTextSpecAEnd <= removeTextSpecB.position) { - removeTextSpecB.position -= removeTextSpecA.length - }else { - if(removeTextSpecB.position < removeTextSpecAEnd) { - if(removeTextSpecA.position < removeTextSpecB.position) { - if(removeTextSpecBEnd < removeTextSpecAEnd) { - removeTextSpecA.length = removeTextSpecA.length - removeTextSpecB.length - }else { - removeTextSpecA.length = removeTextSpecB.position - removeTextSpecA.position - } - if(removeTextSpecAEnd < removeTextSpecBEnd) { - removeTextSpecB.position = removeTextSpecA.position; - removeTextSpecB.length = removeTextSpecBEnd - removeTextSpecAEnd - }else { - removeTextSpecBResult = [] - } - }else { - if(removeTextSpecAEnd < removeTextSpecBEnd) { - removeTextSpecB.length = removeTextSpecB.length - removeTextSpecA.length - }else { - if(removeTextSpecB.position < removeTextSpecA.position) { - removeTextSpecB.length = removeTextSpecA.position - removeTextSpecB.position - }else { - removeTextSpecBResult = [] - } - } - if(removeTextSpecBEnd < removeTextSpecAEnd) { - removeTextSpecA.position = removeTextSpecB.position; - removeTextSpecA.length = removeTextSpecAEnd - removeTextSpecBEnd - }else { - removeTextSpecAResult = [] - } - } - } - } - } - return{opSpecsA:removeTextSpecAResult, opSpecsB:removeTextSpecBResult} - } - function transformRemoveTextSplitParagraph(removeTextSpec, splitParagraphSpec) { - var removeTextSpecEnd = removeTextSpec.position + removeTextSpec.length, helperOpspec, removeTextSpecResult = [removeTextSpec], splitParagraphSpecResult = [splitParagraphSpec]; - if(splitParagraphSpec.position <= removeTextSpec.position) { - removeTextSpec.position += 1 - }else { - if(splitParagraphSpec.position < removeTextSpecEnd) { - removeTextSpec.length = splitParagraphSpec.position - removeTextSpec.position; - helperOpspec = {optype:"RemoveText", memberid:removeTextSpec.memberid, timestamp:removeTextSpec.timestamp, position:splitParagraphSpec.position + 1, length:removeTextSpecEnd - splitParagraphSpec.position}; - removeTextSpecResult.unshift(helperOpspec) - } - } - if(removeTextSpec.position + removeTextSpec.length <= splitParagraphSpec.position) { - splitParagraphSpec.position -= removeTextSpec.length - }else { - if(removeTextSpec.position < splitParagraphSpec.position) { - splitParagraphSpec.position = removeTextSpec.position - } - } - return{opSpecsA:removeTextSpecResult, opSpecsB:splitParagraphSpecResult} - } - function passUnchanged(opSpecA, opSpecB) { - return{opSpecsA:[opSpecA], opSpecsB:[opSpecB]} - } - var transformations = {"AddCursor":{"AddCursor":passUnchanged, "AddMember":passUnchanged, "AddStyle":passUnchanged, "ApplyDirectStyling":passUnchanged, "InsertText":passUnchanged, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveMember":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "AddMember":{"AddStyle":passUnchanged, - "InsertText":passUnchanged, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "AddStyle":{"AddStyle":passUnchanged, "ApplyDirectStyling":passUnchanged, "InsertText":passUnchanged, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveMember":passUnchanged, "RemoveStyle":transformAddStyleRemoveStyle, - "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "ApplyDirectStyling":{"ApplyDirectStyling":transformApplyDirectStylingApplyDirectStyling, "InsertText":transformApplyDirectStylingInsertText, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":transformApplyDirectStylingRemoveText, "SetParagraphStyle":passUnchanged, - "SplitParagraph":transformApplyDirectStylingSplitParagraph, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "InsertText":{"InsertText":transformInsertTextInsertText, "MoveCursor":transformInsertTextMoveCursor, "RemoveCursor":passUnchanged, "RemoveMember":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":transformInsertTextRemoveText, "SplitParagraph":transformInsertTextSplitParagraph, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, - "MoveCursor":{"MoveCursor":passUnchanged, "RemoveCursor":transformMoveCursorRemoveCursor, "RemoveMember":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":transformMoveCursorRemoveText, "SetParagraphStyle":passUnchanged, "SplitParagraph":transformMoveCursorSplitParagraph, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "RemoveCursor":{"RemoveCursor":transformRemoveCursorRemoveCursor, "RemoveMember":passUnchanged, "RemoveStyle":passUnchanged, - "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "RemoveMember":{"RemoveStyle":passUnchanged, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "RemoveStyle":{"RemoveStyle":transformRemoveStyleRemoveStyle, "RemoveText":passUnchanged, "SetParagraphStyle":transformRemoveStyleSetParagraphStyle, - "SplitParagraph":passUnchanged, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":transformRemoveStyleUpdateParagraphStyle}, "RemoveText":{"RemoveText":transformRemoveTextRemoveText, "SplitParagraph":transformRemoveTextSplitParagraph, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "SetParagraphStyle":{"UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "SplitParagraph":{"SplitParagraph":transformSplitParagraphSplitParagraph, - "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "UpdateMember":{"UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "UpdateMetadata":{"UpdateMetadata":transformUpdateMetadataUpdateMetadata, "UpdateParagraphStyle":passUnchanged}, "UpdateParagraphStyle":{"UpdateParagraphStyle":transformUpdateParagraphStyleUpdateParagraphStyle}}; - this.passUnchanged = passUnchanged; - this.extendTransformations = function(moreTransformations) { - Object.keys(moreTransformations).forEach(function(optypeA) { - var moreTransformationsOptypeAMap = moreTransformations[optypeA], optypeAMap, isExtendingOptypeAMap = transformations.hasOwnProperty(optypeA); - runtime.log((isExtendingOptypeAMap ? "Extending" : "Adding") + " map for optypeA: " + optypeA); - if(!isExtendingOptypeAMap) { - transformations[optypeA] = {} - } - optypeAMap = transformations[optypeA]; - Object.keys(moreTransformationsOptypeAMap).forEach(function(optypeB) { - var isOverwritingOptypeBEntry = optypeAMap.hasOwnProperty(optypeB); - runtime.assert(optypeA <= optypeB, "Wrong order:" + optypeA + ", " + optypeB); - runtime.log(" " + (isOverwritingOptypeBEntry ? "Overwriting" : "Adding") + " entry for optypeB: " + optypeB); - optypeAMap[optypeB] = moreTransformationsOptypeAMap[optypeB] - }) - }) - }; - this.transformOpspecVsOpspec = function(opSpecA, opSpecB) { - var isOptypeAAlphaNumericSmaller = opSpecA.optype <= opSpecB.optype, helper, transformationFunctionMap, transformationFunction, result; - runtime.log("Crosstransforming:"); - runtime.log(runtime.toJson(opSpecA)); - runtime.log(runtime.toJson(opSpecB)); - if(!isOptypeAAlphaNumericSmaller) { - helper = opSpecA; - opSpecA = opSpecB; - opSpecB = helper - } - transformationFunctionMap = transformations[opSpecA.optype]; - transformationFunction = transformationFunctionMap && transformationFunctionMap[opSpecB.optype]; - if(transformationFunction) { - result = transformationFunction(opSpecA, opSpecB, !isOptypeAAlphaNumericSmaller); - if(!isOptypeAAlphaNumericSmaller && result !== null) { - result = {opSpecsA:result.opSpecsB, opSpecsB:result.opSpecsA} - } - }else { - result = null - } - runtime.log("result:"); - if(result) { - runtime.log(runtime.toJson(result.opSpecsA)); - runtime.log(runtime.toJson(result.opSpecsB)) - }else { - runtime.log("null") - } - return result - } -}; -/* - - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> - - @licstart - This file is part of WebODF. - - WebODF 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. - - WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. - @licend - - @source: http://www.webodf.org/ - @source: https://github.com/kogmbh/WebODF/ -*/ -runtime.loadClass("ops.OperationFactory"); -runtime.loadClass("ops.OperationTransformMatrix"); -ops.OperationTransformer = function OperationTransformer() { - var operationFactory, operationTransformMatrix = new ops.OperationTransformMatrix; - function operations(opspecs) { - var ops = []; - opspecs.forEach(function(opspec) { - ops.push(operationFactory.create(opspec)) - }); - return ops - } - function transformOpVsOp(opSpecA, opSpecB) { - return operationTransformMatrix.transformOpspecVsOpspec(opSpecA, opSpecB) - } - function transformOpListVsOp(opSpecsA, opSpecB) { - var transformResult, transformListResult, transformedOpspecsA = [], transformedOpspecsB = []; - while(opSpecsA.length > 0 && opSpecB) { - transformResult = transformOpVsOp(opSpecsA.shift(), (opSpecB)); - if(!transformResult) { - return null - } - transformedOpspecsA = transformedOpspecsA.concat(transformResult.opSpecsA); - if(transformResult.opSpecsB.length === 0) { - transformedOpspecsA = transformedOpspecsA.concat(opSpecsA); - opSpecB = null; - break - } - while(transformResult.opSpecsB.length > 1) { - transformListResult = transformOpListVsOp(opSpecsA, transformResult.opSpecsB.shift()); - if(!transformListResult) { - return null - } - transformedOpspecsB = transformedOpspecsB.concat(transformListResult.opSpecsB); - opSpecsA = transformListResult.opSpecsA - } - opSpecB = transformResult.opSpecsB.pop() - } - if(opSpecB) { - transformedOpspecsB.push(opSpecB) - } - return{opSpecsA:transformedOpspecsA, opSpecsB:transformedOpspecsB} - } - this.setOperationFactory = function(f) { - operationFactory = f - }; - this.getOperationTransformMatrix = function() { - return operationTransformMatrix - }; - this.transform = function(opSpecsA, opSpecsB) { - var transformResult, transformedOpspecsB = []; - while(opSpecsB.length > 0) { - transformResult = transformOpListVsOp(opSpecsA, opSpecsB.shift()); - if(!transformResult) { - return null - } - opSpecsA = transformResult.opSpecsA; - transformedOpspecsB = transformedOpspecsB.concat(transformResult.opSpecsB) - } - return{opsA:operations(opSpecsA), opsB:operations(transformedOpspecsB)} - } -}; +ops.OperationRouter.signalProcessingBatchStart = "router/batchstart"; +ops.OperationRouter.signalProcessingBatchEnd = "router/batchend"; /* Copyright (C) 2012 KO GmbH <copyright@kogmbh.com> @@ -15413,7 +12351,7 @@ ops.OperationTransformer = function OperationTransformer() { @source: https://github.com/kogmbh/WebODF/ */ ops.TrivialOperationRouter = function TrivialOperationRouter() { - var operationFactory, playbackFunction; + var events = new core.EventNotifier([ops.OperationRouter.signalProcessingBatchStart, ops.OperationRouter.signalProcessingBatchEnd]), operationFactory, playbackFunction, groupIdentifier = 0; this.setOperationFactory = function(f) { operationFactory = f }; @@ -15421,19 +12359,25 @@ ops.TrivialOperationRouter = function TrivialOperationRouter() { playbackFunction = playback_func }; this.push = function(operations) { + groupIdentifier += 1; + events.emit(ops.OperationRouter.signalProcessingBatchStart, {}); operations.forEach(function(op) { var timedOp, opspec = op.spec(); opspec.timestamp = (new Date).getTime(); timedOp = operationFactory.create(opspec); + timedOp.group = "g" + groupIdentifier; playbackFunction(timedOp) - }) + }); + events.emit(ops.OperationRouter.signalProcessingBatchEnd, {}) }; this.close = function(cb) { cb() }; this.subscribe = function(eventId, cb) { + events.subscribe(eventId, cb) }; this.unsubscribe = function(eventId, cb) { + events.unsubscribe(eventId, cb) }; this.hasLocalUnsyncedOps = function() { return false @@ -15479,97 +12423,61 @@ ops.TrivialOperationRouter = function TrivialOperationRouter() { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.EditInfo"); -runtime.loadClass("gui.EditInfoHandle"); -gui.EditInfoMarker = function EditInfoMarker(editInfo, initialVisibility) { - var self = this, editInfoNode, handle, marker, editinfons = "urn:webodf:names:editinfo", decay1, decay2, decayTimeStep = 1E4; - function applyDecay(opacity, delay) { - return runtime.setTimeout(function() { - marker.style.opacity = opacity - }, delay) - } - function deleteDecay(timer) { - runtime.clearTimeout(timer) +ops.Session = function Session(odfCanvas) { + var self = this, operationFactory = new ops.OperationFactory, odtDocument = new ops.OdtDocument(odfCanvas), operationRouter = null; + function forwardBatchStart(args) { + odtDocument.emit(ops.OdtDocument.signalProcessingBatchStart, args) } - function setLastAuthor(memberid) { - marker.setAttributeNS(editinfons, "editinfo:memberid", memberid) + function forwardBatchEnd(args) { + odtDocument.emit(ops.OdtDocument.signalProcessingBatchEnd, args) } - this.addEdit = function(memberid, timestamp) { - var age = Date.now() - timestamp; - editInfo.addEdit(memberid, timestamp); - handle.setEdits(editInfo.getSortedEdits()); - setLastAuthor(memberid); - if(decay1) { - deleteDecay(decay1) - } - if(decay2) { - deleteDecay(decay2) - } - if(age < decayTimeStep) { - applyDecay(1, 0); - decay1 = applyDecay(0.5, decayTimeStep - age); - decay2 = applyDecay(0.2, decayTimeStep * 2 - age) - }else { - if(age >= decayTimeStep && age < decayTimeStep * 2) { - applyDecay(0.5, 0); - decay2 = applyDecay(0.2, decayTimeStep * 2 - age) - }else { - applyDecay(0.2, 0) - } + this.setOperationFactory = function(opFactory) { + operationFactory = opFactory; + if(operationRouter) { + operationRouter.setOperationFactory(operationFactory) } }; - this.getEdits = function() { - return editInfo.getEdits() - }; - this.clearEdits = function() { - editInfo.clearEdits(); - handle.setEdits([]); - if(marker.hasAttributeNS(editinfons, "editinfo:memberid")) { - marker.removeAttributeNS(editinfons, "editinfo:memberid") + this.setOperationRouter = function(opRouter) { + if(operationRouter) { + operationRouter.unsubscribe(ops.OperationRouter.signalProcessingBatchStart, forwardBatchStart); + operationRouter.unsubscribe(ops.OperationRouter.signalProcessingBatchEnd, forwardBatchEnd) } + operationRouter = opRouter; + operationRouter.subscribe(ops.OperationRouter.signalProcessingBatchStart, forwardBatchStart); + operationRouter.subscribe(ops.OperationRouter.signalProcessingBatchEnd, forwardBatchEnd); + opRouter.setPlaybackFunction(function(op) { + odtDocument.emit(ops.OdtDocument.signalOperationStart, op); + if(op.execute(odtDocument)) { + odtDocument.emit(ops.OdtDocument.signalOperationEnd, op); + return true + } + return false + }); + opRouter.setOperationFactory(operationFactory) }; - this.getEditInfo = function() { - return editInfo - }; - this.show = function() { - marker.style.display = "block" - }; - this.hide = function() { - self.hideHandle(); - marker.style.display = "none" + this.getOperationFactory = function() { + return operationFactory }; - this.showHandle = function() { - handle.show() + this.getOdtDocument = function() { + return odtDocument }; - this.hideHandle = function() { - handle.hide() + this.enqueue = function(ops) { + operationRouter.push(ops) }; - this.destroy = function(callback) { - editInfoNode.removeChild(marker); - handle.destroy(function(err) { + this.close = function(callback) { + operationRouter.close(function(err) { if(err) { callback(err) }else { - editInfo.destroy(callback) + odtDocument.close(callback) } }) }; + this.destroy = function(callback) { + odtDocument.destroy(callback) + }; function init() { - var dom = editInfo.getOdtDocument().getDOM(), htmlns = dom.documentElement.namespaceURI; - marker = dom.createElementNS(htmlns, "div"); - marker.setAttribute("class", "editInfoMarker"); - marker.onmouseover = function() { - self.showHandle() - }; - marker.onmouseout = function() { - self.hideHandle() - }; - editInfoNode = editInfo.getNode(); - editInfoNode.appendChild(marker); - handle = new gui.EditInfoHandle(editInfoNode); - if(!initialVisibility) { - self.hide() - } + self.setOperationRouter(new ops.TrivialOperationRouter) } init() }; @@ -15578,347 +12486,379 @@ gui.EditInfoMarker = function EditInfoMarker(editInfo, initialVisibility) { 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/>. + This file is part of WebODF. - 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. + WebODF 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. - 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. + WebODF 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. - This license applies to this entire compilation. + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see <http://www.gnu.org/licenses/>. @licend + @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -gui.PlainTextPasteboard = function PlainTextPasteboard(odtDocument, inputMemberId) { - function createOp(op, data) { - op.init(data); - return op - } - this.createPasteOps = function(data) { - var originalCursorPosition = odtDocument.getCursorPosition(inputMemberId), cursorPosition = originalCursorPosition, operations = [], paragraphs; - paragraphs = data.replace(/\r/g, "").split("\n"); - paragraphs.forEach(function(text) { - operations.push(createOp(new ops.OpSplitParagraph, {memberid:inputMemberId, position:cursorPosition, moveCursor:true})); - cursorPosition += 1; - operations.push(createOp(new ops.OpInsertText, {memberid:inputMemberId, position:cursorPosition, text:text, moveCursor:true})); - cursorPosition += text.length - }); - operations.push(createOp(new ops.OpRemoveText, {memberid:inputMemberId, position:originalCursorPosition, length:1})); - return operations - } -}; -runtime.loadClass("core.DomUtils"); -runtime.loadClass("odf.OdfUtils"); -runtime.loadClass("odf.OdfNodeFilter"); -runtime.loadClass("gui.SelectionMover"); -gui.SelectionView = function SelectionView(cursor) { - var odtDocument = cursor.getOdtDocument(), documentRoot, root, doc = odtDocument.getDOM(), overlayTop = doc.createElement("div"), overlayMiddle = doc.createElement("div"), overlayBottom = doc.createElement("div"), odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils, isVisible = true, positionIterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), FILTER_ACCEPT = NodeFilter.FILTER_ACCEPT, FILTER_REJECT = NodeFilter.FILTER_REJECT; - function addOverlays() { - var newDocumentRoot = odtDocument.getRootNode(); - if(documentRoot !== newDocumentRoot) { - documentRoot = newDocumentRoot; - root = (documentRoot.parentNode.parentNode.parentNode); - root.appendChild(overlayTop); - root.appendChild(overlayMiddle); - root.appendChild(overlayBottom) +gui.AnnotationController = function AnnotationController(session, inputMemberId) { + var odtDocument = session.getOdtDocument(), isAnnotatable = false, eventNotifier = new core.EventNotifier([gui.AnnotationController.annotatableChanged]), officens = odf.Namespaces.officens; + function isWithinAnnotation(node, container) { + while(node && node !== container) { + if(node.namespaceURI === officens && node.localName === "annotation") { + return true + } + node = node.parentNode } + return false } - function setRect(div, rect) { - div.style.left = rect.left + "px"; - div.style.top = rect.top + "px"; - div.style.width = rect.width + "px"; - div.style.height = rect.height + "px" - } - function showOverlays(choice) { - var display; - isVisible = choice; - display = choice === true ? "block" : "none"; - overlayTop.style.display = overlayMiddle.style.display = overlayBottom.style.display = display + function updatedCachedValues() { + var cursor = odtDocument.getCursor(inputMemberId), cursorNode = cursor && cursor.getNode(), newIsAnnotatable = false; + if(cursorNode) { + newIsAnnotatable = !isWithinAnnotation(cursorNode, odtDocument.getRootNode()) + } + if(newIsAnnotatable !== isAnnotatable) { + isAnnotatable = newIsAnnotatable; + eventNotifier.emit(gui.AnnotationController.annotatableChanged, isAnnotatable) + } } - function translateRect(rect) { - var rootRect = domUtils.getBoundingClientRect(root), zoomLevel = odtDocument.getOdfCanvas().getZoomLevel(), resultRect = {}; - resultRect.top = domUtils.adaptRangeDifferenceToZoomLevel(rect.top - rootRect.top, zoomLevel); - resultRect.left = domUtils.adaptRangeDifferenceToZoomLevel(rect.left - rootRect.left, zoomLevel); - resultRect.bottom = domUtils.adaptRangeDifferenceToZoomLevel(rect.bottom - rootRect.top, zoomLevel); - resultRect.right = domUtils.adaptRangeDifferenceToZoomLevel(rect.right - rootRect.left, zoomLevel); - resultRect.width = domUtils.adaptRangeDifferenceToZoomLevel(rect.width, zoomLevel); - resultRect.height = domUtils.adaptRangeDifferenceToZoomLevel(rect.height, zoomLevel); - return resultRect + function onCursorAdded(cursor) { + if(cursor.getMemberId() === inputMemberId) { + updatedCachedValues() + } } - function isRangeVisible(range) { - var bcr = range.getBoundingClientRect(); - return Boolean(bcr && bcr.height !== 0) + function onCursorRemoved(memberId) { + if(memberId === inputMemberId) { + updatedCachedValues() + } } - function lastVisibleRect(range, nodes) { - var nextNodeIndex = nodes.length - 1, node = nodes[nextNodeIndex], startOffset = range.endContainer === node ? range.endOffset : node.length || node.childNodes.length, endOffset = startOffset; - range.setStart(node, startOffset); - range.setEnd(node, endOffset); - while(!isRangeVisible(range)) { - if(node.nodeType === Node.ELEMENT_NODE && startOffset > 0) { - startOffset = 0 - }else { - if(node.nodeType === Node.TEXT_NODE && startOffset > 0) { - startOffset -= 1 - }else { - if(nodes[nextNodeIndex]) { - node = nodes[nextNodeIndex]; - nextNodeIndex -= 1; - startOffset = endOffset = node.length || node.childNodes.length - }else { - return false - } - } - } - range.setStart(node, startOffset); - range.setEnd(node, endOffset) + function onCursorMoved(cursor) { + if(cursor.getMemberId() === inputMemberId) { + updatedCachedValues() } - return true } - function firstVisibleRect(range, nodes) { - var nextNodeIndex = 0, node = nodes[nextNodeIndex], startOffset = range.startContainer === node ? range.startOffset : 0, endOffset = startOffset; - range.setStart(node, startOffset); - range.setEnd(node, endOffset); - while(!isRangeVisible(range)) { - if(node.nodeType === Node.ELEMENT_NODE && endOffset < node.childNodes.length) { - endOffset = node.childNodes.length - }else { - if(node.nodeType === Node.TEXT_NODE && endOffset < node.length) { - endOffset += 1 - }else { - if(nodes[nextNodeIndex]) { - node = nodes[nextNodeIndex]; - nextNodeIndex += 1; - startOffset = endOffset = 0 - }else { - return false - } - } - } - range.setStart(node, startOffset); - range.setEnd(node, endOffset) + this.isAnnotatable = function() { + return isAnnotatable + }; + this.addAnnotation = function() { + var op = new ops.OpAddAnnotation, selection = odtDocument.getCursorSelection(inputMemberId), length = selection.length, position = selection.position; + if(!isAnnotatable) { + return } - return true + position = length >= 0 ? position : position + length; + length = Math.abs(length); + op.init({memberid:inputMemberId, position:position, length:length, name:inputMemberId + Date.now()}); + session.enqueue([op]) + }; + this.removeAnnotation = function(annotationNode) { + var startStep, endStep, op, moveCursor; + startStep = odtDocument.convertDomPointToCursorStep(annotationNode, 0) + 1; + endStep = odtDocument.convertDomPointToCursorStep(annotationNode, annotationNode.childNodes.length); + op = new ops.OpRemoveAnnotation; + op.init({memberid:inputMemberId, position:startStep, length:endStep - startStep}); + moveCursor = new ops.OpMoveCursor; + moveCursor.init({memberid:inputMemberId, position:startStep > 0 ? startStep - 1 : startStep, length:0}); + session.enqueue([op, moveCursor]) + }; + this.subscribe = function(eventid, cb) { + eventNotifier.subscribe(eventid, cb) + }; + this.unsubscribe = function(eventid, cb) { + eventNotifier.unsubscribe(eventid, cb) + }; + this.destroy = function(callback) { + odtDocument.unsubscribe(ops.Document.signalCursorAdded, onCursorAdded); + odtDocument.unsubscribe(ops.Document.signalCursorRemoved, onCursorRemoved); + odtDocument.unsubscribe(ops.Document.signalCursorMoved, onCursorMoved); + callback() + }; + function init() { + odtDocument.subscribe(ops.Document.signalCursorAdded, onCursorAdded); + odtDocument.subscribe(ops.Document.signalCursorRemoved, onCursorRemoved); + odtDocument.subscribe(ops.Document.signalCursorMoved, onCursorMoved); + updatedCachedValues() } - function getExtremeRanges(range) { - var nodes = odfUtils.getTextElements(range, true, false), firstRange = (range.cloneRange()), lastRange = (range.cloneRange()), fillerRange = range.cloneRange(); - if(!nodes.length) { - return null + init() +}; +gui.AnnotationController.annotatableChanged = "annotatable/changed"; +(function() { + return gui.AnnotationController +})(); +gui.Avatar = function Avatar(parentElement, avatarInitiallyVisible) { + var self = this, handle, image, pendingImageUrl, displayShown = "block", displayHidden = "none"; + this.setColor = function(color) { + image.style.borderColor = color + }; + this.setImageUrl = function(url) { + if(self.isVisible()) { + image.src = url + }else { + pendingImageUrl = url } - if(!firstVisibleRect(firstRange, nodes)) { - return null + }; + this.isVisible = function() { + return handle.style.display === displayShown + }; + this.show = function() { + if(pendingImageUrl) { + image.src = pendingImageUrl; + pendingImageUrl = undefined } - if(!lastVisibleRect(lastRange, nodes)) { - return null + handle.style.display = displayShown + }; + this.hide = function() { + handle.style.display = displayHidden + }; + this.markAsFocussed = function(isFocussed) { + if(isFocussed) { + handle.classList.add("active") + }else { + handle.classList.remove("active") } - fillerRange.setStart(firstRange.startContainer, firstRange.startOffset); - fillerRange.setEnd(lastRange.endContainer, lastRange.endOffset); - return{firstRange:firstRange, lastRange:lastRange, fillerRange:fillerRange} + }; + this.destroy = function(callback) { + parentElement.removeChild(handle); + callback() + }; + function init() { + var document = (parentElement.ownerDocument), htmlns = document.documentElement.namespaceURI; + handle = (document.createElementNS(htmlns, "div")); + image = (document.createElementNS(htmlns, "img")); + image.width = 64; + image.height = 64; + handle.appendChild(image); + handle.style.width = "64px"; + handle.style.height = "70px"; + handle.style.position = "absolute"; + handle.style.top = "-80px"; + handle.style.left = "-34px"; + handle.style.display = avatarInitiallyVisible ? displayShown : displayHidden; + handle.className = "handle"; + parentElement.appendChild(handle) } - function getBoundingRect(rect1, rect2) { - var resultRect = {}; - resultRect.top = Math.min(rect1.top, rect2.top); - resultRect.left = Math.min(rect1.left, rect2.left); - resultRect.right = Math.max(rect1.right, rect2.right); - resultRect.bottom = Math.max(rect1.bottom, rect2.bottom); - resultRect.width = resultRect.right - resultRect.left; - resultRect.height = resultRect.bottom - resultRect.top; - return resultRect + init() +}; +gui.Caret = function Caret(cursor, avatarInitiallyVisible, blinkOnRangeSelect) { + var MIN_CARET_HEIGHT_PX = 8, DEFAULT_CARET_TOP = "5%", DEFAULT_CARET_HEIGHT = "1em", BLINK_PERIOD_MS = 500, span, avatar, cursorNode, overlayElement, domUtils = new core.DomUtils, async = new core.Async, redrawTask, blinkTask, shouldResetBlink = false, shouldCheckCaretVisibility = false, shouldUpdateCaretSize = false, state = {isFocused:false, isShown:true, visibility:"hidden"}, lastState = {isFocused:!state.isFocused, isShown:!state.isShown, visibility:"hidden"}; + function blinkCaret() { + span.style.opacity = span.style.opacity === "0" ? "1" : "0"; + blinkTask.trigger() } - function checkAndGrowOrCreateRect(originalRect, newRect) { - if(newRect && (newRect.width > 0 && newRect.height > 0)) { - if(!originalRect) { - originalRect = newRect - }else { - originalRect = getBoundingRect(originalRect, newRect) - } + function getCaretClientRectWithMargin(caretElement, margin) { + var caretRect = caretElement.getBoundingClientRect(); + return{left:caretRect.left - margin.left, top:caretRect.top - margin.top, right:caretRect.right + margin.right, bottom:caretRect.bottom + margin.bottom} + } + function length(node) { + return node.nodeType === Node.TEXT_NODE ? node.textContent.length : node.childNodes.length + } + function verticalOverlap(cursorNode, rangeRect) { + var cursorRect = cursorNode.getBoundingClientRect(), intersectTop = 0, intersectBottom = 0; + if(cursorRect && rangeRect) { + intersectTop = Math.max(cursorRect.top, rangeRect.top); + intersectBottom = Math.min(cursorRect.bottom, rangeRect.bottom) } - return originalRect + return intersectBottom - intersectTop } - function getFillerRect(fillerRange) { - var containerNode = fillerRange.commonAncestorContainer, firstNode = (fillerRange.startContainer), lastNode = (fillerRange.endContainer), firstOffset = fillerRange.startOffset, lastOffset = fillerRange.endOffset, currentNode, lastMeasuredNode, firstSibling, lastSibling, grownRect = null, currentRect, range = doc.createRange(), rootFilter, odfNodeFilter = new odf.OdfNodeFilter, treeWalker; - function acceptNode(node) { - positionIterator.setUnfilteredPosition(node, 0); - if(odfNodeFilter.acceptNode(node) === FILTER_ACCEPT && rootFilter.acceptPosition(positionIterator) === FILTER_ACCEPT) { - return FILTER_ACCEPT + function getSelectionRect() { + var range = cursor.getSelectedRange().cloneRange(), node = cursor.getNode(), nextRectangle, selectionRectangle = null, nodeLength; + if(node.previousSibling) { + nodeLength = length(node.previousSibling); + range.setStart(node.previousSibling, nodeLength > 0 ? nodeLength - 1 : 0); + range.setEnd(node.previousSibling, nodeLength); + nextRectangle = range.getBoundingClientRect(); + if(nextRectangle && nextRectangle.height) { + selectionRectangle = nextRectangle } - return FILTER_REJECT } - function getRectFromNodeAfterFiltering(node) { - var rect = null; - if(acceptNode(node) === FILTER_ACCEPT) { - rect = domUtils.getBoundingClientRect(node) + if(node.nextSibling) { + range.setStart(node.nextSibling, 0); + range.setEnd(node.nextSibling, length(node.nextSibling) > 0 ? 1 : 0); + nextRectangle = range.getBoundingClientRect(); + if(nextRectangle && nextRectangle.height) { + if(!selectionRectangle || verticalOverlap(node, nextRectangle) > verticalOverlap(node, selectionRectangle)) { + selectionRectangle = nextRectangle + } } - return rect } - if(firstNode === containerNode || lastNode === containerNode) { - range = fillerRange.cloneRange(); - grownRect = range.getBoundingClientRect(); - range.detach(); - return grownRect - } - firstSibling = firstNode; - while(firstSibling.parentNode !== containerNode) { - firstSibling = firstSibling.parentNode - } - lastSibling = lastNode; - while(lastSibling.parentNode !== containerNode) { - lastSibling = lastSibling.parentNode - } - rootFilter = odtDocument.createRootFilter(firstNode); - currentNode = firstSibling.nextSibling; - while(currentNode && currentNode !== lastSibling) { - currentRect = getRectFromNodeAfterFiltering(currentNode); - grownRect = checkAndGrowOrCreateRect(grownRect, currentRect); - currentNode = currentNode.nextSibling - } - if(odfUtils.isParagraph(firstSibling)) { - grownRect = checkAndGrowOrCreateRect(grownRect, domUtils.getBoundingClientRect(firstSibling)) + return selectionRectangle + } + function updateCaretHeightAndPosition() { + var selectionRect = getSelectionRect(), canvas = (cursor.getDocument().getCanvas()), zoomLevel = canvas.getZoomLevel(), rootRect = domUtils.getBoundingClientRect(canvas.getSizer()), caretRect, caretStyle; + if(selectionRect) { + span.style.top = "0"; + caretRect = domUtils.getBoundingClientRect(span); + if(selectionRect.height < MIN_CARET_HEIGHT_PX) { + selectionRect = {top:selectionRect.top - (MIN_CARET_HEIGHT_PX - selectionRect.height) / 2, height:MIN_CARET_HEIGHT_PX} + } + span.style.height = domUtils.adaptRangeDifferenceToZoomLevel(selectionRect.height, zoomLevel) + "px"; + span.style.top = domUtils.adaptRangeDifferenceToZoomLevel(selectionRect.top - caretRect.top, zoomLevel) + "px" }else { - if(firstSibling.nodeType === Node.TEXT_NODE) { - currentNode = firstSibling; - range.setStart(currentNode, firstOffset); - range.setEnd(currentNode, currentNode === lastSibling ? lastOffset : currentNode.length); - currentRect = range.getBoundingClientRect(); - grownRect = checkAndGrowOrCreateRect(grownRect, currentRect) + span.style.height = DEFAULT_CARET_HEIGHT; + span.style.top = DEFAULT_CARET_TOP + } + if(overlayElement) { + caretStyle = runtime.getWindow().getComputedStyle(span, null); + caretRect = domUtils.getBoundingClientRect(span); + overlayElement.style.bottom = domUtils.adaptRangeDifferenceToZoomLevel(rootRect.bottom - caretRect.bottom, zoomLevel) + "px"; + overlayElement.style.left = domUtils.adaptRangeDifferenceToZoomLevel(caretRect.right - rootRect.left, zoomLevel) + "px"; + if(caretStyle.font) { + overlayElement.style.font = caretStyle.font }else { - treeWalker = doc.createTreeWalker(firstSibling, NodeFilter.SHOW_TEXT, acceptNode, false); - currentNode = treeWalker.currentNode = firstNode; - while(currentNode && currentNode !== lastNode) { - range.setStart(currentNode, firstOffset); - range.setEnd(currentNode, currentNode.length); - currentRect = range.getBoundingClientRect(); - grownRect = checkAndGrowOrCreateRect(grownRect, currentRect); - lastMeasuredNode = currentNode; - firstOffset = 0; - currentNode = treeWalker.nextNode() - } + overlayElement.style.fontStyle = caretStyle.fontStyle; + overlayElement.style.fontVariant = caretStyle.fontVariant; + overlayElement.style.fontWeight = caretStyle.fontWeight; + overlayElement.style.fontSize = caretStyle.fontSize; + overlayElement.style.lineHeight = caretStyle.lineHeight; + overlayElement.style.fontFamily = caretStyle.fontFamily } } - if(!lastMeasuredNode) { - lastMeasuredNode = firstNode + } + function ensureVisible() { + var canvasElement = cursor.getDocument().getCanvas().getElement(), canvasContainerElement = (canvasElement.parentNode), caretRect, canvasContainerRect, horizontalMargin = canvasContainerElement.offsetWidth - canvasContainerElement.clientWidth + 5, verticalMargin = canvasContainerElement.offsetHeight - canvasContainerElement.clientHeight + 5; + caretRect = getCaretClientRectWithMargin(span, {top:verticalMargin, left:horizontalMargin, bottom:verticalMargin, right:horizontalMargin}); + canvasContainerRect = canvasContainerElement.getBoundingClientRect(); + if(caretRect.top < canvasContainerRect.top) { + canvasContainerElement.scrollTop -= canvasContainerRect.top - caretRect.top + }else { + if(caretRect.bottom > canvasContainerRect.bottom) { + canvasContainerElement.scrollTop += caretRect.bottom - canvasContainerRect.bottom + } } - if(odfUtils.isParagraph(lastSibling)) { - grownRect = checkAndGrowOrCreateRect(grownRect, domUtils.getBoundingClientRect(lastSibling)) + if(caretRect.left < canvasContainerRect.left) { + canvasContainerElement.scrollLeft -= canvasContainerRect.left - caretRect.left }else { - if(lastSibling.nodeType === Node.TEXT_NODE) { - currentNode = lastSibling; - range.setStart(currentNode, currentNode === firstSibling ? firstOffset : 0); - range.setEnd(currentNode, lastOffset); - currentRect = range.getBoundingClientRect(); - grownRect = checkAndGrowOrCreateRect(grownRect, currentRect) - }else { - treeWalker = doc.createTreeWalker(lastSibling, NodeFilter.SHOW_TEXT, acceptNode, false); - currentNode = treeWalker.currentNode = lastNode; - while(currentNode && currentNode !== lastMeasuredNode) { - range.setStart(currentNode, 0); - range.setEnd(currentNode, lastOffset); - currentRect = range.getBoundingClientRect(); - grownRect = checkAndGrowOrCreateRect(grownRect, currentRect); - currentNode = treeWalker.previousNode(); - if(currentNode) { - lastOffset = currentNode.length - } - } + if(caretRect.right > canvasContainerRect.right) { + canvasContainerElement.scrollLeft += caretRect.right - canvasContainerRect.right } } - return grownRect } - function getCollapsedRectOfTextRange(range, useRightEdge) { - var clientRect = range.getBoundingClientRect(), collapsedRect = {}; - collapsedRect.width = 0; - collapsedRect.top = clientRect.top; - collapsedRect.bottom = clientRect.bottom; - collapsedRect.height = clientRect.height; - collapsedRect.left = collapsedRect.right = useRightEdge ? clientRect.right : clientRect.left; - return collapsedRect + function hasStateChanged(property) { + return lastState[property] !== state[property] } - function repositionOverlays(selectedRange) { - var extremes = getExtremeRanges(selectedRange), firstRange, lastRange, fillerRange, firstRect, fillerRect, lastRect; - if(selectedRange.collapsed || !extremes) { - showOverlays(false) + function saveState() { + Object.keys(state).forEach(function(key) { + lastState[key] = state[key] + }) + } + function updateCaret() { + if(state.isShown === false || (cursor.getSelectionType() !== ops.OdtCursor.RangeSelection || !blinkOnRangeSelect && !cursor.getSelectedRange().collapsed)) { + state.visibility = "hidden"; + span.style.visibility = "hidden"; + blinkTask.cancel() }else { - showOverlays(true); - firstRange = extremes.firstRange; - lastRange = extremes.lastRange; - fillerRange = extremes.fillerRange; - firstRect = translateRect(getCollapsedRectOfTextRange(firstRange, false)); - lastRect = translateRect(getCollapsedRectOfTextRange(lastRange, true)); - fillerRect = getFillerRect(fillerRange); - if(!fillerRect) { - fillerRect = getBoundingRect(firstRect, lastRect) + state.visibility = "visible"; + span.style.visibility = "visible"; + if(state.isFocused === false) { + span.style.opacity = "1"; + blinkTask.cancel() }else { - fillerRect = translateRect(fillerRect) + if(shouldResetBlink || hasStateChanged("visibility")) { + span.style.opacity = "1"; + blinkTask.cancel() + } + blinkTask.trigger() } - setRect(overlayTop, {left:firstRect.left, top:firstRect.top, width:Math.max(0, fillerRect.width - (firstRect.left - fillerRect.left)), height:firstRect.height}); - if(lastRect.top === firstRect.top || lastRect.bottom === firstRect.bottom) { - overlayMiddle.style.display = overlayBottom.style.display = "none" - }else { - setRect(overlayBottom, {left:fillerRect.left, top:lastRect.top, width:Math.max(0, lastRect.right - fillerRect.left), height:lastRect.height}); - setRect(overlayMiddle, {left:fillerRect.left, top:firstRect.top + firstRect.height, width:Math.max(0, parseFloat(overlayTop.style.left) + parseFloat(overlayTop.style.width) - parseFloat(overlayBottom.style.left)), height:Math.max(0, lastRect.top - firstRect.bottom)}) + if(shouldUpdateCaretSize || (shouldCheckCaretVisibility || hasStateChanged("visibility"))) { + updateCaretHeightAndPosition() + } + if(shouldCheckCaretVisibility) { + ensureVisible() } - firstRange.detach(); - lastRange.detach(); - fillerRange.detach() } - } - function rerender() { - addOverlays(); - if(cursor.getSelectionType() === ops.OdtCursor.RangeSelection) { - showOverlays(true); - repositionOverlays(cursor.getSelectedRange()) - }else { - showOverlays(false) + if(hasStateChanged("isFocused")) { + avatar.markAsFocussed(state.isFocused) } + saveState(); + shouldResetBlink = false; + shouldCheckCaretVisibility = false; + shouldUpdateCaretSize = false } - this.rerender = rerender; - this.show = rerender; + this.handleUpdate = function() { + shouldUpdateCaretSize = true; + if(state.visibility !== "hidden") { + state.visibility = "hidden"; + span.style.visibility = "hidden" + } + redrawTask.trigger() + }; + this.refreshCursorBlinking = function() { + shouldResetBlink = true; + redrawTask.trigger() + }; + this.setFocus = function() { + state.isFocused = true; + redrawTask.trigger() + }; + this.removeFocus = function() { + state.isFocused = false; + redrawTask.trigger() + }; + this.show = function() { + state.isShown = true; + redrawTask.trigger() + }; this.hide = function() { - showOverlays(false) + state.isShown = false; + redrawTask.trigger() }; - this.visible = function() { - return isVisible + this.setAvatarImageUrl = function(url) { + avatar.setImageUrl(url) }; - function handleCursorMove(movedCursor) { - if(movedCursor === cursor) { - rerender() + this.setColor = function(newColor) { + span.style.borderColor = newColor; + avatar.setColor(newColor) + }; + this.getCursor = function() { + return cursor + }; + this.getFocusElement = function() { + return span + }; + this.toggleHandleVisibility = function() { + if(avatar.isVisible()) { + avatar.hide() + }else { + avatar.show() } + }; + this.showHandle = function() { + avatar.show() + }; + this.hideHandle = function() { + avatar.hide() + }; + this.setOverlayElement = function(element) { + overlayElement = element; + shouldUpdateCaretSize = true; + redrawTask.trigger() + }; + this.ensureVisible = function() { + shouldCheckCaretVisibility = true; + redrawTask.trigger() + }; + function destroy(callback) { + cursorNode.removeChild(span); + callback() } this.destroy = function(callback) { - root.removeChild(overlayTop); - root.removeChild(overlayMiddle); - root.removeChild(overlayBottom); - cursor.getOdtDocument().unsubscribe(ops.OdtDocument.signalCursorMoved, handleCursorMove); - callback() + var cleanup = [redrawTask.destroy, blinkTask.destroy, avatar.destroy, destroy]; + async.destroyAll(cleanup, callback) }; function init() { - var editinfons = "urn:webodf:names:editinfo", memberid = cursor.getMemberId(); - addOverlays(); - overlayTop.setAttributeNS(editinfons, "editinfo:memberid", memberid); - overlayMiddle.setAttributeNS(editinfons, "editinfo:memberid", memberid); - overlayBottom.setAttributeNS(editinfons, "editinfo:memberid", memberid); - overlayTop.className = overlayMiddle.className = overlayBottom.className = "selectionOverlay"; - cursor.getOdtDocument().subscribe(ops.OdtDocument.signalCursorMoved, handleCursorMove) + var dom = cursor.getDocument().getDOMDocument(), htmlns = dom.documentElement.namespaceURI; + span = (dom.createElementNS(htmlns, "span")); + span.className = "caret"; + span.style.top = DEFAULT_CARET_TOP; + cursorNode = cursor.getNode(); + cursorNode.appendChild(span); + avatar = new gui.Avatar(cursorNode, avatarInitiallyVisible); + redrawTask = new core.ScheduledTask(updateCaret, 0); + blinkTask = new core.ScheduledTask(blinkCaret, BLINK_PERIOD_MS); + redrawTask.triggerImmediate() } init() }; @@ -15959,72 +12899,84 @@ gui.SelectionView = function SelectionView(cursor) { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("gui.SelectionView"); -gui.SelectionViewManager = function SelectionViewManager() { - var selectionViews = {}; - function getSelectionView(memberId) { - return selectionViews.hasOwnProperty(memberId) ? selectionViews[memberId] : null - } - this.getSelectionView = getSelectionView; - function getSelectionViews() { - return Object.keys(selectionViews).map(function(memberid) { - return selectionViews[memberid] - }) - } - this.getSelectionViews = getSelectionViews; - function removeSelectionView(memberId) { - if(selectionViews.hasOwnProperty(memberId)) { - selectionViews[memberId].destroy(function() { - }); - delete selectionViews[memberId] +odf.TextSerializer = function TextSerializer() { + var self = this, odfUtils = new odf.OdfUtils; + function serializeNode(node) { + var s = "", accept = self.filter ? self.filter.acceptNode(node) : NodeFilter.FILTER_ACCEPT, nodeType = node.nodeType, child; + if((accept === NodeFilter.FILTER_ACCEPT || accept === NodeFilter.FILTER_SKIP) && odfUtils.isTextContentContainingNode(node)) { + child = node.firstChild; + while(child) { + s += serializeNode(child); + child = child.nextSibling + } } - } - this.removeSelectionView = removeSelectionView; - function hideSelectionView(memberId) { - if(selectionViews.hasOwnProperty(memberId)) { - selectionViews[memberId].hide() + if(accept === NodeFilter.FILTER_ACCEPT) { + if(nodeType === Node.ELEMENT_NODE && odfUtils.isParagraph(node)) { + s += "\n" + }else { + if(nodeType === Node.TEXT_NODE && node.textContent) { + s += node.textContent + } + } } + return s } - this.hideSelectionView = hideSelectionView; - function showSelectionView(memberId) { - if(selectionViews.hasOwnProperty(memberId)) { - selectionViews[memberId].show() + this.filter = null; + this.writeToString = function(node) { + var plainText; + if(!node) { + return"" } + plainText = serializeNode(node); + if(plainText[plainText.length - 1] === "\n") { + plainText = plainText.substr(0, plainText.length - 1) + } + return plainText } - this.showSelectionView = showSelectionView; - this.rerenderSelectionViews = function() { - Object.keys(selectionViews).forEach(function(memberId) { - if(selectionViews[memberId].visible()) { - selectionViews[memberId].rerender() - } - }) - }; - this.registerCursor = function(cursor, virtualSelectionsInitiallyVisible) { - var memberId = cursor.getMemberId(), selectionView = new gui.SelectionView(cursor); - if(virtualSelectionsInitiallyVisible) { - selectionView.show() - }else { - selectionView.hide() +}; +/* + + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +gui.MimeDataExporter = function MimeDataExporter() { + var textSerializer, filter; + this.exportRangeToDataTransfer = function(dataTransfer, range) { + var document = range.startContainer.ownerDocument, serializedFragment, fragmentContainer; + fragmentContainer = document.createElement("span"); + fragmentContainer.appendChild(range.cloneContents()); + serializedFragment = textSerializer.writeToString(fragmentContainer); + try { + dataTransfer.setData("text/plain", serializedFragment) + }catch(e) { + dataTransfer.setData("Text", serializedFragment) } - selectionViews[memberId] = selectionView; - return selectionView }; - this.destroy = function(callback) { - var selectionViewArray = getSelectionViews(); - (function destroySelectionView(i, err) { - if(err) { - callback(err) - }else { - if(i < selectionViewArray.length) { - selectionViewArray[i].destroy(function(err) { - destroySelectionView(i + 1, err) - }) - }else { - callback() - } - } - })(0, undefined) + function init() { + textSerializer = new odf.TextSerializer; + filter = new odf.OdfNodeFilter; + textSerializer.filter = filter } + init() }; /* @@ -16063,170 +13015,25 @@ gui.SelectionViewManager = function SelectionViewManager() { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils"); -runtime.loadClass("gui.UndoManager"); -runtime.loadClass("gui.UndoStateRules"); -gui.TrivialUndoManager = function TrivialUndoManager(defaultRules) { - var self = this, cursorns = "urn:webodf:names:cursor", domUtils = new core.DomUtils, initialDoc, initialState = [], playFunc, odtDocument, currentUndoState = [], undoStates = [], redoStates = [], eventNotifier = new core.EventNotifier([gui.UndoManager.signalUndoStackChanged, gui.UndoManager.signalUndoStateCreated, gui.UndoManager.signalUndoStateModified, gui.TrivialUndoManager.signalDocumentRootReplaced]), undoRules = defaultRules || new gui.UndoStateRules; - function emitStackChange() { - eventNotifier.emit(gui.UndoManager.signalUndoStackChanged, {undoAvailable:self.hasUndoStates(), redoAvailable:self.hasRedoStates()}) - } - function mostRecentUndoState() { - return undoStates[undoStates.length - 1] - } - function completeCurrentUndoState() { - if(currentUndoState !== initialState && currentUndoState !== mostRecentUndoState()) { - undoStates.push(currentUndoState) - } - } - function removeNode(node) { - var sibling = node.previousSibling || node.nextSibling; - node.parentNode.removeChild(node); - domUtils.normalizeTextNodes(sibling) - } - function removeCursors(root) { - domUtils.getElementsByTagNameNS(root, cursorns, "cursor").forEach(removeNode); - domUtils.getElementsByTagNameNS(root, cursorns, "anchor").forEach(removeNode) - } - function values(obj) { - return Object.keys(obj).map(function(key) { - return obj[key] - }) - } - function extractCursorStates(undoStates) { - var addCursor = {}, moveCursor = {}, requiredAddOps = {}, remainingAddOps, operations = undoStates.pop(); - odtDocument.getCursors().forEach(function(cursor) { - requiredAddOps[cursor.getMemberId()] = true - }); - remainingAddOps = Object.keys(requiredAddOps).length; - function processOp(op) { - var spec = op.spec(); - if(!requiredAddOps[spec.memberid]) { - return - } - switch(spec.optype) { - case "AddCursor": - if(!addCursor[spec.memberid]) { - addCursor[spec.memberid] = op; - delete requiredAddOps[spec.memberid]; - remainingAddOps -= 1 - } - break; - case "MoveCursor": - if(!moveCursor[spec.memberid]) { - moveCursor[spec.memberid] = op - } - break - } - } - while(operations && remainingAddOps > 0) { - operations.reverse(); - operations.forEach(processOp); - operations = undoStates.pop() - } - return values(addCursor).concat(values(moveCursor)) - } - this.subscribe = function(signal, callback) { - eventNotifier.subscribe(signal, callback) - }; - this.unsubscribe = function(signal, callback) { - eventNotifier.unsubscribe(signal, callback) - }; - this.hasUndoStates = function() { - return undoStates.length > 0 - }; - this.hasRedoStates = function() { - return redoStates.length > 0 - }; - this.setOdtDocument = function(newDocument) { - odtDocument = newDocument - }; - this.resetInitialState = function() { - undoStates.length = 0; - redoStates.length = 0; - initialState.length = 0; - currentUndoState.length = 0; - initialDoc = null; - emitStackChange() - }; - this.saveInitialState = function() { - var odfContainer = odtDocument.getOdfCanvas().odfContainer(), annotationViewManager = odtDocument.getOdfCanvas().getAnnotationViewManager(); - if(annotationViewManager) { - annotationViewManager.forgetAnnotations() +gui.Clipboard = function Clipboard(mimeDataExporter) { + this.setDataFromRange = function(e, range) { + var result, clipboard = e.clipboardData, window = runtime.getWindow(); + if(!clipboard && window) { + clipboard = window.clipboardData } - initialDoc = odfContainer.rootElement.cloneNode(true); - odtDocument.getOdfCanvas().refreshAnnotations(); - removeCursors(initialDoc); - completeCurrentUndoState(); - undoStates.unshift(initialState); - currentUndoState = initialState = extractCursorStates(undoStates); - undoStates.length = 0; - redoStates.length = 0; - emitStackChange() - }; - this.setPlaybackFunction = function(playback_func) { - playFunc = playback_func - }; - this.onOperationExecuted = function(op) { - redoStates.length = 0; - if(undoRules.isEditOperation(op) && currentUndoState === initialState || !undoRules.isPartOfOperationSet(op, currentUndoState)) { - completeCurrentUndoState(); - currentUndoState = [op]; - undoStates.push(currentUndoState); - eventNotifier.emit(gui.UndoManager.signalUndoStateCreated, {operations:currentUndoState}); - emitStackChange() + if(clipboard) { + result = true; + mimeDataExporter.exportRangeToDataTransfer((clipboard), range); + e.preventDefault() }else { - currentUndoState.push(op); - eventNotifier.emit(gui.UndoManager.signalUndoStateModified, {operations:currentUndoState}) - } - }; - this.moveForward = function(states) { - var moved = 0, redoOperations; - while(states && redoStates.length) { - redoOperations = redoStates.pop(); - undoStates.push(redoOperations); - redoOperations.forEach(playFunc); - states -= 1; - moved += 1 - } - if(moved) { - currentUndoState = mostRecentUndoState(); - emitStackChange() - } - return moved - }; - this.moveBackward = function(states) { - var odfCanvas = odtDocument.getOdfCanvas(), odfContainer = odfCanvas.odfContainer(), moved = 0; - while(states && undoStates.length) { - redoStates.push(undoStates.pop()); - states -= 1; - moved += 1 - } - if(moved) { - odfContainer.setRootElement(initialDoc.cloneNode(true)); - odfCanvas.setOdfContainer(odfContainer, true); - eventNotifier.emit(gui.TrivialUndoManager.signalDocumentRootReplaced, {}); - odtDocument.getCursors().forEach(function(cursor) { - odtDocument.removeCursor(cursor.getMemberId()) - }); - initialState.forEach(playFunc); - undoStates.forEach(function(ops) { - ops.forEach(playFunc) - }); - odfCanvas.refreshCSS(); - currentUndoState = mostRecentUndoState() || initialState; - emitStackChange() + result = false } - return moved + return result } }; -gui.TrivialUndoManager.signalDocumentRootReplaced = "documentRootReplaced"; -(function() { - return gui.TrivialUndoManager -})(); /* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012-2014 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -16261,167 +13068,54 @@ gui.TrivialUndoManager.signalDocumentRootReplaced = "documentRootReplaced"; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.TrivialOperationRouter"); -runtime.loadClass("ops.OperationFactory"); -runtime.loadClass("ops.OdtDocument"); -ops.Session = function Session(odfCanvas) { - var self = this, operationFactory = new ops.OperationFactory, odtDocument = new ops.OdtDocument(odfCanvas), operationRouter = null; - this.setOperationFactory = function(opFactory) { - operationFactory = opFactory; - if(operationRouter) { - operationRouter.setOperationFactory(operationFactory) - } - }; - this.setOperationRouter = function(opRouter) { - operationRouter = opRouter; - opRouter.setPlaybackFunction(function(op) { - if(op.execute(odtDocument)) { - odtDocument.emit(ops.OdtDocument.signalOperationExecuted, op); - return true - } - return false - }); - opRouter.setOperationFactory(operationFactory) - }; - this.getOperationFactory = function() { - return operationFactory - }; - this.getOdtDocument = function() { - return odtDocument - }; - this.enqueue = function(ops) { - operationRouter.push(ops) - }; - this.close = function(callback) { - operationRouter.close(function(err) { - if(err) { - callback(err) - }else { - odtDocument.close(callback) - } - }) - }; - this.destroy = function(callback) { - odtDocument.destroy(callback) - }; - function init() { - self.setOperationRouter(new ops.TrivialOperationRouter) - } - init() -}; -/* - - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> - - @licstart - This file is part of WebODF. - - WebODF 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. - - WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. - @licend - - @source: http://www.webodf.org/ - @source: https://github.com/kogmbh/WebODF/ -*/ -runtime.loadClass("core.EventNotifier"); -runtime.loadClass("core.PositionFilter"); -runtime.loadClass("ops.Session"); -runtime.loadClass("ops.OpAddAnnotation"); -runtime.loadClass("ops.OpRemoveAnnotation"); -runtime.loadClass("gui.SelectionMover"); -gui.AnnotationController = function AnnotationController(session, inputMemberId) { - var odtDocument = session.getOdtDocument(), isAnnotatable = false, eventNotifier = new core.EventNotifier([gui.AnnotationController.annotatableChanged]), officens = odf.Namespaces.officens; - function isWithinAnnotation(node, container) { - while(node && node !== container) { - if(node.namespaceURI === officens && node.localName === "annotation") { - return true - } - node = node.parentNode - } - return false - } - function updatedCachedValues() { - var cursor = odtDocument.getCursor(inputMemberId), cursorNode = cursor && cursor.getNode(), newIsAnnotatable = false; - if(cursorNode) { - newIsAnnotatable = !isWithinAnnotation(cursorNode, odtDocument.getRootNode()) - } - if(newIsAnnotatable !== isAnnotatable) { - isAnnotatable = newIsAnnotatable; - eventNotifier.emit(gui.AnnotationController.annotatableChanged, isAnnotatable) - } - } - function onCursorAdded(cursor) { - if(cursor.getMemberId() === inputMemberId) { - updatedCachedValues() +gui.StyleSummary = function StyleSummary(styles) { + var propertyValues = {}; + function getPropertyValues(section, propertyName) { + var cacheKey = section + "|" + propertyName, values; + if(!propertyValues.hasOwnProperty(cacheKey)) { + values = []; + styles.forEach(function(style) { + var styleSection = style[section], value = styleSection && styleSection[propertyName]; + if(values.indexOf(value) === -1) { + values.push(value) + } + }); + propertyValues[cacheKey] = values } + return propertyValues[cacheKey] } - function onCursorRemoved(memberId) { - if(memberId === inputMemberId) { - updatedCachedValues() + this.getPropertyValues = getPropertyValues; + function lazilyLoaded(section, propertyName, acceptedPropertyValues) { + return function() { + var existingPropertyValues = getPropertyValues(section, propertyName); + return acceptedPropertyValues.length >= existingPropertyValues.length && existingPropertyValues.every(function(v) { + return acceptedPropertyValues.indexOf(v) !== -1 + }) } } - function onCursorMoved(cursor) { - if(cursor.getMemberId() === inputMemberId) { - updatedCachedValues() - } + function getCommonValue(section, propertyName) { + var values = getPropertyValues(section, propertyName); + return values.length === 1 ? values[0] : undefined } - this.isAnnotatable = function() { - return isAnnotatable - }; - this.addAnnotation = function() { - var op = new ops.OpAddAnnotation, selection = odtDocument.getCursorSelection(inputMemberId), length = selection.length, position = selection.position; - if(!isAnnotatable) { - return - } - position = length >= 0 ? position : position + length; - length = Math.abs(length); - op.init({memberid:inputMemberId, position:position, length:length, name:inputMemberId + Date.now()}); - session.enqueue([op]) - }; - this.removeAnnotation = function(annotationNode) { - var startStep, endStep, op, moveCursor; - startStep = odtDocument.convertDomPointToCursorStep(annotationNode, 0) + 1; - endStep = odtDocument.convertDomPointToCursorStep(annotationNode, annotationNode.childNodes.length); - op = new ops.OpRemoveAnnotation; - op.init({memberid:inputMemberId, position:startStep, length:endStep - startStep}); - moveCursor = new ops.OpMoveCursor; - moveCursor.init({memberid:inputMemberId, position:startStep > 0 ? startStep - 1 : startStep, length:0}); - session.enqueue([op, moveCursor]) - }; - this.subscribe = function(eventid, cb) { - eventNotifier.subscribe(eventid, cb) - }; - this.unsubscribe = function(eventid, cb) { - eventNotifier.unsubscribe(eventid, cb) - }; - this.destroy = function(callback) { - odtDocument.unsubscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); - callback() + this.getCommonValue = getCommonValue; + this.isBold = lazilyLoaded("style:text-properties", "fo:font-weight", ["bold"]); + this.isItalic = lazilyLoaded("style:text-properties", "fo:font-style", ["italic"]); + this.hasUnderline = lazilyLoaded("style:text-properties", "style:text-underline-style", ["solid"]); + this.hasStrikeThrough = lazilyLoaded("style:text-properties", "style:text-line-through-style", ["solid"]); + this.fontSize = function() { + var stringFontSize = getCommonValue("style:text-properties", "fo:font-size"); + return(stringFontSize && parseFloat(stringFontSize)) }; - function init() { - odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); - odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); - odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); - updatedCachedValues() - } - init() + this.fontName = function() { + return getCommonValue("style:text-properties", "style:font-name") + }; + this.isAlignedLeft = lazilyLoaded("style:paragraph-properties", "fo:text-align", ["left", "start"]); + this.isAlignedCenter = lazilyLoaded("style:paragraph-properties", "fo:text-align", ["center"]); + this.isAlignedRight = lazilyLoaded("style:paragraph-properties", "fo:text-align", ["right", "end"]); + this.isAlignedJustified = lazilyLoaded("style:paragraph-properties", "fo:text-align", ["justify"]); + this.text = {isBold:this.isBold, isItalic:this.isItalic, hasUnderline:this.hasUnderline, hasStrikeThrough:this.hasStrikeThrough, fontSize:this.fontSize, fontName:this.fontName}; + this.paragraph = {isAlignedLeft:this.isAlignedLeft, isAlignedCenter:this.isAlignedCenter, isAlignedRight:this.isAlignedRight, isAlignedJustified:this.isAlignedJustified} }; -gui.AnnotationController.annotatableChanged = "annotatable/changed"; -(function() { - return gui.AnnotationController -})(); /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -16459,86 +13153,214 @@ gui.AnnotationController.annotatableChanged = "annotatable/changed"; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.EventNotifier"); -runtime.loadClass("core.Utils"); -runtime.loadClass("odf.OdfUtils"); -runtime.loadClass("ops.OpAddStyle"); -runtime.loadClass("ops.OpSetParagraphStyle"); -runtime.loadClass("gui.StyleHelper"); -gui.DirectParagraphStyler = function DirectParagraphStyler(session, inputMemberId, objectNameGenerator) { - var odtDocument = session.getOdtDocument(), utils = new core.Utils, odfUtils = new odf.OdfUtils, styleHelper = new gui.StyleHelper(odtDocument.getFormatting()), eventNotifier = new core.EventNotifier([gui.DirectParagraphStyler.paragraphStylingChanged]), isAlignedLeftValue, isAlignedCenterValue, isAlignedRightValue, isAlignedJustifiedValue; - function updatedCachedValues() { - var cursor = odtDocument.getCursor(inputMemberId), range = cursor && cursor.getSelectedRange(), diffMap; - function noteChange(oldValue, newValue, id) { - if(oldValue !== newValue) { - if(diffMap === undefined) { - diffMap = {} - } - diffMap[id] = newValue +gui.DirectFormattingController = function DirectFormattingController(session, inputMemberId, objectNameGenerator, directParagraphStylingEnabled) { + var self = this, odtDocument = session.getOdtDocument(), utils = new core.Utils, odfUtils = new odf.OdfUtils, eventNotifier = new core.EventNotifier([gui.DirectFormattingController.textStylingChanged, gui.DirectFormattingController.paragraphStylingChanged]), textns = odf.Namespaces.textns, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, directCursorStyleProperties, selectionAppliedStyles = [], selectionStylesSummary = new gui.StyleSummary(selectionAppliedStyles); + function getNodes(range) { + var container, nodes; + if(range.collapsed) { + container = range.startContainer; + if(container.hasChildNodes() && range.startOffset < container.childNodes.length) { + container = container.childNodes.item(range.startOffset) } - return newValue - } - isAlignedLeftValue = noteChange(isAlignedLeftValue, range ? styleHelper.isAlignedLeft(range) : false, "isAlignedLeft"); - isAlignedCenterValue = noteChange(isAlignedCenterValue, range ? styleHelper.isAlignedCenter(range) : false, "isAlignedCenter"); - isAlignedRightValue = noteChange(isAlignedRightValue, range ? styleHelper.isAlignedRight(range) : false, "isAlignedRight"); - isAlignedJustifiedValue = noteChange(isAlignedJustifiedValue, range ? styleHelper.isAlignedJustified(range) : false, "isAlignedJustified"); - if(diffMap) { - eventNotifier.emit(gui.DirectParagraphStyler.paragraphStylingChanged, diffMap) + nodes = [container] + }else { + nodes = odfUtils.getTextNodes(range, true) } + return nodes } - function onCursorAdded(cursor) { - if(cursor.getMemberId() === inputMemberId) { - updatedCachedValues() + function getSelectionAppliedStyles() { + var cursor = odtDocument.getCursor(inputMemberId), range = cursor && cursor.getSelectedRange(), nodes = range ? getNodes(range) : [], selectionStyles = odtDocument.getFormatting().getAppliedStyles(nodes); + if(selectionStyles[0] && directCursorStyleProperties) { + selectionStyles[0] = utils.mergeObjects(selectionStyles[0], (directCursorStyleProperties)) } + return selectionStyles } - function onCursorRemoved(memberId) { - if(memberId === inputMemberId) { - updatedCachedValues() + function createDiff(oldSummary, newSummary) { + var diffMap = {}; + Object.keys(oldSummary).forEach(function(funcName) { + var oldValue = oldSummary[funcName](), newValue = newSummary[funcName](); + if(oldValue !== newValue) { + diffMap[funcName] = newValue + } + }); + return diffMap + } + function updateSelectionStylesInfo() { + var textStyleDiff, paragraphStyleDiff, newSelectionStylesSummary; + selectionAppliedStyles = getSelectionAppliedStyles(); + newSelectionStylesSummary = new gui.StyleSummary(selectionAppliedStyles); + textStyleDiff = createDiff(selectionStylesSummary.text, newSelectionStylesSummary.text); + paragraphStyleDiff = createDiff(selectionStylesSummary.paragraph, newSelectionStylesSummary.paragraph); + selectionStylesSummary = newSelectionStylesSummary; + if(Object.keys(textStyleDiff).length > 0) { + eventNotifier.emit(gui.DirectFormattingController.textStylingChanged, textStyleDiff) + } + if(Object.keys(paragraphStyleDiff).length > 0) { + eventNotifier.emit(gui.DirectFormattingController.paragraphStylingChanged, paragraphStyleDiff) } } - function onCursorMoved(cursor) { - if(cursor.getMemberId() === inputMemberId) { - updatedCachedValues() + function onCursorEvent(cursorOrId) { + var cursorMemberId = typeof cursorOrId === "string" ? cursorOrId : cursorOrId.getMemberId(); + if(cursorMemberId === inputMemberId) { + updateSelectionStylesInfo() } } function onParagraphStyleModified() { - updatedCachedValues() + updateSelectionStylesInfo() } function onParagraphChanged(args) { - var cursor = odtDocument.getCursor(inputMemberId); - if(cursor && odtDocument.getParagraphElement(cursor.getNode()) === args.paragraphElement) { - updatedCachedValues() + var cursor = odtDocument.getCursor(inputMemberId), p = args.paragraphElement; + if(cursor && odtDocument.getParagraphElement(cursor.getNode()) === p) { + updateSelectionStylesInfo() + } + } + function toggle(predicate, toggleMethod) { + toggleMethod(!predicate()); + return true + } + function formatTextSelection(textProperties) { + var selection = odtDocument.getCursorSelection(inputMemberId), op, properties = {"style:text-properties":textProperties}; + if(selection.length !== 0) { + op = new ops.OpApplyDirectStyling; + op.init({memberid:inputMemberId, position:selection.position, length:selection.length, setProperties:properties}); + session.enqueue([op]) + }else { + directCursorStyleProperties = utils.mergeObjects(directCursorStyleProperties || {}, properties); + updateSelectionStylesInfo() + } + } + this.formatTextSelection = formatTextSelection; + function applyTextPropertyToSelection(propertyName, propertyValue) { + var textProperties = {}; + textProperties[propertyName] = propertyValue; + formatTextSelection(textProperties) + } + this.createCursorStyleOp = function(position, length, useCachedStyle) { + var styleOp = null, properties = useCachedStyle ? selectionAppliedStyles[0] : directCursorStyleProperties; + if(properties && properties["style:text-properties"]) { + styleOp = new ops.OpApplyDirectStyling; + styleOp.init({memberid:inputMemberId, position:position, length:length, setProperties:{"style:text-properties":properties["style:text-properties"]}}); + directCursorStyleProperties = null; + updateSelectionStylesInfo() + } + return styleOp + }; + function clearCursorStyle(op) { + var spec = op.spec(); + if(directCursorStyleProperties && spec.memberid === inputMemberId) { + if(spec.optype !== "SplitParagraph") { + directCursorStyleProperties = null; + updateSelectionStylesInfo() + } } } + function setBold(checked) { + var value = checked ? "bold" : "normal"; + applyTextPropertyToSelection("fo:font-weight", value) + } + this.setBold = setBold; + function setItalic(checked) { + var value = checked ? "italic" : "normal"; + applyTextPropertyToSelection("fo:font-style", value) + } + this.setItalic = setItalic; + function setHasUnderline(checked) { + var value = checked ? "solid" : "none"; + applyTextPropertyToSelection("style:text-underline-style", value) + } + this.setHasUnderline = setHasUnderline; + function setHasStrikethrough(checked) { + var value = checked ? "solid" : "none"; + applyTextPropertyToSelection("style:text-line-through-style", value) + } + this.setHasStrikethrough = setHasStrikethrough; + function setFontSize(value) { + applyTextPropertyToSelection("fo:font-size", value + "pt") + } + this.setFontSize = setFontSize; + function setFontName(value) { + applyTextPropertyToSelection("style:font-name", value) + } + this.setFontName = setFontName; + this.getAppliedStyles = function() { + return selectionAppliedStyles + }; + this.toggleBold = toggle.bind(self, function() { + return selectionStylesSummary.isBold() + }, setBold); + this.toggleItalic = toggle.bind(self, function() { + return selectionStylesSummary.isItalic() + }, setItalic); + this.toggleUnderline = toggle.bind(self, function() { + return selectionStylesSummary.hasUnderline() + }, setHasUnderline); + this.toggleStrikethrough = toggle.bind(self, function() { + return selectionStylesSummary.hasStrikeThrough() + }, setHasStrikethrough); + this.isBold = function() { + return selectionStylesSummary.isBold() + }; + this.isItalic = function() { + return selectionStylesSummary.isItalic() + }; + this.hasUnderline = function() { + return selectionStylesSummary.hasUnderline() + }; + this.hasStrikeThrough = function() { + return selectionStylesSummary.hasStrikeThrough() + }; + this.fontSize = function() { + return selectionStylesSummary.fontSize() + }; + this.fontName = function() { + return selectionStylesSummary.fontName() + }; this.isAlignedLeft = function() { - return isAlignedLeftValue + return selectionStylesSummary.isAlignedLeft() }; this.isAlignedCenter = function() { - return isAlignedCenterValue + return selectionStylesSummary.isAlignedCenter() }; this.isAlignedRight = function() { - return isAlignedRightValue + return selectionStylesSummary.isAlignedRight() }; this.isAlignedJustified = function() { - return isAlignedJustifiedValue + return selectionStylesSummary.isAlignedJustified() }; function roundUp(step) { return step === ops.StepsTranslator.NEXT_STEP } + function getOwnProperty(obj, key) { + return obj.hasOwnProperty(key) ? obj[key] : undefined + } function applyParagraphDirectStyling(applyDirectStyling) { - var range = odtDocument.getCursor(inputMemberId).getSelectedRange(), paragraphs = odfUtils.getParagraphElements(range), formatting = odtDocument.getFormatting(); + var range = odtDocument.getCursor(inputMemberId).getSelectedRange(), paragraphs = odfUtils.getParagraphElements(range), formatting = odtDocument.getFormatting(), operations = [], derivedStyleNames = {}, defaultStyleName; paragraphs.forEach(function(paragraph) { - var paragraphStartPoint = odtDocument.convertDomPointToCursorStep(paragraph, 0, roundUp), paragraphStyleName = paragraph.getAttributeNS(odf.Namespaces.textns, "style-name"), newParagraphStyleName = objectNameGenerator.generateStyleName(), opAddStyle, opSetParagraphStyle, paragraphProperties; + var paragraphStartPoint = odtDocument.convertDomPointToCursorStep(paragraph, 0, roundUp), paragraphStyleName = paragraph.getAttributeNS(odf.Namespaces.textns, "style-name"), newParagraphStyleName, opAddStyle, opSetParagraphStyle, paragraphProperties; if(paragraphStyleName) { - paragraphProperties = formatting.createDerivedStyleObject(paragraphStyleName, "paragraph", {}) + newParagraphStyleName = getOwnProperty(derivedStyleNames, paragraphStyleName) + }else { + newParagraphStyleName = defaultStyleName + } + if(!newParagraphStyleName) { + newParagraphStyleName = objectNameGenerator.generateStyleName(); + if(paragraphStyleName) { + derivedStyleNames[paragraphStyleName] = newParagraphStyleName; + paragraphProperties = formatting.createDerivedStyleObject(paragraphStyleName, "paragraph", {}) + }else { + defaultStyleName = newParagraphStyleName; + paragraphProperties = {} + } + paragraphProperties = applyDirectStyling(paragraphProperties); + opAddStyle = new ops.OpAddStyle; + opAddStyle.init({memberid:inputMemberId, styleName:newParagraphStyleName.toString(), styleFamily:"paragraph", isAutomaticStyle:true, setProperties:paragraphProperties}); + operations.push(opAddStyle) } - paragraphProperties = applyDirectStyling(paragraphProperties || {}); - opAddStyle = new ops.OpAddStyle; - opAddStyle.init({memberid:inputMemberId, styleName:newParagraphStyleName, styleFamily:"paragraph", isAutomaticStyle:true, setProperties:paragraphProperties}); opSetParagraphStyle = new ops.OpSetParagraphStyle; - opSetParagraphStyle.init({memberid:inputMemberId, styleName:newParagraphStyleName, position:paragraphStartPoint}); - session.enqueue([opAddStyle, opSetParagraphStyle]) - }) + opSetParagraphStyle.init({memberid:inputMemberId, styleName:newParagraphStyleName.toString(), position:paragraphStartPoint}); + operations.push(opSetParagraphStyle) + }); + session.enqueue(operations) } function applySimpleParagraphDirectStyling(styleOverrides) { applyParagraphDirectStyling(function(paragraphStyle) { @@ -16565,7 +13387,13 @@ gui.DirectParagraphStyler = function DirectParagraphStyler(session, inputMemberI return true }; function modifyParagraphIndent(direction, paragraphStyle) { - var tabStopDistance = odtDocument.getFormatting().getDefaultTabStopDistance(), paragraphProperties = paragraphStyle["style:paragraph-properties"], indentValue = paragraphProperties && paragraphProperties["fo:margin-left"], indent = indentValue && odfUtils.parseLength(indentValue), newIndent; + var tabStopDistance = odtDocument.getFormatting().getDefaultTabStopDistance(), paragraphProperties = paragraphStyle["style:paragraph-properties"], indentValue, indent, newIndent; + if(paragraphProperties) { + indentValue = paragraphProperties["fo:margin-left"]; + if(indentValue) { + indent = odfUtils.parseLength(indentValue) + } + } if(indent && indent.unit === tabStopDistance.unit) { newIndent = indent.value + direction * tabStopDistance.value + indent.unit }else { @@ -16581,6 +13409,70 @@ gui.DirectParagraphStyler = function DirectParagraphStyler(session, inputMemberI applyParagraphDirectStyling(modifyParagraphIndent.bind(null, -1)); return true }; + function isSelectionAtTheEndOfLastParagraph(range, paragraphNode) { + var iterator = gui.SelectionMover.createPositionIterator(paragraphNode), rootConstrainedFilter = new core.PositionFilterChain; + rootConstrainedFilter.addFilter(odtDocument.getPositionFilter()); + rootConstrainedFilter.addFilter(odtDocument.createRootFilter(inputMemberId)); + iterator.setUnfilteredPosition((range.endContainer), range.endOffset); + while(iterator.nextPosition()) { + if(rootConstrainedFilter.acceptPosition(iterator) === FILTER_ACCEPT) { + return odtDocument.getParagraphElement(iterator.getCurrentNode()) !== paragraphNode + } + } + return true + } + function isTextStyleDifferentFromFirstParagraph(range, paragraphNode) { + var textNodes = getNodes(range), textStyle = odtDocument.getFormatting().getAppliedStyles(textNodes)[0], paragraphStyle = odtDocument.getFormatting().getAppliedStylesForElement(paragraphNode); + if(!textStyle || (textStyle["style:family"] !== "text" || !textStyle["style:text-properties"])) { + return false + } + if(!paragraphStyle || !paragraphStyle["style:text-properties"]) { + return true + } + textStyle = (textStyle["style:text-properties"]); + paragraphStyle = (paragraphStyle["style:text-properties"]); + return!Object.keys(textStyle).every(function(key) { + return textStyle[key] === paragraphStyle[key] + }) + } + this.createParagraphStyleOps = function(position) { + var cursor = odtDocument.getCursor(inputMemberId), range = cursor.getSelectedRange(), operations = [], op, startNode, endNode, paragraphNode, properties, parentStyleName, styleName; + if(cursor.hasForwardSelection()) { + startNode = cursor.getAnchorNode(); + endNode = cursor.getNode() + }else { + startNode = cursor.getNode(); + endNode = cursor.getAnchorNode() + } + paragraphNode = (odtDocument.getParagraphElement(endNode)); + runtime.assert(Boolean(paragraphNode), "DirectFormattingController: Cursor outside paragraph"); + if(!isSelectionAtTheEndOfLastParagraph(range, paragraphNode)) { + return operations + } + if(endNode !== startNode) { + paragraphNode = (odtDocument.getParagraphElement(startNode)) + } + if(!directCursorStyleProperties && !isTextStyleDifferentFromFirstParagraph(range, paragraphNode)) { + return operations + } + properties = selectionAppliedStyles[0]; + if(!properties) { + return operations + } + parentStyleName = paragraphNode.getAttributeNS(textns, "style-name"); + if(parentStyleName) { + properties = {"style:text-properties":properties["style:text-properties"]}; + properties = odtDocument.getFormatting().createDerivedStyleObject(parentStyleName, "paragraph", properties) + } + styleName = objectNameGenerator.generateStyleName(); + op = new ops.OpAddStyle; + op.init({memberid:inputMemberId, styleName:styleName, styleFamily:"paragraph", isAutomaticStyle:true, setProperties:properties}); + operations.push(op); + op = new ops.OpSetParagraphStyle; + op.init({memberid:inputMemberId, styleName:styleName, position:position}); + operations.push(op); + return operations + }; this.subscribe = function(eventid, cb) { eventNotifier.subscribe(eventid, cb) }; @@ -16588,270 +13480,352 @@ gui.DirectParagraphStyler = function DirectParagraphStyler(session, inputMemberI eventNotifier.unsubscribe(eventid, cb) }; this.destroy = function(callback) { - odtDocument.unsubscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); + odtDocument.unsubscribe(ops.Document.signalCursorAdded, onCursorEvent); + odtDocument.unsubscribe(ops.Document.signalCursorRemoved, onCursorEvent); + odtDocument.unsubscribe(ops.Document.signalCursorMoved, onCursorEvent); odtDocument.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified); odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); + odtDocument.unsubscribe(ops.OdtDocument.signalOperationEnd, clearCursorStyle); callback() }; + function emptyFunction() { + } function init() { - odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); - odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); - odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); + odtDocument.subscribe(ops.Document.signalCursorAdded, onCursorEvent); + odtDocument.subscribe(ops.Document.signalCursorRemoved, onCursorEvent); + odtDocument.subscribe(ops.Document.signalCursorMoved, onCursorEvent); odtDocument.subscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified); odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); - updatedCachedValues() + odtDocument.subscribe(ops.OdtDocument.signalOperationEnd, clearCursorStyle); + updateSelectionStylesInfo(); + if(!directParagraphStylingEnabled) { + self.alignParagraphCenter = emptyFunction; + self.alignParagraphJustified = emptyFunction; + self.alignParagraphLeft = emptyFunction; + self.alignParagraphRight = emptyFunction; + self.createParagraphStyleOps = function() { + return[] + }; + self.indent = emptyFunction; + self.outdent = emptyFunction + } } init() }; -gui.DirectParagraphStyler.paragraphStylingChanged = "paragraphStyling/changed"; +gui.DirectFormattingController.textStylingChanged = "textStyling/changed"; +gui.DirectFormattingController.paragraphStylingChanged = "paragraphStyling/changed"; (function() { - return gui.DirectParagraphStyler + return gui.DirectFormattingController })(); -/* - - 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/ -*/ -runtime.loadClass("core.EventNotifier"); -runtime.loadClass("core.Utils"); -runtime.loadClass("ops.OpApplyDirectStyling"); -runtime.loadClass("gui.StyleHelper"); -gui.DirectTextStyler = function DirectTextStyler(session, inputMemberId) { - var self = this, utils = new core.Utils, odtDocument = session.getOdtDocument(), styleHelper = new gui.StyleHelper(odtDocument.getFormatting()), eventNotifier = new core.EventNotifier([gui.DirectTextStyler.textStylingChanged]), directCursorStyleProperties, currentSelectionStyles = [], isBoldValue = false, isItalicValue = false, hasUnderlineValue = false, hasStrikeThroughValue = false, fontSizeValue, fontNameValue; - function get(obj, keys) { - var i = 0, key = keys[i]; - while(key && obj) { - obj = obj[key]; - i += 1; - key = keys[i] - } - return keys.length === i ? obj : undefined - } - function getCommonValue(objArray, keys) { - var value = get(objArray[0], keys); - return objArray.every(function(obj) { - return value === get(obj, keys) - }) ? value : undefined - } - function getAppliedStyles() { - var cursor = odtDocument.getCursor(inputMemberId), range = cursor && cursor.getSelectedRange(), selectionStyles = range && styleHelper.getAppliedStyles(range) || []; - if(selectionStyles[0] && directCursorStyleProperties) { - selectionStyles[0] = utils.mergeObjects(selectionStyles[0], (directCursorStyleProperties)) +gui.HyperlinkClickHandler = function HyperlinkClickHandler(getRootNode) { + var webodfns = "urn:webodf:names:helper", links = "links", inactive = "inactive", None = gui.HyperlinkClickHandler.Modifier.None, Ctrl = gui.HyperlinkClickHandler.Modifier.Ctrl, Meta = gui.HyperlinkClickHandler.Modifier.Meta, odfUtils = new odf.OdfUtils, xpath = xmldom.XPath, modifier = None; + function getHyperlinkElement(node) { + while(node !== null) { + if(odfUtils.isHyperlink(node)) { + return(node) + } + if(odfUtils.isParagraph(node)) { + break + } + node = node.parentNode } - return selectionStyles + return null } - function updatedCachedValues() { - var fontSize, diffMap; - currentSelectionStyles = getAppliedStyles(); - function noteChange(oldValue, newValue, id) { - if(oldValue !== newValue) { - if(diffMap === undefined) { - diffMap = {} - } - diffMap[id] = newValue + this.handleClick = function(e) { + var target = e.target || e.srcElement, modifierPressed, linkElement, url, rootNode, bookmarks; + if(e.ctrlKey) { + modifierPressed = Ctrl + }else { + if(e.metaKey) { + modifierPressed = Meta } - return newValue } - isBoldValue = noteChange(isBoldValue, currentSelectionStyles ? styleHelper.isBold(currentSelectionStyles) : false, "isBold"); - isItalicValue = noteChange(isItalicValue, currentSelectionStyles ? styleHelper.isItalic(currentSelectionStyles) : false, "isItalic"); - hasUnderlineValue = noteChange(hasUnderlineValue, currentSelectionStyles ? styleHelper.hasUnderline(currentSelectionStyles) : false, "hasUnderline"); - hasStrikeThroughValue = noteChange(hasStrikeThroughValue, currentSelectionStyles ? styleHelper.hasStrikeThrough(currentSelectionStyles) : false, "hasStrikeThrough"); - fontSize = currentSelectionStyles && getCommonValue(currentSelectionStyles, ["style:text-properties", "fo:font-size"]); - fontSizeValue = noteChange(fontSizeValue, fontSize && parseFloat(fontSize), "fontSize"); - fontNameValue = noteChange(fontNameValue, currentSelectionStyles && getCommonValue(currentSelectionStyles, ["style:text-properties", "style:font-name"]), "fontName"); - if(diffMap) { - eventNotifier.emit(gui.DirectTextStyler.textStylingChanged, diffMap) + if(modifier !== None && modifier !== modifierPressed) { + return } - } - function onCursorAdded(cursor) { - if(cursor.getMemberId() === inputMemberId) { - updatedCachedValues() + linkElement = getHyperlinkElement((target)); + if(!linkElement) { + return } - } - function onCursorRemoved(memberId) { - if(memberId === inputMemberId) { - updatedCachedValues() + url = odfUtils.getHyperlinkTarget(linkElement); + if(url === "") { + return } - } - function onCursorMoved(cursor) { - if(cursor.getMemberId() === inputMemberId) { - updatedCachedValues() + if(url[0] === "#") { + url = url.substring(1); + rootNode = (getRootNode()); + bookmarks = xpath.getODFElementsWithXPath(rootNode, "//text:bookmark-start[@text:name='" + url + "']", odf.Namespaces.lookupNamespaceURI); + if(bookmarks.length === 0) { + bookmarks = xpath.getODFElementsWithXPath(rootNode, "//text:bookmark[@text:name='" + url + "']", odf.Namespaces.lookupNamespaceURI) + } + if(bookmarks.length > 0) { + bookmarks[0].scrollIntoView(true) + } + }else { + runtime.getWindow().open(url) } - } - function onParagraphStyleModified() { - updatedCachedValues() - } - function onParagraphChanged(args) { - var cursor = odtDocument.getCursor(inputMemberId); - if(cursor && odtDocument.getParagraphElement(cursor.getNode()) === args.paragraphElement) { - updatedCachedValues() + if(e.preventDefault) { + e.preventDefault() + }else { + e.returnValue = false } + }; + function showPointerCursor() { + getRootNode().removeAttributeNS(webodfns, links) } - function toggle(predicate, toggleMethod) { - var cursor = odtDocument.getCursor(inputMemberId), appliedStyles; - if(!cursor) { - return false - } - appliedStyles = styleHelper.getAppliedStyles(cursor.getSelectedRange()); - toggleMethod(!predicate(appliedStyles)); - return true + this.showPointerCursor = showPointerCursor; + function showTextCursor() { + getRootNode().setAttributeNS(webodfns, links, inactive) } - function formatTextSelection(textProperties) { - var selection = odtDocument.getCursorSelection(inputMemberId), op, properties = {"style:text-properties":textProperties}; - if(selection.length !== 0) { - op = new ops.OpApplyDirectStyling; - op.init({memberid:inputMemberId, position:selection.position, length:selection.length, setProperties:properties}); - session.enqueue([op]) + this.showTextCursor = showTextCursor; + this.setModifier = function(value) { + modifier = value; + if(modifier !== None) { + showTextCursor() }else { - directCursorStyleProperties = utils.mergeObjects(directCursorStyleProperties || {}, properties); - updatedCachedValues() + showPointerCursor() } } - this.formatTextSelection = formatTextSelection; - function applyTextPropertyToSelection(propertyName, propertyValue) { - var textProperties = {}; - textProperties[propertyName] = propertyValue; - formatTextSelection(textProperties) +}; +gui.HyperlinkClickHandler.Modifier = {None:0, Ctrl:1, Meta:2}; +gui.HyperlinkController = function HyperlinkController(session, inputMemberId) { + var odfUtils = new odf.OdfUtils, odtDocument = session.getOdtDocument(); + function addHyperlink(hyperlink, insertionText) { + var selection = odtDocument.getCursorSelection(inputMemberId), op = new ops.OpApplyHyperlink, operations = []; + if(selection.length === 0 || insertionText) { + insertionText = insertionText || hyperlink; + op = new ops.OpInsertText; + op.init({memberid:inputMemberId, position:selection.position, text:insertionText}); + selection.length = insertionText.length; + operations.push(op) + } + op = new ops.OpApplyHyperlink; + op.init({memberid:inputMemberId, position:selection.position, length:selection.length, hyperlink:hyperlink}); + operations.push(op); + session.enqueue(operations) } - this.createCursorStyleOp = function(position, length) { - var styleOp = null; - if(directCursorStyleProperties) { - styleOp = new ops.OpApplyDirectStyling; - styleOp.init({memberid:inputMemberId, position:position, length:length, setProperties:directCursorStyleProperties}); - directCursorStyleProperties = null; - updatedCachedValues() + this.addHyperlink = addHyperlink; + function removeHyperlinks() { + var iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), selectedRange = odtDocument.getCursor(inputMemberId).getSelectedRange(), links = odfUtils.getHyperlinkElements(selectedRange), removeEntireLink = selectedRange.collapsed && links.length === 1, domRange = odtDocument.getDOMDocument().createRange(), operations = [], cursorRange, firstLink, lastLink, offset, op; + if(links.length === 0) { + return } - return styleOp - }; - function clearCursorStyle(op) { - var spec = op.spec(); - if(directCursorStyleProperties && spec.memberid === inputMemberId) { - if(spec.optype !== "SplitParagraph") { - directCursorStyleProperties = null; - updatedCachedValues() + links.forEach(function(link) { + domRange.selectNodeContents(link); + cursorRange = odtDocument.convertDomToCursorRange({anchorNode:(domRange.startContainer), anchorOffset:domRange.startOffset, focusNode:(domRange.endContainer), focusOffset:domRange.endOffset}); + op = new ops.OpRemoveHyperlink; + op.init({memberid:inputMemberId, position:cursorRange.position, length:cursorRange.length}); + operations.push(op) + }); + if(!removeEntireLink) { + firstLink = (links[0]); + if(selectedRange.comparePoint(firstLink, 0) === -1) { + domRange.setStart(firstLink, 0); + domRange.setEnd(selectedRange.startContainer, selectedRange.startOffset); + cursorRange = odtDocument.convertDomToCursorRange({anchorNode:(domRange.startContainer), anchorOffset:domRange.startOffset, focusNode:(domRange.endContainer), focusOffset:domRange.endOffset}); + if(cursorRange.length > 0) { + op = new ops.OpApplyHyperlink; + (op).init({memberid:inputMemberId, position:cursorRange.position, length:cursorRange.length, hyperlink:odfUtils.getHyperlinkTarget(firstLink)}); + operations.push(op) + } + } + lastLink = (links[links.length - 1]); + iterator.moveToEndOfNode(lastLink); + offset = iterator.unfilteredDomOffset(); + if(selectedRange.comparePoint(lastLink, offset) === 1) { + domRange.setStart(selectedRange.endContainer, selectedRange.endOffset); + domRange.setEnd(lastLink, offset); + cursorRange = odtDocument.convertDomToCursorRange({anchorNode:(domRange.startContainer), anchorOffset:domRange.startOffset, focusNode:(domRange.endContainer), focusOffset:domRange.endOffset}); + if(cursorRange.length > 0) { + op = new ops.OpApplyHyperlink; + (op).init({memberid:inputMemberId, position:cursorRange.position, length:cursorRange.length, hyperlink:odfUtils.getHyperlinkTarget(lastLink)}); + operations.push(op) + } } } + session.enqueue(operations); + domRange.detach() } - function setBold(checked) { - var value = checked ? "bold" : "normal"; - applyTextPropertyToSelection("fo:font-weight", value) - } - this.setBold = setBold; - function setItalic(checked) { - var value = checked ? "italic" : "normal"; - applyTextPropertyToSelection("fo:font-style", value) + this.removeHyperlinks = removeHyperlinks +}; +gui.EventManager = function EventManager(odtDocument) { + var window = (runtime.getWindow()), bindToDirectHandler = {"beforecut":true, "beforepaste":true}, bindToWindow = {"mousedown":true, "mouseup":true, "focus":true}, eventDelegates = {}, eventTrap, canvasElement = odtDocument.getCanvas().getElement(); + function EventDelegate() { + var self = this, recentEvents = []; + this.filters = []; + this.handlers = []; + this.handleEvent = function(e) { + if(recentEvents.indexOf(e) === -1) { + recentEvents.push(e); + if(self.filters.every(function(filter) { + return filter(e) + })) { + self.handlers.forEach(function(handler) { + handler(e) + }) + } + runtime.setTimeout(function() { + recentEvents.splice(recentEvents.indexOf(e), 1) + }, 0) + } + } } - this.setItalic = setItalic; - function setHasUnderline(checked) { - var value = checked ? "solid" : "none"; - applyTextPropertyToSelection("style:text-underline-style", value) + function WindowScrollState(window) { + var x = window.scrollX, y = window.scrollY; + this.restore = function() { + if(window.scrollX !== x || window.scrollY !== y) { + window.scrollTo(x, y) + } + } } - this.setHasUnderline = setHasUnderline; - function setHasStrikethrough(checked) { - var value = checked ? "solid" : "none"; - applyTextPropertyToSelection("style:text-line-through-style", value) + function ElementScrollState(element) { + var top = element.scrollTop, left = element.scrollLeft; + this.restore = function() { + if(element.scrollTop !== top || element.scrollLeft !== left) { + element.scrollTop = top; + element.scrollLeft = left + } + } } - this.setHasStrikethrough = setHasStrikethrough; - function setFontSize(value) { - applyTextPropertyToSelection("fo:font-size", value + "pt") + function listenEvent(eventTarget, eventType, eventHandler) { + var onVariant = "on" + eventType, bound = false; + if(eventTarget.attachEvent) { + eventTarget.attachEvent(onVariant, eventHandler); + bound = true + } + if(!bound && eventTarget.addEventListener) { + eventTarget.addEventListener(eventType, eventHandler, false); + bound = true + } + if((!bound || bindToDirectHandler[eventType]) && eventTarget.hasOwnProperty(onVariant)) { + eventTarget[onVariant] = eventHandler + } } - this.setFontSize = setFontSize; - function setFontName(value) { - applyTextPropertyToSelection("style:font-name", value) + function getDelegateForEvent(eventName, shouldCreate) { + var delegate = eventDelegates[eventName] || null; + if(!delegate && shouldCreate) { + delegate = eventDelegates[eventName] = new EventDelegate; + if(bindToWindow[eventName]) { + listenEvent(window, eventName, delegate.handleEvent) + } + listenEvent(eventTrap, eventName, delegate.handleEvent); + listenEvent(canvasElement, eventName, delegate.handleEvent) + } + return delegate } - this.setFontName = setFontName; - this.getAppliedStyles = function() { - return currentSelectionStyles + this.addFilter = function(eventName, filter) { + var delegate = getDelegateForEvent(eventName, true); + delegate.filters.push(filter) }; - this.toggleBold = toggle.bind(self, styleHelper.isBold, setBold); - this.toggleItalic = toggle.bind(self, styleHelper.isItalic, setItalic); - this.toggleUnderline = toggle.bind(self, styleHelper.hasUnderline, setHasUnderline); - this.toggleStrikethrough = toggle.bind(self, styleHelper.hasStrikeThrough, setHasStrikethrough); - this.isBold = function() { - return isBoldValue - }; - this.isItalic = function() { - return isItalicValue + this.removeFilter = function(eventName, filter) { + var delegate = getDelegateForEvent(eventName, true), index = delegate.filters.indexOf(filter); + if(index !== -1) { + delegate.filters.splice(index, 1) + } }; - this.hasUnderline = function() { - return hasUnderlineValue + this.subscribe = function(eventName, handler) { + var delegate = getDelegateForEvent(eventName, true); + delegate.handlers.push(handler) }; - this.hasStrikeThrough = function() { - return hasStrikeThroughValue + this.unsubscribe = function(eventName, handler) { + var delegate = getDelegateForEvent(eventName, false), handlerIndex = delegate && delegate.handlers.indexOf(handler); + if(delegate && handlerIndex !== -1) { + delegate.handlers.splice(handlerIndex, 1) + } }; - this.fontSize = function() { - return fontSizeValue + function hasFocus() { + return odtDocument.getDOMDocument().activeElement === eventTrap + } + this.hasFocus = hasFocus; + function findScrollableParents(element) { + var scrollParents = []; + while(element) { + if(element.scrollWidth > element.clientWidth || element.scrollHeight > element.clientHeight) { + scrollParents.push(new ElementScrollState(element)) + } + element = (element.parentNode) + } + scrollParents.push(new WindowScrollState(window)); + return scrollParents + } + this.focus = function() { + var scrollParents; + if(!hasFocus()) { + scrollParents = findScrollableParents(eventTrap); + eventTrap.focus(); + scrollParents.forEach(function(scrollParent) { + scrollParent.restore() + }) + } }; - this.fontName = function() { - return fontNameValue + this.getEventTrap = function() { + return eventTrap }; - this.subscribe = function(eventid, cb) { - eventNotifier.subscribe(eventid, cb) + this.blur = function() { + if(hasFocus()) { + eventTrap.blur() + } }; - this.unsubscribe = function(eventid, cb) { - eventNotifier.unsubscribe(eventid, cb) + this.destroy = function(callback) { + eventTrap.parentNode.removeChild(eventTrap); + callback() }; + function init() { + var sizerElement = odtDocument.getOdfCanvas().getSizer(), doc = sizerElement.ownerDocument; + runtime.assert(Boolean(window), "EventManager requires a window object to operate correctly"); + eventTrap = (doc.createElement("input")); + eventTrap.id = "eventTrap"; + eventTrap.setAttribute("tabindex", -1); + sizerElement.appendChild(eventTrap) + } + init() +}; +/* + + Copyright (C) 2014 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +gui.IOSSafariSupport = function(eventManager) { + var window = runtime.getWindow(), eventTrap = eventManager.getEventTrap(); + function suppressFocusScrollIfKeyboardOpen() { + if(window.innerHeight !== window.outerHeight) { + eventTrap.style.display = "none"; + runtime.requestAnimationFrame(function() { + eventTrap.style.display = "block" + }) + } + } this.destroy = function(callback) { - odtDocument.unsubscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); - odtDocument.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified); - odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); - odtDocument.unsubscribe(ops.OdtDocument.signalOperationExecuted, clearCursorStyle); + eventManager.unsubscribe("focus", suppressFocusScrollIfKeyboardOpen); + eventTrap.removeAttribute("autocapitalize"); callback() }; function init() { - odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); - odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); - odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); - odtDocument.subscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified); - odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); - odtDocument.subscribe(ops.OdtDocument.signalOperationExecuted, clearCursorStyle); - updatedCachedValues() + eventManager.subscribe("focus", suppressFocusScrollIfKeyboardOpen); + eventTrap.setAttribute("autocapitalize", "off") } init() }; -gui.DirectTextStyler.textStylingChanged = "textStyling/changed"; -(function() { - return gui.DirectTextStyler -})(); -runtime.loadClass("odf.Namespaces"); -runtime.loadClass("odf.ObjectNameGenerator"); -gui.ImageManager = function ImageManager(session, inputMemberId, objectNameGenerator) { +gui.ImageController = function ImageController(session, inputMemberId, objectNameGenerator) { var cmPerPixel = 0.0264583333333334, fileExtensionByMimetype = {"image/gif":".gif", "image/jpeg":".jpg", "image/png":".png"}, textns = odf.Namespaces.textns, odtDocument = session.getOdtDocument(), formatting = odtDocument.getFormatting(), paragraphStyleToPageContentSizeMap = {}; function createAddGraphicsStyleOp(name) { var op = new ops.OpAddStyle; @@ -16913,6 +13887,313 @@ gui.ImageManager = function ImageManager(session, inputMemberId, objectNameGener insertImageInternal(mimetype, content, newSize.width, newSize.height) } }; +gui.ImageSelector = function ImageSelector(odfCanvas) { + var svgns = odf.Namespaces.svgns, imageSelectorId = "imageSelector", selectorBorderWidth = 1, squareClassNames = ["topLeft", "topRight", "bottomRight", "bottomLeft", "topMiddle", "rightMiddle", "bottomMiddle", "leftMiddle"], document = odfCanvas.getElement().ownerDocument, hasSelection = false; + function createSelectorElement() { + var sizerElement = odfCanvas.getSizer(), selectorElement = (document.createElement("div")); + selectorElement.id = "imageSelector"; + selectorElement.style.borderWidth = selectorBorderWidth + "px"; + sizerElement.appendChild(selectorElement); + function createDiv(className) { + var squareElement = document.createElement("div"); + squareElement.className = className; + selectorElement.appendChild(squareElement) + } + squareClassNames.forEach(createDiv); + return selectorElement + } + function getPosition(element, referenceElement) { + var rect = element.getBoundingClientRect(), refRect = referenceElement.getBoundingClientRect(), zoomLevel = odfCanvas.getZoomLevel(); + return{left:(rect.left - refRect.left) / zoomLevel - selectorBorderWidth, top:(rect.top - refRect.top) / zoomLevel - selectorBorderWidth} + } + this.select = function(frameElement) { + var selectorElement = document.getElementById(imageSelectorId), position; + if(!selectorElement) { + selectorElement = createSelectorElement() + } + hasSelection = true; + position = getPosition(frameElement, (selectorElement.parentNode)); + selectorElement.style.display = "block"; + selectorElement.style.left = position.left + "px"; + selectorElement.style.top = position.top + "px"; + selectorElement.style.width = frameElement.getAttributeNS(svgns, "width"); + selectorElement.style.height = frameElement.getAttributeNS(svgns, "height") + }; + this.clearSelection = function() { + var selectorElement; + if(hasSelection) { + selectorElement = document.getElementById(imageSelectorId); + if(selectorElement) { + selectorElement.style.display = "none" + } + } + hasSelection = false + }; + this.isSelectorElement = function(node) { + var selectorElement = document.getElementById(imageSelectorId); + if(!selectorElement) { + return false + } + return node === selectorElement || node.parentNode === selectorElement + } +}; +(function() { + function DetectSafariCompositionError(eventManager) { + var lastCompositionValue, suppressedKeyPress = false; + function suppressIncorrectKeyPress(e) { + suppressedKeyPress = e.which && String.fromCharCode(e.which) === lastCompositionValue; + lastCompositionValue = undefined; + return suppressedKeyPress === false + } + function clearSuppression() { + suppressedKeyPress = false + } + function trapComposedValue(e) { + lastCompositionValue = e.data; + suppressedKeyPress = false + } + function init() { + eventManager.subscribe("textInput", clearSuppression); + eventManager.subscribe("compositionend", trapComposedValue); + eventManager.addFilter("keypress", suppressIncorrectKeyPress) + } + this.destroy = function(callback) { + eventManager.unsubscribe("textInput", clearSuppression); + eventManager.unsubscribe("compositionend", trapComposedValue); + eventManager.removeFilter("keypress", suppressIncorrectKeyPress); + callback() + }; + init() + } + gui.InputMethodEditor = function InputMethodEditor(inputMemberId, eventManager) { + var cursorns = "urn:webodf:names:cursor", localCursor = null, eventTrap = eventManager.getEventTrap(), doc = (eventTrap.ownerDocument), compositionElement, async = new core.Async, FAKE_CONTENT = "b", processUpdates, pendingEvent = false, pendingData = "", events = new core.EventNotifier([gui.InputMethodEditor.signalCompositionStart, gui.InputMethodEditor.signalCompositionEnd]), lastCompositionData, filters = [], cleanup, isEditable = false; + this.subscribe = events.subscribe; + this.unsubscribe = events.unsubscribe; + function setCursorComposing(state) { + if(localCursor) { + if(state) { + localCursor.getNode().setAttributeNS(cursorns, "composing", "true") + }else { + localCursor.getNode().removeAttributeNS(cursorns, "composing"); + compositionElement.textContent = "" + } + } + } + function flushEvent() { + if(pendingEvent) { + pendingEvent = false; + setCursorComposing(false); + events.emit(gui.InputMethodEditor.signalCompositionEnd, {data:pendingData}); + pendingData = "" + } + } + function addCompositionData(data) { + pendingEvent = true; + pendingData += data; + processUpdates.trigger() + } + function resetWindowSelection() { + flushEvent(); + if(localCursor && localCursor.getSelectedRange().collapsed) { + eventTrap.value = "" + }else { + eventTrap.value = FAKE_CONTENT + } + eventTrap.setSelectionRange(0, eventTrap.value.length) + } + function compositionStart() { + lastCompositionData = undefined; + processUpdates.cancel(); + setCursorComposing(true); + if(!pendingEvent) { + events.emit(gui.InputMethodEditor.signalCompositionStart, {data:""}) + } + } + function compositionEnd(e) { + lastCompositionData = e.data; + addCompositionData(e.data) + } + function textInput(e) { + if(e.data !== lastCompositionData) { + addCompositionData(e.data) + } + lastCompositionData = undefined + } + function synchronizeCompositionText() { + compositionElement.textContent = eventTrap.value + } + this.registerCursor = function(cursor) { + if(cursor.getMemberId() === inputMemberId) { + localCursor = cursor; + localCursor.getNode().appendChild(compositionElement); + eventManager.subscribe("input", synchronizeCompositionText); + eventManager.subscribe("compositionupdate", synchronizeCompositionText) + } + }; + this.removeCursor = function(memberid) { + if(localCursor && memberid === inputMemberId) { + localCursor.getNode().removeChild(compositionElement); + eventManager.unsubscribe("input", synchronizeCompositionText); + eventManager.unsubscribe("compositionupdate", synchronizeCompositionText); + localCursor = null + } + }; + function suppressFocus() { + eventManager.blur(); + eventTrap.setAttribute("disabled", true) + } + function synchronizeEventStatus() { + var hasFocus = eventManager.hasFocus(); + if(hasFocus) { + eventManager.blur() + } + if(isEditable) { + eventTrap.removeAttribute("disabled") + }else { + eventTrap.setAttribute("disabled", true) + } + if(hasFocus) { + eventManager.focus() + } + } + this.setEditing = function(editable) { + isEditable = editable; + synchronizeEventStatus() + }; + this.destroy = function(callback) { + eventManager.unsubscribe("compositionstart", compositionStart); + eventManager.unsubscribe("compositionend", compositionEnd); + eventManager.unsubscribe("textInput", textInput); + eventManager.unsubscribe("keypress", flushEvent); + eventManager.unsubscribe("mousedown", suppressFocus); + eventManager.unsubscribe("mouseup", synchronizeEventStatus); + eventManager.unsubscribe("focus", resetWindowSelection); + async.destroyAll(cleanup, callback) + }; + function init() { + eventManager.subscribe("compositionstart", compositionStart); + eventManager.subscribe("compositionend", compositionEnd); + eventManager.subscribe("textInput", textInput); + eventManager.subscribe("keypress", flushEvent); + eventManager.subscribe("mousedown", suppressFocus); + eventManager.subscribe("mouseup", synchronizeEventStatus); + eventManager.subscribe("focus", resetWindowSelection); + filters.push(new DetectSafariCompositionError(eventManager)); + function getDestroy(filter) { + return filter.destroy + } + cleanup = filters.map(getDestroy); + compositionElement = doc.createElement("span"); + compositionElement.setAttribute("id", "composer"); + processUpdates = new core.ScheduledTask(resetWindowSelection, 1); + cleanup.push(processUpdates.destroy) + } + init() + }; + gui.InputMethodEditor.signalCompositionStart = "input/compositionstart"; + gui.InputMethodEditor.signalCompositionEnd = "input/compositionend"; + return gui.InputMethodEditor +})(); +/* + + Copyright (C) 2012-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/ +*/ +gui.KeyboardHandler = function KeyboardHandler() { + var modifier = gui.KeyboardHandler.Modifier, defaultBinding = null, bindings = {}; + function getModifiers(e) { + var modifiers = modifier.None; + if(e.metaKey) { + modifiers |= modifier.Meta + } + if(e.ctrlKey) { + modifiers |= modifier.Ctrl + } + if(e.altKey) { + modifiers |= modifier.Alt + } + if(e.shiftKey) { + modifiers |= modifier.Shift + } + return modifiers + } + function getKeyCombo(keyCode, modifiers) { + if(!modifiers) { + modifiers = modifier.None + } + return keyCode + ":" + modifiers + } + this.setDefault = function(callback) { + defaultBinding = callback + }; + this.bind = function(keyCode, modifiers, callback, overwrite) { + var keyCombo = getKeyCombo(keyCode, modifiers); + runtime.assert(overwrite || bindings.hasOwnProperty(keyCombo) === false, "tried to overwrite the callback handler of key combo: " + keyCombo); + bindings[keyCombo] = callback + }; + this.unbind = function(keyCode, modifiers) { + var keyCombo = getKeyCombo(keyCode, modifiers); + delete bindings[keyCombo] + }; + this.reset = function() { + defaultBinding = null; + bindings = {} + }; + this.handleEvent = function(e) { + var keyCombo = getKeyCombo(e.keyCode, getModifiers(e)), callback = bindings[keyCombo], handled = false; + if(callback) { + handled = callback() + }else { + if(defaultBinding !== null) { + handled = defaultBinding(e) + } + } + if(handled) { + if(e.preventDefault) { + e.preventDefault() + }else { + e.returnValue = false + } + } + } +}; +gui.KeyboardHandler.Modifier = {None:0, Meta:1, Ctrl:2, Alt:4, CtrlAlt:6, Shift:8, MetaShift:9, CtrlShift:10, AltShift:12}; +gui.KeyboardHandler.KeyCode = {Backspace:8, Tab:9, Clear:12, Enter:13, Ctrl:17, End:35, Home:36, Left:37, Up:38, Right:39, Down:40, Delete:46, A:65, B:66, C:67, D:68, E:69, F:70, G:71, H:72, I:73, J:74, K:75, L:76, M:77, N:78, O:79, P:80, Q:81, R:82, S:83, T:84, U:85, V:86, W:87, X:88, Y:89, Z:90, LeftMeta:91, MetaInMozilla:224}; +(function() { + return gui.KeyboardHandler +})(); /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -16950,8 +14231,505 @@ gui.ImageManager = function ImageManager(session, inputMemberId, objectNameGener @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.PositionFilter"); -gui.TextManipulator = function TextManipulator(session, inputMemberId, directStyleOp) { +gui.PlainTextPasteboard = function PlainTextPasteboard(odtDocument, inputMemberId) { + function createOp(op, data) { + op.init(data); + return op + } + this.createPasteOps = function(data) { + var originalCursorPosition = odtDocument.getCursorPosition(inputMemberId), cursorPosition = originalCursorPosition, operations = [], paragraphs; + paragraphs = data.replace(/\r/g, "").split("\n"); + paragraphs.forEach(function(text) { + operations.push(createOp(new ops.OpSplitParagraph, {memberid:inputMemberId, position:cursorPosition, moveCursor:true})); + cursorPosition += 1; + operations.push(createOp(new ops.OpInsertText, {memberid:inputMemberId, position:cursorPosition, text:text, moveCursor:true})); + cursorPosition += text.length + }); + operations.push(createOp(new ops.OpRemoveText, {memberid:inputMemberId, position:originalCursorPosition, length:1})); + return operations + } +}; +/* + + Copyright (C) 2014 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/ +*/ +odf.WordBoundaryFilter = function WordBoundaryFilter(odtDocument, includeWhitespace) { + var TEXT_NODE = Node.TEXT_NODE, ELEMENT_NODE = Node.ELEMENT_NODE, odfUtils = new odf.OdfUtils, punctuation = /[!-#%-*,-\/:-;?-@\[-\]_{}\u00a1\u00ab\u00b7\u00bb\u00bf;\u00b7\u055a-\u055f\u0589-\u058a\u05be\u05c0\u05c3\u05c6\u05f3-\u05f4\u0609-\u060a\u060c-\u060d\u061b\u061e-\u061f\u066a-\u066d\u06d4\u0700-\u070d\u07f7-\u07f9\u0964-\u0965\u0970\u0df4\u0e4f\u0e5a-\u0e5b\u0f04-\u0f12\u0f3a-\u0f3d\u0f85\u0fd0-\u0fd4\u104a-\u104f\u10fb\u1361-\u1368\u166d-\u166e\u169b-\u169c\u16eb-\u16ed\u1735-\u1736\u17d4-\u17d6\u17d8-\u17da\u1800-\u180a\u1944-\u1945\u19de-\u19df\u1a1e-\u1a1f\u1b5a-\u1b60\u1c3b-\u1c3f\u1c7e-\u1c7f\u2000-\u206e\u207d-\u207e\u208d-\u208e\u3008-\u3009\u2768-\u2775\u27c5-\u27c6\u27e6-\u27ef\u2983-\u2998\u29d8-\u29db\u29fc-\u29fd\u2cf9-\u2cfc\u2cfe-\u2cff\u2e00-\u2e7e\u3000-\u303f\u30a0\u30fb\ua60d-\ua60f\ua673\ua67e\ua874-\ua877\ua8ce-\ua8cf\ua92e-\ua92f\ua95f\uaa5c-\uaa5f\ufd3e-\ufd3f\ufe10-\ufe19\ufe30-\ufe52\ufe54-\ufe61\ufe63\ufe68\ufe6a-\ufe6b\uff01-\uff03\uff05-\uff0a\uff0c-\uff0f\uff1a-\uff1b\uff1f-\uff20\uff3b-\uff3d\uff3f\uff5b\uff5d\uff5f-\uff65]|\ud800[\udd00-\udd01\udf9f\udfd0]|\ud802[\udd1f\udd3f\ude50-\ude58]|\ud809[\udc00-\udc7e]/, + spacing = /\s/, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT, TRAILING = odf.WordBoundaryFilter.IncludeWhitespace.TRAILING, LEADING = odf.WordBoundaryFilter.IncludeWhitespace.LEADING, NeighborType = {NO_NEIGHBOUR:0, SPACE_CHAR:1, PUNCTUATION_CHAR:2, WORD_CHAR:3, OTHER:4}; + function findHigherNeighborNode(node, direction, nodeFilter) { + var neighboringNode = null, rootNode = odtDocument.getRootNode(), unfilteredCandidate; + while(node !== rootNode && (node !== null && neighboringNode === null)) { + unfilteredCandidate = direction < 0 ? node.previousSibling : node.nextSibling; + if(nodeFilter(unfilteredCandidate) === NodeFilter.FILTER_ACCEPT) { + neighboringNode = unfilteredCandidate + } + node = node.parentNode + } + return neighboringNode + } + function typeOfNeighbor(node, getOffset) { + var neighboringChar; + if(node === null) { + return NeighborType.NO_NEIGHBOUR + } + if(odfUtils.isCharacterElement(node)) { + return NeighborType.SPACE_CHAR + } + if(node.nodeType === TEXT_NODE || (odfUtils.isTextSpan(node) || odfUtils.isHyperlink(node))) { + neighboringChar = node.textContent.charAt(getOffset()); + if(spacing.test(neighboringChar)) { + return NeighborType.SPACE_CHAR + } + if(punctuation.test(neighboringChar)) { + return NeighborType.PUNCTUATION_CHAR + } + return NeighborType.WORD_CHAR + } + return NeighborType.OTHER + } + this.acceptPosition = function(iterator) { + var container = iterator.container(), leftNode = iterator.leftNode(), rightNode = iterator.rightNode(), getRightCharOffset = iterator.unfilteredDomOffset, getLeftCharOffset = function() { + return iterator.unfilteredDomOffset() - 1 + }, leftNeighborType, rightNeighborType; + if(container.nodeType === ELEMENT_NODE) { + if(rightNode === null) { + rightNode = findHigherNeighborNode(container, 1, iterator.getNodeFilter()) + } + if(leftNode === null) { + leftNode = findHigherNeighborNode(container, -1, iterator.getNodeFilter()) + } + } + if(container !== rightNode) { + getRightCharOffset = function() { + return 0 + } + } + if(container !== leftNode && leftNode !== null) { + getLeftCharOffset = function() { + return leftNode.textContent.length - 1 + } + } + leftNeighborType = typeOfNeighbor(leftNode, getLeftCharOffset); + rightNeighborType = typeOfNeighbor(rightNode, getRightCharOffset); + if(leftNeighborType === NeighborType.WORD_CHAR && rightNeighborType === NeighborType.WORD_CHAR || (leftNeighborType === NeighborType.PUNCTUATION_CHAR && rightNeighborType === NeighborType.PUNCTUATION_CHAR || (includeWhitespace === TRAILING && (leftNeighborType !== NeighborType.NO_NEIGHBOUR && rightNeighborType === NeighborType.SPACE_CHAR) || includeWhitespace === LEADING && (leftNeighborType === NeighborType.SPACE_CHAR && rightNeighborType !== NeighborType.NO_NEIGHBOUR)))) { + return FILTER_REJECT + } + return FILTER_ACCEPT + } +}; +odf.WordBoundaryFilter.IncludeWhitespace = {None:0, TRAILING:1, LEADING:2}; +(function() { + return odf.WordBoundaryFilter +})(); +gui.SelectionController = function SelectionController(session, inputMemberId) { + var odtDocument = session.getOdtDocument(), domUtils = new core.DomUtils, odfUtils = new odf.OdfUtils, baseFilter = odtDocument.getPositionFilter(), keyboardMovementsFilter = new core.PositionFilterChain, rootFilter = odtDocument.createRootFilter(inputMemberId), TRAILING_SPACE = odf.WordBoundaryFilter.IncludeWhitespace.TRAILING, LEADING_SPACE = odf.WordBoundaryFilter.IncludeWhitespace.LEADING; + function createKeyboardStepIterator() { + var cursor = odtDocument.getCursor(inputMemberId), node = cursor.getNode(); + return odtDocument.createStepIterator(node, 0, [baseFilter, rootFilter], odtDocument.getRootElement(node)) + } + function createWordBoundaryStepIterator(node, offset, includeWhitespace) { + var wordBoundaryFilter = new odf.WordBoundaryFilter(odtDocument, includeWhitespace); + return odtDocument.createStepIterator(node, offset, [baseFilter, rootFilter, wordBoundaryFilter], odtDocument.getRootElement(node)) + } + function constrain(lookup) { + return function(originalNode) { + var originalContainer = lookup(originalNode); + return function(step, node) { + return lookup(node) === originalContainer + } + } + } + function selectionToRange(selection) { + var hasForwardSelection = domUtils.comparePoints((selection.anchorNode), selection.anchorOffset, (selection.focusNode), selection.focusOffset) >= 0, range = selection.focusNode.ownerDocument.createRange(); + if(hasForwardSelection) { + range.setStart(selection.anchorNode, selection.anchorOffset); + range.setEnd(selection.focusNode, selection.focusOffset) + }else { + range.setStart(selection.focusNode, selection.focusOffset); + range.setEnd(selection.anchorNode, selection.anchorOffset) + } + return{range:range, hasForwardSelection:hasForwardSelection} + } + this.selectionToRange = selectionToRange; + function rangeToSelection(range, hasForwardSelection) { + if(hasForwardSelection) { + return{anchorNode:(range.startContainer), anchorOffset:range.startOffset, focusNode:(range.endContainer), focusOffset:range.endOffset} + } + return{anchorNode:(range.endContainer), anchorOffset:range.endOffset, focusNode:(range.startContainer), focusOffset:range.startOffset} + } + this.rangeToSelection = rangeToSelection; + function createOpMoveCursor(position, length, selectionType) { + var op = new ops.OpMoveCursor; + op.init({memberid:inputMemberId, position:position, length:length || 0, selectionType:selectionType}); + return op + } + function selectImage(frameNode) { + var frameRoot = odtDocument.getRootElement(frameNode), frameRootFilter = odtDocument.createRootFilter(frameRoot), stepIterator = odtDocument.createStepIterator(frameNode, 0, [frameRootFilter, odtDocument.getPositionFilter()], frameRoot), anchorNode, anchorOffset, newSelection, op; + if(!stepIterator.roundToPreviousStep()) { + runtime.assert(false, "No walkable position before frame") + } + anchorNode = stepIterator.container(); + anchorOffset = stepIterator.offset(); + stepIterator.setPosition(frameNode, frameNode.childNodes.length); + if(!stepIterator.roundToNextStep()) { + runtime.assert(false, "No walkable position after frame") + } + newSelection = odtDocument.convertDomToCursorRange({anchorNode:anchorNode, anchorOffset:anchorOffset, focusNode:stepIterator.container(), focusOffset:stepIterator.offset()}); + op = createOpMoveCursor(newSelection.position, newSelection.length, ops.OdtCursor.RegionSelection); + session.enqueue([op]) + } + this.selectImage = selectImage; + function expandToWordBoundaries(range) { + var stepIterator; + stepIterator = createWordBoundaryStepIterator((range.startContainer), range.startOffset, TRAILING_SPACE); + if(stepIterator.roundToPreviousStep()) { + range.setStart(stepIterator.container(), stepIterator.offset()) + } + stepIterator = createWordBoundaryStepIterator((range.endContainer), range.endOffset, LEADING_SPACE); + if(stepIterator.roundToNextStep()) { + range.setEnd(stepIterator.container(), stepIterator.offset()) + } + } + this.expandToWordBoundaries = expandToWordBoundaries; + function expandToParagraphBoundaries(range) { + var paragraphs = odfUtils.getParagraphElements(range), startParagraph = paragraphs[0], endParagraph = paragraphs[paragraphs.length - 1]; + if(startParagraph) { + range.setStart(startParagraph, 0) + } + if(endParagraph) { + if(odfUtils.isParagraph(range.endContainer) && range.endOffset === 0) { + range.setEndBefore(endParagraph) + }else { + range.setEnd(endParagraph, endParagraph.childNodes.length) + } + } + } + this.expandToParagraphBoundaries = expandToParagraphBoundaries; + function selectRange(range, hasForwardSelection, clickCount) { + var canvasElement = odtDocument.getOdfCanvas().getElement(), validSelection, startInsideCanvas, endInsideCanvas, existingSelection, newSelection, op; + startInsideCanvas = domUtils.containsNode(canvasElement, range.startContainer); + endInsideCanvas = domUtils.containsNode(canvasElement, range.endContainer); + if(!startInsideCanvas && !endInsideCanvas) { + return + } + if(startInsideCanvas && endInsideCanvas) { + if(clickCount === 2) { + expandToWordBoundaries(range) + }else { + if(clickCount >= 3) { + expandToParagraphBoundaries(range) + } + } + } + validSelection = rangeToSelection(range, hasForwardSelection); + newSelection = odtDocument.convertDomToCursorRange(validSelection, constrain(odfUtils.getParagraphElement)); + existingSelection = odtDocument.getCursorSelection(inputMemberId); + if(newSelection.position !== existingSelection.position || newSelection.length !== existingSelection.length) { + op = createOpMoveCursor(newSelection.position, newSelection.length, ops.OdtCursor.RangeSelection); + session.enqueue([op]) + } + } + this.selectRange = selectRange; + function extendCursorByAdjustment(lengthAdjust) { + var selection = odtDocument.getCursorSelection(inputMemberId), stepCounter = odtDocument.getCursor(inputMemberId).getStepCounter(), newLength; + if(lengthAdjust !== 0) { + if(lengthAdjust > 0) { + lengthAdjust = stepCounter.convertForwardStepsBetweenFilters(lengthAdjust, keyboardMovementsFilter, baseFilter) + }else { + lengthAdjust = -stepCounter.convertBackwardStepsBetweenFilters(-lengthAdjust, keyboardMovementsFilter, baseFilter) + } + newLength = selection.length + lengthAdjust; + session.enqueue([createOpMoveCursor(selection.position, newLength)]) + } + } + function extendSelection(advanceIterator) { + var stepIterator = createKeyboardStepIterator(), anchorNode = odtDocument.getCursor(inputMemberId).getAnchorNode(), newSelection; + if(advanceIterator(stepIterator)) { + newSelection = odtDocument.convertDomToCursorRange({anchorNode:anchorNode, anchorOffset:0, focusNode:stepIterator.container(), focusOffset:stepIterator.offset()}); + session.enqueue([createOpMoveCursor(newSelection.position, newSelection.length)]) + } + } + function moveCursorByAdjustment(positionAdjust) { + var position = odtDocument.getCursorPosition(inputMemberId), stepCounter = odtDocument.getCursor(inputMemberId).getStepCounter(); + if(positionAdjust !== 0) { + positionAdjust = positionAdjust > 0 ? stepCounter.convertForwardStepsBetweenFilters(positionAdjust, keyboardMovementsFilter, baseFilter) : -stepCounter.convertBackwardStepsBetweenFilters(-positionAdjust, keyboardMovementsFilter, baseFilter); + position = position + positionAdjust; + session.enqueue([createOpMoveCursor(position, 0)]) + } + } + function moveCursor(advanceIterator) { + var stepIterator = createKeyboardStepIterator(), position; + if(advanceIterator(stepIterator)) { + position = odtDocument.convertDomPointToCursorStep(stepIterator.container(), stepIterator.offset()); + session.enqueue([createOpMoveCursor(position, 0)]) + } + } + function moveCursorToLeft() { + moveCursor(function(iterator) { + return iterator.previousStep() + }); + return true + } + this.moveCursorToLeft = moveCursorToLeft; + function moveCursorToRight() { + moveCursor(function(iterator) { + return iterator.nextStep() + }); + return true + } + this.moveCursorToRight = moveCursorToRight; + function extendSelectionToLeft() { + extendSelection(function(iterator) { + return iterator.previousStep() + }); + return true + } + this.extendSelectionToLeft = extendSelectionToLeft; + function extendSelectionToRight() { + extendSelection(function(iterator) { + return iterator.nextStep() + }); + return true + } + this.extendSelectionToRight = extendSelectionToRight; + function moveCursorByLine(direction, extend) { + var paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), steps; + runtime.assert(Boolean(paragraphNode), "SelectionController: Cursor outside paragraph"); + steps = odtDocument.getCursor(inputMemberId).getStepCounter().countLinesSteps(direction, keyboardMovementsFilter); + if(extend) { + extendCursorByAdjustment(steps) + }else { + moveCursorByAdjustment(steps) + } + } + function moveCursorUp() { + moveCursorByLine(-1, false); + return true + } + this.moveCursorUp = moveCursorUp; + function moveCursorDown() { + moveCursorByLine(1, false); + return true + } + this.moveCursorDown = moveCursorDown; + function extendSelectionUp() { + moveCursorByLine(-1, true); + return true + } + this.extendSelectionUp = extendSelectionUp; + function extendSelectionDown() { + moveCursorByLine(1, true); + return true + } + this.extendSelectionDown = extendSelectionDown; + function moveCursorToLineBoundary(direction, extend) { + var steps = odtDocument.getCursor(inputMemberId).getStepCounter().countStepsToLineBoundary(direction, keyboardMovementsFilter); + if(extend) { + extendCursorByAdjustment(steps) + }else { + moveCursorByAdjustment(steps) + } + } + function moveCursorByWord(direction, extend) { + var cursor = odtDocument.getCursor(inputMemberId), newSelection = rangeToSelection(cursor.getSelectedRange(), cursor.hasForwardSelection()), newCursorSelection, selectionUpdated, stepIterator = createWordBoundaryStepIterator(newSelection.focusNode, newSelection.focusOffset, TRAILING_SPACE); + if(direction >= 0) { + selectionUpdated = stepIterator.nextStep() + }else { + selectionUpdated = stepIterator.previousStep() + } + if(selectionUpdated) { + newSelection.focusNode = stepIterator.container(); + newSelection.focusOffset = stepIterator.offset(); + if(!extend) { + newSelection.anchorNode = newSelection.focusNode; + newSelection.anchorOffset = newSelection.focusOffset + } + newCursorSelection = odtDocument.convertDomToCursorRange(newSelection); + session.enqueue([createOpMoveCursor(newCursorSelection.position, newCursorSelection.length)]) + } + } + function moveCursorBeforeWord() { + moveCursorByWord(-1, false); + return true + } + this.moveCursorBeforeWord = moveCursorBeforeWord; + function moveCursorPastWord() { + moveCursorByWord(1, false); + return true + } + this.moveCursorPastWord = moveCursorPastWord; + function extendSelectionBeforeWord() { + moveCursorByWord(-1, true); + return true + } + this.extendSelectionBeforeWord = extendSelectionBeforeWord; + function extendSelectionPastWord() { + moveCursorByWord(1, true); + return true + } + this.extendSelectionPastWord = extendSelectionPastWord; + function moveCursorToLineStart() { + moveCursorToLineBoundary(-1, false); + return true + } + this.moveCursorToLineStart = moveCursorToLineStart; + function moveCursorToLineEnd() { + moveCursorToLineBoundary(1, false); + return true + } + this.moveCursorToLineEnd = moveCursorToLineEnd; + function extendSelectionToLineStart() { + moveCursorToLineBoundary(-1, true); + return true + } + this.extendSelectionToLineStart = extendSelectionToLineStart; + function extendSelectionToLineEnd() { + moveCursorToLineBoundary(1, true); + return true + } + this.extendSelectionToLineEnd = extendSelectionToLineEnd; + function extendCursorToNodeBoundary(direction, getContainmentNode) { + var cursor = odtDocument.getCursor(inputMemberId), node = getContainmentNode(cursor.getNode()), selection = rangeToSelection(cursor.getSelectedRange(), cursor.hasForwardSelection()), newCursorSelection; + runtime.assert(Boolean(node), "SelectionController: Cursor outside root"); + if(direction < 0) { + selection.focusNode = (node); + selection.focusOffset = 0 + }else { + selection.focusNode = (node); + selection.focusOffset = node.childNodes.length + } + newCursorSelection = odtDocument.convertDomToCursorRange(selection, constrain(getContainmentNode)); + session.enqueue([createOpMoveCursor(newCursorSelection.position, newCursorSelection.length)]) + } + function extendSelectionToParagraphStart() { + extendCursorToNodeBoundary(-1, odtDocument.getParagraphElement); + return true + } + this.extendSelectionToParagraphStart = extendSelectionToParagraphStart; + function extendSelectionToParagraphEnd() { + extendCursorToNodeBoundary(1, odtDocument.getParagraphElement); + return true + } + this.extendSelectionToParagraphEnd = extendSelectionToParagraphEnd; + function moveCursorToRootBoundary(direction) { + var cursor = odtDocument.getCursor(inputMemberId), root = odtDocument.getRootElement(cursor.getNode()), newPosition; + runtime.assert(Boolean(root), "SelectionController: Cursor outside root"); + if(direction < 0) { + newPosition = odtDocument.convertDomPointToCursorStep(root, 0, function(step) { + return step === ops.StepsTranslator.NEXT_STEP + }) + }else { + newPosition = odtDocument.convertDomPointToCursorStep(root, root.childNodes.length) + } + session.enqueue([createOpMoveCursor(newPosition, 0)]); + return true + } + function moveCursorToDocumentStart() { + moveCursorToRootBoundary(-1); + return true + } + this.moveCursorToDocumentStart = moveCursorToDocumentStart; + function moveCursorToDocumentEnd() { + moveCursorToRootBoundary(1); + return true + } + this.moveCursorToDocumentEnd = moveCursorToDocumentEnd; + function extendSelectionToDocumentStart() { + extendCursorToNodeBoundary(-1, odtDocument.getRootElement); + return true + } + this.extendSelectionToDocumentStart = extendSelectionToDocumentStart; + function extendSelectionToDocumentEnd() { + extendCursorToNodeBoundary(1, odtDocument.getRootElement); + return true + } + this.extendSelectionToDocumentEnd = extendSelectionToDocumentEnd; + function extendSelectionToEntireDocument() { + var cursor = odtDocument.getCursor(inputMemberId), root = odtDocument.getRootElement(cursor.getNode()), newSelection, newCursorSelection; + runtime.assert(Boolean(root), "SelectionController: Cursor outside root"); + newSelection = {anchorNode:root, anchorOffset:0, focusNode:root, focusOffset:root.childNodes.length}; + newCursorSelection = odtDocument.convertDomToCursorRange(newSelection, constrain(odtDocument.getRootElement)); + session.enqueue([createOpMoveCursor(newCursorSelection.position, newCursorSelection.length)]); + return true + } + this.extendSelectionToEntireDocument = extendSelectionToEntireDocument; + function init() { + keyboardMovementsFilter.addFilter(baseFilter); + keyboardMovementsFilter.addFilter(odtDocument.createRootFilter(inputMemberId)) + } + init() +}; +/* + + 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/ +*/ +gui.TextController = function TextController(session, inputMemberId, directStyleOp, paragraphStyleOps) { var odtDocument = session.getOdtDocument(), FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT; function createOpRemoveSelection(selection) { var op = new ops.OpRemoveText; @@ -16966,7 +14744,7 @@ gui.TextManipulator = function TextManipulator(session, inputMemberId, directSty return selection } this.enqueueParagraphSplittingOps = function() { - var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op, operations = []; + var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op, operations = [], styleOps; if(selection.length > 0) { op = createOpRemoveSelection(selection); operations.push(op) @@ -16974,13 +14752,17 @@ gui.TextManipulator = function TextManipulator(session, inputMemberId, directSty op = new ops.OpSplitParagraph; op.init({memberid:inputMemberId, position:selection.position, moveCursor:true}); operations.push(op); + if(paragraphStyleOps) { + styleOps = paragraphStyleOps(selection.position + 1); + operations = operations.concat(styleOps) + } session.enqueue(operations); return true }; function hasPositionInDirection(cursorNode, forward) { var rootConstrainedFilter = new core.PositionFilterChain, iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootElement(cursorNode)), nextPosition = (forward ? iterator.nextPosition : iterator.previousPosition); - rootConstrainedFilter.addFilter("BaseFilter", odtDocument.getPositionFilter()); - rootConstrainedFilter.addFilter("RootFilter", odtDocument.createRootFilter(inputMemberId)); + rootConstrainedFilter.addFilter(odtDocument.getPositionFilter()); + rootConstrainedFilter.addFilter(odtDocument.createRootFilter(inputMemberId)); iterator.setUnfilteredPosition(cursorNode, 0); while(nextPosition()) { if(rootConstrainedFilter.acceptPosition(iterator) === FILTER_ACCEPT) { @@ -17026,16 +14808,17 @@ gui.TextManipulator = function TextManipulator(session, inputMemberId, directSty return true }; function insertText(text) { - var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op, stylingOp, operations = []; + var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op, stylingOp, operations = [], useCachedStyle = false; if(selection.length > 0) { op = createOpRemoveSelection(selection); - operations.push(op) + operations.push(op); + useCachedStyle = true } op = new ops.OpInsertText; op.init({memberid:inputMemberId, position:selection.position, text:text, moveCursor:true}); operations.push(op); if(directStyleOp) { - stylingOp = directStyleOp(selection.position, text.length); + stylingOp = directStyleOp(selection.position, text.length, useCachedStyle); if(stylingOp) { operations.push(stylingOp) } @@ -17045,37 +14828,88 @@ gui.TextManipulator = function TextManipulator(session, inputMemberId, directSty this.insertText = insertText }; (function() { - return gui.TextManipulator + return gui.TextController })(); -runtime.loadClass("core.DomUtils"); -runtime.loadClass("core.Async"); -runtime.loadClass("core.ScheduledTask"); -runtime.loadClass("odf.OdfUtils"); -runtime.loadClass("odf.ObjectNameGenerator"); -runtime.loadClass("ops.OdtCursor"); -runtime.loadClass("ops.OpAddCursor"); -runtime.loadClass("ops.OpRemoveCursor"); -runtime.loadClass("gui.Clipboard"); -runtime.loadClass("gui.DirectTextStyler"); -runtime.loadClass("gui.DirectParagraphStyler"); -runtime.loadClass("gui.KeyboardHandler"); -runtime.loadClass("gui.ImageManager"); -runtime.loadClass("gui.ImageSelector"); -runtime.loadClass("gui.TextManipulator"); -runtime.loadClass("gui.AnnotationController"); -runtime.loadClass("gui.EventManager"); -runtime.loadClass("gui.PlainTextPasteboard"); -gui.SessionController = function() { +/* + + 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/ +*/ +gui.UndoManager = function UndoManager() { +}; +gui.UndoManager.prototype.subscribe = function(signal, callback) { +}; +gui.UndoManager.prototype.unsubscribe = function(signal, callback) { +}; +gui.UndoManager.prototype.setDocument = function(newDocument) { +}; +gui.UndoManager.prototype.setInitialState = function() { +}; +gui.UndoManager.prototype.initialize = function() { +}; +gui.UndoManager.prototype.purgeInitialState = function() { +}; +gui.UndoManager.prototype.setPlaybackFunction = function(playback_func) { +}; +gui.UndoManager.prototype.hasUndoStates = function() { +}; +gui.UndoManager.prototype.hasRedoStates = function() { +}; +gui.UndoManager.prototype.moveForward = function(states) { +}; +gui.UndoManager.prototype.moveBackward = function(states) { +}; +gui.UndoManager.prototype.onOperationExecuted = function(op) { +}; +gui.UndoManager.signalUndoStackChanged = "undoStackChanged"; +gui.UndoManager.signalUndoStateCreated = "undoStateCreated"; +gui.UndoManager.signalUndoStateModified = "undoStateModified"; +(function() { + return gui.UndoManager +})(); +(function() { var FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT; gui.SessionController = function SessionController(session, inputMemberId, shadowCursor, args) { - var window = (runtime.getWindow()), odtDocument = session.getOdtDocument(), async = new core.Async, domUtils = new core.DomUtils, odfUtils = new odf.OdfUtils, clipboard = new gui.Clipboard, keyDownHandler = new gui.KeyboardHandler, keyPressHandler = new gui.KeyboardHandler, keyboardMovementsFilter = new core.PositionFilterChain, baseFilter = odtDocument.getPositionFilter(), clickStartedWithinContainer = false, objectNameGenerator = new odf.ObjectNameGenerator(odtDocument.getOdfCanvas().odfContainer(), - inputMemberId), isMouseMoved = false, mouseDownRootFilter = null, undoManager = null, eventManager = new gui.EventManager(odtDocument), annotationController = new gui.AnnotationController(session, inputMemberId), directTextStyler = new gui.DirectTextStyler(session, inputMemberId), directParagraphStyler = args && args.directParagraphStylingEnabled ? new gui.DirectParagraphStyler(session, inputMemberId, objectNameGenerator) : null, createCursorStyleOp = (directTextStyler.createCursorStyleOp), textManipulator = - new gui.TextManipulator(session, inputMemberId, createCursorStyleOp), imageManager = new gui.ImageManager(session, inputMemberId, objectNameGenerator), imageSelector = new gui.ImageSelector(odtDocument.getOdfCanvas()), shadowCursorIterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), drawShadowCursorTask, redrawRegionSelectionTask, pasteHandler = new gui.PlainTextPasteboard(odtDocument, inputMemberId), clickCount = 0; + var window = (runtime.getWindow()), odtDocument = session.getOdtDocument(), async = new core.Async, domUtils = new core.DomUtils, odfUtils = new odf.OdfUtils, mimeDataExporter = new gui.MimeDataExporter, clipboard = new gui.Clipboard(mimeDataExporter), keyDownHandler = new gui.KeyboardHandler, keyPressHandler = new gui.KeyboardHandler, keyUpHandler = new gui.KeyboardHandler, clickStartedWithinCanvas = false, objectNameGenerator = new odf.ObjectNameGenerator(odtDocument.getOdfCanvas().odfContainer(), + inputMemberId), isMouseMoved = false, mouseDownRootFilter = null, handleMouseClickTimeoutId, undoManager = null, eventManager = new gui.EventManager(odtDocument), annotationController = new gui.AnnotationController(session, inputMemberId), directFormattingController = new gui.DirectFormattingController(session, inputMemberId, objectNameGenerator, args.directParagraphStylingEnabled), createCursorStyleOp = (directFormattingController.createCursorStyleOp), createParagraphStyleOps = (directFormattingController.createParagraphStyleOps), + textController = new gui.TextController(session, inputMemberId, createCursorStyleOp, createParagraphStyleOps), imageController = new gui.ImageController(session, inputMemberId, objectNameGenerator), imageSelector = new gui.ImageSelector(odtDocument.getOdfCanvas()), shadowCursorIterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), drawShadowCursorTask, redrawRegionSelectionTask, pasteHandler = new gui.PlainTextPasteboard(odtDocument, inputMemberId), inputMethodEditor = + new gui.InputMethodEditor(inputMemberId, eventManager), clickCount = 0, hyperlinkClickHandler = new gui.HyperlinkClickHandler(odtDocument.getRootNode), hyperlinkController = new gui.HyperlinkController(session, inputMemberId), selectionController = new gui.SelectionController(session, inputMemberId), modifier = gui.KeyboardHandler.Modifier, keyCode = gui.KeyboardHandler.KeyCode, isMacOS = window.navigator.appVersion.toLowerCase().indexOf("mac") !== -1, isIOS = ["iPad", "iPod", "iPhone"].indexOf(window.navigator.platform) !== + -1, iOSSafariSupport; runtime.assert(window !== null, "Expected to be run in an environment which has a global window, like a browser."); - keyboardMovementsFilter.addFilter("BaseFilter", baseFilter); - keyboardMovementsFilter.addFilter("RootFilter", odtDocument.createRootFilter(inputMemberId)); function getTarget(e) { - return e.target || e.srcElement + return(e.target) || (e.srcElement || null) } function cancelEvent(event) { if(event.preventDefault) { @@ -17084,19 +14918,11 @@ gui.SessionController = function() { event.returnValue = false } } - function dummyHandler(e) { - cancelEvent(e) - } - function createOpMoveCursor(position, length, selectionType) { - var op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:position, length:length || 0, selectionType:selectionType}); - return op - } function caretPositionFromPoint(x, y) { - var doc = odtDocument.getDOM(), c, result = null; + var doc = odtDocument.getDOMDocument(), c, result = null; if(doc.caretRangeFromPoint) { c = doc.caretRangeFromPoint(x, y); - result = {container:c.startContainer, offset:c.startOffset} + result = {container:(c.startContainer), offset:c.startOffset} }else { if(doc.caretPositionFromPoint) { c = doc.caretPositionFromPoint(x, y); @@ -17107,260 +14933,6 @@ gui.SessionController = function() { } return result } - function expandToWordBoundaries(range) { - var alphaNumeric = /[A-Za-z0-9]/, iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), currentNode, c; - iterator.setUnfilteredPosition((range.startContainer), range.startOffset); - while(iterator.previousPosition()) { - currentNode = iterator.getCurrentNode(); - if(currentNode.nodeType === Node.TEXT_NODE) { - c = currentNode.data[iterator.unfilteredDomOffset()]; - if(!alphaNumeric.test(c)) { - break - } - }else { - if(!odfUtils.isTextSpan(currentNode)) { - break - } - } - range.setStart(iterator.container(), iterator.unfilteredDomOffset()) - } - iterator.setUnfilteredPosition((range.endContainer), range.endOffset); - do { - currentNode = iterator.getCurrentNode(); - if(currentNode.nodeType === Node.TEXT_NODE) { - c = currentNode.data[iterator.unfilteredDomOffset()]; - if(!alphaNumeric.test(c)) { - break - } - }else { - if(!odfUtils.isTextSpan(currentNode)) { - break - } - } - }while(iterator.nextPosition()); - range.setEnd(iterator.container(), iterator.unfilteredDomOffset()) - } - function expandToParagraphBoundaries(range) { - var startParagraph = odtDocument.getParagraphElement(range.startContainer), endParagraph = odtDocument.getParagraphElement(range.endContainer); - if(startParagraph) { - range.setStart(startParagraph, 0) - } - if(endParagraph) { - if(odfUtils.isParagraph(range.endContainer) && range.endOffset === 0) { - range.setEndBefore(endParagraph) - }else { - range.setEnd(endParagraph, endParagraph.childNodes.length) - } - } - } - function selectImage(frameNode) { - var stepsToAnchor = odtDocument.getDistanceFromCursor(inputMemberId, frameNode, 0), stepsToFocus = stepsToAnchor !== null ? stepsToAnchor + 1 : null, oldPosition, op; - if(stepsToFocus || stepsToAnchor) { - oldPosition = odtDocument.getCursorPosition(inputMemberId); - op = createOpMoveCursor(oldPosition + stepsToAnchor, stepsToFocus - stepsToAnchor, ops.OdtCursor.RegionSelection); - session.enqueue([op]) - } - eventManager.focus() - } - function selectionToRange(selection) { - var hasForwardSelection = domUtils.comparePoints((selection.anchorNode), selection.anchorOffset, (selection.focusNode), selection.focusOffset) >= 0, range = selection.focusNode.ownerDocument.createRange(); - if(hasForwardSelection) { - range.setStart(selection.anchorNode, selection.anchorOffset); - range.setEnd(selection.focusNode, selection.focusOffset) - }else { - range.setStart(selection.focusNode, selection.focusOffset); - range.setEnd(selection.anchorNode, selection.anchorOffset) - } - return{range:range, hasForwardSelection:hasForwardSelection} - } - function rangeToSelection(range, hasForwardSelection) { - if(hasForwardSelection) { - return{anchorNode:(range.startContainer), anchorOffset:range.startOffset, focusNode:(range.endContainer), focusOffset:range.endOffset} - } - return{anchorNode:(range.endContainer), anchorOffset:range.endOffset, focusNode:(range.startContainer), focusOffset:range.startOffset} - } - function constrain(lookup) { - return function(originalNode) { - var originalContainer = lookup(originalNode); - return function(step, node) { - return lookup(node) === originalContainer - } - } - } - function selectRange(range, hasForwardSelection, clickCount) { - var canvasElement = odtDocument.getOdfCanvas().getElement(), validSelection, startInsideCanvas, endInsideCanvas, existingSelection, newSelection, op; - startInsideCanvas = domUtils.containsNode(canvasElement, range.startContainer); - endInsideCanvas = domUtils.containsNode(canvasElement, range.endContainer); - if(!startInsideCanvas && !endInsideCanvas) { - return - } - if(startInsideCanvas && endInsideCanvas) { - if(clickCount === 2) { - expandToWordBoundaries(range) - }else { - if(clickCount >= 3) { - expandToParagraphBoundaries(range) - } - } - } - validSelection = rangeToSelection(range, hasForwardSelection); - newSelection = odtDocument.convertDomToCursorRange(validSelection, constrain(odfUtils.getParagraphElement)); - existingSelection = odtDocument.getCursorSelection(inputMemberId); - if(newSelection.position !== existingSelection.position || newSelection.length !== existingSelection.length) { - op = createOpMoveCursor(newSelection.position, newSelection.length, ops.OdtCursor.RangeSelection); - session.enqueue([op]) - } - } - this.selectRange = selectRange; - function extendCursorByAdjustment(lengthAdjust) { - var selection = odtDocument.getCursorSelection(inputMemberId), stepCounter = odtDocument.getCursor(inputMemberId).getStepCounter(), newLength; - if(lengthAdjust !== 0) { - lengthAdjust = lengthAdjust > 0 ? stepCounter.convertForwardStepsBetweenFilters(lengthAdjust, keyboardMovementsFilter, baseFilter) : -stepCounter.convertBackwardStepsBetweenFilters(-lengthAdjust, keyboardMovementsFilter, baseFilter); - newLength = selection.length + lengthAdjust; - session.enqueue([createOpMoveCursor(selection.position, newLength)]) - } - } - function moveCursorByAdjustment(positionAdjust) { - var position = odtDocument.getCursorPosition(inputMemberId), stepCounter = odtDocument.getCursor(inputMemberId).getStepCounter(); - if(positionAdjust !== 0) { - positionAdjust = positionAdjust > 0 ? stepCounter.convertForwardStepsBetweenFilters(positionAdjust, keyboardMovementsFilter, baseFilter) : -stepCounter.convertBackwardStepsBetweenFilters(-positionAdjust, keyboardMovementsFilter, baseFilter); - position = position + positionAdjust; - session.enqueue([createOpMoveCursor(position, 0)]) - } - } - function moveCursorToLeft() { - moveCursorByAdjustment(-1); - return true - } - this.moveCursorToLeft = moveCursorToLeft; - function moveCursorToRight() { - moveCursorByAdjustment(1); - return true - } - function extendSelectionToLeft() { - extendCursorByAdjustment(-1); - return true - } - function extendSelectionToRight() { - extendCursorByAdjustment(1); - return true - } - function moveCursorByLine(direction, extend) { - var paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), steps; - runtime.assert(Boolean(paragraphNode), "SessionController: Cursor outside paragraph"); - steps = odtDocument.getCursor(inputMemberId).getStepCounter().countLinesSteps(direction, keyboardMovementsFilter); - if(extend) { - extendCursorByAdjustment(steps) - }else { - moveCursorByAdjustment(steps) - } - } - function moveCursorUp() { - moveCursorByLine(-1, false); - return true - } - function moveCursorDown() { - moveCursorByLine(1, false); - return true - } - function extendSelectionUp() { - moveCursorByLine(-1, true); - return true - } - function extendSelectionDown() { - moveCursorByLine(1, true); - return true - } - function moveCursorToLineBoundary(direction, extend) { - var steps = odtDocument.getCursor(inputMemberId).getStepCounter().countStepsToLineBoundary(direction, keyboardMovementsFilter); - if(extend) { - extendCursorByAdjustment(steps) - }else { - moveCursorByAdjustment(steps) - } - } - function moveCursorToLineStart() { - moveCursorToLineBoundary(-1, false); - return true - } - function moveCursorToLineEnd() { - moveCursorToLineBoundary(1, false); - return true - } - function extendSelectionToLineStart() { - moveCursorToLineBoundary(-1, true); - return true - } - function extendSelectionToLineEnd() { - moveCursorToLineBoundary(1, true); - return true - } - function extendSelectionToParagraphStart() { - var paragraphNode = (odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode())), iterator, node, steps; - runtime.assert(Boolean(paragraphNode), "SessionController: Cursor outside paragraph"); - steps = odtDocument.getDistanceFromCursor(inputMemberId, paragraphNode, 0); - iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()); - iterator.setUnfilteredPosition(paragraphNode, 0); - while(steps === 0 && iterator.previousPosition()) { - node = iterator.getCurrentNode(); - if(odfUtils.isParagraph(node)) { - steps = odtDocument.getDistanceFromCursor(inputMemberId, node, 0) - } - } - extendCursorByAdjustment(steps); - return true - } - function extendSelectionToParagraphEnd() { - var paragraphNode = (odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode())), iterator, node, steps; - runtime.assert(Boolean(paragraphNode), "SessionController: Cursor outside paragraph"); - iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()); - iterator.moveToEndOfNode(paragraphNode); - steps = odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()); - while(steps === 0 && iterator.nextPosition()) { - node = iterator.getCurrentNode(); - if(odfUtils.isParagraph(node)) { - iterator.moveToEndOfNode(node); - steps = odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()) - } - } - extendCursorByAdjustment(steps); - return true - } - function moveCursorToDocumentBoundary(direction, extend) { - var iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), steps; - if(direction > 0) { - iterator.moveToEnd() - } - steps = odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()); - if(extend) { - extendCursorByAdjustment(steps) - }else { - moveCursorByAdjustment(steps) - } - } - this.moveCursorToDocumentBoundary = moveCursorToDocumentBoundary; - function moveCursorToDocumentStart() { - moveCursorToDocumentBoundary(-1, false); - return true - } - function moveCursorToDocumentEnd() { - moveCursorToDocumentBoundary(1, false); - return true - } - function extendSelectionToDocumentStart() { - moveCursorToDocumentBoundary(-1, true); - return true - } - function extendSelectionToDocumentEnd() { - moveCursorToDocumentBoundary(1, true); - return true - } - function extendSelectionToEntireDocument() { - var rootNode = odtDocument.getRootNode(), lastWalkableStep = odtDocument.convertDomPointToCursorStep(rootNode, rootNode.childNodes.length); - session.enqueue([createOpMoveCursor(0, lastWalkableStep)]); - return true - } - this.extendSelectionToEntireDocument = extendSelectionToEntireDocument; function redrawRegionSelection() { var cursor = odtDocument.getCursor(inputMemberId), imageElement; if(cursor && cursor.getSelectionType() === ops.OdtCursor.RegionSelection) { @@ -17388,7 +14960,7 @@ gui.SessionController = function() { return } if(clipboard.setDataFromRange(e, selectedRange)) { - textManipulator.removeCurrentSelection() + textController.removeCurrentSelection() }else { runtime.log("Cut operation failed") } @@ -17417,7 +14989,7 @@ gui.SessionController = function() { } } if(plainText) { - textManipulator.removeCurrentSelection(); + textController.removeCurrentSelection(); session.enqueue(pasteHandler.createPasteOps(plainText)) } cancelEvent(e) @@ -17434,37 +15006,51 @@ gui.SessionController = function() { odtDocument.emit(ops.OdtDocument.signalUndoStackChanged, e) } function undo() { + var eventTrap = eventManager.getEventTrap(), sizer, hadFocusBefore; if(undoManager) { + hadFocusBefore = eventManager.hasFocus(); undoManager.moveBackward(1); - redrawRegionSelectionTask.trigger(); + sizer = odtDocument.getOdfCanvas().getSizer(); + if(!domUtils.containsNode(sizer, eventTrap)) { + sizer.appendChild(eventTrap); + if(hadFocusBefore) { + eventManager.focus() + } + } return true } return false } + this.undo = undo; function redo() { + var hadFocusBefore; if(undoManager) { + hadFocusBefore = eventManager.hasFocus(); undoManager.moveForward(1); - redrawRegionSelectionTask.trigger(); + if(hadFocusBefore) { + eventManager.focus() + } return true } return false } + this.redo = redo; function updateShadowCursor() { - var selection = window.getSelection(), selectionRange = selection.rangeCount > 0 && selectionToRange(selection); - if(clickStartedWithinContainer && selectionRange) { + var selection = window.getSelection(), selectionRange = selection.rangeCount > 0 && selectionController.selectionToRange(selection); + if(clickStartedWithinCanvas && selectionRange) { isMouseMoved = true; imageSelector.clearSelection(); shadowCursorIterator.setUnfilteredPosition((selection.focusNode), selection.focusOffset); if(mouseDownRootFilter.acceptPosition(shadowCursorIterator) === FILTER_ACCEPT) { if(clickCount === 2) { - expandToWordBoundaries(selectionRange.range) + selectionController.expandToWordBoundaries(selectionRange.range) }else { if(clickCount >= 3) { - expandToParagraphBoundaries(selectionRange.range) + selectionController.expandToParagraphBoundaries(selectionRange.range) } } shadowCursor.setSelectedRange(selectionRange.range, selectionRange.hasForwardSelection); - odtDocument.emit(ops.OdtDocument.signalCursorMoved, shadowCursor) + odtDocument.emit(ops.Document.signalCursorMoved, shadowCursor) } } } @@ -17480,16 +15066,15 @@ gui.SessionController = function() { } }else { selection.removeAllRanges(); - selection.addRange(range.cloneRange()); - (odtDocument.getOdfCanvas().getElement()).setActive() + selection.addRange(range.cloneRange()) } } function handleMouseDown(e) { var target = getTarget(e), cursor = odtDocument.getCursor(inputMemberId); - clickStartedWithinContainer = target && domUtils.containsNode(odtDocument.getOdfCanvas().getElement(), target); - if(clickStartedWithinContainer) { + clickStartedWithinCanvas = target !== null && domUtils.containsNode(odtDocument.getOdfCanvas().getElement(), target); + if(clickStartedWithinCanvas) { isMouseMoved = false; - mouseDownRootFilter = odtDocument.createRootFilter(target); + mouseDownRootFilter = odtDocument.createRootFilter((target)); clickCount = e.detail; if(cursor && e.shiftKey) { window.getSelection().collapse(cursor.getAnchorNode(), 0) @@ -17507,111 +15092,263 @@ gui.SessionController = function() { } return null } + function getNextWalkablePosition(node) { + var root = odtDocument.getRootElement(node), rootFilter = odtDocument.createRootFilter(root), stepIterator = odtDocument.createStepIterator(node, 0, [rootFilter, odtDocument.getPositionFilter()], root); + stepIterator.setPosition(node, node.childNodes.length); + if(!stepIterator.roundToNextStep()) { + return null + } + return{container:stepIterator.container(), offset:stepIterator.offset()} + } + function moveByMouseClickEvent(event) { + var selection = mutableSelection(window.getSelection()), position, selectionRange, rect, frameNode; + if(!selection.anchorNode && !selection.focusNode) { + position = caretPositionFromPoint(event.clientX, event.clientY); + if(position) { + selection.anchorNode = (position.container); + selection.anchorOffset = position.offset; + selection.focusNode = selection.anchorNode; + selection.focusOffset = selection.anchorOffset + } + } + if(odfUtils.isImage(selection.focusNode) && (selection.focusOffset === 0 && odfUtils.isCharacterFrame(selection.focusNode.parentNode))) { + frameNode = (selection.focusNode.parentNode); + rect = frameNode.getBoundingClientRect(); + if(event.clientX > rect.right) { + position = getNextWalkablePosition(frameNode); + if(position) { + selection.anchorNode = selection.focusNode = position.container; + selection.anchorOffset = selection.focusOffset = position.offset + } + } + }else { + if(odfUtils.isImage(selection.focusNode.firstChild) && (selection.focusOffset === 1 && odfUtils.isCharacterFrame(selection.focusNode))) { + position = getNextWalkablePosition(selection.focusNode); + if(position) { + selection.anchorNode = selection.focusNode = position.container; + selection.anchorOffset = selection.focusOffset = position.offset + } + } + } + if(selection.anchorNode && selection.focusNode) { + selectionRange = selectionController.selectionToRange(selection); + selectionController.selectRange(selectionRange.range, selectionRange.hasForwardSelection, event.detail) + } + eventManager.focus() + } function handleMouseClickEvent(event) { - var target = getTarget(event), eventDetails = {detail:event.detail, clientX:event.clientX, clientY:event.clientY, target:target}; + var target = getTarget(event), range, wasCollapsed, frameNode, pos; drawShadowCursorTask.processRequests(); - if(odfUtils.isImage(target) && odfUtils.isCharacterFrame(target.parentNode)) { - selectImage(target.parentNode); + if(odfUtils.isImage(target) && (odfUtils.isCharacterFrame(target.parentNode) && window.getSelection().isCollapsed)) { + selectionController.selectImage((target.parentNode)); eventManager.focus() }else { - if(clickStartedWithinContainer && !imageSelector.isSelectorElement(target)) { - if(isMouseMoved) { - selectRange(shadowCursor.getSelectedRange(), shadowCursor.hasForwardSelection(), event.detail); - eventManager.focus() - }else { - runtime.setTimeout(function() { - var selection = mutableSelection(window.getSelection()), selectionRange, caretPos; - if(!selection.anchorNode && !selection.focusNode) { - caretPos = caretPositionFromPoint(eventDetails.clientX, eventDetails.clientY); - if(caretPos) { - selection.anchorNode = (caretPos.container); - selection.anchorOffset = caretPos.offset; - selection.focusNode = selection.anchorNode; - selection.focusOffset = selection.anchorOffset + if(imageSelector.isSelectorElement(target)) { + eventManager.focus() + }else { + if(clickStartedWithinCanvas) { + if(isMouseMoved) { + range = shadowCursor.getSelectedRange(); + wasCollapsed = range.collapsed; + if(odfUtils.isImage(range.endContainer) && (range.endOffset === 0 && odfUtils.isCharacterFrame(range.endContainer.parentNode))) { + frameNode = (range.endContainer.parentNode); + pos = getNextWalkablePosition(frameNode); + if(pos) { + range.setEnd(pos.container, pos.offset); + if(wasCollapsed) { + range.collapse(false) + } } } - if(selection.anchorNode && selection.focusNode) { - selectionRange = selectionToRange(selection); - selectRange(selectionRange.range, selectionRange.hasForwardSelection, eventDetails.detail) - } + selectionController.selectRange(range, shadowCursor.hasForwardSelection(), event.detail); eventManager.focus() - }, 0) + }else { + if(isIOS) { + moveByMouseClickEvent(event) + }else { + handleMouseClickTimeoutId = runtime.setTimeout(function() { + moveByMouseClickEvent(event) + }, 0) + } + } } } } clickCount = 0; - clickStartedWithinContainer = false; + clickStartedWithinCanvas = false; isMouseMoved = false } + function handleDragStart(e) { + var cursor = odtDocument.getCursor(inputMemberId), selectedRange = cursor.getSelectedRange(); + if(selectedRange.collapsed) { + return + } + mimeDataExporter.exportRangeToDataTransfer((e.dataTransfer), selectedRange) + } function handleDragEnd() { - if(clickStartedWithinContainer) { + if(clickStartedWithinCanvas) { eventManager.focus() } clickCount = 0; - clickStartedWithinContainer = false; + clickStartedWithinCanvas = false; isMouseMoved = false } function handleContextMenu(e) { handleMouseClickEvent(e) } function handleMouseUp(event) { - var target = getTarget(event), annotationNode = null; + var target = (getTarget(event)), annotationNode = null; if(target.className === "annotationRemoveButton") { - annotationNode = domUtils.getElementsByTagNameNS(target.parentNode, odf.Namespaces.officens, "annotation")[0]; - annotationController.removeAnnotation(annotationNode) + annotationNode = domUtils.getElementsByTagNameNS((target.parentNode), odf.Namespaces.officens, "annotation")[0]; + annotationController.removeAnnotation(annotationNode); + eventManager.focus() }else { handleMouseClickEvent(event) } } + function insertNonEmptyData(e) { + var input = e.data; + if(input) { + textController.insertText(input) + } + } + function returnTrue(fn) { + return function() { + fn(); + return true + } + } + function rangeSelectionOnly(fn) { + return function(e) { + var selectionType = odtDocument.getCursor(inputMemberId).getSelectionType(); + if(selectionType === ops.OdtCursor.RangeSelection) { + return fn(e) + } + return true + } + } + function insertLocalCursor() { + runtime.assert(session.getOdtDocument().getCursor(inputMemberId) === undefined, "Inserting local cursor a second time."); + var op = new ops.OpAddCursor; + op.init({memberid:inputMemberId}); + session.enqueue([op]); + eventManager.focus() + } + this.insertLocalCursor = insertLocalCursor; + function removeLocalCursor() { + runtime.assert(session.getOdtDocument().getCursor(inputMemberId) !== undefined, "Removing local cursor without inserting before."); + var op = new ops.OpRemoveCursor; + op.init({memberid:inputMemberId}); + session.enqueue([op]) + } + this.removeLocalCursor = removeLocalCursor; this.startEditing = function() { - var op; - odtDocument.getOdfCanvas().getElement().classList.add("virtualSelections"); - eventManager.subscribe("keydown", keyDownHandler.handleEvent); - eventManager.subscribe("keypress", keyPressHandler.handleEvent); - eventManager.subscribe("keyup", dummyHandler); + inputMethodEditor.subscribe(gui.InputMethodEditor.signalCompositionStart, textController.removeCurrentSelection); + inputMethodEditor.subscribe(gui.InputMethodEditor.signalCompositionEnd, insertNonEmptyData); eventManager.subscribe("beforecut", handleBeforeCut); eventManager.subscribe("cut", handleCut); - eventManager.subscribe("copy", handleCopy); eventManager.subscribe("beforepaste", handleBeforePaste); eventManager.subscribe("paste", handlePaste); - eventManager.subscribe("mousedown", handleMouseDown); - eventManager.subscribe("mousemove", drawShadowCursorTask.trigger); - eventManager.subscribe("mouseup", handleMouseUp); - eventManager.subscribe("contextmenu", handleContextMenu); - eventManager.subscribe("dragend", handleDragEnd); - odtDocument.subscribe(ops.OdtDocument.signalOperationExecuted, redrawRegionSelectionTask.trigger); - odtDocument.subscribe(ops.OdtDocument.signalOperationExecuted, updateUndoStack); - op = new ops.OpAddCursor; - op.init({memberid:inputMemberId}); - session.enqueue([op]); + window.addEventListener("focus", hyperlinkClickHandler.showTextCursor, false); if(undoManager) { - undoManager.saveInitialState() + undoManager.initialize() + } + inputMethodEditor.setEditing(true); + hyperlinkClickHandler.setModifier(isMacOS ? gui.HyperlinkClickHandler.Modifier.Meta : gui.HyperlinkClickHandler.Modifier.Ctrl); + keyDownHandler.bind(keyCode.Backspace, modifier.None, returnTrue(textController.removeTextByBackspaceKey), true); + keyDownHandler.bind(keyCode.Delete, modifier.None, textController.removeTextByDeleteKey); + keyDownHandler.bind(keyCode.Tab, modifier.None, rangeSelectionOnly(function() { + textController.insertText("\t"); + return true + })); + if(isMacOS) { + keyDownHandler.bind(keyCode.Clear, modifier.None, textController.removeCurrentSelection); + keyDownHandler.bind(keyCode.B, modifier.Meta, rangeSelectionOnly(directFormattingController.toggleBold)); + keyDownHandler.bind(keyCode.I, modifier.Meta, rangeSelectionOnly(directFormattingController.toggleItalic)); + keyDownHandler.bind(keyCode.U, modifier.Meta, rangeSelectionOnly(directFormattingController.toggleUnderline)); + keyDownHandler.bind(keyCode.L, modifier.MetaShift, rangeSelectionOnly(directFormattingController.alignParagraphLeft)); + keyDownHandler.bind(keyCode.E, modifier.MetaShift, rangeSelectionOnly(directFormattingController.alignParagraphCenter)); + keyDownHandler.bind(keyCode.R, modifier.MetaShift, rangeSelectionOnly(directFormattingController.alignParagraphRight)); + keyDownHandler.bind(keyCode.J, modifier.MetaShift, rangeSelectionOnly(directFormattingController.alignParagraphJustified)); + keyDownHandler.bind(keyCode.C, modifier.MetaShift, annotationController.addAnnotation); + keyDownHandler.bind(keyCode.Z, modifier.Meta, undo); + keyDownHandler.bind(keyCode.Z, modifier.MetaShift, redo); + keyDownHandler.bind(keyCode.LeftMeta, modifier.Meta, hyperlinkClickHandler.showPointerCursor); + keyDownHandler.bind(keyCode.MetaInMozilla, modifier.Meta, hyperlinkClickHandler.showPointerCursor); + keyUpHandler.bind(keyCode.LeftMeta, modifier.None, hyperlinkClickHandler.showTextCursor); + keyUpHandler.bind(keyCode.MetaInMozilla, modifier.None, hyperlinkClickHandler.showTextCursor) + }else { + keyDownHandler.bind(keyCode.B, modifier.Ctrl, rangeSelectionOnly(directFormattingController.toggleBold)); + keyDownHandler.bind(keyCode.I, modifier.Ctrl, rangeSelectionOnly(directFormattingController.toggleItalic)); + keyDownHandler.bind(keyCode.U, modifier.Ctrl, rangeSelectionOnly(directFormattingController.toggleUnderline)); + keyDownHandler.bind(keyCode.L, modifier.CtrlShift, rangeSelectionOnly(directFormattingController.alignParagraphLeft)); + keyDownHandler.bind(keyCode.E, modifier.CtrlShift, rangeSelectionOnly(directFormattingController.alignParagraphCenter)); + keyDownHandler.bind(keyCode.R, modifier.CtrlShift, rangeSelectionOnly(directFormattingController.alignParagraphRight)); + keyDownHandler.bind(keyCode.J, modifier.CtrlShift, rangeSelectionOnly(directFormattingController.alignParagraphJustified)); + keyDownHandler.bind(keyCode.C, modifier.CtrlAlt, annotationController.addAnnotation); + keyDownHandler.bind(keyCode.Z, modifier.Ctrl, undo); + keyDownHandler.bind(keyCode.Z, modifier.CtrlShift, redo); + keyDownHandler.bind(keyCode.Ctrl, modifier.Ctrl, hyperlinkClickHandler.showPointerCursor); + keyUpHandler.bind(keyCode.Ctrl, modifier.None, hyperlinkClickHandler.showTextCursor) } + function handler(e) { + var text = stringFromKeyPress(e); + if(text && !(e.altKey || (e.ctrlKey || e.metaKey))) { + textController.insertText(text); + return true + } + return false + } + keyPressHandler.setDefault(rangeSelectionOnly(handler)); + keyPressHandler.bind(keyCode.Enter, modifier.None, rangeSelectionOnly(textController.enqueueParagraphSplittingOps)) }; this.endEditing = function() { - var op; - op = new ops.OpRemoveCursor; - op.init({memberid:inputMemberId}); - session.enqueue([op]); - if(undoManager) { - undoManager.resetInitialState() - } - odtDocument.unsubscribe(ops.OdtDocument.signalOperationExecuted, updateUndoStack); - odtDocument.unsubscribe(ops.OdtDocument.signalOperationExecuted, redrawRegionSelectionTask.trigger); - eventManager.unsubscribe("keydown", keyDownHandler.handleEvent); - eventManager.unsubscribe("keypress", keyPressHandler.handleEvent); - eventManager.unsubscribe("keyup", dummyHandler); + inputMethodEditor.unsubscribe(gui.InputMethodEditor.signalCompositionStart, textController.removeCurrentSelection); + inputMethodEditor.unsubscribe(gui.InputMethodEditor.signalCompositionEnd, insertNonEmptyData); eventManager.unsubscribe("cut", handleCut); eventManager.unsubscribe("beforecut", handleBeforeCut); - eventManager.unsubscribe("copy", handleCopy); eventManager.unsubscribe("paste", handlePaste); eventManager.unsubscribe("beforepaste", handleBeforePaste); - eventManager.unsubscribe("mousemove", drawShadowCursorTask.trigger); - eventManager.unsubscribe("mousedown", handleMouseDown); - eventManager.unsubscribe("mouseup", handleMouseUp); - eventManager.unsubscribe("contextmenu", handleContextMenu); - eventManager.unsubscribe("dragend", handleDragEnd); - odtDocument.getOdfCanvas().getElement().classList.remove("virtualSelections") + window.removeEventListener("focus", hyperlinkClickHandler.showTextCursor, false); + inputMethodEditor.setEditing(false); + hyperlinkClickHandler.setModifier(gui.HyperlinkClickHandler.Modifier.None); + keyDownHandler.bind(keyCode.Backspace, modifier.None, function() { + return true + }, true); + keyDownHandler.unbind(keyCode.Delete, modifier.None); + keyDownHandler.unbind(keyCode.Tab, modifier.None); + if(isMacOS) { + keyDownHandler.unbind(keyCode.Clear, modifier.None); + keyDownHandler.unbind(keyCode.B, modifier.Meta); + keyDownHandler.unbind(keyCode.I, modifier.Meta); + keyDownHandler.unbind(keyCode.U, modifier.Meta); + keyDownHandler.unbind(keyCode.L, modifier.MetaShift); + keyDownHandler.unbind(keyCode.E, modifier.MetaShift); + keyDownHandler.unbind(keyCode.R, modifier.MetaShift); + keyDownHandler.unbind(keyCode.J, modifier.MetaShift); + keyDownHandler.unbind(keyCode.C, modifier.MetaShift); + keyDownHandler.unbind(keyCode.Z, modifier.Meta); + keyDownHandler.unbind(keyCode.Z, modifier.MetaShift); + keyDownHandler.unbind(keyCode.LeftMeta, modifier.Meta); + keyDownHandler.unbind(keyCode.MetaInMozilla, modifier.Meta); + keyUpHandler.unbind(keyCode.LeftMeta, modifier.None); + keyUpHandler.unbind(keyCode.MetaInMozilla, modifier.None) + }else { + keyDownHandler.unbind(keyCode.B, modifier.Ctrl); + keyDownHandler.unbind(keyCode.I, modifier.Ctrl); + keyDownHandler.unbind(keyCode.U, modifier.Ctrl); + keyDownHandler.unbind(keyCode.L, modifier.CtrlShift); + keyDownHandler.unbind(keyCode.E, modifier.CtrlShift); + keyDownHandler.unbind(keyCode.R, modifier.CtrlShift); + keyDownHandler.unbind(keyCode.J, modifier.CtrlShift); + keyDownHandler.unbind(keyCode.C, modifier.CtrlAlt); + keyDownHandler.unbind(keyCode.Z, modifier.Ctrl); + keyDownHandler.unbind(keyCode.Z, modifier.CtrlShift); + keyDownHandler.unbind(keyCode.Ctrl, modifier.Ctrl); + keyUpHandler.unbind(keyCode.Ctrl, modifier.None) + } + keyPressHandler.setDefault(null); + keyPressHandler.unbind(keyCode.Enter, modifier.None) }; this.getInputMemberId = function() { return inputMemberId @@ -17625,10 +15362,8 @@ gui.SessionController = function() { } undoManager = manager; if(undoManager) { - undoManager.setOdtDocument(odtDocument); - undoManager.setPlaybackFunction(function(op) { - op.execute(odtDocument) - }); + undoManager.setDocument(odtDocument); + undoManager.setPlaybackFunction(session.enqueue); undoManager.subscribe(gui.UndoManager.signalUndoStackChanged, forwardUndoStackChange) } }; @@ -17638,17 +15373,20 @@ gui.SessionController = function() { this.getAnnotationController = function() { return annotationController }; - this.getDirectTextStyler = function() { - return directTextStyler + this.getDirectFormattingController = function() { + return directFormattingController + }; + this.getHyperlinkController = function() { + return hyperlinkController }; - this.getDirectParagraphStyler = function() { - return directParagraphStyler + this.getImageController = function() { + return imageController }; - this.getImageManager = function() { - return imageManager + this.getSelectionController = function() { + return selectionController }; - this.getTextManipulator = function() { - return textManipulator + this.getTextController = function() { + return textController }; this.getEventManager = function() { return eventManager @@ -17656,114 +15394,100 @@ gui.SessionController = function() { this.getKeyboardHandlers = function() { return{keydown:keyDownHandler, keypress:keyPressHandler} }; + function destroy(callback) { + eventManager.unsubscribe("keydown", keyDownHandler.handleEvent); + eventManager.unsubscribe("keypress", keyPressHandler.handleEvent); + eventManager.unsubscribe("keyup", keyUpHandler.handleEvent); + eventManager.unsubscribe("copy", handleCopy); + eventManager.unsubscribe("mousedown", handleMouseDown); + eventManager.unsubscribe("mousemove", drawShadowCursorTask.trigger); + eventManager.unsubscribe("mouseup", handleMouseUp); + eventManager.unsubscribe("contextmenu", handleContextMenu); + eventManager.unsubscribe("dragstart", handleDragStart); + eventManager.unsubscribe("dragend", handleDragEnd); + eventManager.unsubscribe("click", hyperlinkClickHandler.handleClick); + odtDocument.unsubscribe(ops.OdtDocument.signalOperationEnd, redrawRegionSelectionTask.trigger); + odtDocument.unsubscribe(ops.Document.signalCursorAdded, inputMethodEditor.registerCursor); + odtDocument.unsubscribe(ops.Document.signalCursorRemoved, inputMethodEditor.removeCursor); + odtDocument.unsubscribe(ops.OdtDocument.signalOperationEnd, updateUndoStack); + callback() + } this.destroy = function(callback) { - var destroyCallbacks = [drawShadowCursorTask.destroy, directTextStyler.destroy]; - if(directParagraphStyler) { - destroyCallbacks.push(directParagraphStyler.destroy) + var destroyCallbacks = []; + if(iOSSafariSupport) { + destroyCallbacks.push(iOSSafariSupport.destroy) } + destroyCallbacks = destroyCallbacks.concat([drawShadowCursorTask.destroy, redrawRegionSelectionTask.destroy, directFormattingController.destroy, inputMethodEditor.destroy, eventManager.destroy, destroy]); + runtime.clearTimeout(handleMouseClickTimeoutId); async.destroyAll(destroyCallbacks, callback) }; - function returnTrue(fn) { - return function() { - fn(); - return true - } - } - function rangeSelectionOnly(fn) { - return function(e) { - var selectionType = odtDocument.getCursor(inputMemberId).getSelectionType(); - if(selectionType === ops.OdtCursor.RangeSelection) { - return fn(e) - } - return true - } - } function init() { - var isMacOS = window.navigator.appVersion.toLowerCase().indexOf("mac") !== -1, modifier = gui.KeyboardHandler.Modifier, keyCode = gui.KeyboardHandler.KeyCode; drawShadowCursorTask = new core.ScheduledTask(updateShadowCursor, 0); redrawRegionSelectionTask = new core.ScheduledTask(redrawRegionSelection, 0); - keyDownHandler.bind(keyCode.Tab, modifier.None, rangeSelectionOnly(function() { - textManipulator.insertText("\t"); - return true - })); - keyDownHandler.bind(keyCode.Left, modifier.None, rangeSelectionOnly(moveCursorToLeft)); - keyDownHandler.bind(keyCode.Right, modifier.None, rangeSelectionOnly(moveCursorToRight)); - keyDownHandler.bind(keyCode.Up, modifier.None, rangeSelectionOnly(moveCursorUp)); - keyDownHandler.bind(keyCode.Down, modifier.None, rangeSelectionOnly(moveCursorDown)); - keyDownHandler.bind(keyCode.Backspace, modifier.None, returnTrue(textManipulator.removeTextByBackspaceKey)); - keyDownHandler.bind(keyCode.Delete, modifier.None, textManipulator.removeTextByDeleteKey); - keyDownHandler.bind(keyCode.Left, modifier.Shift, rangeSelectionOnly(extendSelectionToLeft)); - keyDownHandler.bind(keyCode.Right, modifier.Shift, rangeSelectionOnly(extendSelectionToRight)); - keyDownHandler.bind(keyCode.Up, modifier.Shift, rangeSelectionOnly(extendSelectionUp)); - keyDownHandler.bind(keyCode.Down, modifier.Shift, rangeSelectionOnly(extendSelectionDown)); - keyDownHandler.bind(keyCode.Home, modifier.None, rangeSelectionOnly(moveCursorToLineStart)); - keyDownHandler.bind(keyCode.End, modifier.None, rangeSelectionOnly(moveCursorToLineEnd)); - keyDownHandler.bind(keyCode.Home, modifier.Ctrl, rangeSelectionOnly(moveCursorToDocumentStart)); - keyDownHandler.bind(keyCode.End, modifier.Ctrl, rangeSelectionOnly(moveCursorToDocumentEnd)); - keyDownHandler.bind(keyCode.Home, modifier.Shift, rangeSelectionOnly(extendSelectionToLineStart)); - keyDownHandler.bind(keyCode.End, modifier.Shift, rangeSelectionOnly(extendSelectionToLineEnd)); - keyDownHandler.bind(keyCode.Up, modifier.CtrlShift, rangeSelectionOnly(extendSelectionToParagraphStart)); - keyDownHandler.bind(keyCode.Down, modifier.CtrlShift, rangeSelectionOnly(extendSelectionToParagraphEnd)); - keyDownHandler.bind(keyCode.Home, modifier.CtrlShift, rangeSelectionOnly(extendSelectionToDocumentStart)); - keyDownHandler.bind(keyCode.End, modifier.CtrlShift, rangeSelectionOnly(extendSelectionToDocumentEnd)); + keyDownHandler.bind(keyCode.Left, modifier.None, rangeSelectionOnly(selectionController.moveCursorToLeft)); + keyDownHandler.bind(keyCode.Right, modifier.None, rangeSelectionOnly(selectionController.moveCursorToRight)); + keyDownHandler.bind(keyCode.Up, modifier.None, rangeSelectionOnly(selectionController.moveCursorUp)); + keyDownHandler.bind(keyCode.Down, modifier.None, rangeSelectionOnly(selectionController.moveCursorDown)); + keyDownHandler.bind(keyCode.Left, modifier.Shift, rangeSelectionOnly(selectionController.extendSelectionToLeft)); + keyDownHandler.bind(keyCode.Right, modifier.Shift, rangeSelectionOnly(selectionController.extendSelectionToRight)); + keyDownHandler.bind(keyCode.Up, modifier.Shift, rangeSelectionOnly(selectionController.extendSelectionUp)); + keyDownHandler.bind(keyCode.Down, modifier.Shift, rangeSelectionOnly(selectionController.extendSelectionDown)); + keyDownHandler.bind(keyCode.Home, modifier.None, rangeSelectionOnly(selectionController.moveCursorToLineStart)); + keyDownHandler.bind(keyCode.End, modifier.None, rangeSelectionOnly(selectionController.moveCursorToLineEnd)); + keyDownHandler.bind(keyCode.Home, modifier.Ctrl, rangeSelectionOnly(selectionController.moveCursorToDocumentStart)); + keyDownHandler.bind(keyCode.End, modifier.Ctrl, rangeSelectionOnly(selectionController.moveCursorToDocumentEnd)); + keyDownHandler.bind(keyCode.Home, modifier.Shift, rangeSelectionOnly(selectionController.extendSelectionToLineStart)); + keyDownHandler.bind(keyCode.End, modifier.Shift, rangeSelectionOnly(selectionController.extendSelectionToLineEnd)); + keyDownHandler.bind(keyCode.Up, modifier.CtrlShift, rangeSelectionOnly(selectionController.extendSelectionToParagraphStart)); + keyDownHandler.bind(keyCode.Down, modifier.CtrlShift, rangeSelectionOnly(selectionController.extendSelectionToParagraphEnd)); + keyDownHandler.bind(keyCode.Home, modifier.CtrlShift, rangeSelectionOnly(selectionController.extendSelectionToDocumentStart)); + keyDownHandler.bind(keyCode.End, modifier.CtrlShift, rangeSelectionOnly(selectionController.extendSelectionToDocumentEnd)); if(isMacOS) { - keyDownHandler.bind(keyCode.Clear, modifier.None, textManipulator.removeCurrentSelection); - keyDownHandler.bind(keyCode.Left, modifier.Meta, rangeSelectionOnly(moveCursorToLineStart)); - keyDownHandler.bind(keyCode.Right, modifier.Meta, rangeSelectionOnly(moveCursorToLineEnd)); - keyDownHandler.bind(keyCode.Home, modifier.Meta, rangeSelectionOnly(moveCursorToDocumentStart)); - keyDownHandler.bind(keyCode.End, modifier.Meta, rangeSelectionOnly(moveCursorToDocumentEnd)); - keyDownHandler.bind(keyCode.Left, modifier.MetaShift, rangeSelectionOnly(extendSelectionToLineStart)); - keyDownHandler.bind(keyCode.Right, modifier.MetaShift, rangeSelectionOnly(extendSelectionToLineEnd)); - keyDownHandler.bind(keyCode.Up, modifier.AltShift, rangeSelectionOnly(extendSelectionToParagraphStart)); - keyDownHandler.bind(keyCode.Down, modifier.AltShift, rangeSelectionOnly(extendSelectionToParagraphEnd)); - keyDownHandler.bind(keyCode.Up, modifier.MetaShift, rangeSelectionOnly(extendSelectionToDocumentStart)); - keyDownHandler.bind(keyCode.Down, modifier.MetaShift, rangeSelectionOnly(extendSelectionToDocumentEnd)); - keyDownHandler.bind(keyCode.A, modifier.Meta, rangeSelectionOnly(extendSelectionToEntireDocument)); - keyDownHandler.bind(keyCode.B, modifier.Meta, rangeSelectionOnly(directTextStyler.toggleBold)); - keyDownHandler.bind(keyCode.I, modifier.Meta, rangeSelectionOnly(directTextStyler.toggleItalic)); - keyDownHandler.bind(keyCode.U, modifier.Meta, rangeSelectionOnly(directTextStyler.toggleUnderline)); - if(directParagraphStyler) { - keyDownHandler.bind(keyCode.L, modifier.MetaShift, rangeSelectionOnly(directParagraphStyler.alignParagraphLeft)); - keyDownHandler.bind(keyCode.E, modifier.MetaShift, rangeSelectionOnly(directParagraphStyler.alignParagraphCenter)); - keyDownHandler.bind(keyCode.R, modifier.MetaShift, rangeSelectionOnly(directParagraphStyler.alignParagraphRight)); - keyDownHandler.bind(keyCode.J, modifier.MetaShift, rangeSelectionOnly(directParagraphStyler.alignParagraphJustified)) - } - if(annotationController) { - keyDownHandler.bind(keyCode.C, modifier.MetaShift, annotationController.addAnnotation) - } - keyDownHandler.bind(keyCode.Z, modifier.Meta, undo); - keyDownHandler.bind(keyCode.Z, modifier.MetaShift, redo) + keyDownHandler.bind(keyCode.Left, modifier.Alt, rangeSelectionOnly(selectionController.moveCursorBeforeWord)); + keyDownHandler.bind(keyCode.Right, modifier.Alt, rangeSelectionOnly(selectionController.moveCursorPastWord)); + keyDownHandler.bind(keyCode.Left, modifier.Meta, rangeSelectionOnly(selectionController.moveCursorToLineStart)); + keyDownHandler.bind(keyCode.Right, modifier.Meta, rangeSelectionOnly(selectionController.moveCursorToLineEnd)); + keyDownHandler.bind(keyCode.Home, modifier.Meta, rangeSelectionOnly(selectionController.moveCursorToDocumentStart)); + keyDownHandler.bind(keyCode.End, modifier.Meta, rangeSelectionOnly(selectionController.moveCursorToDocumentEnd)); + keyDownHandler.bind(keyCode.Left, modifier.AltShift, rangeSelectionOnly(selectionController.extendSelectionBeforeWord)); + keyDownHandler.bind(keyCode.Right, modifier.AltShift, rangeSelectionOnly(selectionController.extendSelectionPastWord)); + keyDownHandler.bind(keyCode.Left, modifier.MetaShift, rangeSelectionOnly(selectionController.extendSelectionToLineStart)); + keyDownHandler.bind(keyCode.Right, modifier.MetaShift, rangeSelectionOnly(selectionController.extendSelectionToLineEnd)); + keyDownHandler.bind(keyCode.Up, modifier.AltShift, rangeSelectionOnly(selectionController.extendSelectionToParagraphStart)); + keyDownHandler.bind(keyCode.Down, modifier.AltShift, rangeSelectionOnly(selectionController.extendSelectionToParagraphEnd)); + keyDownHandler.bind(keyCode.Up, modifier.MetaShift, rangeSelectionOnly(selectionController.extendSelectionToDocumentStart)); + keyDownHandler.bind(keyCode.Down, modifier.MetaShift, rangeSelectionOnly(selectionController.extendSelectionToDocumentEnd)); + keyDownHandler.bind(keyCode.A, modifier.Meta, rangeSelectionOnly(selectionController.extendSelectionToEntireDocument)) }else { - keyDownHandler.bind(keyCode.A, modifier.Ctrl, rangeSelectionOnly(extendSelectionToEntireDocument)); - keyDownHandler.bind(keyCode.B, modifier.Ctrl, rangeSelectionOnly(directTextStyler.toggleBold)); - keyDownHandler.bind(keyCode.I, modifier.Ctrl, rangeSelectionOnly(directTextStyler.toggleItalic)); - keyDownHandler.bind(keyCode.U, modifier.Ctrl, rangeSelectionOnly(directTextStyler.toggleUnderline)); - if(directParagraphStyler) { - keyDownHandler.bind(keyCode.L, modifier.CtrlShift, rangeSelectionOnly(directParagraphStyler.alignParagraphLeft)); - keyDownHandler.bind(keyCode.E, modifier.CtrlShift, rangeSelectionOnly(directParagraphStyler.alignParagraphCenter)); - keyDownHandler.bind(keyCode.R, modifier.CtrlShift, rangeSelectionOnly(directParagraphStyler.alignParagraphRight)); - keyDownHandler.bind(keyCode.J, modifier.CtrlShift, rangeSelectionOnly(directParagraphStyler.alignParagraphJustified)) - } - if(annotationController) { - keyDownHandler.bind(keyCode.C, modifier.CtrlAlt, annotationController.addAnnotation) - } - keyDownHandler.bind(keyCode.Z, modifier.Ctrl, undo); - keyDownHandler.bind(keyCode.Z, modifier.CtrlShift, redo) + keyDownHandler.bind(keyCode.Left, modifier.Ctrl, rangeSelectionOnly(selectionController.moveCursorBeforeWord)); + keyDownHandler.bind(keyCode.Right, modifier.Ctrl, rangeSelectionOnly(selectionController.moveCursorPastWord)); + keyDownHandler.bind(keyCode.Left, modifier.CtrlShift, rangeSelectionOnly(selectionController.extendSelectionBeforeWord)); + keyDownHandler.bind(keyCode.Right, modifier.CtrlShift, rangeSelectionOnly(selectionController.extendSelectionPastWord)); + keyDownHandler.bind(keyCode.A, modifier.Ctrl, rangeSelectionOnly(selectionController.extendSelectionToEntireDocument)) } - keyPressHandler.setDefault(rangeSelectionOnly(function(e) { - var text = stringFromKeyPress(e); - if(text && !(e.altKey || (e.ctrlKey || e.metaKey))) { - textManipulator.insertText(text); - return true - } - return false - })); - keyPressHandler.bind(keyCode.Enter, modifier.None, rangeSelectionOnly(textManipulator.enqueueParagraphSplittingOps)) + if(isIOS) { + iOSSafariSupport = new gui.IOSSafariSupport(eventManager) + } + eventManager.subscribe("keydown", keyDownHandler.handleEvent); + eventManager.subscribe("keypress", keyPressHandler.handleEvent); + eventManager.subscribe("keyup", keyUpHandler.handleEvent); + eventManager.subscribe("copy", handleCopy); + eventManager.subscribe("mousedown", handleMouseDown); + eventManager.subscribe("mousemove", drawShadowCursorTask.trigger); + eventManager.subscribe("mouseup", handleMouseUp); + eventManager.subscribe("contextmenu", handleContextMenu); + eventManager.subscribe("dragstart", handleDragStart); + eventManager.subscribe("dragend", handleDragEnd); + eventManager.subscribe("click", hyperlinkClickHandler.handleClick); + odtDocument.subscribe(ops.OdtDocument.signalOperationEnd, redrawRegionSelectionTask.trigger); + odtDocument.subscribe(ops.Document.signalCursorAdded, inputMethodEditor.registerCursor); + odtDocument.subscribe(ops.Document.signalCursorRemoved, inputMethodEditor.removeCursor); + odtDocument.subscribe(ops.OdtDocument.signalOperationEnd, updateUndoStack) } init() }; return gui.SessionController -}(); +})(); /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -17801,9 +15525,8 @@ gui.SessionController = function() { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("gui.Caret"); gui.CaretManager = function CaretManager(sessionController) { - var carets = {}, window = runtime.getWindow(), scrollIntoViewScheduled = false; + var carets = {}, async = new core.Async, window = runtime.getWindow(), ensureCaretVisibleTimeoutId, scrollIntoViewScheduled = false; function getCaret(memberId) { return carets.hasOwnProperty(memberId) ? carets[memberId] : null } @@ -17812,14 +15535,13 @@ gui.CaretManager = function CaretManager(sessionController) { return carets[memberid] }) } - function getCanvasElement() { - return sessionController.getSession().getOdtDocument().getOdfCanvas().getElement() - } function removeCaret(memberId) { - if(memberId === sessionController.getInputMemberId()) { - getCanvasElement().removeAttribute("tabindex") + var caret = carets[memberId]; + if(caret) { + caret.destroy(function() { + }); + delete carets[memberId] } - delete carets[memberId] } function refreshLocalCaretBlinking(cursor) { var caret, memberId = cursor.getMemberId(); @@ -17843,7 +15565,7 @@ gui.CaretManager = function CaretManager(sessionController) { caret.handleUpdate(); if(!scrollIntoViewScheduled) { scrollIntoViewScheduled = true; - runtime.setTimeout(executeEnsureCaretVisible, 50) + ensureCaretVisibleTimeoutId = runtime.setTimeout(executeEnsureCaretVisible, 50) } } } @@ -17877,49 +15599,39 @@ gui.CaretManager = function CaretManager(sessionController) { } } this.registerCursor = function(cursor, caretAvatarInitiallyVisible, blinkOnRangeSelect) { - var memberid = cursor.getMemberId(), caret = new gui.Caret(cursor, caretAvatarInitiallyVisible, blinkOnRangeSelect); + var memberid = cursor.getMemberId(), caret = new gui.Caret(cursor, caretAvatarInitiallyVisible, blinkOnRangeSelect), eventManager = sessionController.getEventManager(); carets[memberid] = caret; if(memberid === sessionController.getInputMemberId()) { runtime.log("Starting to track input on new cursor of " + memberid); - cursor.handleUpdate = scheduleCaretVisibilityCheck; - getCanvasElement().setAttribute("tabindex", -1); - sessionController.getEventManager().focus() + cursor.subscribe(ops.OdtCursor.signalCursorUpdated, scheduleCaretVisibilityCheck); + caret.setOverlayElement(eventManager.getEventTrap()) }else { - cursor.handleUpdate = caret.handleUpdate + cursor.subscribe(ops.OdtCursor.signalCursorUpdated, caret.handleUpdate) } return caret }; this.getCaret = getCaret; this.getCarets = getCarets; this.destroy = function(callback) { - var odtDocument = sessionController.getSession().getOdtDocument(), eventManager = sessionController.getEventManager(), caretArray = getCarets(); + var odtDocument = sessionController.getSession().getOdtDocument(), eventManager = sessionController.getEventManager(), caretCleanup = getCarets().map(function(caret) { + return caret.destroy + }); + runtime.clearTimeout(ensureCaretVisibleTimeoutId); odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, ensureLocalCaretVisible); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, refreshLocalCaretBlinking); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, removeCaret); + odtDocument.unsubscribe(ops.Document.signalCursorMoved, refreshLocalCaretBlinking); + odtDocument.unsubscribe(ops.Document.signalCursorRemoved, removeCaret); eventManager.unsubscribe("focus", focusLocalCaret); eventManager.unsubscribe("blur", blurLocalCaret); window.removeEventListener("focus", showLocalCaret, false); window.removeEventListener("blur", hideLocalCaret, false); - (function destroyCaret(i, err) { - if(err) { - callback(err) - }else { - if(i < caretArray.length) { - caretArray[i].destroy(function(err) { - destroyCaret(i + 1, err) - }) - }else { - callback() - } - } - })(0, undefined); - carets = {} + carets = {}; + async.destroyAll(caretCleanup, callback) }; function init() { var odtDocument = sessionController.getSession().getOdtDocument(), eventManager = sessionController.getEventManager(); odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, ensureLocalCaretVisible); - odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, refreshLocalCaretBlinking); - odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, removeCaret); + odtDocument.subscribe(ops.Document.signalCursorMoved, refreshLocalCaretBlinking); + odtDocument.subscribe(ops.Document.signalCursorRemoved, removeCaret); eventManager.subscribe("focus", focusLocalCaret); eventManager.subscribe("blur", blurLocalCaret); window.addEventListener("focus", showLocalCaret, false); @@ -17927,6 +15639,406 @@ gui.CaretManager = function CaretManager(sessionController) { } init() }; +gui.EditInfoHandle = function EditInfoHandle(parentElement) { + var edits = [], handle, document = (parentElement.ownerDocument), htmlns = document.documentElement.namespaceURI, editinfons = "urn:webodf:names:editinfo"; + function renderEdits() { + var i, infoDiv, colorSpan, authorSpan, timeSpan; + handle.innerHTML = ""; + for(i = 0;i < edits.length;i += 1) { + infoDiv = document.createElementNS(htmlns, "div"); + infoDiv.className = "editInfo"; + colorSpan = document.createElementNS(htmlns, "span"); + colorSpan.className = "editInfoColor"; + colorSpan.setAttributeNS(editinfons, "editinfo:memberid", edits[i].memberid); + authorSpan = document.createElementNS(htmlns, "span"); + authorSpan.className = "editInfoAuthor"; + authorSpan.setAttributeNS(editinfons, "editinfo:memberid", edits[i].memberid); + timeSpan = document.createElementNS(htmlns, "span"); + timeSpan.className = "editInfoTime"; + timeSpan.setAttributeNS(editinfons, "editinfo:memberid", edits[i].memberid); + timeSpan.innerHTML = edits[i].time; + infoDiv.appendChild(colorSpan); + infoDiv.appendChild(authorSpan); + infoDiv.appendChild(timeSpan); + handle.appendChild(infoDiv) + } + } + this.setEdits = function(editArray) { + edits = editArray; + renderEdits() + }; + this.show = function() { + handle.style.display = "block" + }; + this.hide = function() { + handle.style.display = "none" + }; + this.destroy = function(callback) { + parentElement.removeChild(handle); + callback() + }; + function init() { + handle = (document.createElementNS(htmlns, "div")); + handle.setAttribute("class", "editInfoHandle"); + handle.style.display = "none"; + parentElement.appendChild(handle) + } + init() +}; +/* + + Copyright (C) 2012 KO GmbH <aditya.bhatt@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/ +*/ +ops.EditInfo = function EditInfo(container, odtDocument) { + var editInfoNode, editHistory = {}; + function sortEdits() { + var arr = [], memberid; + for(memberid in editHistory) { + if(editHistory.hasOwnProperty(memberid)) { + arr.push({"memberid":memberid, "time":editHistory[memberid].time}) + } + } + arr.sort(function(a, b) { + return a.time - b.time + }); + return arr + } + this.getNode = function() { + return editInfoNode + }; + this.getOdtDocument = function() { + return odtDocument + }; + this.getEdits = function() { + return editHistory + }; + this.getSortedEdits = function() { + return sortEdits() + }; + this.addEdit = function(memberid, timestamp) { + editHistory[memberid] = {time:timestamp} + }; + this.clearEdits = function() { + editHistory = {} + }; + this.destroy = function(callback) { + if(container.parentNode) { + container.removeChild(editInfoNode) + } + callback() + }; + function init() { + var editInfons = "urn:webodf:names:editinfo", dom = odtDocument.getDOMDocument(); + editInfoNode = dom.createElementNS(editInfons, "editinfo"); + container.insertBefore(editInfoNode, container.firstChild) + } + init() +}; +/* + + Copyright (C) 2012-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/ +*/ +gui.EditInfoMarker = function EditInfoMarker(editInfo, initialVisibility) { + var self = this, editInfoNode, handle, marker, editinfons = "urn:webodf:names:editinfo", decayTimer0, decayTimer1, decayTimer2, decayTimeStep = 1E4; + function applyDecay(opacity, delay) { + return runtime.setTimeout(function() { + marker.style.opacity = opacity + }, delay) + } + function deleteDecay(timerId) { + runtime.clearTimeout(timerId) + } + function setLastAuthor(memberid) { + marker.setAttributeNS(editinfons, "editinfo:memberid", memberid) + } + this.addEdit = function(memberid, timestamp) { + var age = Date.now() - timestamp; + editInfo.addEdit(memberid, timestamp); + handle.setEdits(editInfo.getSortedEdits()); + setLastAuthor(memberid); + deleteDecay(decayTimer1); + deleteDecay(decayTimer2); + if(age < decayTimeStep) { + decayTimer0 = applyDecay(1, 0); + decayTimer1 = applyDecay(0.5, decayTimeStep - age); + decayTimer2 = applyDecay(0.2, decayTimeStep * 2 - age) + }else { + if(age >= decayTimeStep && age < decayTimeStep * 2) { + decayTimer0 = applyDecay(0.5, 0); + decayTimer2 = applyDecay(0.2, decayTimeStep * 2 - age) + }else { + decayTimer0 = applyDecay(0.2, 0) + } + } + }; + this.getEdits = function() { + return editInfo.getEdits() + }; + this.clearEdits = function() { + editInfo.clearEdits(); + handle.setEdits([]); + if(marker.hasAttributeNS(editinfons, "editinfo:memberid")) { + marker.removeAttributeNS(editinfons, "editinfo:memberid") + } + }; + this.getEditInfo = function() { + return editInfo + }; + this.show = function() { + marker.style.display = "block" + }; + this.hide = function() { + self.hideHandle(); + marker.style.display = "none" + }; + this.showHandle = function() { + handle.show() + }; + this.hideHandle = function() { + handle.hide() + }; + this.destroy = function(callback) { + deleteDecay(decayTimer0); + deleteDecay(decayTimer1); + deleteDecay(decayTimer2); + editInfoNode.removeChild(marker); + handle.destroy(function(err) { + if(err) { + callback(err) + }else { + editInfo.destroy(callback) + } + }) + }; + function init() { + var dom = editInfo.getOdtDocument().getDOMDocument(), htmlns = dom.documentElement.namespaceURI; + marker = (dom.createElementNS(htmlns, "div")); + marker.setAttribute("class", "editInfoMarker"); + marker.onmouseover = function() { + self.showHandle() + }; + marker.onmouseout = function() { + self.hideHandle() + }; + editInfoNode = editInfo.getNode(); + editInfoNode.appendChild(marker); + handle = new gui.EditInfoHandle(editInfoNode); + if(!initialVisibility) { + self.hide() + } + } + init() +}; +gui.ShadowCursor = function ShadowCursor(document) { + var selectedRange = (document.getDOMDocument().createRange()), forwardSelection = true; + this.removeFromDocument = function() { + }; + this.getMemberId = function() { + return gui.ShadowCursor.ShadowCursorMemberId + }; + this.getSelectedRange = function() { + return selectedRange + }; + this.setSelectedRange = function(range, isForwardSelection) { + selectedRange = range; + forwardSelection = isForwardSelection !== false + }; + this.hasForwardSelection = function() { + return forwardSelection + }; + this.getDocument = function() { + return document + }; + this.getSelectionType = function() { + return ops.OdtCursor.RangeSelection + }; + function init() { + selectedRange.setStart(document.getRootNode(), 0) + } + init() +}; +gui.ShadowCursor.ShadowCursorMemberId = ""; +(function() { + return gui.ShadowCursor +})(); +gui.SelectionView = function SelectionView(cursor) { +}; +gui.SelectionView.prototype.rerender = function() { +}; +gui.SelectionView.prototype.show = function() { +}; +gui.SelectionView.prototype.hide = function() { +}; +gui.SelectionView.prototype.destroy = function(callback) { +}; +/* + + 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/ +*/ +gui.SelectionViewManager = function SelectionViewManager(SelectionView) { + var selectionViews = {}; + function getSelectionView(memberId) { + return selectionViews.hasOwnProperty(memberId) ? selectionViews[memberId] : null + } + this.getSelectionView = getSelectionView; + function getSelectionViews() { + return Object.keys(selectionViews).map(function(memberid) { + return selectionViews[memberid] + }) + } + this.getSelectionViews = getSelectionViews; + function removeSelectionView(memberId) { + if(selectionViews.hasOwnProperty(memberId)) { + selectionViews[memberId].destroy(function() { + }); + delete selectionViews[memberId] + } + } + this.removeSelectionView = removeSelectionView; + function hideSelectionView(memberId) { + if(selectionViews.hasOwnProperty(memberId)) { + selectionViews[memberId].hide() + } + } + this.hideSelectionView = hideSelectionView; + function showSelectionView(memberId) { + if(selectionViews.hasOwnProperty(memberId)) { + selectionViews[memberId].show() + } + } + this.showSelectionView = showSelectionView; + this.rerenderSelectionViews = function() { + Object.keys(selectionViews).forEach(function(memberId) { + selectionViews[memberId].rerender() + }) + }; + this.registerCursor = function(cursor, virtualSelectionsInitiallyVisible) { + var memberId = cursor.getMemberId(), selectionView = new SelectionView(cursor); + if(virtualSelectionsInitiallyVisible) { + selectionView.show() + }else { + selectionView.hide() + } + selectionViews[memberId] = selectionView; + return selectionView + }; + this.destroy = function(callback) { + var selectionViewArray = getSelectionViews(); + function destroySelectionView(i, err) { + if(err) { + callback(err) + }else { + if(i < selectionViewArray.length) { + selectionViewArray[i].destroy(function(err) { + destroySelectionView(i + 1, err) + }) + }else { + callback() + } + } + } + destroySelectionView(0, undefined) + } +}; /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -17964,27 +16076,24 @@ gui.CaretManager = function CaretManager(sessionController) { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("gui.Caret"); -runtime.loadClass("ops.EditInfo"); -runtime.loadClass("gui.EditInfoMarker"); gui.SessionViewOptions = function() { this.editInfoMarkersInitiallyVisible = true; this.caretAvatarsInitiallyVisible = true; this.caretBlinksOnRangeSelect = true }; -gui.SessionView = function() { +(function() { function configOption(userValue, defaultValue) { return userValue !== undefined ? Boolean(userValue) : defaultValue } - function SessionView(viewOptions, localMemberId, session, caretManager, selectionViewManager) { - var avatarInfoStyles, editInfons = "urn:webodf:names:editinfo", editInfoMap = {}, showEditInfoMarkers = configOption(viewOptions.editInfoMarkersInitiallyVisible, true), showCaretAvatars = configOption(viewOptions.caretAvatarsInitiallyVisible, true), blinkOnRangeSelect = configOption(viewOptions.caretBlinksOnRangeSelect, true), rerenderIntervalId, rerenderSelectionViews = false, RERENDER_INTERVAL = 200; + gui.SessionView = function SessionView(viewOptions, localMemberId, session, caretManager, selectionViewManager) { + var avatarInfoStyles, editInfons = "urn:webodf:names:editinfo", editInfoMap = {}, showEditInfoMarkers = configOption(viewOptions.editInfoMarkersInitiallyVisible, true), showCaretAvatars = configOption(viewOptions.caretAvatarsInitiallyVisible, true), blinkOnRangeSelect = configOption(viewOptions.caretBlinksOnRangeSelect, true); function createAvatarInfoNodeMatch(nodeName, memberId, pseudoClass) { return nodeName + '[editinfo|memberid="' + memberId + '"]' + pseudoClass } function getAvatarInfoStyle(nodeName, memberId, pseudoClass) { var node = avatarInfoStyles.firstChild, nodeMatch = createAvatarInfoNodeMatch(nodeName, memberId, pseudoClass) + "{"; while(node) { - if(node.nodeType === Node.TEXT_NODE && node.data.indexOf(nodeMatch) === 0) { + if(node.nodeType === Node.TEXT_NODE && (node).data.indexOf(nodeMatch) === 0) { return node } node = node.nextSibling @@ -18004,18 +16113,18 @@ gui.SessionView = function() { setStyle("span.editInfoColor", "{ background-color: " + color + "; }", ""); setStyle("span.editInfoAuthor", '{ content: "' + name + '"; }', ":before"); setStyle("dc|creator", "{ background-color: " + color + "; }", ""); - setStyle("div.selectionOverlay", "{ background-color: " + color + ";}", "") + setStyle(".selectionOverlay", "{ fill: " + color + "; stroke: " + color + ";}", "") } function highlightEdit(element, memberId, timestamp) { - var editInfo, editInfoMarker, id = "", editInfoNode = element.getElementsByTagNameNS(editInfons, "editinfo")[0]; + var editInfo, editInfoMarker, id = "", editInfoNode = element.getElementsByTagNameNS(editInfons, "editinfo").item(0); if(editInfoNode) { - id = editInfoNode.getAttributeNS(editInfons, "id"); + id = (editInfoNode).getAttributeNS(editInfons, "id"); editInfoMarker = editInfoMap[id] }else { id = Math.random().toString(); editInfo = new ops.EditInfo(element, session.getOdtDocument()); editInfoMarker = new gui.EditInfoMarker(editInfo, showEditInfoMarkers); - editInfoNode = element.getElementsByTagNameNS(editInfons, "editinfo")[0]; + editInfoNode = (element.getElementsByTagNameNS(editInfons, "editinfo").item(0)); editInfoNode.setAttributeNS(editInfons, "id", id); editInfoMap[id] = editInfoMarker } @@ -18123,34 +16232,19 @@ gui.SessionView = function() { function onParagraphChanged(info) { highlightEdit(info.paragraphElement, info.memberId, info.timeStamp) } - function requestRerenderOfSelectionViews() { - rerenderSelectionViews = true - } - function startRerenderLoop() { - rerenderIntervalId = runtime.getWindow().setInterval(function() { - if(rerenderSelectionViews) { - selectionViewManager.rerenderSelectionViews(); - rerenderSelectionViews = false - } - }, RERENDER_INTERVAL) - } - function stopRerenderLoop() { - runtime.getWindow().clearInterval(rerenderIntervalId) - } this.destroy = function(callback) { var odtDocument = session.getOdtDocument(), editInfoArray = Object.keys(editInfoMap).map(function(keyname) { return editInfoMap[keyname] }); - odtDocument.unsubscribe(ops.OdtDocument.signalMemberAdded, renderMemberData); - odtDocument.unsubscribe(ops.OdtDocument.signalMemberUpdated, renderMemberData); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); + odtDocument.unsubscribe(ops.Document.signalMemberAdded, renderMemberData); + odtDocument.unsubscribe(ops.Document.signalMemberUpdated, renderMemberData); + odtDocument.unsubscribe(ops.Document.signalCursorAdded, onCursorAdded); + odtDocument.unsubscribe(ops.Document.signalCursorRemoved, onCursorRemoved); odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); - odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, requestRerenderOfSelectionViews); - odtDocument.unsubscribe(ops.OdtDocument.signalTableAdded, requestRerenderOfSelectionViews); - odtDocument.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, requestRerenderOfSelectionViews); - stopRerenderLoop(); + odtDocument.unsubscribe(ops.Document.signalCursorMoved, onCursorMoved); + odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, selectionViewManager.rerenderSelectionViews); + odtDocument.unsubscribe(ops.OdtDocument.signalTableAdded, selectionViewManager.rerenderSelectionViews); + odtDocument.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, selectionViewManager.rerenderSelectionViews); avatarInfoStyles.parentNode.removeChild(avatarInfoStyles); (function destroyEditInfo(i, err) { if(err) { @@ -18167,18 +16261,17 @@ gui.SessionView = function() { })(0, undefined) }; function init() { - var odtDocument = session.getOdtDocument(), head = document.getElementsByTagName("head")[0]; - odtDocument.subscribe(ops.OdtDocument.signalMemberAdded, renderMemberData); - odtDocument.subscribe(ops.OdtDocument.signalMemberUpdated, renderMemberData); - odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); - odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); + var odtDocument = session.getOdtDocument(), head = document.getElementsByTagName("head").item(0); + odtDocument.subscribe(ops.Document.signalMemberAdded, renderMemberData); + odtDocument.subscribe(ops.Document.signalMemberUpdated, renderMemberData); + odtDocument.subscribe(ops.Document.signalCursorAdded, onCursorAdded); + odtDocument.subscribe(ops.Document.signalCursorRemoved, onCursorRemoved); odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); - odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); - startRerenderLoop(); - odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, requestRerenderOfSelectionViews); - odtDocument.subscribe(ops.OdtDocument.signalTableAdded, requestRerenderOfSelectionViews); - odtDocument.subscribe(ops.OdtDocument.signalParagraphStyleModified, requestRerenderOfSelectionViews); - avatarInfoStyles = document.createElementNS(head.namespaceURI, "style"); + odtDocument.subscribe(ops.Document.signalCursorMoved, onCursorMoved); + odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, selectionViewManager.rerenderSelectionViews); + odtDocument.subscribe(ops.OdtDocument.signalTableAdded, selectionViewManager.rerenderSelectionViews); + odtDocument.subscribe(ops.OdtDocument.signalParagraphStyleModified, selectionViewManager.rerenderSelectionViews); + avatarInfoStyles = (document.createElementNS(head.namespaceURI, "style")); avatarInfoStyles.type = "text/css"; avatarInfoStyles.media = "screen, print, handheld, projection"; avatarInfoStyles.appendChild(document.createTextNode("@namespace editinfo url(urn:webodf:names:editinfo);")); @@ -18187,7 +16280,1395 @@ gui.SessionView = function() { } init() } - return SessionView -}(); -var webodf_css = "@namespace draw url(urn:oasis:names:tc:opendocument:xmlns:drawing:1.0);\n@namespace fo url(urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0);\n@namespace office url(urn:oasis:names:tc:opendocument:xmlns:office:1.0);\n@namespace presentation url(urn:oasis:names:tc:opendocument:xmlns:presentation:1.0);\n@namespace style url(urn:oasis:names:tc:opendocument:xmlns:style:1.0);\n@namespace svg url(urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0);\n@namespace table url(urn:oasis:names:tc:opendocument:xmlns:table:1.0);\n@namespace text url(urn:oasis:names:tc:opendocument:xmlns:text:1.0);\n@namespace webodfhelper url(urn:webodf:names:helper);\n@namespace cursor url(urn:webodf:names:cursor);\n@namespace editinfo url(urn:webodf:names:editinfo);\n@namespace annotation url(urn:webodf:names:annotation);\n@namespace dc url(http://purl.org/dc/elements/1.1/);\n\noffice|document > *, office|document-content > * {\n display: none;\n}\noffice|body, office|document {\n display: inline-block;\n position: relative;\n}\n\ntext|p, text|h {\n display: block;\n padding: 0;\n margin: 0;\n line-height: normal;\n position: relative;\n min-height: 1.3em; /* prevent empty paragraphs and headings from collapsing if they are empty */\n}\n*[webodfhelper|containsparagraphanchor] {\n position: relative;\n}\ntext|s {\n white-space: pre;\n}\ntext|tab {\n display: inline;\n white-space: pre;\n}\ntext|tracked-changes {\n /*Consumers that do not support change tracking, should ignore changes.*/\n display: none;\n}\noffice|binary-data {\n display: none;\n}\noffice|text {\n display: block;\n text-align: left;\n overflow: visible;\n word-wrap: break-word;\n}\n\noffice|text::selection {\n /** Let's not draw selection highlight that overflows into the office|text\n * node when selecting content across several paragraphs\n */\n background: transparent;\n}\n\n.virtualSelections office|document *::selection {\n background: transparent;\n}\n.virtualSelections office|document *::-moz-selection {\n background: transparent;\n}\n\noffice|text * draw|text-box {\n/** only for text documents */\n display: block;\n border: 1px solid #d3d3d3;\n}\noffice|spreadsheet {\n display: block;\n border-collapse: collapse;\n empty-cells: show;\n font-family: sans-serif;\n font-size: 10pt;\n text-align: left;\n page-break-inside: avoid;\n overflow: hidden;\n}\noffice|presentation {\n display: inline-block;\n text-align: left;\n}\n#shadowContent {\n display: inline-block;\n text-align: left;\n}\ndraw|page {\n display: block;\n position: relative;\n overflow: hidden;\n}\npresentation|notes, presentation|footer-decl, presentation|date-time-decl {\n display: none;\n}\n@media print {\n draw|page {\n border: 1pt solid black;\n page-break-inside: avoid;\n }\n presentation|notes {\n /*TODO*/\n }\n}\noffice|spreadsheet text|p {\n border: 0px;\n padding: 1px;\n margin: 0px;\n}\noffice|spreadsheet table|table {\n margin: 3px;\n}\noffice|spreadsheet table|table:after {\n /* show sheet name the end of the sheet */\n /*content: attr(table|name);*/ /* gives parsing error in opera */\n}\noffice|spreadsheet table|table-row {\n counter-increment: row;\n}\noffice|spreadsheet table|table-row:before {\n width: 3em;\n background: #cccccc;\n border: 1px solid black;\n text-align: center;\n content: counter(row);\n display: table-cell;\n}\noffice|spreadsheet table|table-cell {\n border: 1px solid #cccccc;\n}\ntable|table {\n display: table;\n}\ndraw|frame table|table {\n width: 100%;\n height: 100%;\n background: white;\n}\ntable|table-header-rows {\n display: table-header-group;\n}\ntable|table-row {\n display: table-row;\n}\ntable|table-column {\n display: table-column;\n}\ntable|table-cell {\n width: 0.889in;\n display: table-cell;\n word-break: break-all; /* prevent long words from extending out the table cell */\n}\ndraw|frame {\n display: block;\n}\ndraw|image {\n display: block;\n width: 100%;\n height: 100%;\n top: 0px;\n left: 0px;\n background-repeat: no-repeat;\n background-size: 100% 100%;\n -moz-background-size: 100% 100%;\n}\n/* only show the first image in frame */\ndraw|frame > draw|image:nth-of-type(n+2) {\n display: none;\n}\ntext|list:before {\n display: none;\n content:\"\";\n}\ntext|list {\n counter-reset: list;\n}\ntext|list-item {\n display: block;\n}\ntext|number {\n display:none;\n}\n\ntext|a {\n color: blue;\n text-decoration: underline;\n cursor: pointer;\n}\ntext|note-citation {\n vertical-align: super;\n font-size: smaller;\n}\ntext|note-body {\n display: none;\n}\ntext|note:hover text|note-citation {\n background: #dddddd;\n}\ntext|note:hover text|note-body {\n display: block;\n left:1em;\n max-width: 80%;\n position: absolute;\n background: #ffffaa;\n}\nsvg|title, svg|desc {\n display: none;\n}\nvideo {\n width: 100%;\n height: 100%\n}\n\n/* below set up the cursor */\ncursor|cursor {\n display: inline;\n width: 0px;\n height: 1em;\n /* making the position relative enables the avatar to use\n the cursor as reference for its absolute position */\n position: relative;\n z-index: 1;\n}\ncursor|cursor > span {\n /* IMPORTANT: when changing these values ensure DEFAULT_CARET_TOP and DEFAULT_CARET_HEIGHT\n in Caret.js remain in sync */\n display: inline;\n position: absolute;\n top: 5%; /* push down the caret; 0px can do the job, 5% looks better, 10% is a bit over */\n height: 1em;\n border-left: 2px solid black;\n outline: none;\n}\n\ncursor|cursor > div {\n padding: 3px;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n border: none !important;\n border-radius: 5px;\n opacity: 0.3;\n}\n\ncursor|cursor > div > img {\n border-radius: 5px;\n}\n\ncursor|cursor > div.active {\n opacity: 0.8;\n}\n\ncursor|cursor > div:after {\n content: ' ';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 43%;\n}\n\n\n.editInfoMarker {\n position: absolute;\n width: 10px;\n height: 100%;\n left: -20px;\n opacity: 0.8;\n top: 0;\n border-radius: 5px;\n background-color: transparent;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n}\n.editInfoMarker:hover {\n box-shadow: 0px 0px 8px rgba(0, 0, 0, 1);\n}\n\n.editInfoHandle {\n position: absolute;\n background-color: black;\n padding: 5px;\n border-radius: 5px;\n opacity: 0.8;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n bottom: 100%;\n margin-bottom: 10px;\n z-index: 3;\n left: -25px;\n}\n.editInfoHandle:after {\n content: ' ';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 5px;\n}\n.editInfo {\n font-family: sans-serif;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n color: white;\n width: 100%;\n height: 12pt;\n}\n.editInfoColor {\n float: left;\n width: 10pt;\n height: 10pt;\n border: 1px solid white;\n}\n.editInfoAuthor {\n float: left;\n margin-left: 5pt;\n font-size: 10pt;\n text-align: left;\n height: 12pt;\n line-height: 12pt;\n}\n.editInfoTime {\n float: right;\n margin-left: 30pt;\n font-size: 8pt;\n font-style: italic;\n color: yellow;\n height: 12pt;\n line-height: 12pt;\n}\n\n.annotationWrapper {\n display: inline;\n position: relative;\n}\n\n.annotationRemoveButton:before {\n content: '\u00d7';\n color: white;\n padding: 5px;\n line-height: 1em;\n}\n\n.annotationRemoveButton {\n width: 20px;\n height: 20px;\n border-radius: 10px;\n background-color: black;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n position: absolute;\n top: -10px;\n left: -10px;\n z-index: 3;\n text-align: center;\n font-family: sans-serif;\n font-style: normal;\n font-weight: normal;\n text-decoration: none;\n font-size: 15px;\n}\n.annotationRemoveButton:hover {\n cursor: pointer;\n box-shadow: 0px 0px 5px rgba(0, 0, 0, 1);\n}\n\n.annotationNote {\n width: 4cm;\n position: absolute;\n display: inline;\n z-index: 10;\n}\n.annotationNote > office|annotation {\n display: block;\n text-align: left;\n}\n\n.annotationConnector {\n position: absolute;\n display: inline;\n z-index: 2;\n border-top: 1px dashed brown;\n}\n.annotationConnector.angular {\n -moz-transform-origin: left top;\n -webkit-transform-origin: left top;\n -ms-transform-origin: left top;\n transform-origin: left top;\n}\n.annotationConnector.horizontal {\n left: 0;\n}\n.annotationConnector.horizontal:before {\n content: '';\n display: inline;\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: brown transparent transparent transparent;\n top: -1px;\n left: -5px;\n}\n\noffice|annotation {\n width: 100%;\n height: 100%;\n display: none;\n background: rgb(198, 238, 184);\n background: -moz-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -webkit-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -o-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -ms-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: linear-gradient(180deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n box-shadow: 0 3px 4px -3px #ccc;\n}\n\noffice|annotation > dc|creator {\n display: block;\n font-size: 10pt;\n font-weight: normal;\n font-style: normal;\n font-family: sans-serif;\n color: white;\n background-color: brown;\n padding: 4px;\n}\noffice|annotation > dc|date {\n display: block;\n font-size: 10pt;\n font-weight: normal;\n font-style: normal;\n font-family: sans-serif;\n border: 4px solid transparent;\n}\noffice|annotation > text|list {\n display: block;\n padding: 5px;\n}\n\n/* This is very temporary CSS. This must go once\n * we start bundling webodf-default ODF styles for annotations.\n */\noffice|annotation text|p {\n font-size: 10pt;\n color: black;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n font-family: sans-serif;\n}\n\ndc|*::selection {\n background: transparent;\n}\ndc|*::-moz-selection {\n background: transparent;\n}\n\n#annotationsPane {\n background-color: #EAEAEA;\n width: 4cm;\n height: 100%;\n display: none;\n position: absolute;\n outline: 1px solid #ccc;\n}\n\n.annotationHighlight {\n background-color: yellow;\n position: relative;\n}\n\n.selectionOverlay {\n position: absolute;\n z-index: 15;\n opacity: 0.2;\n pointer-events: none;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n}\n\n#imageSelector {\n display: none;\n position: absolute;\n border-style: solid;\n border-color: black;\n}\n\n#imageSelector > div {\n width: 5px;\n height: 5px;\n display: block;\n position: absolute;\n border: 1px solid black;\n background-color: #ffffff;\n}\n\n#imageSelector > .topLeft {\n top: -4px;\n left: -4px;\n}\n\n#imageSelector > .topRight {\n top: -4px;\n right: -4px;\n}\n\n#imageSelector > .bottomRight {\n right: -4px;\n bottom: -4px;\n}\n\n#imageSelector > .bottomLeft {\n bottom: -4px;\n left: -4px;\n}\n\n#imageSelector > .topMiddle {\n top: -4px;\n left: 50%;\n margin-left: -2.5px; /* half of the width defined in #imageSelector > div */\n}\n\n#imageSelector > .rightMiddle {\n top: 50%;\n right: -4px;\n margin-top: -2.5px; /* half of the height defined in #imageSelector > div */\n}\n\n#imageSelector > .bottomMiddle {\n bottom: -4px;\n left: 50%;\n margin-left: -2.5px; /* half of the width defined in #imageSelector > div */\n}\n\n#imageSelector > .leftMiddle {\n top: 50%;\n left: -4px;\n margin-top: -2.5px; /* half of the height defined in #imageSelector > div */\n}\n"; +})(); +gui.SvgSelectionView = function SvgSelectionView(cursor) { + var document = cursor.getDocument(), documentRoot, root, doc = document.getDOMDocument(), async = new core.Async, svgns = "http://www.w3.org/2000/svg", overlay = doc.createElementNS(svgns, "svg"), polygon = doc.createElementNS(svgns, "polygon"), odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils, isVisible = true, positionIterator = gui.SelectionMover.createPositionIterator(document.getRootNode()), FILTER_ACCEPT = NodeFilter.FILTER_ACCEPT, FILTER_REJECT = NodeFilter.FILTER_REJECT, renderTask; + function addOverlay() { + var newDocumentRoot = document.getRootNode(); + if(documentRoot !== newDocumentRoot) { + documentRoot = newDocumentRoot; + root = (documentRoot.parentNode.parentNode.parentNode); + root.appendChild(overlay); + overlay.setAttribute("class", "selectionOverlay"); + overlay.appendChild(polygon) + } + } + function translateRect(rect) { + var rootRect = domUtils.getBoundingClientRect(root), zoomLevel = document.getCanvas().getZoomLevel(), resultRect = {}; + resultRect.top = domUtils.adaptRangeDifferenceToZoomLevel(rect.top - rootRect.top, zoomLevel); + resultRect.left = domUtils.adaptRangeDifferenceToZoomLevel(rect.left - rootRect.left, zoomLevel); + resultRect.bottom = domUtils.adaptRangeDifferenceToZoomLevel(rect.bottom - rootRect.top, zoomLevel); + resultRect.right = domUtils.adaptRangeDifferenceToZoomLevel(rect.right - rootRect.left, zoomLevel); + resultRect.width = domUtils.adaptRangeDifferenceToZoomLevel(rect.width, zoomLevel); + resultRect.height = domUtils.adaptRangeDifferenceToZoomLevel(rect.height, zoomLevel); + return resultRect + } + function isRangeVisible(range) { + var bcr = range.getBoundingClientRect(); + return Boolean(bcr && bcr.height !== 0) + } + function lastVisibleRect(range, nodes) { + var nextNodeIndex = nodes.length - 1, node = nodes[nextNodeIndex], startOffset, endOffset; + if(range.endContainer === node) { + startOffset = range.endOffset + }else { + if(node.nodeType === Node.TEXT_NODE) { + startOffset = node.length + }else { + startOffset = node.childNodes.length + } + } + endOffset = startOffset; + range.setStart(node, startOffset); + range.setEnd(node, endOffset); + while(!isRangeVisible(range)) { + if(node.nodeType === Node.ELEMENT_NODE && startOffset > 0) { + startOffset = 0 + }else { + if(node.nodeType === Node.TEXT_NODE && startOffset > 0) { + startOffset -= 1 + }else { + if(nodes[nextNodeIndex]) { + node = nodes[nextNodeIndex]; + nextNodeIndex -= 1; + startOffset = endOffset = node.length || node.childNodes.length + }else { + return false + } + } + } + range.setStart(node, startOffset); + range.setEnd(node, endOffset) + } + return true + } + function firstVisibleRect(range, nodes) { + var nextNodeIndex = 0, node = nodes[nextNodeIndex], startOffset = range.startContainer === node ? range.startOffset : 0, endOffset = startOffset; + range.setStart(node, startOffset); + range.setEnd(node, endOffset); + while(!isRangeVisible(range)) { + if(node.nodeType === Node.ELEMENT_NODE && endOffset < node.childNodes.length) { + endOffset = node.childNodes.length + }else { + if(node.nodeType === Node.TEXT_NODE && endOffset < node.length) { + endOffset += 1 + }else { + if(nodes[nextNodeIndex]) { + node = nodes[nextNodeIndex]; + nextNodeIndex += 1; + startOffset = endOffset = 0 + }else { + return false + } + } + } + range.setStart(node, startOffset); + range.setEnd(node, endOffset) + } + return true + } + function getExtremeRanges(range) { + var nodes = odfUtils.getTextElements(range, true, false), firstRange = (range.cloneRange()), lastRange = (range.cloneRange()), fillerRange = range.cloneRange(); + if(!nodes.length) { + return null + } + if(!firstVisibleRect(firstRange, nodes)) { + return null + } + if(!lastVisibleRect(lastRange, nodes)) { + return null + } + fillerRange.setStart(firstRange.startContainer, firstRange.startOffset); + fillerRange.setEnd(lastRange.endContainer, lastRange.endOffset); + return{firstRange:firstRange, lastRange:lastRange, fillerRange:fillerRange} + } + function getBoundingRect(rect1, rect2) { + var resultRect = {}; + resultRect.top = Math.min(rect1.top, rect2.top); + resultRect.left = Math.min(rect1.left, rect2.left); + resultRect.right = Math.max(rect1.right, rect2.right); + resultRect.bottom = Math.max(rect1.bottom, rect2.bottom); + resultRect.width = resultRect.right - resultRect.left; + resultRect.height = resultRect.bottom - resultRect.top; + return resultRect + } + function checkAndGrowOrCreateRect(originalRect, newRect) { + if(newRect && (newRect.width > 0 && newRect.height > 0)) { + if(!originalRect) { + originalRect = newRect + }else { + originalRect = getBoundingRect(originalRect, newRect) + } + } + return originalRect + } + function getFillerRect(fillerRange) { + var containerNode = fillerRange.commonAncestorContainer, firstNode = (fillerRange.startContainer), lastNode = (fillerRange.endContainer), firstOffset = fillerRange.startOffset, lastOffset = fillerRange.endOffset, currentNode, lastMeasuredNode, firstSibling, lastSibling, grownRect = null, currentRect, range = doc.createRange(), rootFilter, odfNodeFilter = new odf.OdfNodeFilter, treeWalker; + function acceptNode(node) { + positionIterator.setUnfilteredPosition(node, 0); + if(odfNodeFilter.acceptNode(node) === FILTER_ACCEPT && rootFilter.acceptPosition(positionIterator) === FILTER_ACCEPT) { + return FILTER_ACCEPT + } + return FILTER_REJECT + } + function getRectFromNodeAfterFiltering(node) { + var rect = null; + if(acceptNode(node) === FILTER_ACCEPT) { + rect = domUtils.getBoundingClientRect(node) + } + return rect + } + if(firstNode === containerNode || lastNode === containerNode) { + range = fillerRange.cloneRange(); + grownRect = range.getBoundingClientRect(); + range.detach(); + return grownRect + } + firstSibling = firstNode; + while(firstSibling.parentNode !== containerNode) { + firstSibling = firstSibling.parentNode + } + lastSibling = lastNode; + while(lastSibling.parentNode !== containerNode) { + lastSibling = lastSibling.parentNode + } + rootFilter = document.createRootFilter(firstNode); + currentNode = firstSibling.nextSibling; + while(currentNode && currentNode !== lastSibling) { + currentRect = getRectFromNodeAfterFiltering(currentNode); + grownRect = checkAndGrowOrCreateRect(grownRect, currentRect); + currentNode = currentNode.nextSibling + } + if(odfUtils.isParagraph(firstSibling)) { + grownRect = checkAndGrowOrCreateRect(grownRect, domUtils.getBoundingClientRect(firstSibling)) + }else { + if(firstSibling.nodeType === Node.TEXT_NODE) { + currentNode = firstSibling; + range.setStart(currentNode, firstOffset); + range.setEnd(currentNode, currentNode === lastSibling ? lastOffset : (currentNode).length); + currentRect = range.getBoundingClientRect(); + grownRect = checkAndGrowOrCreateRect(grownRect, currentRect) + }else { + treeWalker = doc.createTreeWalker(firstSibling, NodeFilter.SHOW_TEXT, acceptNode, false); + currentNode = treeWalker.currentNode = firstNode; + while(currentNode && currentNode !== lastNode) { + range.setStart(currentNode, firstOffset); + range.setEnd(currentNode, (currentNode).length); + currentRect = range.getBoundingClientRect(); + grownRect = checkAndGrowOrCreateRect(grownRect, currentRect); + lastMeasuredNode = currentNode; + firstOffset = 0; + currentNode = treeWalker.nextNode() + } + } + } + if(!lastMeasuredNode) { + lastMeasuredNode = firstNode + } + if(odfUtils.isParagraph(lastSibling)) { + grownRect = checkAndGrowOrCreateRect(grownRect, domUtils.getBoundingClientRect(lastSibling)) + }else { + if(lastSibling.nodeType === Node.TEXT_NODE) { + currentNode = lastSibling; + range.setStart(currentNode, currentNode === firstSibling ? firstOffset : 0); + range.setEnd(currentNode, lastOffset); + currentRect = range.getBoundingClientRect(); + grownRect = checkAndGrowOrCreateRect(grownRect, currentRect) + }else { + treeWalker = doc.createTreeWalker(lastSibling, NodeFilter.SHOW_TEXT, acceptNode, false); + currentNode = treeWalker.currentNode = lastNode; + while(currentNode && currentNode !== lastMeasuredNode) { + range.setStart(currentNode, 0); + range.setEnd(currentNode, lastOffset); + currentRect = range.getBoundingClientRect(); + grownRect = checkAndGrowOrCreateRect(grownRect, currentRect); + currentNode = treeWalker.previousNode(); + if(currentNode) { + lastOffset = (currentNode).length + } + } + } + } + return grownRect + } + function getCollapsedRectOfTextRange(range, useRightEdge) { + var clientRect = range.getBoundingClientRect(), collapsedRect = {}; + collapsedRect.width = 0; + collapsedRect.top = clientRect.top; + collapsedRect.bottom = clientRect.bottom; + collapsedRect.height = clientRect.height; + collapsedRect.left = collapsedRect.right = useRightEdge ? clientRect.right : clientRect.left; + return collapsedRect + } + function setPoints(points) { + var pointsString = "", i; + for(i = 0;i < points.length;i += 1) { + pointsString += points[i].x + "," + points[i].y + " " + } + polygon.setAttribute("points", pointsString) + } + function repositionOverlays(selectedRange) { + var extremes = getExtremeRanges(selectedRange), firstRange, lastRange, fillerRange, firstRect, fillerRect, lastRect, left, right, top, bottom; + if(extremes) { + firstRange = extremes.firstRange; + lastRange = extremes.lastRange; + fillerRange = extremes.fillerRange; + firstRect = translateRect(getCollapsedRectOfTextRange(firstRange, false)); + lastRect = translateRect(getCollapsedRectOfTextRange(lastRange, true)); + fillerRect = getFillerRect(fillerRange); + if(!fillerRect) { + fillerRect = getBoundingRect(firstRect, lastRect) + }else { + fillerRect = translateRect(fillerRect) + } + left = fillerRect.left; + right = firstRect.left + Math.max(0, fillerRect.width - (firstRect.left - fillerRect.left)); + top = Math.min(firstRect.top, lastRect.top); + bottom = lastRect.top + lastRect.height; + setPoints([{x:firstRect.left, y:top + firstRect.height}, {x:firstRect.left, y:top}, {x:right, y:top}, {x:right, y:bottom - lastRect.height}, {x:lastRect.right, y:bottom - lastRect.height}, {x:lastRect.right, y:bottom}, {x:left, y:bottom}, {x:left, y:top + firstRect.height}, {x:firstRect.left, y:top + firstRect.height}]); + firstRange.detach(); + lastRange.detach(); + fillerRange.detach() + } + return Boolean(extremes) + } + function rerender() { + var range = cursor.getSelectedRange(), shouldShow; + shouldShow = isVisible && (cursor.getSelectionType() === ops.OdtCursor.RangeSelection && !range.collapsed); + if(shouldShow) { + addOverlay(); + shouldShow = repositionOverlays(range) + } + if(shouldShow) { + overlay.style.display = "block" + }else { + overlay.style.display = "none" + } + } + this.rerender = function() { + if(isVisible) { + renderTask.trigger() + } + }; + this.show = function() { + isVisible = true; + renderTask.trigger() + }; + this.hide = function() { + isVisible = false; + renderTask.trigger() + }; + function handleCursorMove(movedCursor) { + if(isVisible && movedCursor === cursor) { + renderTask.trigger() + } + } + function destroy(callback) { + root.removeChild(overlay); + cursor.getDocument().unsubscribe(ops.Document.signalCursorMoved, handleCursorMove); + callback() + } + this.destroy = function(callback) { + async.destroyAll([renderTask.destroy, destroy], callback) + }; + function init() { + var editinfons = "urn:webodf:names:editinfo", memberid = cursor.getMemberId(); + renderTask = new core.ScheduledTask(rerender, 0); + addOverlay(); + overlay.setAttributeNS(editinfons, "editinfo:memberid", memberid); + cursor.getDocument().subscribe(ops.Document.signalCursorMoved, handleCursorMove) + } + init() +}; +/* + + 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/ +*/ +gui.UndoStateRules = function UndoStateRules() { + function ReverseIterator(array, predicate) { + var index = array.length; + this.previous = function() { + for(index = index - 1;index >= 0;index -= 1) { + if(predicate(array[index])) { + return array[index] + } + } + return null + } + } + function getOpType(op) { + return op.spec().optype + } + function getOpPosition(op) { + var key = "position", spec = op.spec(), value; + if(spec.hasOwnProperty(key)) { + value = (spec[key]) + } + return value + } + function isEditOperation(op) { + return op.isEdit + } + this.isEditOperation = isEditOperation; + function canAggregateOperation(op) { + switch(getOpType(op)) { + case "RemoveText": + ; + case "InsertText": + return true; + default: + return false + } + } + function isSameDirectionOfTravel(thisOp, lastEditOp, secondLastEditOp) { + var thisPosition = getOpPosition(thisOp), lastPosition = getOpPosition(lastEditOp), secondLastPosition = getOpPosition(secondLastEditOp), diffLastToSecondLast = lastPosition - secondLastPosition, diffThisToLast = thisPosition - lastPosition; + return diffThisToLast === diffLastToSecondLast + } + function isAdjacentOperation(thisOp, lastEditOp) { + var positionDifference = getOpPosition(thisOp) - getOpPosition(lastEditOp); + return positionDifference === 0 || Math.abs(positionDifference) === 1 + } + function continuesOperations(thisOp, lastEditOp, secondLastEditOp) { + if(!secondLastEditOp) { + return isAdjacentOperation(thisOp, lastEditOp) + } + return isSameDirectionOfTravel(thisOp, lastEditOp, secondLastEditOp) + } + function continuesMostRecentEditOperation(thisOp, recentOperations) { + var thisOpType = getOpType(thisOp), editOpsFinder = new ReverseIterator(recentOperations, isEditOperation), lastEditOp = editOpsFinder.previous(); + runtime.assert(Boolean(lastEditOp), "No edit operations found in state"); + if(thisOpType === getOpType((lastEditOp))) { + return continuesOperations(thisOp, (lastEditOp), editOpsFinder.previous()) + } + return false + } + function continuesMostRecentEditGroup(thisOp, recentOperations) { + var thisOpType = getOpType(thisOp), editOpsFinder = new ReverseIterator(recentOperations, isEditOperation), candidateOp = editOpsFinder.previous(), lastEditOp, secondLastEditOp = null, inspectedGroupsCount, groupId; + runtime.assert(Boolean(candidateOp), "No edit operations found in state"); + groupId = candidateOp.group; + runtime.assert(groupId !== undefined, "Operation has no group"); + inspectedGroupsCount = 1; + while(candidateOp && candidateOp.group === groupId) { + if(thisOpType === getOpType(candidateOp)) { + lastEditOp = candidateOp; + break + } + candidateOp = editOpsFinder.previous() + } + if(lastEditOp) { + candidateOp = editOpsFinder.previous(); + while(candidateOp) { + if(candidateOp.group !== groupId) { + if(inspectedGroupsCount === 2) { + break + } + groupId = candidateOp.group; + inspectedGroupsCount += 1 + } + if(thisOpType === getOpType(candidateOp)) { + secondLastEditOp = candidateOp; + break + } + candidateOp = editOpsFinder.previous() + } + return continuesOperations(thisOp, (lastEditOp), secondLastEditOp) + } + return false + } + function isPartOfOperationSet(operation, recentOperations) { + var areOperationsGrouped = operation.group !== undefined, lastOperation; + if(!isEditOperation(operation)) { + return true + } + if(recentOperations.length === 0) { + return true + } + lastOperation = recentOperations[recentOperations.length - 1]; + if(areOperationsGrouped && operation.group === lastOperation.group) { + return true + } + if(canAggregateOperation(operation) && recentOperations.some(isEditOperation)) { + if(areOperationsGrouped) { + return continuesMostRecentEditGroup(operation, recentOperations) + } + return continuesMostRecentEditOperation(operation, recentOperations) + } + return false + } + this.isPartOfOperationSet = isPartOfOperationSet +}; +/* + + 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/ +*/ +gui.TrivialUndoManager = function TrivialUndoManager(defaultRules) { + var self = this, cursorns = "urn:webodf:names:cursor", domUtils = new core.DomUtils, initialDoc, initialState = [], playFunc, document, currentUndoState = [], undoStates = [], redoStates = [], eventNotifier = new core.EventNotifier([gui.UndoManager.signalUndoStackChanged, gui.UndoManager.signalUndoStateCreated, gui.UndoManager.signalUndoStateModified, gui.TrivialUndoManager.signalDocumentRootReplaced]), undoRules = defaultRules || new gui.UndoStateRules, isExecutingOps = false; + function executeOperations(operations) { + if(operations.length > 0) { + isExecutingOps = true; + playFunc(operations); + isExecutingOps = false + } + } + function emitStackChange() { + eventNotifier.emit(gui.UndoManager.signalUndoStackChanged, {undoAvailable:self.hasUndoStates(), redoAvailable:self.hasRedoStates()}) + } + function mostRecentUndoState() { + return undoStates[undoStates.length - 1] + } + function completeCurrentUndoState() { + if(currentUndoState !== initialState && currentUndoState !== mostRecentUndoState()) { + undoStates.push(currentUndoState) + } + } + function removeNode(node) { + var sibling = node.previousSibling || node.nextSibling; + node.parentNode.removeChild(node); + domUtils.normalizeTextNodes(sibling) + } + function removeCursors(root) { + domUtils.getElementsByTagNameNS(root, cursorns, "cursor").forEach(removeNode); + domUtils.getElementsByTagNameNS(root, cursorns, "anchor").forEach(removeNode) + } + function values(obj) { + return Object.keys(obj).map(function(key) { + return obj[key] + }) + } + function extractCursorStates(undoStates) { + var addCursor = {}, moveCursor = {}, requiredAddOps = {}, remainingAddOps, operations = undoStates.pop(); + document.getMemberIds().forEach(function(memberid) { + requiredAddOps[memberid] = true + }); + remainingAddOps = Object.keys(requiredAddOps).length; + function processOp(op) { + var spec = op.spec(); + if(!requiredAddOps[spec.memberid]) { + return + } + switch(spec.optype) { + case "AddCursor": + if(!addCursor[spec.memberid]) { + addCursor[spec.memberid] = op; + delete requiredAddOps[spec.memberid]; + remainingAddOps -= 1 + } + break; + case "MoveCursor": + if(!moveCursor[spec.memberid]) { + moveCursor[spec.memberid] = op + } + break + } + } + while(operations && remainingAddOps > 0) { + operations.reverse(); + operations.forEach(processOp); + operations = undoStates.pop() + } + return values(addCursor).concat(values(moveCursor)) + } + this.subscribe = function(signal, callback) { + eventNotifier.subscribe(signal, callback) + }; + this.unsubscribe = function(signal, callback) { + eventNotifier.unsubscribe(signal, callback) + }; + this.hasUndoStates = function() { + return undoStates.length > 0 + }; + this.hasRedoStates = function() { + return redoStates.length > 0 + }; + this.setDocument = function(newDocument) { + document = newDocument + }; + this.purgeInitialState = function() { + undoStates.length = 0; + redoStates.length = 0; + initialState.length = 0; + currentUndoState.length = 0; + initialDoc = null; + emitStackChange() + }; + function setInitialState() { + initialDoc = document.cloneDocumentElement(); + removeCursors(initialDoc); + completeCurrentUndoState(); + currentUndoState = initialState = extractCursorStates([initialState].concat(undoStates)); + undoStates.length = 0; + redoStates.length = 0; + emitStackChange() + } + this.setInitialState = setInitialState; + this.initialize = function() { + if(!initialDoc) { + setInitialState() + } + }; + this.setPlaybackFunction = function(playback_func) { + playFunc = playback_func + }; + this.onOperationExecuted = function(op) { + if(isExecutingOps) { + return + } + if(undoRules.isEditOperation(op) && (currentUndoState === initialState || redoStates.length > 0) || !undoRules.isPartOfOperationSet(op, currentUndoState)) { + redoStates.length = 0; + completeCurrentUndoState(); + currentUndoState = [op]; + undoStates.push(currentUndoState); + eventNotifier.emit(gui.UndoManager.signalUndoStateCreated, {operations:currentUndoState}); + emitStackChange() + }else { + currentUndoState.push(op); + eventNotifier.emit(gui.UndoManager.signalUndoStateModified, {operations:currentUndoState}) + } + }; + this.moveForward = function(states) { + var moved = 0, redoOperations; + while(states && redoStates.length) { + redoOperations = redoStates.pop(); + undoStates.push(redoOperations); + executeOperations(redoOperations); + states -= 1; + moved += 1 + } + if(moved) { + currentUndoState = mostRecentUndoState(); + emitStackChange() + } + return moved + }; + this.moveBackward = function(states) { + var moved = 0; + while(states && undoStates.length) { + redoStates.push(undoStates.pop()); + states -= 1; + moved += 1 + } + if(moved) { + document.setDocumentElement((initialDoc.cloneNode(true))); + eventNotifier.emit(gui.TrivialUndoManager.signalDocumentRootReplaced, {}); + document.getMemberIds().forEach(function(memberid) { + document.removeCursor(memberid) + }); + executeOperations(initialState); + undoStates.forEach(executeOperations); + currentUndoState = mostRecentUndoState() || initialState; + emitStackChange() + } + return moved + } +}; +gui.TrivialUndoManager.signalDocumentRootReplaced = "documentRootReplaced"; +(function() { + return gui.TrivialUndoManager +})(); +/* + + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +ops.OperationTransformMatrix = function OperationTransformMatrix() { + function invertMoveCursorSpecRange(moveCursorSpec) { + moveCursorSpec.position = moveCursorSpec.position + moveCursorSpec.length; + moveCursorSpec.length *= -1 + } + function invertMoveCursorSpecRangeOnNegativeLength(moveCursorSpec) { + var isBackwards = moveCursorSpec.length < 0; + if(isBackwards) { + invertMoveCursorSpecRange(moveCursorSpec) + } + return isBackwards + } + function getStyleReferencingAttributes(setProperties, styleName) { + var attributes = []; + function check(attributeName) { + if(setProperties[attributeName] === styleName) { + attributes.push(attributeName) + } + } + if(setProperties) { + ["style:parent-style-name", "style:next-style-name"].forEach(check) + } + return attributes + } + function dropStyleReferencingAttributes(setProperties, deletedStyleName) { + function del(attributeName) { + if(setProperties[attributeName] === deletedStyleName) { + delete setProperties[attributeName] + } + } + if(setProperties) { + ["style:parent-style-name", "style:next-style-name"].forEach(del) + } + } + function cloneOpspec(opspec) { + var result = {}; + Object.keys(opspec).forEach(function(key) { + if(typeof opspec[key] === "object") { + result[key] = cloneOpspec(opspec[key]) + }else { + result[key] = opspec[key] + } + }); + return result + } + function dropOverruledAndUnneededAttributes(minorSetProperties, minorRemovedProperties, majorSetProperties, majorRemovedProperties) { + var i, name, majorChanged = false, minorChanged = false, removedPropertyNames, majorRemovedPropertyNames = []; + if(majorRemovedProperties && majorRemovedProperties.attributes) { + majorRemovedPropertyNames = majorRemovedProperties.attributes.split(",") + } + if(minorSetProperties && (majorSetProperties || majorRemovedPropertyNames.length > 0)) { + Object.keys(minorSetProperties).forEach(function(key) { + var value = minorSetProperties[key], overrulingPropertyValue; + if(typeof value !== "object") { + if(majorSetProperties) { + overrulingPropertyValue = majorSetProperties[key] + } + if(overrulingPropertyValue !== undefined) { + delete minorSetProperties[key]; + minorChanged = true; + if(overrulingPropertyValue === value) { + delete majorSetProperties[key]; + majorChanged = true + } + }else { + if(majorRemovedPropertyNames.indexOf(key) !== -1) { + delete minorSetProperties[key]; + minorChanged = true + } + } + } + }) + } + if(minorRemovedProperties && (minorRemovedProperties.attributes && (majorSetProperties || majorRemovedPropertyNames.length > 0))) { + removedPropertyNames = minorRemovedProperties.attributes.split(","); + for(i = 0;i < removedPropertyNames.length;i += 1) { + name = removedPropertyNames[i]; + if(majorSetProperties && majorSetProperties[name] !== undefined || majorRemovedPropertyNames && majorRemovedPropertyNames.indexOf(name) !== -1) { + removedPropertyNames.splice(i, 1); + i -= 1; + minorChanged = true + } + } + if(removedPropertyNames.length > 0) { + minorRemovedProperties.attributes = removedPropertyNames.join(",") + }else { + delete minorRemovedProperties.attributes + } + } + return{majorChanged:majorChanged, minorChanged:minorChanged} + } + function hasProperties(properties) { + var key; + for(key in properties) { + if(properties.hasOwnProperty(key)) { + return true + } + } + return false + } + function hasRemovedProperties(properties) { + var key; + for(key in properties) { + if(properties.hasOwnProperty(key)) { + if(key !== "attributes" || properties.attributes.length > 0) { + return true + } + } + } + return false + } + function dropOverruledAndUnneededProperties(minorSet, minorRem, majorSet, majorRem, propertiesName) { + var minorSP = minorSet ? minorSet[propertiesName] : null, minorRP = minorRem ? minorRem[propertiesName] : null, majorSP = majorSet ? majorSet[propertiesName] : null, majorRP = majorRem ? majorRem[propertiesName] : null, result; + result = dropOverruledAndUnneededAttributes(minorSP, minorRP, majorSP, majorRP); + if(minorSP && !hasProperties(minorSP)) { + delete minorSet[propertiesName] + } + if(minorRP && !hasRemovedProperties(minorRP)) { + delete minorRem[propertiesName] + } + if(majorSP && !hasProperties(majorSP)) { + delete majorSet[propertiesName] + } + if(majorRP && !hasRemovedProperties(majorRP)) { + delete majorRem[propertiesName] + } + return result + } + function transformAddStyleRemoveStyle(addStyleSpec, removeStyleSpec) { + var setAttributes, helperOpspec, addStyleSpecResult = [addStyleSpec], removeStyleSpecResult = [removeStyleSpec]; + if(addStyleSpec.styleFamily === removeStyleSpec.styleFamily) { + setAttributes = getStyleReferencingAttributes(addStyleSpec.setProperties, removeStyleSpec.styleName); + if(setAttributes.length > 0) { + helperOpspec = {optype:"UpdateParagraphStyle", memberid:removeStyleSpec.memberid, timestamp:removeStyleSpec.timestamp, styleName:addStyleSpec.styleName, removedProperties:{attributes:setAttributes.join(",")}}; + removeStyleSpecResult.unshift(helperOpspec) + } + dropStyleReferencingAttributes(addStyleSpec.setProperties, removeStyleSpec.styleName) + } + return{opSpecsA:addStyleSpecResult, opSpecsB:removeStyleSpecResult} + } + function transformApplyDirectStylingApplyDirectStyling(applyDirectStylingSpecA, applyDirectStylingSpecB, hasAPriority) { + var majorSpec, minorSpec, majorSpecResult, minorSpecResult, majorSpecEnd, minorSpecEnd, dropResult, originalMajorSpec, originalMinorSpec, helperOpspecBefore, helperOpspecAfter, applyDirectStylingSpecAResult = [applyDirectStylingSpecA], applyDirectStylingSpecBResult = [applyDirectStylingSpecB]; + if(!(applyDirectStylingSpecA.position + applyDirectStylingSpecA.length <= applyDirectStylingSpecB.position || applyDirectStylingSpecA.position >= applyDirectStylingSpecB.position + applyDirectStylingSpecB.length)) { + majorSpec = hasAPriority ? applyDirectStylingSpecA : applyDirectStylingSpecB; + minorSpec = hasAPriority ? applyDirectStylingSpecB : applyDirectStylingSpecA; + if(applyDirectStylingSpecA.position !== applyDirectStylingSpecB.position || applyDirectStylingSpecA.length !== applyDirectStylingSpecB.length) { + originalMajorSpec = cloneOpspec(majorSpec); + originalMinorSpec = cloneOpspec(minorSpec) + } + dropResult = dropOverruledAndUnneededProperties(minorSpec.setProperties, null, majorSpec.setProperties, null, "style:text-properties"); + if(dropResult.majorChanged || dropResult.minorChanged) { + majorSpecResult = []; + minorSpecResult = []; + majorSpecEnd = majorSpec.position + majorSpec.length; + minorSpecEnd = minorSpec.position + minorSpec.length; + if(minorSpec.position < majorSpec.position) { + if(dropResult.minorChanged) { + helperOpspecBefore = cloneOpspec((originalMinorSpec)); + helperOpspecBefore.length = majorSpec.position - minorSpec.position; + minorSpecResult.push(helperOpspecBefore); + minorSpec.position = majorSpec.position; + minorSpec.length = minorSpecEnd - minorSpec.position + } + }else { + if(majorSpec.position < minorSpec.position) { + if(dropResult.majorChanged) { + helperOpspecBefore = cloneOpspec((originalMajorSpec)); + helperOpspecBefore.length = minorSpec.position - majorSpec.position; + majorSpecResult.push(helperOpspecBefore); + majorSpec.position = minorSpec.position; + majorSpec.length = majorSpecEnd - majorSpec.position + } + } + } + if(minorSpecEnd > majorSpecEnd) { + if(dropResult.minorChanged) { + helperOpspecAfter = originalMinorSpec; + helperOpspecAfter.position = majorSpecEnd; + helperOpspecAfter.length = minorSpecEnd - majorSpecEnd; + minorSpecResult.push(helperOpspecAfter); + minorSpec.length = majorSpecEnd - minorSpec.position + } + }else { + if(majorSpecEnd > minorSpecEnd) { + if(dropResult.majorChanged) { + helperOpspecAfter = originalMajorSpec; + helperOpspecAfter.position = minorSpecEnd; + helperOpspecAfter.length = majorSpecEnd - minorSpecEnd; + majorSpecResult.push(helperOpspecAfter); + majorSpec.length = minorSpecEnd - majorSpec.position + } + } + } + if(majorSpec.setProperties && hasProperties(majorSpec.setProperties)) { + majorSpecResult.push(majorSpec) + } + if(minorSpec.setProperties && hasProperties(minorSpec.setProperties)) { + minorSpecResult.push(minorSpec) + } + if(hasAPriority) { + applyDirectStylingSpecAResult = majorSpecResult; + applyDirectStylingSpecBResult = minorSpecResult + }else { + applyDirectStylingSpecAResult = minorSpecResult; + applyDirectStylingSpecBResult = majorSpecResult + } + } + } + return{opSpecsA:applyDirectStylingSpecAResult, opSpecsB:applyDirectStylingSpecBResult} + } + function transformApplyDirectStylingInsertText(applyDirectStylingSpec, insertTextSpec) { + if(insertTextSpec.position <= applyDirectStylingSpec.position) { + applyDirectStylingSpec.position += insertTextSpec.text.length + }else { + if(insertTextSpec.position <= applyDirectStylingSpec.position + applyDirectStylingSpec.length) { + applyDirectStylingSpec.length += insertTextSpec.text.length + } + } + return{opSpecsA:[applyDirectStylingSpec], opSpecsB:[insertTextSpec]} + } + function transformApplyDirectStylingRemoveText(applyDirectStylingSpec, removeTextSpec) { + var applyDirectStylingSpecEnd = applyDirectStylingSpec.position + applyDirectStylingSpec.length, removeTextSpecEnd = removeTextSpec.position + removeTextSpec.length, applyDirectStylingSpecResult = [applyDirectStylingSpec], removeTextSpecResult = [removeTextSpec]; + if(removeTextSpecEnd <= applyDirectStylingSpec.position) { + applyDirectStylingSpec.position -= removeTextSpec.length + }else { + if(removeTextSpec.position < applyDirectStylingSpecEnd) { + if(applyDirectStylingSpec.position < removeTextSpec.position) { + if(removeTextSpecEnd < applyDirectStylingSpecEnd) { + applyDirectStylingSpec.length -= removeTextSpec.length + }else { + applyDirectStylingSpec.length = removeTextSpec.position - applyDirectStylingSpec.position + } + }else { + applyDirectStylingSpec.position = removeTextSpec.position; + if(removeTextSpecEnd < applyDirectStylingSpecEnd) { + applyDirectStylingSpec.length = applyDirectStylingSpecEnd - removeTextSpecEnd + }else { + applyDirectStylingSpecResult = [] + } + } + } + } + return{opSpecsA:applyDirectStylingSpecResult, opSpecsB:removeTextSpecResult} + } + function transformApplyDirectStylingSplitParagraph(applyDirectStylingSpec, splitParagraphSpec) { + if(splitParagraphSpec.position < applyDirectStylingSpec.position) { + applyDirectStylingSpec.position += 1 + }else { + if(splitParagraphSpec.position < applyDirectStylingSpec.position + applyDirectStylingSpec.length) { + applyDirectStylingSpec.length += 1 + } + } + return{opSpecsA:[applyDirectStylingSpec], opSpecsB:[splitParagraphSpec]} + } + function transformInsertTextInsertText(insertTextSpecA, insertTextSpecB, hasAPriority) { + if(insertTextSpecA.position < insertTextSpecB.position) { + insertTextSpecB.position += insertTextSpecA.text.length + }else { + if(insertTextSpecA.position > insertTextSpecB.position) { + insertTextSpecA.position += insertTextSpecB.text.length + }else { + if(hasAPriority) { + insertTextSpecB.position += insertTextSpecA.text.length + }else { + insertTextSpecA.position += insertTextSpecB.text.length + } + } + } + return{opSpecsA:[insertTextSpecA], opSpecsB:[insertTextSpecB]} + } + function transformInsertTextMoveCursor(insertTextSpec, moveCursorSpec) { + var isMoveCursorSpecRangeInverted = invertMoveCursorSpecRangeOnNegativeLength(moveCursorSpec); + if(insertTextSpec.position < moveCursorSpec.position) { + moveCursorSpec.position += insertTextSpec.text.length + }else { + if(insertTextSpec.position < moveCursorSpec.position + moveCursorSpec.length) { + moveCursorSpec.length += insertTextSpec.text.length + } + } + if(isMoveCursorSpecRangeInverted) { + invertMoveCursorSpecRange(moveCursorSpec) + } + return{opSpecsA:[insertTextSpec], opSpecsB:[moveCursorSpec]} + } + function transformInsertTextRemoveText(insertTextSpec, removeTextSpec) { + var helperOpspec, removeTextSpecEnd = removeTextSpec.position + removeTextSpec.length, insertTextSpecResult = [insertTextSpec], removeTextSpecResult = [removeTextSpec]; + if(removeTextSpecEnd <= insertTextSpec.position) { + insertTextSpec.position -= removeTextSpec.length + }else { + if(insertTextSpec.position <= removeTextSpec.position) { + removeTextSpec.position += insertTextSpec.text.length + }else { + removeTextSpec.length = insertTextSpec.position - removeTextSpec.position; + helperOpspec = {optype:"RemoveText", memberid:removeTextSpec.memberid, timestamp:removeTextSpec.timestamp, position:insertTextSpec.position + insertTextSpec.text.length, length:removeTextSpecEnd - insertTextSpec.position}; + removeTextSpecResult.unshift(helperOpspec); + insertTextSpec.position = removeTextSpec.position + } + } + return{opSpecsA:insertTextSpecResult, opSpecsB:removeTextSpecResult} + } + function transformInsertTextSplitParagraph(insertTextSpec, splitParagraphSpec, hasAPriority) { + if(insertTextSpec.position < splitParagraphSpec.position) { + splitParagraphSpec.position += insertTextSpec.text.length + }else { + if(insertTextSpec.position > splitParagraphSpec.position) { + insertTextSpec.position += 1 + }else { + if(hasAPriority) { + splitParagraphSpec.position += insertTextSpec.text.length + }else { + insertTextSpec.position += 1 + } + return null + } + } + return{opSpecsA:[insertTextSpec], opSpecsB:[splitParagraphSpec]} + } + function transformUpdateParagraphStyleUpdateParagraphStyle(updateParagraphStyleSpecA, updateParagraphStyleSpecB, hasAPriority) { + var majorSpec, minorSpec, updateParagraphStyleSpecAResult = [updateParagraphStyleSpecA], updateParagraphStyleSpecBResult = [updateParagraphStyleSpecB]; + if(updateParagraphStyleSpecA.styleName === updateParagraphStyleSpecB.styleName) { + majorSpec = hasAPriority ? updateParagraphStyleSpecA : updateParagraphStyleSpecB; + minorSpec = hasAPriority ? updateParagraphStyleSpecB : updateParagraphStyleSpecA; + dropOverruledAndUnneededProperties(minorSpec.setProperties, minorSpec.removedProperties, majorSpec.setProperties, majorSpec.removedProperties, "style:paragraph-properties"); + dropOverruledAndUnneededProperties(minorSpec.setProperties, minorSpec.removedProperties, majorSpec.setProperties, majorSpec.removedProperties, "style:text-properties"); + dropOverruledAndUnneededAttributes(minorSpec.setProperties || null, (minorSpec.removedProperties) || null, majorSpec.setProperties || null, (majorSpec.removedProperties) || null); + if(!(majorSpec.setProperties && hasProperties(majorSpec.setProperties)) && !(majorSpec.removedProperties && hasRemovedProperties(majorSpec.removedProperties))) { + if(hasAPriority) { + updateParagraphStyleSpecAResult = [] + }else { + updateParagraphStyleSpecBResult = [] + } + } + if(!(minorSpec.setProperties && hasProperties(minorSpec.setProperties)) && !(minorSpec.removedProperties && hasRemovedProperties(minorSpec.removedProperties))) { + if(hasAPriority) { + updateParagraphStyleSpecBResult = [] + }else { + updateParagraphStyleSpecAResult = [] + } + } + } + return{opSpecsA:updateParagraphStyleSpecAResult, opSpecsB:updateParagraphStyleSpecBResult} + } + function transformUpdateMetadataUpdateMetadata(updateMetadataSpecA, updateMetadataSpecB, hasAPriority) { + var majorSpec, minorSpec, updateMetadataSpecAResult = [updateMetadataSpecA], updateMetadataSpecBResult = [updateMetadataSpecB]; + majorSpec = hasAPriority ? updateMetadataSpecA : updateMetadataSpecB; + minorSpec = hasAPriority ? updateMetadataSpecB : updateMetadataSpecA; + dropOverruledAndUnneededAttributes(minorSpec.setProperties || null, minorSpec.removedProperties || null, majorSpec.setProperties || null, majorSpec.removedProperties || null); + if(!(majorSpec.setProperties && hasProperties(majorSpec.setProperties)) && !(majorSpec.removedProperties && hasRemovedProperties(majorSpec.removedProperties))) { + if(hasAPriority) { + updateMetadataSpecAResult = [] + }else { + updateMetadataSpecBResult = [] + } + } + if(!(minorSpec.setProperties && hasProperties(minorSpec.setProperties)) && !(minorSpec.removedProperties && hasRemovedProperties(minorSpec.removedProperties))) { + if(hasAPriority) { + updateMetadataSpecBResult = [] + }else { + updateMetadataSpecAResult = [] + } + } + return{opSpecsA:updateMetadataSpecAResult, opSpecsB:updateMetadataSpecBResult} + } + function transformSplitParagraphSplitParagraph(splitParagraphSpecA, splitParagraphSpecB, hasAPriority) { + if(splitParagraphSpecA.position < splitParagraphSpecB.position) { + splitParagraphSpecB.position += 1 + }else { + if(splitParagraphSpecA.position > splitParagraphSpecB.position) { + splitParagraphSpecA.position += 1 + }else { + if(splitParagraphSpecA.position === splitParagraphSpecB.position) { + if(hasAPriority) { + splitParagraphSpecB.position += 1 + }else { + splitParagraphSpecA.position += 1 + } + } + } + } + return{opSpecsA:[splitParagraphSpecA], opSpecsB:[splitParagraphSpecB]} + } + function transformMoveCursorRemoveCursor(moveCursorSpec, removeCursorSpec) { + var isSameCursorRemoved = moveCursorSpec.memberid === removeCursorSpec.memberid; + return{opSpecsA:isSameCursorRemoved ? [] : [moveCursorSpec], opSpecsB:[removeCursorSpec]} + } + function transformMoveCursorRemoveText(moveCursorSpec, removeTextSpec) { + var isMoveCursorSpecRangeInverted = invertMoveCursorSpecRangeOnNegativeLength(moveCursorSpec), moveCursorSpecEnd = moveCursorSpec.position + moveCursorSpec.length, removeTextSpecEnd = removeTextSpec.position + removeTextSpec.length; + if(removeTextSpecEnd <= moveCursorSpec.position) { + moveCursorSpec.position -= removeTextSpec.length + }else { + if(removeTextSpec.position < moveCursorSpecEnd) { + if(moveCursorSpec.position < removeTextSpec.position) { + if(removeTextSpecEnd < moveCursorSpecEnd) { + moveCursorSpec.length -= removeTextSpec.length + }else { + moveCursorSpec.length = removeTextSpec.position - moveCursorSpec.position + } + }else { + moveCursorSpec.position = removeTextSpec.position; + if(removeTextSpecEnd < moveCursorSpecEnd) { + moveCursorSpec.length = moveCursorSpecEnd - removeTextSpecEnd + }else { + moveCursorSpec.length = 0 + } + } + } + } + if(isMoveCursorSpecRangeInverted) { + invertMoveCursorSpecRange(moveCursorSpec) + } + return{opSpecsA:[moveCursorSpec], opSpecsB:[removeTextSpec]} + } + function transformMoveCursorSplitParagraph(moveCursorSpec, splitParagraphSpec) { + var isMoveCursorSpecRangeInverted = invertMoveCursorSpecRangeOnNegativeLength(moveCursorSpec); + if(splitParagraphSpec.position < moveCursorSpec.position) { + moveCursorSpec.position += 1 + }else { + if(splitParagraphSpec.position < moveCursorSpec.position + moveCursorSpec.length) { + moveCursorSpec.length += 1 + } + } + if(isMoveCursorSpecRangeInverted) { + invertMoveCursorSpecRange(moveCursorSpec) + } + return{opSpecsA:[moveCursorSpec], opSpecsB:[splitParagraphSpec]} + } + function transformRemoveCursorRemoveCursor(removeCursorSpecA, removeCursorSpecB) { + var isSameMemberid = removeCursorSpecA.memberid === removeCursorSpecB.memberid; + return{opSpecsA:isSameMemberid ? [] : [removeCursorSpecA], opSpecsB:isSameMemberid ? [] : [removeCursorSpecB]} + } + function transformRemoveStyleRemoveStyle(removeStyleSpecA, removeStyleSpecB) { + var isSameStyle = removeStyleSpecA.styleName === removeStyleSpecB.styleName && removeStyleSpecA.styleFamily === removeStyleSpecB.styleFamily; + return{opSpecsA:isSameStyle ? [] : [removeStyleSpecA], opSpecsB:isSameStyle ? [] : [removeStyleSpecB]} + } + function transformRemoveStyleSetParagraphStyle(removeStyleSpec, setParagraphStyleSpec) { + var helperOpspec, removeStyleSpecResult = [removeStyleSpec], setParagraphStyleSpecResult = [setParagraphStyleSpec]; + if(removeStyleSpec.styleFamily === "paragraph" && removeStyleSpec.styleName === setParagraphStyleSpec.styleName) { + helperOpspec = {optype:"SetParagraphStyle", memberid:removeStyleSpec.memberid, timestamp:removeStyleSpec.timestamp, position:setParagraphStyleSpec.position, styleName:""}; + removeStyleSpecResult.unshift(helperOpspec); + setParagraphStyleSpec.styleName = "" + } + return{opSpecsA:removeStyleSpecResult, opSpecsB:setParagraphStyleSpecResult} + } + function transformRemoveStyleUpdateParagraphStyle(removeStyleSpec, updateParagraphStyleSpec) { + var setAttributes, helperOpspec, removeStyleSpecResult = [removeStyleSpec], updateParagraphStyleSpecResult = [updateParagraphStyleSpec]; + if(removeStyleSpec.styleFamily === "paragraph") { + setAttributes = getStyleReferencingAttributes(updateParagraphStyleSpec.setProperties, removeStyleSpec.styleName); + if(setAttributes.length > 0) { + helperOpspec = {optype:"UpdateParagraphStyle", memberid:removeStyleSpec.memberid, timestamp:removeStyleSpec.timestamp, styleName:updateParagraphStyleSpec.styleName, removedProperties:{attributes:setAttributes.join(",")}}; + removeStyleSpecResult.unshift(helperOpspec) + } + if(removeStyleSpec.styleName === updateParagraphStyleSpec.styleName) { + updateParagraphStyleSpecResult = [] + }else { + dropStyleReferencingAttributes(updateParagraphStyleSpec.setProperties, removeStyleSpec.styleName) + } + } + return{opSpecsA:removeStyleSpecResult, opSpecsB:updateParagraphStyleSpecResult} + } + function transformRemoveTextRemoveText(removeTextSpecA, removeTextSpecB) { + var removeTextSpecAEnd = removeTextSpecA.position + removeTextSpecA.length, removeTextSpecBEnd = removeTextSpecB.position + removeTextSpecB.length, removeTextSpecAResult = [removeTextSpecA], removeTextSpecBResult = [removeTextSpecB]; + if(removeTextSpecBEnd <= removeTextSpecA.position) { + removeTextSpecA.position -= removeTextSpecB.length + }else { + if(removeTextSpecAEnd <= removeTextSpecB.position) { + removeTextSpecB.position -= removeTextSpecA.length + }else { + if(removeTextSpecB.position < removeTextSpecAEnd) { + if(removeTextSpecA.position < removeTextSpecB.position) { + if(removeTextSpecBEnd < removeTextSpecAEnd) { + removeTextSpecA.length = removeTextSpecA.length - removeTextSpecB.length + }else { + removeTextSpecA.length = removeTextSpecB.position - removeTextSpecA.position + } + if(removeTextSpecAEnd < removeTextSpecBEnd) { + removeTextSpecB.position = removeTextSpecA.position; + removeTextSpecB.length = removeTextSpecBEnd - removeTextSpecAEnd + }else { + removeTextSpecBResult = [] + } + }else { + if(removeTextSpecAEnd < removeTextSpecBEnd) { + removeTextSpecB.length = removeTextSpecB.length - removeTextSpecA.length + }else { + if(removeTextSpecB.position < removeTextSpecA.position) { + removeTextSpecB.length = removeTextSpecA.position - removeTextSpecB.position + }else { + removeTextSpecBResult = [] + } + } + if(removeTextSpecBEnd < removeTextSpecAEnd) { + removeTextSpecA.position = removeTextSpecB.position; + removeTextSpecA.length = removeTextSpecAEnd - removeTextSpecBEnd + }else { + removeTextSpecAResult = [] + } + } + } + } + } + return{opSpecsA:removeTextSpecAResult, opSpecsB:removeTextSpecBResult} + } + function transformRemoveTextSplitParagraph(removeTextSpec, splitParagraphSpec) { + var removeTextSpecEnd = removeTextSpec.position + removeTextSpec.length, helperOpspec, removeTextSpecResult = [removeTextSpec], splitParagraphSpecResult = [splitParagraphSpec]; + if(splitParagraphSpec.position <= removeTextSpec.position) { + removeTextSpec.position += 1 + }else { + if(splitParagraphSpec.position < removeTextSpecEnd) { + removeTextSpec.length = splitParagraphSpec.position - removeTextSpec.position; + helperOpspec = {optype:"RemoveText", memberid:removeTextSpec.memberid, timestamp:removeTextSpec.timestamp, position:splitParagraphSpec.position + 1, length:removeTextSpecEnd - splitParagraphSpec.position}; + removeTextSpecResult.unshift(helperOpspec) + } + } + if(removeTextSpec.position + removeTextSpec.length <= splitParagraphSpec.position) { + splitParagraphSpec.position -= removeTextSpec.length + }else { + if(removeTextSpec.position < splitParagraphSpec.position) { + splitParagraphSpec.position = removeTextSpec.position + } + } + return{opSpecsA:removeTextSpecResult, opSpecsB:splitParagraphSpecResult} + } + function passUnchanged(opSpecA, opSpecB) { + return{opSpecsA:[opSpecA], opSpecsB:[opSpecB]} + } + var transformations; + transformations = {"AddCursor":{"AddCursor":passUnchanged, "AddMember":passUnchanged, "AddStyle":passUnchanged, "ApplyDirectStyling":passUnchanged, "InsertText":passUnchanged, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveMember":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "AddMember":{"AddStyle":passUnchanged, + "InsertText":passUnchanged, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "AddStyle":{"AddStyle":passUnchanged, "ApplyDirectStyling":passUnchanged, "InsertText":passUnchanged, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveMember":passUnchanged, "RemoveStyle":transformAddStyleRemoveStyle, + "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "ApplyDirectStyling":{"ApplyDirectStyling":transformApplyDirectStylingApplyDirectStyling, "InsertText":transformApplyDirectStylingInsertText, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":transformApplyDirectStylingRemoveText, "SetParagraphStyle":passUnchanged, + "SplitParagraph":transformApplyDirectStylingSplitParagraph, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "InsertText":{"InsertText":transformInsertTextInsertText, "MoveCursor":transformInsertTextMoveCursor, "RemoveCursor":passUnchanged, "RemoveMember":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":transformInsertTextRemoveText, "SplitParagraph":transformInsertTextSplitParagraph, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, + "MoveCursor":{"MoveCursor":passUnchanged, "RemoveCursor":transformMoveCursorRemoveCursor, "RemoveMember":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":transformMoveCursorRemoveText, "SetParagraphStyle":passUnchanged, "SplitParagraph":transformMoveCursorSplitParagraph, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "RemoveCursor":{"RemoveCursor":transformRemoveCursorRemoveCursor, "RemoveMember":passUnchanged, "RemoveStyle":passUnchanged, + "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "RemoveMember":{"RemoveStyle":passUnchanged, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "RemoveStyle":{"RemoveStyle":transformRemoveStyleRemoveStyle, "RemoveText":passUnchanged, "SetParagraphStyle":transformRemoveStyleSetParagraphStyle, + "SplitParagraph":passUnchanged, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":transformRemoveStyleUpdateParagraphStyle}, "RemoveText":{"RemoveText":transformRemoveTextRemoveText, "SplitParagraph":transformRemoveTextSplitParagraph, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "SetParagraphStyle":{"UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "SplitParagraph":{"SplitParagraph":transformSplitParagraphSplitParagraph, + "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "UpdateMember":{"UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "UpdateMetadata":{"UpdateMetadata":transformUpdateMetadataUpdateMetadata, "UpdateParagraphStyle":passUnchanged}, "UpdateParagraphStyle":{"UpdateParagraphStyle":transformUpdateParagraphStyleUpdateParagraphStyle}}; + this.passUnchanged = passUnchanged; + this.extendTransformations = function(moreTransformations) { + Object.keys(moreTransformations).forEach(function(optypeA) { + var moreTransformationsOptypeAMap = moreTransformations[optypeA], optypeAMap, isExtendingOptypeAMap = transformations.hasOwnProperty(optypeA); + runtime.log((isExtendingOptypeAMap ? "Extending" : "Adding") + " map for optypeA: " + optypeA); + if(!isExtendingOptypeAMap) { + transformations[optypeA] = {} + } + optypeAMap = transformations[optypeA]; + Object.keys(moreTransformationsOptypeAMap).forEach(function(optypeB) { + var isOverwritingOptypeBEntry = optypeAMap.hasOwnProperty(optypeB); + runtime.assert(optypeA <= optypeB, "Wrong order:" + optypeA + ", " + optypeB); + runtime.log(" " + (isOverwritingOptypeBEntry ? "Overwriting" : "Adding") + " entry for optypeB: " + optypeB); + optypeAMap[optypeB] = moreTransformationsOptypeAMap[optypeB] + }) + }) + }; + this.transformOpspecVsOpspec = function(opSpecA, opSpecB) { + var isOptypeAAlphaNumericSmaller = opSpecA.optype <= opSpecB.optype, helper, transformationFunctionMap, transformationFunction, result; + runtime.log("Crosstransforming:"); + runtime.log(runtime.toJson(opSpecA)); + runtime.log(runtime.toJson(opSpecB)); + if(!isOptypeAAlphaNumericSmaller) { + helper = opSpecA; + opSpecA = opSpecB; + opSpecB = helper + } + transformationFunctionMap = transformations[opSpecA.optype]; + transformationFunction = transformationFunctionMap && transformationFunctionMap[opSpecB.optype]; + if(transformationFunction) { + result = transformationFunction(opSpecA, opSpecB, !isOptypeAAlphaNumericSmaller); + if(!isOptypeAAlphaNumericSmaller && result !== null) { + result = {opSpecsA:result.opSpecsB, opSpecsB:result.opSpecsA} + } + }else { + result = null + } + runtime.log("result:"); + if(result) { + runtime.log(runtime.toJson(result.opSpecsA)); + runtime.log(runtime.toJson(result.opSpecsB)) + }else { + runtime.log("null") + } + return result + } +}; +/* + + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +ops.OperationTransformer = function OperationTransformer() { + var operationFactory, operationTransformMatrix = new ops.OperationTransformMatrix; + function operations(opspecs) { + var ops = []; + opspecs.forEach(function(opspec) { + ops.push(operationFactory.create(opspec)) + }); + return ops + } + function transformOpVsOp(opSpecA, opSpecB) { + return operationTransformMatrix.transformOpspecVsOpspec(opSpecA, opSpecB) + } + function transformOpListVsOp(opSpecsA, opSpecB) { + var transformResult, transformListResult, transformedOpspecsA = [], transformedOpspecsB = []; + while(opSpecsA.length > 0 && opSpecB) { + transformResult = transformOpVsOp(opSpecsA.shift(), opSpecB); + if(!transformResult) { + return null + } + transformedOpspecsA = transformedOpspecsA.concat(transformResult.opSpecsA); + if(transformResult.opSpecsB.length === 0) { + transformedOpspecsA = transformedOpspecsA.concat(opSpecsA); + opSpecB = null; + break + } + while(transformResult.opSpecsB.length > 1) { + transformListResult = transformOpListVsOp(opSpecsA, transformResult.opSpecsB.shift()); + if(!transformListResult) { + return null + } + transformedOpspecsB = transformedOpspecsB.concat(transformListResult.opSpecsB); + opSpecsA = transformListResult.opSpecsA + } + opSpecB = transformResult.opSpecsB.pop() + } + if(opSpecB) { + transformedOpspecsB.push(opSpecB) + } + return{opSpecsA:transformedOpspecsA, opSpecsB:transformedOpspecsB} + } + this.setOperationFactory = function(f) { + operationFactory = f + }; + this.getOperationTransformMatrix = function() { + return operationTransformMatrix + }; + this.transform = function(opSpecsA, opSpecsB) { + var transformResult, transformedOpspecsB = []; + while(opSpecsB.length > 0) { + transformResult = transformOpListVsOp(opSpecsA, opSpecsB.shift()); + if(!transformResult) { + return null + } + opSpecsA = transformResult.opSpecsA; + transformedOpspecsB = transformedOpspecsB.concat(transformResult.opSpecsB) + } + return{opsA:operations(opSpecsA), opsB:operations(transformedOpspecsB)} + } +}; +/* + + 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/ +*/ +ops.Server = function Server() { +}; +ops.Server.prototype.connect = function(timeout, cb) { +}; +ops.Server.prototype.networkStatus = function() { +}; +ops.Server.prototype.login = function(login, password, successCb, failCb) { +}; +ops.Server.prototype.joinSession = function(userId, sessionId, successCb, failCb) { +}; +ops.Server.prototype.leaveSession = function(sessionId, memberId, successCb, failCb) { +}; +ops.Server.prototype.getGenesisUrl = function(sessionId) { +}; +var webodf_css = '@namespace draw url(urn:oasis:names:tc:opendocument:xmlns:drawing:1.0);\n@namespace fo url(urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0);\n@namespace office url(urn:oasis:names:tc:opendocument:xmlns:office:1.0);\n@namespace presentation url(urn:oasis:names:tc:opendocument:xmlns:presentation:1.0);\n@namespace style url(urn:oasis:names:tc:opendocument:xmlns:style:1.0);\n@namespace svg url(urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0);\n@namespace table url(urn:oasis:names:tc:opendocument:xmlns:table:1.0);\n@namespace text url(urn:oasis:names:tc:opendocument:xmlns:text:1.0);\n@namespace webodfhelper url(urn:webodf:names:helper);\n@namespace cursor url(urn:webodf:names:cursor);\n@namespace editinfo url(urn:webodf:names:editinfo);\n@namespace annotation url(urn:webodf:names:annotation);\n@namespace dc url(http://purl.org/dc/elements/1.1/);\n@namespace svgns url(http://www.w3.org/2000/svg);\n\noffice|document > *, office|document-content > * {\n display: none;\n}\noffice|body, office|document {\n display: inline-block;\n position: relative;\n}\n\ntext|p, text|h {\n display: block;\n padding: 0;\n margin: 0;\n line-height: normal;\n position: relative;\n min-height: 1.3em; /* prevent empty paragraphs and headings from collapsing if they are empty */\n}\n*[webodfhelper|containsparagraphanchor] {\n position: relative;\n}\ntext|s {\n white-space: pre;\n}\ntext|tab {\n display: inline;\n white-space: pre;\n}\ntext|tracked-changes {\n /*Consumers that do not support change tracking, should ignore changes.*/\n display: none;\n}\noffice|binary-data {\n display: none;\n}\noffice|text {\n display: block;\n text-align: left;\n overflow: visible;\n word-wrap: break-word;\n}\n\noffice|text::selection {\n /** Let\'s not draw selection highlight that overflows into the office|text\n * node when selecting content across several paragraphs\n */\n background: transparent;\n}\n\noffice|document *::selection {\n background: transparent;\n}\noffice|document *::-moz-selection {\n background: transparent;\n}\n\noffice|text * draw|text-box {\n/** only for text documents */\n display: block;\n border: 1px solid #d3d3d3;\n}\ndraw|frame {\n /** make sure frames are above the main body. */\n z-index: 1;\n}\noffice|spreadsheet {\n display: block;\n border-collapse: collapse;\n empty-cells: show;\n font-family: sans-serif;\n font-size: 10pt;\n text-align: left;\n page-break-inside: avoid;\n overflow: hidden;\n}\noffice|presentation {\n display: inline-block;\n text-align: left;\n}\n#shadowContent {\n display: inline-block;\n text-align: left;\n}\ndraw|page {\n display: block;\n position: relative;\n overflow: hidden;\n}\npresentation|notes, presentation|footer-decl, presentation|date-time-decl {\n display: none;\n}\n@media print {\n draw|page {\n border: 1pt solid black;\n page-break-inside: avoid;\n }\n presentation|notes {\n /*TODO*/\n }\n}\noffice|spreadsheet text|p {\n border: 0px;\n padding: 1px;\n margin: 0px;\n}\noffice|spreadsheet table|table {\n margin: 3px;\n}\noffice|spreadsheet table|table:after {\n /* show sheet name the end of the sheet */\n /*content: attr(table|name);*/ /* gives parsing error in opera */\n}\noffice|spreadsheet table|table-row {\n counter-increment: row;\n}\noffice|spreadsheet table|table-row:before {\n width: 3em;\n background: #cccccc;\n border: 1px solid black;\n text-align: center;\n content: counter(row);\n display: table-cell;\n}\noffice|spreadsheet table|table-cell {\n border: 1px solid #cccccc;\n}\ntable|table {\n display: table;\n}\ndraw|frame table|table {\n width: 100%;\n height: 100%;\n background: white;\n}\ntable|table-header-rows {\n display: table-header-group;\n}\ntable|table-row {\n display: table-row;\n}\ntable|table-column {\n display: table-column;\n}\ntable|table-cell {\n width: 0.889in;\n display: table-cell;\n word-break: break-all; /* prevent long words from extending out the table cell */\n}\ndraw|frame {\n display: block;\n}\ndraw|image {\n display: block;\n width: 100%;\n height: 100%;\n top: 0px;\n left: 0px;\n background-repeat: no-repeat;\n background-size: 100% 100%;\n -moz-background-size: 100% 100%;\n}\n/* only show the first image in frame */\ndraw|frame > draw|image:nth-of-type(n+2) {\n display: none;\n}\ntext|list:before {\n display: none;\n content:"";\n}\ntext|list {\n counter-reset: list;\n}\ntext|list-item {\n display: block;\n}\ntext|number {\n display:none;\n}\n\ntext|a {\n color: blue;\n text-decoration: underline;\n cursor: pointer;\n}\noffice|text[webodfhelper|links="inactive"] text|a {\n cursor: text;\n}\ntext|note-citation {\n vertical-align: super;\n font-size: smaller;\n}\ntext|note-body {\n display: none;\n}\ntext|note:hover text|note-citation {\n background: #dddddd;\n}\ntext|note:hover text|note-body {\n display: block;\n left:1em;\n max-width: 80%;\n position: absolute;\n background: #ffffaa;\n}\nsvg|title, svg|desc {\n display: none;\n}\nvideo {\n width: 100%;\n height: 100%\n}\n\n/* below set up the cursor */\ncursor|cursor {\n display: inline;\n width: 0;\n height: 1em;\n /* making the position relative enables the avatar to use\n the cursor as reference for its absolute position */\n position: relative;\n z-index: 1;\n pointer-events: none;\n}\n\ncursor|cursor > .caret {\n /* IMPORTANT: when changing these values ensure DEFAULT_CARET_TOP and DEFAULT_CARET_HEIGHT\n in Caret.js remain in sync */\n display: inline;\n position: absolute;\n top: 5%; /* push down the caret; 0px can do the job, 5% looks better, 10% is a bit over */\n height: 1em;\n border-left: 2px solid black;\n outline: none;\n}\n\ncursor|cursor > .handle {\n padding: 3px;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n border: none !important;\n border-radius: 5px;\n opacity: 0.3;\n}\n\ncursor|cursor > .handle > img {\n border-radius: 5px;\n}\n\ncursor|cursor > .handle.active {\n opacity: 0.8;\n}\n\ncursor|cursor > .handle:after {\n content: \' \';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 43%;\n}\n\n/** Input Method Editor input pane & behaviours */\n/* not within a cursor */\n#eventTrap {\n height: auto;\n display: block;\n position: absolute;\n width: 1px;\n outline: none;\n opacity: 0;\n color: rgba(255, 255, 255, 0); /* hide the blinking caret by setting the colour to fully transparent */\n overflow: hidden; /* The overflow visibility is used to hide and show characters being entered */\n pointer-events: none;\n}\n\n/* within a cursor */\ncursor|cursor > #composer {\n text-decoration: underline;\n}\n\ncursor|cursor[cursor|composing="true"] > #composer {\n display: inline-block;\n height: auto;\n width: auto;\n}\n\ncursor|cursor[cursor|composing="true"] {\n display: inline-block;\n width: auto;\n height: inherit;\n}\n\ncursor|cursor[cursor|composing="true"] > .caret {\n /* during composition, the caret should be pushed along by the composition text, inline with the text */\n position: static;\n /* as it is now part of an inline-block, it will no longer need correct to top or height values to align properly */\n height: auto !important;\n top: auto !important;\n}\n\neditinfo|editinfo {\n /* Empty or invisible display:inline elements respond very badly to mouse selection.\n Inline blocks are much more reliably selectable in Chrome & friends */\n display: inline-block;\n}\n\n.editInfoMarker {\n position: absolute;\n width: 10px;\n height: 100%;\n left: -20px;\n opacity: 0.8;\n top: 0;\n border-radius: 5px;\n background-color: transparent;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n}\n.editInfoMarker:hover {\n box-shadow: 0px 0px 8px rgba(0, 0, 0, 1);\n}\n\n.editInfoHandle {\n position: absolute;\n background-color: black;\n padding: 5px;\n border-radius: 5px;\n opacity: 0.8;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n bottom: 100%;\n margin-bottom: 10px;\n z-index: 3;\n left: -25px;\n}\n.editInfoHandle:after {\n content: \' \';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 5px;\n}\n.editInfo {\n font-family: sans-serif;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n color: white;\n width: 100%;\n height: 12pt;\n}\n.editInfoColor {\n float: left;\n width: 10pt;\n height: 10pt;\n border: 1px solid white;\n}\n.editInfoAuthor {\n float: left;\n margin-left: 5pt;\n font-size: 10pt;\n text-align: left;\n height: 12pt;\n line-height: 12pt;\n}\n.editInfoTime {\n float: right;\n margin-left: 30pt;\n font-size: 8pt;\n font-style: italic;\n color: yellow;\n height: 12pt;\n line-height: 12pt;\n}\n\n.annotationWrapper {\n display: inline;\n position: relative;\n}\n\n.annotationRemoveButton:before {\n content: \'\u00d7\';\n color: white;\n padding: 5px;\n line-height: 1em;\n}\n\n.annotationRemoveButton {\n width: 20px;\n height: 20px;\n border-radius: 10px;\n background-color: black;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n position: absolute;\n top: -10px;\n left: -10px;\n z-index: 3;\n text-align: center;\n font-family: sans-serif;\n font-style: normal;\n font-weight: normal;\n text-decoration: none;\n font-size: 15px;\n}\n.annotationRemoveButton:hover {\n cursor: pointer;\n box-shadow: 0px 0px 5px rgba(0, 0, 0, 1);\n}\n\n.annotationNote {\n width: 4cm;\n position: absolute;\n display: inline;\n z-index: 10;\n}\n.annotationNote > office|annotation {\n display: block;\n text-align: left;\n}\n\n.annotationConnector {\n position: absolute;\n display: inline;\n z-index: 2;\n border-top: 1px dashed brown;\n}\n.annotationConnector.angular {\n -moz-transform-origin: left top;\n -webkit-transform-origin: left top;\n -ms-transform-origin: left top;\n transform-origin: left top;\n}\n.annotationConnector.horizontal {\n left: 0;\n}\n.annotationConnector.horizontal:before {\n content: \'\';\n display: inline;\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: brown transparent transparent transparent;\n top: -1px;\n left: -5px;\n}\n\noffice|annotation {\n width: 100%;\n height: 100%;\n display: none;\n background: rgb(198, 238, 184);\n background: -moz-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -webkit-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -o-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -ms-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: linear-gradient(180deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n box-shadow: 0 3px 4px -3px #ccc;\n}\n\noffice|annotation > dc|creator {\n display: block;\n font-size: 10pt;\n font-weight: normal;\n font-style: normal;\n font-family: sans-serif;\n color: white;\n background-color: brown;\n padding: 4px;\n}\noffice|annotation > dc|date {\n display: block;\n font-size: 10pt;\n font-weight: normal;\n font-style: normal;\n font-family: sans-serif;\n border: 4px solid transparent;\n color: black;\n}\noffice|annotation > text|list {\n display: block;\n padding: 5px;\n}\n\n/* This is very temporary CSS. This must go once\n * we start bundling webodf-default ODF styles for annotations.\n */\noffice|annotation text|p {\n font-size: 10pt;\n color: black;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n font-family: sans-serif;\n}\n\ndc|*::selection {\n background: transparent;\n}\ndc|*::-moz-selection {\n background: transparent;\n}\n\n#annotationsPane {\n background-color: #EAEAEA;\n width: 4cm;\n height: 100%;\n display: none;\n position: absolute;\n outline: 1px solid #ccc;\n}\n\n.annotationHighlight {\n background-color: yellow;\n position: relative;\n}\n\n.selectionOverlay {\n position: absolute;\n pointer-events: none;\n top: 0;\n left: 0;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 15;\n}\n.selectionOverlay > polygon {\n fill-opacity: 0.3;\n stroke-opacity: 0.8;\n stroke-width: 1;\n fill-rule: evenodd;\n}\n\n#imageSelector {\n display: none;\n position: absolute;\n border-style: solid;\n border-color: black;\n}\n\n#imageSelector > div {\n width: 5px;\n height: 5px;\n display: block;\n position: absolute;\n border: 1px solid black;\n background-color: #ffffff;\n}\n\n#imageSelector > .topLeft {\n top: -4px;\n left: -4px;\n}\n\n#imageSelector > .topRight {\n top: -4px;\n right: -4px;\n}\n\n#imageSelector > .bottomRight {\n right: -4px;\n bottom: -4px;\n}\n\n#imageSelector > .bottomLeft {\n bottom: -4px;\n left: -4px;\n}\n\n#imageSelector > .topMiddle {\n top: -4px;\n left: 50%;\n margin-left: -2.5px; /* half of the width defined in #imageSelector > div */\n}\n\n#imageSelector > .rightMiddle {\n top: 50%;\n right: -4px;\n margin-top: -2.5px; /* half of the height defined in #imageSelector > div */\n}\n\n#imageSelector > .bottomMiddle {\n bottom: -4px;\n left: 50%;\n margin-left: -2.5px; /* half of the width defined in #imageSelector > div */\n}\n\n#imageSelector > .leftMiddle {\n top: 50%;\n left: -4px;\n margin-top: -2.5px; /* half of the height defined in #imageSelector > div */\n}\n\ndiv.customScrollbars::-webkit-scrollbar\n{\n width: 8px;\n height: 8px;\n background-color: transparent;\n}\n\ndiv.customScrollbars::-webkit-scrollbar-track\n{\n background-color: transparent;\n}\n\ndiv.customScrollbars::-webkit-scrollbar-thumb\n{\n background-color: #444;\n border-radius: 4px;\n}\n'; diff --git a/js/3rdparty/webodf/webodf.js b/js/3rdparty/webodf/webodf.js index 688b4a12..2690b0fd 100644 --- a/js/3rdparty/webodf/webodf.js +++ b/js/3rdparty/webodf/webodf.js @@ -1,55 +1,57 @@ // Input 0 -var webodf_version="0.4.2-1579-gfc3a4e6"; +var webodf_version="0.4.2-2010-ge06842f"; // Input 1 -function Runtime(){}Runtime.prototype.getVariable=function(g){};Runtime.prototype.toJson=function(g){};Runtime.prototype.fromJson=function(g){};Runtime.prototype.byteArrayFromString=function(g,l){};Runtime.prototype.byteArrayToString=function(g,l){};Runtime.prototype.read=function(g,l,f,p){};Runtime.prototype.readFile=function(g,l,f){};Runtime.prototype.readFileSync=function(g,l){};Runtime.prototype.loadXML=function(g,l){};Runtime.prototype.writeFile=function(g,l,f){}; -Runtime.prototype.isFile=function(g,l){};Runtime.prototype.getFileSize=function(g,l){};Runtime.prototype.deleteFile=function(g,l){};Runtime.prototype.log=function(g,l){};Runtime.prototype.setTimeout=function(g,l){};Runtime.prototype.clearTimeout=function(g){};Runtime.prototype.libraryPaths=function(){};Runtime.prototype.currentDirectory=function(){};Runtime.prototype.setCurrentDirectory=function(g){};Runtime.prototype.type=function(){};Runtime.prototype.getDOMImplementation=function(){}; -Runtime.prototype.parseXML=function(g){};Runtime.prototype.exit=function(g){};Runtime.prototype.getWindow=function(){};Runtime.prototype.assert=function(g,l,f){};var IS_COMPILED_CODE=!0; -Runtime.byteArrayToString=function(g,l){function f(f){var h="",d,m=f.length;for(d=0;d<m;d+=1)h+=String.fromCharCode(f[d]&255);return h}function p(f){var h="",d,m=f.length,c=[],e,a,b,q;for(d=0;d<m;d+=1)e=f[d],128>e?c.push(e):(d+=1,a=f[d],194<=e&&224>e?c.push((e&31)<<6|a&63):(d+=1,b=f[d],224<=e&&240>e?c.push((e&15)<<12|(a&63)<<6|b&63):(d+=1,q=f[d],240<=e&&245>e&&(e=(e&7)<<18|(a&63)<<12|(b&63)<<6|q&63,e-=65536,c.push((e>>10)+55296,(e&1023)+56320))))),1E3===c.length&&(h+=String.fromCharCode.apply(null, -c),c.length=0);return h+String.fromCharCode.apply(null,c)}var r;"utf8"===l?r=p(g):("binary"!==l&&this.log("Unsupported encoding: "+l),r=f(g));return r};Runtime.getVariable=function(g){try{return eval(g)}catch(l){}};Runtime.toJson=function(g){return JSON.stringify(g)};Runtime.fromJson=function(g){return JSON.parse(g)};Runtime.getFunctionName=function(g){return void 0===g.name?(g=/function\s+(\w+)/.exec(g))&&g[1]:g.name}; -function BrowserRuntime(g){function l(d,m){var c,e,a;void 0!==m?a=d:m=d;g?(e=g.ownerDocument,a&&(c=e.createElement("span"),c.className=a,c.appendChild(e.createTextNode(a)),g.appendChild(c),g.appendChild(e.createTextNode(" "))),c=e.createElement("span"),0<m.length&&"<"===m[0]?c.innerHTML=m:c.appendChild(e.createTextNode(m)),g.appendChild(c),g.appendChild(e.createElement("br"))):console&&console.log(m);"alert"===a&&alert(m)}function f(d,m,c){if(0!==c.status||c.responseText)if(200===c.status||0===c.status){if(c.response&& -"string"!==typeof c.response)"binary"===m?(m=c.response,m=new Uint8Array(m)):m=String(c.response);else if("binary"===m)if(null!==c.responseBody&&"undefined"!==String(typeof VBArray)){m=(new VBArray(c.responseBody)).toArray();c=m.length;var e,a=new Uint8Array(new ArrayBuffer(c));for(e=0;e<c;e+=1)a[e]=m[e];m=a}else m=n.byteArrayFromString(c.responseText,"binary");else m=c.responseText;h[d]=m;d={err:null,data:m}}else d={err:c.responseText||c.statusText,data:null};else d={err:"File "+d+" is empty.",data:null}; -return d}function p(d,m,c){var e=new XMLHttpRequest;e.open("GET",d,c);e.overrideMimeType&&("binary"!==m?e.overrideMimeType("text/plain; charset="+m):e.overrideMimeType("text/plain; charset=x-user-defined"));return e}function r(d,m,c){function e(){var b;4===a.readyState&&(b=f(d,m,a),c(b.err,b.data))}if(h.hasOwnProperty(d))c(null,h[d]);else{var a=p(d,m,!0);a.onreadystatechange=e;try{a.send(null)}catch(b){c(b.message,null)}}}var n=this,h={};this.byteArrayFromString=function(d,m){var c;if("utf8"===m){c= -d.length;var e,a,b,q=0;for(a=0;a<c;a+=1)b=d.charCodeAt(a),q+=1+(128<b)+(2048<b);e=new Uint8Array(new ArrayBuffer(q));for(a=q=0;a<c;a+=1)b=d.charCodeAt(a),128>b?(e[q]=b,q+=1):2048>b?(e[q]=192|b>>>6,e[q+1]=128|b&63,q+=2):(e[q]=224|b>>>12&15,e[q+1]=128|b>>>6&63,e[q+2]=128|b&63,q+=3)}else for("binary"!==m&&n.log("unknown encoding: "+m),c=d.length,e=new Uint8Array(new ArrayBuffer(c)),a=0;a<c;a+=1)e[a]=d.charCodeAt(a)&255;return c=e};this.byteArrayToString=Runtime.byteArrayToString;this.getVariable=Runtime.getVariable; -this.fromJson=Runtime.fromJson;this.toJson=Runtime.toJson;this.readFile=r;this.read=function(d,m,c,e){r(d,"binary",function(a,b){var q=null;if(b){if("string"===typeof b)throw"This should not happen.";q=b.subarray(m,m+c)}e(a,q)})};this.readFileSync=function(d,m){var c=p(d,m,!1),e;try{c.send(null);e=f(d,m,c);if(e.err)throw e.err;if(null===e.data)throw"No data read from "+d+".";}catch(a){throw a;}return e.data};this.writeFile=function(d,m,c){h[d]=m;var e=new XMLHttpRequest,a;e.open("PUT",d,!0);e.onreadystatechange= -function(){4===e.readyState&&(0!==e.status||e.responseText?200<=e.status&&300>e.status||0===e.status?c(null):c("Status "+String(e.status)+": "+e.responseText||e.statusText):c("File "+d+" is empty."))};a=m.buffer&&!e.sendAsBinary?m.buffer:n.byteArrayToString(m,"binary");try{e.sendAsBinary?e.sendAsBinary(a):e.send(a)}catch(b){n.log("HUH? "+b+" "+m),c(b.message)}};this.deleteFile=function(d,m){delete h[d];var c=new XMLHttpRequest;c.open("DELETE",d,!0);c.onreadystatechange=function(){4===c.readyState&& -(200>c.status&&300<=c.status?m(c.responseText):m(null))};c.send(null)};this.loadXML=function(d,m){var c=new XMLHttpRequest;c.open("GET",d,!0);c.overrideMimeType&&c.overrideMimeType("text/xml");c.onreadystatechange=function(){4===c.readyState&&(0!==c.status||c.responseText?200===c.status||0===c.status?m(null,c.responseXML):m(c.responseText,null):m("File "+d+" is empty.",null))};try{c.send(null)}catch(e){m(e.message,null)}};this.isFile=function(d,m){n.getFileSize(d,function(c){m(-1!==c)})};this.getFileSize= -function(d,m){if(h.hasOwnProperty(d)&&"string"!==typeof h[d])m(h[d].length);else{var c=new XMLHttpRequest;c.open("HEAD",d,!0);c.onreadystatechange=function(){if(4===c.readyState){var e=c.getResponseHeader("Content-Length");e?m(parseInt(e,10)):r(d,"binary",function(a,b){a?m(-1):m(b.length)})}};c.send(null)}};this.log=l;this.assert=function(d,m,c){if(!d)throw l("alert","ASSERTION FAILED:\n"+m),c&&c(),m;};this.setTimeout=function(d,m){return setTimeout(function(){d()},m)};this.clearTimeout=function(d){clearTimeout(d)}; -this.libraryPaths=function(){return["lib"]};this.setCurrentDirectory=function(){};this.currentDirectory=function(){return""};this.type=function(){return"BrowserRuntime"};this.getDOMImplementation=function(){return window.document.implementation};this.parseXML=function(d){return(new DOMParser).parseFromString(d,"text/xml")};this.exit=function(d){l("Calling exit with code "+String(d)+", but exit() is not implemented.")};this.getWindow=function(){return window}} -function NodeJSRuntime(){function g(d){var c=d.length,e,a=new Uint8Array(new ArrayBuffer(c));for(e=0;e<c;e+=1)a[e]=d[e];return a}function l(d,c,e){function a(a,c){if(a)return e(a,null);if(!c)return e("No data for "+d+".",null);if("string"===typeof c)return e(a,c);e(a,g(c))}d=r.resolve(n,d);"binary"!==c?p.readFile(d,c,a):p.readFile(d,null,a)}var f=this,p=require("fs"),r=require("path"),n="",h,d;this.byteArrayFromString=function(d,c){var e=new Buffer(d,c),a,b=e.length,q=new Uint8Array(new ArrayBuffer(b)); -for(a=0;a<b;a+=1)q[a]=e[a];return q};this.byteArrayToString=Runtime.byteArrayToString;this.getVariable=Runtime.getVariable;this.fromJson=Runtime.fromJson;this.toJson=Runtime.toJson;this.readFile=l;this.loadXML=function(d,c){l(d,"utf-8",function(e,a){if(e)return c(e,null);if(!a)return c("No data for "+d+".",null);c(null,f.parseXML(a))})};this.writeFile=function(d,c,e){c=new Buffer(c);d=r.resolve(n,d);p.writeFile(d,c,"binary",function(a){e(a||null)})};this.deleteFile=function(d,c){d=r.resolve(n,d); -p.unlink(d,c)};this.read=function(d,c,e,a){d=r.resolve(n,d);p.open(d,"r+",666,function(b,q){if(b)a(b,null);else{var k=new Buffer(e);p.read(q,k,0,e,c,function(b){p.close(q);a(b,g(k))})}})};this.readFileSync=function(d,c){var e;e=p.readFileSync(d,"binary"===c?null:c);if(null===e)throw"File "+d+" could not be read.";"binary"===c&&(e=g(e));return e};this.isFile=function(d,c){d=r.resolve(n,d);p.stat(d,function(e,a){c(!e&&a.isFile())})};this.getFileSize=function(d,c){d=r.resolve(n,d);p.stat(d,function(e, -a){e?c(-1):c(a.size)})};this.log=function(d,c){var e;void 0!==c?e=d:c=d;"alert"===e&&process.stderr.write("\n!!!!! ALERT !!!!!\n");process.stderr.write(c+"\n");"alert"===e&&process.stderr.write("!!!!! ALERT !!!!!\n")};this.assert=function(d,c,e){d||(process.stderr.write("ASSERTION FAILED: "+c),e&&e())};this.setTimeout=function(d,c){return setTimeout(function(){d()},c)};this.clearTimeout=function(d){clearTimeout(d)};this.libraryPaths=function(){return[__dirname]};this.setCurrentDirectory=function(d){n= -d};this.currentDirectory=function(){return n};this.type=function(){return"NodeJSRuntime"};this.getDOMImplementation=function(){return d};this.parseXML=function(d){return h.parseFromString(d,"text/xml")};this.exit=process.exit;this.getWindow=function(){return null};h=new (require("xmldom").DOMParser);d=f.parseXML("<a/>").implementation} -function RhinoRuntime(){function g(d,h){var c;void 0!==h?c=d:h=d;"alert"===c&&print("\n!!!!! ALERT !!!!!");print(h);"alert"===c&&print("!!!!! ALERT !!!!!")}var l=this,f={},p=f.javax.xml.parsers.DocumentBuilderFactory.newInstance(),r,n,h="";p.setValidating(!1);p.setNamespaceAware(!0);p.setExpandEntityReferences(!1);p.setSchema(null);n=f.org.xml.sax.EntityResolver({resolveEntity:function(d,h){var c=new f.java.io.FileReader(h);return new f.org.xml.sax.InputSource(c)}});r=p.newDocumentBuilder();r.setEntityResolver(n); -this.byteArrayFromString=function(d,h){var c,e=d.length,a=new Uint8Array(new ArrayBuffer(e));for(c=0;c<e;c+=1)a[c]=d.charCodeAt(c)&255;return a};this.byteArrayToString=Runtime.byteArrayToString;this.getVariable=Runtime.getVariable;this.fromJson=Runtime.fromJson;this.toJson=Runtime.toJson;this.loadXML=function(d,h){var c=new f.java.io.File(d),e=null;try{e=r.parse(c)}catch(a){return print(a),h(a,null)}h(null,e)};this.readFile=function(d,m,c){h&&(d=h+"/"+d);var e=new f.java.io.File(d),a="binary"===m? -"latin1":m;e.isFile()?((d=readFile(d,a))&&"binary"===m&&(d=l.byteArrayFromString(d,"binary")),c(null,d)):c(d+" is not a file.",null)};this.writeFile=function(d,m,c){h&&(d=h+"/"+d);d=new f.java.io.FileOutputStream(d);var e,a=m.length;for(e=0;e<a;e+=1)d.write(m[e]);d.close();c(null)};this.deleteFile=function(d,m){h&&(d=h+"/"+d);var c=new f.java.io.File(d),e=d+Math.random(),e=new f.java.io.File(e);c.rename(e)?(e.deleteOnExit(),m(null)):m("Could not delete "+d)};this.read=function(d,m,c,e){h&&(d=h+"/"+ -d);var a;a=d;var b="binary";(new f.java.io.File(a)).isFile()?("binary"===b&&(b="latin1"),a=readFile(a,b)):a=null;a?e(null,this.byteArrayFromString(a.substring(m,m+c),"binary")):e("Cannot read "+d,null)};this.readFileSync=function(d,h){if(!h)return"";var c=readFile(d,h);if(null===c)throw"File could not be read.";return c};this.isFile=function(d,m){h&&(d=h+"/"+d);var c=new f.java.io.File(d);m(c.isFile())};this.getFileSize=function(d,m){h&&(d=h+"/"+d);var c=new f.java.io.File(d);m(c.length())};this.log= -g;this.assert=function(d,h,c){d||(g("alert","ASSERTION FAILED: "+h),c&&c())};this.setTimeout=function(d){d();return 0};this.clearTimeout=function(){};this.libraryPaths=function(){return["lib"]};this.setCurrentDirectory=function(d){h=d};this.currentDirectory=function(){return h};this.type=function(){return"RhinoRuntime"};this.getDOMImplementation=function(){return r.getDOMImplementation()};this.parseXML=function(d){d=new f.java.io.StringReader(d);d=new f.org.xml.sax.InputSource(d);return r.parse(d)}; -this.exit=quit;this.getWindow=function(){return null}}Runtime.create=function(){return"undefined"!==String(typeof window)?new BrowserRuntime(window.document.getElementById("logoutput")):"undefined"!==String(typeof require)?new NodeJSRuntime:new RhinoRuntime};var runtime=Runtime.create(),core={},gui={},xmldom={},odf={},ops={}; -(function(){function g(h,d){var f=h+"/manifest.json",c,e;if(!n.hasOwnProperty(f)){n[f]=1;try{c=runtime.readFileSync(f,"utf-8")}catch(a){console.log(String(a));return}f=JSON.parse(c);for(e in f)f.hasOwnProperty(e)&&(d[e]={dir:h,deps:f[e]})}}function l(h,d,f){var c=d[h].deps,e={};f[h]=e;c.forEach(function(a){e[a]=1});c.forEach(function(a){f[a]||l(a,d,f)});c.forEach(function(a){Object.keys(f[a]).forEach(function(a){e[a]=1})})}function f(h,d){function f(a,b){var c,k=d[a];if(-1===e.indexOf(a)&&-1===b.indexOf(a)){b.push(a); -for(c=0;c<h.length;c+=1)k[h[c]]&&f(h[c],b);b.pop();e.push(a)}}var c,e=[];for(c=0;c<h.length;c+=1)f(h[c],[]);return e}function p(h,d){for(var f=0;f<h.length&&void 0!==d[f];)null!==d[f]&&(eval(d[f]),d[f]=null),f+=1}var r={},n={};runtime.loadClass=function(h){if(!IS_COMPILED_CODE){var d=h.replace(".","/")+".js";if(!n.hasOwnProperty(d)){if(!(0<Object.keys(r).length)){var m=runtime.libraryPaths(),d={},c;runtime.currentDirectory()&&g(runtime.currentDirectory(),d);for(c=0;c<m.length;c+=1)g(m[c],d);var e; -c={};for(e in d)d.hasOwnProperty(e)&&l(e,d,c);for(e in d)d.hasOwnProperty(e)&&(m=Object.keys(c[e]),d[e].deps=f(m,c),d[e].deps.push(e));r=d}e=h.replace(".","/")+".js";h=[];e=r[e].deps;for(d=0;d<e.length;d+=1)n.hasOwnProperty(e[d])||h.push(e[d]);e=[];e.length=h.length;for(d=h.length-1;0<=d;d-=1)n[h[d]]=1,void 0===e[d]&&(m=h[d],m=r[m].dir+"/"+m,c=runtime.readFileSync(m,"utf-8"),c+="\n//# sourceURL="+m,c+="\n//@ sourceURL="+m,e[d]=c);p(h,e)}}}})(); -(function(){var g=function(g){return g};runtime.getTranslator=function(){return g};runtime.setTranslator=function(l){g=l};runtime.tr=function(l){var f=g(l);return f&&"string"===String(typeof f)?f:l}})(); -(function(g){function l(f){if(f.length){var g=f[0];runtime.readFile(g,"utf8",function(l,n){function h(){var c;(c=eval(m))&&runtime.exit(c)}var d="",m=n;-1!==g.indexOf("/")&&(d=g.substring(0,g.indexOf("/")));runtime.setCurrentDirectory(d);l?(runtime.log(l),runtime.exit(1)):null===m?(runtime.log("No code found for "+g),runtime.exit(1)):h.apply(null,f)})}}g=g?Array.prototype.slice.call(g):[];"NodeJSRuntime"===runtime.type()?l(process.argv.slice(2)):"RhinoRuntime"===runtime.type()?l(g):l(g.slice(1))})("undefined"!== +function Runtime(){}Runtime.prototype.getVariable=function(k){};Runtime.prototype.toJson=function(k){};Runtime.prototype.fromJson=function(k){};Runtime.prototype.byteArrayFromString=function(k,h){};Runtime.prototype.byteArrayToString=function(k,h){};Runtime.prototype.read=function(k,h,b,p){};Runtime.prototype.readFile=function(k,h,b){};Runtime.prototype.readFileSync=function(k,h){};Runtime.prototype.loadXML=function(k,h){};Runtime.prototype.writeFile=function(k,h,b){}; +Runtime.prototype.isFile=function(k,h){};Runtime.prototype.getFileSize=function(k,h){};Runtime.prototype.deleteFile=function(k,h){};Runtime.prototype.log=function(k,h){};Runtime.prototype.setTimeout=function(k,h){};Runtime.prototype.clearTimeout=function(k){};Runtime.prototype.libraryPaths=function(){};Runtime.prototype.currentDirectory=function(){};Runtime.prototype.setCurrentDirectory=function(k){};Runtime.prototype.type=function(){};Runtime.prototype.getDOMImplementation=function(){}; +Runtime.prototype.parseXML=function(k){};Runtime.prototype.exit=function(k){};Runtime.prototype.getWindow=function(){};Runtime.prototype.requestAnimationFrame=function(k){};Runtime.prototype.cancelAnimationFrame=function(k){};Runtime.prototype.assert=function(k,h,b){};var IS_COMPILED_CODE=!0; +Runtime.byteArrayToString=function(k,h){function b(b){var g="",q,d=b.length;for(q=0;q<d;q+=1)g+=String.fromCharCode(b[q]&255);return g}function p(b){var g="",q,d=b.length,l=[],f,c,a,m;for(q=0;q<d;q+=1)f=b[q],128>f?l.push(f):(q+=1,c=b[q],194<=f&&224>f?l.push((f&31)<<6|c&63):(q+=1,a=b[q],224<=f&&240>f?l.push((f&15)<<12|(c&63)<<6|a&63):(q+=1,m=b[q],240<=f&&245>f&&(f=(f&7)<<18|(c&63)<<12|(a&63)<<6|m&63,f-=65536,l.push((f>>10)+55296,(f&1023)+56320))))),1E3===l.length&&(g+=String.fromCharCode.apply(null, +l),l.length=0);return g+String.fromCharCode.apply(null,l)}var d;"utf8"===h?d=p(k):("binary"!==h&&this.log("Unsupported encoding: "+h),d=b(k));return d};Runtime.getVariable=function(k){try{return eval(k)}catch(h){}};Runtime.toJson=function(k){return JSON.stringify(k)};Runtime.fromJson=function(k){return JSON.parse(k)};Runtime.getFunctionName=function(k){return void 0===k.name?(k=/function\s+(\w+)/.exec(k))&&k[1]:k.name}; +function BrowserRuntime(k){function h(f){var c=f.length,a,m,e=0;for(a=0;a<c;a+=1)m=f.charCodeAt(a),e+=1+(128<m)+(2048<m),55040<m&&57344>m&&(e+=1,a+=1);return e}function b(f,c,a){var m=f.length,e,b;c=new Uint8Array(new ArrayBuffer(c));a?(c[0]=239,c[1]=187,c[2]=191,b=3):b=0;for(a=0;a<m;a+=1)e=f.charCodeAt(a),128>e?(c[b]=e,b+=1):2048>e?(c[b]=192|e>>>6,c[b+1]=128|e&63,b+=2):55040>=e||57344<=e?(c[b]=224|e>>>12&15,c[b+1]=128|e>>>6&63,c[b+2]=128|e&63,b+=3):(a+=1,e=(e-55296<<10|f.charCodeAt(a)-56320)+65536, +c[b]=240|e>>>18&7,c[b+1]=128|e>>>12&63,c[b+2]=128|e>>>6&63,c[b+3]=128|e&63,b+=4);return c}function p(f){var c=f.length,a=new Uint8Array(new ArrayBuffer(c)),m;for(m=0;m<c;m+=1)a[m]=f.charCodeAt(m)&255;return a}function d(f,c){var a,m,e;void 0!==c?e=f:c=f;k?(m=k.ownerDocument,e&&(a=m.createElement("span"),a.className=e,a.appendChild(m.createTextNode(e)),k.appendChild(a),k.appendChild(m.createTextNode(" "))),a=m.createElement("span"),0<c.length&&"<"===c[0]?a.innerHTML=c:a.appendChild(m.createTextNode(c)), +k.appendChild(a),k.appendChild(m.createElement("br"))):console&&console.log(c);"alert"===e&&alert(c)}function n(f,c,a){if(0!==a.status||a.responseText)if(200===a.status||0===a.status){if(a.response&&"string"!==typeof a.response)"binary"===c?(a=a.response,a=new Uint8Array(a)):a=String(a.response);else if("binary"===c)if(null!==a.responseBody&&"undefined"!==String(typeof VBArray)){a=(new VBArray(a.responseBody)).toArray();var m=a.length,e=new Uint8Array(new ArrayBuffer(m));for(c=0;c<m;c+=1)e[c]=a[c]; +a=e}else{(c=a.getResponseHeader("Content-Length"))&&(c=parseInt(c,10));if(c&&c!==a.responseText.length)a:{var m=a.responseText,e=!1,q=h(m);if("number"===typeof c){if(c!==q&&c!==q+3){m=void 0;break a}e=q+3===c;q=c}m=b(m,q,e)}void 0===m&&(m=p(a.responseText));a=m}else a=a.responseText;l[f]=a;f={err:null,data:a}}else f={err:a.responseText||a.statusText,data:null};else f={err:"File "+f+" is empty.",data:null};return f}function g(f,c,a){var m=new XMLHttpRequest;m.open("GET",f,a);m.overrideMimeType&&("binary"!== +c?m.overrideMimeType("text/plain; charset="+c):m.overrideMimeType("text/plain; charset=x-user-defined"));return m}function q(f,c,a){function m(){var m;4===e.readyState&&(m=n(f,c,e),a(m.err,m.data))}if(l.hasOwnProperty(f))a(null,l[f]);else{var e=g(f,c,!0);e.onreadystatechange=m;try{e.send(null)}catch(b){a(b.message,null)}}}var r=this,l={};this.byteArrayFromString=function(f,c){var a;"utf8"===c?a=b(f,h(f),!1):("binary"!==c&&r.log("unknown encoding: "+c),a=p(f));return a};this.byteArrayToString=Runtime.byteArrayToString; +this.getVariable=Runtime.getVariable;this.fromJson=Runtime.fromJson;this.toJson=Runtime.toJson;this.readFile=q;this.read=function(f,c,a,m){q(f,"binary",function(e,f){var b=null;if(f){if("string"===typeof f)throw"This should not happen.";b=f.subarray(c,c+a)}m(e,b)})};this.readFileSync=function(f,c){var a=g(f,c,!1),m;try{a.send(null);m=n(f,c,a);if(m.err)throw m.err;if(null===m.data)throw"No data read from "+f+".";}catch(e){throw e;}return m.data};this.writeFile=function(f,c,a){l[f]=c;var m=new XMLHttpRequest, +e;m.open("PUT",f,!0);m.onreadystatechange=function(){4===m.readyState&&(0!==m.status||m.responseText?200<=m.status&&300>m.status||0===m.status?a(null):a("Status "+String(m.status)+": "+m.responseText||m.statusText):a("File "+f+" is empty."))};e=c.buffer&&!m.sendAsBinary?c.buffer:r.byteArrayToString(c,"binary");try{m.sendAsBinary?m.sendAsBinary(e):m.send(e)}catch(b){r.log("HUH? "+b+" "+c),a(b.message)}};this.deleteFile=function(f,c){delete l[f];var a=new XMLHttpRequest;a.open("DELETE",f,!0);a.onreadystatechange= +function(){4===a.readyState&&(200>a.status&&300<=a.status?c(a.responseText):c(null))};a.send(null)};this.loadXML=function(f,c){var a=new XMLHttpRequest;a.open("GET",f,!0);a.overrideMimeType&&a.overrideMimeType("text/xml");a.onreadystatechange=function(){4===a.readyState&&(0!==a.status||a.responseText?200===a.status||0===a.status?c(null,a.responseXML):c(a.responseText,null):c("File "+f+" is empty.",null))};try{a.send(null)}catch(m){c(m.message,null)}};this.isFile=function(f,c){r.getFileSize(f,function(a){c(-1!== +a)})};this.getFileSize=function(f,c){if(l.hasOwnProperty(f)&&"string"!==typeof l[f])c(l[f].length);else{var a=new XMLHttpRequest;a.open("HEAD",f,!0);a.onreadystatechange=function(){if(4===a.readyState){var m=a.getResponseHeader("Content-Length");m?c(parseInt(m,10)):q(f,"binary",function(a,f){a?c(-1):c(f.length)})}};a.send(null)}};this.log=d;this.assert=function(f,c,a){if(!f)throw d("alert","ASSERTION FAILED:\n"+c),a&&a(),c;};this.setTimeout=function(f,c){return setTimeout(function(){f()},c)};this.clearTimeout= +function(f){clearTimeout(f)};this.libraryPaths=function(){return["lib"]};this.setCurrentDirectory=function(){};this.currentDirectory=function(){return""};this.type=function(){return"BrowserRuntime"};this.getDOMImplementation=function(){return window.document.implementation};this.parseXML=function(f){return(new DOMParser).parseFromString(f,"text/xml")};this.exit=function(f){d("Calling exit with code "+String(f)+", but exit() is not implemented.")};this.getWindow=function(){return window};this.requestAnimationFrame= +function(f){var c=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame,a=0;if(c)c.bind(window),a=c(f);else return setTimeout(f,15);return a};this.cancelAnimationFrame=function(f){var c=window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.msCancelAnimationFrame;c?(c.bind(window),c(f)):clearTimeout(f)}} +function NodeJSRuntime(){function k(b){var l=b.length,f,c=new Uint8Array(new ArrayBuffer(l));for(f=0;f<l;f+=1)c[f]=b[f];return c}function h(b,l,f){function c(a,c){if(a)return f(a,null);if(!c)return f("No data for "+b+".",null);if("string"===typeof c)return f(a,c);f(a,k(c))}b=d.resolve(n,b);"binary"!==l?p.readFile(b,l,c):p.readFile(b,null,c)}var b=this,p=require("fs"),d=require("path"),n="",g,q;this.byteArrayFromString=function(b,l){var f=new Buffer(b,l),c,a=f.length,m=new Uint8Array(new ArrayBuffer(a)); +for(c=0;c<a;c+=1)m[c]=f[c];return m};this.byteArrayToString=Runtime.byteArrayToString;this.getVariable=Runtime.getVariable;this.fromJson=Runtime.fromJson;this.toJson=Runtime.toJson;this.readFile=h;this.loadXML=function(q,l){h(q,"utf-8",function(f,c){if(f)return l(f,null);if(!c)return l("No data for "+q+".",null);l(null,b.parseXML(c))})};this.writeFile=function(b,l,f){l=new Buffer(l);b=d.resolve(n,b);p.writeFile(b,l,"binary",function(c){f(c||null)})};this.deleteFile=function(b,l){b=d.resolve(n,b); +p.unlink(b,l)};this.read=function(b,l,f,c){b=d.resolve(n,b);p.open(b,"r+",666,function(a,m){if(a)c(a,null);else{var e=new Buffer(f);p.read(m,e,0,f,l,function(a){p.close(m);c(a,k(e))})}})};this.readFileSync=function(b,l){var f;f=p.readFileSync(b,"binary"===l?null:l);if(null===f)throw"File "+b+" could not be read.";"binary"===l&&(f=k(f));return f};this.isFile=function(b,l){b=d.resolve(n,b);p.stat(b,function(f,c){l(!f&&c.isFile())})};this.getFileSize=function(b,l){b=d.resolve(n,b);p.stat(b,function(f, +c){f?l(-1):l(c.size)})};this.log=function(b,l){var f;void 0!==l?f=b:l=b;"alert"===f&&process.stderr.write("\n!!!!! ALERT !!!!!\n");process.stderr.write(l+"\n");"alert"===f&&process.stderr.write("!!!!! ALERT !!!!!\n")};this.assert=function(b,l,f){b||(process.stderr.write("ASSERTION FAILED: "+l),f&&f())};this.setTimeout=function(b,l){return setTimeout(function(){b()},l)};this.clearTimeout=function(b){clearTimeout(b)};this.libraryPaths=function(){return[__dirname]};this.setCurrentDirectory=function(b){n= +b};this.currentDirectory=function(){return n};this.type=function(){return"NodeJSRuntime"};this.getDOMImplementation=function(){return q};this.parseXML=function(b){return g.parseFromString(b,"text/xml")};this.exit=process.exit;this.getWindow=function(){return null};this.requestAnimationFrame=function(b){return setTimeout(b,15)};this.cancelAnimationFrame=function(b){clearTimeout(b)};g=new (require("xmldom").DOMParser);q=b.parseXML("<a/>").implementation} +function RhinoRuntime(){function k(b,g){var l;void 0!==g?l=b:g=b;"alert"===l&&print("\n!!!!! ALERT !!!!!");print(g);"alert"===l&&print("!!!!! ALERT !!!!!")}var h=this,b={},p=b.javax.xml.parsers.DocumentBuilderFactory.newInstance(),d,n,g="";p.setValidating(!1);p.setNamespaceAware(!0);p.setExpandEntityReferences(!1);p.setSchema(null);n=b.org.xml.sax.EntityResolver({resolveEntity:function(q,g){var l=new b.java.io.FileReader(g);return new b.org.xml.sax.InputSource(l)}});d=p.newDocumentBuilder();d.setEntityResolver(n); +this.byteArrayFromString=function(b,g){var l,f=b.length,c=new Uint8Array(new ArrayBuffer(f));for(l=0;l<f;l+=1)c[l]=b.charCodeAt(l)&255;return c};this.byteArrayToString=Runtime.byteArrayToString;this.getVariable=Runtime.getVariable;this.fromJson=Runtime.fromJson;this.toJson=Runtime.toJson;this.loadXML=function(q,g){var l=new b.java.io.File(q),f=null;try{f=d.parse(l)}catch(c){return print(c),g(c,null)}g(null,f)};this.readFile=function(q,d,l){g&&(q=g+"/"+q);var f=new b.java.io.File(q),c="binary"===d? +"latin1":d;f.isFile()?((q=readFile(q,c))&&"binary"===d&&(q=h.byteArrayFromString(q,"binary")),l(null,q)):l(q+" is not a file.",null)};this.writeFile=function(q,d,l){g&&(q=g+"/"+q);q=new b.java.io.FileOutputStream(q);var f,c=d.length;for(f=0;f<c;f+=1)q.write(d[f]);q.close();l(null)};this.deleteFile=function(q,d){g&&(q=g+"/"+q);var l=new b.java.io.File(q),f=q+Math.random(),f=new b.java.io.File(f);l.rename(f)?(f.deleteOnExit(),d(null)):d("Could not delete "+q)};this.read=function(q,d,l,f){g&&(q=g+"/"+ +q);var c;c=q;var a="binary";(new b.java.io.File(c)).isFile()?("binary"===a&&(a="latin1"),c=readFile(c,a)):c=null;c?f(null,this.byteArrayFromString(c.substring(d,d+l),"binary")):f("Cannot read "+q,null)};this.readFileSync=function(b,d){if(!d)return"";var l=readFile(b,d);if(null===l)throw"File could not be read.";return l};this.isFile=function(d,h){g&&(d=g+"/"+d);var l=new b.java.io.File(d);h(l.isFile())};this.getFileSize=function(d,h){g&&(d=g+"/"+d);var l=new b.java.io.File(d);h(l.length())};this.log= +k;this.assert=function(b,d,l){b||(k("alert","ASSERTION FAILED: "+d),l&&l())};this.setTimeout=function(b){b();return 0};this.clearTimeout=function(){};this.libraryPaths=function(){return["lib"]};this.setCurrentDirectory=function(b){g=b};this.currentDirectory=function(){return g};this.type=function(){return"RhinoRuntime"};this.getDOMImplementation=function(){return d.getDOMImplementation()};this.parseXML=function(g){g=new b.java.io.StringReader(g);g=new b.org.xml.sax.InputSource(g);return d.parse(g)}; +this.exit=quit;this.getWindow=function(){return null};this.requestAnimationFrame=function(b){b();return 0};this.cancelAnimationFrame=function(){}}Runtime.create=function(){return"undefined"!==String(typeof window)?new BrowserRuntime(window.document.getElementById("logoutput")):"undefined"!==String(typeof require)?new NodeJSRuntime:new RhinoRuntime};var runtime=Runtime.create(),core={},gui={},xmldom={},odf={},ops={}; +(function(){function k(b,d,l){var f=b+"/manifest.json",c,a;runtime.log("Loading manifest: "+f);try{c=runtime.readFileSync(f,"utf-8")}catch(m){if(l)runtime.log("No loadable manifest found.");else throw console.log(String(m)),m;return}l=JSON.parse(c);for(a in l)l.hasOwnProperty(a)&&(d[a]={dir:b,deps:l[a]})}function h(b,d,l){function f(e){if(!m[e]&&!l(e)){if(a[e])throw"Circular dependency detected for "+e+".";a[e]=!0;if(!d[e])throw"Missing dependency information for class "+e+".";var b=d[e],g=b.deps, +h,q=g.length;for(h=0;h<q;h+=1)f(g[h]);a[e]=!1;m[e]=!0;c.push(b.dir+"/"+e.replace(".","/")+".js")}}var c=[],a={},m={};b.forEach(f);return c}function b(b,d){return d=d+("\n//# sourceURL="+b)+("\n//@ sourceURL="+b)}function p(d){var g,l;for(g=0;g<d.length;g+=1)l=runtime.readFileSync(d[g],"utf-8"),l=b(d[g],l),eval(l)}function d(b){b=b.split(".");var d,l=g,f=b.length;for(d=0;d<f;d+=1){if(!l.hasOwnProperty(b[d]))return!1;l=l[b[d]]}return!0}var n,g={core:core,gui:gui,xmldom:xmldom,odf:odf,ops:ops};runtime.loadClasses= +function(b,g){if(IS_COMPILED_CODE||0===b.length)return g&&g();var l;if(!(l=n)){l=[];var f=runtime.libraryPaths(),c;runtime.currentDirectory()&&-1===f.indexOf(runtime.currentDirectory())&&k(runtime.currentDirectory(),l,!0);for(c=0;c<f.length;c+=1)k(f[c],l)}n=l;b=h(b,n,d);if(0===b.length)return g&&g();if("BrowserRuntime"===runtime.type()&&g){l=b;f=document.currentScript||document.documentElement.lastChild;c=document.createDocumentFragment();var a,m;for(m=0;m<l.length;m+=1)a=document.createElement("script"), +a.type="text/javascript",a.charset="utf-8",a.async=!1,a.setAttribute("src",l[m]),c.appendChild(a);g&&(a.onload=g);f.parentNode.insertBefore(c,f)}else p(b),g&&g()};runtime.loadClass=function(b,d){runtime.loadClasses([b],d)}})();(function(){var k=function(h){return h};runtime.getTranslator=function(){return k};runtime.setTranslator=function(h){k=h};runtime.tr=function(h){var b=k(h);return b&&"string"===String(typeof b)?b:h}})(); +(function(k){function h(b){if(b.length){var h=b[0];runtime.readFile(h,"utf8",function(d,n){function g(){var b;(b=eval(k))&&runtime.exit(b)}var q="",q=h.lastIndexOf("/"),k=n,q=-1!==q?h.substring(0,q):".";runtime.setCurrentDirectory(q);d?(runtime.log(d),runtime.exit(1)):null===k?(runtime.log("No code found for "+h),runtime.exit(1)):g.apply(null,b)})}}k=k?Array.prototype.slice.call(k):[];"NodeJSRuntime"===runtime.type()?h(process.argv.slice(2)):"RhinoRuntime"===runtime.type()?h(k):h(k.slice(1))})("undefined"!== String(typeof arguments)&&arguments); // Input 2 -core.Async=function(){this.forEach=function(g,l,f){function p(d){h!==n&&(d?(h=n,f(d)):(h+=1,h===n&&f(null)))}var r,n=g.length,h=0;for(r=0;r<n;r+=1)l(g[r],p)};this.destroyAll=function(g,l){function f(p,r){if(r)l(r);else if(p<g.length)g[p](function(g){f(p+1,g)});else l()}f(0,void 0)}}; +core.Async=function(){this.forEach=function(k,h,b){function p(d){g!==n&&(d?(g=n,b(d)):(g+=1,g===n&&b(null)))}var d,n=k.length,g=0;for(d=0;d<n;d+=1)h(k[d],p)};this.destroyAll=function(k,h){function b(p,d){if(d)h(d);else if(p<k.length)k[p](function(d){b(p+1,d)});else h()}b(0,void 0)}}; // Input 3 -function makeBase64(){function g(a){var b,c=a.length,e=new Uint8Array(new ArrayBuffer(c));for(b=0;b<c;b+=1)e[b]=a.charCodeAt(b)&255;return e}function l(a){var b,c="",e,q=a.length-2;for(e=0;e<q;e+=3)b=a[e]<<16|a[e+1]<<8|a[e+2],c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b>>>18],c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b>>>12&63],c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b>>>6&63],c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b& -63];e===q+1?(b=a[e]<<4,c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b>>>6],c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b&63],c+="=="):e===q&&(b=a[e]<<10|a[e+1]<<2,c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b>>>12],c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b>>>6&63],c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[b&63],c+="=");return c}function f(a){a=a.replace(/[^A-Za-z0-9+\/]+/g, -"");var b=a.length,c=new Uint8Array(new ArrayBuffer(3*b)),e=a.length%4,q=0,d,f;for(d=0;d<b;d+=4)f=(k[a.charAt(d)]||0)<<18|(k[a.charAt(d+1)]||0)<<12|(k[a.charAt(d+2)]||0)<<6|(k[a.charAt(d+3)]||0),c[q]=f>>16,c[q+1]=f>>8&255,c[q+2]=f&255,q+=3;b=3*b-[0,0,2,1][e];return c.subarray(0,b)}function p(a){var b,c,e=a.length,q=0,k=new Uint8Array(new ArrayBuffer(3*e));for(b=0;b<e;b+=1)c=a[b],128>c?k[q++]=c:(2048>c?k[q++]=192|c>>>6:(k[q++]=224|c>>>12&15,k[q++]=128|c>>>6&63),k[q++]=128|c&63);return k.subarray(0, -q)}function r(a){var b,c,e,q,k=a.length,d=new Uint8Array(new ArrayBuffer(k)),f=0;for(b=0;b<k;b+=1)c=a[b],128>c?d[f++]=c:(b+=1,e=a[b],224>c?d[f++]=(c&31)<<6|e&63:(b+=1,q=a[b],d[f++]=(c&15)<<12|(e&63)<<6|q&63));return d.subarray(0,f)}function n(a){return l(g(a))}function h(a){return String.fromCharCode.apply(String,f(a))}function d(a){return r(g(a))}function m(a){a=r(a);for(var b="",c=0;c<a.length;)b+=String.fromCharCode.apply(String,a.subarray(c,c+45E3)),c+=45E3;return b}function c(a,b,c){var e,q, -k,d="";for(k=b;k<c;k+=1)b=a.charCodeAt(k)&255,128>b?d+=String.fromCharCode(b):(k+=1,e=a.charCodeAt(k)&255,224>b?d+=String.fromCharCode((b&31)<<6|e&63):(k+=1,q=a.charCodeAt(k)&255,d+=String.fromCharCode((b&15)<<12|(e&63)<<6|q&63)));return d}function e(a,b){function e(){var d=k+1E5;d>a.length&&(d=a.length);q+=c(a,k,d);k=d;d=k===a.length;b(q,d)&&!d&&runtime.setTimeout(e,0)}var q="",k=0;1E5>a.length?b(c(a,0,a.length),!0):("string"!==typeof a&&(a=a.slice()),e())}function a(a){return p(g(a))}function b(a){return String.fromCharCode.apply(String, -p(a))}function q(a){return String.fromCharCode.apply(String,p(g(a)))}var k=function(a){var b={},c,e;c=0;for(e=a.length;c<e;c+=1)b[a.charAt(c)]=c;return b}("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),t,A,w=runtime.getWindow(),x,v;w&&w.btoa?(x=w.btoa,t=function(a){return x(q(a))}):(x=n,t=function(b){return l(a(b))});w&&w.atob?(v=w.atob,A=function(a){a=v(a);return c(a,0,a.length)}):(v=h,A=function(a){return m(f(a))});core.Base64=function(){this.convertByteArrayToBase64=this.convertUTF8ArrayToBase64= -l;this.convertBase64ToByteArray=this.convertBase64ToUTF8Array=f;this.convertUTF16ArrayToByteArray=this.convertUTF16ArrayToUTF8Array=p;this.convertByteArrayToUTF16Array=this.convertUTF8ArrayToUTF16Array=r;this.convertUTF8StringToBase64=n;this.convertBase64ToUTF8String=h;this.convertUTF8StringToUTF16Array=d;this.convertByteArrayToUTF16String=this.convertUTF8ArrayToUTF16String=m;this.convertUTF8StringToUTF16String=e;this.convertUTF16StringToByteArray=this.convertUTF16StringToUTF8Array=a;this.convertUTF16ArrayToUTF8String= -b;this.convertUTF16StringToUTF8String=q;this.convertUTF16StringToBase64=t;this.convertBase64ToUTF16String=A;this.fromBase64=h;this.toBase64=n;this.atob=v;this.btoa=x;this.utob=q;this.btou=e;this.encode=t;this.encodeURI=function(a){return t(a).replace(/[+\/]/g,function(a){return"+"===a?"-":"_"}).replace(/\\=+$/,"")};this.decode=function(a){return A(a.replace(/[\-_]/g,function(a){return"-"===a?"+":"/"}))};return this};return core.Base64}core.Base64=makeBase64(); +function makeBase64(){function k(a){var c,e=a.length,f=new Uint8Array(new ArrayBuffer(e));for(c=0;c<e;c+=1)f[c]=a.charCodeAt(c)&255;return f}function h(a){var c,e="",f,b=a.length-2;for(f=0;f<b;f+=3)c=a[f]<<16|a[f+1]<<8|a[f+2],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c>>>18],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c>>>12&63],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c>>>6&63],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c& +63];f===b+1?(c=a[f]<<4,e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c>>>6],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c&63],e+="=="):f===b&&(c=a[f]<<10|a[f+1]<<2,e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c>>>12],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c>>>6&63],e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c&63],e+="=");return e}function b(a){a=a.replace(/[^A-Za-z0-9+\/]+/g, +"");var c=a.length,f=new Uint8Array(new ArrayBuffer(3*c)),b=a.length%4,m=0,d,g;for(d=0;d<c;d+=4)g=(e[a.charAt(d)]||0)<<18|(e[a.charAt(d+1)]||0)<<12|(e[a.charAt(d+2)]||0)<<6|(e[a.charAt(d+3)]||0),f[m]=g>>16,f[m+1]=g>>8&255,f[m+2]=g&255,m+=3;c=3*c-[0,0,2,1][b];return f.subarray(0,c)}function p(a){var c,e,f=a.length,b=0,m=new Uint8Array(new ArrayBuffer(3*f));for(c=0;c<f;c+=1)e=a[c],128>e?m[b++]=e:(2048>e?m[b++]=192|e>>>6:(m[b++]=224|e>>>12&15,m[b++]=128|e>>>6&63),m[b++]=128|e&63);return m.subarray(0, +b)}function d(a){var c,e,f,b,m=a.length,d=new Uint8Array(new ArrayBuffer(m)),g=0;for(c=0;c<m;c+=1)e=a[c],128>e?d[g++]=e:(c+=1,f=a[c],224>e?d[g++]=(e&31)<<6|f&63:(c+=1,b=a[c],d[g++]=(e&15)<<12|(f&63)<<6|b&63));return d.subarray(0,g)}function n(a){return h(k(a))}function g(a){return String.fromCharCode.apply(String,b(a))}function q(a){return d(k(a))}function r(a){a=d(a);for(var c="",e=0;e<a.length;)c+=String.fromCharCode.apply(String,a.subarray(e,e+45E3)),e+=45E3;return c}function l(a,c,e){var f,b, +m,d="";for(m=c;m<e;m+=1)c=a.charCodeAt(m)&255,128>c?d+=String.fromCharCode(c):(m+=1,f=a.charCodeAt(m)&255,224>c?d+=String.fromCharCode((c&31)<<6|f&63):(m+=1,b=a.charCodeAt(m)&255,d+=String.fromCharCode((c&15)<<12|(f&63)<<6|b&63)));return d}function f(a,c){function e(){var m=b+1E5;m>a.length&&(m=a.length);f+=l(a,b,m);b=m;m=b===a.length;c(f,m)&&!m&&runtime.setTimeout(e,0)}var f="",b=0;1E5>a.length?c(l(a,0,a.length),!0):("string"!==typeof a&&(a=a.slice()),e())}function c(a){return p(k(a))}function a(a){return String.fromCharCode.apply(String, +p(a))}function m(a){return String.fromCharCode.apply(String,p(k(a)))}var e=function(a){var c={},e,f;e=0;for(f=a.length;e<f;e+=1)c[a.charAt(e)]=e;return c}("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"),t,w,z=runtime.getWindow(),x,v;z&&z.btoa?(x=z.btoa,t=function(a){return x(m(a))}):(x=n,t=function(a){return h(c(a))});z&&z.atob?(v=z.atob,w=function(a){a=v(a);return l(a,0,a.length)}):(v=g,w=function(a){return r(b(a))});core.Base64=function(){this.convertByteArrayToBase64=this.convertUTF8ArrayToBase64= +h;this.convertBase64ToByteArray=this.convertBase64ToUTF8Array=b;this.convertUTF16ArrayToByteArray=this.convertUTF16ArrayToUTF8Array=p;this.convertByteArrayToUTF16Array=this.convertUTF8ArrayToUTF16Array=d;this.convertUTF8StringToBase64=n;this.convertBase64ToUTF8String=g;this.convertUTF8StringToUTF16Array=q;this.convertByteArrayToUTF16String=this.convertUTF8ArrayToUTF16String=r;this.convertUTF8StringToUTF16String=f;this.convertUTF16StringToByteArray=this.convertUTF16StringToUTF8Array=c;this.convertUTF16ArrayToUTF8String= +a;this.convertUTF16StringToUTF8String=m;this.convertUTF16StringToBase64=t;this.convertBase64ToUTF16String=w;this.fromBase64=g;this.toBase64=n;this.atob=v;this.btoa=x;this.utob=m;this.btou=f;this.encode=t;this.encodeURI=function(a){return t(a).replace(/[+\/]/g,function(a){return"+"===a?"-":"_"}).replace(/\\=+$/,"")};this.decode=function(a){return w(a.replace(/[\-_]/g,function(a){return"-"===a?"+":"/"}))};return this};return core.Base64}core.Base64=makeBase64(); // Input 4 -core.ByteArray=function(g){this.pos=0;this.data=g;this.readUInt32LE=function(){this.pos+=4;var g=this.data,f=this.pos;return g[--f]<<24|g[--f]<<16|g[--f]<<8|g[--f]};this.readUInt16LE=function(){this.pos+=2;var g=this.data,f=this.pos;return g[--f]<<8|g[--f]}}; +core.ByteArray=function(k){this.pos=0;this.data=k;this.readUInt32LE=function(){this.pos+=4;var h=this.data,b=this.pos;return h[--b]<<24|h[--b]<<16|h[--b]<<8|h[--b]};this.readUInt16LE=function(){this.pos+=2;var h=this.data,b=this.pos;return h[--b]<<8|h[--b]}}; // Input 5 -core.ByteArrayWriter=function(g){function l(f){f>r-p&&(r=Math.max(2*r,p+f),f=new Uint8Array(new ArrayBuffer(r)),f.set(n),n=f)}var f=this,p=0,r=1024,n=new Uint8Array(new ArrayBuffer(r));this.appendByteArrayWriter=function(h){f.appendByteArray(h.getByteArray())};this.appendByteArray=function(f){var d=f.length;l(d);n.set(f,p);p+=d};this.appendArray=function(f){var d=f.length;l(d);n.set(f,p);p+=d};this.appendUInt16LE=function(h){f.appendArray([h&255,h>>8&255])};this.appendUInt32LE=function(h){f.appendArray([h& -255,h>>8&255,h>>16&255,h>>24&255])};this.appendString=function(h){f.appendByteArray(runtime.byteArrayFromString(h,g))};this.getLength=function(){return p};this.getByteArray=function(){var f=new Uint8Array(new ArrayBuffer(p));f.set(n.subarray(0,p));return f}}; +core.ByteArrayWriter=function(k){function h(b){b>d-p&&(d=Math.max(2*d,p+b),b=new Uint8Array(new ArrayBuffer(d)),b.set(n),n=b)}var b=this,p=0,d=1024,n=new Uint8Array(new ArrayBuffer(d));this.appendByteArrayWriter=function(d){b.appendByteArray(d.getByteArray())};this.appendByteArray=function(b){var d=b.length;h(d);n.set(b,p);p+=d};this.appendArray=function(b){var d=b.length;h(d);n.set(b,p);p+=d};this.appendUInt16LE=function(d){b.appendArray([d&255,d>>8&255])};this.appendUInt32LE=function(d){b.appendArray([d& +255,d>>8&255,d>>16&255,d>>24&255])};this.appendString=function(d){b.appendByteArray(runtime.byteArrayFromString(d,k))};this.getLength=function(){return p};this.getByteArray=function(){var b=new Uint8Array(new ArrayBuffer(p));b.set(n.subarray(0,p));return b}}; // Input 6 -core.CSSUnits=function(){var g=this,l={"in":1,cm:2.54,mm:25.4,pt:72,pc:12};this.convert=function(f,g,r){return f*l[r]/l[g]};this.convertMeasure=function(f,l){var r,n;f&&l?(r=parseFloat(f),n=f.replace(r.toString(),""),r=g.convert(r,n,l).toString()):r="";return r};this.getUnits=function(f){return f.substr(f.length-2,f.length)}}; +core.CSSUnits=function(){var k=this,h={"in":1,cm:2.54,mm:25.4,pt:72,pc:12};this.convert=function(b,k,d){return b*h[d]/h[k]};this.convertMeasure=function(b,h){var d,n;b&&h?(d=parseFloat(b),n=b.replace(d.toString(),""),d=k.convert(d,n,h).toString()):d="";return d};this.getUnits=function(b){return b.substr(b.length-2,b.length)}}; // Input 7 /* @@ -88,18 +90,65 @@ core.CSSUnits=function(){var g=this,l={"in":1,cm:2.54,mm:25.4,pt:72,pc:12};this. @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -(function(){function g(){var f,g,r,n,h;void 0===l&&(h=(f=runtime.getWindow())&&f.document,l={rangeBCRIgnoresElementBCR:!1,unscaledRangeClientRects:!1},h&&(n=h.createElement("div"),n.style.position="absolute",n.style.left="-99999px",n.style.transform="scale(2)",n.style["-webkit-transform"]="scale(2)",g=h.createElement("div"),n.appendChild(g),h.body.appendChild(n),f=h.createRange(),f.selectNode(g),l.rangeBCRIgnoresElementBCR=0===f.getClientRects().length,g.appendChild(h.createTextNode("Rect transform test")), -g=g.getBoundingClientRect(),r=f.getBoundingClientRect(),l.unscaledRangeClientRects=2<Math.abs(g.height-r.height),f.detach(),h.body.removeChild(n),f=Object.keys(l).map(function(d){return d+":"+String(l[d])}).join(", "),runtime.log("Detected browser quirks - "+f)));return l}var l;core.DomUtils=function(){function f(a,b){return 0>=a.compareBoundaryPoints(Range.START_TO_START,b)&&0<=a.compareBoundaryPoints(Range.END_TO_END,b)}function l(a,b){return 0>=a.compareBoundaryPoints(Range.END_TO_START,b)&&0<= -a.compareBoundaryPoints(Range.START_TO_END,b)}function r(a,b){var c=null;a.nodeType===Node.TEXT_NODE&&(0===a.length?(a.parentNode.removeChild(a),b.nodeType===Node.TEXT_NODE&&(c=b)):(b.nodeType===Node.TEXT_NODE&&(a.appendData(b.data),b.parentNode.removeChild(b)),c=a));return c}function n(a){for(var b=a.parentNode;a.firstChild;)b.insertBefore(a.firstChild,a);b.removeChild(a);return b}function h(a,b){for(var c=a.parentNode,e=a.firstChild,d;e;)d=e.nextSibling,h(e,b),e=d;b(a)&&(c=n(a));return c}function d(a, -b){return a===b||Boolean(a.compareDocumentPosition(b)&Node.DOCUMENT_POSITION_CONTAINED_BY)}function m(a,b){for(var c=0,e;a.parentNode!==b;)runtime.assert(null!==a.parentNode,"parent is null"),a=a.parentNode;for(e=b.firstChild;e!==a;)c+=1,e=e.nextSibling;return c}function c(a,b,e){Object.keys(b).forEach(function(k){var d=k.split(":"),f=d[1],h=e(d[0]),d=b[k];"object"===typeof d&&Object.keys(d).length?(k=h?a.getElementsByTagNameNS(h,f)[0]||a.ownerDocument.createElementNS(h,k):a.getElementsByTagName(f)[0]|| -a.ownerDocument.createElement(k),a.appendChild(k),c(k,d,e)):h&&a.setAttributeNS(h,k,String(d))})}var e=null;this.splitBoundaries=function(a){var b=[],c,e;if(a.startContainer.nodeType===Node.TEXT_NODE||a.endContainer.nodeType===Node.TEXT_NODE){if(c=a.endContainer){c=a.endOffset;e=a.endContainer;if(c<e.childNodes.length)for(e=e.childNodes.item(c),c=0;e.firstChild;)e=e.firstChild;else for(;e.lastChild;)e=e.lastChild,c=e.nodeType===Node.TEXT_NODE?e.textContent.length:e.childNodes.length;c={container:e, -offset:c}}a.setEnd(c.container,c.offset);c=a.endContainer;0!==a.endOffset&&c.nodeType===Node.TEXT_NODE&&(e=c,a.endOffset!==e.length&&(b.push(e.splitText(a.endOffset)),b.push(e)));c=a.startContainer;0!==a.startOffset&&c.nodeType===Node.TEXT_NODE&&(e=c,a.startOffset!==e.length&&(c=e.splitText(a.startOffset),b.push(e),b.push(c),a.setStart(c,0)))}return b};this.containsRange=f;this.rangesIntersect=l;this.getNodesInRange=function(a,b){for(var c=[],e=a.commonAncestorContainer,d,f=a.startContainer.ownerDocument.createTreeWalker(e.nodeType=== -Node.TEXT_NODE?e.parentNode:e,NodeFilter.SHOW_ALL,b,!1),e=f.currentNode=a.startContainer;e;){d=b(e);if(d===NodeFilter.FILTER_ACCEPT)c.push(e);else if(d===NodeFilter.FILTER_REJECT)break;e=e.parentNode}c.reverse();for(e=f.nextNode();e;)c.push(e),e=f.nextNode();return c};this.normalizeTextNodes=function(a){a&&a.nextSibling&&(a=r(a,a.nextSibling));a&&a.previousSibling&&r(a.previousSibling,a)};this.rangeContainsNode=function(a,b){var c=b.ownerDocument.createRange(),e=b.ownerDocument.createRange(),d;c.setStart(a.startContainer, -a.startOffset);c.setEnd(a.endContainer,a.endOffset);e.selectNodeContents(b);d=f(c,e);c.detach();e.detach();return d};this.mergeIntoParent=n;this.removeUnwantedNodes=h;this.getElementsByTagNameNS=function(a,b,c){var e=[];a=a.getElementsByTagNameNS(b,c);e.length=c=a.length;for(b=0;b<c;b+=1)e[b]=a.item(b);return e};this.rangeIntersectsNode=function(a,b){var c=b.ownerDocument.createRange(),e;c.selectNodeContents(b);e=l(a,c);c.detach();return e};this.containsNode=function(a,b){return a===b||a.contains(b)}; -this.comparePoints=function(a,b,c,e){if(a===c)return e-b;var d=a.compareDocumentPosition(c);2===d?d=-1:4===d?d=1:10===d?(b=m(a,c),d=b<e?1:-1):(e=m(c,a),d=e<b?-1:1);return d};this.adaptRangeDifferenceToZoomLevel=function(a,b){return g().unscaledRangeClientRects?a:a/b};this.getBoundingClientRect=function(a){var b=a.ownerDocument,c=g();if((!1===c.unscaledRangeClientRects||c.rangeBCRIgnoresElementBCR)&&a.nodeType===Node.ELEMENT_NODE)return a.getBoundingClientRect();var d;e?d=e:e=d=b.createRange();b=d; -b.selectNode(a);return b.getBoundingClientRect()};this.mapKeyValObjOntoNode=function(a,b,c){Object.keys(b).forEach(function(e){var d=e.split(":"),f=d[1],d=c(d[0]),h=b[e];d?(f=a.getElementsByTagNameNS(d,f)[0],f||(f=a.ownerDocument.createElementNS(d,e),a.appendChild(f)),f.textContent=h):runtime.log("Key ignored: "+e)})};this.removeKeyElementsFromNode=function(a,b,c){b.forEach(function(b){var e=b.split(":"),d=e[1];(e=c(e[0]))?(d=a.getElementsByTagNameNS(e,d)[0])?d.parentNode.removeChild(d):runtime.log("Element for "+ -b+" not found."):runtime.log("Property Name ignored: "+b)})};this.getKeyValRepresentationOfNode=function(a,b){for(var c={},e=a.firstElementChild,d;e;){if(d=b(e.namespaceURI))c[d+":"+e.localName]=e.textContent;e=e.nextElementSibling}return c};this.mapObjOntoNode=c;(function(a){var b,c;c=runtime.getWindow();null!==c&&(b=c.navigator.appVersion.toLowerCase(),c=-1===b.indexOf("chrome")&&(-1!==b.indexOf("applewebkit")||-1!==b.indexOf("safari")),b=b.indexOf("msie"),c||b)&&(a.containsNode=d)})(this)};return core.DomUtils})(); +(function(){function k(){var b,k,d,n,g,q,r,l,f;void 0===h&&(k=(b=runtime.getWindow())&&b.document,q=k.documentElement,r=k.body,h={rangeBCRIgnoresElementBCR:!1,unscaledRangeClientRects:!1,elementBCRIgnoresBodyScroll:!1},k&&(n=k.createElement("div"),n.style.position="absolute",n.style.left="-99999px",n.style.transform="scale(2)",n.style["-webkit-transform"]="scale(2)",g=k.createElement("div"),n.appendChild(g),r.appendChild(n),b=k.createRange(),b.selectNode(g),h.rangeBCRIgnoresElementBCR=0===b.getClientRects().length, +g.appendChild(k.createTextNode("Rect transform test")),k=g.getBoundingClientRect(),d=b.getBoundingClientRect(),h.unscaledRangeClientRects=2<Math.abs(k.height-d.height),n.style.transform="",n.style["-webkit-transform"]="",k=q.style.overflow,d=r.style.overflow,l=r.style.height,f=r.scrollTop,q.style.overflow="visible",r.style.overflow="visible",r.style.height="200%",r.scrollTop=r.scrollHeight,h.elementBCRIgnoresBodyScroll=b.getBoundingClientRect().top!==g.getBoundingClientRect().top,r.scrollTop=f,r.style.height= +l,r.style.overflow=d,q.style.overflow=k,b.detach(),r.removeChild(n),b=Object.keys(h).map(function(c){return c+":"+String(h[c])}).join(", "),runtime.log("Detected browser quirks - "+b)));return h}var h;core.DomUtils=function(){function b(f,c){for(var a=0,b;f.parentNode!==c;)runtime.assert(null!==f.parentNode,"parent is null"),f=f.parentNode;for(b=c.firstChild;b!==f;)a+=1,b=b.nextSibling;return a}function h(f,c){return 0>=f.compareBoundaryPoints(Range.START_TO_START,c)&&0<=f.compareBoundaryPoints(Range.END_TO_END, +c)}function d(f,c){var a=null;f.nodeType===Node.TEXT_NODE&&(0===f.length?(f.parentNode.removeChild(f),c.nodeType===Node.TEXT_NODE&&(a=c)):(c.nodeType===Node.TEXT_NODE&&(f.appendData(c.data),c.parentNode.removeChild(c)),a=f));return a}function n(f){for(var c=f.parentNode;f.firstChild;)c.insertBefore(f.firstChild,f);c.removeChild(f);return c}function g(f,c){for(var a=f.parentNode,b=f.firstChild,e;b;)e=b.nextSibling,g(b,c),b=e;a&&c(f)&&n(f);return a}function q(b,c){return b===c||Boolean(b.compareDocumentPosition(c)& +Node.DOCUMENT_POSITION_CONTAINED_BY)}function r(b,c,a){Object.keys(c).forEach(function(m){var e=m.split(":"),d=e[1],l=a(e[0]),e=c[m],g=typeof e;"object"===g?Object.keys(e).length&&(m=l?b.getElementsByTagNameNS(l,d)[0]||b.ownerDocument.createElementNS(l,m):b.getElementsByTagName(d)[0]||b.ownerDocument.createElement(m),b.appendChild(m),r(m,e,a)):l&&(runtime.assert("number"===g||"string"===g,"attempting to map unsupported type '"+g+"' (key: "+m+")"),b.setAttributeNS(l,m,String(e)))})}var l=null;this.splitBoundaries= +function(f){var c,a=[],m,e,d;if(f.startContainer.nodeType===Node.TEXT_NODE||f.endContainer.nodeType===Node.TEXT_NODE){m=f.endContainer;e=f.endContainer.nodeType!==Node.TEXT_NODE?f.endOffset===f.endContainer.childNodes.length:!1;d=f.endOffset;c=f.endContainer;if(d<c.childNodes.length)for(c=c.childNodes.item(d),d=0;c.firstChild;)c=c.firstChild;else for(;c.lastChild;)c=c.lastChild,d=c.nodeType===Node.TEXT_NODE?c.textContent.length:c.childNodes.length;c===m&&(m=null);f.setEnd(c,d);d=f.endContainer;0!== +f.endOffset&&d.nodeType===Node.TEXT_NODE&&(c=d,f.endOffset!==c.length&&(a.push(c.splitText(f.endOffset)),a.push(c)));d=f.startContainer;0!==f.startOffset&&d.nodeType===Node.TEXT_NODE&&(c=d,f.startOffset!==c.length&&(d=c.splitText(f.startOffset),a.push(c),a.push(d),f.setStart(d,0)));if(null!==m){for(d=f.endContainer;d.parentNode&&d.parentNode!==m;)d=d.parentNode;e=e?m.childNodes.length:b(d,m);f.setEnd(m,e)}}return a};this.containsRange=h;this.rangesIntersect=function(b,c){return 0>=b.compareBoundaryPoints(Range.END_TO_START, +c)&&0<=b.compareBoundaryPoints(Range.START_TO_END,c)};this.getNodesInRange=function(b,c,a){var m=[],e=b.commonAncestorContainer;a=b.startContainer.ownerDocument.createTreeWalker(e.nodeType===Node.TEXT_NODE?e.parentNode:e,a,c,!1);var d;b.endContainer.childNodes[b.endOffset-1]?(e=b.endContainer.childNodes[b.endOffset-1],d=Node.DOCUMENT_POSITION_PRECEDING|Node.DOCUMENT_POSITION_CONTAINED_BY):(e=b.endContainer,d=Node.DOCUMENT_POSITION_PRECEDING);b.startContainer.childNodes[b.startOffset]?(b=b.startContainer.childNodes[b.startOffset], +a.currentNode=b):b.startOffset===(b.startContainer.nodeType===Node.TEXT_NODE?b.startContainer.length:b.startContainer.childNodes.length)?(b=b.startContainer,a.currentNode=b,a.lastChild(),b=a.nextNode()):(b=b.startContainer,a.currentNode=b);b&&c(b)===NodeFilter.FILTER_ACCEPT&&m.push(b);for(b=a.nextNode();b;){c=e.compareDocumentPosition(b);if(0!==c&&0===(c&d))break;m.push(b);b=a.nextNode()}return m};this.normalizeTextNodes=function(b){b&&b.nextSibling&&(b=d(b,b.nextSibling));b&&b.previousSibling&&d(b.previousSibling, +b)};this.rangeContainsNode=function(b,c){var a=c.ownerDocument.createRange(),m=c.ownerDocument.createRange(),e;a.setStart(b.startContainer,b.startOffset);a.setEnd(b.endContainer,b.endOffset);m.selectNodeContents(c);e=h(a,m);a.detach();m.detach();return e};this.mergeIntoParent=n;this.removeUnwantedNodes=g;this.getElementsByTagNameNS=function(b,c,a){var m=[];b=b.getElementsByTagNameNS(c,a);m.length=a=b.length;for(c=0;c<a;c+=1)m[c]=b.item(c);return m};this.containsNode=function(b,c){return b===c||b.contains(c)}; +this.comparePoints=function(f,c,a,m){if(f===a)return m-c;var e=f.compareDocumentPosition(a);2===e?e=-1:4===e?e=1:10===e?(c=b(f,a),e=c<m?1:-1):(m=b(a,f),e=m<c?-1:1);return e};this.adaptRangeDifferenceToZoomLevel=function(b,c){return k().unscaledRangeClientRects?b:b/c};this.getBoundingClientRect=function(b){var c=b.ownerDocument,a=k(),m=c.body;if((!1===a.unscaledRangeClientRects||a.rangeBCRIgnoresElementBCR)&&b.nodeType===Node.ELEMENT_NODE)return b=b.getBoundingClientRect(),a.elementBCRIgnoresBodyScroll? +{left:b.left+m.scrollLeft,right:b.right+m.scrollLeft,top:b.top+m.scrollTop,bottom:b.bottom+m.scrollTop}:b;var e;l?e=l:l=e=c.createRange();a=e;a.selectNode(b);return a.getBoundingClientRect()};this.mapKeyValObjOntoNode=function(b,c,a){Object.keys(c).forEach(function(m){var e=m.split(":"),d=e[1],e=a(e[0]),l=c[m];e?(d=b.getElementsByTagNameNS(e,d)[0],d||(d=b.ownerDocument.createElementNS(e,m),b.appendChild(d)),d.textContent=l):runtime.log("Key ignored: "+m)})};this.removeKeyElementsFromNode=function(b, +c,a){c.forEach(function(c){var e=c.split(":"),d=e[1];(e=a(e[0]))?(d=b.getElementsByTagNameNS(e,d)[0])?d.parentNode.removeChild(d):runtime.log("Element for "+c+" not found."):runtime.log("Property Name ignored: "+c)})};this.getKeyValRepresentationOfNode=function(b,c){for(var a={},m=b.firstElementChild,e;m;){if(e=c(m.namespaceURI))a[e+":"+m.localName]=m.textContent;m=m.nextElementSibling}return a};this.mapObjOntoNode=r;(function(b){var c,a;a=runtime.getWindow();null!==a&&(c=a.navigator.appVersion.toLowerCase(), +a=-1===c.indexOf("chrome")&&(-1!==c.indexOf("applewebkit")||-1!==c.indexOf("safari")),c=c.indexOf("msie"),a||c)&&(b.containsNode=q)})(this)};return core.DomUtils})(); // Input 8 +core.Cursor=function(k,h){function b(c){c.parentNode&&(q.push(c.previousSibling),q.push(c.nextSibling),c.parentNode.removeChild(c))}function p(c,a,b){if(a.nodeType===Node.TEXT_NODE){runtime.assert(Boolean(a),"putCursorIntoTextNode: invalid container");var e=a.parentNode;runtime.assert(Boolean(e),"putCursorIntoTextNode: container without parent");runtime.assert(0<=b&&b<=a.length,"putCursorIntoTextNode: offset is out of bounds");0===b?e.insertBefore(c,a):(b!==a.length&&a.splitText(b),e.insertBefore(c, +a.nextSibling))}else a.nodeType===Node.ELEMENT_NODE&&a.insertBefore(c,a.childNodes.item(b));q.push(c.previousSibling);q.push(c.nextSibling)}var d=k.createElementNS("urn:webodf:names:cursor","cursor"),n=k.createElementNS("urn:webodf:names:cursor","anchor"),g,q=[],r=k.createRange(),l,f=new core.DomUtils;this.getNode=function(){return d};this.getAnchorNode=function(){return n.parentNode?n:d};this.getSelectedRange=function(){l?(r.setStartBefore(d),r.collapse(!0)):(r.setStartAfter(g?n:d),r.setEndBefore(g? +d:n));return r};this.setSelectedRange=function(c,a){r&&r!==c&&r.detach();r=c;g=!1!==a;(l=c.collapsed)?(b(n),b(d),p(d,c.startContainer,c.startOffset)):(b(n),b(d),p(g?d:n,c.endContainer,c.endOffset),p(g?n:d,c.startContainer,c.startOffset));q.forEach(f.normalizeTextNodes);q.length=0};this.hasForwardSelection=function(){return g};this.remove=function(){b(d);q.forEach(f.normalizeTextNodes);q.length=0};d.setAttributeNS("urn:webodf:names:cursor","memberId",h);n.setAttributeNS("urn:webodf:names:cursor","memberId", +h)}; +// Input 9 +/* + + Copyright (C) 2012-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/ +*/ +core.Destroyable=function(){};core.Destroyable.prototype.destroy=function(k){}; +// Input 10 /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -137,9 +186,9 @@ b+" not found."):runtime.log("Property Name ignored: "+b)})};this.getKeyValRepre @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -core.EventNotifier=function(g){var l={};this.emit=function(f,g){var r,n;runtime.assert(l.hasOwnProperty(f),'unknown event fired "'+f+'"');n=l[f];for(r=0;r<n.length;r+=1)n[r](g)};this.subscribe=function(f,g){runtime.assert(l.hasOwnProperty(f),'tried to subscribe to unknown event "'+f+'"');l[f].push(g);runtime.log('event "'+f+'" subscribed.')};this.unsubscribe=function(f,g){var r;runtime.assert(l.hasOwnProperty(f),'tried to unsubscribe from unknown event "'+f+'"');r=l[f].indexOf(g);runtime.assert(-1!== -r,'tried to unsubscribe unknown callback from event "'+f+'"');-1!==r&&l[f].splice(r,1);runtime.log('event "'+f+'" unsubscribed.')};(function(){var f,p;for(f=0;f<g.length;f+=1)p=g[f],runtime.assert(!l.hasOwnProperty(p),'Duplicated event ids: "'+p+'" registered more than once.'),l[p]=[]})()}; -// Input 9 +core.EventNotifier=function(k){var h={};this.emit=function(b,k){var d,n;runtime.assert(h.hasOwnProperty(b),'unknown event fired "'+b+'"');n=h[b];for(d=0;d<n.length;d+=1)n[d](k)};this.subscribe=function(b,k){runtime.assert(h.hasOwnProperty(b),'tried to subscribe to unknown event "'+b+'"');h[b].push(k)};this.unsubscribe=function(b,k){var d;runtime.assert(h.hasOwnProperty(b),'tried to unsubscribe from unknown event "'+b+'"');d=h[b].indexOf(k);runtime.assert(-1!==d,'tried to unsubscribe unknown callback from event "'+ +b+'"');-1!==d&&h[b].splice(d,1)};(function(){var b,p;for(b=0;b<k.length;b+=1)p=k[b],runtime.assert(!h.hasOwnProperty(p),'Duplicated event ids: "'+p+'" registered more than once.'),h[p]=[]})()}; +// Input 11 /* Copyright (C) 2012 KO GmbH <copyright@kogmbh.com> @@ -177,46 +226,93 @@ r,'tried to unsubscribe unknown callback from event "'+f+'"');-1!==r&&l[f].splic @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -core.LoopWatchDog=function(g,l){var f=Date.now(),p=0;this.check=function(){var r;if(g&&(r=Date.now(),r-f>g))throw runtime.log("alert","watchdog timeout"),"timeout!";if(0<l&&(p+=1,p>l))throw runtime.log("alert","watchdog loop overflow"),"loop overflow";}}; -// Input 10 -core.PositionIterator=function(g,l,f,p){function r(){this.acceptNode=function(a){return!a||a.nodeType===b&&0===a.length?t:k}}function n(a){this.acceptNode=function(c){return!c||c.nodeType===b&&0===c.length?t:a.acceptNode(c)}}function h(){var a=c.currentNode,d=a.nodeType;e=d===b?a.length-1:d===q?1:0}function d(){if(null===c.previousSibling()){if(!c.parentNode()||c.currentNode===g)return c.firstChild(),!1;e=0}else h();return!0}var m=this,c,e,a,b=Node.TEXT_NODE,q=Node.ELEMENT_NODE,k=NodeFilter.FILTER_ACCEPT, -t=NodeFilter.FILTER_REJECT;this.nextPosition=function(){var a=c.currentNode,d=a.nodeType;if(a===g)return!1;if(0===e&&d===q)null===c.firstChild()&&(e=1);else if(d===b&&e+1<a.length)e+=1;else if(null!==c.nextSibling())e=0;else if(c.parentNode())e=1;else return!1;return!0};this.previousPosition=function(){var a=!0,q=c.currentNode;0===e?a=d():q.nodeType===b?e-=1:null!==c.lastChild()?h():q===g?a=!1:e=0;return a};this.previousNode=d;this.container=function(){var a=c.currentNode,d=a.nodeType;0===e&&d!== -b&&(a=a.parentNode);return a};this.rightNode=function(){var d=c.currentNode,f=d.nodeType;if(f===b&&e===d.length)for(d=d.nextSibling;d&&a(d)!==k;)d=d.nextSibling;else f===q&&1===e&&(d=null);return d};this.leftNode=function(){var b=c.currentNode;if(0===e)for(b=b.previousSibling;b&&a(b)!==k;)b=b.previousSibling;else if(b.nodeType===q)for(b=b.lastChild;b&&a(b)!==k;)b=b.previousSibling;return b};this.getCurrentNode=function(){return c.currentNode};this.unfilteredDomOffset=function(){if(c.currentNode.nodeType=== -b)return e;for(var a=0,d=c.currentNode,d=1===e?d.lastChild:d.previousSibling;d;)a+=1,d=d.previousSibling;return a};this.getPreviousSibling=function(){var a=c.currentNode,b=c.previousSibling();c.currentNode=a;return b};this.getNextSibling=function(){var a=c.currentNode,b=c.nextSibling();c.currentNode=a;return b};this.setUnfilteredPosition=function(d,q){var f,h;runtime.assert(null!==d&&void 0!==d,"PositionIterator.setUnfilteredPosition called without container");c.currentNode=d;if(d.nodeType===b)return e= -q,runtime.assert(q<=d.length,"Error in setPosition: "+q+" > "+d.length),runtime.assert(0<=q,"Error in setPosition: "+q+" < 0"),q===d.length&&(c.nextSibling()?e=0:c.parentNode()?e=1:runtime.assert(!1,"Error in setUnfilteredPosition: position not valid.")),!0;f=a(d);for(h=d.parentNode;h&&h!==g&&f===k;)f=a(h),f!==k&&(c.currentNode=h),h=h.parentNode;q<d.childNodes.length&&f!==NodeFilter.FILTER_REJECT?(c.currentNode=d.childNodes.item(q),f=a(c.currentNode),e=0):e=1;f===NodeFilter.FILTER_REJECT&&(e=1);if(f!== -k)return m.nextPosition();runtime.assert(a(c.currentNode)===k,"PositionIterater.setUnfilteredPosition call resulted in an non-visible node being set");return!0};this.moveToEnd=function(){c.currentNode=g;e=1};this.moveToEndOfNode=function(a){a.nodeType===b?m.setUnfilteredPosition(a,a.length):(c.currentNode=a,e=1)};this.getNodeFilter=function(){return a};a=(f?new n(f):new r).acceptNode;a.acceptNode=a;l=l||4294967295;runtime.assert(g.nodeType!==Node.TEXT_NODE,"Internet Explorer doesn't allow tree walker roots to be text nodes"); -c=g.ownerDocument.createTreeWalker(g,l,a,p);e=0;null===c.firstChild()&&(e=1)}; -// Input 11 -core.zip_HuftNode=function(){this.n=this.b=this.e=0;this.t=null};core.zip_HuftList=function(){this.list=this.next=null}; -core.RawInflate=function(){function g(a,b,c,e,d,q){this.BMAX=16;this.N_MAX=288;this.status=0;this.root=null;this.m=0;var f=Array(this.BMAX+1),k,h,I,g,m,s,l,n=Array(this.BMAX+1),r,p,v,t=new core.zip_HuftNode,W=Array(this.BMAX);g=Array(this.N_MAX);var u,y=Array(this.BMAX+1),z,Q,B;B=this.root=null;for(m=0;m<f.length;m++)f[m]=0;for(m=0;m<n.length;m++)n[m]=0;for(m=0;m<W.length;m++)W[m]=null;for(m=0;m<g.length;m++)g[m]=0;for(m=0;m<y.length;m++)y[m]=0;k=256<b?a[256]:this.BMAX;r=a;p=0;m=b;do f[r[p]]++,p++; -while(0<--m);if(f[0]===b)this.root=null,this.status=this.m=0;else{for(s=1;s<=this.BMAX&&0===f[s];s++);l=s;q<s&&(q=s);for(m=this.BMAX;0!==m&&0===f[m];m--);I=m;q>m&&(q=m);for(z=1<<s;s<m;s++,z<<=1)if(z-=f[s],0>z){this.status=2;this.m=q;return}z-=f[m];if(0>z)this.status=2,this.m=q;else{f[m]+=z;y[1]=s=0;r=f;p=1;for(v=2;0<--m;)s+=r[p++],y[v++]=s;r=a;m=p=0;do s=r[p++],0!==s&&(g[y[s]++]=m);while(++m<b);b=y[I];y[0]=m=0;r=g;p=0;g=-1;u=n[0]=0;v=null;Q=0;for(l=l-1+1;l<=I;l++)for(a=f[l];0<a--;){for(;l>u+n[1+g];){u+= -n[1+g];g++;Q=I-u;Q=Q>q?q:Q;s=l-u;h=1<<s;if(h>a+1)for(h-=a+1,v=l;++s<Q;){h<<=1;if(h<=f[++v])break;h-=f[v]}u+s>k&&u<k&&(s=k-u);Q=1<<s;n[1+g]=s;v=Array(Q);for(h=0;h<Q;h++)v[h]=new core.zip_HuftNode;B=null===B?this.root=new core.zip_HuftList:B.next=new core.zip_HuftList;B.next=null;B.list=v;W[g]=v;0<g&&(y[g]=m,t.b=n[g],t.e=16+s,t.t=v,s=(m&(1<<u)-1)>>u-n[g],W[g-1][s].e=t.e,W[g-1][s].b=t.b,W[g-1][s].n=t.n,W[g-1][s].t=t.t)}t.b=l-u;p>=b?t.e=99:r[p]<c?(t.e=256>r[p]?16:15,t.n=r[p++]):(t.e=d[r[p]-c],t.n=e[r[p++]- -c]);h=1<<l-u;for(s=m>>u;s<Q;s+=h)v[s].e=t.e,v[s].b=t.b,v[s].n=t.n,v[s].t=t.t;for(s=1<<l-1;0!==(m&s);s>>=1)m^=s;for(m^=s;(m&(1<<u)-1)!==y[g];)u-=n[g],g--}this.m=n[1];this.status=0!==z&&1!==I?1:0}}}function l(c){for(;b<c;){var e=a,d;d=s.length===H?-1:s[H++];a=e|d<<b;b+=8}}function f(b){return a&y[b]}function p(c){a>>=c;b-=c}function r(a,b,c){var e,k,I;if(0===c)return 0;for(I=0;;){l(v);k=w.list[f(v)];for(e=k.e;16<e;){if(99===e)return-1;p(k.b);e-=16;l(e);k=k.t[f(e)];e=k.e}p(k.b);if(16===e)d&=32767,a[b+ -I++]=h[d++]=k.n;else{if(15===e)break;l(e);t=k.n+f(e);p(e);l(u);k=x.list[f(u)];for(e=k.e;16<e;){if(99===e)return-1;p(k.b);e-=16;l(e);k=k.t[f(e)];e=k.e}p(k.b);l(e);A=d-k.n-f(e);for(p(e);0<t&&I<c;)t--,A&=32767,d&=32767,a[b+I++]=h[d++]=h[A++]}if(I===c)return c}q=-1;return I}function n(a,b,c){var e,d,q,k,h,m,s,n=Array(316);for(e=0;e<n.length;e++)n[e]=0;l(5);m=257+f(5);p(5);l(5);s=1+f(5);p(5);l(4);e=4+f(4);p(4);if(286<m||30<s)return-1;for(d=0;d<e;d++)l(3),n[Q[d]]=f(3),p(3);for(d=e;19>d;d++)n[Q[d]]=0;v= -7;d=new g(n,19,19,null,null,v);if(0!==d.status)return-1;w=d.root;v=d.m;k=m+s;for(e=q=0;e<k;)if(l(v),h=w.list[f(v)],d=h.b,p(d),d=h.n,16>d)n[e++]=q=d;else if(16===d){l(2);d=3+f(2);p(2);if(e+d>k)return-1;for(;0<d--;)n[e++]=q}else{17===d?(l(3),d=3+f(3),p(3)):(l(7),d=11+f(7),p(7));if(e+d>k)return-1;for(;0<d--;)n[e++]=0;q=0}v=9;d=new g(n,m,257,B,L,v);0===v&&(d.status=1);if(0!==d.status)return-1;w=d.root;v=d.m;for(e=0;e<s;e++)n[e]=n[e+m];u=6;d=new g(n,s,0,I,W,u);x=d.root;u=d.m;return 0===u&&257<m||0!==d.status? --1:r(a,b,c)}var h=[],d,m=null,c,e,a,b,q,k,t,A,w,x,v,u,s,H,y=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],B=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],L=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,99,99],I=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],W=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],Q=[16,17,18,0,8,7,9,6, -10,5,11,4,12,3,13,2,14,1,15],z;this.inflate=function(y,Q){h.length=65536;b=a=d=0;q=-1;k=!1;t=A=0;w=null;s=y;H=0;var G=new Uint8Array(new ArrayBuffer(Q));a:for(var Z=0,O;Z<Q&&(!k||-1!==q);){if(0<t){if(0!==q)for(;0<t&&Z<Q;)t--,A&=32767,d&=32767,G[0+Z]=h[d]=h[A],Z+=1,d+=1,A+=1;else{for(;0<t&&Z<Q;)t-=1,d&=32767,l(8),G[0+Z]=h[d]=f(8),Z+=1,d+=1,p(8);0===t&&(q=-1)}if(Z===Q)break}if(-1===q){if(k)break;l(1);0!==f(1)&&(k=!0);p(1);l(2);q=f(2);p(2);w=null;t=0}switch(q){case 0:O=G;var aa=0+Z,J=Q-Z,F=void 0,F= -b&7;p(F);l(16);F=f(16);p(16);l(16);if(F!==(~a&65535))O=-1;else{p(16);t=F;for(F=0;0<t&&F<J;)t--,d&=32767,l(8),O[aa+F++]=h[d++]=f(8),p(8);0===t&&(q=-1);O=F}break;case 1:if(null!==w)O=r(G,0+Z,Q-Z);else b:{O=G;aa=0+Z;J=Q-Z;if(null===m){for(var C=void 0,F=Array(288),C=void 0,C=0;144>C;C++)F[C]=8;for(C=144;256>C;C++)F[C]=9;for(C=256;280>C;C++)F[C]=7;for(C=280;288>C;C++)F[C]=8;e=7;C=new g(F,288,257,B,L,e);if(0!==C.status){alert("HufBuild error: "+C.status);O=-1;break b}m=C.root;e=C.m;for(C=0;30>C;C++)F[C]= -5;z=5;C=new g(F,30,0,I,W,z);if(1<C.status){m=null;alert("HufBuild error: "+C.status);O=-1;break b}c=C.root;z=C.m}w=m;x=c;v=e;u=z;O=r(O,aa,J)}break;case 2:O=null!==w?r(G,0+Z,Q-Z):n(G,0+Z,Q-Z);break;default:O=-1}if(-1===O)break a;Z+=O}s=new Uint8Array(new ArrayBuffer(0));return G}}; +core.LoopWatchDog=function(k,h){var b=Date.now(),p=0;this.check=function(){var d;if(k&&(d=Date.now(),d-b>k))throw runtime.log("alert","watchdog timeout"),"timeout!";if(0<h&&(p+=1,p>h))throw runtime.log("alert","watchdog loop overflow"),"loop overflow";}}; // Input 12 -core.ScheduledTask=function(g,l){function f(){n&&(runtime.clearTimeout(r),n=!1)}function p(){f();g.apply(void 0,h);h=null}var r,n=!1,h=[];this.trigger=function(){h=Array.prototype.slice.call(arguments);n||(n=!0,r=runtime.setTimeout(p,l))};this.triggerImmediate=function(){h=Array.prototype.slice.call(arguments);p()};this.processRequests=function(){n&&p()};this.cancel=f;this.destroy=function(d){f();d()}}; +core.PositionIterator=function(k,h,b,p){function d(){this.acceptNode=function(a){return!a||a.nodeType===m&&0===a.length?w:t}}function n(a){this.acceptNode=function(c){return!c||c.nodeType===m&&0===c.length?w:a.acceptNode(c)}}function g(){var a=f.currentNode,b=a.nodeType;c=b===m?a.length-1:b===e?1:0}function q(){if(null===f.previousSibling()){if(!f.parentNode()||f.currentNode===k)return f.firstChild(),!1;c=0}else g();return!0}function r(){var b=f.currentNode,e;e=a(b);if(b!==k)for(b=b.parentNode;b&& +b!==k;)a(b)===w&&(f.currentNode=b,e=w),b=b.parentNode;e===w?(c=1,b=l.nextPosition()):b=e===t?!0:l.nextPosition();b&&runtime.assert(a(f.currentNode)===t,"moveToAcceptedNode did not result in walker being on an accepted node");return b}var l=this,f,c,a,m=Node.TEXT_NODE,e=Node.ELEMENT_NODE,t=NodeFilter.FILTER_ACCEPT,w=NodeFilter.FILTER_REJECT;this.nextPosition=function(){var a=f.currentNode,b=a.nodeType;if(a===k)return!1;if(0===c&&b===e)null===f.firstChild()&&(c=1);else if(b===m&&c+1<a.length)c+=1;else if(null!== +f.nextSibling())c=0;else if(f.parentNode())c=1;else return!1;return!0};this.previousPosition=function(){var a=!0,b=f.currentNode;0===c?a=q():b.nodeType===m?c-=1:null!==f.lastChild()?g():b===k?a=!1:c=0;return a};this.previousNode=q;this.container=function(){var a=f.currentNode,b=a.nodeType;0===c&&b!==m&&(a=a.parentNode);return a};this.rightNode=function(){var b=f.currentNode,d=b.nodeType;if(d===m&&c===b.length)for(b=b.nextSibling;b&&a(b)!==t;)b=b.nextSibling;else d===e&&1===c&&(b=null);return b};this.leftNode= +function(){var b=f.currentNode;if(0===c)for(b=b.previousSibling;b&&a(b)!==t;)b=b.previousSibling;else if(b.nodeType===e)for(b=b.lastChild;b&&a(b)!==t;)b=b.previousSibling;return b};this.getCurrentNode=function(){return f.currentNode};this.unfilteredDomOffset=function(){if(f.currentNode.nodeType===m)return c;for(var a=0,b=f.currentNode,b=1===c?b.lastChild:b.previousSibling;b;)a+=1,b=b.previousSibling;return a};this.getPreviousSibling=function(){var a=f.currentNode,c=f.previousSibling();f.currentNode= +a;return c};this.getNextSibling=function(){var a=f.currentNode,c=f.nextSibling();f.currentNode=a;return c};this.setPositionBeforeElement=function(a){runtime.assert(Boolean(a),"setPositionBeforeElement called without element");f.currentNode=a;c=0;return r()};this.setUnfilteredPosition=function(a,b){runtime.assert(Boolean(a),"PositionIterator.setUnfilteredPosition called without container");f.currentNode=a;if(a.nodeType===m)return c=b,runtime.assert(b<=a.length,"Error in setPosition: "+b+" > "+a.length), +runtime.assert(0<=b,"Error in setPosition: "+b+" < 0"),b===a.length&&(f.nextSibling()?c=0:f.parentNode()?c=1:runtime.assert(!1,"Error in setUnfilteredPosition: position not valid.")),!0;b<a.childNodes.length?(f.currentNode=a.childNodes.item(b),c=0):c=1;return r()};this.moveToEnd=function(){f.currentNode=k;c=1};this.moveToEndOfNode=function(a){a.nodeType===m?l.setUnfilteredPosition(a,a.length):(f.currentNode=a,c=1)};this.isBeforeNode=function(){return 0===c};this.getNodeFilter=function(){return a}; +a=(b?new n(b):new d).acceptNode;a.acceptNode=a;h=h||NodeFilter.SHOW_ALL;runtime.assert(k.nodeType!==Node.TEXT_NODE,"Internet Explorer doesn't allow tree walker roots to be text nodes");f=k.ownerDocument.createTreeWalker(k,h,a,p);c=0;null===f.firstChild()&&(c=1)}; // Input 13 -core.UnitTest=function(){};core.UnitTest.prototype.setUp=function(){};core.UnitTest.prototype.tearDown=function(){};core.UnitTest.prototype.description=function(){};core.UnitTest.prototype.tests=function(){};core.UnitTest.prototype.asyncTests=function(){}; -core.UnitTest.provideTestAreaDiv=function(){var g=runtime.getWindow().document,l=g.getElementById("testarea");runtime.assert(!l,'Unclean test environment, found a div with id "testarea".');l=g.createElement("div");l.setAttribute("id","testarea");g.body.appendChild(l);return l}; -core.UnitTest.cleanupTestAreaDiv=function(){var g=runtime.getWindow().document,l=g.getElementById("testarea");runtime.assert(!!l&&l.parentNode===g.body,'Test environment broken, found no div with id "testarea" below body.');g.body.removeChild(l)};core.UnitTest.createOdtDocument=function(g,l){var f="<?xml version='1.0' encoding='UTF-8'?>",f=f+"<office:document";Object.keys(l).forEach(function(g){f+=" xmlns:"+g+'="'+l[g]+'"'});f+=">";f+=g;f+="</office:document>";return runtime.parseXML(f)}; -core.UnitTestRunner=function(){function g(d){h+=1;runtime.log("fail",d)}function l(d,c){var e;try{if(d.length!==c.length)return g("array of length "+d.length+" should be "+c.length+" long"),!1;for(e=0;e<d.length;e+=1)if(d[e]!==c[e])return g(d[e]+" should be "+c[e]+" at array index "+e),!1}catch(a){return!1}return!0}function f(d,c,e){var a=d.attributes,b=a.length,q,k,h;for(q=0;q<b;q+=1)if(k=a.item(q),"xmlns"!==k.prefix&&"urn:webodf:names:steps"!==k.namespaceURI){h=c.getAttributeNS(k.namespaceURI,k.localName); -if(!c.hasAttributeNS(k.namespaceURI,k.localName))return g("Attribute "+k.localName+" with value "+k.value+" was not present"),!1;if(h!==k.value)return g("Attribute "+k.localName+" was "+h+" should be "+k.value),!1}return e?!0:f(c,d,!0)}function p(d,c){var e,a;e=d.nodeType;a=c.nodeType;if(e!==a)return g("Nodetype '"+e+"' should be '"+a+"'"),!1;if(e===Node.TEXT_NODE){if(d.data===c.data)return!0;g("Textnode data '"+d.data+"' should be '"+c.data+"'");return!1}runtime.assert(e===Node.ELEMENT_NODE,"Only textnodes and elements supported."); -if(d.namespaceURI!==c.namespaceURI)return g("namespace '"+d.namespaceURI+"' should be '"+c.namespaceURI+"'"),!1;if(d.localName!==c.localName)return g("localName '"+d.localName+"' should be '"+c.localName+"'"),!1;if(!f(d,c,!1))return!1;e=d.firstChild;for(a=c.firstChild;e;){if(!a)return g("Nodetype '"+e.nodeType+"' is unexpected here."),!1;if(!p(e,a))return!1;e=e.nextSibling;a=a.nextSibling}return a?(g("Nodetype '"+a.nodeType+"' is missing here."),!1):!0}function r(f,c){return 0===c?f===c&&1/f===1/ -c:f===c?!0:"number"===typeof c&&isNaN(c)?"number"===typeof f&&isNaN(f):Object.prototype.toString.call(c)===Object.prototype.toString.call([])?l(f,c):"object"===typeof c&&"object"===typeof f?c.constructor===Element||c.constructor===Node?p(c,f):d(c,f):!1}function n(d,c,e){"string"===typeof c&&"string"===typeof e||runtime.log("WARN: shouldBe() expects string arguments");var a,b;try{b=eval(c)}catch(q){a=q}d=eval(e);a?g(c+" should be "+d+". Threw exception "+a):r(b,d)?runtime.log("pass",c+" is "+e):String(typeof b)=== -String(typeof d)?(e=0===b&&0>1/b?"-0":String(b),g(c+" should be "+d+". Was "+e+".")):g(c+" should be "+d+" (of type "+typeof d+"). Was "+b+" (of type "+typeof b+").")}var h=0,d;d=function(d,c){var e=Object.keys(d),a=Object.keys(c);e.sort();a.sort();return l(e,a)&&Object.keys(d).every(function(a){var e=d[a],f=c[a];return r(e,f)?!0:(g(e+" should be "+f+" for key "+a),!1)})};this.areNodesEqual=p;this.shouldBeNull=function(d,c){n(d,c,"null")};this.shouldBeNonNull=function(d,c){var e,a;try{a=eval(c)}catch(b){e= -b}e?g(c+" should be non-null. Threw exception "+e):null!==a?runtime.log("pass",c+" is non-null."):g(c+" should be non-null. Was "+a)};this.shouldBe=n;this.countFailedTests=function(){return h};this.name=function(d){var c,e,a=[],b=d.length;a.length=b;for(c=0;c<b;c+=1){e=Runtime.getFunctionName(d[c])||"";if(""===e)throw"Found a function without a name.";a[c]={f:d[c],name:e}}return a}}; -core.UnitTester=function(){function g(f,g){return"<span style='color:blue;cursor:pointer' onclick='"+g+"'>"+f+"</span>"}var l=0,f={};this.runTests=function(p,r,n){function h(a){if(0===a.length)f[d]=e,l+=m.countFailedTests(),r();else{b=a[0].f;var q=a[0].name;runtime.log("Running "+q);k=m.countFailedTests();c.setUp();b(function(){c.tearDown();e[q]=k===m.countFailedTests();h(a.slice(1))})}}var d=Runtime.getFunctionName(p)||"",m=new core.UnitTestRunner,c=new p(m),e={},a,b,q,k,t="BrowserRuntime"===runtime.type(); -if(f.hasOwnProperty(d))runtime.log("Test "+d+" has already run.");else{t?runtime.log("<span>Running "+g(d,'runSuite("'+d+'");')+": "+c.description()+"</span>"):runtime.log("Running "+d+": "+c.description);q=c.tests();for(a=0;a<q.length;a+=1)b=q[a].f,p=q[a].name,n.length&&-1===n.indexOf(p)||(t?runtime.log("<span>Running "+g(p,'runTest("'+d+'","'+p+'")')+"</span>"):runtime.log("Running "+p),k=m.countFailedTests(),c.setUp(),b(),c.tearDown(),e[p]=k===m.countFailedTests());h(c.asyncTests())}};this.countFailedTests= -function(){return l};this.results=function(){return f}}; +core.PositionFilter=function(){};core.PositionFilter.FilterResult={FILTER_ACCEPT:1,FILTER_REJECT:2,FILTER_SKIP:3};core.PositionFilter.prototype.acceptPosition=function(k){};(function(){return core.PositionFilter})(); // Input 14 -core.Utils=function(){function g(l,f){if(f&&Array.isArray(f)){l=l||[];if(!Array.isArray(l))throw"Destination is not an array.";l=l.concat(f.map(function(f){return g(null,f)}))}else if(f&&"object"===typeof f){l=l||{};if("object"!==typeof l)throw"Destination is not an object.";Object.keys(f).forEach(function(p){l[p]=g(l[p],f[p])})}else l=f;return l}this.hashString=function(g){var f=0,p,r;p=0;for(r=g.length;p<r;p+=1)f=(f<<5)-f+g.charCodeAt(p),f|=0;return f};this.mergeObjects=function(l,f){Object.keys(f).forEach(function(p){l[p]= -g(l[p],f[p])});return l}}; +core.PositionFilterChain=function(){var k=[],h=core.PositionFilter.FilterResult.FILTER_ACCEPT,b=core.PositionFilter.FilterResult.FILTER_REJECT;this.acceptPosition=function(p){var d;for(d=0;d<k.length;d+=1)if(k[d].acceptPosition(p)===b)return b;return h};this.addFilter=function(b){k.push(b)}}; // Input 15 +core.zip_HuftNode=function(){this.n=this.b=this.e=0;this.t=null};core.zip_HuftList=function(){this.list=this.next=null}; +core.RawInflate=function(){function k(a,c,b,e,m,f){this.BMAX=16;this.N_MAX=288;this.status=0;this.root=null;this.m=0;var d=Array(this.BMAX+1),l,g,h,k,A,n,q,p=Array(this.BMAX+1),F,t,r,s=new core.zip_HuftNode,J=Array(this.BMAX);k=Array(this.N_MAX);var v,G=Array(this.BMAX+1),D,u,O;O=this.root=null;for(A=0;A<d.length;A++)d[A]=0;for(A=0;A<p.length;A++)p[A]=0;for(A=0;A<J.length;A++)J[A]=null;for(A=0;A<k.length;A++)k[A]=0;for(A=0;A<G.length;A++)G[A]=0;l=256<c?a[256]:this.BMAX;F=a;t=0;A=c;do d[F[t]]++,t++; +while(0<--A);if(d[0]===c)this.root=null,this.status=this.m=0;else{for(n=1;n<=this.BMAX&&0===d[n];n++);q=n;f<n&&(f=n);for(A=this.BMAX;0!==A&&0===d[A];A--);h=A;f>A&&(f=A);for(D=1<<n;n<A;n++,D<<=1)if(D-=d[n],0>D){this.status=2;this.m=f;return}D-=d[A];if(0>D)this.status=2,this.m=f;else{d[A]+=D;G[1]=n=0;F=d;t=1;for(r=2;0<--A;)n+=F[t++],G[r++]=n;F=a;A=t=0;do n=F[t++],0!==n&&(k[G[n]++]=A);while(++A<c);c=G[h];G[0]=A=0;F=k;t=0;k=-1;v=p[0]=0;r=null;u=0;for(q=q-1+1;q<=h;q++)for(a=d[q];0<a--;){for(;q>v+p[1+k];){v+= +p[1+k];k++;u=h-v;u=u>f?f:u;n=q-v;g=1<<n;if(g>a+1)for(g-=a+1,r=q;++n<u;){g<<=1;if(g<=d[++r])break;g-=d[r]}v+n>l&&v<l&&(n=l-v);u=1<<n;p[1+k]=n;r=Array(u);for(g=0;g<u;g++)r[g]=new core.zip_HuftNode;O=null===O?this.root=new core.zip_HuftList:O.next=new core.zip_HuftList;O.next=null;O.list=r;J[k]=r;0<k&&(G[k]=A,s.b=p[k],s.e=16+n,s.t=r,n=(A&(1<<v)-1)>>v-p[k],J[k-1][n].e=s.e,J[k-1][n].b=s.b,J[k-1][n].n=s.n,J[k-1][n].t=s.t)}s.b=q-v;t>=c?s.e=99:F[t]<b?(s.e=256>F[t]?16:15,s.n=F[t++]):(s.e=m[F[t]-b],s.n=e[F[t++]- +b]);g=1<<q-v;for(n=A>>v;n<u;n+=g)r[n].e=s.e,r[n].b=s.b,r[n].n=s.n,r[n].t=s.t;for(n=1<<q-1;0!==(A&n);n>>=1)A^=n;for(A^=n;(A&(1<<v)-1)!==G[k];)v-=p[k],k--}this.m=p[1];this.status=0!==D&&1!==h?1:0}}}function h(b){for(;a<b;){var e=c,m;m=s.length===A?-1:s[A++];c=e|m<<a;a+=8}}function b(a){return c&J[a]}function p(b){c>>=b;a-=b}function d(a,c,e){var f,d,l;if(0===e)return 0;for(l=0;;){h(v);d=z.list[b(v)];for(f=d.e;16<f;){if(99===f)return-1;p(d.b);f-=16;h(f);d=d.t[b(f)];f=d.e}p(d.b);if(16===f)q&=32767,a[c+ +l++]=g[q++]=d.n;else{if(15===f)break;h(f);t=d.n+b(f);p(f);h(u);d=x.list[b(u)];for(f=d.e;16<f;){if(99===f)return-1;p(d.b);f-=16;h(f);d=d.t[b(f)];f=d.e}p(d.b);h(f);w=q-d.n-b(f);for(p(f);0<t&&l<e;)t--,w&=32767,q&=32767,a[c+l++]=g[q++]=g[w++]}if(l===e)return e}m=-1;return l}function n(a,c,e){var m,f,l,g,A,n,q,t=Array(316);for(m=0;m<t.length;m++)t[m]=0;h(5);n=257+b(5);p(5);h(5);q=1+b(5);p(5);h(4);m=4+b(4);p(4);if(286<n||30<q)return-1;for(f=0;f<m;f++)h(3),t[K[f]]=b(3),p(3);for(f=m;19>f;f++)t[K[f]]=0;v= +7;f=new k(t,19,19,null,null,v);if(0!==f.status)return-1;z=f.root;v=f.m;g=n+q;for(m=l=0;m<g;)if(h(v),A=z.list[b(v)],f=A.b,p(f),f=A.n,16>f)t[m++]=l=f;else if(16===f){h(2);f=3+b(2);p(2);if(m+f>g)return-1;for(;0<f--;)t[m++]=l}else{17===f?(h(3),f=3+b(3),p(3)):(h(7),f=11+b(7),p(7));if(m+f>g)return-1;for(;0<f--;)t[m++]=0;l=0}v=9;f=new k(t,n,257,G,D,v);0===v&&(f.status=1);if(0!==f.status)return-1;z=f.root;v=f.m;for(m=0;m<q;m++)t[m]=t[m+n];u=6;f=new k(t,q,0,F,O,u);x=f.root;u=f.m;return 0===u&&257<n||0!==f.status? +-1:d(a,c,e)}var g=[],q,r=null,l,f,c,a,m,e,t,w,z,x,v,u,s,A,J=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],G=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],D=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,99,99],F=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],O=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],K=[16,17,18,0,8,7,9,6, +10,5,11,4,12,3,13,2,14,1,15],Z;this.inflate=function(J,K){g.length=65536;a=c=q=0;m=-1;e=!1;t=w=0;z=null;s=J;A=0;var H=new Uint8Array(new ArrayBuffer(K));a:for(var T=0,y;T<K&&(!e||-1!==m);){if(0<t){if(0!==m)for(;0<t&&T<K;)t--,w&=32767,q&=32767,H[0+T]=g[q]=g[w],T+=1,q+=1,w+=1;else{for(;0<t&&T<K;)t-=1,q&=32767,h(8),H[0+T]=g[q]=b(8),T+=1,q+=1,p(8);0===t&&(m=-1)}if(T===K)break}if(-1===m){if(e)break;h(1);0!==b(1)&&(e=!0);p(1);h(2);m=b(2);p(2);z=null;t=0}switch(m){case 0:y=H;var aa=0+T,N=K-T,R=void 0,R= +a&7;p(R);h(16);R=b(16);p(16);h(16);if(R!==(~c&65535))y=-1;else{p(16);t=R;for(R=0;0<t&&R<N;)t--,q&=32767,h(8),y[aa+R++]=g[q++]=b(8),p(8);0===t&&(m=-1);y=R}break;case 1:if(null!==z)y=d(H,0+T,K-T);else b:{y=H;aa=0+T;N=K-T;if(null===r){for(var I=void 0,R=Array(288),I=void 0,I=0;144>I;I++)R[I]=8;for(I=144;256>I;I++)R[I]=9;for(I=256;280>I;I++)R[I]=7;for(I=280;288>I;I++)R[I]=8;f=7;I=new k(R,288,257,G,D,f);if(0!==I.status){alert("HufBuild error: "+I.status);y=-1;break b}r=I.root;f=I.m;for(I=0;30>I;I++)R[I]= +5;Z=5;I=new k(R,30,0,F,O,Z);if(1<I.status){r=null;alert("HufBuild error: "+I.status);y=-1;break b}l=I.root;Z=I.m}z=r;x=l;v=f;u=Z;y=d(y,aa,N)}break;case 2:y=null!==z?d(H,0+T,K-T):n(H,0+T,K-T);break;default:y=-1}if(-1===y)break a;T+=y}s=new Uint8Array(new ArrayBuffer(0));return H}}; +// Input 16 +core.ScheduledTask=function(k,h){function b(){n&&(runtime.clearTimeout(d),n=!1)}function p(){b();k.apply(void 0,g);g=null}var d,n=!1,g=[];this.trigger=function(){g=Array.prototype.slice.call(arguments);n||(n=!0,d=runtime.setTimeout(p,h))};this.triggerImmediate=function(){g=Array.prototype.slice.call(arguments);p()};this.processRequests=function(){n&&p()};this.cancel=b;this.destroy=function(d){b();d()}}; +// Input 17 +/* + + Copyright (C) 2014 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/ +*/ +core.StepIterator=function(k,h){function b(){f=null;a=c=void 0}function p(){void 0===a&&(a=k.acceptPosition(h)===l);return a}function d(a,c){b();return h.setUnfilteredPosition(a,c)}function n(){f||(f=h.container());return f}function g(){void 0===c&&(c=h.unfilteredDomOffset());return c}function q(){for(b();h.nextPosition();)if(b(),p())return!0;return!1}function r(){for(b();h.previousPosition();)if(b(),p())return!0;return!1}var l=core.PositionFilter.FilterResult.FILTER_ACCEPT,f,c,a;this.isStep=p;this.setPosition= +d;this.container=n;this.offset=g;this.nextStep=q;this.previousStep=r;this.roundToClosestStep=function(){var a=n(),c=g(),b=p();b||(b=r(),b||(d(a,c),b=q()));return b};this.roundToPreviousStep=function(){var a=p();a||(a=r());return a};this.roundToNextStep=function(){var a=p();a||(a=q());return a}}; +// Input 18 +core.UnitTest=function(){};core.UnitTest.prototype.setUp=function(){};core.UnitTest.prototype.tearDown=function(){};core.UnitTest.prototype.description=function(){};core.UnitTest.prototype.tests=function(){};core.UnitTest.prototype.asyncTests=function(){}; +core.UnitTest.provideTestAreaDiv=function(){var k=runtime.getWindow().document,h=k.getElementById("testarea");runtime.assert(!h,'Unclean test environment, found a div with id "testarea".');h=k.createElement("div");h.setAttribute("id","testarea");k.body.appendChild(h);return h}; +core.UnitTest.cleanupTestAreaDiv=function(){var k=runtime.getWindow().document,h=k.getElementById("testarea");runtime.assert(!!h&&h.parentNode===k.body,'Test environment broken, found no div with id "testarea" below body.');k.body.removeChild(h)};core.UnitTest.createOdtDocument=function(k,h){var b="<?xml version='1.0' encoding='UTF-8'?>",b=b+"<office:document";Object.keys(h).forEach(function(k){b+=" xmlns:"+k+'="'+h[k]+'"'});b+=">";b+=k;b+="</office:document>";return runtime.parseXML(b)}; +core.UnitTestLogger=function(){var k=[],h=0,b=0,p="",d="";this.startTest=function(n,g){k=[];h=0;p=n;d=g;b=(new Date).getTime()};this.endTest=function(){var n=(new Date).getTime();return{description:d,suite:[p,d],success:0===h,log:k,time:n-b}};this.debug=function(b){k.push({category:"debug",message:b})};this.fail=function(b){h+=1;k.push({category:"fail",message:b})};this.pass=function(b){k.push({category:"pass",message:b})}}; +core.UnitTestRunner=function(k,h){function b(a){r+=1;c?h.debug(a):h.fail(a)}function p(a,c){var e;try{if(a.length!==c.length)return b("array of length "+a.length+" should be "+c.length+" long"),!1;for(e=0;e<a.length;e+=1)if(a[e]!==c[e])return b(a[e]+" should be "+c[e]+" at array index "+e),!1}catch(f){return!1}return!0}function d(a,c,e){var f=a.attributes,l=f.length,g,n,h;for(g=0;g<l;g+=1)if(n=f.item(g),"xmlns"!==n.prefix&&"urn:webodf:names:steps"!==n.namespaceURI){h=c.getAttributeNS(n.namespaceURI, +n.localName);if(!c.hasAttributeNS(n.namespaceURI,n.localName))return b("Attribute "+n.localName+" with value "+n.value+" was not present"),!1;if(h!==n.value)return b("Attribute "+n.localName+" was "+h+" should be "+n.value),!1}return e?!0:d(c,a,!0)}function n(a,c){var e,f;e=a.nodeType;f=c.nodeType;if(e!==f)return b("Nodetype '"+e+"' should be '"+f+"'"),!1;if(e===Node.TEXT_NODE){if(a.data===c.data)return!0;b("Textnode data '"+a.data+"' should be '"+c.data+"'");return!1}runtime.assert(e===Node.ELEMENT_NODE, +"Only textnodes and elements supported.");if(a.namespaceURI!==c.namespaceURI)return b("namespace '"+a.namespaceURI+"' should be '"+c.namespaceURI+"'"),!1;if(a.localName!==c.localName)return b("localName '"+a.localName+"' should be '"+c.localName+"'"),!1;if(!d(a,c,!1))return!1;e=a.firstChild;for(f=c.firstChild;e;){if(!f)return b("Nodetype '"+e.nodeType+"' is unexpected here."),!1;if(!n(e,f))return!1;e=e.nextSibling;f=f.nextSibling}return f?(b("Nodetype '"+f.nodeType+"' is missing here."),!1):!0}function g(a, +c){return 0===c?a===c&&1/a===1/c:a===c?!0:null===a||null===c?!1:"number"===typeof c&&isNaN(c)?"number"===typeof a&&isNaN(a):Object.prototype.toString.call(c)===Object.prototype.toString.call([])?p(a,c):"object"===typeof c&&"object"===typeof a?c.constructor===Element||c.constructor===Node?n(a,c):f(a,c):!1}function q(a,c,e){"string"===typeof c&&"string"===typeof e||h.debug("WARN: shouldBe() expects string arguments");var f,d;try{d=eval(c)}catch(l){f=l}a=eval(e);f?b(c+" should be "+a+". Threw exception "+ +f):g(d,a)?h.pass(c+" is "+e):String(typeof d)===String(typeof a)?(e=0===d&&0>1/d?"-0":String(d),b(c+" should be "+a+". Was "+e+".")):b(c+" should be "+a+" (of type "+typeof a+"). Was "+d+" (of type "+typeof d+").")}var r=0,l,f,c=!1;this.resourcePrefix=function(){return k};this.beginExpectFail=function(){l=r;c=!0};this.endExpectFail=function(){var a=l===r;c=!1;r=l;a&&(r+=1,h.fail("Expected at least one failed test, but none registered."))};f=function(a,c){var e=Object.keys(a),f=Object.keys(c);e.sort(); +f.sort();return p(e,f)&&Object.keys(a).every(function(e){var f=a[e],d=c[e];return g(f,d)?!0:(b(f+" should be "+d+" for key "+e),!1)})};this.areNodesEqual=n;this.shouldBeNull=function(a,c){q(a,c,"null")};this.shouldBeNonNull=function(a,c){var e,f;try{f=eval(c)}catch(d){e=d}e?b(c+" should be non-null. Threw exception "+e):null!==f?h.pass(c+" is non-null."):b(c+" should be non-null. Was "+f)};this.shouldBe=q;this.testFailed=b;this.countFailedTests=function(){return r};this.name=function(a){var c,b,f= +[],d=a.length;f.length=d;for(c=0;c<d;c+=1){b=Runtime.getFunctionName(a[c])||"";if(""===b)throw"Found a function without a name.";f[c]={f:a[c],name:b}}return f}}; +core.UnitTester=function(){function k(b,d){return"<span style='color:blue;cursor:pointer' onclick='"+d+"'>"+b+"</span>"}function h(d){b.reporter&&b.reporter(d)}var b=this,p=0,d=new core.UnitTestLogger,n={},g="BrowserRuntime"===runtime.type();this.resourcePrefix="";this.reporter=function(b){var d,l;g?runtime.log("<span>Running "+k(b.description,'runTest("'+b.suite[0]+'","'+b.description+'")')+"</span>"):runtime.log("Running "+b.description);if(!b.success)for(d=0;d<b.log.length;d+=1)l=b.log[d],runtime.log(l.category, +l.message)};this.runTests=function(q,r,l){function f(b){if(0===b.length)n[c]=e,p+=a.countFailedTests(),r();else{w=b[0].f;var g=b[0].name,k=!0===b[0].expectFail;v=a.countFailedTests();l.length&&-1===l.indexOf(g)?f(b.slice(1)):(m.setUp(),d.startTest(c,g),k&&a.beginExpectFail(),w(function(){k&&a.endExpectFail();h(d.endTest());m.tearDown();e[g]=v===a.countFailedTests();f(b.slice(1))}))}}var c=Runtime.getFunctionName(q)||"",a=new core.UnitTestRunner(b.resourcePrefix,d),m=new q(a),e={},t,w,z,x,v;if(n.hasOwnProperty(c))runtime.log("Test "+ +c+" has already run.");else{g?runtime.log("<span>Running "+k(c,'runSuite("'+c+'");')+": "+m.description()+"</span>"):runtime.log("Running "+c+": "+m.description);z=m.tests();for(t=0;t<z.length;t+=1)if(w=z[t].f,q=z[t].name,x=!0===z[t].expectFail,!l.length||-1!==l.indexOf(q)){v=a.countFailedTests();m.setUp();d.startTest(c,q);x&&a.beginExpectFail();try{w()}catch(u){a.testFailed("Unexpected exception encountered: "+u.toString()+"\n"+u.stack)}x&&a.endExpectFail();h(d.endTest());m.tearDown();e[q]=v===a.countFailedTests()}f(m.asyncTests())}}; +this.countFailedTests=function(){return p};this.results=function(){return n}}; +// Input 19 +core.Utils=function(){function k(h,b){if(b&&Array.isArray(b)){h=h||[];if(!Array.isArray(h))throw"Destination is not an array.";h=h.concat(b.map(function(b){return k(null,b)}))}else if(b&&"object"===typeof b){h=h||{};if("object"!==typeof h)throw"Destination is not an object.";Object.keys(b).forEach(function(p){h[p]=k(h[p],b[p])})}else h=b;return h}this.hashString=function(h){var b=0,k,d;k=0;for(d=h.length;k<d;k+=1)b=(b<<5)-b+h.charCodeAt(k),b|=0;return b};this.mergeObjects=function(h,b){Object.keys(b).forEach(function(p){h[p]= +k(h[p],b[p])});return h}}; +// Input 20 /* WebODF @@ -225,34 +321,29 @@ g(l[p],f[p])});return l}}; Project home: http://www.webodf.org/ */ -runtime.loadClass("core.RawInflate");runtime.loadClass("core.ByteArray");runtime.loadClass("core.ByteArrayWriter");runtime.loadClass("core.Base64"); -core.Zip=function(g,l){function f(a){var b=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728, +core.Zip=function(k,h){function b(a){var c=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728, 853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202, 4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804, 225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542, 2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035, -2932959818,3654703836,1088359270,936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117],c,e,d=a.length,q=0,q=0;c=-1;for(e=0;e<d;e+=1)q=(c^a[e])&255,q=b[q],c=c>>>8^q;return c^-1}function p(a){return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&15,a>>5&63,(a&31)<<1)}function r(a){var b=a.getFullYear();return 1980>b?0:b-1980<< -25|a.getMonth()+1<<21|a.getDate()<<16|a.getHours()<<11|a.getMinutes()<<5|a.getSeconds()>>1}function n(a,b){var c,e,d,q,f,h,g,m=this;this.load=function(b){if(null!==m.data)b(null,m.data);else{var c=f+34+e+d+256;c+g>k&&(c=k-g);runtime.read(a,g,c,function(c,e){if(c||null===e)b(c,e);else a:{var d=e,k=new core.ByteArray(d),g=k.readUInt32LE(),s;if(67324752!==g)b("File entry signature is wrong."+g.toString()+" "+d.length.toString(),null);else{k.pos+=22;g=k.readUInt16LE();s=k.readUInt16LE();k.pos+=g+s;if(q){d= -d.subarray(k.pos,k.pos+f);if(f!==d.length){b("The amount of compressed bytes read was "+d.length.toString()+" instead of "+f.toString()+" for "+m.filename+" in "+a+".",null);break a}d=A(d,h)}else d=d.subarray(k.pos,k.pos+h);h!==d.length?b("The amount of bytes read was "+d.length.toString()+" instead of "+h.toString()+" for "+m.filename+" in "+a+".",null):(m.data=d,b(null,d))}}})}};this.set=function(a,b,c,e){m.filename=a;m.data=b;m.compressed=c;m.date=e};this.error=null;b&&(c=b.readUInt32LE(),33639248!== -c?this.error="Central directory entry has wrong signature at position "+(b.pos-4).toString()+' for file "'+a+'": '+b.data.length.toString():(b.pos+=6,q=b.readUInt16LE(),this.date=p(b.readUInt32LE()),b.readUInt32LE(),f=b.readUInt32LE(),h=b.readUInt32LE(),e=b.readUInt16LE(),d=b.readUInt16LE(),c=b.readUInt16LE(),b.pos+=8,g=b.readUInt32LE(),this.filename=runtime.byteArrayToString(b.data.subarray(b.pos,b.pos+e),"utf8"),this.data=null,b.pos+=e+d+c))}function h(a,b){if(22!==a.length)b("Central directory length should be 22.", -w);else{var c=new core.ByteArray(a),e;e=c.readUInt32LE();101010256!==e?b("Central directory signature is wrong: "+e.toString(),w):(e=c.readUInt16LE(),0!==e?b("Zip files with non-zero disk numbers are not supported.",w):(e=c.readUInt16LE(),0!==e?b("Zip files with non-zero disk numbers are not supported.",w):(e=c.readUInt16LE(),t=c.readUInt16LE(),e!==t?b("Number of entries is inconsistent.",w):(e=c.readUInt32LE(),c=c.readUInt16LE(),c=k-22-e,runtime.read(g,c,k-c,function(a,c){if(a||null===c)b(a,w);else a:{var e= -new core.ByteArray(c),d,f;q=[];for(d=0;d<t;d+=1){f=new n(g,e);if(f.error){b(f.error,w);break a}q[q.length]=f}b(null,w)}})))))}}function d(a,b){var c=null,e,d;for(d=0;d<q.length;d+=1)if(e=q[d],e.filename===a){c=e;break}c?c.data?b(null,c.data):c.load(b):b(a+" not found.",null)}function m(a){var b=new core.ByteArrayWriter("utf8"),c=0;b.appendArray([80,75,3,4,20,0,0,0,0,0]);a.data&&(c=a.data.length);b.appendUInt32LE(r(a.date));b.appendUInt32LE(a.data?f(a.data):0);b.appendUInt32LE(c);b.appendUInt32LE(c); -b.appendUInt16LE(a.filename.length);b.appendUInt16LE(0);b.appendString(a.filename);a.data&&b.appendByteArray(a.data);return b}function c(a,b){var c=new core.ByteArrayWriter("utf8"),e=0;c.appendArray([80,75,1,2,20,0,20,0,0,0,0,0]);a.data&&(e=a.data.length);c.appendUInt32LE(r(a.date));c.appendUInt32LE(a.data?f(a.data):0);c.appendUInt32LE(e);c.appendUInt32LE(e);c.appendUInt16LE(a.filename.length);c.appendArray([0,0,0,0,0,0,0,0,0,0,0,0]);c.appendUInt32LE(b);c.appendString(a.filename);return c}function e(a, -b){if(a===q.length)b(null);else{var c=q[a];null!==c.data?e(a+1,b):c.load(function(c){c?b(c):e(a+1,b)})}}function a(a,b){e(0,function(e){if(e)b(e);else{var d,f,k=new core.ByteArrayWriter("utf8"),h=[0];for(d=0;d<q.length;d+=1)k.appendByteArrayWriter(m(q[d])),h.push(k.getLength());e=k.getLength();for(d=0;d<q.length;d+=1)f=q[d],k.appendByteArrayWriter(c(f,h[d]));d=k.getLength()-e;k.appendArray([80,75,5,6,0,0,0,0]);k.appendUInt16LE(q.length);k.appendUInt16LE(q.length);k.appendUInt32LE(d);k.appendUInt32LE(e); -k.appendArray([0,0]);a(k.getByteArray())}})}function b(b,c){a(function(a){runtime.writeFile(b,a,c)},c)}var q,k,t,A=(new core.RawInflate).inflate,w=this,x=new core.Base64;this.load=d;this.save=function(a,b,c,e){var d,f;for(d=0;d<q.length;d+=1)if(f=q[d],f.filename===a){f.set(a,b,c,e);return}f=new n(g);f.set(a,b,c,e);q.push(f)};this.remove=function(a){var b,c;for(b=0;b<q.length;b+=1)if(c=q[b],c.filename===a)return q.splice(b,1),!0;return!1};this.write=function(a){b(g,a)};this.writeAs=b;this.createByteArray= -a;this.loadContentXmlAsFragments=function(a,b){w.loadAsString(a,function(a,c){if(a)return b.rootElementReady(a);b.rootElementReady(null,c,!0)})};this.loadAsString=function(a,b){d(a,function(a,c){if(a||null===c)return b(a,null);var e=runtime.byteArrayToString(c,"utf8");b(null,e)})};this.loadAsDOM=function(a,b){w.loadAsString(a,function(a,c){if(a||null===c)b(a,null);else{var e=(new DOMParser).parseFromString(c,"text/xml");b(null,e)}})};this.loadAsDataURL=function(a,b,c){d(a,function(a,e){if(a||!e)return c(a, -null);var d=0,f;b||(b=80===e[1]&&78===e[2]&&71===e[3]?"image/png":255===e[0]&&216===e[1]&&255===e[2]?"image/jpeg":71===e[0]&&73===e[1]&&70===e[2]?"image/gif":"");for(f="data:"+b+";base64,";d<e.length;)f+=x.convertUTF8ArrayToBase64(e.subarray(d,Math.min(d+45E3,e.length))),d+=45E3;c(null,f)})};this.getEntries=function(){return q.slice()};k=-1;null===l?q=[]:runtime.getFileSize(g,function(a){k=a;0>k?l("File '"+g+"' cannot be read.",w):runtime.read(g,k-22,22,function(a,b){a||null===l||null===b?l(a,w): -h(b,l)})})}; -// Input 16 -gui.Avatar=function(g,l){var f=this,p,r,n;this.setColor=function(f){r.style.borderColor=f};this.setImageUrl=function(h){f.isVisible()?r.src=h:n=h};this.isVisible=function(){return"block"===p.style.display};this.show=function(){n&&(r.src=n,n=void 0);p.style.display="block"};this.hide=function(){p.style.display="none"};this.markAsFocussed=function(f){p.className=f?"active":""};this.destroy=function(f){g.removeChild(p);f()};(function(){var f=g.ownerDocument,d=f.documentElement.namespaceURI;p=f.createElementNS(d, -"div");r=f.createElementNS(d,"img");r.width=64;r.height=64;p.appendChild(r);p.style.width="64px";p.style.height="70px";p.style.position="absolute";p.style.top="-80px";p.style.left="-34px";p.style.display=l?"block":"none";g.appendChild(p)})()}; -// Input 17 -gui.EditInfoHandle=function(g){var l=[],f,p=g.ownerDocument,r=p.documentElement.namespaceURI;this.setEdits=function(g){l=g;var h,d,m,c;f.innerHTML="";for(g=0;g<l.length;g+=1)h=p.createElementNS(r,"div"),h.className="editInfo",d=p.createElementNS(r,"span"),d.className="editInfoColor",d.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",l[g].memberid),m=p.createElementNS(r,"span"),m.className="editInfoAuthor",m.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",l[g].memberid), -c=p.createElementNS(r,"span"),c.className="editInfoTime",c.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",l[g].memberid),c.innerHTML=l[g].time,h.appendChild(d),h.appendChild(m),h.appendChild(c),f.appendChild(h)};this.show=function(){f.style.display="block"};this.hide=function(){f.style.display="none"};this.destroy=function(l){g.removeChild(f);l()};f=p.createElementNS(r,"div");f.setAttribute("class","editInfoHandle");f.style.display="none";g.appendChild(f)}; -// Input 18 +2932959818,3654703836,1088359270,936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117],b,e,f=a.length,d=0,d=0;b=-1;for(e=0;e<f;e+=1)d=(b^a[e])&255,d=c[d],b=b>>>8^d;return b^-1}function p(a){return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&15,a>>5&63,(a&31)<<1)}function d(a){var c=a.getFullYear();return 1980>c?0:c-1980<< +25|a.getMonth()+1<<21|a.getDate()<<16|a.getHours()<<11|a.getMinutes()<<5|a.getSeconds()>>1}function n(a,c){var b,f,d,m,l,g,n,k=this;this.load=function(c){if(null!==k.data)c(null,k.data);else{var b=l+34+f+d+256;b+n>e&&(b=e-n);runtime.read(a,n,b,function(b,e){if(b||null===e)c(b,e);else a:{var f=e,d=new core.ByteArray(f),n=d.readUInt32LE(),h;if(67324752!==n)c("File entry signature is wrong."+n.toString()+" "+f.length.toString(),null);else{d.pos+=22;n=d.readUInt16LE();h=d.readUInt16LE();d.pos+=n+h;if(m){f= +f.subarray(d.pos,d.pos+l);if(l!==f.length){c("The amount of compressed bytes read was "+f.length.toString()+" instead of "+l.toString()+" for "+k.filename+" in "+a+".",null);break a}f=w(f,g)}else f=f.subarray(d.pos,d.pos+g);g!==f.length?c("The amount of bytes read was "+f.length.toString()+" instead of "+g.toString()+" for "+k.filename+" in "+a+".",null):(k.data=f,c(null,f))}}})}};this.set=function(a,c,b,e){k.filename=a;k.data=c;k.compressed=b;k.date=e};this.error=null;c&&(b=c.readUInt32LE(),33639248!== +b?this.error="Central directory entry has wrong signature at position "+(c.pos-4).toString()+' for file "'+a+'": '+c.data.length.toString():(c.pos+=6,m=c.readUInt16LE(),this.date=p(c.readUInt32LE()),c.readUInt32LE(),l=c.readUInt32LE(),g=c.readUInt32LE(),f=c.readUInt16LE(),d=c.readUInt16LE(),b=c.readUInt16LE(),c.pos+=8,n=c.readUInt32LE(),this.filename=runtime.byteArrayToString(c.data.subarray(c.pos,c.pos+f),"utf8"),this.data=null,c.pos+=f+d+b))}function g(a,c){if(22!==a.length)c("Central directory length should be 22.", +z);else{var b=new core.ByteArray(a),f;f=b.readUInt32LE();101010256!==f?c("Central directory signature is wrong: "+f.toString(),z):(f=b.readUInt16LE(),0!==f?c("Zip files with non-zero disk numbers are not supported.",z):(f=b.readUInt16LE(),0!==f?c("Zip files with non-zero disk numbers are not supported.",z):(f=b.readUInt16LE(),t=b.readUInt16LE(),f!==t?c("Number of entries is inconsistent.",z):(f=b.readUInt32LE(),b=b.readUInt16LE(),b=e-22-f,runtime.read(k,b,e-b,function(a,b){if(a||null===b)c(a,z);else a:{var e= +new core.ByteArray(b),f,d;m=[];for(f=0;f<t;f+=1){d=new n(k,e);if(d.error){c(d.error,z);break a}m[m.length]=d}c(null,z)}})))))}}function q(a,c){var b=null,e,f;for(f=0;f<m.length;f+=1)if(e=m[f],e.filename===a){b=e;break}b?b.data?c(null,b.data):b.load(c):c(a+" not found.",null)}function r(a){var c=new core.ByteArrayWriter("utf8"),e=0;c.appendArray([80,75,3,4,20,0,0,0,0,0]);a.data&&(e=a.data.length);c.appendUInt32LE(d(a.date));c.appendUInt32LE(a.data?b(a.data):0);c.appendUInt32LE(e);c.appendUInt32LE(e); +c.appendUInt16LE(a.filename.length);c.appendUInt16LE(0);c.appendString(a.filename);a.data&&c.appendByteArray(a.data);return c}function l(a,c){var e=new core.ByteArrayWriter("utf8"),f=0;e.appendArray([80,75,1,2,20,0,20,0,0,0,0,0]);a.data&&(f=a.data.length);e.appendUInt32LE(d(a.date));e.appendUInt32LE(a.data?b(a.data):0);e.appendUInt32LE(f);e.appendUInt32LE(f);e.appendUInt16LE(a.filename.length);e.appendArray([0,0,0,0,0,0,0,0,0,0,0,0]);e.appendUInt32LE(c);e.appendString(a.filename);return e}function f(a, +c){if(a===m.length)c(null);else{var b=m[a];null!==b.data?f(a+1,c):b.load(function(b){b?c(b):f(a+1,c)})}}function c(a,c){f(0,function(b){if(b)c(b);else{var e,f,d=new core.ByteArrayWriter("utf8"),g=[0];for(e=0;e<m.length;e+=1)d.appendByteArrayWriter(r(m[e])),g.push(d.getLength());b=d.getLength();for(e=0;e<m.length;e+=1)f=m[e],d.appendByteArrayWriter(l(f,g[e]));e=d.getLength()-b;d.appendArray([80,75,5,6,0,0,0,0]);d.appendUInt16LE(m.length);d.appendUInt16LE(m.length);d.appendUInt32LE(e);d.appendUInt32LE(b); +d.appendArray([0,0]);a(d.getByteArray())}})}function a(a,b){c(function(c){runtime.writeFile(a,c,b)},b)}var m,e,t,w=(new core.RawInflate).inflate,z=this,x=new core.Base64;this.load=q;this.save=function(a,c,b,e){var f,d;for(f=0;f<m.length;f+=1)if(d=m[f],d.filename===a){d.set(a,c,b,e);return}d=new n(k);d.set(a,c,b,e);m.push(d)};this.remove=function(a){var c,b;for(c=0;c<m.length;c+=1)if(b=m[c],b.filename===a)return m.splice(c,1),!0;return!1};this.write=function(c){a(k,c)};this.writeAs=a;this.createByteArray= +c;this.loadContentXmlAsFragments=function(a,c){z.loadAsString(a,function(a,b){if(a)return c.rootElementReady(a);c.rootElementReady(null,b,!0)})};this.loadAsString=function(a,c){q(a,function(a,b){if(a||null===b)return c(a,null);var e=runtime.byteArrayToString(b,"utf8");c(null,e)})};this.loadAsDOM=function(a,c){z.loadAsString(a,function(a,b){if(a||null===b)c(a,null);else{var e=(new DOMParser).parseFromString(b,"text/xml");c(null,e)}})};this.loadAsDataURL=function(a,c,b){q(a,function(a,e){if(a||!e)return b(a, +null);var f=0,d;c||(c=80===e[1]&&78===e[2]&&71===e[3]?"image/png":255===e[0]&&216===e[1]&&255===e[2]?"image/jpeg":71===e[0]&&73===e[1]&&70===e[2]?"image/gif":"");for(d="data:"+c+";base64,";f<e.length;)d+=x.convertUTF8ArrayToBase64(e.subarray(f,Math.min(f+45E3,e.length))),f+=45E3;b(null,d)})};this.getEntries=function(){return m.slice()};e=-1;null===h?m=[]:runtime.getFileSize(k,function(a){e=a;0>e?h("File '"+k+"' cannot be read.",z):runtime.read(k,e-22,22,function(a,c){a||null===h||null===c?h(a,z): +g(c,h)})})}; +// Input 21 +xmldom.LSSerializerFilter=function(){};xmldom.LSSerializerFilter.prototype.acceptNode=function(k){}; +// Input 22 /* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -287,9 +378,8 @@ c=p.createElementNS(r,"span"),c.className="editInfoTime",c.setAttributeNS("urn:w @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -gui.KeyboardHandler=function(){function g(f,g){g||(g=l.None);return f+":"+g}var l=gui.KeyboardHandler.Modifier,f=null,p={};this.setDefault=function(g){f=g};this.bind=function(f,l,h){f=g(f,l);runtime.assert(!1===p.hasOwnProperty(f),"tried to overwrite the callback handler of key combo: "+f);p[f]=h};this.unbind=function(f,l){var h=g(f,l);delete p[h]};this.reset=function(){f=null;p={}};this.handleEvent=function(r){var n=r.keyCode,h=l.None;r.metaKey&&(h|=l.Meta);r.ctrlKey&&(h|=l.Ctrl);r.altKey&&(h|=l.Alt); -r.shiftKey&&(h|=l.Shift);n=g(n,h);n=p[n];h=!1;n?h=n():null!==f&&(h=f(r));h&&(r.preventDefault?r.preventDefault():r.returnValue=!1)}};gui.KeyboardHandler.Modifier={None:0,Meta:1,Ctrl:2,Alt:4,CtrlAlt:6,Shift:8,MetaShift:9,CtrlShift:10,AltShift:12};gui.KeyboardHandler.KeyCode={Backspace:8,Tab:9,Clear:12,Enter:13,End:35,Home:36,Left:37,Up:38,Right:39,Down:40,Delete:46,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90};(function(){return gui.KeyboardHandler})(); -// Input 19 +odf.OdfNodeFilter=function(){this.acceptNode=function(k){return"http://www.w3.org/1999/xhtml"===k.namespaceURI?NodeFilter.FILTER_SKIP:k.namespaceURI&&k.namespaceURI.match(/^urn:webodf:/)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}; +// Input 23 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -331,9 +421,17 @@ odf.Namespaces={namespaceMap:{db:"urn:oasis:names:tc:opendocument:xmlns:database office:"urn:oasis:names:tc:opendocument:xmlns:office:1.0",presentation:"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0",style:"urn:oasis:names:tc:opendocument:xmlns:style:1.0",svg:"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",table:"urn:oasis:names:tc:opendocument:xmlns:table:1.0",text:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace"},prefixMap:{},dbns:"urn:oasis:names:tc:opendocument:xmlns:database:1.0", dcns:"http://purl.org/dc/elements/1.1/",dr3dns:"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0",drawns:"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",chartns:"urn:oasis:names:tc:opendocument:xmlns:chart:1.0",fons:"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",formns:"urn:oasis:names:tc:opendocument:xmlns:form:1.0",metans:"urn:oasis:names:tc:opendocument:xmlns:meta:1.0",numberns:"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",officens:"urn:oasis:names:tc:opendocument:xmlns:office:1.0", presentationns:"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0",stylens:"urn:oasis:names:tc:opendocument:xmlns:style:1.0",svgns:"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",tablens:"urn:oasis:names:tc:opendocument:xmlns:table:1.0",textns:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",xlinkns:"http://www.w3.org/1999/xlink",xmlns:"http://www.w3.org/XML/1998/namespace"}; -(function(){var g=odf.Namespaces.namespaceMap,l=odf.Namespaces.prefixMap,f;for(f in g)g.hasOwnProperty(f)&&(l[g[f]]=f)})();odf.Namespaces.forEachPrefix=function(g){var l=odf.Namespaces.namespaceMap,f;for(f in l)l.hasOwnProperty(f)&&g(f,l[f])};odf.Namespaces.lookupNamespaceURI=function(g){var l=null;odf.Namespaces.namespaceMap.hasOwnProperty(g)&&(l=odf.Namespaces.namespaceMap[g]);return l};odf.Namespaces.lookupPrefix=function(g){var l=odf.Namespaces.prefixMap;return l.hasOwnProperty(g)?l[g]:null}; +(function(){var k=odf.Namespaces.namespaceMap,h=odf.Namespaces.prefixMap,b;for(b in k)k.hasOwnProperty(b)&&(h[k[b]]=b)})();odf.Namespaces.forEachPrefix=function(k){var h=odf.Namespaces.namespaceMap,b;for(b in h)h.hasOwnProperty(b)&&k(b,h[b])};odf.Namespaces.lookupNamespaceURI=function(k){var h=null;odf.Namespaces.namespaceMap.hasOwnProperty(k)&&(h=odf.Namespaces.namespaceMap[k]);return h};odf.Namespaces.lookupPrefix=function(k){var h=odf.Namespaces.prefixMap;return h.hasOwnProperty(k)?h[k]:null}; odf.Namespaces.lookupNamespaceURI.lookupNamespaceURI=odf.Namespaces.lookupNamespaceURI; -// Input 20 +// Input 24 +xmldom.XPathIterator=function(){};xmldom.XPathIterator.prototype.next=function(){};xmldom.XPathIterator.prototype.reset=function(){}; +function createXPathSingleton(){function k(b,c,a){return-1!==b&&(b<c||-1===c)&&(b<a||-1===a)}function h(b){for(var c=[],a=0,d=b.length,e;a<d;){var g=b,n=d,h=c,q="",p=[],r=g.indexOf("[",a),s=g.indexOf("/",a),A=g.indexOf("=",a);k(s,r,A)?(q=g.substring(a,s),a=s+1):k(r,s,A)?(q=g.substring(a,r),a=l(g,r,p)):k(A,s,r)?(q=g.substring(a,A),a=A):(q=g.substring(a,n),a=n);h.push({location:q,predicates:p});if(a<d&&"="===b[a]){e=b.substring(a+1,d);if(2<e.length&&("'"===e[0]||'"'===e[0]))e=e.slice(1,e.length-1); +else try{e=parseInt(e,10)}catch(J){}a=d}}return{steps:c,value:e}}function b(){var b=null,c=!1;this.setNode=function(a){b=a};this.reset=function(){c=!1};this.next=function(){var a=c?null:b;c=!0;return a}}function p(b,c,a){this.reset=function(){b.reset()};this.next=function(){for(var d=b.next();d;){d.nodeType===Node.ELEMENT_NODE&&(d=d.getAttributeNodeNS(c,a));if(d)break;d=b.next()}return d}}function d(b,c){var a=b.next(),d=null;this.reset=function(){b.reset();a=b.next();d=null};this.next=function(){for(;a;){if(d)if(c&& +d.firstChild)d=d.firstChild;else{for(;!d.nextSibling&&d!==a;)d=d.parentNode;d===a?a=b.next():d=d.nextSibling}else{do(d=a.firstChild)||(a=b.next());while(a&&!d)}if(d&&d.nodeType===Node.ELEMENT_NODE)return d}return null}}function n(b,c){this.reset=function(){b.reset()};this.next=function(){for(var a=b.next();a&&!c(a);)a=b.next();return a}}function g(b,c,a){c=c.split(":",2);var d=a(c[0]),e=c[1];return new n(b,function(a){return a.localName===e&&a.namespaceURI===d})}function q(d,c,a){var m=new b,e=r(m, +c,a),g=c.value;return void 0===g?new n(d,function(a){m.setNode(a);e.reset();return null!==e.next()}):new n(d,function(a){m.setNode(a);e.reset();return(a=e.next())?a.nodeValue===g:!1})}var r,l;l=function(b,c,a){for(var d=c,e=b.length,g=0;d<e;)"]"===b[d]?(g-=1,0>=g&&a.push(h(b.substring(c,d)))):"["===b[d]&&(0>=g&&(c=d+1),g+=1),d+=1;return d};r=function(b,c,a){var m,e,l,n;for(m=0;m<c.steps.length;m+=1){l=c.steps[m];e=l.location;if(""===e)b=new d(b,!1);else if("@"===e[0]){e=e.substr(1).split(":",2);n= +a(e[0]);if(!n)throw"No namespace associated with the prefix "+e[0];b=new p(b,n,e[1])}else"."!==e&&(b=new d(b,!1),-1!==e.indexOf(":")&&(b=g(b,e,a)));for(e=0;e<l.predicates.length;e+=1)n=l.predicates[e],b=q(b,n,a)}return b};return{getODFElementsWithXPath:function(d,c,a){var m=d.ownerDocument,e=[],g=null;if(m&&"function"===typeof m.evaluate)for(a=m.evaluate(c,d,a,XPathResult.UNORDERED_NODE_ITERATOR_TYPE,null),g=a.iterateNext();null!==g;)g.nodeType===Node.ELEMENT_NODE&&e.push(g),g=a.iterateNext();else{e= +new b;e.setNode(d);d=h(c);e=r(e,d,a);d=[];for(a=e.next();a;)d.push(a),a=e.next();e=d}return e}}}xmldom.XPath=createXPathSingleton(); +// Input 25 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -371,24 +469,44 @@ odf.Namespaces.lookupNamespaceURI.lookupNamespaceURI=odf.Namespaces.lookupNamesp @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils");runtime.loadClass("odf.Namespaces"); -odf.OdfUtils=function(){function g(a){return"image"===(a&&a.localName)&&a.namespaceURI===y}function l(a){return null!==a&&a.nodeType===Node.ELEMENT_NODE&&"frame"===a.localName&&a.namespaceURI===y&&"as-char"===a.getAttributeNS(H,"anchor-type")}function f(a){var b;(b="annotation"===(a&&a.localName)&&a.namespaceURI===odf.Namespaces.officens)||(b="div"===(a&&a.localName)&&"annotationWrapper"===a.className);return b}function p(a){var b=a&&a.localName;return("p"===b||"h"===b)&&a.namespaceURI===H}function r(a){for(;a&& -!p(a);)a=a.parentNode;return a}function n(a){return/^[ \t\r\n]+$/.test(a)}function h(a){if(null===a||a.nodeType!==Node.ELEMENT_NODE)return!1;var b=a.localName;return/^(span|p|h|a|meta)$/.test(b)&&a.namespaceURI===H||"span"===b&&"annotationHighlight"===a.className}function d(a){var b=a&&a.localName,c=!1;b&&(a=a.namespaceURI,a===H&&(c="s"===b||"tab"===b||"line-break"===b));return c}function m(a){return d(a)||l(a)||f(a)}function c(a){var b=a&&a.localName,c=!1;b&&(a=a.namespaceURI,a===H&&(c="s"===b)); -return c}function e(a){for(;null!==a.firstChild&&h(a);)a=a.firstChild;return a}function a(a){for(;null!==a.lastChild&&h(a);)a=a.lastChild;return a}function b(b){for(;!p(b)&&null===b.previousSibling;)b=b.parentNode;return p(b)?null:a(b.previousSibling)}function q(a){for(;!p(a)&&null===a.nextSibling;)a=a.parentNode;return p(a)?null:e(a.nextSibling)}function k(a){for(var e=!1;a;)if(a.nodeType===Node.TEXT_NODE)if(0===a.length)a=b(a);else return!n(a.data.substr(a.length-1,1));else m(a)?(e=!1===c(a),a= -null):a=b(a);return e}function t(a){var b=!1,c;for(a=a&&e(a);a;){c=a.nodeType===Node.TEXT_NODE?a.length:0;if(0<c&&!n(a.data)){b=!0;break}if(m(a)){b=!0;break}a=q(a)}return b}function A(a,b){return n(a.data.substr(b))?!t(q(a)):!1}function w(a,c){var e=a.data,d;if(!n(e[c])||m(a.parentNode))return!1;0<c?n(e[c-1])||(d=!0):k(b(a))&&(d=!0);return!0===d?A(a,c)?!1:!0:!1}function x(a){return(a=/(-?[0-9]*[0-9][0-9]*(\.[0-9]*)?|0+\.[0-9]*[1-9][0-9]*|\.[0-9]*[1-9][0-9]*)((cm)|(mm)|(in)|(pt)|(pc)|(px)|(%))/.exec(a))? -{value:parseFloat(a[1]),unit:a[3]}:null}function v(a){return(a=x(a))&&(0>a.value||"%"===a.unit)?null:a}function u(a){return(a=x(a))&&"%"!==a.unit?null:a}function s(a){switch(a.namespaceURI){case odf.Namespaces.drawns:case odf.Namespaces.svgns:case odf.Namespaces.dr3dns:return!1;case odf.Namespaces.textns:switch(a.localName){case "note-body":case "ruby-text":return!1}break;case odf.Namespaces.officens:switch(a.localName){case "annotation":case "binary-data":case "event-listeners":return!1}break;default:switch(a.localName){case "editinfo":return!1}}return!0} -var H=odf.Namespaces.textns,y=odf.Namespaces.drawns,B=/^\s*$/,L=new core.DomUtils;this.isImage=g;this.isCharacterFrame=l;this.isInlineRoot=f;this.isTextSpan=function(a){return"span"===(a&&a.localName)&&a.namespaceURI===H};this.isParagraph=p;this.getParagraphElement=r;this.isWithinTrackedChanges=function(a,b){for(;a&&a!==b;){if(a.namespaceURI===H&&"tracked-changes"===a.localName)return!0;a=a.parentNode}return!1};this.isListItem=function(a){return"list-item"===(a&&a.localName)&&a.namespaceURI===H}; -this.isLineBreak=function(a){return"line-break"===(a&&a.localName)&&a.namespaceURI===H};this.isODFWhitespace=n;this.isGroupingElement=h;this.isCharacterElement=d;this.isAnchoredAsCharacterElement=m;this.isSpaceElement=c;this.firstChild=e;this.lastChild=a;this.previousNode=b;this.nextNode=q;this.scanLeftForNonSpace=k;this.lookLeftForCharacter=function(a){var c,e=c=0;a.nodeType===Node.TEXT_NODE&&(e=a.length);0<e?(c=a.data,c=n(c.substr(e-1,1))?1===e?k(b(a))?2:0:n(c.substr(e-2,1))?0:2:1):m(a)&&(c=1); -return c};this.lookRightForCharacter=function(a){var b=!1,c=0;a&&a.nodeType===Node.TEXT_NODE&&(c=a.length);0<c?b=!n(a.data.substr(0,1)):m(a)&&(b=!0);return b};this.scanLeftForAnyCharacter=function(c){var e=!1,d;for(c=c&&a(c);c;){d=c.nodeType===Node.TEXT_NODE?c.length:0;if(0<d&&!n(c.data)){e=!0;break}if(m(c)){e=!0;break}c=b(c)}return e};this.scanRightForAnyCharacter=t;this.isTrailingWhitespace=A;this.isSignificantWhitespace=w;this.isDowngradableSpaceElement=function(a){return a.namespaceURI===H&&"s"=== -a.localName?k(b(a))&&t(q(a)):!1};this.getFirstNonWhitespaceChild=function(a){for(a=a&&a.firstChild;a&&a.nodeType===Node.TEXT_NODE&&B.test(a.nodeValue);)a=a.nextSibling;return a};this.parseLength=x;this.parseNonNegativeLength=v;this.parseFoFontSize=function(a){var b;b=(b=x(a))&&(0>=b.value||"%"===b.unit)?null:b;return b||u(a)};this.parseFoLineHeight=function(a){return v(a)||u(a)};this.getImpactedParagraphs=function(a){var b,c,e;b=a.commonAncestorContainer;var d=[],f=[];for(b.nodeType===Node.ELEMENT_NODE&& -(d=L.getElementsByTagNameNS(b,H,"p").concat(L.getElementsByTagNameNS(b,H,"h")));b&&!p(b);)b=b.parentNode;b&&d.push(b);c=d.length;for(b=0;b<c;b+=1)e=d[b],L.rangeIntersectsNode(a,e)&&f.push(e);return f};this.getTextNodes=function(a,b){var c=a.startContainer.ownerDocument.createRange(),e;e=L.getNodesInRange(a,function(e){c.selectNodeContents(e);if(e.nodeType===Node.TEXT_NODE){if(b&&L.rangesIntersect(a,c)||L.containsRange(a,c))return Boolean(r(e)&&(!n(e.textContent)||w(e,0)))?NodeFilter.FILTER_ACCEPT: -NodeFilter.FILTER_REJECT}else if(L.rangesIntersect(a,c)&&s(e))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});c.detach();return e};this.getTextElements=function(a,b,c){var e=a.startContainer.ownerDocument.createRange(),f;f=L.getNodesInRange(a,function(f){e.selectNodeContents(f);if(d(f.parentNode))return NodeFilter.FILTER_REJECT;if(f.nodeType===Node.TEXT_NODE){if(b&&L.rangesIntersect(a,e)||L.containsRange(a,e))if(c||Boolean(r(f)&&(!n(f.textContent)||w(f,0))))return NodeFilter.FILTER_ACCEPT}else if(m(f)){if(b&& -L.rangesIntersect(a,e)||L.containsRange(a,e))return NodeFilter.FILTER_ACCEPT}else if(s(f)||h(f))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});e.detach();return f};this.getParagraphElements=function(a){var b=a.startContainer.ownerDocument.createRange(),c;c=L.getNodesInRange(a,function(c){b.selectNodeContents(c);if(p(c)){if(L.rangesIntersect(a,b))return NodeFilter.FILTER_ACCEPT}else if(s(c)||h(c))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});b.detach();return c}; -this.getImageElements=function(a){var b=a.startContainer.ownerDocument.createRange(),c;c=L.getNodesInRange(a,function(c){b.selectNodeContents(c);return g(c)&&L.containsRange(a,b)?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP});b.detach();return c}}; -// Input 21 +odf.StyleInfo=function(){function k(a,c){var b,e,d,f,m,g=0;if(b=G[a.localName])if(d=b[a.namespaceURI])g=d.length;for(b=0;b<g;b+=1)e=d[b],f=e.ns,m=e.localname,(e=a.getAttributeNS(f,m))&&a.setAttributeNS(f,A[f]+m,c+e);for(d=a.firstElementChild;d;)k(d,c),d=d.nextElementSibling}function h(a,c){var b,e,d,f,m,g=0;if(b=G[a.localName])if(d=b[a.namespaceURI])g=d.length;for(b=0;b<g;b+=1)if(e=d[b],f=e.ns,m=e.localname,e=a.getAttributeNS(f,m))e=e.replace(c,""),a.setAttributeNS(f,A[f]+m,e);for(d=a.firstElementChild;d;)h(d, +c),d=d.nextElementSibling}function b(a,c){var b,e,d,f,m,g=0;if(b=G[a.localName])if(d=b[a.namespaceURI])g=d.length;for(b=0;b<g;b+=1)if(f=d[b],e=f.ns,m=f.localname,e=a.getAttributeNS(e,m))c=c||{},f=f.keyname,c.hasOwnProperty(f)?c[f][e]=1:(m={},m[e]=1,c[f]=m);return c}function p(a,c){var e,d;b(a,c);for(e=a.firstChild;e;)e.nodeType===Node.ELEMENT_NODE&&(d=e,p(d,c)),e=e.nextSibling}function d(a,c,b){this.key=a;this.name=c;this.family=b;this.requires={}}function n(a,c,b){var e=a+'"'+c,f=b[e];f||(f=b[e]= +new d(e,a,c));return f}function g(a,c,b){var e,d,f,m,l,k=0;e=a.getAttributeNS(v,"name");m=a.getAttributeNS(v,"family");e&&m&&(c=n(e,m,b));if(c){if(e=G[a.localName])if(f=e[a.namespaceURI])k=f.length;for(e=0;e<k;e+=1)if(m=f[e],d=m.ns,l=m.localname,d=a.getAttributeNS(d,l))m=m.keyname,m=n(d,m,b),c.requires[m.key]=m}for(a=a.firstElementChild;a;)g(a,c,b),a=a.nextElementSibling;return b}function q(a,c){var b=c[a.family];b||(b=c[a.family]={});b[a.name]=1;Object.keys(a.requires).forEach(function(b){q(a.requires[b], +c)})}function r(a,c){var b=g(a,null,{});Object.keys(b).forEach(function(a){a=b[a];var e=c[a.family];e&&e.hasOwnProperty(a.name)&&q(a,c)})}function l(a,c){function b(c){(c=f.getAttributeNS(v,c))&&(a[c]=!0)}var e=["font-name","font-name-asian","font-name-complex"],d,f;for(d=c&&c.firstElementChild;d;)f=d,e.forEach(b),l(a,f),d=d.nextElementSibling}function f(a,c){function b(a){var e=m.getAttributeNS(v,a);e&&c.hasOwnProperty(e)&&m.setAttributeNS(v,"style:"+a,c[e])}var e=["font-name","font-name-asian", +"font-name-complex"],d,m;for(d=a&&a.firstElementChild;d;)m=d,e.forEach(b),f(m,c),d=d.nextElementSibling}var c=odf.Namespaces.chartns,a=odf.Namespaces.dbns,m=odf.Namespaces.dr3dns,e=odf.Namespaces.drawns,t=odf.Namespaces.formns,w=odf.Namespaces.numberns,z=odf.Namespaces.officens,x=odf.Namespaces.presentationns,v=odf.Namespaces.stylens,u=odf.Namespaces.tablens,s=odf.Namespaces.textns,A={"urn:oasis:names:tc:opendocument:xmlns:chart:1.0":"chart:","urn:oasis:names:tc:opendocument:xmlns:database:1.0":"db:", +"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0":"dr3d:","urn:oasis:names:tc:opendocument:xmlns:drawing:1.0":"draw:","urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0":"fo:","urn:oasis:names:tc:opendocument:xmlns:form:1.0":"form:","urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0":"number:","urn:oasis:names:tc:opendocument:xmlns:office:1.0":"office:","urn:oasis:names:tc:opendocument:xmlns:presentation:1.0":"presentation:","urn:oasis:names:tc:opendocument:xmlns:style:1.0":"style:","urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0":"svg:", +"urn:oasis:names:tc:opendocument:xmlns:table:1.0":"table:","urn:oasis:names:tc:opendocument:xmlns:text:1.0":"chart:","http://www.w3.org/XML/1998/namespace":"xml:"},J={text:[{ens:v,en:"tab-stop",ans:v,a:"leader-text-style"},{ens:v,en:"drop-cap",ans:v,a:"style-name"},{ens:s,en:"notes-configuration",ans:s,a:"citation-body-style-name"},{ens:s,en:"notes-configuration",ans:s,a:"citation-style-name"},{ens:s,en:"a",ans:s,a:"style-name"},{ens:s,en:"alphabetical-index",ans:s,a:"style-name"},{ens:s,en:"linenumbering-configuration", +ans:s,a:"style-name"},{ens:s,en:"list-level-style-number",ans:s,a:"style-name"},{ens:s,en:"ruby-text",ans:s,a:"style-name"},{ens:s,en:"span",ans:s,a:"style-name"},{ens:s,en:"a",ans:s,a:"visited-style-name"},{ens:v,en:"text-properties",ans:v,a:"text-line-through-text-style"},{ens:s,en:"alphabetical-index-source",ans:s,a:"main-entry-style-name"},{ens:s,en:"index-entry-bibliography",ans:s,a:"style-name"},{ens:s,en:"index-entry-chapter",ans:s,a:"style-name"},{ens:s,en:"index-entry-link-end",ans:s,a:"style-name"}, +{ens:s,en:"index-entry-link-start",ans:s,a:"style-name"},{ens:s,en:"index-entry-page-number",ans:s,a:"style-name"},{ens:s,en:"index-entry-span",ans:s,a:"style-name"},{ens:s,en:"index-entry-tab-stop",ans:s,a:"style-name"},{ens:s,en:"index-entry-text",ans:s,a:"style-name"},{ens:s,en:"index-title-template",ans:s,a:"style-name"},{ens:s,en:"list-level-style-bullet",ans:s,a:"style-name"},{ens:s,en:"outline-level-style",ans:s,a:"style-name"}],paragraph:[{ens:e,en:"caption",ans:e,a:"text-style-name"},{ens:e, +en:"circle",ans:e,a:"text-style-name"},{ens:e,en:"connector",ans:e,a:"text-style-name"},{ens:e,en:"control",ans:e,a:"text-style-name"},{ens:e,en:"custom-shape",ans:e,a:"text-style-name"},{ens:e,en:"ellipse",ans:e,a:"text-style-name"},{ens:e,en:"frame",ans:e,a:"text-style-name"},{ens:e,en:"line",ans:e,a:"text-style-name"},{ens:e,en:"measure",ans:e,a:"text-style-name"},{ens:e,en:"path",ans:e,a:"text-style-name"},{ens:e,en:"polygon",ans:e,a:"text-style-name"},{ens:e,en:"polyline",ans:e,a:"text-style-name"}, +{ens:e,en:"rect",ans:e,a:"text-style-name"},{ens:e,en:"regular-polygon",ans:e,a:"text-style-name"},{ens:z,en:"annotation",ans:e,a:"text-style-name"},{ens:t,en:"column",ans:t,a:"text-style-name"},{ens:v,en:"style",ans:v,a:"next-style-name"},{ens:u,en:"body",ans:u,a:"paragraph-style-name"},{ens:u,en:"even-columns",ans:u,a:"paragraph-style-name"},{ens:u,en:"even-rows",ans:u,a:"paragraph-style-name"},{ens:u,en:"first-column",ans:u,a:"paragraph-style-name"},{ens:u,en:"first-row",ans:u,a:"paragraph-style-name"}, +{ens:u,en:"last-column",ans:u,a:"paragraph-style-name"},{ens:u,en:"last-row",ans:u,a:"paragraph-style-name"},{ens:u,en:"odd-columns",ans:u,a:"paragraph-style-name"},{ens:u,en:"odd-rows",ans:u,a:"paragraph-style-name"},{ens:s,en:"notes-configuration",ans:s,a:"default-style-name"},{ens:s,en:"alphabetical-index-entry-template",ans:s,a:"style-name"},{ens:s,en:"bibliography-entry-template",ans:s,a:"style-name"},{ens:s,en:"h",ans:s,a:"style-name"},{ens:s,en:"illustration-index-entry-template",ans:s,a:"style-name"}, +{ens:s,en:"index-source-style",ans:s,a:"style-name"},{ens:s,en:"object-index-entry-template",ans:s,a:"style-name"},{ens:s,en:"p",ans:s,a:"style-name"},{ens:s,en:"table-index-entry-template",ans:s,a:"style-name"},{ens:s,en:"table-of-content-entry-template",ans:s,a:"style-name"},{ens:s,en:"table-index-entry-template",ans:s,a:"style-name"},{ens:s,en:"user-index-entry-template",ans:s,a:"style-name"},{ens:v,en:"page-layout-properties",ans:v,a:"register-truth-ref-style-name"}],chart:[{ens:c,en:"axis",ans:c, +a:"style-name"},{ens:c,en:"chart",ans:c,a:"style-name"},{ens:c,en:"data-label",ans:c,a:"style-name"},{ens:c,en:"data-point",ans:c,a:"style-name"},{ens:c,en:"equation",ans:c,a:"style-name"},{ens:c,en:"error-indicator",ans:c,a:"style-name"},{ens:c,en:"floor",ans:c,a:"style-name"},{ens:c,en:"footer",ans:c,a:"style-name"},{ens:c,en:"grid",ans:c,a:"style-name"},{ens:c,en:"legend",ans:c,a:"style-name"},{ens:c,en:"mean-value",ans:c,a:"style-name"},{ens:c,en:"plot-area",ans:c,a:"style-name"},{ens:c,en:"regression-curve", +ans:c,a:"style-name"},{ens:c,en:"series",ans:c,a:"style-name"},{ens:c,en:"stock-gain-marker",ans:c,a:"style-name"},{ens:c,en:"stock-loss-marker",ans:c,a:"style-name"},{ens:c,en:"stock-range-line",ans:c,a:"style-name"},{ens:c,en:"subtitle",ans:c,a:"style-name"},{ens:c,en:"title",ans:c,a:"style-name"},{ens:c,en:"wall",ans:c,a:"style-name"}],section:[{ens:s,en:"alphabetical-index",ans:s,a:"style-name"},{ens:s,en:"bibliography",ans:s,a:"style-name"},{ens:s,en:"illustration-index",ans:s,a:"style-name"}, +{ens:s,en:"index-title",ans:s,a:"style-name"},{ens:s,en:"object-index",ans:s,a:"style-name"},{ens:s,en:"section",ans:s,a:"style-name"},{ens:s,en:"table-of-content",ans:s,a:"style-name"},{ens:s,en:"table-index",ans:s,a:"style-name"},{ens:s,en:"user-index",ans:s,a:"style-name"}],ruby:[{ens:s,en:"ruby",ans:s,a:"style-name"}],table:[{ens:a,en:"query",ans:a,a:"style-name"},{ens:a,en:"table-representation",ans:a,a:"style-name"},{ens:u,en:"background",ans:u,a:"style-name"},{ens:u,en:"table",ans:u,a:"style-name"}], +"table-column":[{ens:a,en:"column",ans:a,a:"style-name"},{ens:u,en:"table-column",ans:u,a:"style-name"}],"table-row":[{ens:a,en:"query",ans:a,a:"default-row-style-name"},{ens:a,en:"table-representation",ans:a,a:"default-row-style-name"},{ens:u,en:"table-row",ans:u,a:"style-name"}],"table-cell":[{ens:a,en:"column",ans:a,a:"default-cell-style-name"},{ens:u,en:"table-column",ans:u,a:"default-cell-style-name"},{ens:u,en:"table-row",ans:u,a:"default-cell-style-name"},{ens:u,en:"body",ans:u,a:"style-name"}, +{ens:u,en:"covered-table-cell",ans:u,a:"style-name"},{ens:u,en:"even-columns",ans:u,a:"style-name"},{ens:u,en:"covered-table-cell",ans:u,a:"style-name"},{ens:u,en:"even-columns",ans:u,a:"style-name"},{ens:u,en:"even-rows",ans:u,a:"style-name"},{ens:u,en:"first-column",ans:u,a:"style-name"},{ens:u,en:"first-row",ans:u,a:"style-name"},{ens:u,en:"last-column",ans:u,a:"style-name"},{ens:u,en:"last-row",ans:u,a:"style-name"},{ens:u,en:"odd-columns",ans:u,a:"style-name"},{ens:u,en:"odd-rows",ans:u,a:"style-name"}, +{ens:u,en:"table-cell",ans:u,a:"style-name"}],graphic:[{ens:m,en:"cube",ans:e,a:"style-name"},{ens:m,en:"extrude",ans:e,a:"style-name"},{ens:m,en:"rotate",ans:e,a:"style-name"},{ens:m,en:"scene",ans:e,a:"style-name"},{ens:m,en:"sphere",ans:e,a:"style-name"},{ens:e,en:"caption",ans:e,a:"style-name"},{ens:e,en:"circle",ans:e,a:"style-name"},{ens:e,en:"connector",ans:e,a:"style-name"},{ens:e,en:"control",ans:e,a:"style-name"},{ens:e,en:"custom-shape",ans:e,a:"style-name"},{ens:e,en:"ellipse",ans:e,a:"style-name"}, +{ens:e,en:"frame",ans:e,a:"style-name"},{ens:e,en:"g",ans:e,a:"style-name"},{ens:e,en:"line",ans:e,a:"style-name"},{ens:e,en:"measure",ans:e,a:"style-name"},{ens:e,en:"page-thumbnail",ans:e,a:"style-name"},{ens:e,en:"path",ans:e,a:"style-name"},{ens:e,en:"polygon",ans:e,a:"style-name"},{ens:e,en:"polyline",ans:e,a:"style-name"},{ens:e,en:"rect",ans:e,a:"style-name"},{ens:e,en:"regular-polygon",ans:e,a:"style-name"},{ens:z,en:"annotation",ans:e,a:"style-name"}],presentation:[{ens:m,en:"cube",ans:x, +a:"style-name"},{ens:m,en:"extrude",ans:x,a:"style-name"},{ens:m,en:"rotate",ans:x,a:"style-name"},{ens:m,en:"scene",ans:x,a:"style-name"},{ens:m,en:"sphere",ans:x,a:"style-name"},{ens:e,en:"caption",ans:x,a:"style-name"},{ens:e,en:"circle",ans:x,a:"style-name"},{ens:e,en:"connector",ans:x,a:"style-name"},{ens:e,en:"control",ans:x,a:"style-name"},{ens:e,en:"custom-shape",ans:x,a:"style-name"},{ens:e,en:"ellipse",ans:x,a:"style-name"},{ens:e,en:"frame",ans:x,a:"style-name"},{ens:e,en:"g",ans:x,a:"style-name"}, +{ens:e,en:"line",ans:x,a:"style-name"},{ens:e,en:"measure",ans:x,a:"style-name"},{ens:e,en:"page-thumbnail",ans:x,a:"style-name"},{ens:e,en:"path",ans:x,a:"style-name"},{ens:e,en:"polygon",ans:x,a:"style-name"},{ens:e,en:"polyline",ans:x,a:"style-name"},{ens:e,en:"rect",ans:x,a:"style-name"},{ens:e,en:"regular-polygon",ans:x,a:"style-name"},{ens:z,en:"annotation",ans:x,a:"style-name"}],"drawing-page":[{ens:e,en:"page",ans:e,a:"style-name"},{ens:x,en:"notes",ans:e,a:"style-name"},{ens:v,en:"handout-master", +ans:e,a:"style-name"},{ens:v,en:"master-page",ans:e,a:"style-name"}],"list-style":[{ens:s,en:"list",ans:s,a:"style-name"},{ens:s,en:"numbered-paragraph",ans:s,a:"style-name"},{ens:s,en:"list-item",ans:s,a:"style-override"},{ens:v,en:"style",ans:v,a:"list-style-name"}],data:[{ens:v,en:"style",ans:v,a:"data-style-name"},{ens:v,en:"style",ans:v,a:"percentage-data-style-name"},{ens:x,en:"date-time-decl",ans:v,a:"data-style-name"},{ens:s,en:"creation-date",ans:v,a:"data-style-name"},{ens:s,en:"creation-time", +ans:v,a:"data-style-name"},{ens:s,en:"database-display",ans:v,a:"data-style-name"},{ens:s,en:"date",ans:v,a:"data-style-name"},{ens:s,en:"editing-duration",ans:v,a:"data-style-name"},{ens:s,en:"expression",ans:v,a:"data-style-name"},{ens:s,en:"meta-field",ans:v,a:"data-style-name"},{ens:s,en:"modification-date",ans:v,a:"data-style-name"},{ens:s,en:"modification-time",ans:v,a:"data-style-name"},{ens:s,en:"print-date",ans:v,a:"data-style-name"},{ens:s,en:"print-time",ans:v,a:"data-style-name"},{ens:s, +en:"table-formula",ans:v,a:"data-style-name"},{ens:s,en:"time",ans:v,a:"data-style-name"},{ens:s,en:"user-defined",ans:v,a:"data-style-name"},{ens:s,en:"user-field-get",ans:v,a:"data-style-name"},{ens:s,en:"user-field-input",ans:v,a:"data-style-name"},{ens:s,en:"variable-get",ans:v,a:"data-style-name"},{ens:s,en:"variable-input",ans:v,a:"data-style-name"},{ens:s,en:"variable-set",ans:v,a:"data-style-name"}],"page-layout":[{ens:x,en:"notes",ans:v,a:"page-layout-name"},{ens:v,en:"handout-master",ans:v, +a:"page-layout-name"},{ens:v,en:"master-page",ans:v,a:"page-layout-name"}]},G,D=xmldom.XPath;this.collectUsedFontFaces=l;this.changeFontFaceNames=f;this.UsedStyleList=function(a,c){var b={};this.uses=function(a){var c=a.localName,d=a.getAttributeNS(e,"name")||a.getAttributeNS(v,"name");a="style"===c?a.getAttributeNS(v,"family"):a.namespaceURI===w?"data":c;return(a=b[a])?0<a[d]:!1};p(a,b);c&&r(c,b)};this.hasDerivedStyles=function(a,c,b){var e=b.getAttributeNS(v,"name");b=b.getAttributeNS(v,"family"); +return D.getODFElementsWithXPath(a,"//style:*[@style:parent-style-name='"+e+"'][@style:family='"+b+"']",c).length?!0:!1};this.prefixStyleNames=function(a,c,b){var d;if(a){for(d=a.firstChild;d;){if(d.nodeType===Node.ELEMENT_NODE){var f=d,m=c,g=f.getAttributeNS(e,"name"),l=void 0;g?l=e:(g=f.getAttributeNS(v,"name"))&&(l=v);l&&f.setAttributeNS(l,A[l]+"name",m+g)}d=d.nextSibling}k(a,c);b&&k(b,c)}};this.removePrefixFromStyleNames=function(a,c,b){var d=RegExp("^"+c);if(a){for(c=a.firstChild;c;){if(c.nodeType=== +Node.ELEMENT_NODE){var f=c,m=d,g=f.getAttributeNS(e,"name"),l=void 0;g?l=e:(g=f.getAttributeNS(v,"name"))&&(l=v);l&&(g=g.replace(m,""),f.setAttributeNS(l,A[l]+"name",g))}c=c.nextSibling}h(a,d);b&&h(b,d)}};this.determineStylesForNode=b;G=function(){var a,c,b,e,d,f={},m,g,l,n;for(b in J)if(J.hasOwnProperty(b))for(e=J[b],c=e.length,a=0;a<c;a+=1)d=e[a],l=d.en,n=d.ens,f.hasOwnProperty(l)?m=f[l]:f[l]=m={},m.hasOwnProperty(n)?g=m[n]:m[n]=g=[],g.push({ns:d.ans,localname:d.a,keyname:b});return f}()}; +// Input 26 +"function"!==typeof Object.create&&(Object.create=function(k){var h=function(){};h.prototype=k;return new h}); +xmldom.LSSerializer=function(){function k(b){var n=b||{},g=function(b){var c={},a;for(a in b)b.hasOwnProperty(a)&&(c[b[a]]=a);return c}(b),k=[n],h=[g],l=0;this.push=function(){l+=1;n=k[l]=Object.create(n);g=h[l]=Object.create(g)};this.pop=function(){k.pop();h.pop();l-=1;n=k[l];g=h[l]};this.getLocalNamespaceDefinitions=function(){return g};this.getQName=function(b){var c=b.namespaceURI,a=0,d;if(!c)return b.localName;if(d=g[c])return d+":"+b.localName;do{d||!b.prefix?(d="ns"+a,a+=1):d=b.prefix;if(n[d]=== +c)break;if(!n[d]){n[d]=c;g[c]=d;break}d=null}while(null===d);return d+":"+b.localName}}function h(b){return b.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""")}function b(d,n){var g="",k=p.filter?p.filter.acceptNode(n):NodeFilter.FILTER_ACCEPT,r;if(k===NodeFilter.FILTER_ACCEPT&&n.nodeType===Node.ELEMENT_NODE){d.push();r=d.getQName(n);var l,f=n.attributes,c,a,m,e="",t;l="<"+r;c=f.length;for(a=0;a<c;a+=1)m=f.item(a),"http://www.w3.org/2000/xmlns/"!== +m.namespaceURI&&(t=p.filter?p.filter.acceptNode(m):NodeFilter.FILTER_ACCEPT,t===NodeFilter.FILTER_ACCEPT&&(t=d.getQName(m),m="string"===typeof m.value?h(m.value):m.value,e+=" "+(t+'="'+m+'"')));c=d.getLocalNamespaceDefinitions();for(a in c)c.hasOwnProperty(a)&&((f=c[a])?"xmlns"!==f&&(l+=" xmlns:"+c[a]+'="'+a+'"'):l+=' xmlns="'+a+'"');g+=l+(e+">")}if(k===NodeFilter.FILTER_ACCEPT||k===NodeFilter.FILTER_SKIP){for(k=n.firstChild;k;)g+=b(d,k),k=k.nextSibling;n.nodeValue&&(g+=h(n.nodeValue))}r&&(g+="</"+ +r+">",d.pop());return g}var p=this;this.filter=null;this.writeToString=function(d,n){if(!d)return"";var g=new k(n);return b(g,d)}}; +// Input 27 /* - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -423,28 +541,36 @@ this.getImageElements=function(a){var b=a.startContainer.ownerDocument.createRan @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.Server=function(){};ops.Server.prototype.connect=function(g,l){};ops.Server.prototype.networkStatus=function(){};ops.Server.prototype.login=function(g,l,f,p){};ops.Server.prototype.joinSession=function(g,l,f,p){};ops.Server.prototype.leaveSession=function(g,l,f,p){};ops.Server.prototype.getGenesisUrl=function(g){}; -// Input 22 -xmldom.LSSerializerFilter=function(){};xmldom.LSSerializerFilter.prototype.acceptNode=function(g){}; -// Input 23 -xmldom.XPathIterator=function(){};xmldom.XPathIterator.prototype.next=function(){};xmldom.XPathIterator.prototype.reset=function(){}; -function createXPathSingleton(){function g(c,a,b){return-1!==c&&(c<a||-1===a)&&(c<b||-1===b)}function l(e){for(var a=[],b=0,d=e.length,f;b<d;){var h=e,m=d,l=a,n="",p=[],r=h.indexOf("[",b),s=h.indexOf("/",b),H=h.indexOf("=",b);g(s,r,H)?(n=h.substring(b,s),b=s+1):g(r,s,H)?(n=h.substring(b,r),b=c(h,r,p)):g(H,s,r)?(n=h.substring(b,H),b=H):(n=h.substring(b,m),b=m);l.push({location:n,predicates:p});if(b<d&&"="===e[b]){f=e.substring(b+1,d);if(2<f.length&&("'"===f[0]||'"'===f[0]))f=f.slice(1,f.length-1); -else try{f=parseInt(f,10)}catch(y){}b=d}}return{steps:a,value:f}}function f(){var c=null,a=!1;this.setNode=function(a){c=a};this.reset=function(){a=!1};this.next=function(){var b=a?null:c;a=!0;return b}}function p(c,a,b){this.reset=function(){c.reset()};this.next=function(){for(var d=c.next();d;){d.nodeType===Node.ELEMENT_NODE&&(d=d.getAttributeNodeNS(a,b));if(d)break;d=c.next()}return d}}function r(c,a){var b=c.next(),d=null;this.reset=function(){c.reset();b=c.next();d=null};this.next=function(){for(;b;){if(d)if(a&& -d.firstChild)d=d.firstChild;else{for(;!d.nextSibling&&d!==b;)d=d.parentNode;d===b?b=c.next():d=d.nextSibling}else{do(d=b.firstChild)||(b=c.next());while(b&&!d)}if(d&&d.nodeType===Node.ELEMENT_NODE)return d}return null}}function n(c,a){this.reset=function(){c.reset()};this.next=function(){for(var b=c.next();b&&!a(b);)b=c.next();return b}}function h(c,a,b){a=a.split(":",2);var d=b(a[0]),f=a[1];return new n(c,function(a){return a.localName===f&&a.namespaceURI===d})}function d(c,a,b){var d=new f,k=m(d, -a,b),h=a.value;return void 0===h?new n(c,function(a){d.setNode(a);k.reset();return null!==k.next()}):new n(c,function(a){d.setNode(a);k.reset();return(a=k.next())?a.nodeValue===h:!1})}var m,c;c=function(c,a,b){for(var d=a,f=c.length,h=0;d<f;)"]"===c[d]?(h-=1,0>=h&&b.push(l(c.substring(a,d)))):"["===c[d]&&(0>=h&&(a=d+1),h+=1),d+=1;return d};m=function(c,a,b){var f,k,g,m;for(f=0;f<a.steps.length;f+=1){g=a.steps[f];k=g.location;if(""===k)c=new r(c,!1);else if("@"===k[0]){k=k.substr(1).split(":",2);m= -b(k[0]);if(!m)throw"No namespace associated with the prefix "+k[0];c=new p(c,m,k[1])}else"."!==k&&(c=new r(c,!1),-1!==k.indexOf(":")&&(c=h(c,k,b)));for(k=0;k<g.predicates.length;k+=1)m=g.predicates[k],c=d(c,m,b)}return c};return{getODFElementsWithXPath:function(c,a,b){var d=c.ownerDocument,k=[],h=null;if(d&&"function"===typeof d.evaluate)for(b=d.evaluate(a,c,b,XPathResult.UNORDERED_NODE_ITERATOR_TYPE,null),h=b.iterateNext();null!==h;)h.nodeType===Node.ELEMENT_NODE&&k.push(h),h=b.iterateNext();else{k= -new f;k.setNode(c);c=l(a);k=m(k,c,b);c=[];for(b=k.next();b;)c.push(b),b=k.next();k=c}return k}}}xmldom.XPath=createXPathSingleton(); -// Input 24 -runtime.loadClass("core.DomUtils"); -core.Cursor=function(g,l){function f(a){a.parentNode&&(d.push(a.previousSibling),d.push(a.nextSibling),a.parentNode.removeChild(a))}function p(a,b,c){if(b.nodeType===Node.TEXT_NODE){runtime.assert(Boolean(b),"putCursorIntoTextNode: invalid container");var e=b.parentNode;runtime.assert(Boolean(e),"putCursorIntoTextNode: container without parent");runtime.assert(0<=c&&c<=b.length,"putCursorIntoTextNode: offset is out of bounds");0===c?e.insertBefore(a,b):(c!==b.length&&b.splitText(c),e.insertBefore(a, -b.nextSibling))}else b.nodeType===Node.ELEMENT_NODE&&b.insertBefore(a,b.childNodes.item(c));d.push(a.previousSibling);d.push(a.nextSibling)}var r=g.createElementNS("urn:webodf:names:cursor","cursor"),n=g.createElementNS("urn:webodf:names:cursor","anchor"),h,d=[],m=g.createRange(),c,e=new core.DomUtils;this.getNode=function(){return r};this.getAnchorNode=function(){return n.parentNode?n:r};this.getSelectedRange=function(){c?(m.setStartBefore(r),m.collapse(!0)):(m.setStartAfter(h?n:r),m.setEndBefore(h? -r:n));return m};this.setSelectedRange=function(a,b){m&&m!==a&&m.detach();m=a;h=!1!==b;(c=a.collapsed)?(f(n),f(r),p(r,a.startContainer,a.startOffset)):(f(n),f(r),p(h?r:n,a.endContainer,a.endOffset),p(h?n:r,a.startContainer,a.startOffset));d.forEach(e.normalizeTextNodes);d.length=0};this.hasForwardSelection=function(){return h};this.remove=function(){f(r);d.forEach(e.normalizeTextNodes);d.length=0};r.setAttributeNS("urn:webodf:names:cursor","memberId",l);n.setAttributeNS("urn:webodf:names:cursor","memberId", -l)}; -// Input 25 -runtime.loadClass("core.PositionIterator");core.PositionFilter=function(){};core.PositionFilter.FilterResult={FILTER_ACCEPT:1,FILTER_REJECT:2,FILTER_SKIP:3};core.PositionFilter.prototype.acceptPosition=function(g){};(function(){return core.PositionFilter})(); -// Input 26 -runtime.loadClass("core.PositionFilter");core.PositionFilterChain=function(){var g={},l=core.PositionFilter.FilterResult.FILTER_ACCEPT,f=core.PositionFilter.FilterResult.FILTER_REJECT;this.acceptPosition=function(p){for(var r in g)if(g.hasOwnProperty(r)&&g[r].acceptPosition(p)===f)return f;return l};this.addFilter=function(f,l){g[f]=l};this.removeFilter=function(f){delete g[f]}}; -// Input 27 +(function(){function k(c,a,b){for(c=c?c.firstChild:null;c;){if(c.localName===b&&c.namespaceURI===a)return c;c=c.nextSibling}return null}function h(c){var a,b=r.length;for(a=0;a<b;a+=1)if("urn:oasis:names:tc:opendocument:xmlns:office:1.0"===c.namespaceURI&&c.localName===r[a])return a;return-1}function b(c,a){var b=new n.UsedStyleList(c,a),e=new odf.OdfNodeFilter;this.acceptNode=function(c){var d=e.acceptNode(c);d===NodeFilter.FILTER_ACCEPT&&c.parentNode===a&&c.nodeType===Node.ELEMENT_NODE&&(d=b.uses(c)? +NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT);return d}}function p(c,a){var d=new b(c,a);this.acceptNode=function(a){var c=d.acceptNode(a);c!==NodeFilter.FILTER_ACCEPT||!a.parentNode||a.parentNode.namespaceURI!==odf.Namespaces.textns||"s"!==a.parentNode.localName&&"tab"!==a.parentNode.localName||(c=NodeFilter.FILTER_REJECT);return c}}function d(c,a){if(a){var b=h(a),e,d=c.firstChild;if(-1!==b){for(;d;){e=h(d);if(-1!==e&&e>b)break;d=d.nextSibling}c.insertBefore(a,d)}}}var n=new odf.StyleInfo, +g=new core.DomUtils,q=odf.Namespaces.stylens,r="meta settings scripts font-face-decls styles automatic-styles master-styles body".split(" "),l=(new Date).getTime()+"_webodf_",f=new core.Base64;odf.ODFElement=function(){};odf.ODFDocumentElement=function(){};odf.ODFDocumentElement.prototype=new odf.ODFElement;odf.ODFDocumentElement.prototype.constructor=odf.ODFDocumentElement;odf.ODFDocumentElement.prototype.fontFaceDecls=null;odf.ODFDocumentElement.prototype.manifest=null;odf.ODFDocumentElement.prototype.settings= +null;odf.ODFDocumentElement.namespaceURI="urn:oasis:names:tc:opendocument:xmlns:office:1.0";odf.ODFDocumentElement.localName="document";odf.AnnotationElement=function(){};odf.OdfPart=function(c,a,b,e){var d=this;this.size=0;this.type=null;this.name=c;this.container=b;this.url=null;this.mimetype=a;this.onstatereadychange=this.document=null;this.EMPTY=0;this.LOADING=1;this.DONE=2;this.state=this.EMPTY;this.data="";this.load=function(){null!==e&&(this.mimetype=a,e.loadAsDataURL(c,a,function(a,c){a&& +runtime.log(a);d.url=c;if(d.onchange)d.onchange(d);if(d.onstatereadychange)d.onstatereadychange(d)}))}};odf.OdfPart.prototype.load=function(){};odf.OdfPart.prototype.getUrl=function(){return this.data?"data:;base64,"+f.toBase64(this.data):null};odf.OdfContainer=function a(m,e){function h(a){for(var b=a.firstChild,e;b;)e=b.nextSibling,b.nodeType===Node.ELEMENT_NODE?h(b):b.nodeType===Node.PROCESSING_INSTRUCTION_NODE&&a.removeChild(b),b=e}function r(a){var b={},e,d,f=a.ownerDocument.createNodeIterator(a, +NodeFilter.SHOW_ELEMENT,null,!1);for(a=f.nextNode();a;)"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&("annotation"===a.localName?(e=a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","name"))&&(b.hasOwnProperty(e)?runtime.log("Warning: annotation name used more than once with <office:annotation/>: '"+e+"'"):b[e]=a):"annotation-end"===a.localName&&((e=a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","name"))?b.hasOwnProperty(e)?(d=b[e],d.annotationEndElement? +runtime.log("Warning: annotation name used more than once with <office:annotation-end/>: '"+e+"'"):d.annotationEndElement=a):runtime.log("Warning: annotation end without an annotation start, name: '"+e+"'"):runtime.log("Warning: annotation end without a name found"))),a=f.nextNode()}function z(a,b){for(var e=a&&a.firstChild;e;)e.nodeType===Node.ELEMENT_NODE&&e.setAttributeNS("urn:webodf:names:scope","scope",b),e=e.nextSibling}function x(a){var b={},e;for(a=a.firstChild;a;)a.nodeType===Node.ELEMENT_NODE&& +a.namespaceURI===q&&"font-face"===a.localName&&(e=a.getAttributeNS(q,"name"),b[e]=a),a=a.nextSibling;return b}function v(a,b){var e=null,d,f,m;if(a)for(e=a.cloneNode(!0),d=e.firstElementChild;d;)f=d.nextElementSibling,(m=d.getAttributeNS("urn:webodf:names:scope","scope"))&&m!==b&&e.removeChild(d),d=f;return e}function u(a,b){var e,d,f,m=null,g={};if(a)for(b.forEach(function(a){n.collectUsedFontFaces(g,a)}),m=a.cloneNode(!0),e=m.firstElementChild;e;)d=e.nextElementSibling,f=e.getAttributeNS(q,"name"), +g[f]||m.removeChild(e),e=d;return m}function s(a){var b=M.rootElement.ownerDocument,e;if(a){h(a.documentElement);try{e=b.importNode(a.documentElement,!0)}catch(d){}}return e}function A(a){M.state=a;if(M.onchange)M.onchange(M);if(M.onstatereadychange)M.onstatereadychange(M)}function J(a){U=null;M.rootElement=a;a.fontFaceDecls=k(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls");a.styles=k(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles");a.automaticStyles=k(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", +"automatic-styles");a.masterStyles=k(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles");a.body=k(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");a.meta=k(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","meta");r(a)}function G(b){var e=s(b),f=M.rootElement,m;e&&"document-styles"===e.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===e.namespaceURI?(f.fontFaceDecls=k(e,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls"),d(f,f.fontFaceDecls), +m=k(e,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles"),f.styles=m||b.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles"),d(f,f.styles),m=k(e,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles"),f.automaticStyles=m||b.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles"),z(f.automaticStyles,"document-styles"),d(f,f.automaticStyles),e=k(e,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles"),f.masterStyles= +e||b.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles"),d(f,f.masterStyles),n.prefixStyleNames(f.automaticStyles,l,f.masterStyles)):A(a.INVALID)}function D(b){b=s(b);var e,f,m,g;if(b&&"document-content"===b.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===b.namespaceURI){e=M.rootElement;m=k(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls");if(e.fontFaceDecls&&m){g=e.fontFaceDecls;var l,h,p,r,F={};f=x(g);r=x(m);for(m=m.firstElementChild;m;){l= +m.nextElementSibling;if(m.namespaceURI===q&&"font-face"===m.localName)if(h=m.getAttributeNS(q,"name"),f.hasOwnProperty(h)){if(!m.isEqualNode(f[h])){p=h;for(var t=f,H=r,J=0,G=void 0,G=p=p.replace(/\d+$/,"");t.hasOwnProperty(G)||H.hasOwnProperty(G);)J+=1,G=p+J;p=G;m.setAttributeNS(q,"style:name",p);g.appendChild(m);f[p]=m;delete r[h];F[h]=p}}else g.appendChild(m),f[h]=m,delete r[h];m=l}g=F}else m&&(e.fontFaceDecls=m,d(e,m));f=k(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles"); +z(f,"document-content");g&&n.changeFontFaceNames(f,g);if(e.automaticStyles&&f)for(g=f.firstChild;g;)e.automaticStyles.appendChild(g),g=f.firstChild;else f&&(e.automaticStyles=f,d(e,f));b=k(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");if(null===b)throw"<office:body/> tag is mising.";e.body=b;d(e,e.body)}else A(a.INVALID)}function F(a){a=s(a);var b;a&&"document-meta"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&(b=M.rootElement,b.meta=k(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", +"meta"),d(b,b.meta))}function O(a){a=s(a);var b;a&&"document-settings"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&(b=M.rootElement,b.settings=k(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","settings"),d(b,b.settings))}function K(a){a=s(a);var b;if(a&&"manifest"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"===a.namespaceURI)for(b=M.rootElement,b.manifest=a,a=b.manifest.firstElementChild;a;)"file-entry"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"=== +a.namespaceURI&&(S[a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","full-path")]=a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","media-type")),a=a.nextElementSibling}function Z(b){var e=b.shift();e?E.loadAsDOM(e.path,function(d,f){e.handler(f);d||M.state===a.INVALID||Z(b)}):(r(M.rootElement),A(a.DONE))}function Q(a){var b="";odf.Namespaces.forEachPrefix(function(a,e){b+=" xmlns:"+a+'="'+e+'"'});return'<?xml version="1.0" encoding="UTF-8"?><office:'+a+" "+ +b+' office:version="1.2">'}function W(){var a=new xmldom.LSSerializer,b=Q("document-meta");a.filter=new odf.OdfNodeFilter;b+=a.writeToString(M.rootElement.meta,odf.Namespaces.namespaceMap);return b+"</office:document-meta>"}function H(a,b){var e=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest:file-entry");e.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest:full-path",a);e.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0", +"manifest:media-type",b);return e}function T(){var a=runtime.parseXML('<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2"></manifest:manifest>'),b=k(a,"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest"),e=new xmldom.LSSerializer,d;for(d in S)S.hasOwnProperty(d)&&b.appendChild(H(d,S[d]));e.filter=new odf.OdfNodeFilter;return'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n'+e.writeToString(a,odf.Namespaces.namespaceMap)} +function y(){var a=new xmldom.LSSerializer,b=Q("document-settings");a.filter=new odf.OdfNodeFilter;M.rootElement.settings.firstElementChild&&(b+=a.writeToString(M.rootElement.settings,odf.Namespaces.namespaceMap));return b+"</office:document-settings>"}function aa(){var a,e,d,f=odf.Namespaces.namespaceMap,m=new xmldom.LSSerializer,g=Q("document-styles");e=v(M.rootElement.automaticStyles,"document-styles");d=M.rootElement.masterStyles.cloneNode(!0);a=u(M.rootElement.fontFaceDecls,[d,M.rootElement.styles, +e]);n.removePrefixFromStyleNames(e,l,d);m.filter=new b(d,e);g+=m.writeToString(a,f);g+=m.writeToString(M.rootElement.styles,f);g+=m.writeToString(e,f);g+=m.writeToString(d,f);return g+"</office:document-styles>"}function N(){var a,b,e=odf.Namespaces.namespaceMap,d=new xmldom.LSSerializer,f=Q("document-content");b=v(M.rootElement.automaticStyles,"document-content");a=u(M.rootElement.fontFaceDecls,[b]);d.filter=new p(M.rootElement.body,b);f+=d.writeToString(a,e);f+=d.writeToString(b,e);f+=d.writeToString(M.rootElement.body, +e);return f+"</office:document-content>"}function R(b,e){runtime.loadXML(b,function(b,d){if(b)e(b);else{var f=s(d);f&&"document"===f.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===f.namespaceURI?(J(f),A(a.DONE)):A(a.INVALID)}})}function I(a,b){var e;e=M.rootElement;var f=e.meta;f||(e.meta=f=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","meta"),d(e,f));e=f;a&&g.mapKeyValObjOntoNode(e,a,odf.Namespaces.lookupNamespaceURI);b&&g.removeKeyElementsFromNode(e, +b,odf.Namespaces.lookupNamespaceURI)}function ca(){function b(a,e){var d;e||(e=a);d=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0",e);f[a]=d;f.appendChild(d)}var e=new core.Zip("",null),d=runtime.byteArrayFromString("application/vnd.oasis.opendocument.text","utf8"),f=M.rootElement,m=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","text");e.save("mimetype",d,!1,new Date);b("meta");b("settings");b("scripts");b("fontFaceDecls","font-face-decls"); +b("styles");b("automaticStyles","automatic-styles");b("masterStyles","master-styles");b("body");f.body.appendChild(m);S["/"]="application/vnd.oasis.opendocument.text";S["settings.xml"]="text/xml";S["meta.xml"]="text/xml";S["styles.xml"]="text/xml";S["content.xml"]="text/xml";A(a.DONE);return e}function ia(){var a,b=new Date,e=runtime.getWindow();a="WebODF/"+("undefined"!==String(typeof webodf_version)?webodf_version:"FromSource");e&&(a=a+" "+e.navigator.userAgent);I({"meta:generator":a},null);a=runtime.byteArrayFromString(y(), +"utf8");E.save("settings.xml",a,!0,b);a=runtime.byteArrayFromString(W(),"utf8");E.save("meta.xml",a,!0,b);a=runtime.byteArrayFromString(aa(),"utf8");E.save("styles.xml",a,!0,b);a=runtime.byteArrayFromString(N(),"utf8");E.save("content.xml",a,!0,b);a=runtime.byteArrayFromString(T(),"utf8");E.save("META-INF/manifest.xml",a,!0,b)}function Y(a,b){ia();E.writeAs(a,function(a){b(a)})}var M=this,E,S={},U;this.onstatereadychange=e;this.state=this.onchange=null;this.setRootElement=J;this.getContentElement= +function(){var a;U||(a=M.rootElement.body,U=k(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","text")||k(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","presentation")||k(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","spreadsheet"));if(!U)throw"Could not find content element in <office:body/>.";return U};this.getDocumentType=function(){var a=M.getContentElement();return a&&a.localName};this.getPart=function(a){return new odf.OdfPart(a,S[a],M,E)};this.getPartData=function(a,b){E.load(a, +b)};this.setMetadata=I;this.incrementEditingCycles=function(){var a;for(a=(a=M.rootElement.meta)&&a.firstChild;a&&(a.namespaceURI!==odf.Namespaces.metans||"editing-cycles"!==a.localName);)a=a.nextSibling;for(a=a&&a.firstChild;a&&a.nodeType!==Node.TEXT_NODE;)a=a.nextSibling;a=a?a.data:null;a=a?parseInt(a,10):0;isNaN(a)&&(a=0);I({"meta:editing-cycles":a+1},null)};this.createByteArray=function(a,b){ia();E.createByteArray(a,b)};this.saveAs=Y;this.save=function(a){Y(m,a)};this.getUrl=function(){return m}; +this.setBlob=function(a,b,e){e=f.convertBase64ToByteArray(e);E.save(a,e,!1,new Date);S.hasOwnProperty(a)&&runtime.log(a+" has been overwritten.");S[a]=b};this.removeBlob=function(a){var b=E.remove(a);runtime.assert(b,"file is not found: "+a);delete S[a]};this.state=a.LOADING;this.rootElement=function(a){var b=document.createElementNS(a.namespaceURI,a.localName),e;a=new a.Type;for(e in a)a.hasOwnProperty(e)&&(b[e]=a[e]);return b}({Type:odf.ODFDocumentElement,namespaceURI:odf.ODFDocumentElement.namespaceURI, +localName:odf.ODFDocumentElement.localName});E=m?new core.Zip(m,function(b,e){E=e;b?R(m,function(e){b&&(E.error=b+"\n"+e,A(a.INVALID))}):Z([{path:"styles.xml",handler:G},{path:"content.xml",handler:D},{path:"meta.xml",handler:F},{path:"settings.xml",handler:O},{path:"META-INF/manifest.xml",handler:K}])}):ca()};odf.OdfContainer.EMPTY=0;odf.OdfContainer.LOADING=1;odf.OdfContainer.DONE=2;odf.OdfContainer.INVALID=3;odf.OdfContainer.SAVING=4;odf.OdfContainer.MODIFIED=5;odf.OdfContainer.getContainer=function(a){return new odf.OdfContainer(a, +null)};return odf.OdfContainer})(); +// Input 28 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -482,14 +608,20 @@ runtime.loadClass("core.PositionFilter");core.PositionFilterChain=function(){var @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -gui.AnnotatableCanvas=function(){};gui.AnnotatableCanvas.prototype.refreshSize=function(){};gui.AnnotatableCanvas.prototype.getZoomLevel=function(){};gui.AnnotatableCanvas.prototype.getSizer=function(){}; -gui.AnnotationViewManager=function(g,l,f){function p(a){var b=a.node,d=a.end;a=m.createRange();d&&(a.setStart(b,b.childNodes.length),a.setEnd(d,0),d=c.getTextNodes(a,!1),d.forEach(function(a){var c=m.createElement("span"),d=b.getAttributeNS(odf.Namespaces.officens,"name");c.className="annotationHighlight";c.setAttribute("annotation",d);a.parentNode.insertBefore(c,a);c.appendChild(a)}));a.detach()}function r(a){var b=g.getSizer();a?(f.style.display="inline-block",b.style.paddingRight=e.getComputedStyle(f).width): -(f.style.display="none",b.style.paddingRight=0);g.refreshSize()}function n(){d.sort(function(a,b){return a.node.compareDocumentPosition(b.node)===Node.DOCUMENT_POSITION_FOLLOWING?-1:1})}function h(){var a;for(a=0;a<d.length;a+=1){var b=d[a],c=b.node.parentElement,e=c.nextElementSibling,h=e.nextElementSibling,m=c.parentElement,l=0,l=d[d.indexOf(b)-1],n=void 0,b=g.getZoomLevel();c.style.left=(f.getBoundingClientRect().left-m.getBoundingClientRect().left)/b+"px";c.style.width=f.getBoundingClientRect().width/ -b+"px";e.style.width=parseFloat(c.style.left)-30+"px";l&&(n=l.node.parentElement.getBoundingClientRect(),20>=(m.getBoundingClientRect().top-n.bottom)/b?c.style.top=Math.abs(m.getBoundingClientRect().top-n.bottom)/b+20+"px":c.style.top="0px");h.style.left=e.getBoundingClientRect().width/b+"px";var e=h.style,m=h.getBoundingClientRect().left/b,l=h.getBoundingClientRect().top/b,n=c.getBoundingClientRect().left/b,r=c.getBoundingClientRect().top/b,p=0,s=0,p=n-m,p=p*p,s=r-l,s=s*s,m=Math.sqrt(p+s);e.width= -m+"px";l=Math.asin((c.getBoundingClientRect().top-h.getBoundingClientRect().top)/(b*parseFloat(h.style.width)));h.style.transform="rotate("+l+"rad)";h.style.MozTransform="rotate("+l+"rad)";h.style.WebkitTransform="rotate("+l+"rad)";h.style.msTransform="rotate("+l+"rad)"}}var d=[],m=l.ownerDocument,c=new odf.OdfUtils,e=runtime.getWindow();runtime.assert(Boolean(e),"Expected to be run in an environment which has a global window, like a browser.");this.rerenderAnnotations=h;this.addAnnotation=function(a){r(!0); -d.push({node:a.node,end:a.end});n();var b=m.createElement("div"),c=m.createElement("div"),e=m.createElement("div"),f=m.createElement("div"),g=m.createElement("div"),l=a.node;b.className="annotationWrapper";l.parentNode.insertBefore(b,l);c.className="annotationNote";c.appendChild(l);g.className="annotationRemoveButton";c.appendChild(g);e.className="annotationConnector horizontal";f.className="annotationConnector angular";b.appendChild(c);b.appendChild(e);b.appendChild(f);a.end&&p(a);h()};this.forgetAnnotations= -function(){for(;d.length;){var a=d[0],b=d.indexOf(a),c=a.node,e=c.parentNode.parentNode;"div"===e.localName&&(e.parentNode.insertBefore(c,e),e.parentNode.removeChild(e));a=a.node.getAttributeNS(odf.Namespaces.officens,"name");a=m.querySelectorAll('span.annotationHighlight[annotation="'+a+'"]');e=c=void 0;for(c=0;c<a.length;c+=1){for(e=a.item(c);e.firstChild;)e.parentNode.insertBefore(e.firstChild,e);e.parentNode.removeChild(e)}-1!==b&&d.splice(b,1);0===d.length&&r(!1)}}}; -// Input 28 +odf.OdfUtils=function(){function k(a){return"image"===(a&&a.localName)&&a.namespaceURI===K}function h(a){return null!==a&&a.nodeType===Node.ELEMENT_NODE&&"frame"===a.localName&&a.namespaceURI===K&&"as-char"===a.getAttributeNS(O,"anchor-type")}function b(a){var c;(c="annotation"===(a&&a.localName)&&a.namespaceURI===odf.Namespaces.officens)||(c="div"===(a&&a.localName)&&"annotationWrapper"===a.className);return c}function p(a){return"a"===(a&&a.localName)&&a.namespaceURI===O}function d(a){var c=a&& +a.localName;return("p"===c||"h"===c)&&a.namespaceURI===O}function n(a){for(;a&&!d(a);)a=a.parentNode;return a}function g(a){return/^[ \t\r\n]+$/.test(a)}function q(a){if(null===a||a.nodeType!==Node.ELEMENT_NODE)return!1;var c=a.localName;return/^(span|p|h|a|meta)$/.test(c)&&a.namespaceURI===O||"span"===c&&"annotationHighlight"===a.className}function r(a){var c=a&&a.localName,b=!1;c&&(a=a.namespaceURI,a===O&&(b="s"===c||"tab"===c||"line-break"===c));return b}function l(a){return r(a)||h(a)||b(a)}function f(a){var c= +a&&a.localName,b=!1;c&&(a=a.namespaceURI,a===O&&(b="s"===c));return b}function c(a){for(;null!==a.firstChild&&q(a);)a=a.firstChild;return a}function a(a){for(;null!==a.lastChild&&q(a);)a=a.lastChild;return a}function m(c){for(;!d(c)&&null===c.previousSibling;)c=c.parentNode;return d(c)?null:a(c.previousSibling)}function e(a){for(;!d(a)&&null===a.nextSibling;)a=a.parentNode;return d(a)?null:c(a.nextSibling)}function t(a){for(var c=!1;a;)if(a.nodeType===Node.TEXT_NODE)if(0===a.length)a=m(a);else return!g(a.data.substr(a.length- +1,1));else l(a)?(c=!1===f(a),a=null):a=m(a);return c}function w(a){var b=!1,d;for(a=a&&c(a);a;){d=a.nodeType===Node.TEXT_NODE?a.length:0;if(0<d&&!g(a.data)){b=!0;break}if(l(a)){b=!0;break}a=e(a)}return b}function z(a,c){return g(a.data.substr(c))?!w(e(a)):!1}function x(a,c){var b=a.data,e;if(!g(b[c])||l(a.parentNode))return!1;0<c?g(b[c-1])||(e=!0):t(m(a))&&(e=!0);return!0===e?z(a,c)?!1:!0:!1}function v(a){return(a=/(-?[0-9]*[0-9][0-9]*(\.[0-9]*)?|0+\.[0-9]*[1-9][0-9]*|\.[0-9]*[1-9][0-9]*)((cm)|(mm)|(in)|(pt)|(pc)|(px)|(%))/.exec(a))? +{value:parseFloat(a[1]),unit:a[3]}:null}function u(a){return(a=v(a))&&(0>a.value||"%"===a.unit)?null:a}function s(a){return(a=v(a))&&"%"!==a.unit?null:a}function A(a){switch(a.namespaceURI){case odf.Namespaces.drawns:case odf.Namespaces.svgns:case odf.Namespaces.dr3dns:return!1;case odf.Namespaces.textns:switch(a.localName){case "note-body":case "ruby-text":return!1}break;case odf.Namespaces.officens:switch(a.localName){case "annotation":case "binary-data":case "event-listeners":return!1}break;default:switch(a.localName){case "cursor":case "editinfo":return!1}}return!0} +function J(a,c){for(;0<c.length&&!W.rangeContainsNode(a,c[0]);)c.shift();for(;0<c.length&&!W.rangeContainsNode(a,c[c.length-1]);)c.pop()}function G(a,c,e){var d;d=W.getNodesInRange(a,function(a){var c=NodeFilter.FILTER_REJECT;if(r(a.parentNode)||b(a))c=NodeFilter.FILTER_REJECT;else if(a.nodeType===Node.TEXT_NODE){if(e||Boolean(n(a)&&(!g(a.textContent)||x(a,0))))c=NodeFilter.FILTER_ACCEPT}else if(l(a))c=NodeFilter.FILTER_ACCEPT;else if(A(a)||q(a))c=NodeFilter.FILTER_SKIP;return c},NodeFilter.SHOW_ELEMENT| +NodeFilter.SHOW_TEXT);c||J(a,d);return d}function D(a,c,e){for(;a;){if(e(a)){c[0]!==a&&c.unshift(a);break}if(b(a))break;a=a.parentNode}}function F(a,c){var b=a;if(c<b.childNodes.length-1)b=b.childNodes[c+1];else{for(;!b.nextSibling;)b=b.parentNode;b=b.nextSibling}for(;b.firstChild;)b=b.firstChild;return b}var O=odf.Namespaces.textns,K=odf.Namespaces.drawns,Z=odf.Namespaces.xlinkns,Q=/^\s*$/,W=new core.DomUtils;this.isImage=k;this.isCharacterFrame=h;this.isInlineRoot=b;this.isTextSpan=function(a){return"span"=== +(a&&a.localName)&&a.namespaceURI===O};this.isHyperlink=p;this.getHyperlinkTarget=function(a){return a.getAttributeNS(Z,"href")};this.isParagraph=d;this.getParagraphElement=n;this.isWithinTrackedChanges=function(a,c){for(;a&&a!==c;){if(a.namespaceURI===O&&"tracked-changes"===a.localName)return!0;a=a.parentNode}return!1};this.isListItem=function(a){return"list-item"===(a&&a.localName)&&a.namespaceURI===O};this.isLineBreak=function(a){return"line-break"===(a&&a.localName)&&a.namespaceURI===O};this.isODFWhitespace= +g;this.isGroupingElement=q;this.isCharacterElement=r;this.isAnchoredAsCharacterElement=l;this.isSpaceElement=f;this.firstChild=c;this.lastChild=a;this.previousNode=m;this.nextNode=e;this.scanLeftForNonSpace=t;this.lookLeftForCharacter=function(a){var c,b=c=0;a.nodeType===Node.TEXT_NODE&&(b=a.length);0<b?(c=a.data,c=g(c.substr(b-1,1))?1===b?t(m(a))?2:0:g(c.substr(b-2,1))?0:2:1):l(a)&&(c=1);return c};this.lookRightForCharacter=function(a){var c=!1,b=0;a&&a.nodeType===Node.TEXT_NODE&&(b=a.length);0< +b?c=!g(a.data.substr(0,1)):l(a)&&(c=!0);return c};this.scanLeftForAnyCharacter=function(c){var b=!1,e;for(c=c&&a(c);c;){e=c.nodeType===Node.TEXT_NODE?c.length:0;if(0<e&&!g(c.data)){b=!0;break}if(l(c)){b=!0;break}c=m(c)}return b};this.scanRightForAnyCharacter=w;this.isTrailingWhitespace=z;this.isSignificantWhitespace=x;this.isDowngradableSpaceElement=function(a){return a.namespaceURI===O&&"s"===a.localName?t(m(a))&&w(e(a)):!1};this.getFirstNonWhitespaceChild=function(a){for(a=a&&a.firstChild;a&&a.nodeType=== +Node.TEXT_NODE&&Q.test(a.nodeValue);)a=a.nextSibling;return a};this.parseLength=v;this.parseNonNegativeLength=u;this.parseFoFontSize=function(a){var c;c=(c=v(a))&&(0>=c.value||"%"===c.unit)?null:c;return c||s(a)};this.parseFoLineHeight=function(a){return u(a)||s(a)};this.isTextContentContainingNode=A;this.getTextNodes=function(a,c){var b;b=W.getNodesInRange(a,function(a){var c=NodeFilter.FILTER_REJECT;a.nodeType===Node.TEXT_NODE?Boolean(n(a)&&(!g(a.textContent)||x(a,0)))&&(c=NodeFilter.FILTER_ACCEPT): +A(a)&&(c=NodeFilter.FILTER_SKIP);return c},NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT);c||J(a,b);return b};this.getTextElements=G;this.getParagraphElements=function(a){var c;c=W.getNodesInRange(a,function(a){var c=NodeFilter.FILTER_REJECT;if(d(a))c=NodeFilter.FILTER_ACCEPT;else if(A(a)||q(a))c=NodeFilter.FILTER_SKIP;return c},NodeFilter.SHOW_ELEMENT);D(a.startContainer,c,d);return c};this.getImageElements=function(a){var c;c=W.getNodesInRange(a,function(a){var c=NodeFilter.FILTER_SKIP;k(a)&&(c= +NodeFilter.FILTER_ACCEPT);return c},NodeFilter.SHOW_ELEMENT);D(a.startContainer,c,k);return c};this.getHyperlinkElements=function(a){var c=[],b=a.cloneRange();a.collapsed&&a.endContainer.nodeType===Node.ELEMENT_NODE&&(a=F(a.endContainer,a.endOffset),a.nodeType===Node.TEXT_NODE&&b.setEnd(a,1));G(b,!0,!1).forEach(function(a){for(a=a.parentNode;!d(a);){if(p(a)&&-1===c.indexOf(a)){c.push(a);break}a=a.parentNode}});b.detach();return c}}; +// Input 29 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -527,22 +659,49 @@ function(){for(;d.length;){var a=d[0],b=d.indexOf(a),c=a.node,e=c.parentNode.par @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.Cursor");runtime.loadClass("core.DomUtils");runtime.loadClass("core.PositionIterator");runtime.loadClass("core.PositionFilter");runtime.loadClass("core.LoopWatchDog");runtime.loadClass("odf.OdfUtils"); -gui.SelectionMover=function(g,l){function f(){w.setUnfilteredPosition(g.getNode(),0);return w}function p(a,b){var c,d=null;a&&0<a.length&&(c=b?a.item(a.length-1):a.item(0));c&&(d={top:c.top,left:b?c.right:c.left,bottom:c.bottom});return d}function r(a,b,c,d){var e=a.nodeType;c.setStart(a,b);c.collapse(!d);d=p(c.getClientRects(),!0===d);!d&&0<b&&(c.setStart(a,b-1),c.setEnd(a,b),d=p(c.getClientRects(),!0));d||(e===Node.ELEMENT_NODE&&0<b&&a.childNodes.length>=b?d=r(a,b-1,c,!0):a.nodeType===Node.TEXT_NODE&& -0<b?d=r(a,b-1,c,!0):a.previousSibling?d=r(a.previousSibling,a.previousSibling.nodeType===Node.TEXT_NODE?a.previousSibling.textContent.length:a.previousSibling.childNodes.length,c,!0):a.parentNode&&a.parentNode!==l?d=r(a.parentNode,0,c,!1):(c.selectNode(l),d=p(c.getClientRects(),!1)));runtime.assert(Boolean(d),"No visible rectangle found");return d}function n(a,b,c){var d=a,e=f(),h,k=l.ownerDocument.createRange(),q=g.getSelectedRange().cloneRange(),m;for(h=r(e.container(),e.unfilteredDomOffset(),k);0< -d&&c();)d-=1;b?(b=e.container(),e=e.unfilteredDomOffset(),-1===A.comparePoints(q.startContainer,q.startOffset,b,e)?(q.setStart(b,e),m=!1):q.setEnd(b,e)):(q.setStart(e.container(),e.unfilteredDomOffset()),q.collapse(!0));g.setSelectedRange(q,m);e=f();q=r(e.container(),e.unfilteredDomOffset(),k);if(q.top===h.top||void 0===x)x=q.left;runtime.clearTimeout(v);v=runtime.setTimeout(function(){x=void 0},2E3);k.detach();return a-d}function h(a){var b=f();return a.acceptPosition(b)===u&&(b.setUnfilteredPosition(g.getAnchorNode(), -0),a.acceptPosition(b)===u)?!0:!1}function d(a,b,c){for(var d=new core.LoopWatchDog(1E4),e=0,f=0,h=0<=b?1:-1,k=0<=b?a.nextPosition:a.previousPosition;0!==b&&k();)d.check(),f+=h,c.acceptPosition(a)===u&&(b-=h,e+=f,f=0);return e}function m(a,b,c){for(var d=f(),e=new core.LoopWatchDog(1E4),h=0,k=0;0<a&&d.nextPosition();)e.check(),c.acceptPosition(d)===u&&(h+=1,b.acceptPosition(d)===u&&(k+=h,h=0,a-=1));return k}function c(a,b,c){for(var d=f(),e=new core.LoopWatchDog(1E4),h=0,k=0;0<a&&d.previousPosition();)e.check(), -c.acceptPosition(d)===u&&(h+=1,b.acceptPosition(d)===u&&(k+=h,h=0,a-=1));return k}function e(a,b){var c=f();return d(c,a,b)}function a(a,b,c){var e=f(),h=t.getParagraphElement(e.getCurrentNode()),k=0;e.setUnfilteredPosition(a,b);c.acceptPosition(e)!==u&&(k=d(e,-1,c),0===k||h&&h!==t.getParagraphElement(e.getCurrentNode()))&&(e.setUnfilteredPosition(a,b),k=d(e,1,c));return k}function b(a,b){var c=f(),d=0,e=0,h=0>a?-1:1;for(a=Math.abs(a);0<a;){for(var k=b,q=h,g=c,m=g.container(),n=0,p=null,v=void 0, -t=10,w=void 0,A=0,F=void 0,C=void 0,Y=void 0,w=void 0,U=l.ownerDocument.createRange(),R=new core.LoopWatchDog(1E4),w=r(m,g.unfilteredDomOffset(),U),F=w.top,C=void 0===x?w.left:x,Y=F;!0===(0>q?g.previousPosition():g.nextPosition());)if(R.check(),k.acceptPosition(g)===u&&(n+=1,m=g.container(),w=r(m,g.unfilteredDomOffset(),U),w.top!==F)){if(w.top!==Y&&Y!==F)break;Y=w.top;w=Math.abs(C-w.left);if(null===p||w<t)p=m,v=g.unfilteredDomOffset(),t=w,A=n}null!==p?(g.setUnfilteredPosition(p,v),n=A):n=0;U.detach(); -d+=n;if(0===d)break;e+=d;a-=1}return e*h}function q(a,b){var c,d,e,h,k=f(),q=t.getParagraphElement(k.getCurrentNode()),g=0,m=l.ownerDocument.createRange();0>a?(c=k.previousPosition,d=-1):(c=k.nextPosition,d=1);for(e=r(k.container(),k.unfilteredDomOffset(),m);c.call(k);)if(b.acceptPosition(k)===u){if(t.getParagraphElement(k.getCurrentNode())!==q)break;h=r(k.container(),k.unfilteredDomOffset(),m);if(h.bottom!==e.bottom&&(e=h.top>=e.top&&h.bottom<e.bottom||h.top<=e.top&&h.bottom>e.bottom,!e))break;g+= -d;e=h}m.detach();return g}function k(a,b,c){runtime.assert(null!==a,"SelectionMover.countStepsToPosition called with element===null");var d=f(),e=d.container(),h=d.unfilteredDomOffset(),k=0,q=new core.LoopWatchDog(1E4);for(d.setUnfilteredPosition(a,b);c.acceptPosition(d)!==u&&d.previousPosition();)q.check();a=d.container();runtime.assert(Boolean(a),"SelectionMover.countStepsToPosition: positionIterator.container() returned null");b=d.unfilteredDomOffset();for(d.setUnfilteredPosition(e,h);c.acceptPosition(d)!== -u&&d.previousPosition();)q.check();e=A.comparePoints(a,b,d.container(),d.unfilteredDomOffset());if(0>e)for(;d.nextPosition()&&(q.check(),c.acceptPosition(d)===u&&(k+=1),d.container()!==a||d.unfilteredDomOffset()!==b););else if(0<e)for(;d.previousPosition()&&(q.check(),c.acceptPosition(d)!==u||(k-=1,d.container()!==a||d.unfilteredDomOffset()!==b)););return k}var t=new odf.OdfUtils,A=new core.DomUtils,w,x,v,u=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.movePointForward=function(a,b){return n(a, -b||!1,w.nextPosition)};this.movePointBackward=function(a,b){return n(a,b||!1,w.previousPosition)};this.getStepCounter=function(){return{countSteps:e,convertForwardStepsBetweenFilters:m,convertBackwardStepsBetweenFilters:c,countLinesSteps:b,countStepsToLineBoundary:q,countStepsToPosition:k,isPositionWalkable:h,countPositionsToNearestStep:a}};(function(){w=gui.SelectionMover.createPositionIterator(l);var a=l.ownerDocument.createRange();a.setStart(w.container(),w.unfilteredDomOffset());a.collapse(!0); -g.setSelectedRange(a)})()};gui.SelectionMover.createPositionIterator=function(g){var l=new function(){this.acceptNode=function(f){return f&&"urn:webodf:names:cursor"!==f.namespaceURI&&"urn:webodf:names:editinfo"!==f.namespaceURI?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}};return new core.PositionIterator(g,5,l,!1)};(function(){return gui.SelectionMover})(); -// Input 29 +gui.AnnotatableCanvas=function(){};gui.AnnotatableCanvas.prototype.refreshSize=function(){};gui.AnnotatableCanvas.prototype.getZoomLevel=function(){};gui.AnnotatableCanvas.prototype.getSizer=function(){}; +gui.AnnotationViewManager=function(k,h,b,p){function d(a){var c=a.annotationEndElement,b=l.createRange(),d=a.getAttributeNS(odf.Namespaces.officens,"name");c&&(b.setStart(a,a.childNodes.length),b.setEnd(c,0),a=f.getTextNodes(b,!1),a.forEach(function(a){var c=l.createElement("span");c.className="annotationHighlight";c.setAttribute("annotation",d);a.parentNode.insertBefore(c,a);c.appendChild(a)}));b.detach()}function n(a){var d=k.getSizer();a?(b.style.display="inline-block",d.style.paddingRight=c.getComputedStyle(b).width): +(b.style.display="none",d.style.paddingRight=0);k.refreshSize()}function g(){r.sort(function(a,c){return 0!==(a.compareDocumentPosition(c)&Node.DOCUMENT_POSITION_FOLLOWING)?-1:1})}function q(){var a;for(a=0;a<r.length;a+=1){var c=r[a],e=c.parentNode,d=e.nextElementSibling,f=d.nextElementSibling,g=e.parentNode,l=0,l=r[r.indexOf(c)-1],n=void 0,c=k.getZoomLevel();e.style.left=(b.getBoundingClientRect().left-g.getBoundingClientRect().left)/c+"px";e.style.width=b.getBoundingClientRect().width/c+"px";d.style.width= +parseFloat(e.style.left)-30+"px";l&&(n=l.parentNode.getBoundingClientRect(),20>=(g.getBoundingClientRect().top-n.bottom)/c?e.style.top=Math.abs(g.getBoundingClientRect().top-n.bottom)/c+20+"px":e.style.top="0px");f.style.left=d.getBoundingClientRect().width/c+"px";var d=f.style,g=f.getBoundingClientRect().left/c,l=f.getBoundingClientRect().top/c,n=e.getBoundingClientRect().left/c,h=e.getBoundingClientRect().top/c,q=0,A=0,q=n-g,q=q*q,A=h-l,A=A*A,g=Math.sqrt(q+A);d.width=g+"px";l=Math.asin((e.getBoundingClientRect().top- +f.getBoundingClientRect().top)/(c*parseFloat(f.style.width)));f.style.transform="rotate("+l+"rad)";f.style.MozTransform="rotate("+l+"rad)";f.style.WebkitTransform="rotate("+l+"rad)";f.style.msTransform="rotate("+l+"rad)"}}var r=[],l=h.ownerDocument,f=new odf.OdfUtils,c=runtime.getWindow();runtime.assert(Boolean(c),"Expected to be run in an environment which has a global window, like a browser.");this.rerenderAnnotations=q;this.getMinimumHeightForAnnotationPane=function(){return"none"!==b.style.display&& +0<r.length?(r[r.length-1].parentNode.getBoundingClientRect().bottom-b.getBoundingClientRect().top)/k.getZoomLevel()+"px":null};this.addAnnotation=function(a){n(!0);r.push(a);g();var c=l.createElement("div"),b=l.createElement("div"),f=l.createElement("div"),k=l.createElement("div"),h;c.className="annotationWrapper";a.parentNode.insertBefore(c,a);b.className="annotationNote";b.appendChild(a);p&&(h=l.createElement("div"),h.className="annotationRemoveButton",b.appendChild(h));f.className="annotationConnector horizontal"; +k.className="annotationConnector angular";c.appendChild(b);c.appendChild(f);c.appendChild(k);a.annotationEndElement&&d(a);q()};this.forgetAnnotations=function(){for(;r.length;){var a=r[0],c=r.indexOf(a),b=a.parentNode.parentNode;"div"===b.localName&&(b.parentNode.insertBefore(a,b),b.parentNode.removeChild(b));for(var a=a.getAttributeNS(odf.Namespaces.officens,"name"),a=l.querySelectorAll('span.annotationHighlight[annotation="'+a+'"]'),d=b=void 0,b=0;b<a.length;b+=1){for(d=a.item(b);d.firstChild;)d.parentNode.insertBefore(d.firstChild, +d);d.parentNode.removeChild(d)}-1!==c&&r.splice(c,1);0===r.length&&n(!1)}}}; +// Input 30 /* - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2014 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +(function(){function k(h,b){var p=this;this.getDistance=function(b){var n=p.x-b.x;b=p.y-b.y;return Math.sqrt(n*n+b*b)};this.getCenter=function(b){return new k((p.x+b.x)/2,(p.y+b.y)/2)};p.x=h;p.y=b}gui.ZoomHelper=function(){function h(c,b,e,d){c=d?"translate3d("+c+"px, "+b+"px, 0) scale3d("+e+", "+e+", 1)":"translate("+c+"px, "+b+"px) scale("+e+")";a.style.WebkitTransform=c;a.style.MozTransform=c;a.style.msTransform=c;a.style.OTransform=c;a.style.transform=c}function b(a){a?h(-m.x,-m.y,w,!0):(h(0, +0,w,!0),h(0,0,w,!1))}function p(a){if(v&&J){var c=v.style.overflow,b=v.classList.contains("customScrollbars");a&&b||!a&&!b||(a?(v.classList.add("customScrollbars"),v.style.overflow="hidden",runtime.requestAnimationFrame(function(){v.style.overflow=c})):v.classList.remove("customScrollbars"))}}function d(){h(-m.x,-m.y,w,!0);v.scrollLeft=0;v.scrollTop=0;p(!1)}function n(){h(0,0,w,!0);v.scrollLeft=m.x;v.scrollTop=m.y;p(!0)}function g(c){return new k(c.pageX-a.offsetLeft,c.pageY-a.offsetTop)}function q(c){e&& +(m.x-=c.x-e.x,m.y-=c.y-e.y,m=new k(Math.min(Math.max(m.x,a.offsetLeft),(a.offsetLeft+a.offsetWidth)*w-v.clientWidth),Math.min(Math.max(m.y,a.offsetTop),(a.offsetTop+a.offsetHeight)*w-v.clientHeight)));e=c}function r(a){var c=a.touches.length,b=0<c?g(a.touches[0]):null;a=1<c?g(a.touches[1]):null;b&&a?(t=b.getDistance(a),z=w,e=b.getCenter(a),d(),A=s.PINCH):b&&(e=b,A=s.SCROLL)}function l(c){var e=c.touches.length,f=0<e?g(c.touches[0]):null,e=1<e?g(c.touches[1]):null;if(f&&e)if(c.preventDefault(),A=== +s.SCROLL)A=s.PINCH,d(),t=f.getDistance(e);else{c=f.getCenter(e);f=f.getDistance(e)/t;q(c);var e=w,l=Math.min(x,a.offsetParent.clientWidth/a.offsetWidth);w=z*f;w=Math.min(Math.max(w,l),x);f=w/e;m.x+=(f-1)*(c.x+m.x);m.y+=(f-1)*(c.y+m.y);b(!0)}else f&&(A===s.PINCH?(A=s.SCROLL,n()):q(f))}function f(){A===s.PINCH&&(u.emit(gui.ZoomHelper.signalZoomChanged,w),n(),b(!1));A=s.NONE}function c(){v&&(v.removeEventListener("touchstart",r,!1),v.removeEventListener("touchmove",l,!1),v.removeEventListener("touchend", +f,!1))}var a,m,e,t,w,z,x=4,v,u=new core.EventNotifier([gui.ZoomHelper.signalZoomChanged]),s={NONE:0,SCROLL:1,PINCH:2},A=s.NONE,J=runtime.getWindow().hasOwnProperty("ontouchstart");this.subscribe=function(a,c){u.subscribe(a,c)};this.unsubscribe=function(a,c){u.unsubscribe(a,c)};this.getZoomLevel=function(){return w};this.setZoomLevel=function(c){a&&(w=c,b(!1),u.emit(gui.ZoomHelper.signalZoomChanged,w))};this.destroy=function(a){c();p(!1);a()};this.setZoomableElement=function(e){c();a=e;v=a.offsetParent; +b(!1);v&&(v.addEventListener("touchstart",r,!1),v.addEventListener("touchmove",l,!1),v.addEventListener("touchend",f,!1));p(!0)};z=w=1;m=new k(0,0)};gui.ZoomHelper.signalZoomChanged="zoomChanged"})(); +// Input 31 +/* + + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -577,8 +736,10 @@ g.setSelectedRange(a)})()};gui.SelectionMover.createPositionIterator=function(g) @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -odf.OdfNodeFilter=function(){this.acceptNode=function(g){return"http://www.w3.org/1999/xhtml"===g.namespaceURI?NodeFilter.FILTER_SKIP:g.namespaceURI&&g.namespaceURI.match(/^urn:webodf:/)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}; -// Input 30 +(function(){function k(h,d,n,g,q){var r,l=0,f;for(f in h)if(h.hasOwnProperty(f)){if(l===n){r=f;break}l+=1}r?d.getPartData(h[r].href,function(c,a){if(c)runtime.log(c);else if(a){var f="@font-face { font-family: '"+(h[r].family||r)+"'; src: url(data:application/x-font-ttf;charset=binary;base64,"+b.convertUTF8ArrayToBase64(a)+') format("truetype"); }';try{g.insertRule(f,g.cssRules.length)}catch(e){runtime.log("Problem inserting rule in CSS: "+runtime.toJson(e)+"\nRule: "+f)}}else runtime.log("missing font data for "+ +h[r].href);k(h,d,n+1,g,q)}):q&&q()}var h=xmldom.XPath,b=new core.Base64;odf.FontLoader=function(){this.loadFonts=function(b,d){for(var n=b.rootElement.fontFaceDecls;d.cssRules.length;)d.deleteRule(d.cssRules.length-1);if(n){var g={},q,r,l,f;if(n)for(n=h.getODFElementsWithXPath(n,"style:font-face[svg:font-face-src]",odf.Namespaces.lookupNamespaceURI),q=0;q<n.length;q+=1)r=n[q],l=r.getAttributeNS(odf.Namespaces.stylens,"name"),f=r.getAttributeNS(odf.Namespaces.svgns,"font-family"),r=h.getODFElementsWithXPath(r, +"svg:font-face-src/svg:font-face-uri",odf.Namespaces.lookupNamespaceURI),0<r.length&&(r=r[0].getAttributeNS(odf.Namespaces.xlinkns,"href"),g[l]={href:r,family:f});k(g,b,0,d)}}};return odf.FontLoader})(); +// Input 32 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -616,30 +777,20 @@ odf.OdfNodeFilter=function(){this.acceptNode=function(g){return"http://www.w3.or @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfUtils");runtime.loadClass("xmldom.XPath");runtime.loadClass("core.CSSUnits");odf.StyleTreeNode=function(g){this.derivedStyles={};this.element=g}; -odf.Style2CSS=function(){function g(a){var b,c,d,e={};if(!a)return e;for(a=a.firstElementChild;a;){if(c=a.namespaceURI!==k||"style"!==a.localName&&"default-style"!==a.localName?a.namespaceURI===w&&"list-style"===a.localName?"list":a.namespaceURI!==k||"page-layout"!==a.localName&&"default-page-layout"!==a.localName?void 0:"page":a.getAttributeNS(k,"family"))(b=a.getAttributeNS(k,"name"))||(b=""),e.hasOwnProperty(c)?d=e[c]:e[c]=d={},d[b]=a;a=a.nextElementSibling}return e}function l(a,b){if(a.hasOwnProperty(b))return a[b]; -var c,d=null;for(c in a)if(a.hasOwnProperty(c)&&(d=l(a[c].derivedStyles,b)))break;return d}function f(a,b,c){var d,e,h;if(!b.hasOwnProperty(a))return null;d=new odf.StyleTreeNode(b[a]);e=d.element.getAttributeNS(k,"parent-style-name");h=null;e&&(h=l(c,e)||f(e,b,c));h?h.derivedStyles[a]=d:c[a]=d;delete b[a];return d}function p(a,b){for(var c in a)a.hasOwnProperty(c)&&f(c,a,b)}function r(a,b,c){var d=[];c=c.derivedStyles;var e;var f=u[a],h;void 0===f?b=null:(h=b?"["+f+'|style-name="'+b+'"]':"","presentation"=== -f&&(f="draw",h=b?'[presentation|style-name="'+b+'"]':""),b=f+"|"+s[a].join(h+","+f+"|")+h);null!==b&&d.push(b);for(e in c)c.hasOwnProperty(e)&&(b=r(a,e,c[e]),d=d.concat(b));return d}function n(a,b,c){for(a=a&&a.firstElementChild;a&&(a.namespaceURI!==b||a.localName!==c);)a=a.nextElementSibling;return a}function h(a,b){var c="",d,e,f;for(d=0;d<b.length;d+=1)if(e=b[d],f=a.getAttributeNS(e[0],e[1])){f=f.trim();if(G.hasOwnProperty(e[1])){var h=f.indexOf(" "),k=void 0,q=void 0;-1!==h?(k=f.substring(0,h), -q=f.substring(h)):(k=f,q="");(k=O.parseLength(k))&&"pt"===k.unit&&0.75>k.value&&(f="0.75pt"+q)}e[2]&&(c+=e[2]+":"+f+";")}return c}function d(a){return(a=n(a,k,"text-properties"))?O.parseFoFontSize(a.getAttributeNS(b,"font-size")):null}function m(a,b,c,d){return b+b+c+c+d+d}function c(a,c,d,e){c='text|list[text|style-name="'+c+'"]';var f=d.getAttributeNS(w,"level");d=n(d,k,"list-level-properties");d=n(d,k,"list-level-label-alignment");var h,q;d&&(h=d.getAttributeNS(b,"text-indent"),q=d.getAttributeNS(b, -"margin-left"));h||(h="-0.6cm");d="-"===h.charAt(0)?h.substring(1):"-"+h;for(f=f&&parseInt(f,10);1<f;)c+=" > text|list-item > text|list",f-=1;if(q){f=c+" > text|list-item > *:not(text|list):first-child";f+="{";f=f+("margin-left:"+q+";")+"}";try{a.insertRule(f,a.cssRules.length)}catch(g){runtime.log("cannot load rule: "+f)}}e=c+" > text|list-item > *:not(text|list):first-child:before{"+e+";";e=e+"counter-increment:list;"+("margin-left:"+h+";");e+="width:"+d+";";e+="display:inline-block}";try{a.insertRule(e, -a.cssRules.length)}catch(m){runtime.log("cannot load rule: "+e)}}function e(f,g,l,p){if("list"===g)for(var s=p.element.firstChild,t,u;s;){if(s.namespaceURI===w)if(t=s,"list-level-style-number"===s.localName){var G=t;u=G.getAttributeNS(k,"num-format");var T=G.getAttributeNS(k,"num-suffix")||"",G=G.getAttributeNS(k,"num-prefix")||"",$={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},X="";G&&(X+=' "'+G+'"');X=$.hasOwnProperty(u)?X+(" counter(list, "+$[u]+")"):u?X+(' "'+u+ -'"'):X+" ''";u="content:"+X+' "'+T+'"';c(f,l,t,u)}else"list-level-style-image"===s.localName?(u="content: none;",c(f,l,t,u)):"list-level-style-bullet"===s.localName&&(u="content: '"+t.getAttributeNS(w,"bullet-char")+"';",c(f,l,t,u));s=s.nextSibling}else if("page"===g){if(u=p.element,G=T=l="",s=n(u,k,"page-layout-properties"))if(t=u.getAttributeNS(k,"name"),l+=h(s,ja),(T=n(s,k,"background-image"))&&(G=T.getAttributeNS(x,"href"))&&(l=l+("background-image: url('odfkit:"+G+"');")+h(T,y)),"presentation"=== -aa)for(u=(u=n(u.parentNode.parentElement,q,"master-styles"))&&u.firstElementChild;u;){if(u.namespaceURI===k&&"master-page"===u.localName&&u.getAttributeNS(k,"page-layout-name")===t){G=u.getAttributeNS(k,"name");T="draw|page[draw|master-page-name="+G+"] {"+l+"}";G="office|body, draw|page[draw|master-page-name="+G+"] {"+h(s,ka)+" }";try{f.insertRule(T,f.cssRules.length),f.insertRule(G,f.cssRules.length)}catch(da){throw da;}}u=u.nextElementSibling}else if("text"===aa){T="office|text {"+l+"}";G="office|body {width: "+ -s.getAttributeNS(b,"page-width")+";}";try{f.insertRule(T,f.cssRules.length),f.insertRule(G,f.cssRules.length)}catch(S){throw S;}}}else{l=r(g,l,p).join(",");s="";if(t=n(p.element,k,"text-properties")){G=t;u=X="";T=1;t=""+h(G,H);$=G.getAttributeNS(k,"text-underline-style");"solid"===$&&(X+=" underline");$=G.getAttributeNS(k,"text-line-through-style");"solid"===$&&(X+=" line-through");X.length&&(t+="text-decoration:"+X+";");if(X=G.getAttributeNS(k,"font-name")||G.getAttributeNS(b,"font-family"))$=Z[X], -t+="font-family: "+($||X)+";";$=G.parentElement;if(G=d($)){for(;$;){if(G=d($)){if("%"!==G.unit){u="font-size: "+G.value*T+G.unit+";";break}T*=G.value/100}G=$;X=$="";$=null;"default-style"===G.localName?$=null:($=G.getAttributeNS(k,"parent-style-name"),X=G.getAttributeNS(k,"family"),$=C.getODFElementsWithXPath(J,$?"//style:*[@style:name='"+$+"'][@style:family='"+X+"']":"//style:default-style[@style:family='"+X+"']",odf.Namespaces.lookupNamespaceURI)[0])}u||(u="font-size: "+parseFloat(F)*T+Y.getUnits(F)+ -";");t+=u}s+=t}if(t=n(p.element,k,"paragraph-properties"))u=t,t=""+h(u,B),(T=n(u,k,"background-image"))&&(G=T.getAttributeNS(x,"href"))&&(t=t+("background-image: url('odfkit:"+G+"');")+h(T,y)),(u=u.getAttributeNS(b,"line-height"))&&"normal"!==u&&(u=O.parseFoLineHeight(u),t="%"!==u.unit?t+("line-height: "+u.value+u.unit+";"):t+("line-height: "+u.value/100+";")),s+=t;if(t=n(p.element,k,"graphic-properties"))G=t,t=""+h(G,L),u=G.getAttributeNS(a,"opacity"),T=G.getAttributeNS(a,"fill"),G=G.getAttributeNS(a, -"fill-color"),"solid"===T||"hatch"===T?G&&"none"!==G?(u=isNaN(parseFloat(u))?1:parseFloat(u)/100,T=G.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,m),(G=(T=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(T))?{r:parseInt(T[1],16),g:parseInt(T[2],16),b:parseInt(T[3],16)}:null)&&(t+="background-color: rgba("+G.r+","+G.g+","+G.b+","+u+");")):t+="background: none;":"none"===T&&(t+="background: none;"),s+=t;if(t=n(p.element,k,"drawing-page-properties"))u=""+h(t,L),"true"===t.getAttributeNS(v,"background-visible")&& -(u+="background: none;"),s+=u;if(t=n(p.element,k,"table-cell-properties"))t=""+h(t,I),s+=t;if(t=n(p.element,k,"table-row-properties"))t=""+h(t,Q),s+=t;if(t=n(p.element,k,"table-column-properties"))t=""+h(t,W),s+=t;if(t=n(p.element,k,"table-properties"))u=t,t=""+h(u,z),u=u.getAttributeNS(A,"border-model"),"collapsing"===u?t+="border-collapse:collapse;":"separating"===u&&(t+="border-collapse:separate;"),s+=t;if(0!==s.length)try{f.insertRule(l+"{"+s+"}",f.cssRules.length)}catch(ga){throw ga;}}for(var E in p.derivedStyles)p.derivedStyles.hasOwnProperty(E)&& -e(f,g,E,p.derivedStyles[E])}var a=odf.Namespaces.drawns,b=odf.Namespaces.fons,q=odf.Namespaces.officens,k=odf.Namespaces.stylens,t=odf.Namespaces.svgns,A=odf.Namespaces.tablens,w=odf.Namespaces.textns,x=odf.Namespaces.xlinkns,v=odf.Namespaces.presentationns,u={graphic:"draw","drawing-page":"draw",paragraph:"text",presentation:"presentation",ruby:"text",section:"text",table:"table","table-cell":"table","table-column":"table","table-row":"table",text:"text",list:"text",page:"office"},s={graphic:"circle connected control custom-shape ellipse frame g line measure page page-thumbnail path polygon polyline rect regular-polygon".split(" "), -paragraph:"alphabetical-index-entry-template h illustration-index-entry-template index-source-style object-index-entry-template p table-index-entry-template table-of-content-entry-template user-index-entry-template".split(" "),presentation:"caption circle connector control custom-shape ellipse frame g line measure page-thumbnail path polygon polyline rect regular-polygon".split(" "),"drawing-page":"caption circle connector control page custom-shape ellipse frame g line measure page-thumbnail path polygon polyline rect regular-polygon".split(" "), -ruby:["ruby","ruby-text"],section:"alphabetical-index bibliography illustration-index index-title object-index section table-of-content table-index user-index".split(" "),table:["background","table"],"table-cell":"body covered-table-cell even-columns even-rows first-column first-row last-column last-row odd-columns odd-rows table-cell".split(" "),"table-column":["table-column"],"table-row":["table-row"],text:"a index-entry-chapter index-entry-link-end index-entry-link-start index-entry-page-number index-entry-span index-entry-tab-stop index-entry-text index-title-template linenumbering-configuration list-level-style-number list-level-style-bullet outline-level-style span".split(" "), -list:["list-item"]},H=[[b,"color","color"],[b,"background-color","background-color"],[b,"font-weight","font-weight"],[b,"font-style","font-style"]],y=[[k,"repeat","background-repeat"]],B=[[b,"background-color","background-color"],[b,"text-align","text-align"],[b,"text-indent","text-indent"],[b,"padding","padding"],[b,"padding-left","padding-left"],[b,"padding-right","padding-right"],[b,"padding-top","padding-top"],[b,"padding-bottom","padding-bottom"],[b,"border-left","border-left"],[b,"border-right", -"border-right"],[b,"border-top","border-top"],[b,"border-bottom","border-bottom"],[b,"margin","margin"],[b,"margin-left","margin-left"],[b,"margin-right","margin-right"],[b,"margin-top","margin-top"],[b,"margin-bottom","margin-bottom"],[b,"border","border"]],L=[[b,"background-color","background-color"],[b,"min-height","min-height"],[a,"stroke","border"],[t,"stroke-color","border-color"],[t,"stroke-width","border-width"],[b,"border","border"],[b,"border-left","border-left"],[b,"border-right","border-right"], -[b,"border-top","border-top"],[b,"border-bottom","border-bottom"]],I=[[b,"background-color","background-color"],[b,"border-left","border-left"],[b,"border-right","border-right"],[b,"border-top","border-top"],[b,"border-bottom","border-bottom"],[b,"border","border"]],W=[[k,"column-width","width"]],Q=[[k,"row-height","height"],[b,"keep-together",null]],z=[[k,"width","width"],[b,"margin-left","margin-left"],[b,"margin-right","margin-right"],[b,"margin-top","margin-top"],[b,"margin-bottom","margin-bottom"]], -ja=[[b,"background-color","background-color"],[b,"padding","padding"],[b,"padding-left","padding-left"],[b,"padding-right","padding-right"],[b,"padding-top","padding-top"],[b,"padding-bottom","padding-bottom"],[b,"border","border"],[b,"border-left","border-left"],[b,"border-right","border-right"],[b,"border-top","border-top"],[b,"border-bottom","border-bottom"],[b,"margin","margin"],[b,"margin-left","margin-left"],[b,"margin-right","margin-right"],[b,"margin-top","margin-top"],[b,"margin-bottom", -"margin-bottom"]],ka=[[b,"page-width","width"],[b,"page-height","height"]],G={border:!0,"border-left":!0,"border-right":!0,"border-top":!0,"border-bottom":!0,"stroke-width":!0},Z={},O=new odf.OdfUtils,aa,J,F,C=xmldom.XPath,Y=new core.CSSUnits;this.style2css=function(a,b,c,d,f){for(var h,k,q,m;b.cssRules.length;)b.deleteRule(b.cssRules.length-1);h=null;d&&(h=d.ownerDocument,J=d.parentNode);f&&(h=f.ownerDocument,J=f.parentNode);if(h)for(m in odf.Namespaces.forEachPrefix(function(a,c){k="@namespace "+ -a+" url("+c+");";try{b.insertRule(k,b.cssRules.length)}catch(d){}}),Z=c,aa=a,F=runtime.getWindow().getComputedStyle(document.body,null).getPropertyValue("font-size")||"12pt",a=g(d),d=g(f),f={},u)if(u.hasOwnProperty(m))for(q in c=f[m]={},p(a[m],c),p(d[m],c),c)c.hasOwnProperty(q)&&e(b,m,q,c[q])}}; -// Input 31 +odf.Formatting=function(){function k(a){return(a=s[a])?u.mergeObjects({},a):{}}function h(a,c,b){for(a=a&&a.firstElementChild;a&&(a.namespaceURI!==c||a.localName!==b);)a=a.nextElementSibling;return a}function b(){for(var a=c.rootElement.fontFaceDecls,b={},d,f,a=a&&a.firstElementChild;a;){if(d=a.getAttributeNS(e,"name"))if((f=a.getAttributeNS(m,"font-family"))||0<a.getElementsByTagNameNS(m,"font-face-uri").length)b[d]=f;a=a.nextElementSibling}return b}function p(a){for(var b=c.rootElement.styles.firstElementChild;b;){if(b.namespaceURI=== +e&&"default-style"===b.localName&&b.getAttributeNS(e,"family")===a)return b;b=b.nextElementSibling}return null}function d(a,b,d){var f,g,m;d=d||[c.rootElement.automaticStyles,c.rootElement.styles];for(m=0;m<d.length;m+=1)for(f=d[m],f=f.firstElementChild;f;){g=f.getAttributeNS(e,"name");if(f.namespaceURI===e&&"style"===f.localName&&f.getAttributeNS(e,"family")===b&&g===a||"list-style"===b&&f.namespaceURI===t&&"list-style"===f.localName&&g===a||"data"===b&&f.namespaceURI===w&&g===a)return f;f=f.nextElementSibling}return null} +function n(a){for(var c,b,d,f,g={},m=a.firstElementChild;m;){if(m.namespaceURI===e)for(d=g[m.nodeName]={},b=m.attributes,c=0;c<b.length;c+=1)f=b.item(c),d[f.name]=f.value;m=m.nextElementSibling}b=a.attributes;for(c=0;c<b.length;c+=1)f=b.item(c),g[f.name]=f.value;return g}function g(a,b){for(var f=c.rootElement.styles,g,m={},l=a.getAttributeNS(e,"family"),h=a;h;)g=n(h),m=u.mergeObjects(g,m),h=(g=h.getAttributeNS(e,"parent-style-name"))?d(g,l,[f]):null;if(h=p(l))g=n(h),m=u.mergeObjects(g,m);!1!==b&& +(g=k(l),m=u.mergeObjects(g,m));return m}function q(c,b){function e(a){Object.keys(a).forEach(function(c){Object.keys(a[c]).forEach(function(a){m+="|"+c+":"+a+"|"})})}for(var d=c.nodeType===Node.TEXT_NODE?c.parentNode:c,f,g=[],m="",l=!1;d;)!l&&x.isGroupingElement(d)&&(l=!0),(f=a.determineStylesForNode(d))&&g.push(f),d=d.parentNode;l&&(g.forEach(e),b&&(b[m]=g));return l?g:void 0}function r(a){var b={orderedStyles:[]};a.forEach(function(a){Object.keys(a).forEach(function(f){var m=Object.keys(a[f])[0], +l={name:m,family:f,displayName:void 0,isCommonStyle:!1},h;(h=d(m,f))?(f=g(h),b=u.mergeObjects(f,b),l.displayName=h.getAttributeNS(e,"display-name"),l.isCommonStyle=h.parentNode===c.rootElement.styles):runtime.log("No style element found for '"+m+"' of family '"+f+"'");b.orderedStyles.push(l)})});return b}function l(a,c){var b={},e=[];c||(c={});a.forEach(function(a){q(a,b)});Object.keys(b).forEach(function(a){c[a]||(c[a]=r(b[a]));e.push(c[a])});return e}function f(a,c){var b=x.parseLength(a),e=c;if(b)switch(b.unit){case "cm":e= +b.value;break;case "mm":e=0.1*b.value;break;case "in":e=2.54*b.value;break;case "pt":e=0.035277778*b.value;break;case "pc":case "px":case "em":break;default:runtime.log("Unit identifier: "+b.unit+" is not supported.")}return e}var c,a=new odf.StyleInfo,m=odf.Namespaces.svgns,e=odf.Namespaces.stylens,t=odf.Namespaces.textns,w=odf.Namespaces.numberns,z=odf.Namespaces.fons,x=new odf.OdfUtils,v=new core.DomUtils,u=new core.Utils,s={paragraph:{"style:paragraph-properties":{"fo:text-align":"left"}}};this.getSystemDefaultStyleAttributes= +k;this.setOdfContainer=function(a){c=a};this.getFontMap=b;this.getAvailableParagraphStyles=function(){for(var a=c.rootElement.styles,b,d,f=[],a=a&&a.firstElementChild;a;)"style"===a.localName&&a.namespaceURI===e&&(b=a.getAttributeNS(e,"family"),"paragraph"===b&&(b=a.getAttributeNS(e,"name"),d=a.getAttributeNS(e,"display-name")||b,b&&d&&f.push({name:b,displayName:d}))),a=a.nextElementSibling;return f};this.isStyleUsed=function(b){var e,d=c.rootElement;e=a.hasDerivedStyles(d,odf.Namespaces.lookupNamespaceURI, +b);b=(new a.UsedStyleList(d.styles)).uses(b)||(new a.UsedStyleList(d.automaticStyles)).uses(b)||(new a.UsedStyleList(d.body)).uses(b);return e||b};this.getDefaultStyleElement=p;this.getStyleElement=d;this.getStyleAttributes=n;this.getInheritedStyleAttributes=g;this.getFirstCommonParentStyleNameOrSelf=function(a){var b=c.rootElement.automaticStyles,f=c.rootElement.styles,g;for(g=d(a,"paragraph",[b]);g;)a=g.getAttributeNS(e,"parent-style-name"),g=d(a,"paragraph",[b]);return(g=d(a,"paragraph",[f]))? +a:null};this.hasParagraphStyle=function(a){return Boolean(d(a,"paragraph"))};this.getAppliedStyles=l;this.getAppliedStylesForElement=function(a,c){return l([a],c)[0]};this.updateStyle=function(a,d){var f,g;v.mapObjOntoNode(a,d,odf.Namespaces.lookupNamespaceURI);(f=d["style:text-properties"]&&d["style:text-properties"]["style:font-name"])&&!b().hasOwnProperty(f)&&(g=a.ownerDocument.createElementNS(e,"style:font-face"),g.setAttributeNS(e,"style:name",f),g.setAttributeNS(m,"svg:font-family",f),c.rootElement.fontFaceDecls.appendChild(g))}; +this.createDerivedStyleObject=function(a,b,e){var f=d(a,b);runtime.assert(Boolean(f),"No style element found for '"+a+"' of family '"+b+"'");a=f.parentNode===c.rootElement.styles?{"style:parent-style-name":a}:n(f);a["style:family"]=b;u.mergeObjects(a,e);return a};this.getDefaultTabStopDistance=function(){for(var a=p("paragraph"),a=a&&a.firstElementChild,c;a;)a.namespaceURI===e&&"paragraph-properties"===a.localName&&(c=a.getAttributeNS(e,"tab-stop-distance")),a=a.nextElementSibling;c||(c="1.25cm"); +return x.parseNonNegativeLength(c)};this.getContentSize=function(a,b){var g,m,l,n,k,q,p,r,t,s,w;a:{var u,x,R;g=d(a,b);runtime.assert("paragraph"===b||"table"===b,"styleFamily has to be either paragraph or table");if(g){u=g.getAttributeNS(e,"master-page-name")||"Standard";for(g=c.rootElement.masterStyles.lastElementChild;g&&g.getAttributeNS(e,"name")!==u;)g=g.previousElementSibling;u=g.getAttributeNS(e,"page-layout-name");x=v.getElementsByTagNameNS(c.rootElement.automaticStyles,e,"page-layout");for(R= +0;R<x.length;R+=1)if(g=x[R],g.getAttributeNS(e,"name")===u)break a}g=null}g||(g=h(c.rootElement.styles,e,"default-page-layout"));if(g=h(g,e,"page-layout-properties"))m=g.getAttributeNS(e,"print-orientation")||"portrait","portrait"===m?(m=21.001,l=29.7):(m=29.7,l=21.001),m=f(g.getAttributeNS(z,"page-width"),m),l=f(g.getAttributeNS(z,"page-height"),l),n=f(g.getAttributeNS(z,"margin"),null),null===n?(n=f(g.getAttributeNS(z,"margin-left"),2),k=f(g.getAttributeNS(z,"margin-right"),2),q=f(g.getAttributeNS(z, +"margin-top"),2),p=f(g.getAttributeNS(z,"margin-bottom"),2)):n=k=q=p=n,r=f(g.getAttributeNS(z,"padding"),null),null===r?(r=f(g.getAttributeNS(z,"padding-left"),0),t=f(g.getAttributeNS(z,"padding-right"),0),s=f(g.getAttributeNS(z,"padding-top"),0),w=f(g.getAttributeNS(z,"padding-bottom"),0)):r=t=s=w=r;return{width:m-n-k-r-t,height:l-q-p-s-w}}}; +// Input 33 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -677,39 +828,33 @@ a+" url("+c+");";try{b.insertRule(k,b.cssRules.length)}catch(d){}}),Z=c,aa=a,F=r @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.Namespaces"); -odf.StyleInfo=function(){function g(a,b){var c,d,e,f,h,k=0;if(c=B[a.localName])if(e=c[a.namespaceURI])k=e.length;for(c=0;c<k;c+=1)d=e[c],f=d.ns,h=d.localname,(d=a.getAttributeNS(f,h))&&a.setAttributeNS(f,H[f]+h,b+d);for(e=a.firstElementChild;e;)g(e,b),e=e.nextElementSibling}function l(a,b){var c,d,e,f,h,k=0;if(c=B[a.localName])if(e=c[a.namespaceURI])k=e.length;for(c=0;c<k;c+=1)if(d=e[c],f=d.ns,h=d.localname,d=a.getAttributeNS(f,h))d=d.replace(b,""),a.setAttributeNS(f,H[f]+h,d);for(e=a.firstElementChild;e;)l(e, -b),e=e.nextElementSibling}function f(a,b){var c,d,e,f,h,k=0;if(c=B[a.localName])if(e=c[a.namespaceURI])k=e.length;for(c=0;c<k;c+=1)if(f=e[c],d=f.ns,h=f.localname,d=a.getAttributeNS(d,h))b=b||{},f=f.keyname,b.hasOwnProperty(f)?b[f][d]=1:(h={},h[d]=1,b[f]=h);return b}function p(a,b){var c,d;f(a,b);for(c=a.firstChild;c;)c.nodeType===Node.ELEMENT_NODE&&(d=c,p(d,b)),c=c.nextSibling}function r(a,b,c){this.key=a;this.name=b;this.family=c;this.requires={}}function n(a,b,c){var d=a+'"'+b,e=c[d];e||(e=c[d]= -new r(d,a,b));return e}function h(a,b,c){var d,e,f,k,q,g=0;d=a.getAttributeNS(v,"name");k=a.getAttributeNS(v,"family");d&&k&&(b=n(d,k,c));if(b){if(d=B[a.localName])if(f=d[a.namespaceURI])g=f.length;for(d=0;d<g;d+=1)if(k=f[d],e=k.ns,q=k.localname,e=a.getAttributeNS(e,q))k=k.keyname,k=n(e,k,c),b.requires[k.key]=k}for(a=a.firstElementChild;a;)h(a,b,c),a=a.nextElementSibling;return c}function d(a,b){var c=b[a.family];c||(c=b[a.family]={});c[a.name]=1;Object.keys(a.requires).forEach(function(c){d(a.requires[c], -b)})}function m(a,b){var c=h(a,null,{});Object.keys(c).forEach(function(a){a=c[a];var e=b[a.family];e&&e.hasOwnProperty(a.name)&&d(a,b)})}function c(a,b){function d(b){(b=h.getAttributeNS(v,b))&&(a[b]=!0)}var e=["font-name","font-name-asian","font-name-complex"],f,h;for(f=b&&b.firstElementChild;f;)h=f,e.forEach(d),c(a,h),f=f.nextElementSibling}function e(a,b){function c(a){var d=h.getAttributeNS(v,a);d&&b.hasOwnProperty(d)&&h.setAttributeNS(v,"style:"+a,b[d])}var d=["font-name","font-name-asian", -"font-name-complex"],f,h;for(f=a&&a.firstElementChild;f;)h=f,d.forEach(c),e(h,b),f=f.nextElementSibling}var a=odf.Namespaces.chartns,b=odf.Namespaces.dbns,q=odf.Namespaces.dr3dns,k=odf.Namespaces.drawns,t=odf.Namespaces.formns,A=odf.Namespaces.numberns,w=odf.Namespaces.officens,x=odf.Namespaces.presentationns,v=odf.Namespaces.stylens,u=odf.Namespaces.tablens,s=odf.Namespaces.textns,H={"urn:oasis:names:tc:opendocument:xmlns:chart:1.0":"chart:","urn:oasis:names:tc:opendocument:xmlns:database:1.0":"db:", -"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0":"dr3d:","urn:oasis:names:tc:opendocument:xmlns:drawing:1.0":"draw:","urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0":"fo:","urn:oasis:names:tc:opendocument:xmlns:form:1.0":"form:","urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0":"number:","urn:oasis:names:tc:opendocument:xmlns:office:1.0":"office:","urn:oasis:names:tc:opendocument:xmlns:presentation:1.0":"presentation:","urn:oasis:names:tc:opendocument:xmlns:style:1.0":"style:","urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0":"svg:", -"urn:oasis:names:tc:opendocument:xmlns:table:1.0":"table:","urn:oasis:names:tc:opendocument:xmlns:text:1.0":"chart:","http://www.w3.org/XML/1998/namespace":"xml:"},y={text:[{ens:v,en:"tab-stop",ans:v,a:"leader-text-style"},{ens:v,en:"drop-cap",ans:v,a:"style-name"},{ens:s,en:"notes-configuration",ans:s,a:"citation-body-style-name"},{ens:s,en:"notes-configuration",ans:s,a:"citation-style-name"},{ens:s,en:"a",ans:s,a:"style-name"},{ens:s,en:"alphabetical-index",ans:s,a:"style-name"},{ens:s,en:"linenumbering-configuration", -ans:s,a:"style-name"},{ens:s,en:"list-level-style-number",ans:s,a:"style-name"},{ens:s,en:"ruby-text",ans:s,a:"style-name"},{ens:s,en:"span",ans:s,a:"style-name"},{ens:s,en:"a",ans:s,a:"visited-style-name"},{ens:v,en:"text-properties",ans:v,a:"text-line-through-text-style"},{ens:s,en:"alphabetical-index-source",ans:s,a:"main-entry-style-name"},{ens:s,en:"index-entry-bibliography",ans:s,a:"style-name"},{ens:s,en:"index-entry-chapter",ans:s,a:"style-name"},{ens:s,en:"index-entry-link-end",ans:s,a:"style-name"}, -{ens:s,en:"index-entry-link-start",ans:s,a:"style-name"},{ens:s,en:"index-entry-page-number",ans:s,a:"style-name"},{ens:s,en:"index-entry-span",ans:s,a:"style-name"},{ens:s,en:"index-entry-tab-stop",ans:s,a:"style-name"},{ens:s,en:"index-entry-text",ans:s,a:"style-name"},{ens:s,en:"index-title-template",ans:s,a:"style-name"},{ens:s,en:"list-level-style-bullet",ans:s,a:"style-name"},{ens:s,en:"outline-level-style",ans:s,a:"style-name"}],paragraph:[{ens:k,en:"caption",ans:k,a:"text-style-name"},{ens:k, -en:"circle",ans:k,a:"text-style-name"},{ens:k,en:"connector",ans:k,a:"text-style-name"},{ens:k,en:"control",ans:k,a:"text-style-name"},{ens:k,en:"custom-shape",ans:k,a:"text-style-name"},{ens:k,en:"ellipse",ans:k,a:"text-style-name"},{ens:k,en:"frame",ans:k,a:"text-style-name"},{ens:k,en:"line",ans:k,a:"text-style-name"},{ens:k,en:"measure",ans:k,a:"text-style-name"},{ens:k,en:"path",ans:k,a:"text-style-name"},{ens:k,en:"polygon",ans:k,a:"text-style-name"},{ens:k,en:"polyline",ans:k,a:"text-style-name"}, -{ens:k,en:"rect",ans:k,a:"text-style-name"},{ens:k,en:"regular-polygon",ans:k,a:"text-style-name"},{ens:w,en:"annotation",ans:k,a:"text-style-name"},{ens:t,en:"column",ans:t,a:"text-style-name"},{ens:v,en:"style",ans:v,a:"next-style-name"},{ens:u,en:"body",ans:u,a:"paragraph-style-name"},{ens:u,en:"even-columns",ans:u,a:"paragraph-style-name"},{ens:u,en:"even-rows",ans:u,a:"paragraph-style-name"},{ens:u,en:"first-column",ans:u,a:"paragraph-style-name"},{ens:u,en:"first-row",ans:u,a:"paragraph-style-name"}, -{ens:u,en:"last-column",ans:u,a:"paragraph-style-name"},{ens:u,en:"last-row",ans:u,a:"paragraph-style-name"},{ens:u,en:"odd-columns",ans:u,a:"paragraph-style-name"},{ens:u,en:"odd-rows",ans:u,a:"paragraph-style-name"},{ens:s,en:"notes-configuration",ans:s,a:"default-style-name"},{ens:s,en:"alphabetical-index-entry-template",ans:s,a:"style-name"},{ens:s,en:"bibliography-entry-template",ans:s,a:"style-name"},{ens:s,en:"h",ans:s,a:"style-name"},{ens:s,en:"illustration-index-entry-template",ans:s,a:"style-name"}, -{ens:s,en:"index-source-style",ans:s,a:"style-name"},{ens:s,en:"object-index-entry-template",ans:s,a:"style-name"},{ens:s,en:"p",ans:s,a:"style-name"},{ens:s,en:"table-index-entry-template",ans:s,a:"style-name"},{ens:s,en:"table-of-content-entry-template",ans:s,a:"style-name"},{ens:s,en:"table-index-entry-template",ans:s,a:"style-name"},{ens:s,en:"user-index-entry-template",ans:s,a:"style-name"},{ens:v,en:"page-layout-properties",ans:v,a:"register-truth-ref-style-name"}],chart:[{ens:a,en:"axis",ans:a, -a:"style-name"},{ens:a,en:"chart",ans:a,a:"style-name"},{ens:a,en:"data-label",ans:a,a:"style-name"},{ens:a,en:"data-point",ans:a,a:"style-name"},{ens:a,en:"equation",ans:a,a:"style-name"},{ens:a,en:"error-indicator",ans:a,a:"style-name"},{ens:a,en:"floor",ans:a,a:"style-name"},{ens:a,en:"footer",ans:a,a:"style-name"},{ens:a,en:"grid",ans:a,a:"style-name"},{ens:a,en:"legend",ans:a,a:"style-name"},{ens:a,en:"mean-value",ans:a,a:"style-name"},{ens:a,en:"plot-area",ans:a,a:"style-name"},{ens:a,en:"regression-curve", -ans:a,a:"style-name"},{ens:a,en:"series",ans:a,a:"style-name"},{ens:a,en:"stock-gain-marker",ans:a,a:"style-name"},{ens:a,en:"stock-loss-marker",ans:a,a:"style-name"},{ens:a,en:"stock-range-line",ans:a,a:"style-name"},{ens:a,en:"subtitle",ans:a,a:"style-name"},{ens:a,en:"title",ans:a,a:"style-name"},{ens:a,en:"wall",ans:a,a:"style-name"}],section:[{ens:s,en:"alphabetical-index",ans:s,a:"style-name"},{ens:s,en:"bibliography",ans:s,a:"style-name"},{ens:s,en:"illustration-index",ans:s,a:"style-name"}, -{ens:s,en:"index-title",ans:s,a:"style-name"},{ens:s,en:"object-index",ans:s,a:"style-name"},{ens:s,en:"section",ans:s,a:"style-name"},{ens:s,en:"table-of-content",ans:s,a:"style-name"},{ens:s,en:"table-index",ans:s,a:"style-name"},{ens:s,en:"user-index",ans:s,a:"style-name"}],ruby:[{ens:s,en:"ruby",ans:s,a:"style-name"}],table:[{ens:b,en:"query",ans:b,a:"style-name"},{ens:b,en:"table-representation",ans:b,a:"style-name"},{ens:u,en:"background",ans:u,a:"style-name"},{ens:u,en:"table",ans:u,a:"style-name"}], -"table-column":[{ens:b,en:"column",ans:b,a:"style-name"},{ens:u,en:"table-column",ans:u,a:"style-name"}],"table-row":[{ens:b,en:"query",ans:b,a:"default-row-style-name"},{ens:b,en:"table-representation",ans:b,a:"default-row-style-name"},{ens:u,en:"table-row",ans:u,a:"style-name"}],"table-cell":[{ens:b,en:"column",ans:b,a:"default-cell-style-name"},{ens:u,en:"table-column",ans:u,a:"default-cell-style-name"},{ens:u,en:"table-row",ans:u,a:"default-cell-style-name"},{ens:u,en:"body",ans:u,a:"style-name"}, -{ens:u,en:"covered-table-cell",ans:u,a:"style-name"},{ens:u,en:"even-columns",ans:u,a:"style-name"},{ens:u,en:"covered-table-cell",ans:u,a:"style-name"},{ens:u,en:"even-columns",ans:u,a:"style-name"},{ens:u,en:"even-rows",ans:u,a:"style-name"},{ens:u,en:"first-column",ans:u,a:"style-name"},{ens:u,en:"first-row",ans:u,a:"style-name"},{ens:u,en:"last-column",ans:u,a:"style-name"},{ens:u,en:"last-row",ans:u,a:"style-name"},{ens:u,en:"odd-columns",ans:u,a:"style-name"},{ens:u,en:"odd-rows",ans:u,a:"style-name"}, -{ens:u,en:"table-cell",ans:u,a:"style-name"}],graphic:[{ens:q,en:"cube",ans:k,a:"style-name"},{ens:q,en:"extrude",ans:k,a:"style-name"},{ens:q,en:"rotate",ans:k,a:"style-name"},{ens:q,en:"scene",ans:k,a:"style-name"},{ens:q,en:"sphere",ans:k,a:"style-name"},{ens:k,en:"caption",ans:k,a:"style-name"},{ens:k,en:"circle",ans:k,a:"style-name"},{ens:k,en:"connector",ans:k,a:"style-name"},{ens:k,en:"control",ans:k,a:"style-name"},{ens:k,en:"custom-shape",ans:k,a:"style-name"},{ens:k,en:"ellipse",ans:k,a:"style-name"}, -{ens:k,en:"frame",ans:k,a:"style-name"},{ens:k,en:"g",ans:k,a:"style-name"},{ens:k,en:"line",ans:k,a:"style-name"},{ens:k,en:"measure",ans:k,a:"style-name"},{ens:k,en:"page-thumbnail",ans:k,a:"style-name"},{ens:k,en:"path",ans:k,a:"style-name"},{ens:k,en:"polygon",ans:k,a:"style-name"},{ens:k,en:"polyline",ans:k,a:"style-name"},{ens:k,en:"rect",ans:k,a:"style-name"},{ens:k,en:"regular-polygon",ans:k,a:"style-name"},{ens:w,en:"annotation",ans:k,a:"style-name"}],presentation:[{ens:q,en:"cube",ans:x, -a:"style-name"},{ens:q,en:"extrude",ans:x,a:"style-name"},{ens:q,en:"rotate",ans:x,a:"style-name"},{ens:q,en:"scene",ans:x,a:"style-name"},{ens:q,en:"sphere",ans:x,a:"style-name"},{ens:k,en:"caption",ans:x,a:"style-name"},{ens:k,en:"circle",ans:x,a:"style-name"},{ens:k,en:"connector",ans:x,a:"style-name"},{ens:k,en:"control",ans:x,a:"style-name"},{ens:k,en:"custom-shape",ans:x,a:"style-name"},{ens:k,en:"ellipse",ans:x,a:"style-name"},{ens:k,en:"frame",ans:x,a:"style-name"},{ens:k,en:"g",ans:x,a:"style-name"}, -{ens:k,en:"line",ans:x,a:"style-name"},{ens:k,en:"measure",ans:x,a:"style-name"},{ens:k,en:"page-thumbnail",ans:x,a:"style-name"},{ens:k,en:"path",ans:x,a:"style-name"},{ens:k,en:"polygon",ans:x,a:"style-name"},{ens:k,en:"polyline",ans:x,a:"style-name"},{ens:k,en:"rect",ans:x,a:"style-name"},{ens:k,en:"regular-polygon",ans:x,a:"style-name"},{ens:w,en:"annotation",ans:x,a:"style-name"}],"drawing-page":[{ens:k,en:"page",ans:k,a:"style-name"},{ens:x,en:"notes",ans:k,a:"style-name"},{ens:v,en:"handout-master", -ans:k,a:"style-name"},{ens:v,en:"master-page",ans:k,a:"style-name"}],"list-style":[{ens:s,en:"list",ans:s,a:"style-name"},{ens:s,en:"numbered-paragraph",ans:s,a:"style-name"},{ens:s,en:"list-item",ans:s,a:"style-override"},{ens:v,en:"style",ans:v,a:"list-style-name"}],data:[{ens:v,en:"style",ans:v,a:"data-style-name"},{ens:v,en:"style",ans:v,a:"percentage-data-style-name"},{ens:x,en:"date-time-decl",ans:v,a:"data-style-name"},{ens:s,en:"creation-date",ans:v,a:"data-style-name"},{ens:s,en:"creation-time", -ans:v,a:"data-style-name"},{ens:s,en:"database-display",ans:v,a:"data-style-name"},{ens:s,en:"date",ans:v,a:"data-style-name"},{ens:s,en:"editing-duration",ans:v,a:"data-style-name"},{ens:s,en:"expression",ans:v,a:"data-style-name"},{ens:s,en:"meta-field",ans:v,a:"data-style-name"},{ens:s,en:"modification-date",ans:v,a:"data-style-name"},{ens:s,en:"modification-time",ans:v,a:"data-style-name"},{ens:s,en:"print-date",ans:v,a:"data-style-name"},{ens:s,en:"print-time",ans:v,a:"data-style-name"},{ens:s, -en:"table-formula",ans:v,a:"data-style-name"},{ens:s,en:"time",ans:v,a:"data-style-name"},{ens:s,en:"user-defined",ans:v,a:"data-style-name"},{ens:s,en:"user-field-get",ans:v,a:"data-style-name"},{ens:s,en:"user-field-input",ans:v,a:"data-style-name"},{ens:s,en:"variable-get",ans:v,a:"data-style-name"},{ens:s,en:"variable-input",ans:v,a:"data-style-name"},{ens:s,en:"variable-set",ans:v,a:"data-style-name"}],"page-layout":[{ens:x,en:"notes",ans:v,a:"page-layout-name"},{ens:v,en:"handout-master",ans:v, -a:"page-layout-name"},{ens:v,en:"master-page",ans:v,a:"page-layout-name"}]},B,L=xmldom.XPath;this.collectUsedFontFaces=c;this.changeFontFaceNames=e;this.UsedStyleList=function(a,b){var c={};this.uses=function(a){var b=a.localName,d=a.getAttributeNS(k,"name")||a.getAttributeNS(v,"name");a="style"===b?a.getAttributeNS(v,"family"):a.namespaceURI===A?"data":b;return(a=c[a])?0<a[d]:!1};p(a,c);b&&m(b,c)};this.hasDerivedStyles=function(a,b,c){var d=c.getAttributeNS(v,"name");c=c.getAttributeNS(v,"family"); -return L.getODFElementsWithXPath(a,"//style:*[@style:parent-style-name='"+d+"'][@style:family='"+c+"']",b).length?!0:!1};this.prefixStyleNames=function(a,b,c){var d;if(a){for(d=a.firstChild;d;){if(d.nodeType===Node.ELEMENT_NODE){var e=d,f=b,h=e.getAttributeNS(k,"name"),q=void 0;h?q=k:(h=e.getAttributeNS(v,"name"))&&(q=v);q&&e.setAttributeNS(q,H[q]+"name",f+h)}d=d.nextSibling}g(a,b);c&&g(c,b)}};this.removePrefixFromStyleNames=function(a,b,c){var d=RegExp("^"+b);if(a){for(b=a.firstChild;b;){if(b.nodeType=== -Node.ELEMENT_NODE){var e=b,f=d,h=e.getAttributeNS(k,"name"),q=void 0;h?q=k:(h=e.getAttributeNS(v,"name"))&&(q=v);q&&(h=h.replace(f,""),e.setAttributeNS(q,H[q]+"name",h))}b=b.nextSibling}l(a,d);c&&l(c,d)}};this.determineStylesForNode=f;B=function(){var a,b,c,d,e,f={},h,k,q,g;for(c in y)if(y.hasOwnProperty(c))for(d=y[c],b=d.length,a=0;a<b;a+=1)e=d[a],q=e.en,g=e.ens,f.hasOwnProperty(q)?h=f[q]:f[q]=h={},h.hasOwnProperty(g)?k=h[g]:h[g]=k=[],k.push({ns:e.ans,localname:e.a,keyname:c});return f}()}; -// Input 32 +odf.StyleTreeNode=function(k){this.derivedStyles={};this.element=k}; +odf.Style2CSS=function(){function k(a){var c,b,d,f={};if(!a)return f;for(a=a.firstElementChild;a;){if(b=a.namespaceURI!==e||"style"!==a.localName&&"default-style"!==a.localName?a.namespaceURI===z&&"list-style"===a.localName?"list":a.namespaceURI!==e||"page-layout"!==a.localName&&"default-page-layout"!==a.localName?void 0:"page":a.getAttributeNS(e,"family"))(c=a.getAttributeNS(e,"name"))||(c=""),f.hasOwnProperty(b)?d=f[b]:f[b]=d={},d[c]=a;a=a.nextElementSibling}return f}function h(a,c){if(a.hasOwnProperty(c))return a[c]; +var b,e=null;for(b in a)if(a.hasOwnProperty(b)&&(e=h(a[b].derivedStyles,c)))break;return e}function b(a,c,d){var f,g,m;if(!c.hasOwnProperty(a))return null;f=new odf.StyleTreeNode(c[a]);g=f.element.getAttributeNS(e,"parent-style-name");m=null;g&&(m=h(d,g)||b(g,c,d));m?m.derivedStyles[a]=f:d[a]=f;delete c[a];return f}function p(a,c){for(var e in a)a.hasOwnProperty(e)&&b(e,a,c)}function d(a,c,b){var e=[];b=b.derivedStyles;var f;var g=u[a],m;void 0===g?c=null:(m=c?"["+g+'|style-name="'+c+'"]':"","presentation"=== +g&&(g="draw",m=c?'[presentation|style-name="'+c+'"]':""),c=g+"|"+s[a].join(m+","+g+"|")+m);null!==c&&e.push(c);for(f in b)b.hasOwnProperty(f)&&(c=d(a,f,b[f]),e=e.concat(c));return e}function n(a,c,b){for(a=a&&a.firstElementChild;a&&(a.namespaceURI!==c||a.localName!==b);)a=a.nextElementSibling;return a}function g(a,c){var b="",e,d,f;for(e=0;e<c.length;e+=1)if(d=c[e],f=a.getAttributeNS(d[0],d[1])){f=f.trim();if(H.hasOwnProperty(d[1])){var g=f.indexOf(" "),m=void 0,l=void 0;-1!==g?(m=f.substring(0,g), +l=f.substring(g)):(m=f,l="");(m=y.parseLength(m))&&"pt"===m.unit&&0.75>m.value&&(f="0.75pt"+l)}d[2]&&(b+=d[2]+":"+f+";")}return b}function q(c){return(c=n(c,e,"text-properties"))?y.parseFoFontSize(c.getAttributeNS(a,"font-size")):null}function r(a,c,b,e){return c+c+b+b+e+e}function l(c,b,d,f){b='text|list[text|style-name="'+b+'"]';var g=d.getAttributeNS(z,"level");d=n(d,e,"list-level-properties");d=n(d,e,"list-level-label-alignment");var m,l;d&&(m=d.getAttributeNS(a,"text-indent"),l=d.getAttributeNS(a, +"margin-left"));m||(m="-0.6cm");d="-"===m.charAt(0)?m.substring(1):"-"+m;for(g=g&&parseInt(g,10);1<g;)b+=" > text|list-item > text|list",g-=1;if(l){g=b+" > text|list-item > *:not(text|list):first-child";g+="{";g=g+("margin-left:"+l+";")+"}";try{c.insertRule(g,c.cssRules.length)}catch(h){runtime.log("cannot load rule: "+g)}}f=b+" > text|list-item > *:not(text|list):first-child:before{"+f+";";f=f+"counter-increment:list;"+("margin-left:"+m+";");f+="width:"+d+";";f+="display:inline-block}";try{c.insertRule(f, +c.cssRules.length)}catch(k){runtime.log("cannot load rule: "+f)}}function f(b,h,k,p){if("list"===h)for(var t=p.element.firstChild,s,u;t;){if(t.namespaceURI===z)if(s=t,"list-level-style-number"===t.localName){var H=s;u=H.getAttributeNS(e,"num-format");var P=H.getAttributeNS(e,"num-suffix")||"",H=H.getAttributeNS(e,"num-prefix")||"",X={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},V="";H&&(V+=' "'+H+'"');V=X.hasOwnProperty(u)?V+(" counter(list, "+X[u]+")"):u?V+(' "'+u+ +'"'):V+" ''";u="content:"+V+' "'+P+'"';l(b,k,s,u)}else"list-level-style-image"===t.localName?(u="content: none;",l(b,k,s,u)):"list-level-style-bullet"===t.localName&&(u="content: '"+s.getAttributeNS(z,"bullet-char")+"';",l(b,k,s,u));t=t.nextSibling}else if("page"===h){if(u=p.element,H=P=k="",t=n(u,e,"page-layout-properties"))if(s=u.getAttributeNS(e,"name"),k+=g(t,Q),(P=n(t,e,"background-image"))&&(H=P.getAttributeNS(x,"href"))&&(k=k+("background-image: url('odfkit:"+H+"');")+g(P,J)),"presentation"=== +aa)for(u=(u=n(u.parentNode.parentNode,m,"master-styles"))&&u.firstElementChild;u;){if(u.namespaceURI===e&&"master-page"===u.localName&&u.getAttributeNS(e,"page-layout-name")===s){H=u.getAttributeNS(e,"name");P="draw|page[draw|master-page-name="+H+"] {"+k+"}";H="office|body, draw|page[draw|master-page-name="+H+"] {"+g(t,W)+" }";try{b.insertRule(P,b.cssRules.length),b.insertRule(H,b.cssRules.length)}catch(ga){throw ga;}}u=u.nextElementSibling}else if("text"===aa){P="office|text {"+k+"}";H="office|body {width: "+ +t.getAttributeNS(a,"page-width")+";}";try{b.insertRule(P,b.cssRules.length),b.insertRule(H,b.cssRules.length)}catch(ha){throw ha;}}}else{k=d(h,k,p).join(",");t="";if(s=n(p.element,e,"text-properties")){H=s;u=V="";P=1;s=""+g(H,A);X=H.getAttributeNS(e,"text-underline-style");"solid"===X&&(V+=" underline");X=H.getAttributeNS(e,"text-line-through-style");"solid"===X&&(V+=" line-through");V.length&&(s+="text-decoration:"+V+";");if(V=H.getAttributeNS(e,"font-name")||H.getAttributeNS(a,"font-family"))X= +T[V],s+="font-family: "+(X||V)+";";X=H.parentNode;if(H=q(X)){for(;X;){if(H=q(X)){if("%"!==H.unit){u="font-size: "+H.value*P+H.unit+";";break}P*=H.value/100}H=X;V=X="";X=null;"default-style"===H.localName?X=null:(X=H.getAttributeNS(e,"parent-style-name"),V=H.getAttributeNS(e,"family"),X=I.getODFElementsWithXPath(N,X?"//style:*[@style:name='"+X+"'][@style:family='"+V+"']":"//style:default-style[@style:family='"+V+"']",odf.Namespaces.lookupNamespaceURI)[0])}u||(u="font-size: "+parseFloat(R)*P+ca.getUnits(R)+ +";");s+=u}t+=s}if(s=n(p.element,e,"paragraph-properties"))u=s,s=""+g(u,G),(P=n(u,e,"background-image"))&&(H=P.getAttributeNS(x,"href"))&&(s=s+("background-image: url('odfkit:"+H+"');")+g(P,J)),(u=u.getAttributeNS(a,"line-height"))&&"normal"!==u&&(u=y.parseFoLineHeight(u),s="%"!==u.unit?s+("line-height: "+u.value+u.unit+";"):s+("line-height: "+u.value/100+";")),t+=s;if(s=n(p.element,e,"graphic-properties"))H=s,s=""+g(H,D),u=H.getAttributeNS(c,"opacity"),P=H.getAttributeNS(c,"fill"),H=H.getAttributeNS(c, +"fill-color"),"solid"===P||"hatch"===P?H&&"none"!==H?(u=isNaN(parseFloat(u))?1:parseFloat(u)/100,P=H.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,r),(H=(P=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(P))?{r:parseInt(P[1],16),g:parseInt(P[2],16),b:parseInt(P[3],16)}:null)&&(s+="background-color: rgba("+H.r+","+H.g+","+H.b+","+u+");")):s+="background: none;":"none"===P&&(s+="background: none;"),t+=s;if(s=n(p.element,e,"drawing-page-properties"))u=""+g(s,D),"true"===s.getAttributeNS(v,"background-visible")&& +(u+="background: none;"),t+=u;if(s=n(p.element,e,"table-cell-properties"))s=""+g(s,F),t+=s;if(s=n(p.element,e,"table-row-properties"))s=""+g(s,K),t+=s;if(s=n(p.element,e,"table-column-properties"))s=""+g(s,O),t+=s;if(s=n(p.element,e,"table-properties"))u=s,s=""+g(u,Z),u=u.getAttributeNS(w,"border-model"),"collapsing"===u?s+="border-collapse:collapse;":"separating"===u&&(s+="border-collapse:separate;"),t+=s;if(0!==t.length)try{b.insertRule(k+"{"+t+"}",b.cssRules.length)}catch($){throw $;}}for(var ea in p.derivedStyles)p.derivedStyles.hasOwnProperty(ea)&& +f(b,h,ea,p.derivedStyles[ea])}var c=odf.Namespaces.drawns,a=odf.Namespaces.fons,m=odf.Namespaces.officens,e=odf.Namespaces.stylens,t=odf.Namespaces.svgns,w=odf.Namespaces.tablens,z=odf.Namespaces.textns,x=odf.Namespaces.xlinkns,v=odf.Namespaces.presentationns,u={graphic:"draw","drawing-page":"draw",paragraph:"text",presentation:"presentation",ruby:"text",section:"text",table:"table","table-cell":"table","table-column":"table","table-row":"table",text:"text",list:"text",page:"office"},s={graphic:"circle connected control custom-shape ellipse frame g line measure page page-thumbnail path polygon polyline rect regular-polygon".split(" "), +paragraph:"alphabetical-index-entry-template h illustration-index-entry-template index-source-style object-index-entry-template p table-index-entry-template table-of-content-entry-template user-index-entry-template".split(" "),presentation:"caption circle connector control custom-shape ellipse frame g line measure page-thumbnail path polygon polyline rect regular-polygon".split(" "),"drawing-page":"caption circle connector control page custom-shape ellipse frame g line measure page-thumbnail path polygon polyline rect regular-polygon".split(" "), +ruby:["ruby","ruby-text"],section:"alphabetical-index bibliography illustration-index index-title object-index section table-of-content table-index user-index".split(" "),table:["background","table"],"table-cell":"body covered-table-cell even-columns even-rows first-column first-row last-column last-row odd-columns odd-rows table-cell".split(" "),"table-column":["table-column"],"table-row":["table-row"],text:"a index-entry-chapter index-entry-link-end index-entry-link-start index-entry-page-number index-entry-span index-entry-tab-stop index-entry-text index-title-template linenumbering-configuration list-level-style-number list-level-style-bullet outline-level-style span".split(" "), +list:["list-item"]},A=[[a,"color","color"],[a,"background-color","background-color"],[a,"font-weight","font-weight"],[a,"font-style","font-style"]],J=[[e,"repeat","background-repeat"]],G=[[a,"background-color","background-color"],[a,"text-align","text-align"],[a,"text-indent","text-indent"],[a,"padding","padding"],[a,"padding-left","padding-left"],[a,"padding-right","padding-right"],[a,"padding-top","padding-top"],[a,"padding-bottom","padding-bottom"],[a,"border-left","border-left"],[a,"border-right", +"border-right"],[a,"border-top","border-top"],[a,"border-bottom","border-bottom"],[a,"margin","margin"],[a,"margin-left","margin-left"],[a,"margin-right","margin-right"],[a,"margin-top","margin-top"],[a,"margin-bottom","margin-bottom"],[a,"border","border"]],D=[[a,"background-color","background-color"],[a,"min-height","min-height"],[c,"stroke","border"],[t,"stroke-color","border-color"],[t,"stroke-width","border-width"],[a,"border","border"],[a,"border-left","border-left"],[a,"border-right","border-right"], +[a,"border-top","border-top"],[a,"border-bottom","border-bottom"]],F=[[a,"background-color","background-color"],[a,"border-left","border-left"],[a,"border-right","border-right"],[a,"border-top","border-top"],[a,"border-bottom","border-bottom"],[a,"border","border"]],O=[[e,"column-width","width"]],K=[[e,"row-height","height"],[a,"keep-together",null]],Z=[[e,"width","width"],[a,"margin-left","margin-left"],[a,"margin-right","margin-right"],[a,"margin-top","margin-top"],[a,"margin-bottom","margin-bottom"]], +Q=[[a,"background-color","background-color"],[a,"padding","padding"],[a,"padding-left","padding-left"],[a,"padding-right","padding-right"],[a,"padding-top","padding-top"],[a,"padding-bottom","padding-bottom"],[a,"border","border"],[a,"border-left","border-left"],[a,"border-right","border-right"],[a,"border-top","border-top"],[a,"border-bottom","border-bottom"],[a,"margin","margin"],[a,"margin-left","margin-left"],[a,"margin-right","margin-right"],[a,"margin-top","margin-top"],[a,"margin-bottom","margin-bottom"]], +W=[[a,"page-width","width"],[a,"page-height","height"]],H={border:!0,"border-left":!0,"border-right":!0,"border-top":!0,"border-bottom":!0,"stroke-width":!0},T={},y=new odf.OdfUtils,aa,N,R,I=xmldom.XPath,ca=new core.CSSUnits;this.style2css=function(a,c,b,e,d){for(var g,m,l,h;c.cssRules.length;)c.deleteRule(c.cssRules.length-1);g=null;e&&(g=e.ownerDocument,N=e.parentNode);d&&(g=d.ownerDocument,N=d.parentNode);if(g)for(h in odf.Namespaces.forEachPrefix(function(a,b){m="@namespace "+a+" url("+b+");"; +try{c.insertRule(m,c.cssRules.length)}catch(e){}}),T=b,aa=a,R=runtime.getWindow().getComputedStyle(document.body,null).getPropertyValue("font-size")||"12pt",a=k(e),e=k(d),d={},u)if(u.hasOwnProperty(h))for(l in b=d[h]={},p(a[h],b),p(e[h],b),b)b.hasOwnProperty(l)&&f(c,h,l,b[l])}}; +// Input 34 /* - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -744,10 +889,8 @@ Node.ELEMENT_NODE){var e=b,f=d,h=e.getAttributeNS(k,"name"),q=void 0;h?q=k:(h=e. @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.OdfUtils"); -odf.TextSerializer=function(){function g(p){var r="",n=l.filter?l.filter.acceptNode(p):NodeFilter.FILTER_ACCEPT,h=p.nodeType,d;if(n===NodeFilter.FILTER_ACCEPT||n===NodeFilter.FILTER_SKIP)for(d=p.firstChild;d;)r+=g(d),d=d.nextSibling;n===NodeFilter.FILTER_ACCEPT&&(h===Node.ELEMENT_NODE&&f.isParagraph(p)?r+="\n":h===Node.TEXT_NODE&&p.textContent&&(r+=p.textContent));return r}var l=this,f=new odf.OdfUtils;this.filter=null;this.writeToString=function(f){if(!f)return"";f=g(f);"\n"===f[f.length-1]&&(f= -f.substr(0,f.length-1));return f}}; -// Input 33 +ops.Canvas=function(){};ops.Canvas.prototype.getZoomLevel=function(){};ops.Canvas.prototype.getElement=function(){}; +// Input 35 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -785,22 +928,68 @@ f.substr(0,f.length-1));return f}}; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.PositionFilter");runtime.loadClass("odf.OdfUtils"); -ops.TextPositionFilter=function(g){function l(d,g,c){var e,a;if(g){if(f.isInlineRoot(g)&&f.isGroupingElement(c))return h;e=f.lookLeftForCharacter(g);if(1===e||2===e&&(f.scanRightForAnyCharacter(c)||f.scanRightForAnyCharacter(f.nextNode(d))))return n}e=null===g&&f.isParagraph(d);a=f.lookRightForCharacter(c);if(e)return a?n:f.scanRightForAnyCharacter(c)?h:n;if(!a)return h;g=g||f.previousNode(d);return f.scanLeftForAnyCharacter(g)?h:n}var f=new odf.OdfUtils,p=Node.ELEMENT_NODE,r=Node.TEXT_NODE,n=core.PositionFilter.FilterResult.FILTER_ACCEPT, -h=core.PositionFilter.FilterResult.FILTER_REJECT;this.acceptPosition=function(d){var m=d.container(),c=m.nodeType,e,a,b;if(c!==p&&c!==r)return h;if(c===r){if(!f.isGroupingElement(m.parentNode)||f.isWithinTrackedChanges(m.parentNode,g()))return h;c=d.unfilteredDomOffset();e=m.data;runtime.assert(c!==e.length,"Unexpected offset.");if(0<c){d=e[c-1];if(!f.isODFWhitespace(d))return n;if(1<c)if(d=e[c-2],!f.isODFWhitespace(d))a=n;else{if(!f.isODFWhitespace(e.substr(0,c)))return h}else b=f.previousNode(m), -f.scanLeftForNonSpace(b)&&(a=n);if(a===n)return f.isTrailingWhitespace(m,c)?h:n;a=e[c];return f.isODFWhitespace(a)?h:f.scanLeftForAnyCharacter(f.previousNode(m))?h:n}b=d.leftNode();a=m;m=m.parentNode;a=l(m,b,a)}else!f.isGroupingElement(m)||f.isWithinTrackedChanges(m,g())?a=h:(b=d.leftNode(),a=d.rightNode(),a=l(m,b,a));return a}}; -// Input 34 -"function"!==typeof Object.create&&(Object.create=function(g){var l=function(){};l.prototype=g;return new l}); -xmldom.LSSerializer=function(){function g(f){var g=f||{},h=function(c){var a={},b;for(b in c)c.hasOwnProperty(b)&&(a[c[b]]=b);return a}(f),d=[g],m=[h],c=0;this.push=function(){c+=1;g=d[c]=Object.create(g);h=m[c]=Object.create(h)};this.pop=function(){d.pop();m.pop();c-=1;g=d[c];h=m[c]};this.getLocalNamespaceDefinitions=function(){return h};this.getQName=function(c){var a=c.namespaceURI,b=0,d;if(!a)return c.localName;if(d=h[a])return d+":"+c.localName;do{d||!c.prefix?(d="ns"+b,b+=1):d=c.prefix;if(g[d]=== -a)break;if(!g[d]){g[d]=a;h[a]=d;break}d=null}while(null===d);return d+":"+c.localName}}function l(f){return f.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""")}function f(g,n){var h="",d=p.filter?p.filter.acceptNode(n):NodeFilter.FILTER_ACCEPT,m;if(d===NodeFilter.FILTER_ACCEPT&&n.nodeType===Node.ELEMENT_NODE){g.push();m=g.getQName(n);var c,e=n.attributes,a,b,q,k="",t;c="<"+m;a=e.length;for(b=0;b<a;b+=1)q=e.item(b),"http://www.w3.org/2000/xmlns/"!== -q.namespaceURI&&(t=p.filter?p.filter.acceptNode(q):NodeFilter.FILTER_ACCEPT,t===NodeFilter.FILTER_ACCEPT&&(t=g.getQName(q),q="string"===typeof q.value?l(q.value):q.value,k+=" "+(t+'="'+q+'"')));a=g.getLocalNamespaceDefinitions();for(b in a)a.hasOwnProperty(b)&&((e=a[b])?"xmlns"!==e&&(c+=" xmlns:"+a[b]+'="'+b+'"'):c+=' xmlns="'+b+'"');h+=c+(k+">")}if(d===NodeFilter.FILTER_ACCEPT||d===NodeFilter.FILTER_SKIP){for(d=n.firstChild;d;)h+=f(g,d),d=d.nextSibling;n.nodeValue&&(h+=l(n.nodeValue))}m&&(h+="</"+ -m+">",g.pop());return h}var p=this;this.filter=null;this.writeToString=function(l,n){if(!l)return"";var h=new g(n);return f(h,l)}}; -// Input 35 +(function(){function k(){function a(e){b=!0;runtime.setTimeout(function(){try{e()}catch(d){runtime.log(String(d))}b=!1;0<c.length&&a(c.pop())},10)}var c=[],b=!1;this.clearQueue=function(){c.length=0};this.addToQueue=function(e){if(0===c.length&&!b)return a(e);c.push(e)}}function h(a){function c(){for(;0<b.cssRules.length;)b.deleteRule(0);b.insertRule("#shadowContent draw|page {display:none;}",0);b.insertRule("office|presentation draw|page {display:none;}",1);b.insertRule("#shadowContent draw|page:nth-of-type("+ +e+") {display:block;}",2);b.insertRule("office|presentation draw|page:nth-of-type("+e+") {display:block;}",3)}var b=a.sheet,e=1;this.showFirstPage=function(){e=1;c()};this.showNextPage=function(){e+=1;c()};this.showPreviousPage=function(){1<e&&(e-=1,c())};this.showPage=function(a){0<a&&(e=a,c())};this.css=a;this.destroy=function(c){a.parentNode.removeChild(a);c()}}function b(a){for(;a.firstChild;)a.removeChild(a.firstChild)}function p(a){a=a.sheet;for(var c=a.cssRules;c.length;)a.deleteRule(c.length- +1)}function d(a,c,b){(new odf.Style2CSS).style2css(a.getDocumentType(),b.sheet,c.getFontMap(),a.rootElement.styles,a.rootElement.automaticStyles)}function n(a,c,b){var e=null;a=a.rootElement.body.getElementsByTagNameNS(F,b+"-decl");b=c.getAttributeNS(F,"use-"+b+"-name");var d;if(b&&0<a.length)for(c=0;c<a.length;c+=1)if(d=a[c],d.getAttributeNS(F,"name")===b){e=d.textContent;break}return e}function g(a,c,e,d){var f=a.ownerDocument;c=a.getElementsByTagNameNS(c,e);for(a=0;a<c.length;a+=1)b(c[a]),d&&(e= +c[a],e.appendChild(f.createTextNode(d)))}function q(a,c,b){c.setAttributeNS("urn:webodf:names:helper","styleid",a);var e,d=c.getAttributeNS(J,"anchor-type"),f=c.getAttributeNS(s,"x"),g=c.getAttributeNS(s,"y"),m=c.getAttributeNS(s,"width"),l=c.getAttributeNS(s,"height"),h=c.getAttributeNS(x,"min-height"),k=c.getAttributeNS(x,"min-width");if("as-char"===d)e="display: inline-block;";else if(d||f||g)e="position: absolute;";else if(m||l||h||k)e="display: block;";f&&(e+="left: "+f+";");g&&(e+="top: "+g+ +";");m&&(e+="width: "+m+";");l&&(e+="height: "+l+";");h&&(e+="min-height: "+h+";");k&&(e+="min-width: "+k+";");e&&(e="draw|"+c.localName+'[webodfhelper|styleid="'+a+'"] {'+e+"}",b.insertRule(e,b.cssRules.length))}function r(a){for(a=a.firstChild;a;){if(a.namespaceURI===v&&"binary-data"===a.localName)return"data:image/png;base64,"+a.textContent.replace(/[\r\n\s]/g,"");a=a.nextSibling}return""}function l(a,c,b,e){function d(c){c&&(c='draw|image[webodfhelper|styleid="'+a+'"] {'+("background-image: url("+ +c+");")+"}",e.insertRule(c,e.cssRules.length))}function f(a){d(a.url)}b.setAttributeNS("urn:webodf:names:helper","styleid",a);var g=b.getAttributeNS(G,"href"),m;if(g)try{m=c.getPart(g),m.onchange=f,m.load()}catch(l){runtime.log("slight problem: "+String(l))}else g=r(b),d(g)}function f(a){var c=a.ownerDocument;Q.getElementsByTagNameNS(a,J,"line-break").forEach(function(a){a.hasChildNodes()||a.appendChild(c.createElement("br"))})}function c(a){var c=a.ownerDocument;Q.getElementsByTagNameNS(a,J,"s").forEach(function(a){for(var b, +e;a.firstChild;)a.removeChild(a.firstChild);a.appendChild(c.createTextNode(" "));e=parseInt(a.getAttributeNS(J,"c"),10);if(1<e)for(a.removeAttributeNS(J,"c"),b=1;b<e;b+=1)a.parentNode.insertBefore(a.cloneNode(!0),a)})}function a(a){Q.getElementsByTagNameNS(a,J,"tab").forEach(function(a){a.textContent="\t"})}function m(a,c){function b(a,e){var g=m.documentElement.namespaceURI;"video/"===e.substr(0,6)?(d=m.createElementNS(g,"video"),d.setAttribute("controls","controls"),f=m.createElementNS(g,"source"), +a&&f.setAttribute("src",a),f.setAttribute("type",e),d.appendChild(f),c.parentNode.appendChild(d)):c.innerHtml="Unrecognised Plugin"}function e(a){b(a.url,a.mimetype)}var d,f,g,m=c.ownerDocument,l;if(g=c.getAttributeNS(G,"href"))try{l=a.getPart(g),l.onchange=e,l.load()}catch(h){runtime.log("slight problem: "+String(h))}else runtime.log("using MP4 data fallback"),g=r(c),b(g,"video/mp4")}function e(a){var c=a.getElementsByTagName("head")[0],b,e;b=a.styleSheets.length;for(e=c.firstElementChild;e&&("style"!== +e.localName||!e.hasAttribute("webodfcss"));)e=e.nextElementSibling;if(e)return b=parseInt(e.getAttribute("webodfcss"),10),e.setAttribute("webodfcss",b+1),e;"string"===String(typeof webodf_css)?b=webodf_css:(e="webodf.css",runtime.currentDirectory&&(e=runtime.currentDirectory(),0<e.length&&"/"!==e.substr(-1)&&(e+="/"),e+="../webodf.css"),b=runtime.readFileSync(e,"utf-8"));e=a.createElementNS(c.namespaceURI,"style");e.setAttribute("media","screen, print, handheld, projection");e.setAttribute("type", +"text/css");e.setAttribute("webodfcss","1");e.appendChild(a.createTextNode(b));c.appendChild(e);return e}function t(a){var c=parseInt(a.getAttribute("webodfcss"),10);1===c?a.parentNode.removeChild(a):a.setAttribute("count",c-1)}function w(a){var c=a.getElementsByTagName("head")[0],b=a.createElementNS(c.namespaceURI,"style"),e="";b.setAttribute("type","text/css");b.setAttribute("media","screen, print, handheld, projection");odf.Namespaces.forEachPrefix(function(a,c){e+="@namespace "+a+" url("+c+");\n"}); +e+="@namespace webodfhelper url(urn:webodf:names:helper);\n";b.appendChild(a.createTextNode(e));c.appendChild(b);return b}var z=odf.Namespaces.drawns,x=odf.Namespaces.fons,v=odf.Namespaces.officens,u=odf.Namespaces.stylens,s=odf.Namespaces.svgns,A=odf.Namespaces.tablens,J=odf.Namespaces.textns,G=odf.Namespaces.xlinkns,D=odf.Namespaces.xmlns,F=odf.Namespaces.presentationns,O=runtime.getWindow(),K=xmldom.XPath,Z=new odf.OdfUtils,Q=new core.DomUtils;odf.OdfCanvas=function(r){function s(a,c,b){function e(a, +c,b,d){C.addToQueue(function(){l(a,c,b,d)})}var d,f;d=c.getElementsByTagNameNS(z,"image");for(c=0;c<d.length;c+=1)f=d.item(c),e("image"+String(c),a,f,b)}function x(a,c){function b(a,c){C.addToQueue(function(){m(a,c)})}var e,d,f;d=c.getElementsByTagNameNS(z,"plugin");for(e=0;e<d.length;e+=1)f=d.item(e),b(a,f)}function G(){var a;a=S.firstChild;var c=ba.getZoomLevel();a&&(S.style.WebkitTransformOrigin="0% 0%",S.style.MozTransformOrigin="0% 0%",S.style.msTransformOrigin="0% 0%",S.style.OTransformOrigin= +"0% 0%",S.style.transformOrigin="0% 0%",P&&((a=P.getMinimumHeightForAnnotationPane())?S.style.minHeight=a:S.style.removeProperty("min-height")),r.style.width=Math.round(c*S.offsetWidth)+"px",r.style.height=Math.round(c*S.offsetHeight)+"px")}function aa(a){da?(U.parentNode||S.appendChild(U),P&&P.forgetAnnotations(),P=new gui.AnnotationViewManager(I,a.body,U,ka),Q.getElementsByTagNameNS(a.body,v,"annotation").forEach(P.addAnnotation),P.rerenderAnnotations(),G()):U.parentNode&&(S.removeChild(U),P.forgetAnnotations(), +G())}function N(e){function m(){p(V);p(ga);p(ha);b(r);r.style.display="inline-block";var l=Y.rootElement;r.ownerDocument.importNode(l,!0);M.setOdfContainer(Y);var h=Y,k=V;(new odf.FontLoader).loadFonts(h,k.sheet);d(Y,M,ga);k=Y;h=ha.sheet;b(r);S=ca.createElementNS(r.namespaceURI,"div");S.style.display="inline-block";S.style.background="white";S.style.setProperty("float","left","important");S.appendChild(l);r.appendChild(S);U=ca.createElementNS(r.namespaceURI,"div");U.id="annotationsPane";$=ca.createElementNS(r.namespaceURI, +"div");$.id="shadowContent";$.style.position="absolute";$.style.top=0;$.style.left=0;k.getContentElement().appendChild($);var t=l.body,w,G=[],y;for(w=t.firstElementChild;w&&w!==t;)if(w.namespaceURI===z&&(G[G.length]=w),w.firstElementChild)w=w.firstElementChild;else{for(;w&&w!==t&&!w.nextElementSibling;)w=w.parentNode;w&&w.nextElementSibling&&(w=w.nextElementSibling)}for(y=0;y<G.length;y+=1)w=G[y],q("frame"+String(y),w,h);G=K.getODFElementsWithXPath(t,".//*[*[@text:anchor-type='paragraph']]",odf.Namespaces.lookupNamespaceURI); +for(w=0;w<G.length;w+=1)t=G[w],t.setAttributeNS&&t.setAttributeNS("urn:webodf:names:helper","containsparagraphanchor",!0);var t=$,B,C,N;N=0;var I,E,G=k.rootElement.ownerDocument;if((w=l.body.firstElementChild)&&w.namespaceURI===v&&("presentation"===w.localName||"drawing"===w.localName))for(w=w.firstElementChild;w;){y=w.getAttributeNS(z,"master-page-name");if(y){for(B=k.rootElement.masterStyles.firstElementChild;B&&(B.getAttributeNS(u,"name")!==y||"master-page"!==B.localName||B.namespaceURI!==u);)B= +B.nextElementSibling;y=B}else y=null;if(y){B=w.getAttributeNS("urn:webodf:names:helper","styleid");C=G.createElementNS(z,"draw:page");E=y.firstElementChild;for(I=0;E;)"true"!==E.getAttributeNS(F,"placeholder")&&(N=E.cloneNode(!0),C.appendChild(N),q(B+"_"+I,N,h)),E=E.nextElementSibling,I+=1;E=I=N=void 0;var R=C.getElementsByTagNameNS(z,"frame");for(N=0;N<R.length;N+=1)I=R[N],(E=I.getAttributeNS(F,"class"))&&!/^(date-time|footer|header|page-number)$/.test(E)&&I.parentNode.removeChild(I);t.appendChild(C); +N=String(t.getElementsByTagNameNS(z,"page").length);g(C,J,"page-number",N);g(C,F,"header",n(k,w,"header"));g(C,F,"footer",n(k,w,"footer"));q(B,C,h);C.setAttributeNS(z,"draw:master-page-name",y.getAttributeNS(u,"name"))}w=w.nextElementSibling}t=r.namespaceURI;G=l.body.getElementsByTagNameNS(A,"table-cell");for(w=0;w<G.length;w+=1)y=G.item(w),y.hasAttributeNS(A,"number-columns-spanned")&&y.setAttributeNS(t,"colspan",y.getAttributeNS(A,"number-columns-spanned")),y.hasAttributeNS(A,"number-rows-spanned")&& +y.setAttributeNS(t,"rowspan",y.getAttributeNS(A,"number-rows-spanned"));f(l.body);c(l.body);a(l.body);s(k,l.body,h);x(k,l.body);y=l.body;k=r.namespaceURI;w={};var G={},Q;B=O.document.getElementsByTagNameNS(J,"list-style");for(t=0;t<B.length;t+=1)I=B.item(t),(E=I.getAttributeNS(u,"name"))&&(G[E]=I);y=y.getElementsByTagNameNS(J,"list");for(t=0;t<y.length;t+=1)if(I=y.item(t),B=I.getAttributeNS(D,"id")){C=I.getAttributeNS(J,"continue-list");I.setAttributeNS(k,"id",B);N="text|list#"+B+" > text|list-item > *:first-child:before {"; +if(E=I.getAttributeNS(J,"style-name")){I=G[E];Q=Z.getFirstNonWhitespaceChild(I);I=void 0;if(Q)if("list-level-style-number"===Q.localName){I=Q.getAttributeNS(u,"num-format");E=Q.getAttributeNS(u,"num-suffix")||"";var R="",R={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},L=void 0,L=Q.getAttributeNS(u,"num-prefix")||"",L=R.hasOwnProperty(I)?L+(" counter(list, "+R[I]+")"):I?L+("'"+I+"';"):L+" ''";E&&(L+=" '"+E+"'");I=R="content: "+L+";"}else"list-level-style-image"===Q.localName? +I="content: none;":"list-level-style-bullet"===Q.localName&&(I="content: '"+Q.getAttributeNS(J,"bullet-char")+"';");Q=I}if(C){for(I=w[C];I;)I=w[I];N+="counter-increment:"+C+";";Q?(Q=Q.replace("list",C),N+=Q):N+="content:counter("+C+");"}else C="",Q?(Q=Q.replace("list",B),N+=Q):N+="content: counter("+B+");",N+="counter-increment:"+B+";",h.insertRule("text|list#"+B+" {counter-reset:"+B+"}",h.cssRules.length);N+="}";w[B]=C;N&&h.insertRule(N,h.cssRules.length)}S.insertBefore($,S.firstChild);ba.setZoomableElement(S); +aa(l);if(!e&&(l=[Y],ea.hasOwnProperty("statereadychange")))for(h=ea.statereadychange,Q=0;Q<h.length;Q+=1)h[Q].apply(null,l)}Y.state===odf.OdfContainer.DONE?m():(runtime.log("WARNING: refreshOdf called but ODF was not DONE."),fa=runtime.setTimeout(function na(){Y.state===odf.OdfContainer.DONE?m():(runtime.log("will be back later..."),fa=runtime.setTimeout(na,500))},100))}function R(a){C.clearQueue();r.innerHTML=runtime.tr("Loading")+" "+a+"...";r.removeAttribute("style");Y=new odf.OdfContainer(a,function(a){Y= +a;N(!1)})}runtime.assert(null!==r&&void 0!==r,"odf.OdfCanvas constructor needs DOM element");runtime.assert(null!==r.ownerDocument&&void 0!==r.ownerDocument,"odf.OdfCanvas constructor needs DOM");var I=this,ca=r.ownerDocument,ia=new core.Async,Y,M=new odf.Formatting,E,S=null,U=null,da=!1,ka=!1,P=null,X,V,ga,ha,$,ea={},fa,ja,L=!1,B=!1,C=new k,ba=new gui.ZoomHelper;this.refreshCSS=function(){L=!0;ja.trigger()};this.refreshSize=function(){ja.trigger()};this.odfContainer=function(){return Y};this.setOdfContainer= +function(a,c){Y=a;N(!0===c)};this.load=this.load=R;this.save=function(a){Y.save(a)};this.addListener=function(a,c){switch(a){case "click":var b=r,e=a;b.addEventListener?b.addEventListener(e,c,!1):b.attachEvent?b.attachEvent("on"+e,c):b["on"+e]=c;break;default:b=ea.hasOwnProperty(a)?ea[a]:ea[a]=[],c&&-1===b.indexOf(c)&&b.push(c)}};this.getFormatting=function(){return M};this.getAnnotationViewManager=function(){return P};this.refreshAnnotations=function(){aa(Y.rootElement)};this.rerenderAnnotations= +function(){P&&(B=!0,ja.trigger())};this.getSizer=function(){return S};this.enableAnnotations=function(a,c){a!==da&&(da=a,ka=c,Y&&aa(Y.rootElement))};this.addAnnotation=function(a){P&&(P.addAnnotation(a),G())};this.forgetAnnotations=function(){P&&(P.forgetAnnotations(),G())};this.getZoomHelper=function(){return ba};this.setZoomLevel=function(a){ba.setZoomLevel(a)};this.getZoomLevel=function(){return ba.getZoomLevel()};this.fitToContainingElement=function(a,c){var b=ba.getZoomLevel(),e=r.offsetHeight/ +b,b=a/(r.offsetWidth/b);c/e<b&&(b=c/e);ba.setZoomLevel(b)};this.fitToWidth=function(a){var c=r.offsetWidth/ba.getZoomLevel();ba.setZoomLevel(a/c)};this.fitSmart=function(a,c){var b,e;e=ba.getZoomLevel();b=r.offsetWidth/e;e=r.offsetHeight/e;b=a/b;void 0!==c&&c/e<b&&(b=c/e);ba.setZoomLevel(Math.min(1,b))};this.fitToHeight=function(a){var c=r.offsetHeight/ba.getZoomLevel();ba.setZoomLevel(a/c)};this.showFirstPage=function(){E.showFirstPage()};this.showNextPage=function(){E.showNextPage()};this.showPreviousPage= +function(){E.showPreviousPage()};this.showPage=function(a){E.showPage(a);G()};this.getElement=function(){return r};this.addCssForFrameWithImage=function(a){var c=a.getAttributeNS(z,"name"),b=a.firstElementChild;q(c,a,ha.sheet);b&&l(c+"img",Y,b,ha.sheet)};this.destroy=function(a){var c=ca.getElementsByTagName("head")[0],b=[E.destroy,ja.destroy];runtime.clearTimeout(fa);U&&U.parentNode&&U.parentNode.removeChild(U);ba.destroy(function(){S&&(r.removeChild(S),S=null)});t(X);c.removeChild(V);c.removeChild(ga); +c.removeChild(ha);ia.destroyAll(b,a)};X=e(ca);E=new h(w(ca));V=w(ca);ga=w(ca);ha=w(ca);ja=new core.ScheduledTask(function(){L&&(d(Y,M,ga),L=!1);B&&(P&&P.rerenderAnnotations(),B=!1);G()},0);ba.subscribe(gui.ZoomHelper.signalZoomChanged,G)}})(); +// Input 36 /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +ops.MemberProperties=function(){}; +ops.Member=function(k,h){var b=new ops.MemberProperties;this.getMemberId=function(){return k};this.getProperties=function(){return b};this.setProperties=function(h){Object.keys(h).forEach(function(d){b[d]=h[d]})};this.removeProperties=function(h){Object.keys(h).forEach(function(d){"fullName"!==d&&"color"!==d&&"imageUrl"!==d&&b.hasOwnProperty(d)&&delete b[d]})};runtime.assert(Boolean(k),"No memberId was supplied!");h.fullName||(h.fullName=runtime.tr("Unknown Author"));h.color||(h.color="black");h.imageUrl|| +(h.imageUrl="avatar-joe.png");b=h}; +// Input 37 +/* + + Copyright (C) 2012-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 @@ -833,10 +1022,14 @@ m+">",g.pop());return h}var p=this;this.filter=null;this.writeToString=function( @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces");runtime.loadClass("xmldom.LSSerializer");runtime.loadClass("odf.OdfNodeFilter");runtime.loadClass("odf.TextSerializer"); -gui.Clipboard=function(){var g,l,f;this.setDataFromRange=function(f,r){var n=!0,h,d=f.clipboardData;h=runtime.getWindow();var m=r.startContainer.ownerDocument;!d&&h&&(d=h.clipboardData);d?(m=m.createElement("span"),m.appendChild(r.cloneContents()),h=d.setData("text/plain",l.writeToString(m)),n=n&&h,h=d.setData("text/html",g.writeToString(m,odf.Namespaces.namespaceMap)),n=n&&h,f.preventDefault()):n=!1;return n};g=new xmldom.LSSerializer;l=new odf.TextSerializer;f=new odf.OdfNodeFilter;g.filter=f;l.filter= -f}; -// Input 36 +gui.SelectionMover=function(k,h){function b(){f.setUnfilteredPosition(k.getNode(),0);return f}function p(a,c){var b,d=null;a&&0<a.length&&(b=c?a.item(a.length-1):a.item(0));b&&(d={top:b.top,left:c?b.right:b.left,bottom:b.bottom});return d}function d(a,c,b,f){var g=a.nodeType;b.setStart(a,c);b.collapse(!f);f=p(b.getClientRects(),!0===f);!f&&0<c&&(b.setStart(a,c-1),b.setEnd(a,c),f=p(b.getClientRects(),!0));f||(g===Node.ELEMENT_NODE&&0<c&&a.childNodes.length>=c?f=d(a,c-1,b,!0):a.nodeType===Node.TEXT_NODE&& +0<c?f=d(a,c-1,b,!0):a.previousSibling?f=d(a.previousSibling,a.previousSibling.nodeType===Node.TEXT_NODE?a.previousSibling.textContent.length:a.previousSibling.childNodes.length,b,!0):a.parentNode&&a.parentNode!==h?f=d(a.parentNode,0,b,!1):(b.selectNode(h),f=p(b.getClientRects(),!1)));runtime.assert(Boolean(f),"No visible rectangle found");return f}function n(a,d,e){for(var f=b(),g=new core.LoopWatchDog(1E4),l=0,h=0;0<a&&f.nextPosition();)g.check(),e.acceptPosition(f)===c&&(l+=1,d.acceptPosition(f)=== +c&&(h+=l,l=0,a-=1));return h}function g(a,d,e){for(var f=b(),g=new core.LoopWatchDog(1E4),l=0,h=0;0<a&&f.previousPosition();)g.check(),e.acceptPosition(f)===c&&(l+=1,d.acceptPosition(f)===c&&(h+=l,l=0,a-=1));return h}function q(a,f){var e=b(),g=0,l=0,k=0>a?-1:1;for(a=Math.abs(a);0<a;){for(var n=f,q=k,p=e,r=p.container(),A=0,J=null,G=void 0,D=10,F=void 0,O=0,K=void 0,Z=void 0,Q=void 0,F=void 0,W=h.ownerDocument.createRange(),H=new core.LoopWatchDog(1E4),F=d(r,p.unfilteredDomOffset(),W),K=F.top,Z=F.left, +Q=K;!0===(0>q?p.previousPosition():p.nextPosition());)if(H.check(),n.acceptPosition(p)===c&&(A+=1,r=p.container(),F=d(r,p.unfilteredDomOffset(),W),F.top!==K)){if(F.top!==Q&&Q!==K)break;Q=F.top;F=Math.abs(Z-F.left);if(null===J||F<D)J=r,G=p.unfilteredDomOffset(),D=F,O=A}null!==J?(p.setUnfilteredPosition(J,G),A=O):A=0;W.detach();g+=A;if(0===g)break;l+=g;a-=1}return l*k}function r(a,f){var e,g,k,n,q=b(),p=l.getParagraphElement(q.getCurrentNode()),r=0,s=h.ownerDocument.createRange();0>a?(e=q.previousPosition, +g=-1):(e=q.nextPosition,g=1);for(k=d(q.container(),q.unfilteredDomOffset(),s);e.call(q);)if(f.acceptPosition(q)===c){if(l.getParagraphElement(q.getCurrentNode())!==p)break;n=d(q.container(),q.unfilteredDomOffset(),s);if(n.bottom!==k.bottom&&(k=n.top>=k.top&&n.bottom<k.bottom||n.top<=k.top&&n.bottom>k.bottom,!k))break;r+=g;k=n}s.detach();return r}var l=new odf.OdfUtils,f,c=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.getStepCounter=function(){return{convertForwardStepsBetweenFilters:n,convertBackwardStepsBetweenFilters:g, +countLinesSteps:q,countStepsToLineBoundary:r}};(function(){f=gui.SelectionMover.createPositionIterator(h);var a=h.ownerDocument.createRange();a.setStart(f.container(),f.unfilteredDomOffset());a.collapse(!0);k.setSelectedRange(a)})()}; +gui.SelectionMover.createPositionIterator=function(k){var h=new function(){this.acceptNode=function(b){return b&&"urn:webodf:names:cursor"!==b.namespaceURI&&"urn:webodf:names:editinfo"!==b.namespaceURI?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}};return new core.PositionIterator(k,5,h,!1)};(function(){return gui.SelectionMover})(); +// Input 38 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -874,34 +1067,13 @@ f}; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.Base64");runtime.loadClass("core.Zip");runtime.loadClass("core.DomUtils");runtime.loadClass("xmldom.LSSerializer");runtime.loadClass("odf.StyleInfo");runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfNodeFilter"); -(function(){function g(a,b,c){for(a=a?a.firstChild:null;a;){if(a.localName===c&&a.namespaceURI===b)return a;a=a.nextSibling}return null}function l(a){var b,c=m.length;for(b=0;b<c;b+=1)if("urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&a.localName===m[b])return b;return-1}function f(a,b){var c=new n.UsedStyleList(a,b),d=new odf.OdfNodeFilter;this.acceptNode=function(a){var e=d.acceptNode(a);e===NodeFilter.FILTER_ACCEPT&&a.parentNode===b&&a.nodeType===Node.ELEMENT_NODE&&(e=c.uses(a)? -NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT);return e}}function p(a,b){var c=new f(a,b);this.acceptNode=function(a){var b=c.acceptNode(a);b!==NodeFilter.FILTER_ACCEPT||!a.parentNode||a.parentNode.namespaceURI!==odf.Namespaces.textns||"s"!==a.parentNode.localName&&"tab"!==a.parentNode.localName||(b=NodeFilter.FILTER_REJECT);return b}}function r(a,b){if(b){var c=l(b),d,e=a.firstChild;if(-1!==c){for(;e;){d=l(e);if(-1!==d&&d>c)break;e=e.nextSibling}a.insertBefore(b,e)}}}var n=new odf.StyleInfo, -h=new core.DomUtils,d=odf.Namespaces.stylens,m="meta settings scripts font-face-decls styles automatic-styles master-styles body".split(" "),c=(new Date).getTime()+"_webodf_",e=new core.Base64;odf.ODFElement=function(){};odf.ODFDocumentElement=function(){};odf.ODFDocumentElement.prototype=new odf.ODFElement;odf.ODFDocumentElement.prototype.constructor=odf.ODFDocumentElement;odf.ODFDocumentElement.prototype.fontFaceDecls=null;odf.ODFDocumentElement.prototype.manifest=null;odf.ODFDocumentElement.prototype.settings= -null;odf.ODFDocumentElement.namespaceURI="urn:oasis:names:tc:opendocument:xmlns:office:1.0";odf.ODFDocumentElement.localName="document";odf.OdfPart=function(a,b,c,d){var e=this;this.size=0;this.type=null;this.name=a;this.container=c;this.url=null;this.mimetype=b;this.onstatereadychange=this.document=null;this.EMPTY=0;this.LOADING=1;this.DONE=2;this.state=this.EMPTY;this.data="";this.load=function(){null!==d&&(this.mimetype=b,d.loadAsDataURL(a,b,function(a,b){a&&runtime.log(a);e.url=b;if(e.onchange)e.onchange(e); -if(e.onstatereadychange)e.onstatereadychange(e)}))}};odf.OdfPart.prototype.load=function(){};odf.OdfPart.prototype.getUrl=function(){return this.data?"data:;base64,"+e.toBase64(this.data):null};odf.OdfContainer=function b(q,k){function m(b){for(var c=b.firstChild,d;c;)d=c.nextSibling,c.nodeType===Node.ELEMENT_NODE?m(c):c.nodeType===Node.PROCESSING_INSTRUCTION_NODE&&b.removeChild(c),c=d}function l(b,c){for(var d=b&&b.firstChild;d;)d.nodeType===Node.ELEMENT_NODE&&d.setAttributeNS("urn:webodf:names:scope", -"scope",c),d=d.nextSibling}function w(b){var c={},e;for(b=b.firstChild;b;)b.nodeType===Node.ELEMENT_NODE&&b.namespaceURI===d&&"font-face"===b.localName&&(e=b.getAttributeNS(d,"name"),c[e]=b),b=b.nextSibling;return c}function x(b,c){var d=null,e,f,h;if(b)for(d=b.cloneNode(!0),e=d.firstElementChild;e;)f=e.nextElementSibling,(h=e.getAttributeNS("urn:webodf:names:scope","scope"))&&h!==c&&d.removeChild(e),e=f;return d}function v(b,c){var e,f,h,k=null,g={};if(b)for(c.forEach(function(b){n.collectUsedFontFaces(g, -b)}),k=b.cloneNode(!0),e=k.firstElementChild;e;)f=e.nextElementSibling,h=e.getAttributeNS(d,"name"),g[h]||k.removeChild(e),e=f;return k}function u(b){var c=R.rootElement.ownerDocument,d;if(b){m(b.documentElement);try{d=c.importNode(b.documentElement,!0)}catch(e){}}return d}function s(b){R.state=b;if(R.onchange)R.onchange(R);if(R.onstatereadychange)R.onstatereadychange(R)}function H(b){ba=null;R.rootElement=b;b.fontFaceDecls=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls"); -b.styles=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles");b.automaticStyles=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles");b.masterStyles=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles");b.body=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");b.meta=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","meta")}function y(d){var e=u(d),f=R.rootElement,h;e&&"document-styles"===e.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"=== -e.namespaceURI?(f.fontFaceDecls=g(e,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls"),r(f,f.fontFaceDecls),h=g(e,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles"),f.styles=h||d.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles"),r(f,f.styles),h=g(e,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles"),f.automaticStyles=h||d.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles"),l(f.automaticStyles, -"document-styles"),r(f,f.automaticStyles),e=g(e,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles"),f.masterStyles=e||d.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles"),r(f,f.masterStyles),n.prefixStyleNames(f.automaticStyles,c,f.masterStyles)):s(b.INVALID)}function B(c){c=u(c);var e,f,h,k;if(c&&"document-content"===c.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===c.namespaceURI){e=R.rootElement;h=g(c,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", -"font-face-decls");if(e.fontFaceDecls&&h){k=e.fontFaceDecls;var q,m,p,t,v={};f=w(k);t=w(h);for(h=h.firstElementChild;h;){q=h.nextElementSibling;if(h.namespaceURI===d&&"font-face"===h.localName)if(m=h.getAttributeNS(d,"name"),f.hasOwnProperty(m)){if(!h.isEqualNode(f[m])){p=m;for(var y=f,I=t,z=0,B=void 0,B=p=p.replace(/\d+$/,"");y.hasOwnProperty(B)||I.hasOwnProperty(B);)z+=1,B=p+z;p=B;h.setAttributeNS(d,"style:name",p);k.appendChild(h);f[p]=h;delete t[m];v[m]=p}}else k.appendChild(h),f[m]=h,delete t[m]; -h=q}k=v}else h&&(e.fontFaceDecls=h,r(e,h));f=g(c,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles");l(f,"document-content");k&&n.changeFontFaceNames(f,k);if(e.automaticStyles&&f)for(k=f.firstChild;k;)e.automaticStyles.appendChild(k),k=f.firstChild;else f&&(e.automaticStyles=f,r(e,f));c=g(c,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");if(null===c)throw"<office:body/> tag is mising.";e.body=c;r(e,e.body)}else s(b.INVALID)}function L(b){b=u(b);var c;b&&"document-meta"=== -b.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===b.namespaceURI&&(c=R.rootElement,c.meta=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","meta"),r(c,c.meta))}function I(b){b=u(b);var c;b&&"document-settings"===b.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===b.namespaceURI&&(c=R.rootElement,c.settings=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","settings"),r(c,c.settings))}function W(b){b=u(b);var c;if(b&&"manifest"===b.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"=== -b.namespaceURI)for(c=R.rootElement,c.manifest=b,b=c.manifest.firstElementChild;b;)"file-entry"===b.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"===b.namespaceURI&&(M[b.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","full-path")]=b.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","media-type")),b=b.nextElementSibling}function Q(c){var d=c.shift();d?P.loadAsDOM(d.path,function(e,f){d.handler(f);e||R.state===b.INVALID||Q(c)}):s(b.DONE)}function z(b){var c= -"";odf.Namespaces.forEachPrefix(function(b,d){c+=" xmlns:"+b+'="'+d+'"'});return'<?xml version="1.0" encoding="UTF-8"?><office:'+b+" "+c+' office:version="1.2">'}function ja(){var b=new xmldom.LSSerializer,c=z("document-meta");b.filter=new odf.OdfNodeFilter;c+=b.writeToString(R.rootElement.meta,odf.Namespaces.namespaceMap);return c+"</office:document-meta>"}function ka(b,c){var d=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest:file-entry");d.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0", -"manifest:full-path",b);d.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest:media-type",c);return d}function G(){var b=runtime.parseXML('<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2"></manifest:manifest>'),c=g(b,"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest"),d=new xmldom.LSSerializer,e;for(e in M)M.hasOwnProperty(e)&&c.appendChild(ka(e,M[e]));d.filter=new odf.OdfNodeFilter;return'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n'+ -d.writeToString(b,odf.Namespaces.namespaceMap)}function Z(){var b=new xmldom.LSSerializer,c=z("document-settings");b.filter=new odf.OdfNodeFilter;c+=b.writeToString(R.rootElement.settings,odf.Namespaces.namespaceMap);return c+"</office:document-settings>"}function O(){var b,d,e,h=odf.Namespaces.namespaceMap,k=new xmldom.LSSerializer,g=z("document-styles");d=x(R.rootElement.automaticStyles,"document-styles");e=R.rootElement.masterStyles.cloneNode(!0);b=v(R.rootElement.fontFaceDecls,[e,R.rootElement.styles, -d]);n.removePrefixFromStyleNames(d,c,e);k.filter=new f(e,d);g+=k.writeToString(b,h);g+=k.writeToString(R.rootElement.styles,h);g+=k.writeToString(d,h);g+=k.writeToString(e,h);return g+"</office:document-styles>"}function aa(){var b,c,d=odf.Namespaces.namespaceMap,e=new xmldom.LSSerializer,f=z("document-content");c=x(R.rootElement.automaticStyles,"document-content");b=v(R.rootElement.fontFaceDecls,[c]);e.filter=new p(R.rootElement.body,c);f+=e.writeToString(b,d);f+=e.writeToString(c,d);f+=e.writeToString(R.rootElement.body, -d);return f+"</office:document-content>"}function J(c,d){runtime.loadXML(c,function(c,e){if(c)d(c);else{var f=u(e);f&&"document"===f.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===f.namespaceURI?(H(f),s(b.DONE)):s(b.INVALID)}})}function F(b,c){var d;d=R.rootElement;var e=d.meta;e||(d.meta=e=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","meta"),r(d,e));d=e;b&&h.mapKeyValObjOntoNode(d,b,odf.Namespaces.lookupNamespaceURI);c&&h.removeKeyElementsFromNode(d, -c,odf.Namespaces.lookupNamespaceURI)}function C(){function c(b,d){var e;d||(d=b);e=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0",d);f[b]=e;f.appendChild(e)}var d=new core.Zip("",null),e=runtime.byteArrayFromString("application/vnd.oasis.opendocument.text","utf8"),f=R.rootElement,h=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","text");d.save("mimetype",e,!1,new Date);c("meta");c("settings");c("scripts");c("fontFaceDecls","font-face-decls"); -c("styles");c("automaticStyles","automatic-styles");c("masterStyles","master-styles");c("body");f.body.appendChild(h);s(b.DONE);return d}function Y(){var b,c=new Date,d=runtime.getWindow();b="WebODF/"+("undefined"!==String(typeof webodf_version)?webodf_version:"FromSource");d&&(b=b+" "+d.navigator.userAgent);F({"meta:generator":b},null);b=runtime.byteArrayFromString(Z(),"utf8");P.save("settings.xml",b,!0,c);b=runtime.byteArrayFromString(ja(),"utf8");P.save("meta.xml",b,!0,c);b=runtime.byteArrayFromString(O(), -"utf8");P.save("styles.xml",b,!0,c);b=runtime.byteArrayFromString(aa(),"utf8");P.save("content.xml",b,!0,c);b=runtime.byteArrayFromString(G(),"utf8");P.save("META-INF/manifest.xml",b,!0,c)}function U(b,c){Y();P.writeAs(b,function(b){c(b)})}var R=this,P,M={},ba;this.onstatereadychange=k;this.state=this.onchange=null;this.setRootElement=H;this.getContentElement=function(){var b;ba||(b=R.rootElement.body,ba=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","text")||g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", -"presentation")||g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","spreadsheet"));if(!ba)throw"Could not find content element in <office:body/>.";return ba};this.getDocumentType=function(){var b=R.getContentElement();return b&&b.localName};this.getPart=function(b){return new odf.OdfPart(b,M[b],R,P)};this.getPartData=function(b,c){P.load(b,c)};this.setMetadata=F;this.incrementEditingCycles=function(){var b;for(b=(b=R.rootElement.meta)&&b.firstChild;b&&(b.namespaceURI!==odf.Namespaces.metans|| -"editing-cycles"!==b.localName);)b=b.nextSibling;for(b=b&&b.firstChild;b&&b.nodeType!==Node.TEXT_NODE;)b=b.nextSibling;b=b?b.data:null;b=b?parseInt(b,10):0;isNaN(b)&&(b=0);F({"meta:editing-cycles":b+1},null)};this.createByteArray=function(b,c){Y();P.createByteArray(b,c)};this.saveAs=U;this.save=function(b){U(q,b)};this.getUrl=function(){return q};this.setBlob=function(b,c,d){d=e.convertBase64ToByteArray(d);P.save(b,d,!1,new Date);M.hasOwnProperty(b)&&runtime.log(b+" has been overwritten.");M[b]=c}; -this.removeBlob=function(b){var c=P.remove(b);runtime.assert(c,"file is not found: "+b);delete M[b]};this.state=b.LOADING;this.rootElement=function(b){var c=document.createElementNS(b.namespaceURI,b.localName),d;b=new b.Type;for(d in b)b.hasOwnProperty(d)&&(c[d]=b[d]);return c}({Type:odf.ODFDocumentElement,namespaceURI:odf.ODFDocumentElement.namespaceURI,localName:odf.ODFDocumentElement.localName});P=q?new core.Zip(q,function(c,d){P=d;c?J(q,function(d){c&&(P.error=c+"\n"+d,s(b.INVALID))}):Q([{path:"styles.xml", -handler:y},{path:"content.xml",handler:B},{path:"meta.xml",handler:L},{path:"settings.xml",handler:I},{path:"META-INF/manifest.xml",handler:W}])}):C()};odf.OdfContainer.EMPTY=0;odf.OdfContainer.LOADING=1;odf.OdfContainer.DONE=2;odf.OdfContainer.INVALID=3;odf.OdfContainer.SAVING=4;odf.OdfContainer.MODIFIED=5;odf.OdfContainer.getContainer=function(b){return new odf.OdfContainer(b,null)};return odf.OdfContainer})(); -// Input 37 +ops.Document=function(){};ops.Document.prototype.getMemberIds=function(){};ops.Document.prototype.removeCursor=function(k){};ops.Document.prototype.getDocumentElement=function(){};ops.Document.prototype.getRootNode=function(){};ops.Document.prototype.getDOMDocument=function(){};ops.Document.prototype.cloneDocumentElement=function(){};ops.Document.prototype.setDocumentElement=function(k){};ops.Document.prototype.subscribe=function(k,h){};ops.Document.prototype.unsubscribe=function(k,h){}; +ops.Document.prototype.getCanvas=function(){};ops.Document.prototype.createRootFilter=function(k){};ops.Document.signalCursorAdded="cursor/added";ops.Document.signalCursorRemoved="cursor/removed";ops.Document.signalCursorMoved="cursor/moved";ops.Document.signalMemberAdded="member/added";ops.Document.signalMemberUpdated="member/updated";ops.Document.signalMemberRemoved="member/removed"; +// Input 39 +ops.OdtCursor=function(k,h){var b=this,p={},d,n,g,q=new core.EventNotifier([ops.OdtCursor.signalCursorUpdated]);this.removeFromDocument=function(){g.remove()};this.subscribe=function(b,d){q.subscribe(b,d)};this.unsubscribe=function(b,d){q.unsubscribe(b,d)};this.getStepCounter=function(){return n.getStepCounter()};this.getMemberId=function(){return k};this.getNode=function(){return g.getNode()};this.getAnchorNode=function(){return g.getAnchorNode()};this.getSelectedRange=function(){return g.getSelectedRange()}; +this.setSelectedRange=function(d,l){g.setSelectedRange(d,l);q.emit(ops.OdtCursor.signalCursorUpdated,b)};this.hasForwardSelection=function(){return g.hasForwardSelection()};this.getDocument=function(){return h};this.getSelectionType=function(){return d};this.setSelectionType=function(b){p.hasOwnProperty(b)?d=b:runtime.log("Invalid selection type: "+b)};this.resetSelectionType=function(){b.setSelectionType(ops.OdtCursor.RangeSelection)};g=new core.Cursor(h.getDOMDocument(),k);n=new gui.SelectionMover(g, +h.getRootNode());p[ops.OdtCursor.RangeSelection]=!0;p[ops.OdtCursor.RegionSelection]=!0;b.resetSelectionType()};ops.OdtCursor.RangeSelection="Range";ops.OdtCursor.RegionSelection="Region";ops.OdtCursor.signalCursorUpdated="cursorUpdated";(function(){return ops.OdtCursor})(); +// Input 40 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -939,11 +1111,41 @@ handler:y},{path:"content.xml",handler:B},{path:"meta.xml",handler:L},{path:"set @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.Base64");runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.OdfContainer"); -(function(){function g(l,r,n,h,d){var m,c=0,e;for(e in l)if(l.hasOwnProperty(e)){if(c===n){m=e;break}c+=1}m?r.getPartData(l[m].href,function(a,b){if(a)runtime.log(a);else if(b){var c="@font-face { font-family: '"+(l[m].family||m)+"'; src: url(data:application/x-font-ttf;charset=binary;base64,"+f.convertUTF8ArrayToBase64(b)+') format("truetype"); }';try{h.insertRule(c,h.cssRules.length)}catch(e){runtime.log("Problem inserting rule in CSS: "+runtime.toJson(e)+"\nRule: "+c)}}else runtime.log("missing font data for "+ -l[m].href);g(l,r,n+1,h,d)}):d&&d()}var l=xmldom.XPath,f=new core.Base64;odf.FontLoader=function(){this.loadFonts=function(f,r){for(var n=f.rootElement.fontFaceDecls;r.cssRules.length;)r.deleteRule(r.cssRules.length-1);if(n){var h={},d,m,c,e;if(n)for(n=l.getODFElementsWithXPath(n,"style:font-face[svg:font-face-src]",odf.Namespaces.lookupNamespaceURI),d=0;d<n.length;d+=1)m=n[d],c=m.getAttributeNS(odf.Namespaces.stylens,"name"),e=m.getAttributeNS(odf.Namespaces.svgns,"font-family"),m=l.getODFElementsWithXPath(m, -"svg:font-face-src/svg:font-face-uri",odf.Namespaces.lookupNamespaceURI),0<m.length&&(m=m[0].getAttributeNS(odf.Namespaces.xlinkns,"href"),h[c]={href:m,family:e});g(h,f,0,r)}}};return odf.FontLoader})(); -// Input 38 +ops.Operation=function(){};ops.Operation.prototype.init=function(k){};ops.Operation.prototype.execute=function(k){};ops.Operation.prototype.spec=function(){}; +// Input 41 +/* + + Copyright (C) 2010-2014 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +(function(){var k=0;ops.StepsCache=function(h,b,p){function d(a,c,e){this.nodeId=a;this.steps=c;this.node=e;this.previousBookmark=this.nextBookmark=null;this.setIteratorPosition=function(a){a.setPositionBeforeElement(e);do if(b.acceptPosition(a)===u)break;while(a.nextPosition())}}function n(a,c,e){this.nodeId=a;this.steps=c;this.node=e;this.previousBookmark=this.nextBookmark=null;this.setIteratorPosition=function(a){a.setUnfilteredPosition(e,0);do if(b.acceptPosition(a)===u)break;while(a.nextPosition())}} +function g(a,c){var b="["+a.nodeId;c&&(b+=" => "+c.nodeId);return b+"]"}function q(){for(var a=x,c,b,e,d=new core.LoopWatchDog(0,1E5);a;){d.check();(c=a.previousBookmark)?runtime.assert(c.nextBookmark===a,"Broken bookmark link to previous @"+g(c,a)):(runtime.assert(a===x,"Broken bookmark link @"+g(a)),runtime.assert(void 0===v||x.steps<=v,"Base point is damaged @"+g(a)));(b=a.nextBookmark)&&runtime.assert(b.previousBookmark===a,"Broken bookmark link to next @"+g(a,b));if(void 0===v||a.steps<=v)runtime.assert(z.containsNode(h, +a.node),"Disconnected node is being reported as undamaged @"+g(a)),c&&(e=a.node.compareDocumentPosition(c.node),runtime.assert(0===e||0!==(e&Node.DOCUMENT_POSITION_PRECEDING),"Bookmark order with previous does not reflect DOM order @"+g(c,a))),b&&z.containsNode(h,b.node)&&(e=a.node.compareDocumentPosition(b.node),runtime.assert(0===e||0!==(e&Node.DOCUMENT_POSITION_FOLLOWING),"Bookmark order with next does not reflect DOM order @"+g(a,b)));a=a.nextBookmark}}function r(a){var c="";a.nodeType===Node.ELEMENT_NODE&& +(c=a.getAttributeNS(m,"nodeId"));return c}function l(a){var c=k.toString();a.setAttributeNS(m,"nodeId",c);k+=1;return c}function f(a){var c,b,d=new core.LoopWatchDog(0,1E4);void 0!==v&&a>v&&(a=v);for(c=Math.floor(a/p)*p;!b&&0!==c;)b=e[c],c-=p;for(b=b||x;b.nextBookmark&&b.nextBookmark.steps<=a;)d.check(),b=b.nextBookmark;return b}function c(a){a.previousBookmark&&(a.previousBookmark.nextBookmark=a.nextBookmark);a.nextBookmark&&(a.nextBookmark.previousBookmark=a.previousBookmark)}function a(a){for(var c, +b=null;!b&&a&&a!==h;)(c=r(a))&&(b=t[c])&&b.node!==a&&(runtime.log("Cloned node detected. Creating new bookmark"),b=null,a.removeAttributeNS(m,"nodeId")),a=a.parentNode;return b}var m="urn:webodf:names:steps",e={},t={},w=new odf.OdfUtils,z=new core.DomUtils,x,v,u=core.PositionFilter.FilterResult.FILTER_ACCEPT,s;this.updateCache=function(a,b,g){var m;m=b.getCurrentNode();if(b.isBeforeNode()&&w.isParagraph(m)){g||(a+=1);b=a;var k,n,q;if(void 0!==v&&v<b){k=f(v);for(g=k.nextBookmark;g&&g.steps<=b;)n=g.nextBookmark, +q=Math.ceil(g.steps/p)*p,e[q]===g&&delete e[q],z.containsNode(h,g.node)?g.steps=b+1:(c(g),delete t[g.nodeId]),g=n;v=b}else k=f(b);b=k;g=r(m)||l(m);(k=t[g])?k.node===m?k.steps=a:(runtime.log("Cloned node detected. Creating new bookmark"),g=l(m),k=t[g]=new d(g,a,m)):k=t[g]=new d(g,a,m);m=k;b!==m&&b.nextBookmark!==m&&(c(m),a=b.nextBookmark,m.nextBookmark=b.nextBookmark,m.previousBookmark=b,b.nextBookmark=m,a&&(a.previousBookmark=m));a=Math.ceil(m.steps/p)*p;b=e[a];if(!b||m.steps>b.steps)e[a]=m;s()}}; +this.setToClosestStep=function(a,c){var b;s();b=f(a);b.setIteratorPosition(c);return b.steps};this.setToClosestDomPoint=function(c,b,d){var g,m;s();if(c===h&&0===b)g=x;else if(c===h&&b===h.childNodes.length)for(m in g=x,e)e.hasOwnProperty(m)&&(c=e[m],c.steps>g.steps&&(g=c));else if(g=a(c.childNodes.item(b)||c),!g)for(d.setUnfilteredPosition(c,b);!g&&d.previousNode();)g=a(d.getCurrentNode());g=g||x;void 0!==v&&g.steps>v&&(g=f(v));g.setIteratorPosition(d);return g.steps};this.damageCacheAfterStep=function(a){0> +a&&(a=0);void 0===v?v=a:a<v&&(v=a);s()};(function(){var a=r(h)||l(h);x=new n(a,0,h);s=ops.StepsCache.ENABLE_CACHE_VERIFICATION?q:function(){}})()};ops.StepsCache.ENABLE_CACHE_VERIFICATION=!1;ops.StepsCache.Bookmark=function(){};ops.StepsCache.Bookmark.prototype.setIteratorPosition=function(h){}})(); +// Input 42 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -981,11 +1183,11 @@ l[m].href);g(l,r,n+1,h,d)}):d&&d()}var l=xmldom.XPath,f=new core.Base64;odf.Font @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils");runtime.loadClass("core.Utils"); -odf.ObjectNameGenerator=function(g,l){function f(a,b){var c={};this.generateName=function(){var d=b(),e=0,f;do f=a+e,e+=1;while(c[f]||d[f]);c[f]=!0;return f}}function p(){var a={};[g.rootElement.automaticStyles,g.rootElement.styles].forEach(function(b){for(b=b.firstElementChild;b;)b.namespaceURI===r&&"style"===b.localName&&(a[b.getAttributeNS(r,"name")]=!0),b=b.nextElementSibling});return a}var r=odf.Namespaces.stylens,n=odf.Namespaces.drawns,h=odf.Namespaces.xlinkns,d=new core.DomUtils,m=(new core.Utils).hashString(l), -c=null,e=null,a=null,b={},q={};this.generateStyleName=function(){null===c&&(c=new f("auto"+m+"_",function(){return p()}));return c.generateName()};this.generateFrameName=function(){null===e&&(d.getElementsByTagNameNS(g.rootElement.body,n,"frame").forEach(function(a){b[a.getAttributeNS(n,"name")]=!0}),e=new f("fr"+m+"_",function(){return b}));return e.generateName()};this.generateImageName=function(){null===a&&(d.getElementsByTagNameNS(g.rootElement.body,n,"image").forEach(function(a){a=a.getAttributeNS(h, -"href");a=a.substring(9,a.lastIndexOf("."));q[a]=!0}),a=new f("img"+m+"_",function(){return q}));return a.generateName()}}; -// Input 39 +(function(){ops.StepsTranslator=function(k,h,b,p){function d(){var c=k();c!==g&&(runtime.log("Undo detected. Resetting steps cache"),g=c,q=new ops.StepsCache(g,b,p),l=h(g))}function n(c,a){if(!a||b.acceptPosition(c)===f)return!0;for(;c.previousPosition();)if(b.acceptPosition(c)===f){if(a(0,c.container(),c.unfilteredDomOffset()))return!0;break}for(;c.nextPosition();)if(b.acceptPosition(c)===f){if(a(1,c.container(),c.unfilteredDomOffset()))return!0;break}return!1}var g=k(),q=new ops.StepsCache(g,b, +p),r=new core.DomUtils,l=h(k()),f=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.convertStepsToDomPoint=function(c){var a,g;if(isNaN(c))throw new TypeError("Requested steps is not numeric ("+c+")");if(0>c)throw new RangeError("Requested steps is negative ("+c+")");d();for(a=q.setToClosestStep(c,l);a<c&&l.nextPosition();)(g=b.acceptPosition(l)===f)&&(a+=1),q.updateCache(a,l,g);if(a!==c)throw new RangeError("Requested steps ("+c+") exceeds available steps ("+a+")");return{node:l.container(),offset:l.unfilteredDomOffset()}}; +this.convertDomPointToSteps=function(c,a,m){var e;d();r.containsNode(g,c)||(a=0>r.comparePoints(g,0,c,a),c=g,a=a?0:g.childNodes.length);l.setUnfilteredPosition(c,a);n(l,m)||l.setUnfilteredPosition(c,a);m=l.container();a=l.unfilteredDomOffset();c=q.setToClosestDomPoint(m,a,l);if(0>r.comparePoints(l.container(),l.unfilteredDomOffset(),m,a))return 0<c?c-1:c;for(;(l.container()!==m||l.unfilteredDomOffset()!==a)&&l.nextPosition();)(e=b.acceptPosition(l)===f)&&(c+=1),q.updateCache(c,l,e);return c+0};this.prime= +function(){var c,a;d();for(c=q.setToClosestStep(0,l);l.nextPosition();)(a=b.acceptPosition(l)===f)&&(c+=1),q.updateCache(c,l,a)};this.handleStepsInserted=function(c){d();q.damageCacheAfterStep(c.position)};this.handleStepsRemoved=function(c){d();q.damageCacheAfterStep(c.position-1)}};ops.StepsTranslator.PREVIOUS_STEP=0;ops.StepsTranslator.NEXT_STEP=1;return ops.StepsTranslator})(); +// Input 43 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1023,21 +1225,10 @@ c=null,e=null,a=null,b={},q={};this.generateStyleName=function(){null===c&&(c=ne @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.Utils");runtime.loadClass("odf.ObjectNameGenerator");runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfContainer");runtime.loadClass("odf.StyleInfo");runtime.loadClass("odf.OdfUtils"); -odf.Formatting=function(){function g(a){return(a=u[a])?v.mergeObjects({},a):{}}function l(a,b,c){for(a=a&&a.firstElementChild;a&&(a.namespaceURI!==b||a.localName!==c);)a=a.nextElementSibling;return a}function f(){for(var a=e.rootElement.fontFaceDecls,c={},d,f,a=a&&a.firstElementChild;a;){if(d=a.getAttributeNS(q,"name"))if((f=a.getAttributeNS(b,"font-family"))||0<a.getElementsByTagNameNS(b,"font-face-uri").length)c[d]=f;a=a.nextElementSibling}return c}function p(a){for(var b=e.rootElement.styles.firstElementChild;b;){if(b.namespaceURI=== -q&&"default-style"===b.localName&&b.getAttributeNS(q,"family")===a)return b;b=b.nextElementSibling}return null}function r(a,b,c){var d,f,h;c=c||[e.rootElement.automaticStyles,e.rootElement.styles];for(h=0;h<c.length;h+=1)for(d=c[h],d=d.firstElementChild;d;){f=d.getAttributeNS(q,"name");if(d.namespaceURI===q&&"style"===d.localName&&d.getAttributeNS(q,"family")===b&&f===a||"list-style"===b&&d.namespaceURI===k&&"list-style"===d.localName&&f===a||"data"===b&&d.namespaceURI===t&&f===a)return d;d=d.nextElementSibling}return null} -function n(a){for(var b,c,d,e,f={},h=a.firstElementChild;h;){if(h.namespaceURI===q)for(d=f[h.nodeName]={},c=h.attributes,b=0;b<c.length;b+=1)e=c.item(b),d[e.name]=e.value;h=h.nextElementSibling}c=a.attributes;for(b=0;b<c.length;b+=1)e=c.item(b),f[e.name]=e.value;return f}function h(a,b){for(var c=e.rootElement.styles,d,f={},h=a.getAttributeNS(q,"family"),k=a;k;)d=n(k),f=v.mergeObjects(d,f),k=(d=k.getAttributeNS(q,"parent-style-name"))?r(d,h,[c]):null;if(k=p(h))d=n(k),f=v.mergeObjects(d,f);b&&(d=g(h))&& -(f=v.mergeObjects(d,f));return f}function d(b,c){function d(a){Object.keys(a).forEach(function(b){Object.keys(a[b]).forEach(function(a){k+="|"+b+":"+a+"|"})})}for(var e=b.nodeType===Node.TEXT_NODE?b.parentNode:b,f,h=[],k="",g=!1;e;)!g&&w.isGroupingElement(e)&&(g=!0),(f=a.determineStylesForNode(e))&&h.push(f),e=e.parentElement;g&&(h.forEach(d),c&&(c[k]=h));return g?h:void 0}function m(a){var b={orderedStyles:[]};a.forEach(function(a){Object.keys(a).forEach(function(c){var d=Object.keys(a[c])[0],e, -f;(e=r(d,c))?(f=h(e),b=v.mergeObjects(f,b),f=e.getAttributeNS(q,"display-name")):runtime.log("No style element found for '"+d+"' of family '"+c+"'");b.orderedStyles.push({name:d,family:c,displayName:f})})});return b}function c(a,b){var c=w.parseLength(a),d=b;if(c)switch(c.unit){case "cm":d=c.value;break;case "mm":d=0.1*c.value;break;case "in":d=2.54*c.value;break;case "pt":d=0.035277778*c.value;break;case "pc":case "px":case "em":break;default:runtime.log("Unit identifier: "+c.unit+" is not supported.")}return d} -var e,a=new odf.StyleInfo,b=odf.Namespaces.svgns,q=odf.Namespaces.stylens,k=odf.Namespaces.textns,t=odf.Namespaces.numberns,A=odf.Namespaces.fons,w=new odf.OdfUtils,x=new core.DomUtils,v=new core.Utils,u={paragraph:{"style:paragraph-properties":{"fo:text-align":"left"}}};this.getSystemDefaultStyleAttributes=g;this.setOdfContainer=function(a){e=a};this.getFontMap=f;this.getAvailableParagraphStyles=function(){for(var a=e.rootElement.styles,b,c,d=[],a=a&&a.firstElementChild;a;)"style"===a.localName&& -a.namespaceURI===q&&(b=a.getAttributeNS(q,"family"),"paragraph"===b&&(b=a.getAttributeNS(q,"name"),c=a.getAttributeNS(q,"display-name")||b,b&&c&&d.push({name:b,displayName:c}))),a=a.nextElementSibling;return d};this.isStyleUsed=function(b){var c,d=e.rootElement;c=a.hasDerivedStyles(d,odf.Namespaces.lookupNamespaceURI,b);b=(new a.UsedStyleList(d.styles)).uses(b)||(new a.UsedStyleList(d.automaticStyles)).uses(b)||(new a.UsedStyleList(d.body)).uses(b);return c||b};this.getDefaultStyleElement=p;this.getStyleElement= -r;this.getStyleAttributes=n;this.getInheritedStyleAttributes=h;this.getFirstCommonParentStyleNameOrSelf=function(a){var b=e.rootElement.automaticStyles,c=e.rootElement.styles,d;for(d=r(a,"paragraph",[b]);d;)a=d.getAttributeNS(q,"parent-style-name"),d=r(a,"paragraph",[b]);return(d=r(a,"paragraph",[c]))?a:null};this.hasParagraphStyle=function(a){return Boolean(r(a,"paragraph"))};this.getAppliedStyles=function(a){var b={},c=[];a.forEach(function(a){d(a,b)});Object.keys(b).forEach(function(a){c.push(m(b[a]))}); -return c};this.getAppliedStylesForElement=function(a){return(a=d(a))?m(a):void 0};this.updateStyle=function(a,c){var d,h;x.mapObjOntoNode(a,c,odf.Namespaces.lookupNamespaceURI);(d=c["style:text-properties"]&&c["style:text-properties"]["style:font-name"])&&!f().hasOwnProperty(d)&&(h=a.ownerDocument.createElementNS(q,"style:font-face"),h.setAttributeNS(q,"style:name",d),h.setAttributeNS(b,"svg:font-family",d),e.rootElement.fontFaceDecls.appendChild(h))};this.createDerivedStyleObject=function(a,b,c){var d= -r(a,b);runtime.assert(Boolean(d),"No style element found for '"+a+"' of family '"+b+"'");a=d.parentNode===e.rootElement.automaticStyles?n(d):{"style:parent-style-name":a};a["style:family"]=b;v.mergeObjects(a,c);return a};this.getDefaultTabStopDistance=function(){for(var a=p("paragraph"),a=a&&a.firstElementChild,b;a;)a.namespaceURI===q&&"paragraph-properties"===a.localName&&(b=a.getAttributeNS(q,"tab-stop-distance")),a=a.nextElementSibling;b||(b="1.25cm");return w.parseNonNegativeLength(b)};this.getContentSize= -function(a,b){var d,f,h,k,g,m,n,p,t,v,u;a:{var w,aa,J;d=r(a,b);runtime.assert("paragraph"===b||"table"===b,"styleFamily has to be either paragraph or table");if(d){w=d.getAttributeNS(q,"master-page-name")||"Standard";for(d=e.rootElement.masterStyles.lastElementChild;d&&d.getAttributeNS(q,"name")!==w;)d=d.previousElementSibling;w=d.getAttributeNS(q,"page-layout-name");aa=x.getElementsByTagNameNS(e.rootElement.automaticStyles,q,"page-layout");for(J=0;J<aa.length;J+=1)if(d=aa[J],d.getAttributeNS(q,"name")=== -w)break a}d=null}d||(d=l(e.rootElement.styles,q,"default-page-layout"));if(d=l(d,q,"page-layout-properties"))f=d.getAttributeNS(q,"print-orientation")||"portrait","portrait"===f?(f=21.001,h=29.7):(f=29.7,h=21.001),f=c(d.getAttributeNS(A,"page-width"),f),h=c(d.getAttributeNS(A,"page-height"),h),k=c(d.getAttributeNS(A,"margin"),null),null===k?(k=c(d.getAttributeNS(A,"margin-left"),2),g=c(d.getAttributeNS(A,"margin-right"),2),m=c(d.getAttributeNS(A,"margin-top"),2),n=c(d.getAttributeNS(A,"margin-bottom"), -2)):k=g=m=n=k,p=c(d.getAttributeNS(A,"padding"),null),null===p?(p=c(d.getAttributeNS(A,"padding-left"),0),t=c(d.getAttributeNS(A,"padding-right"),0),v=c(d.getAttributeNS(A,"padding-top"),0),u=c(d.getAttributeNS(A,"padding-bottom"),0)):p=t=v=u=p;return{width:f-k-g-p-t,height:h-m-n-v-u}}}; -// Input 40 +ops.TextPositionFilter=function(k){function h(d,h,l){var f,c;if(h){if(b.isInlineRoot(h)&&b.isGroupingElement(l))return g;f=b.lookLeftForCharacter(h);if(1===f||2===f&&(b.scanRightForAnyCharacter(l)||b.scanRightForAnyCharacter(b.nextNode(d))))return n}f=null===h&&b.isParagraph(d);c=b.lookRightForCharacter(l);if(f)return c?n:b.scanRightForAnyCharacter(l)?g:n;if(!c)return g;h=h||b.previousNode(d);return b.scanLeftForAnyCharacter(h)?g:n}var b=new odf.OdfUtils,p=Node.ELEMENT_NODE,d=Node.TEXT_NODE,n=core.PositionFilter.FilterResult.FILTER_ACCEPT, +g=core.PositionFilter.FilterResult.FILTER_REJECT;this.acceptPosition=function(q){var r=q.container(),l=r.nodeType,f,c,a;if(l!==p&&l!==d)return g;if(l===d){if(!b.isGroupingElement(r.parentNode)||b.isWithinTrackedChanges(r.parentNode,k()))return g;l=q.unfilteredDomOffset();f=r.data;runtime.assert(l!==f.length,"Unexpected offset.");if(0<l){q=f[l-1];if(!b.isODFWhitespace(q))return n;if(1<l)if(q=f[l-2],!b.isODFWhitespace(q))c=n;else{if(!b.isODFWhitespace(f.substr(0,l)))return g}else a=b.previousNode(r), +b.scanLeftForNonSpace(a)&&(c=n);if(c===n)return b.isTrailingWhitespace(r,l)?g:n;c=f[l];return b.isODFWhitespace(c)?g:b.scanLeftForAnyCharacter(b.previousNode(r))?g:n}a=q.leftNode();c=r;r=r.parentNode;c=h(r,a,c)}else!b.isGroupingElement(r)||b.isWithinTrackedChanges(r,k())?c=g:(a=q.leftNode(),c=q.rightNode(),c=h(r,a,c));return c}}; +// Input 44 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1075,36 +1266,26 @@ w)break a}d=null}d||(d=l(e.rootElement.styles,q,"default-page-layout"));if(d=l(d @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils");runtime.loadClass("odf.OdfContainer");runtime.loadClass("odf.Formatting");runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.FontLoader");runtime.loadClass("odf.Style2CSS");runtime.loadClass("odf.OdfUtils");runtime.loadClass("gui.AnnotationViewManager"); -(function(){function g(){function a(d){c=!0;runtime.setTimeout(function(){try{d()}catch(e){runtime.log(String(e))}c=!1;0<b.length&&a(b.pop())},10)}var b=[],c=!1;this.clearQueue=function(){b.length=0};this.addToQueue=function(d){if(0===b.length&&!c)return a(d);b.push(d)}}function l(a){function b(){for(;0<c.cssRules.length;)c.deleteRule(0);c.insertRule("#shadowContent draw|page {display:none;}",0);c.insertRule("office|presentation draw|page {display:none;}",1);c.insertRule("#shadowContent draw|page:nth-of-type("+ -d+") {display:block;}",2);c.insertRule("office|presentation draw|page:nth-of-type("+d+") {display:block;}",3)}var c=a.sheet,d=1;this.showFirstPage=function(){d=1;b()};this.showNextPage=function(){d+=1;b()};this.showPreviousPage=function(){1<d&&(d-=1,b())};this.showPage=function(a){0<a&&(d=a,b())};this.css=a;this.destroy=function(b){a.parentNode.removeChild(a);b()}}function f(a){for(;a.firstChild;)a.removeChild(a.firstChild)}function p(a,b,c){(new odf.Style2CSS).style2css(a.getDocumentType(),c.sheet, -b.getFontMap(),a.rootElement.styles,a.rootElement.automaticStyles)}function r(a,b,c){var d=null;a=a.rootElement.body.getElementsByTagNameNS(L,c+"-decl");c=b.getAttributeNS(L,"use-"+c+"-name");var e;if(c&&0<a.length)for(b=0;b<a.length;b+=1)if(e=a[b],e.getAttributeNS(L,"name")===c){d=e.textContent;break}return d}function n(a,b,c,d){var e=a.ownerDocument;b=a.getElementsByTagNameNS(b,c);for(a=0;a<b.length;a+=1)f(b[a]),d&&(c=b[a],c.appendChild(e.createTextNode(d)))}function h(a,b,c){b.setAttributeNS("urn:webodf:names:helper", -"styleid",a);var d,e=b.getAttributeNS(H,"anchor-type"),f=b.getAttributeNS(u,"x"),h=b.getAttributeNS(u,"y"),k=b.getAttributeNS(u,"width"),g=b.getAttributeNS(u,"height"),q=b.getAttributeNS(w,"min-height"),m=b.getAttributeNS(w,"min-width");if("as-char"===e)d="display: inline-block;";else if(e||f||h)d="position: absolute;";else if(k||g||q||m)d="display: block;";f&&(d+="left: "+f+";");h&&(d+="top: "+h+";");k&&(d+="width: "+k+";");g&&(d+="height: "+g+";");q&&(d+="min-height: "+q+";");m&&(d+="min-width: "+ -m+";");d&&(d="draw|"+b.localName+'[webodfhelper|styleid="'+a+'"] {'+d+"}",c.insertRule(d,c.cssRules.length))}function d(a){for(a=a.firstChild;a;){if(a.namespaceURI===x&&"binary-data"===a.localName)return"data:image/png;base64,"+a.textContent.replace(/[\r\n\s]/g,"");a=a.nextSibling}return""}function m(a,b,c,e){function f(b){b&&(b='draw|image[webodfhelper|styleid="'+a+'"] {'+("background-image: url("+b+");")+"}",e.insertRule(b,e.cssRules.length))}function h(a){f(a.url)}c.setAttributeNS("urn:webodf:names:helper", -"styleid",a);var k=c.getAttributeNS(y,"href"),g;if(k)try{g=b.getPart(k),g.onchange=h,g.load()}catch(q){runtime.log("slight problem: "+String(q))}else k=d(c),f(k)}function c(a){function b(c){var d,e;c.hasAttributeNS(y,"href")&&(d=c.getAttributeNS(y,"href"),"#"===d[0]?(d=d.substring(1),e=function(){var b=W.getODFElementsWithXPath(a,"//text:bookmark-start[@text:name='"+d+"']",odf.Namespaces.lookupNamespaceURI);0===b.length&&(b=W.getODFElementsWithXPath(a,"//text:bookmark[@text:name='"+d+"']",odf.Namespaces.lookupNamespaceURI)); -0<b.length&&b[0].scrollIntoView(!0);return!1}):e=function(){I.open(d)},c.onclick=e)}var c,d,e;d=a.getElementsByTagNameNS(H,"a");for(c=0;c<d.length;c+=1)e=d.item(c),b(e)}function e(a){var b=a.ownerDocument;z.getElementsByTagNameNS(a,H,"line-break").forEach(function(a){a.hasChildNodes()||a.appendChild(b.createElement("br"))})}function a(a){var b=a.ownerDocument;z.getElementsByTagNameNS(a,H,"s").forEach(function(a){for(var c,d;a.firstChild;)a.removeChild(a.firstChild);a.appendChild(b.createTextNode(" ")); -d=parseInt(a.getAttributeNS(H,"c"),10);if(1<d)for(a.removeAttributeNS(H,"c"),c=1;c<d;c+=1)a.parentNode.insertBefore(a.cloneNode(!0),a)})}function b(a){z.getElementsByTagNameNS(a,H,"tab").forEach(function(a){a.textContent="\t"})}function q(a,b){function c(a,d){var e=g.documentElement.namespaceURI;"video/"===d.substr(0,6)?(f=g.createElementNS(e,"video"),f.setAttribute("controls","controls"),h=g.createElementNS(e,"source"),a&&h.setAttribute("src",a),h.setAttribute("type",d),f.appendChild(h),b.parentNode.appendChild(f)): -b.innerHtml="Unrecognised Plugin"}function e(a){c(a.url,a.mimetype)}var f,h,k,g=b.ownerDocument,q;if(k=b.getAttributeNS(y,"href"))try{q=a.getPart(k),q.onchange=e,q.load()}catch(m){runtime.log("slight problem: "+String(m))}else runtime.log("using MP4 data fallback"),k=d(b),c(k,"video/mp4")}function k(a){var b=a.getElementsByTagName("head")[0],c;"undefined"!==String(typeof webodf_css)?(c=a.createElementNS(b.namespaceURI,"style"),c.setAttribute("media","screen, print, handheld, projection"),c.appendChild(a.createTextNode(webodf_css))): -(c=a.createElementNS(b.namespaceURI,"link"),a="webodf.css",runtime.currentDirectory&&(a=runtime.currentDirectory()+"/../"+a),c.setAttribute("href",a),c.setAttribute("rel","stylesheet"));c.setAttribute("type","text/css");b.appendChild(c);return c}function t(a){var b=a.getElementsByTagName("head")[0],c=a.createElementNS(b.namespaceURI,"style"),d="";c.setAttribute("type","text/css");c.setAttribute("media","screen, print, handheld, projection");odf.Namespaces.forEachPrefix(function(a,b){d+="@namespace "+ -a+" url("+b+");\n"});d+="@namespace webodfhelper url(urn:webodf:names:helper);\n";c.appendChild(a.createTextNode(d));b.appendChild(c);return c}var A=odf.Namespaces.drawns,w=odf.Namespaces.fons,x=odf.Namespaces.officens,v=odf.Namespaces.stylens,u=odf.Namespaces.svgns,s=odf.Namespaces.tablens,H=odf.Namespaces.textns,y=odf.Namespaces.xlinkns,B=odf.Namespaces.xmlns,L=odf.Namespaces.presentationns,I=runtime.getWindow(),W=xmldom.XPath,Q=new odf.OdfUtils,z=new core.DomUtils;odf.OdfCanvas=function(d){function u(a, -b,c){function d(a,b,c,e){E.addToQueue(function(){m(a,b,c,e)})}var e,f;e=b.getElementsByTagNameNS(A,"image");for(b=0;b<e.length;b+=1)f=e.item(b),d("image"+String(b),a,f,c)}function w(a,b){function c(a,b){E.addToQueue(function(){q(a,b)})}var d,e,f;e=b.getElementsByTagNameNS(A,"plugin");for(d=0;d<e.length;d+=1)f=e.item(d),c(a,f)}function y(){M.firstChild&&(1<S?(M.style.MozTransformOrigin="center top",M.style.WebkitTransformOrigin="center top",M.style.OTransformOrigin="center top",M.style.msTransformOrigin= -"center top"):(M.style.MozTransformOrigin="left top",M.style.WebkitTransformOrigin="left top",M.style.OTransformOrigin="left top",M.style.msTransformOrigin="left top"),M.style.WebkitTransform="scale("+S+")",M.style.MozTransform="scale("+S+")",M.style.OTransform="scale("+S+")",M.style.msTransform="scale("+S+")",d.style.width=Math.round(S*M.offsetWidth)+"px",d.style.height=Math.round(S*M.offsetHeight)+"px")}function O(a){function b(a){return d===a.getAttributeNS(x,"name")}var c=z.getElementsByTagNameNS(a, -x,"annotation");a=z.getElementsByTagNameNS(a,x,"annotation-end");var d,e;for(e=0;e<c.length;e+=1)d=c[e].getAttributeNS(x,"name"),ca.addAnnotation({node:c[e],end:a.filter(b)[0]||null});ca.rerenderAnnotations()}function aa(a){la?(ba.parentNode||(M.appendChild(ba),y()),ca&&ca.forgetAnnotations(),ca=new gui.AnnotationViewManager(C,a.body,ba),O(a.body)):ba.parentNode&&(M.removeChild(ba),ca.forgetAnnotations(),y())}function J(k){function g(){f(d);d.style.display="inline-block";var q=U.rootElement;d.ownerDocument.importNode(q, -!0);R.setOdfContainer(U);var m=U,l=T;(new odf.FontLoader).loadFonts(m,l.sheet);p(U,R,$);l=U;m=X.sheet;f(d);M=Y.createElementNS(d.namespaceURI,"div");M.style.display="inline-block";M.style.background="white";M.appendChild(q);d.appendChild(M);ba=Y.createElementNS(d.namespaceURI,"div");ba.id="annotationsPane";da=Y.createElementNS(d.namespaceURI,"div");da.id="shadowContent";da.style.position="absolute";da.style.top=0;da.style.left=0;l.getContentElement().appendChild(da);var t=q.body,z,D=[],C;for(z=t.firstElementChild;z&& -z!==t;)if(z.namespaceURI===A&&(D[D.length]=z),z.firstElementChild)z=z.firstElementChild;else{for(;z&&z!==t&&!z.nextElementSibling;)z=z.parentElement;z&&z.nextElementSibling&&(z=z.nextElementSibling)}for(C=0;C<D.length;C+=1)z=D[C],h("frame"+String(C),z,m);D=W.getODFElementsWithXPath(t,".//*[*[@text:anchor-type='paragraph']]",odf.Namespaces.lookupNamespaceURI);for(z=0;z<D.length;z+=1)t=D[z],t.setAttributeNS&&t.setAttributeNS("urn:webodf:names:helper","containsparagraphanchor",!0);var t=da,O,E,F;F=0; -var J,P,D=l.rootElement.ownerDocument;if((z=q.body.firstElementChild)&&z.namespaceURI===x&&("presentation"===z.localName||"drawing"===z.localName))for(z=z.firstElementChild;z;){C=z.getAttributeNS(A,"master-page-name");if(C){for(O=l.rootElement.masterStyles.firstElementChild;O&&(O.getAttributeNS(v,"name")!==C||"master-page"!==O.localName||O.namespaceURI!==v););C=O}else C=null;if(C){O=z.getAttributeNS("urn:webodf:names:helper","styleid");E=D.createElementNS(A,"draw:page");P=C.firstElementChild;for(J= -0;P;)"true"!==P.getAttributeNS(L,"placeholder")&&(F=P.cloneNode(!0),E.appendChild(F),h(O+"_"+J,F,m)),P=P.nextElementSibling,J+=1;P=J=F=void 0;var V=E.getElementsByTagNameNS(A,"frame");for(F=0;F<V.length;F+=1)J=V[F],(P=J.getAttributeNS(L,"class"))&&!/^(date-time|footer|header|page-number')$/.test(P)&&J.parentNode.removeChild(J);t.appendChild(E);F=String(t.getElementsByTagNameNS(A,"page").length);n(E,H,"page-number",F);n(E,L,"header",r(l,z,"header"));n(E,L,"footer",r(l,z,"footer"));h(O,E,m);E.setAttributeNS(A, -"draw:master-page-name",C.getAttributeNS(v,"name"))}z=z.nextElementSibling}t=d.namespaceURI;D=q.body.getElementsByTagNameNS(s,"table-cell");for(z=0;z<D.length;z+=1)C=D.item(z),C.hasAttributeNS(s,"number-columns-spanned")&&C.setAttributeNS(t,"colspan",C.getAttributeNS(s,"number-columns-spanned")),C.hasAttributeNS(s,"number-rows-spanned")&&C.setAttributeNS(t,"rowspan",C.getAttributeNS(s,"number-rows-spanned"));c(q.body);e(q.body);a(q.body);b(q.body);u(l,q.body,m);w(l,q.body);C=q.body;l=d.namespaceURI; -z={};var D={},K;O=I.document.getElementsByTagNameNS(H,"list-style");for(t=0;t<O.length;t+=1)J=O.item(t),(P=J.getAttributeNS(v,"name"))&&(D[P]=J);C=C.getElementsByTagNameNS(H,"list");for(t=0;t<C.length;t+=1)if(J=C.item(t),O=J.getAttributeNS(B,"id")){E=J.getAttributeNS(H,"continue-list");J.setAttributeNS(l,"id",O);F="text|list#"+O+" > text|list-item > *:first-child:before {";if(P=J.getAttributeNS(H,"style-name")){J=D[P];K=Q.getFirstNonWhitespaceChild(J);J=void 0;if(K)if("list-level-style-number"=== -K.localName){J=K.getAttributeNS(v,"num-format");P=K.getAttributeNS(v,"num-suffix")||"";var V="",V={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},S=void 0,S=K.getAttributeNS(v,"num-prefix")||"",S=V.hasOwnProperty(J)?S+(" counter(list, "+V[J]+")"):J?S+("'"+J+"';"):S+" ''";P&&(S+=" '"+P+"'");J=V="content: "+S+";"}else"list-level-style-image"===K.localName?J="content: none;":"list-level-style-bullet"===K.localName&&(J="content: '"+K.getAttributeNS(H,"bullet-char")+"';"); -K=J}if(E){for(J=z[E];J;)J=z[J];F+="counter-increment:"+E+";";K?(K=K.replace("list",E),F+=K):F+="content:counter("+E+");"}else E="",K?(K=K.replace("list",O),F+=K):F+="content: counter("+O+");",F+="counter-increment:"+O+";",m.insertRule("text|list#"+O+" {counter-reset:"+O+"}",m.cssRules.length);F+="}";z[O]=E;F&&m.insertRule(F,m.cssRules.length)}M.insertBefore(da,M.firstChild);y();aa(q);if(!k&&(q=[U],ga.hasOwnProperty("statereadychange")))for(m=ga.statereadychange,K=0;K<m.length;K+=1)m[K].apply(null, -q)}U.state===odf.OdfContainer.DONE?g():(runtime.log("WARNING: refreshOdf called but ODF was not DONE."),runtime.setTimeout(function ha(){U.state===odf.OdfContainer.DONE?g():(runtime.log("will be back later..."),runtime.setTimeout(ha,500))},100))}function F(a){E.clearQueue();d.innerHTML=runtime.tr("Loading")+" "+a+"...";d.removeAttribute("style");U=new odf.OdfContainer(a,function(a){U=a;J(!1)})}runtime.assert(null!==d&&void 0!==d,"odf.OdfCanvas constructor needs DOM element");runtime.assert(null!== -d.ownerDocument&&void 0!==d.ownerDocument,"odf.OdfCanvas constructor needs DOM");var C=this,Y=d.ownerDocument,U,R=new odf.Formatting,P,M=null,ba=null,la=!1,ca=null,ma,T,$,X,da,S=1,ga={},E=new g;this.refreshCSS=function(){p(U,R,$);y()};this.refreshSize=function(){y()};this.odfContainer=function(){return U};this.setOdfContainer=function(a,b){U=a;J(!0===b)};this.load=this.load=F;this.save=function(a){U.save(a)};this.addListener=function(a,b){switch(a){case "click":var c=d,e=a;c.addEventListener?c.addEventListener(e, -b,!1):c.attachEvent?c.attachEvent("on"+e,b):c["on"+e]=b;break;default:c=ga.hasOwnProperty(a)?ga[a]:ga[a]=[],b&&-1===c.indexOf(b)&&c.push(b)}};this.getFormatting=function(){return R};this.getAnnotationViewManager=function(){return ca};this.refreshAnnotations=function(){aa(U.rootElement)};this.rerenderAnnotations=function(){ca&&ca.rerenderAnnotations()};this.getSizer=function(){return M};this.enableAnnotations=function(a){a!==la&&(la=a,U&&aa(U.rootElement))};this.addAnnotation=function(a){ca&&ca.addAnnotation(a)}; -this.forgetAnnotations=function(){ca&&ca.forgetAnnotations()};this.setZoomLevel=function(a){S=a;y()};this.getZoomLevel=function(){return S};this.fitToContainingElement=function(a,b){var c=d.offsetHeight/S;S=a/(d.offsetWidth/S);b/c<S&&(S=b/c);y()};this.fitToWidth=function(a){S=a/(d.offsetWidth/S);y()};this.fitSmart=function(a,b){var c,e;c=d.offsetWidth/S;e=d.offsetHeight/S;c=a/c;void 0!==b&&b/e<c&&(c=b/e);S=Math.min(1,c);y()};this.fitToHeight=function(a){S=a/(d.offsetHeight/S);y()};this.showFirstPage= -function(){P.showFirstPage()};this.showNextPage=function(){P.showNextPage()};this.showPreviousPage=function(){P.showPreviousPage()};this.showPage=function(a){P.showPage(a);y()};this.getElement=function(){return d};this.addCssForFrameWithImage=function(a){var b=a.getAttributeNS(A,"name"),c=a.firstElementChild;h(b,a,X.sheet);c&&m(b+"img",U,c,X.sheet)};this.destroy=function(a){var b=Y.getElementsByTagName("head")[0];ba&&ba.parentNode&&ba.parentNode.removeChild(ba);M&&(d.removeChild(M),M=null);b.removeChild(ma); -b.removeChild(T);b.removeChild($);b.removeChild(X);P.destroy(a)};ma=k(Y);P=new l(t(Y));T=t(Y);$=t(Y);X=t(Y)}})(); -// Input 41 +ops.OdtDocument=function(k){function h(){var a=k.odfContainer().getContentElement(),c=a&&a.localName;runtime.assert("text"===c,"Unsupported content element type '"+c+"' for OdtDocument");return a}function b(){return c.getDocumentElement().ownerDocument}function p(a){for(;a&&!(a.namespaceURI===odf.Namespaces.officens&&"text"===a.localName||a.namespaceURI===odf.Namespaces.officens&&"annotation"===a.localName);)a=a.parentNode;return a}function d(a){this.acceptPosition=function(c){c=c.container();var b; +b="string"===typeof a?e[a].getNode():a;return p(c)===p(b)?z:x}}function n(a,c,b,e){e=gui.SelectionMover.createPositionIterator(e);var d;1===b.length?d=b[0]:(d=new core.PositionFilterChain,b.forEach(d.addFilter));b=new core.StepIterator(d,e);b.setPosition(a,c);return b}function g(a){var c=gui.SelectionMover.createPositionIterator(h());a=u.convertStepsToDomPoint(a);c.setUnfilteredPosition(a.node,a.offset);return c}function q(c){return a.getParagraphElement(c)}function r(a,c){return k.getFormatting().getStyleElement(a, +c)}function l(a){return r(a,"paragraph")}function f(a,c,b){a=a.childNodes.item(c)||a;return(a=q(a))&&m.containsNode(b,a)?a:b}var c=this,a,m,e={},t={},w=new core.EventNotifier([ops.Document.signalMemberAdded,ops.Document.signalMemberUpdated,ops.Document.signalMemberRemoved,ops.Document.signalCursorAdded,ops.Document.signalCursorRemoved,ops.Document.signalCursorMoved,ops.OdtDocument.signalParagraphChanged,ops.OdtDocument.signalParagraphStyleModified,ops.OdtDocument.signalCommonStyleCreated,ops.OdtDocument.signalCommonStyleDeleted, +ops.OdtDocument.signalTableAdded,ops.OdtDocument.signalOperationStart,ops.OdtDocument.signalOperationEnd,ops.OdtDocument.signalProcessingBatchStart,ops.OdtDocument.signalProcessingBatchEnd,ops.OdtDocument.signalUndoStackChanged,ops.OdtDocument.signalStepsInserted,ops.OdtDocument.signalStepsRemoved]),z=core.PositionFilter.FilterResult.FILTER_ACCEPT,x=core.PositionFilter.FilterResult.FILTER_REJECT,v,u,s;this.getDocumentElement=function(){return k.odfContainer().rootElement};this.getDOMDocument=function(){return this.getDocumentElement().ownerDocument}; +this.cloneDocumentElement=function(){var a=c.getDocumentElement(),b=k.getAnnotationViewManager();b&&b.forgetAnnotations();a=a.cloneNode(!0);k.refreshAnnotations();return a};this.setDocumentElement=function(a){var c=k.odfContainer();c.setRootElement(a);k.setOdfContainer(c,!0);k.refreshCSS()};this.getDOMDocument=b;this.getRootElement=p;this.createStepIterator=n;this.getIteratorAtPosition=g;this.convertDomPointToCursorStep=function(a,c,b){return u.convertDomPointToSteps(a,c,b)};this.convertDomToCursorRange= +function(a,c){var b,e;b=c&&c(a.anchorNode,a.anchorOffset);b=u.convertDomPointToSteps(a.anchorNode,a.anchorOffset,b);c||a.anchorNode!==a.focusNode||a.anchorOffset!==a.focusOffset?(e=c&&c(a.focusNode,a.focusOffset),e=u.convertDomPointToSteps(a.focusNode,a.focusOffset,e)):e=b;return{position:b,length:e-b}};this.convertCursorToDomRange=function(a,c){var e=b().createRange(),d,f;d=u.convertStepsToDomPoint(a);c?(f=u.convertStepsToDomPoint(a+c),0<c?(e.setStart(d.node,d.offset),e.setEnd(f.node,f.offset)): +(e.setStart(f.node,f.offset),e.setEnd(d.node,d.offset))):e.setStart(d.node,d.offset);return e};this.getStyleElement=r;this.upgradeWhitespacesAtPosition=function(c){c=g(c);var b,e,d;c.previousPosition();c.previousPosition();for(d=-1;1>=d;d+=1){b=c.container();e=c.unfilteredDomOffset();if(b.nodeType===Node.TEXT_NODE&&" "===b.data[e]&&a.isSignificantWhitespace(b,e)){runtime.assert(" "===b.data[e],"upgradeWhitespaceToElement: textNode.data[offset] should be a literal space");var f=b.ownerDocument.createElementNS(odf.Namespaces.textns, +"text:s"),m=b.parentNode,l=b;f.appendChild(b.ownerDocument.createTextNode(" "));1===b.length?m.replaceChild(f,b):(b.deleteData(e,1),0<e&&(e<b.length&&b.splitText(e),l=b.nextSibling),m.insertBefore(f,l));b=f;c.moveToEndOfNode(b)}c.nextPosition()}};this.downgradeWhitespacesAtPosition=function(c){var b=g(c),e;c=b.container();for(b=b.unfilteredDomOffset();!a.isSpaceElement(c)&&c.childNodes.item(b);)c=c.childNodes.item(b),b=0;c.nodeType===Node.TEXT_NODE&&(c=c.parentNode);a.isDowngradableSpaceElement(c)&& +(b=c.firstChild,e=c.lastChild,m.mergeIntoParent(c),e!==b&&m.normalizeTextNodes(e),m.normalizeTextNodes(b))};this.getParagraphStyleElement=l;this.getParagraphElement=q;this.getParagraphStyleAttributes=function(a){return(a=l(a))?k.getFormatting().getInheritedStyleAttributes(a,!1):null};this.getTextNodeAtStep=function(a,d){var f=g(a),m=f.container(),l,h=0,k=null;m.nodeType===Node.TEXT_NODE?(l=m,h=f.unfilteredDomOffset(),0<l.length&&(0<h&&(l=l.splitText(h)),l.parentNode.insertBefore(b().createTextNode(""), +l),l=l.previousSibling,h=0)):(l=b().createTextNode(""),h=0,m.insertBefore(l,f.rightNode()));if(d){if(e[d]&&c.getCursorPosition(d)===a){for(k=e[d].getNode();k.nextSibling&&"cursor"===k.nextSibling.localName;)k.parentNode.insertBefore(k.nextSibling,k);0<l.length&&l.nextSibling!==k&&(l=b().createTextNode(""),h=0);k.parentNode.insertBefore(l,k)}}else for(;l.nextSibling&&"cursor"===l.nextSibling.localName;)l.parentNode.insertBefore(l.nextSibling,l);for(;l.previousSibling&&l.previousSibling.nodeType=== +Node.TEXT_NODE;)f=l.previousSibling,f.appendData(l.data),h=f.length,l=f,l.parentNode.removeChild(l.nextSibling);for(;l.nextSibling&&l.nextSibling.nodeType===Node.TEXT_NODE;)f=l.nextSibling,l.appendData(f.data),l.parentNode.removeChild(f);return{textNode:l,offset:h}};this.fixCursorPositions=function(){Object.keys(e).forEach(function(a){var b=e[a],d=p(b.getNode()),g=c.createRootFilter(d),m,l,h,k=!1;h=b.getSelectedRange();m=f(h.startContainer,h.startOffset,d);l=n(h.startContainer,h.startOffset,[v,g], +m);h.collapsed?d=l:(m=f(h.endContainer,h.endOffset,d),d=n(h.endContainer,h.endOffset,[v,g],m));l.isStep()&&d.isStep()?l.container()!==d.container()||l.offset()!==d.offset()||h.collapsed&&b.getAnchorNode()===b.getNode()||(k=!0,h.setStart(l.container(),l.offset()),h.collapse(!0)):(k=!0,runtime.assert(l.roundToClosestStep(),"No walkable step found for cursor owned by "+a),h.setStart(l.container(),l.offset()),runtime.assert(d.roundToClosestStep(),"No walkable step found for cursor owned by "+a),h.setEnd(d.container(), +d.offset()));k&&(b.setSelectedRange(h,b.hasForwardSelection()),c.emit(ops.Document.signalCursorMoved,b))})};this.getCursorPosition=function(a){return(a=e[a])?u.convertDomPointToSteps(a.getNode(),0):0};this.getCursorSelection=function(a){a=e[a];var c=0,b=0;a&&(c=u.convertDomPointToSteps(a.getNode(),0),b=u.convertDomPointToSteps(a.getAnchorNode(),0));return{position:b,length:c-b}};this.getPositionFilter=function(){return v};this.getOdfCanvas=function(){return k};this.getCanvas=function(){return k}; +this.getRootNode=h;this.addMember=function(a){runtime.assert(void 0===t[a.getMemberId()],"This member already exists");t[a.getMemberId()]=a};this.getMember=function(a){return t.hasOwnProperty(a)?t[a]:null};this.removeMember=function(a){delete t[a]};this.getCursor=function(a){return e[a]};this.getMemberIds=function(){var a=[],c;for(c in e)e.hasOwnProperty(c)&&a.push(e[c].getMemberId());return a};this.addCursor=function(a){runtime.assert(Boolean(a),"OdtDocument::addCursor without cursor");var b=a.getMemberId(), +d=c.convertCursorToDomRange(0,0);runtime.assert("string"===typeof b,"OdtDocument::addCursor has cursor without memberid");runtime.assert(!e[b],"OdtDocument::addCursor is adding a duplicate cursor with memberid "+b);a.setSelectedRange(d,!0);e[b]=a};this.removeCursor=function(a){var b=e[a];return b?(b.removeFromDocument(),delete e[a],c.emit(ops.Document.signalCursorRemoved,a),!0):!1};this.moveCursor=function(a,b,d,f){a=e[a];b=c.convertCursorToDomRange(b,d);a&&(a.setSelectedRange(b,0<=d),a.setSelectionType(f|| +ops.OdtCursor.RangeSelection))};this.getFormatting=function(){return k.getFormatting()};this.emit=function(a,c){w.emit(a,c)};this.subscribe=function(a,c){w.subscribe(a,c)};this.unsubscribe=function(a,c){w.unsubscribe(a,c)};this.createRootFilter=function(a){return new d(a)};this.close=function(a){a()};this.destroy=function(a){a()};v=new ops.TextPositionFilter(h);a=new odf.OdfUtils;m=new core.DomUtils;u=new ops.StepsTranslator(h,gui.SelectionMover.createPositionIterator,v,500);w.subscribe(ops.OdtDocument.signalStepsInserted, +u.handleStepsInserted);w.subscribe(ops.OdtDocument.signalStepsRemoved,u.handleStepsRemoved);w.subscribe(ops.OdtDocument.signalOperationEnd,function(a){var b=a.spec(),e=b.memberid,b=(new Date(b.timestamp)).toISOString(),d=k.odfContainer();a.isEdit&&(e=c.getMember(e).getProperties().fullName,d.setMetadata({"dc:creator":e,"dc:date":b},null),s||(d.incrementEditingCycles(),d.setMetadata(null,["meta:editing-duration","meta:document-statistic"])),s=a)})};ops.OdtDocument.signalParagraphChanged="paragraph/changed"; +ops.OdtDocument.signalTableAdded="table/added";ops.OdtDocument.signalCommonStyleCreated="style/created";ops.OdtDocument.signalCommonStyleDeleted="style/deleted";ops.OdtDocument.signalParagraphStyleModified="paragraphstyle/modified";ops.OdtDocument.signalOperationStart="operation/start";ops.OdtDocument.signalOperationEnd="operation/end";ops.OdtDocument.signalProcessingBatchStart="router/batchstart";ops.OdtDocument.signalProcessingBatchEnd="router/batchend";ops.OdtDocument.signalUndoStackChanged="undo/changed"; +ops.OdtDocument.signalStepsInserted="steps/inserted";ops.OdtDocument.signalStepsRemoved="steps/removed";(function(){return ops.OdtDocument})(); +// Input 45 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1142,12 +1323,11 @@ b.removeChild(T);b.removeChild($);b.removeChild(X);P.destroy(a)};ma=k(Y);P=new l @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils");runtime.loadClass("core.LoopWatchDog");runtime.loadClass("odf.Namespaces"); -odf.TextStyleApplicator=function(g,l,f){function p(c){function d(a,b){return"object"===typeof a&&"object"===typeof b?Object.keys(a).every(function(c){return d(a[c],b[c])}):a===b}this.isStyleApplied=function(a){a=l.getAppliedStylesForElement(a);return d(c,a)}}function r(c){var e={};this.applyStyleToContainer=function(a){var b;b=a.getAttributeNS(d,"style-name");var h=a.ownerDocument;b=b||"";if(!e.hasOwnProperty(b)){var k=b,n;n=b?l.createDerivedStyleObject(b,"text",c):c;h=h.createElementNS(m,"style:style"); -l.updateStyle(h,n);h.setAttributeNS(m,"style:name",g.generateStyleName());h.setAttributeNS(m,"style:family","text");h.setAttributeNS("urn:webodf:names:scope","scope","document-content");f.appendChild(h);e[k]=h}b=e[b].getAttributeNS(m,"name");a.setAttributeNS(d,"text:style-name",b)}}function n(c,e){var a=c.ownerDocument,b=c.parentNode,f,k,g=new core.LoopWatchDog(1E4);k=[];"span"!==b.localName||b.namespaceURI!==d?(f=a.createElementNS(d,"text:span"),b.insertBefore(f,c),b=!1):(c.previousSibling&&!h.rangeContainsNode(e, -b.firstChild)?(f=b.cloneNode(!1),b.parentNode.insertBefore(f,b.nextSibling)):f=b,b=!0);k.push(c);for(a=c.nextSibling;a&&h.rangeContainsNode(e,a);)g.check(),k.push(a),a=a.nextSibling;k.forEach(function(a){a.parentNode!==f&&f.appendChild(a)});if(a&&b)for(k=f.cloneNode(!1),f.parentNode.insertBefore(k,f.nextSibling);a;)g.check(),b=a.nextSibling,k.appendChild(a),a=b;return f}var h=new core.DomUtils,d=odf.Namespaces.textns,m=odf.Namespaces.stylens;this.applyStyle=function(c,d,a){var b={},f,h,g,m;runtime.assert(a&& -a.hasOwnProperty("style:text-properties"),"applyStyle without any text properties");b["style:text-properties"]=a["style:text-properties"];g=new r(b);m=new p(b);c.forEach(function(a){f=m.isStyleApplied(a);!1===f&&(h=n(a,d),g.applyStyleToContainer(h))})}}; -// Input 42 +ops.OpAddAnnotation=function(){function k(b,d,g){var f=b.getTextNodeAtStep(g,h);f&&(b=f.textNode,g=b.parentNode,f.offset!==b.length&&b.splitText(f.offset),g.insertBefore(d,b.nextSibling),0===b.length&&g.removeChild(b))}var h,b,p,d,n,g;this.init=function(g){h=g.memberid;b=parseInt(g.timestamp,10);p=parseInt(g.position,10);d=parseInt(g.length,10)||0;n=g.name};this.isEdit=!0;this.group=void 0;this.execute=function(q){var r=q.getCursor(h),l,f;f=new core.DomUtils;g=q.getDOMDocument();var c=new Date(b), +a,m,e,t;a=g.createElementNS(odf.Namespaces.officens,"office:annotation");a.setAttributeNS(odf.Namespaces.officens,"office:name",n);l=g.createElementNS(odf.Namespaces.dcns,"dc:creator");l.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",h);l.textContent=q.getMember(h).getProperties().fullName;m=g.createElementNS(odf.Namespaces.dcns,"dc:date");m.appendChild(g.createTextNode(c.toISOString()));c=g.createElementNS(odf.Namespaces.textns,"text:list");e=g.createElementNS(odf.Namespaces.textns, +"text:list-item");t=g.createElementNS(odf.Namespaces.textns,"text:p");e.appendChild(t);c.appendChild(e);a.appendChild(l);a.appendChild(m);a.appendChild(c);d&&(l=g.createElementNS(odf.Namespaces.officens,"office:annotation-end"),l.setAttributeNS(odf.Namespaces.officens,"office:name",n),a.annotationEndElement=l,k(q,l,p+d));k(q,a,p);q.emit(ops.OdtDocument.signalStepsInserted,{position:p,length:d});r&&(l=g.createRange(),f=f.getElementsByTagNameNS(a,odf.Namespaces.textns,"p")[0],l.selectNodeContents(f), +r.setSelectedRange(l,!1),q.emit(ops.Document.signalCursorMoved,r));q.getOdfCanvas().addAnnotation(a);q.fixCursorPositions();return!0};this.spec=function(){return{optype:"AddAnnotation",memberid:h,timestamp:b,position:p,length:d,name:n}}}; +// Input 46 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1185,36 +1365,8 @@ a.hasOwnProperty("style:text-properties"),"applyStyle without any text propertie @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfUtils"); -gui.StyleHelper=function(g){function l(f,h,d){var g=!0,c;for(c=0;c<f.length&&!(g=f[c]["style:text-properties"],g=!g||g[h]!==d);c+=1);return!g}function f(f,h,d){function m(){b=!0;(e=g.getDefaultStyleElement("paragraph"))||(e=null)}var c,e;f=p.getParagraphElements(f);for(var a={},b=!1;0<f.length;){(c=f[0].getAttributeNS(r,"style-name"))?a[c]||(e=g.getStyleElement(c,"paragraph"),a[c]=!0,e||b||m()):b?e=void 0:m();if(void 0!==e&&(c=null===e?g.getSystemDefaultStyleAttributes("paragraph"):g.getInheritedStyleAttributes(e, -!0),(c=c["style:paragraph-properties"])&&-1===d.indexOf(c[h])))return!1;f.pop()}return!0}var p=new odf.OdfUtils,r=odf.Namespaces.textns;this.getAppliedStyles=function(f){var h;f.collapsed?(h=f.startContainer,h.hasChildNodes()&&f.startOffset<h.childNodes.length&&(h=h.childNodes.item(f.startOffset)),f=[h]):f=p.getTextNodes(f,!0);return g.getAppliedStyles(f)};this.isBold=function(f){return l(f,"fo:font-weight","bold")};this.isItalic=function(f){return l(f,"fo:font-style","italic")};this.hasUnderline= -function(f){return l(f,"style:text-underline-style","solid")};this.hasStrikeThrough=function(f){return l(f,"style:text-line-through-style","solid")};this.isAlignedLeft=function(g){return f(g,"fo:text-align",["left","start"])};this.isAlignedCenter=function(g){return f(g,"fo:text-align",["center"])};this.isAlignedRight=function(g){return f(g,"fo:text-align",["right","end"])};this.isAlignedJustified=function(g){return f(g,"fo:text-align",["justify"])}}; -// Input 43 -core.RawDeflate=function(){function g(){this.dl=this.fc=0}function l(){this.extra_bits=this.static_tree=this.dyn_tree=null;this.max_code=this.max_length=this.elems=this.extra_base=0}function f(a,b,c,d){this.good_length=a;this.max_lazy=b;this.nice_length=c;this.max_chain=d}function p(){this.next=null;this.len=0;this.ptr=[];this.ptr.length=r;this.off=0}var r=8192,n,h,d,m,c=null,e,a,b,q,k,t,A,w,x,v,u,s,H,y,B,L,I,W,Q,z,ja,ka,G,Z,O,aa,J,F,C,Y,U,R,P,M,ba,la,ca,ma,T,$,X,da,S,ga,E,fa,D,pa,ha,ia,Da,N=[0,0, -0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],qa=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],sa=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],xa=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],ra;ra=[new f(0,0,0,0),new f(4,4,8,4),new f(4,5,16,8),new f(4,6,32,32),new f(4,4,16,16),new f(8,16,32,32),new f(8,16,128,128),new f(8,32,128,256),new f(32,128,258,1024),new f(32,258,258,4096)];var Aa=function(b){c[a+e++]=b;if(a+e===r){var f;if(0!==e){null!==n?(b=n,n=n.next):b=new p; -b.next=null;b.len=b.off=0;null===h?h=d=b:d=d.next=b;b.len=e-a;for(f=0;f<b.len;f++)b.ptr[f]=c[a+f];e=a=0}}},ta=function(b){b&=65535;a+e<r-2?(c[a+e++]=b&255,c[a+e++]=b>>>8):(Aa(b&255),Aa(b>>>8))},Ba=function(){u=(u<<5^q[I+3-1]&255)&8191;s=A[32768+u];A[I&32767]=s;A[32768+u]=I},V=function(a,b){x>16-b?(w|=a<<x,ta(w),w=a>>16-x,x+=b-16):(w|=a<<x,x+=b)},K=function(a,b){V(b[a].fc,b[a].dl)},ua=function(a,b,c){return a[b].fc<a[c].fc||a[b].fc===a[c].fc&&ca[b]<=ca[c]},na=function(a,b,c){var d;for(d=0;d<c&&Da< -ia.length;d++)a[b+d]=ia.charCodeAt(Da++)&255;return d},ea=function(){var a,b,c=65536-z-I;if(-1===c)c--;else if(65274<=I){for(a=0;32768>a;a++)q[a]=q[a+32768];W-=32768;I-=32768;v-=32768;for(a=0;8192>a;a++)b=A[32768+a],A[32768+a]=32768<=b?b-32768:0;for(a=0;32768>a;a++)b=A[a],A[a]=32768<=b?b-32768:0;c+=32768}Q||(a=na(q,I+z,c),0>=a?Q=!0:z+=a)},oa=function(a){var b=ja,c=I,d,e=L,f=32506<I?I-32506:0,h=I+258,k=q[c+e-1],g=q[c+e];L>=Z&&(b>>=2);do if(d=a,q[d+e]===g&&q[d+e-1]===k&&q[d]===q[c]&&q[++d]===q[c+1]){c+= -2;d++;do++c;while(q[c]===q[++d]&&q[++c]===q[++d]&&q[++c]===q[++d]&&q[++c]===q[++d]&&q[++c]===q[++d]&&q[++c]===q[++d]&&q[++c]===q[++d]&&q[++c]===q[++d]&&c<h);d=258-(h-c);c=h-258;if(d>e){W=a;e=d;if(258<=d)break;k=q[c+e-1];g=q[c+e]}a=A[a&32767]}while(a>f&&0!==--b);return e},Ca=function(a,b){t[S++]=b;0===a?O[b].fc++:(a--,O[ma[b]+256+1].fc++,aa[(256>a?T[a]:T[256+(a>>7)])&255].fc++,k[ga++]=a,fa|=D);D<<=1;0===(S&7)&&(da[E++]=fa,fa=0,D=1);if(2<G&&0===(S&4095)){var c=8*S,d=I-v,e;for(e=0;30>e;e++)c+=aa[e].fc* -(5+qa[e]);c>>=3;if(ga<parseInt(S/2,10)&&c<parseInt(d/2,10))return!0}return 8191===S||8192===ga},ya=function(a,b){for(var c=M[b],d=b<<1;d<=ba;){d<ba&&ua(a,M[d+1],M[d])&&d++;if(ua(a,c,M[d]))break;M[b]=M[d];b=d;d<<=1}M[b]=c},Ea=function(a,b){var c=0;do c|=a&1,a>>=1,c<<=1;while(0<--b);return c>>1},za=function(a,b){var c=[];c.length=16;var d=0,e;for(e=1;15>=e;e++)d=d+P[e-1]<<1,c[e]=d;for(d=0;d<=b;d++)e=a[d].dl,0!==e&&(a[d].fc=Ea(c[e]++,e))},va=function(a){var b=a.dyn_tree,c=a.static_tree,d=a.elems,e,f= --1,h=d;ba=0;la=573;for(e=0;e<d;e++)0!==b[e].fc?(M[++ba]=f=e,ca[e]=0):b[e].dl=0;for(;2>ba;)e=M[++ba]=2>f?++f:0,b[e].fc=1,ca[e]=0,pa--,null!==c&&(ha-=c[e].dl);a.max_code=f;for(e=ba>>1;1<=e;e--)ya(b,e);do e=M[1],M[1]=M[ba--],ya(b,1),c=M[1],M[--la]=e,M[--la]=c,b[h].fc=b[e].fc+b[c].fc,ca[h]=ca[e]>ca[c]+1?ca[e]:ca[c]+1,b[e].dl=b[c].dl=h,M[1]=h++,ya(b,1);while(2<=ba);M[--la]=M[1];h=a.dyn_tree;e=a.extra_bits;var d=a.extra_base,c=a.max_code,k=a.max_length,g=a.static_tree,q,m,l,p,n=0;for(m=0;15>=m;m++)P[m]= -0;h[M[la]].dl=0;for(a=la+1;573>a;a++)q=M[a],m=h[h[q].dl].dl+1,m>k&&(m=k,n++),h[q].dl=m,q>c||(P[m]++,l=0,q>=d&&(l=e[q-d]),p=h[q].fc,pa+=p*(m+l),null!==g&&(ha+=p*(g[q].dl+l)));if(0!==n){do{for(m=k-1;0===P[m];)m--;P[m]--;P[m+1]+=2;P[k]--;n-=2}while(0<n);for(m=k;0!==m;m--)for(q=P[m];0!==q;)e=M[--a],e>c||(h[e].dl!==m&&(pa+=(m-h[e].dl)*h[e].fc,h[e].fc=m),q--)}za(b,f)},Fa=function(a,b){var c,d=-1,e,f=a[0].dl,h=0,k=7,g=4;0===f&&(k=138,g=3);a[b+1].dl=65535;for(c=0;c<=b;c++)e=f,f=a[c+1].dl,++h<k&&e===f||(h< -g?C[e].fc+=h:0!==e?(e!==d&&C[e].fc++,C[16].fc++):10>=h?C[17].fc++:C[18].fc++,h=0,d=e,0===f?(k=138,g=3):e===f?(k=6,g=3):(k=7,g=4))},wa=function(){8<x?ta(w):0<x&&Aa(w);x=w=0},Ha=function(a,b){var c,d=0,e=0,f=0,h=0,g,q;if(0!==S){do 0===(d&7)&&(h=da[f++]),c=t[d++]&255,0===(h&1)?K(c,a):(g=ma[c],K(g+256+1,a),q=N[g],0!==q&&(c-=$[g],V(c,q)),c=k[e++],g=(256>c?T[c]:T[256+(c>>7)])&255,K(g,b),q=qa[g],0!==q&&(c-=X[g],V(c,q))),h>>=1;while(d<S)}K(256,a)},Ia=function(a,b){var c,d=-1,e,f=a[0].dl,h=0,k=7,g=4;0===f&& -(k=138,g=3);for(c=0;c<=b;c++)if(e=f,f=a[c+1].dl,!(++h<k&&e===f)){if(h<g){do K(e,C);while(0!==--h)}else 0!==e?(e!==d&&(K(e,C),h--),K(16,C),V(h-3,2)):10>=h?(K(17,C),V(h-3,3)):(K(18,C),V(h-11,7));h=0;d=e;0===f?(k=138,g=3):e===f?(k=6,g=3):(k=7,g=4)}},Ja=function(){var a;for(a=0;286>a;a++)O[a].fc=0;for(a=0;30>a;a++)aa[a].fc=0;for(a=0;19>a;a++)C[a].fc=0;O[256].fc=1;fa=S=ga=E=pa=ha=0;D=1},Ga=function(a){var b,c,d,e;e=I-v;da[E]=fa;va(Y);va(U);Fa(O,Y.max_code);Fa(aa,U.max_code);va(R);for(d=18;3<=d&&0===C[xa[d]].dl;d--); -pa+=3*(d+1)+14;b=pa+3+7>>3;c=ha+3+7>>3;c<=b&&(b=c);if(e+4<=b&&0<=v)for(V(0+a,3),wa(),ta(e),ta(~e),d=0;d<e;d++)Aa(q[v+d]);else if(c===b)V(2+a,3),Ha(J,F);else{V(4+a,3);e=Y.max_code+1;b=U.max_code+1;d+=1;V(e-257,5);V(b-1,5);V(d-4,4);for(c=0;c<d;c++)V(C[xa[c]].dl,3);Ia(O,e-1);Ia(aa,b-1);Ha(O,aa)}Ja();0!==a&&wa()},Ka=function(b,d,f){var k,g,q;for(k=0;null!==h&&k<f;){g=f-k;g>h.len&&(g=h.len);for(q=0;q<g;q++)b[d+k+q]=h.ptr[h.off+q];h.off+=g;h.len-=g;k+=g;0===h.len&&(g=h,h=h.next,g.next=n,n=g)}if(k===f)return k; -if(a<e){g=f-k;g>e-a&&(g=e-a);for(q=0;q<g;q++)b[d+k+q]=c[a+q];a+=g;k+=g;e===a&&(e=a=0)}return k},La=function(c,d,f){var k;if(!m){if(!Q){x=w=0;var g,l;if(0===F[0].dl){Y.dyn_tree=O;Y.static_tree=J;Y.extra_bits=N;Y.extra_base=257;Y.elems=286;Y.max_length=15;Y.max_code=0;U.dyn_tree=aa;U.static_tree=F;U.extra_bits=qa;U.extra_base=0;U.elems=30;U.max_length=15;U.max_code=0;R.dyn_tree=C;R.static_tree=null;R.extra_bits=sa;R.extra_base=0;R.elems=19;R.max_length=7;for(l=g=R.max_code=0;28>l;l++)for($[l]=g,k=0;k< -1<<N[l];k++)ma[g++]=l;ma[g-1]=l;for(l=g=0;16>l;l++)for(X[l]=g,k=0;k<1<<qa[l];k++)T[g++]=l;for(g>>=7;30>l;l++)for(X[l]=g<<7,k=0;k<1<<qa[l]-7;k++)T[256+g++]=l;for(k=0;15>=k;k++)P[k]=0;for(k=0;143>=k;)J[k++].dl=8,P[8]++;for(;255>=k;)J[k++].dl=9,P[9]++;for(;279>=k;)J[k++].dl=7,P[7]++;for(;287>=k;)J[k++].dl=8,P[8]++;za(J,287);for(k=0;30>k;k++)F[k].dl=5,F[k].fc=Ea(k,5);Ja()}for(k=0;8192>k;k++)A[32768+k]=0;ka=ra[G].max_lazy;Z=ra[G].good_length;ja=ra[G].max_chain;v=I=0;z=na(q,0,65536);if(0>=z)Q=!0,z=0;else{for(Q= -!1;262>z&&!Q;)ea();for(k=u=0;2>k;k++)u=(u<<5^q[k]&255)&8191}h=null;a=e=0;3>=G?(L=2,B=0):(B=2,y=0);b=!1}m=!0;if(0===z)return b=!0,0}k=Ka(c,d,f);if(k===f)return f;if(b)return k;if(3>=G)for(;0!==z&&null===h;){Ba();0!==s&&32506>=I-s&&(B=oa(s),B>z&&(B=z));if(3<=B)if(l=Ca(I-W,B-3),z-=B,B<=ka){B--;do I++,Ba();while(0!==--B);I++}else I+=B,B=0,u=q[I]&255,u=(u<<5^q[I+1]&255)&8191;else l=Ca(0,q[I]&255),z--,I++;l&&(Ga(0),v=I);for(;262>z&&!Q;)ea()}else for(;0!==z&&null===h;){Ba();L=B;H=W;B=2;0!==s&&L<ka&&32506>= -I-s&&(B=oa(s),B>z&&(B=z),3===B&&4096<I-W&&B--);if(3<=L&&B<=L){l=Ca(I-1-H,L-3);z-=L-1;L-=2;do I++,Ba();while(0!==--L);y=0;B=2;I++;l&&(Ga(0),v=I)}else 0!==y?Ca(0,q[I-1]&255)&&(Ga(0),v=I):y=1,I++,z--;for(;262>z&&!Q;)ea()}0===z&&(0!==y&&Ca(0,q[I-1]&255),Ga(1),b=!0);return k+Ka(c,k+d,f-k)};this.deflate=function(a,b){var e,f;ia=a;Da=0;"undefined"===String(typeof b)&&(b=6);(e=b)?1>e?e=1:9<e&&(e=9):e=6;G=e;Q=m=!1;if(null===c){n=h=d=null;c=[];c.length=r;q=[];q.length=65536;k=[];k.length=8192;t=[];t.length= -32832;A=[];A.length=65536;O=[];O.length=573;for(e=0;573>e;e++)O[e]=new g;aa=[];aa.length=61;for(e=0;61>e;e++)aa[e]=new g;J=[];J.length=288;for(e=0;288>e;e++)J[e]=new g;F=[];F.length=30;for(e=0;30>e;e++)F[e]=new g;C=[];C.length=39;for(e=0;39>e;e++)C[e]=new g;Y=new l;U=new l;R=new l;P=[];P.length=16;M=[];M.length=573;ca=[];ca.length=573;ma=[];ma.length=256;T=[];T.length=512;$=[];$.length=29;X=[];X.length=30;da=[];da.length=1024}var p=Array(1024),v=[],s=[];for(e=La(p,0,p.length);0<e;){s.length=e;for(f= -0;f<e;f++)s[f]=String.fromCharCode(p[f]);v[v.length]=s.join("");e=La(p,0,p.length)}ia="";return v.join("")}}; -// Input 44 -runtime.loadClass("odf.Namespaces"); -gui.ImageSelector=function(g){function l(){var f=g.getSizer(),d,m;d=r.createElement("div");d.id="imageSelector";d.style.borderWidth="1px";f.appendChild(d);p.forEach(function(c){m=r.createElement("div");m.className=c;d.appendChild(m)});return d}var f=odf.Namespaces.svgns,p="topLeft topRight bottomRight bottomLeft topMiddle rightMiddle bottomMiddle leftMiddle".split(" "),r=g.getElement().ownerDocument,n=!1;this.select=function(h){var d,m,c=r.getElementById("imageSelector");c||(c=l());n=!0;d=c.parentNode; -m=h.getBoundingClientRect();var e=d.getBoundingClientRect(),a=g.getZoomLevel();d=(m.left-e.left)/a-1;m=(m.top-e.top)/a-1;c.style.display="block";c.style.left=d+"px";c.style.top=m+"px";c.style.width=h.getAttributeNS(f,"width");c.style.height=h.getAttributeNS(f,"height")};this.clearSelection=function(){var f;n&&(f=r.getElementById("imageSelector"))&&(f.style.display="none");n=!1};this.isSelectorElement=function(f){var d=r.getElementById("imageSelector");return d?f===d||f.parentNode===d:!1}}; -// Input 45 -runtime.loadClass("odf.OdfCanvas"); -odf.CommandLineTools=function(){this.roundTrip=function(g,l,f){return new odf.OdfContainer(g,function(p){if(p.state===odf.OdfContainer.INVALID)return f("Document "+g+" is invalid.");p.state===odf.OdfContainer.DONE?p.saveAs(l,function(g){f(g)}):f("Document was not completely loaded.")})};this.render=function(g,l,f){for(l=l.getElementsByTagName("body")[0];l.firstChild;)l.removeChild(l.firstChild);l=new odf.OdfCanvas(l);l.addListener("statereadychange",function(g){f(g)});l.load(g)}}; -// Input 46 +ops.OpAddCursor=function(){var k,h;this.init=function(b){k=b.memberid;h=b.timestamp};this.isEdit=!1;this.group=void 0;this.execute=function(b){var h=b.getCursor(k);if(h)return!1;h=new ops.OdtCursor(k,b);b.addCursor(h);b.emit(ops.Document.signalCursorAdded,h);return!0};this.spec=function(){return{optype:"AddCursor",memberid:k,timestamp:h}}}; +// Input 47 /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -1239,9 +1391,8 @@ odf.CommandLineTools=function(){this.roundTrip=function(g,l,f){return new odf.Od @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.Member=function(g,l){var f={};this.getMemberId=function(){return g};this.getProperties=function(){return f};this.setProperties=function(g){Object.keys(g).forEach(function(l){f[l]=g[l]})};this.removeProperties=function(g){delete g.fullName;delete g.color;delete g.imageUrl;Object.keys(g).forEach(function(g){f.hasOwnProperty(g)&&delete f[g]})};runtime.assert(Boolean(g),"No memberId was supplied!");l.fullName||(l.fullName=runtime.tr("Unknown Author"));l.color||(l.color="black");l.imageUrl||(l.imageUrl= -"avatar-joe.png");f=l}; -// Input 47 +ops.OpAddMember=function(){var k,h,b;this.init=function(p){k=p.memberid;h=parseInt(p.timestamp,10);b=p.setProperties};this.isEdit=!1;this.group=void 0;this.execute=function(h){var d;if(h.getMember(k))return!1;d=new ops.Member(k,b);h.addMember(d);h.emit(ops.Document.signalMemberAdded,d);return!0};this.spec=function(){return{optype:"AddMember",memberid:k,timestamp:h,setProperties:b}}}; +// Input 48 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1279,33 +1430,9 @@ ops.Member=function(g,l){var f={};this.getMemberId=function(){return g};this.get @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils");runtime.loadClass("core.PositionFilter");runtime.loadClass("odf.OdfUtils"); -(function(){function g(f,g,r){function n(a,b){function c(a){for(var b=0;a&&a.previousSibling;)b+=1,a=a.previousSibling;return b}this.steps=a;this.node=b;this.setIteratorPosition=function(a){a.setUnfilteredPosition(b.parentNode,c(b));do if(g.acceptPosition(a)===t)break;while(a.nextPosition())}}function h(a){return a.nodeType===Node.ELEMENT_NODE&&a.getAttributeNS(c,"nodeId")}function d(a){var b=l;a.setAttributeNS(c,"nodeId",b.toString());l+=1;return b}function m(b,d){var e,k=null;for(b=b.childNodes[d]|| -b;!k&&b&&b!==f;)(e=h(b))&&(k=a[e])&&k.node!==b&&(runtime.log("Cloned node detected. Creating new bookmark"),k=null,b.removeAttributeNS(c,"nodeId")),b=b.parentNode;return k}var c="urn:webodf:names:steps",e={},a={},b=new odf.OdfUtils,q=new core.DomUtils,k,t=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.updateCache=function(c,f,k,g){var q;0===k&&b.isParagraph(f)?(q=!0,g||(c+=1)):f.hasChildNodes()&&f.childNodes[k]&&(f=f.childNodes[k],(q=b.isParagraph(f))&&(c+=1));q&&(k=h(f)||d(f),(g=a[k])?g.node=== -f?g.steps=c:(runtime.log("Cloned node detected. Creating new bookmark"),k=d(f),g=a[k]=new n(c,f)):g=a[k]=new n(c,f),k=g,c=Math.ceil(k.steps/r)*r,f=e[c],!f||k.steps>f.steps)&&(e[c]=k)};this.setToClosestStep=function(a,b){for(var c=Math.floor(a/r)*r,d;!d&&0!==c;)d=e[c],c-=r;d=d||k;d.setIteratorPosition(b);return d.steps};this.setToClosestDomPoint=function(a,b,c){var d;if(a===f&&0===b)d=k;else if(a===f&&b===f.childNodes.length)d=Object.keys(e).map(function(a){return e[a]}).reduce(function(a,b){return b.steps> -a.steps?b:a},k);else if(d=m(a,b),!d)for(c.setUnfilteredPosition(a,b);!d&&c.previousNode();)d=m(c.container(),c.unfilteredDomOffset());d=d||k;d.setIteratorPosition(c);return d.steps};this.updateCacheAtPoint=function(b,c){var d={};Object.keys(a).map(function(b){return a[b]}).filter(function(a){return a.steps>b}).forEach(function(b){var k=Math.ceil(b.steps/r)*r,g,m;if(q.containsNode(f,b.node)){if(c(b),g=Math.ceil(b.steps/r)*r,m=d[g],!m||b.steps>m.steps)d[g]=b}else delete a[h(b.node)];e[k]===b&&delete e[k]}); -Object.keys(d).forEach(function(a){e[a]=d[a]})};k=new function(a,b){this.steps=a;this.node=b;this.setIteratorPosition=function(a){a.setUnfilteredPosition(b,0);do if(g.acceptPosition(a)===t)break;while(a.nextPosition())}}(0,f)}var l=0;ops.StepsTranslator=function(f,l,r,n){function h(){var b=f();b!==m&&(runtime.log("Undo detected. Resetting steps cache"),m=b,c=new g(m,r,n),a=l(m))}function d(a,c){if(!c||r.acceptPosition(a)===b)return!0;for(;a.previousPosition();)if(r.acceptPosition(a)===b){if(c(0,a.container(), -a.unfilteredDomOffset()))return!0;break}for(;a.nextPosition();)if(r.acceptPosition(a)===b){if(c(1,a.container(),a.unfilteredDomOffset()))return!0;break}return!1}var m=f(),c=new g(m,r,n),e=new core.DomUtils,a=l(f()),b=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.convertStepsToDomPoint=function(d){var e,f;0>d&&(runtime.log("warn","Requested steps were negative ("+d+")"),d=0);h();for(e=c.setToClosestStep(d,a);e<d&&a.nextPosition();)(f=r.acceptPosition(a)===b)&&(e+=1),c.updateCache(e,a.container(), -a.unfilteredDomOffset(),f);e!==d&&runtime.log("warn","Requested "+d+" steps but only "+e+" are available");return{node:a.container(),offset:a.unfilteredDomOffset()}};this.convertDomPointToSteps=function(f,k,g){var l;h();e.containsNode(m,f)||(k=0>e.comparePoints(m,0,f,k),f=m,k=k?0:m.childNodes.length);a.setUnfilteredPosition(f,k);d(a,g)||a.setUnfilteredPosition(f,k);g=a.container();k=a.unfilteredDomOffset();f=c.setToClosestDomPoint(g,k,a);if(0>e.comparePoints(a.container(),a.unfilteredDomOffset(), -g,k))return 0<f?f-1:f;for(;(a.container()!==g||a.unfilteredDomOffset()!==k)&&a.nextPosition();)(l=r.acceptPosition(a)===b)&&(f+=1),c.updateCache(f,a.container(),a.unfilteredDomOffset(),l);return f+0};this.prime=function(){var d,e;h();for(d=c.setToClosestStep(0,a);a.nextPosition();)(e=r.acceptPosition(a)===b)&&(d+=1),c.updateCache(d,a.container(),a.unfilteredDomOffset(),e)};this.handleStepsInserted=function(a){h();c.updateCacheAtPoint(a.position,function(b){b.steps+=a.length})};this.handleStepsRemoved= -function(a){h();c.updateCacheAtPoint(a.position,function(b){b.steps-=a.length;0>b.steps&&(b.steps=0)})}};ops.StepsTranslator.PREVIOUS_STEP=0;ops.StepsTranslator.NEXT_STEP=1;return ops.StepsTranslator})(); -// Input 48 -xmldom.RNG={}; -xmldom.RelaxNGParser=function(){function g(c,d){this.message=function(){d&&(c+=1===d.nodeType?" Element ":" Node ",c+=d.nodeName,d.nodeValue&&(c+=" with value '"+d.nodeValue+"'"),c+=".");return c}}function l(c){if(2>=c.e.length)return c;var d={name:c.name,e:c.e.slice(0,2)};return l({name:c.name,e:[d].concat(c.e.slice(2))})}function f(c){c=c.split(":",2);var e="",a;1===c.length?c=["",c[0]]:e=c[0];for(a in d)d[a]===e&&(c[0]=a);return c}function p(c,d){for(var a=0,b,h,k=c.name;c.e&&a<c.e.length;)if(b=c.e[a], -"ref"===b.name){h=d[b.a.name];if(!h)throw b.a.name+" was not defined.";b=c.e.slice(a+1);c.e=c.e.slice(0,a);c.e=c.e.concat(h.e);c.e=c.e.concat(b)}else a+=1,p(b,d);b=c.e;"choice"!==k||b&&b[1]&&"empty"!==b[1].name||(b&&b[0]&&"empty"!==b[0].name?(b[1]=b[0],b[0]={name:"empty"}):(delete c.e,c.name="empty"));if("group"===k||"interleave"===k)"empty"===b[0].name?"empty"===b[1].name?(delete c.e,c.name="empty"):(k=c.name=b[1].name,c.names=b[1].names,b=c.e=b[1].e):"empty"===b[1].name&&(k=c.name=b[0].name,c.names= -b[0].names,b=c.e=b[0].e);"oneOrMore"===k&&"empty"===b[0].name&&(delete c.e,c.name="empty");if("attribute"===k){h=c.names?c.names.length:0;for(var g,m=[],l=[],a=0;a<h;a+=1)g=f(c.names[a]),l[a]=g[0],m[a]=g[1];c.localnames=m;c.namespaces=l}"interleave"===k&&("interleave"===b[0].name?c.e="interleave"===b[1].name?b[0].e.concat(b[1].e):[b[1]].concat(b[0].e):"interleave"===b[1].name&&(c.e=[b[0]].concat(b[1].e)))}function r(c,d){for(var a=0,b;c.e&&a<c.e.length;)b=c.e[a],"elementref"===b.name?(b.id=b.id|| -0,c.e[a]=d[b.id]):"element"!==b.name&&r(b,d),a+=1}var n=this,h,d={"http://www.w3.org/XML/1998/namespace":"xml"},m;m=function(c,e,a){var b=[],h,g,n=c.localName,p=[];h=c.attributes;var r=n,x=p,v={},u,s;for(u=0;h&&u<h.length;u+=1)if(s=h.item(u),s.namespaceURI)"http://www.w3.org/2000/xmlns/"===s.namespaceURI&&(d[s.value]=s.localName);else{"name"!==s.localName||"element"!==r&&"attribute"!==r||x.push(s.value);if("name"===s.localName||"combine"===s.localName||"type"===s.localName){var H=s,y;y=s.value;y= -y.replace(/^\s\s*/,"");for(var B=/\s/,L=y.length-1;B.test(y.charAt(L));)L-=1;y=y.slice(0,L+1);H.value=y}v[s.localName]=s.value}h=v;h.combine=h.combine||void 0;c=c.firstChild;r=b;x=p;for(v="";c;){if(c.nodeType===Node.ELEMENT_NODE&&"http://relaxng.org/ns/structure/1.0"===c.namespaceURI){if(u=m(c,e,r))"name"===u.name?x.push(d[u.a.ns]+":"+u.text):"choice"===u.name&&u.names&&u.names.length&&(x=x.concat(u.names),delete u.names),r.push(u)}else c.nodeType===Node.TEXT_NODE&&(v+=c.nodeValue);c=c.nextSibling}c= -v;"value"!==n&&"param"!==n&&(c=/^\s*([\s\S]*\S)?\s*$/.exec(c)[1]);"value"===n&&void 0===h.type&&(h.type="token",h.datatypeLibrary="");"attribute"!==n&&"element"!==n||void 0===h.name||(g=f(h.name),b=[{name:"name",text:g[1],a:{ns:g[0]}}].concat(b),delete h.name);"name"===n||"nsName"===n||"value"===n?void 0===h.ns&&(h.ns=""):delete h.ns;"name"===n&&(g=f(c),h.ns=g[0],c=g[1]);1<b.length&&("define"===n||"oneOrMore"===n||"zeroOrMore"===n||"optional"===n||"list"===n||"mixed"===n)&&(b=[{name:"group",e:l({name:"group", -e:b}).e}]);2<b.length&&"element"===n&&(b=[b[0]].concat({name:"group",e:l({name:"group",e:b.slice(1)}).e}));1===b.length&&"attribute"===n&&b.push({name:"text",text:c});1!==b.length||"choice"!==n&&"group"!==n&&"interleave"!==n?2<b.length&&("choice"===n||"group"===n||"interleave"===n)&&(b=l({name:n,e:b}).e):(n=b[0].name,p=b[0].names,h=b[0].a,c=b[0].text,b=b[0].e);"mixed"===n&&(n="interleave",b=[b[0],{name:"text"}]);"optional"===n&&(n="choice",b=[b[0],{name:"empty"}]);"zeroOrMore"===n&&(n="choice",b= -[{name:"oneOrMore",e:[b[0]]},{name:"empty"}]);if("define"===n&&h.combine){a:{r=h.combine;x=h.name;v=b;for(u=0;a&&u<a.length;u+=1)if(s=a[u],"define"===s.name&&s.a&&s.a.name===x){s.e=[{name:r,e:s.e.concat(v)}];a=s;break a}a=null}if(a)return null}a={name:n};b&&0<b.length&&(a.e=b);for(g in h)if(h.hasOwnProperty(g)){a.a=h;break}void 0!==c&&(a.text=c);p&&0<p.length&&(a.names=p);"element"===n&&(a.id=e.length,e.push(a),a={name:"elementref",id:a.id});return a};this.parseRelaxNGDOM=function(c,e){var a=[],b= -m(c&&c.documentElement,a,void 0),f,k,l={};for(f=0;f<b.e.length;f+=1)k=b.e[f],"define"===k.name?l[k.a.name]=k:"start"===k.name&&(h=k);if(!h)return[new g("No Relax NG start element was found.")];p(h,l);for(f in l)l.hasOwnProperty(f)&&p(l[f],l);for(f=0;f<a.length;f+=1)p(a[f],l);e&&(n.rootPattern=e(h.e[0],a));r(h,a);for(f=0;f<a.length;f+=1)r(a[f],a);n.start=h;n.elements=a;n.nsmap=d;return null}}; +ops.OpAddStyle=function(){var k,h,b,p,d,n,g=odf.Namespaces.stylens;this.init=function(g){k=g.memberid;h=g.timestamp;b=g.styleName;p=g.styleFamily;d="true"===g.isAutomaticStyle||!0===g.isAutomaticStyle;n=g.setProperties};this.isEdit=!0;this.group=void 0;this.execute=function(h){var k=h.getOdfCanvas().odfContainer(),l=h.getFormatting(),f=h.getDOMDocument().createElementNS(g,"style:style");if(!f)return!1;n&&l.updateStyle(f,n);f.setAttributeNS(g,"style:family",p);f.setAttributeNS(g,"style:name",b);d? +k.rootElement.automaticStyles.appendChild(f):k.rootElement.styles.appendChild(f);h.getOdfCanvas().refreshCSS();d||h.emit(ops.OdtDocument.signalCommonStyleCreated,{name:b,family:p});return!0};this.spec=function(){return{optype:"AddStyle",memberid:k,timestamp:h,styleName:b,styleFamily:p,isAutomaticStyle:d,setProperties:n}}}; // Input 49 -runtime.loadClass("core.Cursor");runtime.loadClass("gui.SelectionMover"); -ops.OdtCursor=function(g,l){var f=this,p={},r,n,h;this.removeFromOdtDocument=function(){h.remove()};this.move=function(d,h){var c=0;0<d?c=n.movePointForward(d,h):0>=d&&(c=-n.movePointBackward(-d,h));f.handleUpdate();return c};this.handleUpdate=function(){};this.getStepCounter=function(){return n.getStepCounter()};this.getMemberId=function(){return g};this.getNode=function(){return h.getNode()};this.getAnchorNode=function(){return h.getAnchorNode()};this.getSelectedRange=function(){return h.getSelectedRange()}; -this.setSelectedRange=function(d,g){h.setSelectedRange(d,g);f.handleUpdate()};this.hasForwardSelection=function(){return h.hasForwardSelection()};this.getOdtDocument=function(){return l};this.getSelectionType=function(){return r};this.setSelectionType=function(d){p.hasOwnProperty(d)?r=d:runtime.log("Invalid selection type: "+d)};this.resetSelectionType=function(){f.setSelectionType(ops.OdtCursor.RangeSelection)};h=new core.Cursor(l.getDOM(),g);n=new gui.SelectionMover(h,l.getRootNode());p[ops.OdtCursor.RangeSelection]= -!0;p[ops.OdtCursor.RegionSelection]=!0;f.resetSelectionType()};ops.OdtCursor.RangeSelection="Range";ops.OdtCursor.RegionSelection="Region";(function(){return ops.OdtCursor})(); -// Input 50 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1343,25 +1470,10 @@ this.setSelectedRange=function(d,g){h.setSelectedRange(d,g);f.handleUpdate()};th @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.EventNotifier");runtime.loadClass("core.DomUtils");runtime.loadClass("odf.OdfUtils");runtime.loadClass("odf.Namespaces");runtime.loadClass("gui.SelectionMover");runtime.loadClass("core.PositionFilterChain");runtime.loadClass("ops.StepsTranslator");runtime.loadClass("ops.TextPositionFilter");runtime.loadClass("ops.Member"); -ops.OdtDocument=function(g){function l(){var a=g.odfContainer().getContentElement(),b=a&&a.localName;runtime.assert("text"===b,"Unsupported content element type '"+b+"' for OdtDocument");return a}function f(){return l().ownerDocument}function p(a){for(;a&&!(a.namespaceURI===odf.Namespaces.officens&&"text"===a.localName||a.namespaceURI===odf.Namespaces.officens&&"annotation"===a.localName);)a=a.parentNode;return a}function r(b){this.acceptPosition=function(c){c=c.container();var d;d="string"===typeof b? -a[b].getNode():b;return p(c)===p(d)?k:t}}function n(a){var b=gui.SelectionMover.createPositionIterator(l());a=w.convertStepsToDomPoint(a);b.setUnfilteredPosition(a.node,a.offset);return b}function h(a,b){return g.getFormatting().getStyleElement(a,b)}function d(a){return h(a,"paragraph")}var m=this,c,e,a={},b={},q=new core.EventNotifier([ops.OdtDocument.signalMemberAdded,ops.OdtDocument.signalMemberUpdated,ops.OdtDocument.signalMemberRemoved,ops.OdtDocument.signalCursorAdded,ops.OdtDocument.signalCursorRemoved, -ops.OdtDocument.signalCursorMoved,ops.OdtDocument.signalParagraphChanged,ops.OdtDocument.signalParagraphStyleModified,ops.OdtDocument.signalCommonStyleCreated,ops.OdtDocument.signalCommonStyleDeleted,ops.OdtDocument.signalTableAdded,ops.OdtDocument.signalOperationExecuted,ops.OdtDocument.signalUndoStackChanged,ops.OdtDocument.signalStepsInserted,ops.OdtDocument.signalStepsRemoved]),k=core.PositionFilter.FilterResult.FILTER_ACCEPT,t=core.PositionFilter.FilterResult.FILTER_REJECT,A,w,x;this.getDOM= -f;this.getRootElement=p;this.getIteratorAtPosition=n;this.convertDomPointToCursorStep=function(a,b,c){return w.convertDomPointToSteps(a,b,c)};this.convertDomToCursorRange=function(a,b){var c,d;c=b(a.anchorNode,a.anchorOffset);c=w.convertDomPointToSteps(a.anchorNode,a.anchorOffset,c);b||a.anchorNode!==a.focusNode||a.anchorOffset!==a.focusOffset?(d=b(a.focusNode,a.focusOffset),d=w.convertDomPointToSteps(a.focusNode,a.focusOffset,d)):d=c;return{position:c,length:d-c}};this.convertCursorToDomRange=function(a, -b){var c=f().createRange(),d,e;d=w.convertStepsToDomPoint(a);b?(e=w.convertStepsToDomPoint(a+b),0<b?(c.setStart(d.node,d.offset),c.setEnd(e.node,e.offset)):(c.setStart(e.node,e.offset),c.setEnd(d.node,d.offset))):c.setStart(d.node,d.offset);return c};this.getStyleElement=h;this.upgradeWhitespacesAtPosition=function(a){a=n(a);var b,d,e;a.previousPosition();a.previousPosition();for(e=-1;1>=e;e+=1){b=a.container();d=a.unfilteredDomOffset();if(b.nodeType===Node.TEXT_NODE&&" "===b.data[d]&&c.isSignificantWhitespace(b, -d)){runtime.assert(" "===b.data[d],"upgradeWhitespaceToElement: textNode.data[offset] should be a literal space");var f=b.ownerDocument.createElementNS(odf.Namespaces.textns,"text:s");f.appendChild(b.ownerDocument.createTextNode(" "));b.deleteData(d,1);0<d&&(b=b.splitText(d));b.parentNode.insertBefore(f,b);b=f;a.moveToEndOfNode(b)}a.nextPosition()}};this.downgradeWhitespacesAtPosition=function(a){var b=n(a),d;a=b.container();for(b=b.unfilteredDomOffset();!c.isSpaceElement(a)&&a.childNodes[b];)a=a.childNodes[b], -b=0;a.nodeType===Node.TEXT_NODE&&(a=a.parentNode);c.isDowngradableSpaceElement(a)&&(b=a.firstChild,d=a.lastChild,e.mergeIntoParent(a),d!==b&&e.normalizeTextNodes(d),e.normalizeTextNodes(b))};this.getParagraphStyleElement=d;this.getParagraphElement=function(a){return c.getParagraphElement(a)};this.getParagraphStyleAttributes=function(a){return(a=d(a))?g.getFormatting().getInheritedStyleAttributes(a):null};this.getTextNodeAtStep=function(b,c){var d=n(b),e=d.container(),h,g=0,k=null;e.nodeType===Node.TEXT_NODE? -(h=e,g=d.unfilteredDomOffset(),0<h.length&&(0<g&&(h=h.splitText(g)),h.parentNode.insertBefore(f().createTextNode(""),h),h=h.previousSibling,g=0)):(h=f().createTextNode(""),g=0,e.insertBefore(h,d.rightNode()));if(c){if(a[c]&&m.getCursorPosition(c)===b){for(k=a[c].getNode();k.nextSibling&&"cursor"===k.nextSibling.localName;)k.parentNode.insertBefore(k.nextSibling,k);0<h.length&&h.nextSibling!==k&&(h=f().createTextNode(""),g=0);k.parentNode.insertBefore(h,k)}}else for(;h.nextSibling&&"cursor"===h.nextSibling.localName;)h.parentNode.insertBefore(h.nextSibling, -h);for(;h.previousSibling&&h.previousSibling.nodeType===Node.TEXT_NODE;)h.previousSibling.appendData(h.data),g=h.previousSibling.length,h=h.previousSibling,h.parentNode.removeChild(h.nextSibling);for(;h.nextSibling&&h.nextSibling.nodeType===Node.TEXT_NODE;)h.appendData(h.nextSibling.data),h.parentNode.removeChild(h.nextSibling);return{textNode:h,offset:g}};this.fixCursorPositions=function(){var b=new core.PositionFilterChain;b.addFilter("BaseFilter",A);Object.keys(a).forEach(function(c){var d=a[c], -e=d.getStepCounter(),f,h,g=!1;b.addFilter("RootFilter",m.createRootFilter(c));c=e.countStepsToPosition(d.getAnchorNode(),0,b);e.isPositionWalkable(b)?0===c&&(g=!0,d.move(0)):(g=!0,f=e.countPositionsToNearestStep(d.getNode(),0,b),h=e.countPositionsToNearestStep(d.getAnchorNode(),0,b),d.move(f),0!==c&&(0<h&&(c+=1),0<f&&(c-=1),e=e.countSteps(c,b),d.move(e),d.move(-e,!0)));g&&m.emit(ops.OdtDocument.signalCursorMoved,d);b.removeFilter("RootFilter")})};this.getDistanceFromCursor=function(b,c,d){b=a[b]; -var e,f;runtime.assert(null!==c&&void 0!==c,"OdtDocument.getDistanceFromCursor called without node");b&&(e=w.convertDomPointToSteps(b.getNode(),0),f=w.convertDomPointToSteps(c,d));return f-e};this.getCursorPosition=function(b){return(b=a[b])?w.convertDomPointToSteps(b.getNode(),0):0};this.getCursorSelection=function(b){b=a[b];var c=0,d=0;b&&(c=w.convertDomPointToSteps(b.getNode(),0),d=w.convertDomPointToSteps(b.getAnchorNode(),0));return{position:d,length:c-d}};this.getPositionFilter=function(){return A}; -this.getOdfCanvas=function(){return g};this.getRootNode=l;this.addMember=function(a){runtime.assert(void 0===b[a.getMemberId()],"This member already exists");b[a.getMemberId()]=a};this.getMember=function(a){return b.hasOwnProperty(a)?b[a]:null};this.removeMember=function(a){delete b[a]};this.getCursor=function(b){return a[b]};this.getCursors=function(){var b=[],c;for(c in a)a.hasOwnProperty(c)&&b.push(a[c]);return b};this.addCursor=function(b){runtime.assert(Boolean(b),"OdtDocument::addCursor without cursor"); -var c=b.getStepCounter().countSteps(1,A),d=b.getMemberId();runtime.assert("string"===typeof d,"OdtDocument::addCursor has cursor without memberid");runtime.assert(!a[d],"OdtDocument::addCursor is adding a duplicate cursor with memberid "+d);b.move(c);a[d]=b};this.removeCursor=function(b){var c=a[b];return c?(c.removeFromOdtDocument(),delete a[b],m.emit(ops.OdtDocument.signalCursorRemoved,b),!0):!1};this.moveCursor=function(b,c,d,e){b=a[b];c=m.convertCursorToDomRange(c,d);b&&c&&(b.setSelectedRange(c, -0<=d),b.setSelectionType(e||ops.OdtCursor.RangeSelection))};this.getFormatting=function(){return g.getFormatting()};this.emit=function(a,b){q.emit(a,b)};this.subscribe=function(a,b){q.subscribe(a,b)};this.unsubscribe=function(a,b){q.unsubscribe(a,b)};this.createRootFilter=function(a){return new r(a)};this.close=function(a){a()};this.destroy=function(a){a()};A=new ops.TextPositionFilter(l);c=new odf.OdfUtils;e=new core.DomUtils;w=new ops.StepsTranslator(l,gui.SelectionMover.createPositionIterator, -A,500);q.subscribe(ops.OdtDocument.signalStepsInserted,w.handleStepsInserted);q.subscribe(ops.OdtDocument.signalStepsRemoved,w.handleStepsRemoved);q.subscribe(ops.OdtDocument.signalOperationExecuted,function(a){var b=a.spec(),c=b.memberid,b=(new Date(b.timestamp)).toISOString(),d=g.odfContainer();a.isEdit&&(c=m.getMember(c).getProperties().fullName,d.setMetadata({"dc:creator":c,"dc:date":b},null),x||(d.incrementEditingCycles(),d.setMetadata(null,["meta:editing-duration","meta:document-statistic"])), -x=a)})};ops.OdtDocument.signalMemberAdded="member/added";ops.OdtDocument.signalMemberUpdated="member/updated";ops.OdtDocument.signalMemberRemoved="member/removed";ops.OdtDocument.signalCursorAdded="cursor/added";ops.OdtDocument.signalCursorRemoved="cursor/removed";ops.OdtDocument.signalCursorMoved="cursor/moved";ops.OdtDocument.signalParagraphChanged="paragraph/changed";ops.OdtDocument.signalTableAdded="table/added";ops.OdtDocument.signalCommonStyleCreated="style/created"; -ops.OdtDocument.signalCommonStyleDeleted="style/deleted";ops.OdtDocument.signalParagraphStyleModified="paragraphstyle/modified";ops.OdtDocument.signalOperationExecuted="operation/executed";ops.OdtDocument.signalUndoStackChanged="undo/changed";ops.OdtDocument.signalStepsInserted="steps/inserted";ops.OdtDocument.signalStepsRemoved="steps/removed";(function(){return ops.OdtDocument})(); -// Input 51 +odf.ObjectNameGenerator=function(k,h){function b(a,c){var b={};this.generateName=function(){var d=c(),f=0,g;do g=a+f,f+=1;while(b[g]||d[g]);b[g]=!0;return g}}function p(){var a={};[k.rootElement.automaticStyles,k.rootElement.styles].forEach(function(c){for(c=c.firstElementChild;c;)c.namespaceURI===d&&"style"===c.localName&&(a[c.getAttributeNS(d,"name")]=!0),c=c.nextElementSibling});return a}var d=odf.Namespaces.stylens,n=odf.Namespaces.drawns,g=odf.Namespaces.xlinkns,q=new core.DomUtils,r=(new core.Utils).hashString(h), +l=null,f=null,c=null,a={},m={};this.generateStyleName=function(){null===l&&(l=new b("auto"+r+"_",function(){return p()}));return l.generateName()};this.generateFrameName=function(){null===f&&(q.getElementsByTagNameNS(k.rootElement.body,n,"frame").forEach(function(c){a[c.getAttributeNS(n,"name")]=!0}),f=new b("fr"+r+"_",function(){return a}));return f.generateName()};this.generateImageName=function(){null===c&&(q.getElementsByTagNameNS(k.rootElement.body,n,"image").forEach(function(a){a=a.getAttributeNS(g, +"href");a=a.substring(9,a.lastIndexOf("."));m[a]=!0}),c=new b("img"+r+"_",function(){return m}));return c.generateName()}}; +// Input 50 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1399,55 +1511,14 @@ ops.OdtDocument.signalCommonStyleDeleted="style/deleted";ops.OdtDocument.signalP @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.Operation=function(){};ops.Operation.prototype.init=function(g){};ops.Operation.prototype.execute=function(g){};ops.Operation.prototype.spec=function(){}; -// Input 52 -runtime.loadClass("xmldom.RelaxNGParser"); -xmldom.RelaxNG=function(){function g(a){return function(){var b;return function(){void 0===b&&(b=a());return b}}()}function l(a,b){return function(){var c={},d=0;return function(e){var f=e.hash||e.toString();if(c.hasOwnProperty(f))return c[f];c[f]=e=b(e);e.hash=a+d.toString();d+=1;return e}}()}function f(a){return function(){var b={};return function(c){var d,e;if(b.hasOwnProperty(c.localName)){if(e=b[c.localName],d=e[c.namespaceURI],void 0!==d)return d}else b[c.localName]=e={};return e[c.namespaceURI]= -d=a(c)}}()}function p(a,b,c){return function(){var d={},e=0;return function(f,h){var g=b&&b(f,h),k;if(void 0!==g)return g;k=f.hash||f.toString();g=h.hash||h.toString();if(d.hasOwnProperty(k)){if(k=d[k],k.hasOwnProperty(g))return k[g]}else d[k]=k={};k[g]=g=c(f,h);g.hash=a+e.toString();e+=1;return g}}()}function r(a,b){"choice"===b.p1.type?r(a,b.p1):a[b.p1.hash]=b.p1;"choice"===b.p2.type?r(a,b.p2):a[b.p2.hash]=b.p2}function n(a,b){return{type:"element",nc:a,nullable:!1,textDeriv:function(){return y}, -startTagOpenDeriv:function(c){return a.contains(c)?q(b,B):y},attDeriv:function(){return y},startTagCloseDeriv:function(){return this}}}function h(){return{type:"list",nullable:!1,hash:"list",textDeriv:function(){return B}}}function d(a,b,e,f){if(b===y)return y;if(f>=e.length)return b;0===f&&(f=0);for(var h=e.item(f);h.namespaceURI===c;){f+=1;if(f>=e.length)return b;h=e.item(f)}return h=d(a,b.attDeriv(a,e.item(f)),e,f+1)}function m(a,b,c){c.e[0].a?(a.push(c.e[0].text),b.push(c.e[0].a.ns)):m(a,b,c.e[0]); -c.e[1].a?(a.push(c.e[1].text),b.push(c.e[1].a.ns)):m(a,b,c.e[1])}var c="http://www.w3.org/2000/xmlns/",e,a,b,q,k,t,A,w,x,v,u,s,H,y={type:"notAllowed",nullable:!1,hash:"notAllowed",nc:void 0,p:void 0,p1:void 0,p2:void 0,textDeriv:function(){return y},startTagOpenDeriv:function(){return y},attDeriv:function(){return y},startTagCloseDeriv:function(){return y},endTagDeriv:function(){return y}},B={type:"empty",nullable:!0,hash:"empty",nc:void 0,p:void 0,p1:void 0,p2:void 0,textDeriv:function(){return y}, -startTagOpenDeriv:function(){return y},attDeriv:function(){return y},startTagCloseDeriv:function(){return B},endTagDeriv:function(){return y}},L={type:"text",nullable:!0,hash:"text",nc:void 0,p:void 0,p1:void 0,p2:void 0,textDeriv:function(){return L},startTagOpenDeriv:function(){return y},attDeriv:function(){return y},startTagCloseDeriv:function(){return L},endTagDeriv:function(){return y}};e=p("choice",function(a,b){if(a===y)return b;if(b===y||a===b)return a},function(a,b){var c={},d;r(c,{p1:a, -p2:b});b=a=void 0;for(d in c)c.hasOwnProperty(d)&&(void 0===a?a=c[d]:b=void 0===b?c[d]:e(b,c[d]));return function(a,b){return{type:"choice",nullable:a.nullable||b.nullable,hash:void 0,nc:void 0,p:void 0,p1:a,p2:b,textDeriv:function(c,d){return e(a.textDeriv(c,d),b.textDeriv(c,d))},startTagOpenDeriv:f(function(c){return e(a.startTagOpenDeriv(c),b.startTagOpenDeriv(c))}),attDeriv:function(c,d){return e(a.attDeriv(c,d),b.attDeriv(c,d))},startTagCloseDeriv:g(function(){return e(a.startTagCloseDeriv(), -b.startTagCloseDeriv())}),endTagDeriv:g(function(){return e(a.endTagDeriv(),b.endTagDeriv())})}}(a,b)});a=function(a,b,c){return function(){var d={},e=0;return function(f,h){var g=b&&b(f,h),k,m;if(void 0!==g)return g;k=f.hash||f.toString();g=h.hash||h.toString();k<g&&(m=k,k=g,g=m,m=f,f=h,h=m);if(d.hasOwnProperty(k)){if(k=d[k],k.hasOwnProperty(g))return k[g]}else d[k]=k={};k[g]=g=c(f,h);g.hash=a+e.toString();e+=1;return g}}()}("interleave",function(a,b){if(a===y||b===y)return y;if(a===B)return b;if(b=== -B)return a},function(b,c){return{type:"interleave",nullable:b.nullable&&c.nullable,hash:void 0,p1:b,p2:c,textDeriv:function(d,f){return e(a(b.textDeriv(d,f),c),a(b,c.textDeriv(d,f)))},startTagOpenDeriv:f(function(d){return e(u(function(b){return a(b,c)},b.startTagOpenDeriv(d)),u(function(c){return a(b,c)},c.startTagOpenDeriv(d)))}),attDeriv:function(d,f){return e(a(b.attDeriv(d,f),c),a(b,c.attDeriv(d,f)))},startTagCloseDeriv:g(function(){return a(b.startTagCloseDeriv(),c.startTagCloseDeriv())}),endTagDeriv:void 0}}); -b=p("group",function(a,b){if(a===y||b===y)return y;if(a===B)return b;if(b===B)return a},function(a,c){return{type:"group",p1:a,p2:c,nullable:a.nullable&&c.nullable,textDeriv:function(d,f){var h=b(a.textDeriv(d,f),c);return a.nullable?e(h,c.textDeriv(d,f)):h},startTagOpenDeriv:function(d){var f=u(function(a){return b(a,c)},a.startTagOpenDeriv(d));return a.nullable?e(f,c.startTagOpenDeriv(d)):f},attDeriv:function(d,f){return e(b(a.attDeriv(d,f),c),b(a,c.attDeriv(d,f)))},startTagCloseDeriv:g(function(){return b(a.startTagCloseDeriv(), -c.startTagCloseDeriv())})}});q=p("after",function(a,b){if(a===y||b===y)return y},function(a,b){return{type:"after",p1:a,p2:b,nullable:!1,textDeriv:function(c,d){return q(a.textDeriv(c,d),b)},startTagOpenDeriv:f(function(c){return u(function(a){return q(a,b)},a.startTagOpenDeriv(c))}),attDeriv:function(c,d){return q(a.attDeriv(c,d),b)},startTagCloseDeriv:g(function(){return q(a.startTagCloseDeriv(),b)}),endTagDeriv:g(function(){return a.nullable?b:y})}});k=l("oneormore",function(a){return a===y?y: -{type:"oneOrMore",p:a,nullable:a.nullable,textDeriv:function(c,d){return b(a.textDeriv(c,d),e(this,B))},startTagOpenDeriv:function(c){var d=this;return u(function(a){return b(a,e(d,B))},a.startTagOpenDeriv(c))},attDeriv:function(c,d){return b(a.attDeriv(c,d),e(this,B))},startTagCloseDeriv:g(function(){return k(a.startTagCloseDeriv())})}});A=p("attribute",void 0,function(a,b){return{type:"attribute",nullable:!1,hash:void 0,nc:a,p:b,p1:void 0,p2:void 0,textDeriv:void 0,startTagOpenDeriv:void 0,attDeriv:function(c, -d){return a.contains(d)&&(b.nullable&&/^\s+$/.test(d.nodeValue)||b.textDeriv(c,d.nodeValue).nullable)?B:y},startTagCloseDeriv:function(){return y},endTagDeriv:void 0}});t=l("value",function(a){return{type:"value",nullable:!1,value:a,textDeriv:function(b,c){return c===a?B:y},attDeriv:function(){return y},startTagCloseDeriv:function(){return this}}});x=l("data",function(a){return{type:"data",nullable:!1,dataType:a,textDeriv:function(){return B},attDeriv:function(){return y},startTagCloseDeriv:function(){return this}}}); -u=function W(a,b){return"after"===b.type?q(b.p1,a(b.p2)):"choice"===b.type?e(W(a,b.p1),W(a,b.p2)):b};s=function(a,b,c){var f=c.currentNode;b=b.startTagOpenDeriv(f);b=d(a,b,f.attributes,0);var h=b=b.startTagCloseDeriv(),f=c.currentNode;b=c.firstChild();for(var g=[],k;b;)b.nodeType===Node.ELEMENT_NODE?g.push(b):b.nodeType!==Node.TEXT_NODE||/^\s*$/.test(b.nodeValue)||g.push(b.nodeValue),b=c.nextSibling();0===g.length&&(g=[""]);k=h;for(h=0;k!==y&&h<g.length;h+=1)b=g[h],"string"===typeof b?k=/^\s*$/.test(b)? -e(k,k.textDeriv(a,b)):k.textDeriv(a,b):(c.currentNode=b,k=s(a,k,c));c.currentNode=f;return b=k.endTagDeriv()};w=function(a){var b,c,d;if("name"===a.name)b=a.text,c=a.a.ns,a={name:b,ns:c,hash:"{"+c+"}"+b,contains:function(a){return a.namespaceURI===c&&a.localName===b}};else if("choice"===a.name){b=[];c=[];m(b,c,a);a="";for(d=0;d<b.length;d+=1)a+="{"+c[d]+"}"+b[d]+",";a={hash:a,contains:function(a){var d;for(d=0;d<b.length;d+=1)if(b[d]===a.localName&&c[d]===a.namespaceURI)return!0;return!1}}}else a= -{hash:"anyName",contains:function(){return!0}};return a};v=function Q(c,d){var f,g;if("elementref"===c.name){f=c.id||0;c=d[f];if(void 0!==c.name){var m=c;f=d[m.id]={hash:"element"+m.id.toString()};m=n(w(m.e[0]),v(m.e[1],d));for(g in m)m.hasOwnProperty(g)&&(f[g]=m[g]);return f}return c}switch(c.name){case "empty":return B;case "notAllowed":return y;case "text":return L;case "choice":return e(Q(c.e[0],d),Q(c.e[1],d));case "interleave":f=Q(c.e[0],d);for(g=1;g<c.e.length;g+=1)f=a(f,Q(c.e[g],d));return f; -case "group":return b(Q(c.e[0],d),Q(c.e[1],d));case "oneOrMore":return k(Q(c.e[0],d));case "attribute":return A(w(c.e[0]),Q(c.e[1],d));case "value":return t(c.text);case "data":return f=c.a&&c.a.type,void 0===f&&(f=""),x(f);case "list":return h()}throw"No support for "+c.name;};this.makePattern=function(a,b){var c={},d;for(d in b)b.hasOwnProperty(d)&&(c[d]=b[d]);return d=v(a,c)};this.validate=function(a,b){var c;a.currentNode=a.root;c=s(null,H,a);c.nullable?b(null):(runtime.log("Error in Relax NG validation: "+ -c),b(["Error in Relax NG validation: "+c]))};this.init=function(a){H=a}}; -// Input 53 -runtime.loadClass("xmldom.RelaxNGParser"); -xmldom.RelaxNG2=function(){function g(f,d){this.message=function(){d&&(f+=d.nodeType===Node.ELEMENT_NODE?" Element ":" Node ",f+=d.nodeName,d.nodeValue&&(f+=" with value '"+d.nodeValue+"'"),f+=".");return f}}function l(f,d,g,c){return"empty"===f.name?null:r(f,d,g,c)}function f(f,d){if(2!==f.e.length)throw"Element with wrong # of elements: "+f.e.length;for(var m=d.currentNode,c=m?m.nodeType:0,e=null;c>Node.ELEMENT_NODE;){if(c!==Node.COMMENT_NODE&&(c!==Node.TEXT_NODE||!/^\s+$/.test(d.currentNode.nodeValue)))return[new g("Not allowed node of type "+ -c+".")];c=(m=d.nextSibling())?m.nodeType:0}if(!m)return[new g("Missing element "+f.names)];if(f.names&&-1===f.names.indexOf(n[m.namespaceURI]+":"+m.localName))return[new g("Found "+m.nodeName+" instead of "+f.names+".",m)];if(d.firstChild()){for(e=l(f.e[1],d,m);d.nextSibling();)if(c=d.currentNode.nodeType,!(d.currentNode&&d.currentNode.nodeType===Node.TEXT_NODE&&/^\s+$/.test(d.currentNode.nodeValue)||c===Node.COMMENT_NODE))return[new g("Spurious content.",d.currentNode)];if(d.parentNode()!==m)return[new g("Implementation error.")]}else e= -l(f.e[1],d,m);d.nextSibling();return e}var p,r,n;r=function(h,d,m,c){var e=h.name,a=null;if("text"===e)a:{for(var b=(h=d.currentNode)?h.nodeType:0;h!==m&&3!==b;){if(1===b){a=[new g("Element not allowed here.",h)];break a}b=(h=d.nextSibling())?h.nodeType:0}d.nextSibling();a=null}else if("data"===e)a=null;else if("value"===e)c!==h.text&&(a=[new g("Wrong value, should be '"+h.text+"', not '"+c+"'",m)]);else if("list"===e)a=null;else if("attribute"===e)a:{if(2!==h.e.length)throw"Attribute with wrong # of elements: "+ -h.e.length;e=h.localnames.length;for(a=0;a<e;a+=1){c=m.getAttributeNS(h.namespaces[a],h.localnames[a]);""!==c||m.hasAttributeNS(h.namespaces[a],h.localnames[a])||(c=void 0);if(void 0!==b&&void 0!==c){a=[new g("Attribute defined too often.",m)];break a}b=c}a=void 0===b?[new g("Attribute not found: "+h.names,m)]:l(h.e[1],d,m,b)}else if("element"===e)a=f(h,d);else if("oneOrMore"===e){c=0;do b=d.currentNode,e=r(h.e[0],d,m),c+=1;while(!e&&b!==d.currentNode);1<c?(d.currentNode=b,a=null):a=e}else if("choice"=== -e){if(2!==h.e.length)throw"Choice with wrong # of options: "+h.e.length;b=d.currentNode;if("empty"===h.e[0].name){if(e=r(h.e[1],d,m,c))d.currentNode=b;a=null}else{if(e=l(h.e[0],d,m,c))d.currentNode=b,e=r(h.e[1],d,m,c);a=e}}else if("group"===e){if(2!==h.e.length)throw"Group with wrong # of members: "+h.e.length;a=r(h.e[0],d,m)||r(h.e[1],d,m)}else if("interleave"===e)a:{b=h.e.length;c=[b];for(var q=b,k,n,p,w;0<q;){k=0;n=d.currentNode;for(a=0;a<b;a+=1)p=d.currentNode,!0!==c[a]&&c[a]!==p&&(w=h.e[a],(e= -r(w,d,m))?(d.currentNode=p,void 0===c[a]&&(c[a]=!1)):p===d.currentNode||"oneOrMore"===w.name||"choice"===w.name&&("oneOrMore"===w.e[0].name||"oneOrMore"===w.e[1].name)?(k+=1,c[a]=p):(k+=1,c[a]=!0));if(n===d.currentNode&&k===q){a=null;break a}if(0===k){for(a=0;a<b;a+=1)if(!1===c[a]){a=[new g("Interleave does not match.",m)];break a}a=null;break a}for(a=q=0;a<b;a+=1)!0!==c[a]&&(q+=1)}a=null}else throw e+" not allowed in nonEmptyPattern.";return a};this.validate=function(f,d){f.currentNode=f.root;var g= -l(p.e[0],f,f.root);d(g)};this.init=function(f,d){p=f;n=d}}; -// Input 54 -runtime.loadClass("core.DomUtils");runtime.loadClass("gui.Avatar");runtime.loadClass("ops.OdtCursor"); -gui.Caret=function(g,l,f){function p(c){e&&m.parentNode&&(!a||c)&&(c&&void 0!==b&&runtime.clearTimeout(b),a=!0,h.style.opacity=c||"0"===h.style.opacity?"1":"0",b=runtime.setTimeout(function(){a=!1;p(!1)},500))}function r(a,b){var c=a.getBoundingClientRect(),d=0,e=0;c&&b&&(d=Math.max(c.top,b.top),e=Math.min(c.bottom,b.bottom));return e-d}function n(){var a;a=g.getSelectedRange().cloneRange();var b=g.getNode(),d,e=null;b.previousSibling&&(d=b.previousSibling.nodeType===Node.TEXT_NODE?b.previousSibling.textContent.length: -b.previousSibling.childNodes.length,a.setStart(b.previousSibling,0<d?d-1:0),a.setEnd(b.previousSibling,d),(d=a.getBoundingClientRect())&&d.height&&(e=d));b.nextSibling&&(a.setStart(b.nextSibling,0),a.setEnd(b.nextSibling,0<(b.nextSibling.nodeType===Node.TEXT_NODE?b.nextSibling.textContent.length:b.nextSibling.childNodes.length)?1:0),(d=a.getBoundingClientRect())&&d.height&&(!e||r(b,d)>r(b,e))&&(e=d));a=e;b=g.getOdtDocument().getOdfCanvas().getZoomLevel();c&&g.getSelectionType()===ops.OdtCursor.RangeSelection? -h.style.visibility="visible":h.style.visibility="hidden";a?(h.style.top="0",e=q.getBoundingClientRect(h),8>a.height&&(a={top:a.top-(8-a.height)/2,height:8}),h.style.height=q.adaptRangeDifferenceToZoomLevel(a.height,b)+"px",h.style.top=q.adaptRangeDifferenceToZoomLevel(a.top-e.top,b)+"px"):(h.style.height="1em",h.style.top="5%")}var h,d,m,c=!0,e=!1,a=!1,b,q=new core.DomUtils;this.handleUpdate=n;this.refreshCursorBlinking=function(){f||g.getSelectedRange().collapsed?(e=!0,p(!0)):(e=!1,h.style.opacity= -"0")};this.setFocus=function(){e=!0;d.markAsFocussed(!0);p(!0)};this.removeFocus=function(){e=!1;d.markAsFocussed(!1);h.style.opacity="1"};this.show=function(){c=!0;n();d.markAsFocussed(!0)};this.hide=function(){c=!1;n();d.markAsFocussed(!1)};this.setAvatarImageUrl=function(a){d.setImageUrl(a)};this.setColor=function(a){h.style.borderColor=a;d.setColor(a)};this.getCursor=function(){return g};this.getFocusElement=function(){return h};this.toggleHandleVisibility=function(){d.isVisible()?d.hide():d.show()}; -this.showHandle=function(){d.show()};this.hideHandle=function(){d.hide()};this.ensureVisible=function(){var a,b,c,d,e=g.getOdtDocument().getOdfCanvas().getElement().parentNode,f;c=e.offsetWidth-e.clientWidth+5;d=e.offsetHeight-e.clientHeight+5;f=h.getBoundingClientRect();a=f.left-c;b=f.top-d;c=f.right+c;d=f.bottom+d;f=e.getBoundingClientRect();b<f.top?e.scrollTop-=f.top-b:d>f.bottom&&(e.scrollTop+=d-f.bottom);a<f.left?e.scrollLeft-=f.left-a:c>f.right&&(e.scrollLeft+=c-f.right);n()};this.destroy=function(a){d.destroy(function(b){b? -a(b):(m.removeChild(h),a())})};(function(){var a=g.getOdtDocument().getDOM();h=a.createElementNS(a.documentElement.namespaceURI,"span");h.style.top="5%";m=g.getNode();m.appendChild(h);d=new gui.Avatar(m,l);n()})()}; -// Input 55 -gui.EventManager=function(g){function l(){return g.getOdfCanvas().getElement()}function f(){var c=this,a=[];this.handlers=[];this.isSubscribed=!1;this.handleEvent=function(b){-1===a.indexOf(b)&&(a.push(b),c.handlers.forEach(function(a){a(b)}),runtime.setTimeout(function(){a.splice(a.indexOf(b),1)},0))}}function p(c){var a=c.scrollX,b=c.scrollY;this.restore=function(){c.scrollX===a&&c.scrollY===b||c.scrollTo(a,b)}}function r(c){var a=c.scrollTop,b=c.scrollLeft;this.restore=function(){if(c.scrollTop!== -a||c.scrollLeft!==b)c.scrollTop=a,c.scrollLeft=b}}function n(c,a,b){var f="on"+a,h=!1;c.attachEvent&&(h=c.attachEvent(f,b));!h&&c.addEventListener&&(c.addEventListener(a,b,!1),h=!0);h&&!d[a]||!c.hasOwnProperty(f)||(c[f]=b)}var h=runtime.getWindow(),d={beforecut:!0,beforepaste:!0},m,c;this.subscribe=function(d,a){var b=m[d],f=l();b?(b.handlers.push(a),b.isSubscribed||(b.isSubscribed=!0,n(h,d,b.handleEvent),n(f,d,b.handleEvent),n(c,d,b.handleEvent))):n(f,d,a)};this.unsubscribe=function(c,a){var b=m[c], -d=b&&b.handlers.indexOf(a),f=l();b?-1!==d&&b.handlers.splice(d,1):(b="on"+c,f.detachEvent&&f.detachEvent(b,a),f.removeEventListener&&f.removeEventListener(c,a,!1),f[b]===a&&(f[b]=null))};this.focus=function(){var d,a=l(),b=h.getSelection();if(g.getDOM().activeElement!==l()){for(d=a;d&&!d.scrollTop&&!d.scrollLeft;)d=d.parentNode;d=d?new r(d):new p(h);a.focus();d&&d.restore()}b&&b.extend&&(c.parentNode!==a&&a.appendChild(c),b.collapse(c.firstChild,0),b.extend(c,c.childNodes.length))};(function(){var d= -l(),a=d.ownerDocument;runtime.assert(Boolean(h),"EventManager requires a window object to operate correctly");m={mousedown:new f,mouseup:new f,focus:new f};c=a.createElement("div");c.id="eventTrap";c.setAttribute("contenteditable","true");c.style.position="absolute";c.style.left="-10000px";c.appendChild(a.createTextNode("dummy content"));d.appendChild(c)})()}; -// Input 56 -runtime.loadClass("gui.SelectionMover");gui.ShadowCursor=function(g){var l=g.getDOM().createRange(),f=!0;this.removeFromOdtDocument=function(){};this.getMemberId=function(){return gui.ShadowCursor.ShadowCursorMemberId};this.getSelectedRange=function(){return l};this.setSelectedRange=function(g,r){l=g;f=!1!==r};this.hasForwardSelection=function(){return f};this.getOdtDocument=function(){return g};this.getSelectionType=function(){return ops.OdtCursor.RangeSelection};l.setStart(g.getRootNode(),0)}; -gui.ShadowCursor.ShadowCursorMemberId="";(function(){return gui.ShadowCursor})(); -// Input 57 +odf.TextStyleApplicator=function(k,h,b){function p(b){function d(a,c){return"object"===typeof a&&"object"===typeof c?Object.keys(a).every(function(b){return d(a[b],c[b])}):a===c}var c={};this.isStyleApplied=function(a){a=h.getAppliedStylesForElement(a,c);return d(b,a)}}function d(d){var f={};this.applyStyleToContainer=function(c){var a;a=c.getAttributeNS(q,"style-name");var g=c.ownerDocument;a=a||"";if(!f.hasOwnProperty(a)){var e=a,n;n=a?h.createDerivedStyleObject(a,"text",d):d;g=g.createElementNS(r, +"style:style");h.updateStyle(g,n);g.setAttributeNS(r,"style:name",k.generateStyleName());g.setAttributeNS(r,"style:family","text");g.setAttributeNS("urn:webodf:names:scope","scope","document-content");b.appendChild(g);f[e]=g}a=f[a].getAttributeNS(r,"name");c.setAttributeNS(q,"text:style-name",a)}}function n(b,d){var c=b.ownerDocument,a=b.parentNode,m,e,h=new core.LoopWatchDog(1E4);e=[];"span"!==a.localName||a.namespaceURI!==q?(m=c.createElementNS(q,"text:span"),a.insertBefore(m,b),a=!1):(b.previousSibling&& +!g.rangeContainsNode(d,a.firstChild)?(m=a.cloneNode(!1),a.parentNode.insertBefore(m,a.nextSibling)):m=a,a=!0);e.push(b);for(c=b.nextSibling;c&&g.rangeContainsNode(d,c);)h.check(),e.push(c),c=c.nextSibling;e.forEach(function(a){a.parentNode!==m&&m.appendChild(a)});if(c&&a)for(e=m.cloneNode(!1),m.parentNode.insertBefore(e,m.nextSibling);c;)h.check(),a=c.nextSibling,e.appendChild(c),c=a;return m}var g=new core.DomUtils,q=odf.Namespaces.textns,r=odf.Namespaces.stylens;this.applyStyle=function(b,f,c){var a= +{},g,e,h,k;runtime.assert(c&&c.hasOwnProperty("style:text-properties"),"applyStyle without any text properties");a["style:text-properties"]=c["style:text-properties"];h=new d(a);k=new p(a);b.forEach(function(a){g=k.isStyleApplied(a);!1===g&&(e=n(a,f),h.applyStyleToContainer(e))})}}; +// Input 51 /* - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1482,12 +1553,13 @@ gui.ShadowCursor.ShadowCursorMemberId="";(function(){return gui.ShadowCursor})() @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -gui.UndoManager=function(){};gui.UndoManager.prototype.subscribe=function(g,l){};gui.UndoManager.prototype.unsubscribe=function(g,l){};gui.UndoManager.prototype.setOdtDocument=function(g){};gui.UndoManager.prototype.saveInitialState=function(){};gui.UndoManager.prototype.resetInitialState=function(){};gui.UndoManager.prototype.setPlaybackFunction=function(g){};gui.UndoManager.prototype.hasUndoStates=function(){};gui.UndoManager.prototype.hasRedoStates=function(){}; -gui.UndoManager.prototype.moveForward=function(g){};gui.UndoManager.prototype.moveBackward=function(g){};gui.UndoManager.prototype.onOperationExecuted=function(g){};gui.UndoManager.signalUndoStackChanged="undoStackChanged";gui.UndoManager.signalUndoStateCreated="undoStateCreated";gui.UndoManager.signalUndoStateModified="undoStateModified";(function(){return gui.UndoManager})(); -// Input 58 +ops.OpApplyDirectStyling=function(){function k(b,d,f){var c=b.getOdfCanvas().odfContainer(),a=q.splitBoundaries(d),m=g.getTextNodes(d,!1);d={startContainer:d.startContainer,startOffset:d.startOffset,endContainer:d.endContainer,endOffset:d.endOffset};(new odf.TextStyleApplicator(new odf.ObjectNameGenerator(c,h),b.getFormatting(),c.rootElement.automaticStyles)).applyStyle(m,d,f);a.forEach(q.normalizeTextNodes)}var h,b,p,d,n,g=new odf.OdfUtils,q=new core.DomUtils;this.init=function(g){h=g.memberid;b= +g.timestamp;p=parseInt(g.position,10);d=parseInt(g.length,10);n=g.setProperties};this.isEdit=!0;this.group=void 0;this.execute=function(q){var l=q.convertCursorToDomRange(p,d),f=g.getParagraphElements(l);k(q,l,n);l.detach();q.getOdfCanvas().refreshCSS();q.fixCursorPositions();f.forEach(function(c){q.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:c,memberId:h,timeStamp:b})});q.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"ApplyDirectStyling",memberid:h, +timestamp:b,position:p,length:d,setProperties:n}}}; +// Input 52 /* - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1522,12 +1594,13 @@ gui.UndoManager.prototype.moveForward=function(g){};gui.UndoManager.prototype.mo @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -gui.UndoStateRules=function(){function g(f){return f.spec().optype}function l(f){return f.isEdit}this.getOpType=g;this.isEditOperation=l;this.isPartOfOperationSet=function(f,p){if(f.isEdit){if(0===p.length)return!0;var r;if(r=p[p.length-1].isEdit)a:{r=p.filter(l);var n=g(f),h;b:switch(n){case "RemoveText":case "InsertText":h=!0;break b;default:h=!1}if(h&&n===g(r[0])){if(1===r.length){r=!0;break a}n=r[r.length-2].spec().position;r=r[r.length-1].spec().position;h=f.spec().position;if(r===h-(r-n)){r= -!0;break a}}r=!1}return r}return!0}}; -// Input 59 +ops.OpApplyHyperlink=function(){function k(b){for(;b;){if(q.isHyperlink(b))return!0;b=b.parentNode}return!1}var h,b,p,d,n,g=new core.DomUtils,q=new odf.OdfUtils;this.init=function(g){h=g.memberid;b=g.timestamp;p=g.position;d=g.length;n=g.hyperlink};this.isEdit=!0;this.group=void 0;this.execute=function(r){var l=r.getDOMDocument(),f=r.convertCursorToDomRange(p,d),c=g.splitBoundaries(f),a=[],m=q.getTextNodes(f,!1);if(0===m.length)return!1;m.forEach(function(c){var b=q.getParagraphElement(c);runtime.assert(!1=== +k(c),"The given range should not contain any link.");var d=n,f=l.createElementNS(odf.Namespaces.textns,"text:a");f.setAttributeNS(odf.Namespaces.xlinkns,"xlink:type","simple");f.setAttributeNS(odf.Namespaces.xlinkns,"xlink:href",d);c.parentNode.insertBefore(f,c);f.appendChild(c);-1===a.indexOf(b)&&a.push(b)});c.forEach(g.normalizeTextNodes);f.detach();r.getOdfCanvas().refreshSize();r.getOdfCanvas().rerenderAnnotations();a.forEach(function(a){r.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a, +memberId:h,timeStamp:b})});return!0};this.spec=function(){return{optype:"ApplyHyperlink",memberid:h,timestamp:b,position:p,length:d,hyperlink:n}}}; +// Input 53 /* - Copyright (C) 2012 KO GmbH <aditya.bhatt@kogmbh.com> + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1562,12 +1635,13 @@ gui.UndoStateRules=function(){function g(f){return f.spec().optype}function l(f) @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.EditInfo=function(g,l){function f(){var f=[],h;for(h in r)r.hasOwnProperty(h)&&f.push({memberid:h,time:r[h].time});f.sort(function(d,f){return d.time-f.time});return f}var p,r={};this.getNode=function(){return p};this.getOdtDocument=function(){return l};this.getEdits=function(){return r};this.getSortedEdits=function(){return f()};this.addEdit=function(f,h){r[f]={time:h}};this.clearEdits=function(){r={}};this.destroy=function(f){g.parentNode&&g.removeChild(p);f()};p=l.getDOM().createElementNS("urn:webodf:names:editinfo", -"editinfo");g.insertBefore(p,g.firstChild)}; -// Input 60 +ops.OpInsertImage=function(){var k,h,b,p,d,n,g,q,r=odf.Namespaces.drawns,l=odf.Namespaces.svgns,f=odf.Namespaces.textns,c=odf.Namespaces.xlinkns;this.init=function(a){k=a.memberid;h=a.timestamp;b=a.position;p=a.filename;d=a.frameWidth;n=a.frameHeight;g=a.frameStyleName;q=a.frameName};this.isEdit=!0;this.group=void 0;this.execute=function(a){var m=a.getOdfCanvas(),e=a.getTextNodeAtStep(b,k),t,w;if(!e)return!1;t=e.textNode;w=a.getParagraphElement(t);var e=e.offset!==t.length?t.splitText(e.offset):t.nextSibling, +z=a.getDOMDocument(),x=z.createElementNS(r,"draw:image"),z=z.createElementNS(r,"draw:frame");x.setAttributeNS(c,"xlink:href",p);x.setAttributeNS(c,"xlink:type","simple");x.setAttributeNS(c,"xlink:show","embed");x.setAttributeNS(c,"xlink:actuate","onLoad");z.setAttributeNS(r,"draw:style-name",g);z.setAttributeNS(r,"draw:name",q);z.setAttributeNS(f,"text:anchor-type","as-char");z.setAttributeNS(l,"svg:width",d);z.setAttributeNS(l,"svg:height",n);z.appendChild(x);t.parentNode.insertBefore(z,e);a.emit(ops.OdtDocument.signalStepsInserted, +{position:b,length:1});0===t.length&&t.parentNode.removeChild(t);m.addCssForFrameWithImage(z);m.refreshCSS();a.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:w,memberId:k,timeStamp:h});m.rerenderAnnotations();return!0};this.spec=function(){return{optype:"InsertImage",memberid:k,timestamp:h,filename:p,position:b,frameWidth:d,frameHeight:n,frameStyleName:g,frameName:q}}}; +// Input 54 /* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1602,12 +1676,12 @@ ops.EditInfo=function(g,l){function f(){var f=[],h;for(h in r)r.hasOwnProperty(h @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils"); -ops.OpAddAnnotation=function(){function g(d,f,c){var e=d.getTextNodeAtStep(c,l);e&&(d=e.textNode,c=d.parentNode,e.offset!==d.length&&d.splitText(e.offset),c.insertBefore(f,d.nextSibling),0===d.length&&c.removeChild(d))}var l,f,p,r,n,h;this.init=function(d){l=d.memberid;f=parseInt(d.timestamp,10);p=parseInt(d.position,10);r=parseInt(d.length,10)||0;n=d.name};this.isEdit=!0;this.execute=function(d){var m={},c=d.getCursor(l),e,a;a=new core.DomUtils;h=d.getDOM();var b=new Date(f),q,k,t,A;e=h.createElementNS(odf.Namespaces.officens, -"office:annotation");e.setAttributeNS(odf.Namespaces.officens,"office:name",n);q=h.createElementNS(odf.Namespaces.dcns,"dc:creator");q.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",l);q.textContent=d.getMember(l).getProperties().fullName;k=h.createElementNS(odf.Namespaces.dcns,"dc:date");k.appendChild(h.createTextNode(b.toISOString()));b=h.createElementNS(odf.Namespaces.textns,"text:list");t=h.createElementNS(odf.Namespaces.textns,"text:list-item");A=h.createElementNS(odf.Namespaces.textns, -"text:p");t.appendChild(A);b.appendChild(t);e.appendChild(q);e.appendChild(k);e.appendChild(b);m.node=e;if(!m.node)return!1;if(r){e=h.createElementNS(odf.Namespaces.officens,"office:annotation-end");e.setAttributeNS(odf.Namespaces.officens,"office:name",n);m.end=e;if(!m.end)return!1;g(d,m.end,p+r)}g(d,m.node,p);d.emit(ops.OdtDocument.signalStepsInserted,{position:p,length:r});c&&(e=h.createRange(),a=a.getElementsByTagNameNS(m.node,odf.Namespaces.textns,"p")[0],e.selectNodeContents(a),c.setSelectedRange(e), -d.emit(ops.OdtDocument.signalCursorMoved,c));d.getOdfCanvas().addAnnotation(m);d.fixCursorPositions();return!0};this.spec=function(){return{optype:"AddAnnotation",memberid:l,timestamp:f,position:p,length:r,name:n}}}; -// Input 61 +ops.OpInsertTable=function(){function k(b,c){var a;if(1===l.length)a=l[0];else if(3===l.length)switch(b){case 0:a=l[0];break;case p-1:a=l[2];break;default:a=l[1]}else a=l[b];if(1===a.length)return a[0];if(3===a.length)switch(c){case 0:return a[0];case d-1:return a[2];default:return a[1]}return a[c]}var h,b,p,d,n,g,q,r,l;this.init=function(f){h=f.memberid;b=f.timestamp;n=f.position;p=f.initialRows;d=f.initialColumns;g=f.tableName;q=f.tableStyleName;r=f.tableColumnStyleName;l=f.tableCellStyleMatrix}; +this.isEdit=!0;this.group=void 0;this.execute=function(f){var c=f.getTextNodeAtStep(n),a=f.getRootNode();if(c){var m=f.getDOMDocument(),e=m.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table"),l=m.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table-column"),w,z,x,v;q&&e.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:style-name",q);g&&e.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:name",g);l.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0", +"table:number-columns-repeated",d);r&&l.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:style-name",r);e.appendChild(l);for(x=0;x<p;x+=1){l=m.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table-row");for(v=0;v<d;v+=1)w=m.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table-cell"),(z=k(x,v))&&w.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:style-name",z),z=m.createElementNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0", +"text:p"),w.appendChild(z),l.appendChild(w);e.appendChild(l)}c=f.getParagraphElement(c.textNode);a.insertBefore(e,c.nextSibling);f.emit(ops.OdtDocument.signalStepsInserted,{position:n,length:d*p+1});f.getOdfCanvas().refreshSize();f.emit(ops.OdtDocument.signalTableAdded,{tableElement:e,memberId:h,timeStamp:b});f.getOdfCanvas().rerenderAnnotations();return!0}return!1};this.spec=function(){return{optype:"InsertTable",memberid:h,timestamp:b,position:n,initialRows:p,initialColumns:d,tableName:g,tableStyleName:q, +tableColumnStyleName:r,tableCellStyleMatrix:l}}}; +// Input 55 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1645,34 +1719,50 @@ d.emit(ops.OdtDocument.signalCursorMoved,c));d.getOdfCanvas().addAnnotation(m);d @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpAddCursor=function(){var g,l;this.init=function(f){g=f.memberid;l=f.timestamp};this.isEdit=!1;this.execute=function(f){var l=f.getCursor(g);if(l)return!1;l=new ops.OdtCursor(g,f);f.addCursor(l);f.emit(ops.OdtDocument.signalCursorAdded,l);return!0};this.spec=function(){return{optype:"AddCursor",memberid:g,timestamp:l}}}; -// Input 62 +ops.OpInsertText=function(){var k,h,b,p,d;this.init=function(n){k=n.memberid;h=n.timestamp;b=n.position;d=n.text;p="true"===n.moveCursor||!0===n.moveCursor};this.isEdit=!0;this.group=void 0;this.execute=function(n){var g,q,r,l=null,f=n.getDOMDocument(),c,a=0,m,e=n.getCursor(k),t;n.upgradeWhitespacesAtPosition(b);if(g=n.getTextNodeAtStep(b)){q=g.textNode;l=q.nextSibling;r=q.parentNode;c=n.getParagraphElement(q);for(t=0;t<d.length;t+=1)if(" "===d[t]&&(0===t||t===d.length-1||" "===d[t-1])||"\t"===d[t])0=== +a?(g.offset!==q.length&&(l=q.splitText(g.offset)),0<t&&q.appendData(d.substring(0,t))):a<t&&(a=d.substring(a,t),r.insertBefore(f.createTextNode(a),l)),a=t+1,m=" "===d[t]?"text:s":"text:tab",m=f.createElementNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0",m),m.appendChild(f.createTextNode(d[t])),r.insertBefore(m,l);0===a?q.insertData(g.offset,d):a<d.length&&(g=d.substring(a),r.insertBefore(f.createTextNode(g),l));r=q.parentNode;l=q.nextSibling;r.removeChild(q);r.insertBefore(q,l);0===q.length&& +q.parentNode.removeChild(q);n.emit(ops.OdtDocument.signalStepsInserted,{position:b,length:d.length});e&&p&&(n.moveCursor(k,b+d.length,0),n.emit(ops.Document.signalCursorMoved,e));0<b&&(1<b&&n.downgradeWhitespacesAtPosition(b-2),n.downgradeWhitespacesAtPosition(b-1));n.downgradeWhitespacesAtPosition(b);n.downgradeWhitespacesAtPosition(b+d.length-1);n.downgradeWhitespacesAtPosition(b+d.length);n.getOdfCanvas().refreshSize();n.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:c,memberId:k, +timeStamp:h});n.getOdfCanvas().rerenderAnnotations();return!0}return!1};this.spec=function(){return{optype:"InsertText",memberid:k,timestamp:h,position:b,text:d,moveCursor:p}}}; +// Input 56 /* - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart - This file is part of WebODF. + 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. - WebODF 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. + 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/>. - WebODF 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. + 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. - You should have received a copy of the GNU Affero General Public License - along with WebODF. If not, see <http://www.gnu.org/licenses/>. - @licend + 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/ */ -runtime.loadClass("ops.Member");ops.OpAddMember=function(){var g,l,f;this.init=function(p){g=p.memberid;l=parseInt(p.timestamp,10);f=p.setProperties};this.isEdit=!1;this.execute=function(l){if(l.getMember(g))return!1;var r=new ops.Member(g,f);l.addMember(r);l.emit(ops.OdtDocument.signalMemberAdded,r);return!0};this.spec=function(){return{optype:"AddMember",memberid:g,timestamp:l,setProperties:f}}}; -// Input 63 +ops.OpMoveCursor=function(){var k,h,b,p,d;this.init=function(n){k=n.memberid;h=n.timestamp;b=n.position;p=n.length||0;d=n.selectionType||ops.OdtCursor.RangeSelection};this.isEdit=!1;this.group=void 0;this.execute=function(h){var g=h.getCursor(k),q;if(!g)return!1;q=h.convertCursorToDomRange(b,p);g.setSelectedRange(q,0<=p);g.setSelectionType(d);h.emit(ops.Document.signalCursorMoved,g);return!0};this.spec=function(){return{optype:"MoveCursor",memberid:k,timestamp:h,position:b,length:p,selectionType:d}}}; +// Input 57 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1710,10 +1800,9 @@ runtime.loadClass("ops.Member");ops.OpAddMember=function(){var g,l,f;this.init=f @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces"); -ops.OpAddStyle=function(){var g,l,f,p,r,n,h=odf.Namespaces.stylens;this.init=function(d){g=d.memberid;l=d.timestamp;f=d.styleName;p=d.styleFamily;r="true"===d.isAutomaticStyle||!0===d.isAutomaticStyle;n=d.setProperties};this.isEdit=!0;this.execute=function(d){var g=d.getOdfCanvas().odfContainer(),c=d.getFormatting(),e=d.getDOM().createElementNS(h,"style:style");if(!e)return!1;n&&c.updateStyle(e,n);e.setAttributeNS(h,"style:family",p);e.setAttributeNS(h,"style:name",f);r?g.rootElement.automaticStyles.appendChild(e): -g.rootElement.styles.appendChild(e);d.getOdfCanvas().refreshCSS();r||d.emit(ops.OdtDocument.signalCommonStyleCreated,{name:f,family:p});return!0};this.spec=function(){return{optype:"AddStyle",memberid:g,timestamp:l,styleName:f,styleFamily:p,isAutomaticStyle:r,setProperties:n}}}; -// Input 64 +ops.OpRemoveAnnotation=function(){var k,h,b,p,d;this.init=function(n){k=n.memberid;h=n.timestamp;b=parseInt(n.position,10);p=parseInt(n.length,10);d=new core.DomUtils};this.isEdit=!0;this.group=void 0;this.execute=function(h){function g(b){r.parentNode.insertBefore(b,r)}for(var k=h.getIteratorAtPosition(b).container(),r;k.namespaceURI!==odf.Namespaces.officens||"annotation"!==k.localName;)k=k.parentNode;if(null===k)return!1;r=k;k=r.annotationEndElement;h.getOdfCanvas().forgetAnnotations();d.getElementsByTagNameNS(r, +"urn:webodf:names:cursor","cursor").forEach(g);d.getElementsByTagNameNS(r,"urn:webodf:names:cursor","anchor").forEach(g);r.parentNode.removeChild(r);k&&k.parentNode.removeChild(k);h.emit(ops.OdtDocument.signalStepsRemoved,{position:0<b?b-1:b,length:p});h.fixCursorPositions();h.getOdfCanvas().refreshAnnotations();return!0};this.spec=function(){return{optype:"RemoveAnnotation",memberid:k,timestamp:h,position:b,length:p}}}; +// Input 58 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1751,11 +1840,8 @@ g.rootElement.styles.appendChild(e);d.getOdfCanvas().refreshCSS();r||d.emit(ops. @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils");runtime.loadClass("odf.OdfUtils");runtime.loadClass("odf.TextStyleApplicator"); -ops.OpApplyDirectStyling=function(){function g(f,c,e){var a=f.getOdfCanvas().odfContainer(),b=d.splitBoundaries(c),g=h.getTextNodes(c,!1);c={startContainer:c.startContainer,startOffset:c.startOffset,endContainer:c.endContainer,endOffset:c.endOffset};(new odf.TextStyleApplicator(new odf.ObjectNameGenerator(a,l),f.getFormatting(),a.rootElement.automaticStyles)).applyStyle(g,c,e);b.forEach(d.normalizeTextNodes)}var l,f,p,r,n,h=new odf.OdfUtils,d=new core.DomUtils;this.init=function(d){l=d.memberid;f= -d.timestamp;p=parseInt(d.position,10);r=parseInt(d.length,10);n=d.setProperties};this.isEdit=!0;this.execute=function(d){var c=d.convertCursorToDomRange(p,r),e=h.getImpactedParagraphs(c);g(d,c,n);c.detach();d.getOdfCanvas().refreshCSS();d.fixCursorPositions();e.forEach(function(a){d.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a,memberId:l,timeStamp:f})});d.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"ApplyDirectStyling",memberid:l,timestamp:f, -position:p,length:r,setProperties:n}}}; -// Input 65 +ops.OpRemoveBlob=function(){var k,h,b;this.init=function(p){k=p.memberid;h=p.timestamp;b=p.filename};this.isEdit=!0;this.group=void 0;this.execute=function(h){h.getOdfCanvas().odfContainer().removeBlob(b);return!0};this.spec=function(){return{optype:"RemoveBlob",memberid:k,timestamp:h,filename:b}}}; +// Input 59 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1793,13 +1879,11 @@ position:p,length:r,setProperties:n}}}; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpInsertImage=function(){var g,l,f,p,r,n,h,d,m=odf.Namespaces.drawns,c=odf.Namespaces.svgns,e=odf.Namespaces.textns,a=odf.Namespaces.xlinkns;this.init=function(a){g=a.memberid;l=a.timestamp;f=a.position;p=a.filename;r=a.frameWidth;n=a.frameHeight;h=a.frameStyleName;d=a.frameName};this.isEdit=!0;this.execute=function(b){var q=b.getOdfCanvas(),k=b.getTextNodeAtStep(f,g),t,A;if(!k)return!1;t=k.textNode;A=b.getParagraphElement(t);var k=k.offset!==t.length?t.splitText(k.offset):t.nextSibling,w=b.getDOM(), -x=w.createElementNS(m,"draw:image"),w=w.createElementNS(m,"draw:frame");x.setAttributeNS(a,"xlink:href",p);x.setAttributeNS(a,"xlink:type","simple");x.setAttributeNS(a,"xlink:show","embed");x.setAttributeNS(a,"xlink:actuate","onLoad");w.setAttributeNS(m,"draw:style-name",h);w.setAttributeNS(m,"draw:name",d);w.setAttributeNS(e,"text:anchor-type","as-char");w.setAttributeNS(c,"svg:width",r);w.setAttributeNS(c,"svg:height",n);w.appendChild(x);t.parentNode.insertBefore(w,k);b.emit(ops.OdtDocument.signalStepsInserted, -{position:f,length:1});0===t.length&&t.parentNode.removeChild(t);q.addCssForFrameWithImage(w);q.refreshCSS();b.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:A,memberId:g,timeStamp:l});q.rerenderAnnotations();return!0};this.spec=function(){return{optype:"InsertImage",memberid:g,timestamp:l,filename:p,position:f,frameWidth:r,frameHeight:n,frameStyleName:h,frameName:d}}}; -// Input 66 +ops.OpRemoveCursor=function(){var k,h;this.init=function(b){k=b.memberid;h=b.timestamp};this.isEdit=!1;this.group=void 0;this.execute=function(b){return b.removeCursor(k)?!0:!1};this.spec=function(){return{optype:"RemoveCursor",memberid:k,timestamp:h}}}; +// Input 60 /* - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1834,12 +1918,35 @@ x=w.createElementNS(m,"draw:image"),w=w.createElementNS(m,"draw:frame");x.setAtt @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpInsertTable=function(){function g(d,a){var b;if(1===c.length)b=c[0];else if(3===c.length)switch(d){case 0:b=c[0];break;case p-1:b=c[2];break;default:b=c[1]}else b=c[d];if(1===b.length)return b[0];if(3===b.length)switch(a){case 0:return b[0];case r-1:return b[2];default:return b[1]}return b[a]}var l,f,p,r,n,h,d,m,c;this.init=function(e){l=e.memberid;f=e.timestamp;n=e.position;p=e.initialRows;r=e.initialColumns;h=e.tableName;d=e.tableStyleName;m=e.tableColumnStyleName;c=e.tableCellStyleMatrix}; -this.isEdit=!0;this.execute=function(c){var a=c.getTextNodeAtStep(n),b=c.getRootNode();if(a){var q=c.getDOM(),k=q.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table"),t=q.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table-column"),A,w,x,v;d&&k.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:style-name",d);h&&k.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:name",h);t.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0", -"table:number-columns-repeated",r);m&&t.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:style-name",m);k.appendChild(t);for(x=0;x<p;x+=1){t=q.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table-row");for(v=0;v<r;v+=1)A=q.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table-cell"),(w=g(x,v))&&A.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:style-name",w),w=q.createElementNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0", -"text:p"),A.appendChild(w),t.appendChild(A);k.appendChild(t)}a=c.getParagraphElement(a.textNode);b.insertBefore(k,a.nextSibling);c.emit(ops.OdtDocument.signalStepsInserted,{position:n,length:r*p+1});c.getOdfCanvas().refreshSize();c.emit(ops.OdtDocument.signalTableAdded,{tableElement:k,memberId:l,timeStamp:f});c.getOdfCanvas().rerenderAnnotations();return!0}return!1};this.spec=function(){return{optype:"InsertTable",memberid:l,timestamp:f,position:n,initialRows:p,initialColumns:r,tableName:h,tableStyleName:d, -tableColumnStyleName:m,tableCellStyleMatrix:c}}}; -// Input 67 +ops.OpRemoveHyperlink=function(){var k,h,b,p,d=new core.DomUtils,n=new odf.OdfUtils;this.init=function(d){k=d.memberid;h=d.timestamp;b=d.position;p=d.length};this.isEdit=!0;this.group=void 0;this.execute=function(g){var q=g.convertCursorToDomRange(b,p),r=n.getHyperlinkElements(q);runtime.assert(1===r.length,"The given range should only contain a single link.");r=d.mergeIntoParent(r[0]);q.detach();g.getOdfCanvas().refreshSize();g.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:n.getParagraphElement(r), +memberId:k,timeStamp:h});g.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"RemoveHyperlink",memberid:k,timestamp:h,position:b,length:p}}}; +// Input 61 +/* + + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +ops.OpRemoveMember=function(){var k,h;this.init=function(b){k=b.memberid;h=parseInt(b.timestamp,10)};this.isEdit=!1;this.group=void 0;this.execute=function(b){if(!b.getMember(k))return!1;b.removeMember(k);b.emit(ops.Document.signalMemberRemoved,k);return!0};this.spec=function(){return{optype:"RemoveMember",memberid:k,timestamp:h}}}; +// Input 62 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1877,11 +1984,8 @@ tableColumnStyleName:m,tableCellStyleMatrix:c}}}; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpInsertText=function(){var g,l,f,p,r;this.init=function(n){g=n.memberid;l=n.timestamp;f=n.position;p=n.text;r="true"===n.moveCursor||!0===n.moveCursor};this.isEdit=!0;this.execute=function(n){var h,d,m,c=null,e=n.getDOM(),a,b=0,q,k=n.getCursor(g),t;n.upgradeWhitespacesAtPosition(f);if(h=n.getTextNodeAtStep(f)){d=h.textNode;c=d.nextSibling;m=d.parentNode;a=n.getParagraphElement(d);for(t=0;t<p.length;t+=1)if(" "===p[t]&&(0===t||t===p.length-1||" "===p[t-1])||"\t"===p[t])0===b?(h.offset!==d.length&& -(c=d.splitText(h.offset)),0<t&&d.appendData(p.substring(0,t))):b<t&&(b=p.substring(b,t),m.insertBefore(e.createTextNode(b),c)),b=t+1,q=" "===p[t]?"text:s":"text:tab",q=e.createElementNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0",q),q.appendChild(e.createTextNode(p[t])),m.insertBefore(q,c);0===b?d.insertData(h.offset,p):b<p.length&&(h=p.substring(b),m.insertBefore(e.createTextNode(h),c));m=d.parentNode;c=d.nextSibling;m.removeChild(d);m.insertBefore(d,c);0===d.length&&d.parentNode.removeChild(d); -n.emit(ops.OdtDocument.signalStepsInserted,{position:f,length:p.length});k&&r&&(n.moveCursor(g,f+p.length,0),n.emit(ops.OdtDocument.signalCursorMoved,k));0<f&&(1<f&&n.downgradeWhitespacesAtPosition(f-2),n.downgradeWhitespacesAtPosition(f-1));n.downgradeWhitespacesAtPosition(f);n.downgradeWhitespacesAtPosition(f+p.length-1);n.downgradeWhitespacesAtPosition(f+p.length);n.getOdfCanvas().refreshSize();n.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a,memberId:g,timeStamp:l});n.getOdfCanvas().rerenderAnnotations(); -return!0}return!1};this.spec=function(){return{optype:"InsertText",memberid:g,timestamp:l,position:f,text:p,moveCursor:r}}}; -// Input 68 +ops.OpRemoveStyle=function(){var k,h,b,p;this.init=function(d){k=d.memberid;h=d.timestamp;b=d.styleName;p=d.styleFamily};this.isEdit=!0;this.group=void 0;this.execute=function(d){var h=d.getStyleElement(b,p);if(!h)return!1;h.parentNode.removeChild(h);d.getOdfCanvas().refreshCSS();d.emit(ops.OdtDocument.signalCommonStyleDeleted,{name:b,family:p});return!0};this.spec=function(){return{optype:"RemoveStyle",memberid:k,timestamp:h,styleName:b,styleFamily:p}}}; +// Input 63 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1919,8 +2023,12 @@ return!0}return!1};this.spec=function(){return{optype:"InsertText",memberid:g,ti @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpMoveCursor=function(){var g,l,f,p,r;this.init=function(n){g=n.memberid;l=n.timestamp;f=n.position;p=n.length||0;r=n.selectionType||ops.OdtCursor.RangeSelection};this.isEdit=!1;this.execute=function(l){var h=l.getCursor(g),d;if(!h)return!1;d=l.convertCursorToDomRange(f,p);h.setSelectedRange(d,0<=p);h.setSelectionType(r);l.emit(ops.OdtDocument.signalCursorMoved,h);return!0};this.spec=function(){return{optype:"MoveCursor",memberid:g,timestamp:l,position:f,length:p,selectionType:r}}}; -// Input 69 +ops.OpRemoveText=function(){function k(b){function d(a){return q.hasOwnProperty(a.namespaceURI)||"br"===a.localName&&n.isLineBreak(a.parentNode)||a.nodeType===Node.TEXT_NODE&&q.hasOwnProperty(a.parentNode.namespaceURI)}function f(a){if(n.isCharacterElement(a))return!1;if(a.nodeType===Node.TEXT_NODE)return 0===a.textContent.length;for(a=a.firstChild;a;){if(q.hasOwnProperty(a.namespaceURI)||!f(a))return!1;a=a.nextSibling}return!0}function c(a){var m;a.nodeType===Node.TEXT_NODE?(m=a.parentNode,m.removeChild(a)): +m=g.removeUnwantedNodes(a,d);return m&&!n.isParagraph(m)&&m!==b&&f(m)?c(m):m}this.isEmpty=f;this.mergeChildrenIntoParent=c}var h,b,p,d,n,g,q={};this.init=function(k){runtime.assert(0<=k.length,"OpRemoveText only supports positive lengths");h=k.memberid;b=k.timestamp;p=parseInt(k.position,10);d=parseInt(k.length,10);n=new odf.OdfUtils;g=new core.DomUtils;q[odf.Namespaces.dbns]=!0;q[odf.Namespaces.dcns]=!0;q[odf.Namespaces.dr3dns]=!0;q[odf.Namespaces.drawns]=!0;q[odf.Namespaces.chartns]=!0;q[odf.Namespaces.formns]= +!0;q[odf.Namespaces.numberns]=!0;q[odf.Namespaces.officens]=!0;q[odf.Namespaces.presentationns]=!0;q[odf.Namespaces.stylens]=!0;q[odf.Namespaces.svgns]=!0;q[odf.Namespaces.tablens]=!0;q[odf.Namespaces.textns]=!0};this.isEdit=!0;this.group=void 0;this.execute=function(q){var l,f,c,a,m=q.getCursor(h),e=new k(q.getRootNode());q.upgradeWhitespacesAtPosition(p);q.upgradeWhitespacesAtPosition(p+d);f=q.convertCursorToDomRange(p,d);g.splitBoundaries(f);l=q.getParagraphElement(f.startContainer);c=n.getTextElements(f, +!1,!0);a=n.getParagraphElements(f);f.detach();c.forEach(function(a){e.mergeChildrenIntoParent(a)});f=a.reduce(function(a,c){var b,d=a,f=c,g,m=null;e.isEmpty(a)&&(c.parentNode!==a.parentNode&&(g=c.parentNode,a.parentNode.insertBefore(c,a.nextSibling)),f=a,d=c,m=d.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo").item(0)||d.firstChild);for(;f.firstChild;)b=f.firstChild,f.removeChild(b),"editinfo"!==b.localName&&d.insertBefore(b,m);g&&e.isEmpty(g)&&e.mergeChildrenIntoParent(g);e.mergeChildrenIntoParent(f); +return d});q.emit(ops.OdtDocument.signalStepsRemoved,{position:p,length:d});q.downgradeWhitespacesAtPosition(p);q.fixCursorPositions();q.getOdfCanvas().refreshSize();q.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:f||l,memberId:h,timeStamp:b});m&&(m.resetSelectionType(),q.emit(ops.Document.signalCursorMoved,m));q.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"RemoveText",memberid:h,timestamp:b,position:p,length:d}}}; +// Input 64 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -1958,11 +2066,8 @@ ops.OpMoveCursor=function(){var g,l,f,p,r;this.init=function(n){g=n.memberid;l=n @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces");runtime.loadClass("core.DomUtils"); -ops.OpRemoveAnnotation=function(){var g,l,f,p,r;this.init=function(n){g=n.memberid;l=n.timestamp;f=parseInt(n.position,10);p=parseInt(n.length,10);r=new core.DomUtils};this.isEdit=!0;this.execute=function(g){for(var h=g.getIteratorAtPosition(f).container(),d,l,c;h.namespaceURI!==odf.Namespaces.officens||"annotation"!==h.localName;)h=h.parentNode;if(null===h)return!1;(d=h.getAttributeNS(odf.Namespaces.officens,"name"))&&(l=r.getElementsByTagNameNS(g.getRootNode(),odf.Namespaces.officens,"annotation-end").filter(function(c){return d=== -c.getAttributeNS(odf.Namespaces.officens,"name")})[0]||null);g.getOdfCanvas().forgetAnnotations();for(c=r.getElementsByTagNameNS(h,"urn:webodf:names:cursor","cursor");c.length;)h.parentNode.insertBefore(c.pop(),h);h.parentNode.removeChild(h);l&&l.parentNode.removeChild(l);g.emit(ops.OdtDocument.signalStepsRemoved,{position:0<f?f-1:f,length:p});g.fixCursorPositions();g.getOdfCanvas().refreshAnnotations();return!0};this.spec=function(){return{optype:"RemoveAnnotation",memberid:g,timestamp:l,position:f, -length:p}}}; -// Input 70 +ops.OpSetBlob=function(){var k,h,b,p,d;this.init=function(n){k=n.memberid;h=n.timestamp;b=n.filename;p=n.mimetype;d=n.content};this.isEdit=!0;this.group=void 0;this.execute=function(h){h.getOdfCanvas().odfContainer().setBlob(b,p,d);return!0};this.spec=function(){return{optype:"SetBlob",memberid:k,timestamp:h,filename:b,mimetype:p,content:d}}}; +// Input 65 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -2000,8 +2105,9 @@ length:p}}}; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpRemoveBlob=function(){var g,l,f;this.init=function(p){g=p.memberid;l=p.timestamp;f=p.filename};this.isEdit=!0;this.execute=function(g){g.getOdfCanvas().odfContainer().removeBlob(f);return!0};this.spec=function(){return{optype:"RemoveBlob",memberid:g,timestamp:l,filename:f}}}; -// Input 71 +ops.OpSetParagraphStyle=function(){var k,h,b,p;this.init=function(d){k=d.memberid;h=d.timestamp;b=d.position;p=d.styleName};this.isEdit=!0;this.group=void 0;this.execute=function(d){var n;n=d.getIteratorAtPosition(b);return(n=d.getParagraphElement(n.container()))?(""!==p?n.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","text:style-name",p):n.removeAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","style-name"),d.getOdfCanvas().refreshSize(),d.emit(ops.OdtDocument.signalParagraphChanged, +{paragraphElement:n,timeStamp:h,memberId:k}),d.getOdfCanvas().rerenderAnnotations(),!0):!1};this.spec=function(){return{optype:"SetParagraphStyle",memberid:k,timestamp:h,position:b,styleName:p}}}; +// Input 66 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -2039,8 +2145,10 @@ ops.OpRemoveBlob=function(){var g,l,f;this.init=function(p){g=p.memberid;l=p.tim @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpRemoveCursor=function(){var g,l;this.init=function(f){g=f.memberid;l=f.timestamp};this.isEdit=!1;this.execute=function(f){return f.removeCursor(g)?!0:!1};this.spec=function(){return{optype:"RemoveCursor",memberid:g,timestamp:l}}}; -// Input 72 +ops.OpSplitParagraph=function(){var k,h,b,p,d;this.init=function(n){k=n.memberid;h=n.timestamp;b=n.position;p="true"===n.moveCursor||!0===n.moveCursor;d=new odf.OdfUtils};this.isEdit=!0;this.group=void 0;this.execute=function(n){var g,q,r,l,f,c,a,m=n.getCursor(k);n.upgradeWhitespacesAtPosition(b);g=n.getTextNodeAtStep(b);if(!g)return!1;q=n.getParagraphElement(g.textNode);if(!q)return!1;r=d.isListItem(q.parentNode)?q.parentNode:q;0===g.offset?(a=g.textNode.previousSibling,c=null):(a=g.textNode,c=g.offset>= +g.textNode.length?null:g.textNode.splitText(g.offset));for(l=g.textNode;l!==r;){l=l.parentNode;f=l.cloneNode(!1);c&&f.appendChild(c);if(a)for(;a&&a.nextSibling;)f.appendChild(a.nextSibling);else for(;l.firstChild;)f.appendChild(l.firstChild);l.parentNode.insertBefore(f,l.nextSibling);a=l;c=f}d.isListItem(c)&&(c=c.childNodes.item(0));0===g.textNode.length&&g.textNode.parentNode.removeChild(g.textNode);n.emit(ops.OdtDocument.signalStepsInserted,{position:b,length:1});m&&p&&(n.moveCursor(k,b+1,0),n.emit(ops.Document.signalCursorMoved, +m));n.fixCursorPositions();n.getOdfCanvas().refreshSize();n.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:q,memberId:k,timeStamp:h});n.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:c,memberId:k,timeStamp:h});n.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"SplitParagraph",memberid:k,timestamp:h,position:b,moveCursor:p}}}; +// Input 67 /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -2065,8 +2173,35 @@ ops.OpRemoveCursor=function(){var g,l;this.init=function(f){g=f.memberid;l=f.tim @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.Member");ops.OpRemoveMember=function(){var g,l;this.init=function(f){g=f.memberid;l=parseInt(f.timestamp,10)};this.isEdit=!1;this.execute=function(f){if(!f.getMember(g))return!1;f.removeMember(g);f.emit(ops.OdtDocument.signalMemberRemoved,g);return!0};this.spec=function(){return{optype:"RemoveMember",memberid:g,timestamp:l}}}; -// Input 73 +ops.OpUpdateMember=function(){function k(b){var d="//dc:creator[@editinfo:memberid='"+h+"']";b=xmldom.XPath.getODFElementsWithXPath(b.getRootNode(),d,function(b){return"editinfo"===b?"urn:webodf:names:editinfo":odf.Namespaces.lookupNamespaceURI(b)});for(d=0;d<b.length;d+=1)b[d].textContent=p.fullName}var h,b,p,d;this.init=function(k){h=k.memberid;b=parseInt(k.timestamp,10);p=k.setProperties;d=k.removedProperties};this.isEdit=!1;this.group=void 0;this.execute=function(b){var g=b.getMember(h);if(!g)return!1; +d&&g.removeProperties(d);p&&(g.setProperties(p),p.fullName&&k(b));b.emit(ops.Document.signalMemberUpdated,g);return!0};this.spec=function(){return{optype:"UpdateMember",memberid:h,timestamp:b,setProperties:p,removedProperties:d}}}; +// Input 68 +/* + + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +ops.OpUpdateMetadata=function(){var k,h,b,p;this.init=function(d){k=d.memberid;h=parseInt(d.timestamp,10);b=d.setProperties;p=d.removedProperties};this.isEdit=!0;this.group=void 0;this.execute=function(d){d=d.getOdfCanvas().odfContainer();var h=[];p&&(h=p.attributes.split(","));d.setMetadata(b,h);return!0};this.spec=function(){return{optype:"UpdateMetadata",memberid:k,timestamp:h,setProperties:b,removedProperties:p}}}; +// Input 69 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -2104,8 +2239,10 @@ runtime.loadClass("ops.Member");ops.OpRemoveMember=function(){var g,l;this.init= @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpRemoveStyle=function(){var g,l,f,p;this.init=function(r){g=r.memberid;l=r.timestamp;f=r.styleName;p=r.styleFamily};this.isEdit=!0;this.execute=function(g){var l=g.getStyleElement(f,p);if(!l)return!1;l.parentNode.removeChild(l);g.getOdfCanvas().refreshCSS();g.emit(ops.OdtDocument.signalCommonStyleDeleted,{name:f,family:p});return!0};this.spec=function(){return{optype:"RemoveStyle",memberid:g,timestamp:l,styleName:f,styleFamily:p}}}; -// Input 74 +ops.OpUpdateParagraphStyle=function(){function k(b,d){var g,f,c=d?d.split(","):[];for(g=0;g<c.length;g+=1)f=c[g].split(":"),b.removeAttributeNS(odf.Namespaces.lookupNamespaceURI(f[0]),f[1])}var h,b,p,d,n,g=odf.Namespaces.stylens;this.init=function(g){h=g.memberid;b=g.timestamp;p=g.styleName;d=g.setProperties;n=g.removedProperties};this.isEdit=!0;this.group=void 0;this.execute=function(b){var h=b.getFormatting(),l,f,c;return(l=""!==p?b.getParagraphStyleElement(p):h.getDefaultStyleElement("paragraph"))? +(f=l.getElementsByTagNameNS(g,"paragraph-properties").item(0),c=l.getElementsByTagNameNS(g,"text-properties").item(0),d&&h.updateStyle(l,d),n&&(h=n["style:paragraph-properties"],f&&h&&(k(f,h.attributes),0===f.attributes.length&&l.removeChild(f)),h=n["style:text-properties"],c&&h&&(k(c,h.attributes),0===c.attributes.length&&l.removeChild(c)),k(l,n.attributes)),b.getOdfCanvas().refreshCSS(),b.emit(ops.OdtDocument.signalParagraphStyleModified,p),b.getOdfCanvas().rerenderAnnotations(),!0):!1};this.spec= +function(){return{optype:"UpdateParagraphStyle",memberid:h,timestamp:b,styleName:p,setProperties:d,removedProperties:n}}}; +// Input 70 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -2143,16 +2280,12 @@ ops.OpRemoveStyle=function(){var g,l,f,p;this.init=function(r){g=r.memberid;l=r. @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfUtils");runtime.loadClass("core.DomUtils"); -ops.OpRemoveText=function(){function g(f){function c(a){return d.hasOwnProperty(a.namespaceURI)||"br"===a.localName&&n.isLineBreak(a.parentNode)||a.nodeType===Node.TEXT_NODE&&d.hasOwnProperty(a.parentNode.namespaceURI)}function e(a){if(n.isCharacterElement(a))return!1;if(a.nodeType===Node.TEXT_NODE)return 0===a.textContent.length;for(a=a.firstChild;a;){if(d.hasOwnProperty(a.namespaceURI)||!e(a))return!1;a=a.nextSibling}return!0}function a(b){var d;b.nodeType===Node.TEXT_NODE?(d=b.parentNode,d.removeChild(b)): -d=h.removeUnwantedNodes(b,c);return!n.isParagraph(d)&&d!==f&&e(d)?a(d):d}this.isEmpty=e;this.mergeChildrenIntoParent=a}var l,f,p,r,n,h,d={};this.init=function(g){runtime.assert(0<=g.length,"OpRemoveText only supports positive lengths");l=g.memberid;f=g.timestamp;p=parseInt(g.position,10);r=parseInt(g.length,10);n=new odf.OdfUtils;h=new core.DomUtils;d[odf.Namespaces.dbns]=!0;d[odf.Namespaces.dcns]=!0;d[odf.Namespaces.dr3dns]=!0;d[odf.Namespaces.drawns]=!0;d[odf.Namespaces.chartns]=!0;d[odf.Namespaces.formns]= -!0;d[odf.Namespaces.numberns]=!0;d[odf.Namespaces.officens]=!0;d[odf.Namespaces.presentationns]=!0;d[odf.Namespaces.stylens]=!0;d[odf.Namespaces.svgns]=!0;d[odf.Namespaces.tablens]=!0;d[odf.Namespaces.textns]=!0};this.isEdit=!0;this.execute=function(d){var c,e,a,b,q=d.getCursor(l),k=new g(d.getRootNode());d.upgradeWhitespacesAtPosition(p);d.upgradeWhitespacesAtPosition(p+r);e=d.convertCursorToDomRange(p,r);h.splitBoundaries(e);c=d.getParagraphElement(e.startContainer);a=n.getTextElements(e,!1,!0); -b=n.getParagraphElements(e);e.detach();a.forEach(function(a){k.mergeChildrenIntoParent(a)});e=b.reduce(function(a,b){var c,d=!1,e=a,f=b,h,g=null;k.isEmpty(a)&&(d=!0,b.parentNode!==a.parentNode&&(h=b.parentNode,a.parentNode.insertBefore(b,a.nextSibling)),f=a,e=b,g=e.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo")[0]||e.firstChild);for(;f.hasChildNodes();)c=d?f.lastChild:f.firstChild,f.removeChild(c),"editinfo"!==c.localName&&e.insertBefore(c,g);h&&k.isEmpty(h)&&k.mergeChildrenIntoParent(h); -k.mergeChildrenIntoParent(f);return e});d.emit(ops.OdtDocument.signalStepsRemoved,{position:p,length:r});d.downgradeWhitespacesAtPosition(p);d.fixCursorPositions();d.getOdfCanvas().refreshSize();d.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:e||c,memberId:l,timeStamp:f});q&&(q.resetSelectionType(),d.emit(ops.OdtDocument.signalCursorMoved,q));d.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"RemoveText",memberid:l,timestamp:f,position:p,length:r}}}; -// Input 75 +ops.OperationFactory=function(){var k;this.register=function(h,b){k[h]=b};this.create=function(h){var b=null,p=k[h.optype];p&&(b=new p,b.init(h));return b};k={AddMember:ops.OpAddMember,UpdateMember:ops.OpUpdateMember,RemoveMember:ops.OpRemoveMember,AddCursor:ops.OpAddCursor,ApplyDirectStyling:ops.OpApplyDirectStyling,SetBlob:ops.OpSetBlob,RemoveBlob:ops.OpRemoveBlob,InsertImage:ops.OpInsertImage,InsertTable:ops.OpInsertTable,InsertText:ops.OpInsertText,RemoveText:ops.OpRemoveText,SplitParagraph:ops.OpSplitParagraph, +SetParagraphStyle:ops.OpSetParagraphStyle,UpdateParagraphStyle:ops.OpUpdateParagraphStyle,AddStyle:ops.OpAddStyle,RemoveStyle:ops.OpRemoveStyle,MoveCursor:ops.OpMoveCursor,RemoveCursor:ops.OpRemoveCursor,AddAnnotation:ops.OpAddAnnotation,RemoveAnnotation:ops.OpRemoveAnnotation,UpdateMetadata:ops.OpUpdateMetadata,ApplyHyperlink:ops.OpApplyHyperlink,RemoveHyperlink:ops.OpRemoveHyperlink}}; +// Input 71 /* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2187,11 +2320,12 @@ k.mergeChildrenIntoParent(f);return e});d.emit(ops.OdtDocument.signalStepsRemove @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpSetBlob=function(){var g,l,f,p,r;this.init=function(n){g=n.memberid;l=n.timestamp;f=n.filename;p=n.mimetype;r=n.content};this.isEdit=!0;this.execute=function(g){g.getOdfCanvas().odfContainer().setBlob(f,p,r);return!0};this.spec=function(){return{optype:"SetBlob",memberid:g,timestamp:l,filename:f,mimetype:p,content:r}}}; -// Input 76 +ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFactory=function(k){};ops.OperationRouter.prototype.setPlaybackFunction=function(k){};ops.OperationRouter.prototype.push=function(k){};ops.OperationRouter.prototype.close=function(k){};ops.OperationRouter.prototype.subscribe=function(k,h){};ops.OperationRouter.prototype.unsubscribe=function(k,h){};ops.OperationRouter.prototype.hasLocalUnsyncedOps=function(){};ops.OperationRouter.prototype.hasSessionHostConnection=function(){}; +ops.OperationRouter.signalProcessingBatchStart="router/batchstart";ops.OperationRouter.signalProcessingBatchEnd="router/batchend"; +// Input 72 /* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2226,9 +2360,9 @@ ops.OpSetBlob=function(){var g,l,f,p,r;this.init=function(n){g=n.memberid;l=n.ti @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpSetParagraphStyle=function(){var g,l,f,p;this.init=function(r){g=r.memberid;l=r.timestamp;f=r.position;p=r.styleName};this.isEdit=!0;this.execute=function(r){var n;n=r.getIteratorAtPosition(f);return(n=r.getParagraphElement(n.container()))?(""!==p?n.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","text:style-name",p):n.removeAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","style-name"),r.getOdfCanvas().refreshSize(),r.emit(ops.OdtDocument.signalParagraphChanged, -{paragraphElement:n,timeStamp:l,memberId:g}),r.getOdfCanvas().rerenderAnnotations(),!0):!1};this.spec=function(){return{optype:"SetParagraphStyle",memberid:g,timestamp:l,position:f,styleName:p}}}; -// Input 77 +ops.TrivialOperationRouter=function(){var k=new core.EventNotifier([ops.OperationRouter.signalProcessingBatchStart,ops.OperationRouter.signalProcessingBatchEnd]),h,b,p=0;this.setOperationFactory=function(b){h=b};this.setPlaybackFunction=function(d){b=d};this.push=function(d){p+=1;k.emit(ops.OperationRouter.signalProcessingBatchStart,{});d.forEach(function(d){d=d.spec();d.timestamp=(new Date).getTime();d=h.create(d);d.group="g"+p;b(d)});k.emit(ops.OperationRouter.signalProcessingBatchEnd,{})};this.close= +function(b){b()};this.subscribe=function(b,h){k.subscribe(b,h)};this.unsubscribe=function(b,h){k.unsubscribe(b,h)};this.hasLocalUnsyncedOps=function(){return!1};this.hasSessionHostConnection=function(){return!0}}; +// Input 73 /* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @@ -2266,10 +2400,9 @@ ops.OpSetParagraphStyle=function(){var g,l,f,p;this.init=function(r){g=r.memberi @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpSplitParagraph=function(){var g,l,f,p,r;this.init=function(n){g=n.memberid;l=n.timestamp;f=n.position;p="true"===n.moveCursor||!0===n.moveCursor;r=new odf.OdfUtils};this.isEdit=!0;this.execute=function(n){var h,d,m,c,e,a,b,q=n.getCursor(g);n.upgradeWhitespacesAtPosition(f);h=n.getTextNodeAtStep(f);if(!h)return!1;d=n.getParagraphElement(h.textNode);if(!d)return!1;m=r.isListItem(d.parentNode)?d.parentNode:d;0===h.offset?(b=h.textNode.previousSibling,a=null):(b=h.textNode,a=h.offset>=h.textNode.length? -null:h.textNode.splitText(h.offset));for(c=h.textNode;c!==m;){c=c.parentNode;e=c.cloneNode(!1);a&&e.appendChild(a);if(b)for(;b&&b.nextSibling;)e.appendChild(b.nextSibling);else for(;c.firstChild;)e.appendChild(c.firstChild);c.parentNode.insertBefore(e,c.nextSibling);b=c;a=e}r.isListItem(a)&&(a=a.childNodes[0]);0===h.textNode.length&&h.textNode.parentNode.removeChild(h.textNode);n.emit(ops.OdtDocument.signalStepsInserted,{position:f,length:1});q&&p&&(n.moveCursor(g,f+1,0),n.emit(ops.OdtDocument.signalCursorMoved, -q));n.fixCursorPositions();n.getOdfCanvas().refreshSize();n.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:d,memberId:g,timeStamp:l});n.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a,memberId:g,timeStamp:l});n.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"SplitParagraph",memberid:g,timestamp:l,position:f,moveCursor:p}}}; -// Input 78 +ops.Session=function(k){function h(b){d.emit(ops.OdtDocument.signalProcessingBatchStart,b)}function b(b){d.emit(ops.OdtDocument.signalProcessingBatchEnd,b)}var p=new ops.OperationFactory,d=new ops.OdtDocument(k),n=null;this.setOperationFactory=function(b){p=b;n&&n.setOperationFactory(p)};this.setOperationRouter=function(g){n&&(n.unsubscribe(ops.OperationRouter.signalProcessingBatchStart,h),n.unsubscribe(ops.OperationRouter.signalProcessingBatchEnd,b));n=g;n.subscribe(ops.OperationRouter.signalProcessingBatchStart, +h);n.subscribe(ops.OperationRouter.signalProcessingBatchEnd,b);g.setPlaybackFunction(function(b){d.emit(ops.OdtDocument.signalOperationStart,b);return b.execute(d)?(d.emit(ops.OdtDocument.signalOperationEnd,b),!0):!1});g.setOperationFactory(p)};this.getOperationFactory=function(){return p};this.getOdtDocument=function(){return d};this.enqueue=function(b){n.push(b)};this.close=function(b){n.close(function(h){h?b(h):d.close(b)})};this.destroy=function(b){d.destroy(b)};this.setOperationRouter(new ops.TrivialOperationRouter)}; +// Input 74 /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -2294,10 +2427,63 @@ q));n.fixCursorPositions();n.getOdfCanvas().refreshSize();n.emit(ops.OdtDocument @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.Member");runtime.loadClass("xmldom.XPath"); -ops.OpUpdateMember=function(){function g(){var f="//dc:creator[@editinfo:memberid='"+l+"']",f=xmldom.XPath.getODFElementsWithXPath(n.getRootNode(),f,function(d){return"editinfo"===d?"urn:webodf:names:editinfo":odf.Namespaces.lookupNamespaceURI(d)}),d;for(d=0;d<f.length;d+=1)f[d].textContent=p.fullName}var l,f,p,r,n;this.init=function(h){l=h.memberid;f=parseInt(h.timestamp,10);p=h.setProperties;r=h.removedProperties};this.isEdit=!1;this.execute=function(f){n=f;var d=f.getMember(l);if(!d)return!1;r&& -d.removeProperties(r);p&&(d.setProperties(p),p.fullName&&g());f.emit(ops.OdtDocument.signalMemberUpdated,d);return!0};this.spec=function(){return{optype:"UpdateMember",memberid:l,timestamp:f,setProperties:p,removedProperties:r}}}; -// Input 79 +gui.AnnotationController=function(k,h){function b(){var b=g.getCursor(h),b=b&&b.getNode(),c=!1;if(b){a:{for(c=g.getRootNode();b&&b!==c;){if(b.namespaceURI===l&&"annotation"===b.localName){b=!0;break a}b=b.parentNode}b=!1}c=!b}c!==q&&(q=c,r.emit(gui.AnnotationController.annotatableChanged,q))}function p(d){d.getMemberId()===h&&b()}function d(d){d===h&&b()}function n(d){d.getMemberId()===h&&b()}var g=k.getOdtDocument(),q=!1,r=new core.EventNotifier([gui.AnnotationController.annotatableChanged]),l=odf.Namespaces.officens; +this.isAnnotatable=function(){return q};this.addAnnotation=function(){var b=new ops.OpAddAnnotation,c=g.getCursorSelection(h),a=c.length,c=c.position;q&&(c=0<=a?c:c+a,a=Math.abs(a),b.init({memberid:h,position:c,length:a,name:h+Date.now()}),k.enqueue([b]))};this.removeAnnotation=function(b){var c,a;c=g.convertDomPointToCursorStep(b,0)+1;a=g.convertDomPointToCursorStep(b,b.childNodes.length);b=new ops.OpRemoveAnnotation;b.init({memberid:h,position:c,length:a-c});a=new ops.OpMoveCursor;a.init({memberid:h, +position:0<c?c-1:c,length:0});k.enqueue([b,a])};this.subscribe=function(b,c){r.subscribe(b,c)};this.unsubscribe=function(b,c){r.unsubscribe(b,c)};this.destroy=function(b){g.unsubscribe(ops.Document.signalCursorAdded,p);g.unsubscribe(ops.Document.signalCursorRemoved,d);g.unsubscribe(ops.Document.signalCursorMoved,n);b()};g.subscribe(ops.Document.signalCursorAdded,p);g.subscribe(ops.Document.signalCursorRemoved,d);g.subscribe(ops.Document.signalCursorMoved,n);b()}; +gui.AnnotationController.annotatableChanged="annotatable/changed";(function(){return gui.AnnotationController})(); +// Input 75 +gui.Avatar=function(k,h){var b=this,p,d,n;this.setColor=function(b){d.style.borderColor=b};this.setImageUrl=function(g){b.isVisible()?d.src=g:n=g};this.isVisible=function(){return"block"===p.style.display};this.show=function(){n&&(d.src=n,n=void 0);p.style.display="block"};this.hide=function(){p.style.display="none"};this.markAsFocussed=function(b){b?p.classList.add("active"):p.classList.remove("active")};this.destroy=function(b){k.removeChild(p);b()};(function(){var b=k.ownerDocument,n=b.documentElement.namespaceURI; +p=b.createElementNS(n,"div");d=b.createElementNS(n,"img");d.width=64;d.height=64;p.appendChild(d);p.style.width="64px";p.style.height="70px";p.style.position="absolute";p.style.top="-80px";p.style.left="-34px";p.style.display=h?"block":"none";p.className="handle";k.appendChild(p)})()}; +// Input 76 +gui.Caret=function(k,h,b){function p(){r.style.opacity="0"===r.style.opacity?"1":"0";t.trigger()}function d(a,b){var c=a.getBoundingClientRect(),e=0,d=0;c&&b&&(e=Math.max(c.top,b.top),d=Math.min(c.bottom,b.bottom));return d-e}function n(){Object.keys(v).forEach(function(a){u[a]=v[a]})}function g(){var e,f,g,m;if(!1===v.isShown||k.getSelectionType()!==ops.OdtCursor.RangeSelection||!b&&!k.getSelectedRange().collapsed)v.visibility="hidden",r.style.visibility="hidden",t.cancel();else{v.visibility="visible"; +r.style.visibility="visible";if(!1===v.isFocused)r.style.opacity="1",t.cancel();else{if(w||u.visibility!==v.visibility)r.style.opacity="1",t.cancel();t.trigger()}if(x||z||u.visibility!==v.visibility){e=k.getSelectedRange().cloneRange();f=k.getNode();var h=null;f.previousSibling&&(g=f.previousSibling.nodeType===Node.TEXT_NODE?f.previousSibling.textContent.length:f.previousSibling.childNodes.length,e.setStart(f.previousSibling,0<g?g-1:0),e.setEnd(f.previousSibling,g),(g=e.getBoundingClientRect())&& +g.height&&(h=g));f.nextSibling&&(e.setStart(f.nextSibling,0),e.setEnd(f.nextSibling,0<(f.nextSibling.nodeType===Node.TEXT_NODE?f.nextSibling.textContent.length:f.nextSibling.childNodes.length)?1:0),(g=e.getBoundingClientRect())&&g.height&&(!h||d(f,g)>d(f,h))&&(h=g));f=h;h=k.getDocument().getCanvas();e=h.getZoomLevel();h=a.getBoundingClientRect(h.getSizer());f?(r.style.top="0",g=a.getBoundingClientRect(r),8>f.height&&(f={top:f.top-(8-f.height)/2,height:8}),r.style.height=a.adaptRangeDifferenceToZoomLevel(f.height, +e)+"px",r.style.top=a.adaptRangeDifferenceToZoomLevel(f.top-g.top,e)+"px"):(r.style.height="1em",r.style.top="5%");c&&(f=runtime.getWindow().getComputedStyle(r,null),g=a.getBoundingClientRect(r),c.style.bottom=a.adaptRangeDifferenceToZoomLevel(h.bottom-g.bottom,e)+"px",c.style.left=a.adaptRangeDifferenceToZoomLevel(g.right-h.left,e)+"px",f.font?c.style.font=f.font:(c.style.fontStyle=f.fontStyle,c.style.fontVariant=f.fontVariant,c.style.fontWeight=f.fontWeight,c.style.fontSize=f.fontSize,c.style.lineHeight= +f.lineHeight,c.style.fontFamily=f.fontFamily))}if(z){var h=k.getDocument().getCanvas().getElement().parentNode,p;g=h.offsetWidth-h.clientWidth+5;m=h.offsetHeight-h.clientHeight+5;p=r.getBoundingClientRect();e=p.left-g;f=p.top-m;g=p.right+g;m=p.bottom+m;p=h.getBoundingClientRect();f<p.top?h.scrollTop-=p.top-f:m>p.bottom&&(h.scrollTop+=m-p.bottom);e<p.left?h.scrollLeft-=p.left-e:g>p.right&&(h.scrollLeft+=g-p.right)}}u.isFocused!==v.isFocused&&l.markAsFocussed(v.isFocused);n();x=z=w=!1}function q(a){f.removeChild(r); +a()}var r,l,f,c,a=new core.DomUtils,m=new core.Async,e,t,w=!1,z=!1,x=!1,v={isFocused:!1,isShown:!0,visibility:"hidden"},u={isFocused:!v.isFocused,isShown:!v.isShown,visibility:"hidden"};this.handleUpdate=function(){x=!0;"hidden"!==v.visibility&&(v.visibility="hidden",r.style.visibility="hidden");e.trigger()};this.refreshCursorBlinking=function(){w=!0;e.trigger()};this.setFocus=function(){v.isFocused=!0;e.trigger()};this.removeFocus=function(){v.isFocused=!1;e.trigger()};this.show=function(){v.isShown= +!0;e.trigger()};this.hide=function(){v.isShown=!1;e.trigger()};this.setAvatarImageUrl=function(a){l.setImageUrl(a)};this.setColor=function(a){r.style.borderColor=a;l.setColor(a)};this.getCursor=function(){return k};this.getFocusElement=function(){return r};this.toggleHandleVisibility=function(){l.isVisible()?l.hide():l.show()};this.showHandle=function(){l.show()};this.hideHandle=function(){l.hide()};this.setOverlayElement=function(a){c=a;x=!0;e.trigger()};this.ensureVisible=function(){z=!0;e.trigger()}; +this.destroy=function(a){m.destroyAll([e.destroy,t.destroy,l.destroy,q],a)};(function(){var a=k.getDocument().getDOMDocument();r=a.createElementNS(a.documentElement.namespaceURI,"span");r.className="caret";r.style.top="5%";f=k.getNode();f.appendChild(r);l=new gui.Avatar(f,h);e=new core.ScheduledTask(g,0);t=new core.ScheduledTask(p,500);e.triggerImmediate()})()}; +// Input 77 +/* + + 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/ +*/ +odf.TextSerializer=function(){function k(p){var d="",n=h.filter?h.filter.acceptNode(p):NodeFilter.FILTER_ACCEPT,g=p.nodeType,q;if((n===NodeFilter.FILTER_ACCEPT||n===NodeFilter.FILTER_SKIP)&&b.isTextContentContainingNode(p))for(q=p.firstChild;q;)d+=k(q),q=q.nextSibling;n===NodeFilter.FILTER_ACCEPT&&(g===Node.ELEMENT_NODE&&b.isParagraph(p)?d+="\n":g===Node.TEXT_NODE&&p.textContent&&(d+=p.textContent));return d}var h=this,b=new odf.OdfUtils;this.filter=null;this.writeToString=function(b){if(!b)return""; +b=k(b);"\n"===b[b.length-1]&&(b=b.substr(0,b.length-1));return b}}; +// Input 78 /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -2322,12 +2508,11 @@ d.removeProperties(r);p&&(d.setProperties(p),p.fullName&&g());f.emit(ops.OdtDocu @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpUpdateMetadata=function(){var g,l,f,p;this.init=function(r){g=r.memberid;l=parseInt(r.timestamp,10);f=r.setProperties;p=r.removedProperties};this.isEdit=!0;this.execute=function(g){g=g.getOdfCanvas().odfContainer();var l=[],h=["dc:date","dc:creator","meta:editing-cycles"];f&&h.forEach(function(d){if(f[d])return!1});p&&(h.forEach(function(d){if(-1!==l.indexOf(d))return!1}),l=p.attributes.split(","));g.setMetadata(f,l);return!0};this.spec=function(){return{optype:"UpdateMetadata",memberid:g,timestamp:l, -setProperties:f,removedProperties:p}}}; -// Input 80 +gui.MimeDataExporter=function(){var k,h;this.exportRangeToDataTransfer=function(b,h){var d;d=h.startContainer.ownerDocument.createElement("span");d.appendChild(h.cloneContents());d=k.writeToString(d);try{b.setData("text/plain",d)}catch(n){b.setData("Text",d)}};k=new odf.TextSerializer;h=new odf.OdfNodeFilter;k.filter=h}; +// Input 79 /* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2362,14 +2547,11 @@ setProperties:f,removedProperties:p}}}; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces"); -ops.OpUpdateParagraphStyle=function(){function g(d,f){var c,e,a=f?f.split(","):[];for(c=0;c<a.length;c+=1)e=a[c].split(":"),d.removeAttributeNS(odf.Namespaces.lookupNamespaceURI(e[0]),e[1])}var l,f,p,r,n,h=odf.Namespaces.stylens;this.init=function(d){l=d.memberid;f=d.timestamp;p=d.styleName;r=d.setProperties;n=d.removedProperties};this.isEdit=!0;this.execute=function(d){var f=d.getFormatting(),c,e,a;return(c=""!==p?d.getParagraphStyleElement(p):f.getDefaultStyleElement("paragraph"))?(e=c.getElementsByTagNameNS(h, -"paragraph-properties")[0],a=c.getElementsByTagNameNS(h,"text-properties")[0],r&&f.updateStyle(c,r),n&&(n["style:paragraph-properties"]&&(g(e,n["style:paragraph-properties"].attributes),0===e.attributes.length&&c.removeChild(e)),n["style:text-properties"]&&(g(a,n["style:text-properties"].attributes),0===a.attributes.length&&c.removeChild(a)),g(c,n.attributes)),d.getOdfCanvas().refreshCSS(),d.emit(ops.OdtDocument.signalParagraphStyleModified,p),d.getOdfCanvas().rerenderAnnotations(),!0):!1};this.spec= -function(){return{optype:"UpdateParagraphStyle",memberid:l,timestamp:f,styleName:p,setProperties:r,removedProperties:n}}}; -// Input 81 +gui.Clipboard=function(k){this.setDataFromRange=function(h,b){var p,d=h.clipboardData;p=runtime.getWindow();!d&&p&&(d=p.clipboardData);d?(p=!0,k.exportRangeToDataTransfer(d,b),h.preventDefault()):p=!1;return p}}; +// Input 80 /* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012-2014 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2404,11 +2586,10 @@ function(){return{optype:"UpdateParagraphStyle",memberid:l,timestamp:f,styleName @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.OpAddMember");runtime.loadClass("ops.OpUpdateMember");runtime.loadClass("ops.OpRemoveMember");runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpApplyDirectStyling");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");runtime.loadClass("ops.OpSetBlob");runtime.loadClass("ops.OpRemoveBlob");runtime.loadClass("ops.OpInsertImage");runtime.loadClass("ops.OpInsertTable");runtime.loadClass("ops.OpInsertText");runtime.loadClass("ops.OpRemoveText"); -runtime.loadClass("ops.OpSplitParagraph");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("ops.OpUpdateParagraphStyle");runtime.loadClass("ops.OpAddStyle");runtime.loadClass("ops.OpRemoveStyle");runtime.loadClass("ops.OpAddAnnotation");runtime.loadClass("ops.OpRemoveAnnotation");runtime.loadClass("ops.OpUpdateMetadata"); -ops.OperationFactory=function(){function g(f){return function(){return new f}}var l;this.register=function(f,g){l[f]=g};this.create=function(f){var g=null,r=l[f.optype];r&&(g=r(f),g.init(f));return g};l={AddMember:g(ops.OpAddMember),UpdateMember:g(ops.OpUpdateMember),RemoveMember:g(ops.OpRemoveMember),AddCursor:g(ops.OpAddCursor),ApplyDirectStyling:g(ops.OpApplyDirectStyling),SetBlob:g(ops.OpSetBlob),RemoveBlob:g(ops.OpRemoveBlob),InsertImage:g(ops.OpInsertImage),InsertTable:g(ops.OpInsertTable), -InsertText:g(ops.OpInsertText),RemoveText:g(ops.OpRemoveText),SplitParagraph:g(ops.OpSplitParagraph),SetParagraphStyle:g(ops.OpSetParagraphStyle),UpdateParagraphStyle:g(ops.OpUpdateParagraphStyle),AddStyle:g(ops.OpAddStyle),RemoveStyle:g(ops.OpRemoveStyle),MoveCursor:g(ops.OpMoveCursor),RemoveCursor:g(ops.OpRemoveCursor),AddAnnotation:g(ops.OpAddAnnotation),RemoveAnnotation:g(ops.OpRemoveAnnotation),UpdateMetadata:g(ops.OpUpdateMetadata)}}; -// Input 82 +gui.StyleSummary=function(k){function h(b,g){var h=b+"|"+g,p;d.hasOwnProperty(h)||(p=[],k.forEach(function(d){d=(d=d[b])&&d[g];-1===p.indexOf(d)&&p.push(d)}),d[h]=p);return d[h]}function b(b,d,k){return function(){var p=h(b,d);return k.length>=p.length&&p.every(function(b){return-1!==k.indexOf(b)})}}function p(b,d){var k=h(b,d);return 1===k.length?k[0]:void 0}var d={};this.getPropertyValues=h;this.getCommonValue=p;this.isBold=b("style:text-properties","fo:font-weight",["bold"]);this.isItalic=b("style:text-properties", +"fo:font-style",["italic"]);this.hasUnderline=b("style:text-properties","style:text-underline-style",["solid"]);this.hasStrikeThrough=b("style:text-properties","style:text-line-through-style",["solid"]);this.fontSize=function(){var b=p("style:text-properties","fo:font-size");return b&&parseFloat(b)};this.fontName=function(){return p("style:text-properties","style:font-name")};this.isAlignedLeft=b("style:paragraph-properties","fo:text-align",["left","start"]);this.isAlignedCenter=b("style:paragraph-properties", +"fo:text-align",["center"]);this.isAlignedRight=b("style:paragraph-properties","fo:text-align",["right","end"]);this.isAlignedJustified=b("style:paragraph-properties","fo:text-align",["justify"]);this.text={isBold:this.isBold,isItalic:this.isItalic,hasUnderline:this.hasUnderline,hasStrikeThrough:this.hasStrikeThrough,fontSize:this.fontSize,fontName:this.fontName};this.paragraph={isAlignedLeft:this.isAlignedLeft,isAlignedCenter:this.isAlignedCenter,isAlignedRight:this.isAlignedRight,isAlignedJustified:this.isAlignedJustified}}; +// Input 81 /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -2446,11 +2627,38 @@ InsertText:g(ops.OpInsertText),RemoveText:g(ops.OpRemoveText),SplitParagraph:g(o @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFactory=function(g){};ops.OperationRouter.prototype.setPlaybackFunction=function(g){};ops.OperationRouter.prototype.push=function(g){};ops.OperationRouter.prototype.close=function(g){};ops.OperationRouter.prototype.subscribe=function(g,l){};ops.OperationRouter.prototype.unsubscribe=function(g,l){};ops.OperationRouter.prototype.hasLocalUnsyncedOps=function(){};ops.OperationRouter.prototype.hasSessionHostConnection=function(){}; +gui.DirectFormattingController=function(k,h,b,p){function d(a){var b;a.collapsed?(b=a.startContainer,b.hasChildNodes()&&a.startOffset<b.childNodes.length&&(b=b.childNodes.item(a.startOffset)),a=[b]):a=K.getTextNodes(a,!0);return a}function n(a,b){var c={};Object.keys(a).forEach(function(e){var d=a[e](),f=b[e]();d!==f&&(c[e]=f)});return c}function g(){var a,b,c;a=(a=(a=F.getCursor(h))&&a.getSelectedRange())?d(a):[];a=F.getFormatting().getAppliedStyles(a);a[0]&&H&&(a[0]=O.mergeObjects(a[0],H));T=a; +c=new gui.StyleSummary(T);a=n(y.text,c.text);b=n(y.paragraph,c.paragraph);y=c;0<Object.keys(a).length&&Z.emit(gui.DirectFormattingController.textStylingChanged,a);0<Object.keys(b).length&&Z.emit(gui.DirectFormattingController.paragraphStylingChanged,b)}function q(a){("string"===typeof a?a:a.getMemberId())===h&&g()}function r(){g()}function l(a){var b=F.getCursor(h);a=a.paragraphElement;b&&F.getParagraphElement(b.getNode())===a&&g()}function f(a,b){b(!a());return!0}function c(a){var b=F.getCursorSelection(h), +c={"style:text-properties":a};0!==b.length?(a=new ops.OpApplyDirectStyling,a.init({memberid:h,position:b.position,length:b.length,setProperties:c}),k.enqueue([a])):(H=O.mergeObjects(H||{},c),g())}function a(a,b){var e={};e[a]=b;c(e)}function m(a){a=a.spec();H&&a.memberid===h&&"SplitParagraph"!==a.optype&&(H=null,g())}function e(b){a("fo:font-weight",b?"bold":"normal")}function t(b){a("fo:font-style",b?"italic":"normal")}function w(b){a("style:text-underline-style",b?"solid":"none")}function z(b){a("style:text-line-through-style", +b?"solid":"none")}function x(a){return a===ops.StepsTranslator.NEXT_STEP}function v(a){var c=F.getCursor(h).getSelectedRange(),c=K.getParagraphElements(c),e=F.getFormatting(),d=[],f={},g;c.forEach(function(c){var m=F.convertDomPointToCursorStep(c,0,x),l=c.getAttributeNS(odf.Namespaces.textns,"style-name"),k;c=l?f.hasOwnProperty(l)?f[l]:void 0:g;c||(c=b.generateStyleName(),l?(f[l]=c,k=e.createDerivedStyleObject(l,"paragraph",{})):(g=c,k={}),k=a(k),l=new ops.OpAddStyle,l.init({memberid:h,styleName:c.toString(), +styleFamily:"paragraph",isAutomaticStyle:!0,setProperties:k}),d.push(l));l=new ops.OpSetParagraphStyle;l.init({memberid:h,styleName:c.toString(),position:m});d.push(l)});k.enqueue(d)}function u(a){v(function(b){return O.mergeObjects(b,a)})}function s(a){u({"style:paragraph-properties":{"fo:text-align":a}})}function A(a,b){var c=F.getFormatting().getDefaultTabStopDistance(),e=b["style:paragraph-properties"],d;e&&(e=e["fo:margin-left"])&&(d=K.parseLength(e));return O.mergeObjects(b,{"style:paragraph-properties":{"fo:margin-left":d&& +d.unit===c.unit?d.value+a*c.value+d.unit:a*c.value+c.unit}})}function J(a,b){var c=d(a),e=F.getFormatting().getAppliedStyles(c)[0],f=F.getFormatting().getAppliedStylesForElement(b);if(!e||"text"!==e["style:family"]||!e["style:text-properties"])return!1;if(!f||!f["style:text-properties"])return!0;e=e["style:text-properties"];f=f["style:text-properties"];return!Object.keys(e).every(function(a){return e[a]===f[a]})}function G(){}var D=this,F=k.getOdtDocument(),O=new core.Utils,K=new odf.OdfUtils,Z=new core.EventNotifier([gui.DirectFormattingController.textStylingChanged, +gui.DirectFormattingController.paragraphStylingChanged]),Q=odf.Namespaces.textns,W=core.PositionFilter.FilterResult.FILTER_ACCEPT,H,T=[],y=new gui.StyleSummary(T);this.formatTextSelection=c;this.createCursorStyleOp=function(a,b,c){var e=null;(c=c?T[0]:H)&&c["style:text-properties"]&&(e=new ops.OpApplyDirectStyling,e.init({memberid:h,position:a,length:b,setProperties:{"style:text-properties":c["style:text-properties"]}}),H=null,g());return e};this.setBold=e;this.setItalic=t;this.setHasUnderline=w; +this.setHasStrikethrough=z;this.setFontSize=function(b){a("fo:font-size",b+"pt")};this.setFontName=function(b){a("style:font-name",b)};this.getAppliedStyles=function(){return T};this.toggleBold=f.bind(D,function(){return y.isBold()},e);this.toggleItalic=f.bind(D,function(){return y.isItalic()},t);this.toggleUnderline=f.bind(D,function(){return y.hasUnderline()},w);this.toggleStrikethrough=f.bind(D,function(){return y.hasStrikeThrough()},z);this.isBold=function(){return y.isBold()};this.isItalic=function(){return y.isItalic()}; +this.hasUnderline=function(){return y.hasUnderline()};this.hasStrikeThrough=function(){return y.hasStrikeThrough()};this.fontSize=function(){return y.fontSize()};this.fontName=function(){return y.fontName()};this.isAlignedLeft=function(){return y.isAlignedLeft()};this.isAlignedCenter=function(){return y.isAlignedCenter()};this.isAlignedRight=function(){return y.isAlignedRight()};this.isAlignedJustified=function(){return y.isAlignedJustified()};this.alignParagraphLeft=function(){s("left");return!0}; +this.alignParagraphCenter=function(){s("center");return!0};this.alignParagraphRight=function(){s("right");return!0};this.alignParagraphJustified=function(){s("justify");return!0};this.indent=function(){v(A.bind(null,1));return!0};this.outdent=function(){v(A.bind(null,-1));return!0};this.createParagraphStyleOps=function(a){var c=F.getCursor(h),e=c.getSelectedRange(),d=[],f,g;c.hasForwardSelection()?(f=c.getAnchorNode(),g=c.getNode()):(f=c.getNode(),g=c.getAnchorNode());c=F.getParagraphElement(g);runtime.assert(Boolean(c), +"DirectFormattingController: Cursor outside paragraph");var m;a:{m=c;var l=gui.SelectionMover.createPositionIterator(m),k=new core.PositionFilterChain;k.addFilter(F.getPositionFilter());k.addFilter(F.createRootFilter(h));for(l.setUnfilteredPosition(e.endContainer,e.endOffset);l.nextPosition();)if(k.acceptPosition(l)===W){m=F.getParagraphElement(l.getCurrentNode())!==m;break a}m=!0}if(!m)return d;g!==f&&(c=F.getParagraphElement(f));if(!H&&!J(e,c))return d;e=T[0];if(!e)return d;if(f=c.getAttributeNS(Q, +"style-name"))e={"style:text-properties":e["style:text-properties"]},e=F.getFormatting().createDerivedStyleObject(f,"paragraph",e);c=b.generateStyleName();f=new ops.OpAddStyle;f.init({memberid:h,styleName:c,styleFamily:"paragraph",isAutomaticStyle:!0,setProperties:e});d.push(f);f=new ops.OpSetParagraphStyle;f.init({memberid:h,styleName:c,position:a});d.push(f);return d};this.subscribe=function(a,b){Z.subscribe(a,b)};this.unsubscribe=function(a,b){Z.unsubscribe(a,b)};this.destroy=function(a){F.unsubscribe(ops.Document.signalCursorAdded, +q);F.unsubscribe(ops.Document.signalCursorRemoved,q);F.unsubscribe(ops.Document.signalCursorMoved,q);F.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,r);F.unsubscribe(ops.OdtDocument.signalParagraphChanged,l);F.unsubscribe(ops.OdtDocument.signalOperationEnd,m);a()};(function(){F.subscribe(ops.Document.signalCursorAdded,q);F.subscribe(ops.Document.signalCursorRemoved,q);F.subscribe(ops.Document.signalCursorMoved,q);F.subscribe(ops.OdtDocument.signalParagraphStyleModified,r);F.subscribe(ops.OdtDocument.signalParagraphChanged, +l);F.subscribe(ops.OdtDocument.signalOperationEnd,m);g();p||(D.alignParagraphCenter=G,D.alignParagraphJustified=G,D.alignParagraphLeft=G,D.alignParagraphRight=G,D.createParagraphStyleOps=function(){return[]},D.indent=G,D.outdent=G)})()};gui.DirectFormattingController.textStylingChanged="textStyling/changed";gui.DirectFormattingController.paragraphStylingChanged="paragraphStyling/changed";(function(){return gui.DirectFormattingController})(); +// Input 82 +gui.HyperlinkClickHandler=function(k){function h(){k().removeAttributeNS("urn:webodf:names:helper","links")}function b(){k().setAttributeNS("urn:webodf:names:helper","links","inactive")}var p=gui.HyperlinkClickHandler.Modifier.None,d=gui.HyperlinkClickHandler.Modifier.Ctrl,n=gui.HyperlinkClickHandler.Modifier.Meta,g=new odf.OdfUtils,q=xmldom.XPath,r=p;this.handleClick=function(b){var f=b.target||b.srcElement,c,a;b.ctrlKey?c=d:b.metaKey&&(c=n);if(r===p||r===c){a:{for(;null!==f;){if(g.isHyperlink(f))break a; +if(g.isParagraph(f))break;f=f.parentNode}f=null}f&&(f=g.getHyperlinkTarget(f),""!==f&&("#"===f[0]?(f=f.substring(1),c=k(),a=q.getODFElementsWithXPath(c,"//text:bookmark-start[@text:name='"+f+"']",odf.Namespaces.lookupNamespaceURI),0===a.length&&(a=q.getODFElementsWithXPath(c,"//text:bookmark[@text:name='"+f+"']",odf.Namespaces.lookupNamespaceURI)),0<a.length&&a[0].scrollIntoView(!0)):runtime.getWindow().open(f),b.preventDefault?b.preventDefault():b.returnValue=!1))}};this.showPointerCursor=h;this.showTextCursor= +b;this.setModifier=function(d){r=d;r!==p?b():h()}};gui.HyperlinkClickHandler.Modifier={None:0,Ctrl:1,Meta:2}; // Input 83 +gui.HyperlinkController=function(k,h){var b=new odf.OdfUtils,p=k.getOdtDocument();this.addHyperlink=function(b,n){var g=p.getCursorSelection(h),q=new ops.OpApplyHyperlink,r=[];if(0===g.length||n)n=n||b,q=new ops.OpInsertText,q.init({memberid:h,position:g.position,text:n}),g.length=n.length,r.push(q);q=new ops.OpApplyHyperlink;q.init({memberid:h,position:g.position,length:g.length,hyperlink:b});r.push(q);k.enqueue(r)};this.removeHyperlinks=function(){var d=gui.SelectionMover.createPositionIterator(p.getRootNode()), +n=p.getCursor(h).getSelectedRange(),g=b.getHyperlinkElements(n),q=n.collapsed&&1===g.length,r=p.getDOMDocument().createRange(),l=[],f,c;0!==g.length&&(g.forEach(function(a){r.selectNodeContents(a);f=p.convertDomToCursorRange({anchorNode:r.startContainer,anchorOffset:r.startOffset,focusNode:r.endContainer,focusOffset:r.endOffset});c=new ops.OpRemoveHyperlink;c.init({memberid:h,position:f.position,length:f.length});l.push(c)}),q||(q=g[0],-1===n.comparePoint(q,0)&&(r.setStart(q,0),r.setEnd(n.startContainer, +n.startOffset),f=p.convertDomToCursorRange({anchorNode:r.startContainer,anchorOffset:r.startOffset,focusNode:r.endContainer,focusOffset:r.endOffset}),0<f.length&&(c=new ops.OpApplyHyperlink,c.init({memberid:h,position:f.position,length:f.length,hyperlink:b.getHyperlinkTarget(q)}),l.push(c))),g=g[g.length-1],d.moveToEndOfNode(g),d=d.unfilteredDomOffset(),1===n.comparePoint(g,d)&&(r.setStart(n.endContainer,n.endOffset),r.setEnd(g,d),f=p.convertDomToCursorRange({anchorNode:r.startContainer,anchorOffset:r.startOffset, +focusNode:r.endContainer,focusOffset:r.endOffset}),0<f.length&&(c=new ops.OpApplyHyperlink,c.init({memberid:h,position:f.position,length:f.length,hyperlink:b.getHyperlinkTarget(g)}),l.push(c)))),k.enqueue(l),r.detach())}}; +// Input 84 +gui.EventManager=function(k){function h(){var a=this,b=[];this.filters=[];this.handlers=[];this.handleEvent=function(c){-1===b.indexOf(c)&&(b.push(c),a.filters.every(function(a){return a(c)})&&a.handlers.forEach(function(a){a(c)}),runtime.setTimeout(function(){b.splice(b.indexOf(c),1)},0))}}function b(a){var b=a.scrollX,c=a.scrollY;this.restore=function(){a.scrollX===b&&a.scrollY===c||a.scrollTo(b,c)}}function p(a){var b=a.scrollTop,c=a.scrollLeft;this.restore=function(){if(a.scrollTop!==b||a.scrollLeft!== +c)a.scrollTop=b,a.scrollLeft=c}}function d(a,b,c){var d="on"+b,f=!1;a.attachEvent&&(a.attachEvent(d,c),f=!0);!f&&a.addEventListener&&(a.addEventListener(b,c,!1),f=!0);f&&!l[b]||!a.hasOwnProperty(d)||(a[d]=c)}function n(b,g){var l=c[b]||null;!l&&g&&(l=c[b]=new h,f[b]&&d(r,b,l.handleEvent),d(a,b,l.handleEvent),d(m,b,l.handleEvent));return l}function g(){return k.getDOMDocument().activeElement===a}function q(a){for(var c=[];a;)(a.scrollWidth>a.clientWidth||a.scrollHeight>a.clientHeight)&&c.push(new p(a)), +a=a.parentNode;c.push(new b(r));return c}var r=runtime.getWindow(),l={beforecut:!0,beforepaste:!0},f={mousedown:!0,mouseup:!0,focus:!0},c={},a,m=k.getCanvas().getElement();this.addFilter=function(a,b){n(a,!0).filters.push(b)};this.removeFilter=function(a,b){var c=n(a,!0),d=c.filters.indexOf(b);-1!==d&&c.filters.splice(d,1)};this.subscribe=function(a,b){n(a,!0).handlers.push(b)};this.unsubscribe=function(a,b){var c=n(a,!1),d=c&&c.handlers.indexOf(b);c&&-1!==d&&c.handlers.splice(d,1)};this.hasFocus= +g;this.focus=function(){var b;g()||(b=q(a),a.focus(),b.forEach(function(a){a.restore()}))};this.getEventTrap=function(){return a};this.blur=function(){g()&&a.blur()};this.destroy=function(b){a.parentNode.removeChild(a);b()};(function(){var b=k.getOdfCanvas().getSizer(),c=b.ownerDocument;runtime.assert(Boolean(r),"EventManager requires a window object to operate correctly");a=c.createElement("input");a.id="eventTrap";a.setAttribute("tabindex",-1);b.appendChild(a)})()}; +// Input 85 /* - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2014 KO GmbH <copyright@kogmbh.com> @licstart This file is part of WebODF. @@ -2472,59 +2680,68 @@ ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFacto @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OperationTransformMatrix=function(){function g(a){a.position+=a.length;a.length*=-1}function l(a){var b=0>a.length;b&&g(a);return b}function f(a,b){var c=[];a&&["style:parent-style-name","style:next-style-name"].forEach(function(d){a[d]===b&&c.push(d)});return c}function p(a,b){a&&["style:parent-style-name","style:next-style-name"].forEach(function(c){a[c]===b&&delete a[c]})}function r(a){var b={};Object.keys(a).forEach(function(c){b[c]="object"===typeof a[c]?r(a[c]):a[c]});return b}function n(a, -b,c,d){var e,f,h=!1,g=!1,l,m,n=d&&d.attributes?d.attributes.split(","):[];a&&(c||0<n.length)&&Object.keys(a).forEach(function(b){e=a[b];"object"!==typeof e&&(l=c&&c[b],void 0!==l?(delete a[b],g=!0,l===e&&(delete c[b],h=!0)):n&&-1!==n.indexOf(b)&&(delete a[b],g=!0))});if(b&&b.attributes&&(c||0<n.length)){m=b.attributes.split(",");for(d=0;d<m.length;d+=1)if(f=m[d],c&&void 0!==c[f]||n&&-1!==n.indexOf(f))m.splice(d,1),d-=1,g=!0;0<m.length?b.attributes=m.join(","):delete b.attributes}return{majorChanged:h, -minorChanged:g}}function h(a){for(var b in a)if(a.hasOwnProperty(b))return!0;return!1}function d(a){for(var b in a)if(a.hasOwnProperty(b)&&("attributes"!==b||0<a.attributes.length))return!0;return!1}function m(a,b,c){var e=a.setProperties?a.setProperties[c]:null,f=a.removedProperties?a.removedProperties[c]:null,g=b.setProperties?b.setProperties[c]:null,l=b.removedProperties?b.removedProperties[c]:null,m;m=n(e,f,g,l);e&&!h(e)&&delete a.setProperties[c];f&&!d(f)&&delete a.removedProperties[c];g&&!h(g)&& -delete b.setProperties[c];l&&!d(l)&&delete b.removedProperties[c];return m}function c(a,b){return{opSpecsA:[a],opSpecsB:[b]}}var e={AddCursor:{AddCursor:c,AddMember:c,AddStyle:c,ApplyDirectStyling:c,InsertText:c,MoveCursor:c,RemoveCursor:c,RemoveMember:c,RemoveStyle:c,RemoveText:c,SetParagraphStyle:c,SplitParagraph:c,UpdateMember:c,UpdateMetadata:c,UpdateParagraphStyle:c},AddMember:{AddStyle:c,InsertText:c,MoveCursor:c,RemoveCursor:c,RemoveStyle:c,RemoveText:c,SetParagraphStyle:c,SplitParagraph:c, -UpdateMetadata:c,UpdateParagraphStyle:c},AddStyle:{AddStyle:c,ApplyDirectStyling:c,InsertText:c,MoveCursor:c,RemoveCursor:c,RemoveMember:c,RemoveStyle:function(a,b){var c,d=[a],e=[b];a.styleFamily===b.styleFamily&&(c=f(a.setProperties,b.styleName),0<c.length&&(c={optype:"UpdateParagraphStyle",memberid:b.memberid,timestamp:b.timestamp,styleName:a.styleName,removedProperties:{attributes:c.join(",")}},e.unshift(c)),p(a.setProperties,b.styleName));return{opSpecsA:d,opSpecsB:e}},RemoveText:c,SetParagraphStyle:c, -SplitParagraph:c,UpdateMember:c,UpdateMetadata:c,UpdateParagraphStyle:c},ApplyDirectStyling:{ApplyDirectStyling:function(a,b,c){var d,e,f,g,l,n,p,s;g=[a];f=[b];if(!(a.position+a.length<=b.position||a.position>=b.position+b.length)){d=c?a:b;e=c?b:a;if(a.position!==b.position||a.length!==b.length)n=r(d),p=r(e);b=m(e,d,"style:text-properties");if(b.majorChanged||b.minorChanged)f=[],a=[],g=d.position+d.length,l=e.position+e.length,e.position<d.position?b.minorChanged&&(s=r(p),s.length=d.position-e.position, -a.push(s),e.position=d.position,e.length=l-e.position):d.position<e.position&&b.majorChanged&&(s=r(n),s.length=e.position-d.position,f.push(s),d.position=e.position,d.length=g-d.position),l>g?b.minorChanged&&(n=p,n.position=g,n.length=l-g,a.push(n),e.length=g-e.position):g>l&&b.majorChanged&&(n.position=l,n.length=g-l,f.push(n),d.length=l-d.position),d.setProperties&&h(d.setProperties)&&f.push(d),e.setProperties&&h(e.setProperties)&&a.push(e),c?(g=f,f=a):g=a}return{opSpecsA:g,opSpecsB:f}},InsertText:function(a, -b){b.position<=a.position?a.position+=b.text.length:b.position<=a.position+a.length&&(a.length+=b.text.length);return{opSpecsA:[a],opSpecsB:[b]}},MoveCursor:c,RemoveCursor:c,RemoveStyle:c,RemoveText:function(a,b){var c=a.position+a.length,d=b.position+b.length,e=[a],f=[b];d<=a.position?a.position-=b.length:b.position<c&&(a.position<b.position?a.length=d<c?a.length-b.length:b.position-a.position:(a.position=b.position,d<c?a.length=c-d:e=[]));return{opSpecsA:e,opSpecsB:f}},SetParagraphStyle:c,SplitParagraph:function(a, -b){b.position<a.position?a.position+=1:b.position<a.position+a.length&&(a.length+=1);return{opSpecsA:[a],opSpecsB:[b]}},UpdateMetadata:c,UpdateParagraphStyle:c},InsertText:{InsertText:function(a,b,c){a.position<b.position?b.position+=a.text.length:a.position>b.position?a.position+=b.text.length:c?b.position+=a.text.length:a.position+=b.text.length;return{opSpecsA:[a],opSpecsB:[b]}},MoveCursor:function(a,b){var c=l(b);a.position<b.position?b.position+=a.text.length:a.position<b.position+b.length&& -(b.length+=a.text.length);c&&g(b);return{opSpecsA:[a],opSpecsB:[b]}},RemoveCursor:c,RemoveMember:c,RemoveStyle:c,RemoveText:function(a,b){var c;c=b.position+b.length;var d=[a],e=[b];c<=a.position?a.position-=b.length:a.position<=b.position?b.position+=a.text.length:(b.length=a.position-b.position,c={optype:"RemoveText",memberid:b.memberid,timestamp:b.timestamp,position:a.position+a.text.length,length:c-a.position},e.unshift(c),a.position=b.position);return{opSpecsA:d,opSpecsB:e}},SplitParagraph:function(a, -b,c){if(a.position<b.position)b.position+=a.text.length;else if(a.position>b.position)a.position+=1;else return c?b.position+=a.text.length:a.position+=1,null;return{opSpecsA:[a],opSpecsB:[b]}},UpdateMember:c,UpdateMetadata:c,UpdateParagraphStyle:c},MoveCursor:{MoveCursor:c,RemoveCursor:function(a,b){return{opSpecsA:a.memberid===b.memberid?[]:[a],opSpecsB:[b]}},RemoveMember:c,RemoveStyle:c,RemoveText:function(a,b){var c=l(a),d=a.position+a.length,e=b.position+b.length;e<=a.position?a.position-=b.length: -b.position<d&&(a.position<b.position?a.length=e<d?a.length-b.length:b.position-a.position:(a.position=b.position,a.length=e<d?d-e:0));c&&g(a);return{opSpecsA:[a],opSpecsB:[b]}},SetParagraphStyle:c,SplitParagraph:function(a,b){var c=l(a);b.position<a.position?a.position+=1:b.position<a.position+a.length&&(a.length+=1);c&&g(a);return{opSpecsA:[a],opSpecsB:[b]}},UpdateMember:c,UpdateMetadata:c,UpdateParagraphStyle:c},RemoveCursor:{RemoveCursor:function(a,b){var c=a.memberid===b.memberid;return{opSpecsA:c? -[]:[a],opSpecsB:c?[]:[b]}},RemoveMember:c,RemoveStyle:c,RemoveText:c,SetParagraphStyle:c,SplitParagraph:c,UpdateMember:c,UpdateMetadata:c,UpdateParagraphStyle:c},RemoveMember:{RemoveStyle:c,RemoveText:c,SetParagraphStyle:c,SplitParagraph:c,UpdateMetadata:c,UpdateParagraphStyle:c},RemoveStyle:{RemoveStyle:function(a,b){var c=a.styleName===b.styleName&&a.styleFamily===b.styleFamily;return{opSpecsA:c?[]:[a],opSpecsB:c?[]:[b]}},RemoveText:c,SetParagraphStyle:function(a,b){var c,d=[a],e=[b];"paragraph"=== -a.styleFamily&&a.styleName===b.styleName&&(c={optype:"SetParagraphStyle",memberid:a.memberid,timestamp:a.timestamp,position:b.position,styleName:""},d.unshift(c),b.styleName="");return{opSpecsA:d,opSpecsB:e}},SplitParagraph:c,UpdateMember:c,UpdateMetadata:c,UpdateParagraphStyle:function(a,b){var c,d=[a],e=[b];"paragraph"===a.styleFamily&&(c=f(b.setProperties,a.styleName),0<c.length&&(c={optype:"UpdateParagraphStyle",memberid:a.memberid,timestamp:a.timestamp,styleName:b.styleName,removedProperties:{attributes:c.join(",")}}, -d.unshift(c)),a.styleName===b.styleName?e=[]:p(b.setProperties,a.styleName));return{opSpecsA:d,opSpecsB:e}}},RemoveText:{RemoveText:function(a,b){var c=a.position+a.length,d=b.position+b.length,e=[a],f=[b];d<=a.position?a.position-=b.length:c<=b.position?b.position-=a.length:b.position<c&&(a.position<b.position?(a.length=d<c?a.length-b.length:b.position-a.position,c<d?(b.position=a.position,b.length=d-c):f=[]):(c<d?b.length-=a.length:b.position<a.position?b.length=a.position-b.position:f=[],d<c?(a.position= -b.position,a.length=c-d):e=[]));return{opSpecsA:e,opSpecsB:f}},SplitParagraph:function(a,b){var c=a.position+a.length,d=[a],e=[b];b.position<=a.position?a.position+=1:b.position<c&&(a.length=b.position-a.position,c={optype:"RemoveText",memberid:a.memberid,timestamp:a.timestamp,position:b.position+1,length:c-b.position},d.unshift(c));a.position+a.length<=b.position?b.position-=a.length:a.position<b.position&&(b.position=a.position);return{opSpecsA:d,opSpecsB:e}},UpdateMember:c,UpdateMetadata:c,UpdateParagraphStyle:c}, -SetParagraphStyle:{UpdateMember:c,UpdateMetadata:c,UpdateParagraphStyle:c},SplitParagraph:{SplitParagraph:function(a,b,c){a.position<b.position?b.position+=1:a.position>b.position?a.position+=1:a.position===b.position&&(c?b.position+=1:a.position+=1);return{opSpecsA:[a],opSpecsB:[b]}},UpdateMember:c,UpdateMetadata:c,UpdateParagraphStyle:c},UpdateMember:{UpdateMetadata:c,UpdateParagraphStyle:c},UpdateMetadata:{UpdateMetadata:function(a,b,c){var e,f=[a],g=[b];e=c?a:b;a=c?b:a;n(a.setProperties||null, -a.removedProperties||null,e.setProperties||null,e.removedProperties||null);e.setProperties&&h(e.setProperties)||e.removedProperties&&d(e.removedProperties)||(c?f=[]:g=[]);a.setProperties&&h(a.setProperties)||a.removedProperties&&d(a.removedProperties)||(c?g=[]:f=[]);return{opSpecsA:f,opSpecsB:g}},UpdateParagraphStyle:c},UpdateParagraphStyle:{UpdateParagraphStyle:function(a,b,c){var e,f=[a],g=[b];a.styleName===b.styleName&&(e=c?a:b,a=c?b:a,m(a,e,"style:paragraph-properties"),m(a,e,"style:text-properties"), -n(a.setProperties||null,a.removedProperties||null,e.setProperties||null,e.removedProperties||null),e.setProperties&&h(e.setProperties)||e.removedProperties&&d(e.removedProperties)||(c?f=[]:g=[]),a.setProperties&&h(a.setProperties)||a.removedProperties&&d(a.removedProperties)||(c?g=[]:f=[]));return{opSpecsA:f,opSpecsB:g}}}};this.passUnchanged=c;this.extendTransformations=function(a){Object.keys(a).forEach(function(b){var c=a[b],d,f=e.hasOwnProperty(b);runtime.log((f?"Extending":"Adding")+" map for optypeA: "+ -b);f||(e[b]={});d=e[b];Object.keys(c).forEach(function(a){var e=d.hasOwnProperty(a);runtime.assert(b<=a,"Wrong order:"+b+", "+a);runtime.log(" "+(e?"Overwriting":"Adding")+" entry for optypeB: "+a);d[a]=c[a]})})};this.transformOpspecVsOpspec=function(a,b){var c=a.optype<=b.optype,d;runtime.log("Crosstransforming:");runtime.log(runtime.toJson(a));runtime.log(runtime.toJson(b));c||(d=a,a=b,b=d);(d=(d=e[a.optype])&&d[b.optype])?(d=d(a,b,!c),c||null===d||(d={opSpecsA:d.opSpecsB,opSpecsB:d.opSpecsA})): -d=null;runtime.log("result:");d?(runtime.log(runtime.toJson(d.opSpecsA)),runtime.log(runtime.toJson(d.opSpecsB))):runtime.log("null");return d}}; -// Input 84 +gui.IOSSafariSupport=function(k){function h(){b.innerHeight!==b.outerHeight&&(p.style.display="none",runtime.requestAnimationFrame(function(){p.style.display="block"}))}var b=runtime.getWindow(),p=k.getEventTrap();this.destroy=function(b){k.unsubscribe("focus",h);p.removeAttribute("autocapitalize");b()};k.subscribe("focus",h);p.setAttribute("autocapitalize","off")}; +// Input 86 +gui.ImageController=function(k,h,b){var p={"image/gif":".gif","image/jpeg":".jpg","image/png":".png"},d=odf.Namespaces.textns,n=k.getOdtDocument(),g=n.getFormatting(),q={};this.insertImage=function(r,l,f,c){var a;runtime.assert(0<f&&0<c,"Both width and height of the image should be greater than 0px.");a=n.getParagraphElement(n.getCursor(h).getNode()).getAttributeNS(d,"style-name");q.hasOwnProperty(a)||(q[a]=g.getContentSize(a,"paragraph"));a=q[a];f*=0.0264583333333334;c*=0.0264583333333334;var m= +1,e=1;f>a.width&&(m=a.width/f);c>a.height&&(e=a.height/c);m=Math.min(m,e);a=f*m;f=c*m;e=n.getOdfCanvas().odfContainer().rootElement.styles;c=r.toLowerCase();var m=p.hasOwnProperty(c)?p[c]:null,t;c=[];runtime.assert(null!==m,"Image type is not supported: "+r);m="Pictures/"+b.generateImageName()+m;t=new ops.OpSetBlob;t.init({memberid:h,filename:m,mimetype:r,content:l});c.push(t);g.getStyleElement("Graphics","graphic",[e])||(r=new ops.OpAddStyle,r.init({memberid:h,styleName:"Graphics",styleFamily:"graphic", +isAutomaticStyle:!1,setProperties:{"style:graphic-properties":{"text:anchor-type":"paragraph","svg:x":"0cm","svg:y":"0cm","style:wrap":"dynamic","style:number-wrapped-paragraphs":"no-limit","style:wrap-contour":"false","style:vertical-pos":"top","style:vertical-rel":"paragraph","style:horizontal-pos":"center","style:horizontal-rel":"paragraph"}}}),c.push(r));r=b.generateStyleName();l=new ops.OpAddStyle;l.init({memberid:h,styleName:r,styleFamily:"graphic",isAutomaticStyle:!0,setProperties:{"style:parent-style-name":"Graphics", +"style:graphic-properties":{"style:vertical-pos":"top","style:vertical-rel":"baseline","style:horizontal-pos":"center","style:horizontal-rel":"paragraph","fo:background-color":"transparent","style:background-transparency":"100%","style:shadow":"none","style:mirror":"none","fo:clip":"rect(0cm, 0cm, 0cm, 0cm)","draw:luminance":"0%","draw:contrast":"0%","draw:red":"0%","draw:green":"0%","draw:blue":"0%","draw:gamma":"100%","draw:color-inversion":"false","draw:image-opacity":"100%","draw:color-mode":"standard"}}}); +c.push(l);t=new ops.OpInsertImage;t.init({memberid:h,position:n.getCursorPosition(h),filename:m,frameWidth:a+"cm",frameHeight:f+"cm",frameStyleName:r,frameName:b.generateFrameName()});c.push(t);k.enqueue(c)}}; +// Input 87 +gui.ImageSelector=function(k){function h(){var b=k.getSizer(),h=d.createElement("div");h.id="imageSelector";h.style.borderWidth="1px";b.appendChild(h);p.forEach(function(b){var g=d.createElement("div");g.className=b;h.appendChild(g)});return h}var b=odf.Namespaces.svgns,p="topLeft topRight bottomRight bottomLeft topMiddle rightMiddle bottomMiddle leftMiddle".split(" "),d=k.getElement().ownerDocument,n=!1;this.select=function(g){var p,r,l=d.getElementById("imageSelector");l||(l=h());n=!0;p=l.parentNode; +r=g.getBoundingClientRect();var f=p.getBoundingClientRect(),c=k.getZoomLevel();p=(r.left-f.left)/c-1;r=(r.top-f.top)/c-1;l.style.display="block";l.style.left=p+"px";l.style.top=r+"px";l.style.width=g.getAttributeNS(b,"width");l.style.height=g.getAttributeNS(b,"height")};this.clearSelection=function(){var b;n&&(b=d.getElementById("imageSelector"))&&(b.style.display="none");n=!1};this.isSelectorElement=function(b){var h=d.getElementById("imageSelector");return h?b===h||b.parentNode===h:!1}}; +// Input 88 +(function(){function k(h){function b(b){g=b.which&&String.fromCharCode(b.which)===n;n=void 0;return!1===g}function k(){g=!1}function d(b){n=b.data;g=!1}var n,g=!1;this.destroy=function(g){h.unsubscribe("textInput",k);h.unsubscribe("compositionend",d);h.removeFilter("keypress",b);g()};h.subscribe("textInput",k);h.subscribe("compositionend",d);h.addFilter("keypress",b)}gui.InputMethodEditor=function(h,b){function p(b){m&&(b?m.getNode().setAttributeNS(a,"composing","true"):(m.getNode().removeAttributeNS(a, +"composing"),w.textContent=""))}function d(){u&&(u=!1,p(!1),A.emit(gui.InputMethodEditor.signalCompositionEnd,{data:s}),s="")}function n(){d();m&&m.getSelectedRange().collapsed?e.value="":e.value=x;e.setSelectionRange(0,e.value.length)}function g(){J=void 0;v.cancel();p(!0);u||A.emit(gui.InputMethodEditor.signalCompositionStart,{data:""})}function q(a){a=J=a.data;u=!0;s+=a;v.trigger()}function r(a){a.data!==J&&(a=a.data,u=!0,s+=a,v.trigger());J=void 0}function l(){w.textContent=e.value}function f(){b.blur(); +e.setAttribute("disabled",!0)}function c(){var a=b.hasFocus();a&&b.blur();F?e.removeAttribute("disabled"):e.setAttribute("disabled",!0);a&&b.focus()}var a="urn:webodf:names:cursor",m=null,e=b.getEventTrap(),t=e.ownerDocument,w,z=new core.Async,x="b",v,u=!1,s="",A=new core.EventNotifier([gui.InputMethodEditor.signalCompositionStart,gui.InputMethodEditor.signalCompositionEnd]),J,G=[],D,F=!1;this.subscribe=A.subscribe;this.unsubscribe=A.unsubscribe;this.registerCursor=function(a){a.getMemberId()===h&& +(m=a,m.getNode().appendChild(w),b.subscribe("input",l),b.subscribe("compositionupdate",l))};this.removeCursor=function(a){m&&a===h&&(m.getNode().removeChild(w),b.unsubscribe("input",l),b.unsubscribe("compositionupdate",l),m=null)};this.setEditing=function(a){F=a;c()};this.destroy=function(a){b.unsubscribe("compositionstart",g);b.unsubscribe("compositionend",q);b.unsubscribe("textInput",r);b.unsubscribe("keypress",d);b.unsubscribe("mousedown",f);b.unsubscribe("mouseup",c);b.unsubscribe("focus",n); +z.destroyAll(D,a)};(function(){b.subscribe("compositionstart",g);b.subscribe("compositionend",q);b.subscribe("textInput",r);b.subscribe("keypress",d);b.subscribe("mousedown",f);b.subscribe("mouseup",c);b.subscribe("focus",n);G.push(new k(b));D=G.map(function(a){return a.destroy});w=t.createElement("span");w.setAttribute("id","composer");v=new core.ScheduledTask(n,1);D.push(v.destroy)})()};gui.InputMethodEditor.signalCompositionStart="input/compositionstart";gui.InputMethodEditor.signalCompositionEnd= +"input/compositionend";return gui.InputMethodEditor})(); +// Input 89 /* - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart - This file is part of WebODF. + 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. - WebODF 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. + 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/>. - WebODF 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. + 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. - You should have received a copy of the GNU Affero General Public License - along with WebODF. If not, see <http://www.gnu.org/licenses/>. - @licend + 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/ */ -runtime.loadClass("ops.OperationFactory");runtime.loadClass("ops.OperationTransformMatrix"); -ops.OperationTransformer=function(){function g(g){var l=[];g.forEach(function(h){l.push(f.create(h))});return l}function l(f,g){for(var h,d,m=[],c=[];0<f.length&&g;){h=f.shift();h=p.transformOpspecVsOpspec(h,g);if(!h)return null;m=m.concat(h.opSpecsA);if(0===h.opSpecsB.length){m=m.concat(f);g=null;break}for(;1<h.opSpecsB.length;){d=l(f,h.opSpecsB.shift());if(!d)return null;c=c.concat(d.opSpecsB);f=d.opSpecsA}g=h.opSpecsB.pop()}g&&c.push(g);return{opSpecsA:m,opSpecsB:c}}var f,p=new ops.OperationTransformMatrix; -this.setOperationFactory=function(g){f=g};this.getOperationTransformMatrix=function(){return p};this.transform=function(f,n){for(var h,d=[];0<n.length;){h=l(f,n.shift());if(!h)return null;f=h.opSpecsA;d=d.concat(h.opSpecsB)}return{opsA:g(f),opsB:g(d)}}}; -// Input 85 +gui.KeyboardHandler=function(){function k(b,k){k||(k=h.None);return b+":"+k}var h=gui.KeyboardHandler.Modifier,b=null,p={};this.setDefault=function(d){b=d};this.bind=function(b,h,g,q){b=k(b,h);runtime.assert(q||!1===p.hasOwnProperty(b),"tried to overwrite the callback handler of key combo: "+b);p[b]=g};this.unbind=function(b,h){var g=k(b,h);delete p[g]};this.reset=function(){b=null;p={}};this.handleEvent=function(d){var n=d.keyCode,g=h.None;d.metaKey&&(g|=h.Meta);d.ctrlKey&&(g|=h.Ctrl);d.altKey&& +(g|=h.Alt);d.shiftKey&&(g|=h.Shift);n=k(n,g);n=p[n];g=!1;n?g=n():null!==b&&(g=b(d));g&&(d.preventDefault?d.preventDefault():d.returnValue=!1)}};gui.KeyboardHandler.Modifier={None:0,Meta:1,Ctrl:2,Alt:4,CtrlAlt:6,Shift:8,MetaShift:9,CtrlShift:10,AltShift:12}; +gui.KeyboardHandler.KeyCode={Backspace:8,Tab:9,Clear:12,Enter:13,Ctrl:17,End:35,Home:36,Left:37,Up:38,Right:39,Down:40,Delete:46,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,LeftMeta:91,MetaInMozilla:224};(function(){return gui.KeyboardHandler})(); +// Input 90 /* - Copyright (C) 2012 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2559,11 +2776,11 @@ this.setOperationFactory=function(g){f=g};this.getOperationTransformMatrix=funct @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.TrivialOperationRouter=function(){var g,l;this.setOperationFactory=function(f){g=f};this.setPlaybackFunction=function(f){l=f};this.push=function(f){f.forEach(function(f){f=f.spec();f.timestamp=(new Date).getTime();f=g.create(f);l(f)})};this.close=function(f){f()};this.subscribe=function(f,g){};this.unsubscribe=function(f,g){};this.hasLocalUnsyncedOps=function(){return!1};this.hasSessionHostConnection=function(){return!0}}; -// Input 86 +gui.PlainTextPasteboard=function(k,h){function b(b,d){b.init(d);return b}this.createPasteOps=function(p){var d=k.getCursorPosition(h),n=d,g=[];p.replace(/\r/g,"").split("\n").forEach(function(d){g.push(b(new ops.OpSplitParagraph,{memberid:h,position:n,moveCursor:!0}));n+=1;g.push(b(new ops.OpInsertText,{memberid:h,position:n,text:d,moveCursor:!0}));n+=d.length});g.push(b(new ops.OpRemoveText,{memberid:h,position:d,length:1}));return g}}; +// Input 91 /* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2014 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2598,11 +2815,25 @@ ops.TrivialOperationRouter=function(){var g,l;this.setOperationFactory=function( @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.EditInfo");runtime.loadClass("gui.EditInfoHandle"); -gui.EditInfoMarker=function(g,l){function f(c,d){return runtime.setTimeout(function(){h.style.opacity=c},d)}var p=this,r,n,h,d,m;this.addEdit=function(c,e){var a=Date.now()-e;g.addEdit(c,e);n.setEdits(g.getSortedEdits());h.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",c);d&&runtime.clearTimeout(d);m&&runtime.clearTimeout(m);1E4>a?(f(1,0),d=f(0.5,1E4-a),m=f(0.2,2E4-a)):1E4<=a&&2E4>a?(f(0.5,0),m=f(0.2,2E4-a)):f(0.2,0)};this.getEdits=function(){return g.getEdits()};this.clearEdits=function(){g.clearEdits(); -n.setEdits([]);h.hasAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")&&h.removeAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")};this.getEditInfo=function(){return g};this.show=function(){h.style.display="block"};this.hide=function(){p.hideHandle();h.style.display="none"};this.showHandle=function(){n.show()};this.hideHandle=function(){n.hide()};this.destroy=function(c){r.removeChild(h);n.destroy(function(d){d?c(d):g.destroy(c)})};(function(){var c=g.getOdtDocument().getDOM(); -h=c.createElementNS(c.documentElement.namespaceURI,"div");h.setAttribute("class","editInfoMarker");h.onmouseover=function(){p.showHandle()};h.onmouseout=function(){p.hideHandle()};r=g.getNode();r.appendChild(h);n=new gui.EditInfoHandle(r);l||p.hide()})()}; -// Input 87 +odf.WordBoundaryFilter=function(k,h){function b(a,b,c){for(var d=null,f=k.getRootNode(),g;a!==f&&null!==a&&null===d;)g=0>b?a.previousSibling:a.nextSibling,c(g)===NodeFilter.FILTER_ACCEPT&&(d=g),a=a.parentNode;return d}function p(a,b){var c;return null===a?m.NO_NEIGHBOUR:g.isCharacterElement(a)?m.SPACE_CHAR:a.nodeType===d||g.isTextSpan(a)||g.isHyperlink(a)?(c=a.textContent.charAt(b()),r.test(c)?m.SPACE_CHAR:q.test(c)?m.PUNCTUATION_CHAR:m.WORD_CHAR):m.OTHER}var d=Node.TEXT_NODE,n=Node.ELEMENT_NODE, +g=new odf.OdfUtils,q=/[!-#%-*,-\/:-;?-@\[-\]_{}\u00a1\u00ab\u00b7\u00bb\u00bf;\u00b7\u055a-\u055f\u0589-\u058a\u05be\u05c0\u05c3\u05c6\u05f3-\u05f4\u0609-\u060a\u060c-\u060d\u061b\u061e-\u061f\u066a-\u066d\u06d4\u0700-\u070d\u07f7-\u07f9\u0964-\u0965\u0970\u0df4\u0e4f\u0e5a-\u0e5b\u0f04-\u0f12\u0f3a-\u0f3d\u0f85\u0fd0-\u0fd4\u104a-\u104f\u10fb\u1361-\u1368\u166d-\u166e\u169b-\u169c\u16eb-\u16ed\u1735-\u1736\u17d4-\u17d6\u17d8-\u17da\u1800-\u180a\u1944-\u1945\u19de-\u19df\u1a1e-\u1a1f\u1b5a-\u1b60\u1c3b-\u1c3f\u1c7e-\u1c7f\u2000-\u206e\u207d-\u207e\u208d-\u208e\u3008-\u3009\u2768-\u2775\u27c5-\u27c6\u27e6-\u27ef\u2983-\u2998\u29d8-\u29db\u29fc-\u29fd\u2cf9-\u2cfc\u2cfe-\u2cff\u2e00-\u2e7e\u3000-\u303f\u30a0\u30fb\ua60d-\ua60f\ua673\ua67e\ua874-\ua877\ua8ce-\ua8cf\ua92e-\ua92f\ua95f\uaa5c-\uaa5f\ufd3e-\ufd3f\ufe10-\ufe19\ufe30-\ufe52\ufe54-\ufe61\ufe63\ufe68\ufe6a-\ufe6b\uff01-\uff03\uff05-\uff0a\uff0c-\uff0f\uff1a-\uff1b\uff1f-\uff20\uff3b-\uff3d\uff3f\uff5b\uff5d\uff5f-\uff65]|\ud800[\udd00-\udd01\udf9f\udfd0]|\ud802[\udd1f\udd3f\ude50-\ude58]|\ud809[\udc00-\udc7e]/, +r=/\s/,l=core.PositionFilter.FilterResult.FILTER_ACCEPT,f=core.PositionFilter.FilterResult.FILTER_REJECT,c=odf.WordBoundaryFilter.IncludeWhitespace.TRAILING,a=odf.WordBoundaryFilter.IncludeWhitespace.LEADING,m={NO_NEIGHBOUR:0,SPACE_CHAR:1,PUNCTUATION_CHAR:2,WORD_CHAR:3,OTHER:4};this.acceptPosition=function(e){var d=e.container(),g=e.leftNode(),k=e.rightNode(),q=e.unfilteredDomOffset,r=function(){return e.unfilteredDomOffset()-1};d.nodeType===n&&(null===k&&(k=b(d,1,e.getNodeFilter())),null===g&&(g= +b(d,-1,e.getNodeFilter())));d!==k&&(q=function(){return 0});d!==g&&null!==g&&(r=function(){return g.textContent.length-1});d=p(g,r);k=p(k,q);return d===m.WORD_CHAR&&k===m.WORD_CHAR||d===m.PUNCTUATION_CHAR&&k===m.PUNCTUATION_CHAR||h===c&&d!==m.NO_NEIGHBOUR&&k===m.SPACE_CHAR||h===a&&d===m.SPACE_CHAR&&k!==m.NO_NEIGHBOUR?f:l}};odf.WordBoundaryFilter.IncludeWhitespace={None:0,TRAILING:1,LEADING:2};(function(){return odf.WordBoundaryFilter})(); +// Input 92 +gui.SelectionController=function(k,h){function b(){var a=x.getCursor(h).getNode();return x.createStepIterator(a,0,[s,J],x.getRootElement(a))}function p(a,b,c){c=new odf.WordBoundaryFilter(x,c);return x.createStepIterator(a,b,[s,J,c],x.getRootElement(a))}function d(a){return function(b){var c=a(b);return function(b,d){return a(d)===c}}}function n(a,b){return b?{anchorNode:a.startContainer,anchorOffset:a.startOffset,focusNode:a.endContainer,focusOffset:a.endOffset}:{anchorNode:a.endContainer,anchorOffset:a.endOffset, +focusNode:a.startContainer,focusOffset:a.startOffset}}function g(a,b,c){var d=new ops.OpMoveCursor;d.init({memberid:h,position:a,length:b||0,selectionType:c});return d}function q(a){var b;b=p(a.startContainer,a.startOffset,G);b.roundToPreviousStep()&&a.setStart(b.container(),b.offset());b=p(a.endContainer,a.endOffset,D);b.roundToNextStep()&&a.setEnd(b.container(),b.offset())}function r(a){var b=u.getParagraphElements(a),c=b[0],b=b[b.length-1];c&&a.setStart(c,0);b&&(u.isParagraph(a.endContainer)&& +0===a.endOffset?a.setEndBefore(b):a.setEnd(b,b.childNodes.length))}function l(a){var b=x.getCursorSelection(h),c=x.getCursor(h).getStepCounter();0!==a&&(a=0<a?c.convertForwardStepsBetweenFilters(a,A,s):-c.convertBackwardStepsBetweenFilters(-a,A,s),a=b.length+a,k.enqueue([g(b.position,a)]))}function f(a){var c=b(),d=x.getCursor(h).getAnchorNode();a(c)&&(a=x.convertDomToCursorRange({anchorNode:d,anchorOffset:0,focusNode:c.container(),focusOffset:c.offset()}),k.enqueue([g(a.position,a.length)]))}function c(a){var b= +x.getCursorPosition(h),c=x.getCursor(h).getStepCounter();0!==a&&(a=0<a?c.convertForwardStepsBetweenFilters(a,A,s):-c.convertBackwardStepsBetweenFilters(-a,A,s),k.enqueue([g(b+a,0)]))}function a(a){var c=b();a(c)&&(a=x.convertDomPointToCursorStep(c.container(),c.offset()),k.enqueue([g(a,0)]))}function m(a,b){var d=x.getParagraphElement(x.getCursor(h).getNode());runtime.assert(Boolean(d),"SelectionController: Cursor outside paragraph");d=x.getCursor(h).getStepCounter().countLinesSteps(a,A);b?l(d):c(d)} +function e(a,b){var d=x.getCursor(h).getStepCounter().countStepsToLineBoundary(a,A);b?l(d):c(d)}function t(a,b){var c=x.getCursor(h),c=n(c.getSelectedRange(),c.hasForwardSelection()),d=p(c.focusNode,c.focusOffset,G);if(0<=a?d.nextStep():d.previousStep())c.focusNode=d.container(),c.focusOffset=d.offset(),b||(c.anchorNode=c.focusNode,c.anchorOffset=c.focusOffset),c=x.convertDomToCursorRange(c),k.enqueue([g(c.position,c.length)])}function w(a,b){var c=x.getCursor(h),e=b(c.getNode()),c=n(c.getSelectedRange(), +c.hasForwardSelection());runtime.assert(Boolean(e),"SelectionController: Cursor outside root");0>a?(c.focusNode=e,c.focusOffset=0):(c.focusNode=e,c.focusOffset=e.childNodes.length);e=x.convertDomToCursorRange(c,d(b));k.enqueue([g(e.position,e.length)])}function z(a){var b=x.getCursor(h),b=x.getRootElement(b.getNode());runtime.assert(Boolean(b),"SelectionController: Cursor outside root");a=0>a?x.convertDomPointToCursorStep(b,0,function(a){return a===ops.StepsTranslator.NEXT_STEP}):x.convertDomPointToCursorStep(b, +b.childNodes.length);k.enqueue([g(a,0)]);return!0}var x=k.getOdtDocument(),v=new core.DomUtils,u=new odf.OdfUtils,s=x.getPositionFilter(),A=new core.PositionFilterChain,J=x.createRootFilter(h),G=odf.WordBoundaryFilter.IncludeWhitespace.TRAILING,D=odf.WordBoundaryFilter.IncludeWhitespace.LEADING;this.selectionToRange=function(a){var b=0<=v.comparePoints(a.anchorNode,a.anchorOffset,a.focusNode,a.focusOffset),c=a.focusNode.ownerDocument.createRange();b?(c.setStart(a.anchorNode,a.anchorOffset),c.setEnd(a.focusNode, +a.focusOffset)):(c.setStart(a.focusNode,a.focusOffset),c.setEnd(a.anchorNode,a.anchorOffset));return{range:c,hasForwardSelection:b}};this.rangeToSelection=n;this.selectImage=function(a){var b=x.getRootElement(a),c=x.createRootFilter(b),b=x.createStepIterator(a,0,[c,x.getPositionFilter()],b),d;b.roundToPreviousStep()||runtime.assert(!1,"No walkable position before frame");c=b.container();d=b.offset();b.setPosition(a,a.childNodes.length);b.roundToNextStep()||runtime.assert(!1,"No walkable position after frame"); +a=x.convertDomToCursorRange({anchorNode:c,anchorOffset:d,focusNode:b.container(),focusOffset:b.offset()});a=g(a.position,a.length,ops.OdtCursor.RegionSelection);k.enqueue([a])};this.expandToWordBoundaries=q;this.expandToParagraphBoundaries=r;this.selectRange=function(a,b,c){var e=x.getOdfCanvas().getElement(),f;f=v.containsNode(e,a.startContainer);e=v.containsNode(e,a.endContainer);if(f||e)if(f&&e&&(2===c?q(a):3<=c&&r(a)),a=n(a,b),b=x.convertDomToCursorRange(a,d(u.getParagraphElement)),a=x.getCursorSelection(h), +b.position!==a.position||b.length!==a.length)a=g(b.position,b.length,ops.OdtCursor.RangeSelection),k.enqueue([a])};this.moveCursorToLeft=function(){a(function(a){return a.previousStep()});return!0};this.moveCursorToRight=function(){a(function(a){return a.nextStep()});return!0};this.extendSelectionToLeft=function(){f(function(a){return a.previousStep()});return!0};this.extendSelectionToRight=function(){f(function(a){return a.nextStep()});return!0};this.moveCursorUp=function(){m(-1,!1);return!0};this.moveCursorDown= +function(){m(1,!1);return!0};this.extendSelectionUp=function(){m(-1,!0);return!0};this.extendSelectionDown=function(){m(1,!0);return!0};this.moveCursorBeforeWord=function(){t(-1,!1);return!0};this.moveCursorPastWord=function(){t(1,!1);return!0};this.extendSelectionBeforeWord=function(){t(-1,!0);return!0};this.extendSelectionPastWord=function(){t(1,!0);return!0};this.moveCursorToLineStart=function(){e(-1,!1);return!0};this.moveCursorToLineEnd=function(){e(1,!1);return!0};this.extendSelectionToLineStart= +function(){e(-1,!0);return!0};this.extendSelectionToLineEnd=function(){e(1,!0);return!0};this.extendSelectionToParagraphStart=function(){w(-1,x.getParagraphElement);return!0};this.extendSelectionToParagraphEnd=function(){w(1,x.getParagraphElement);return!0};this.moveCursorToDocumentStart=function(){z(-1);return!0};this.moveCursorToDocumentEnd=function(){z(1);return!0};this.extendSelectionToDocumentStart=function(){w(-1,x.getRootElement);return!0};this.extendSelectionToDocumentEnd=function(){w(1,x.getRootElement); +return!0};this.extendSelectionToEntireDocument=function(){var a=x.getCursor(h),a=x.getRootElement(a.getNode());runtime.assert(Boolean(a),"SelectionController: Cursor outside root");a=x.convertDomToCursorRange({anchorNode:a,anchorOffset:0,focusNode:a,focusOffset:a.childNodes.length},d(x.getRootElement));k.enqueue([g(a.position,a.length)]);return!0};A.addFilter(s);A.addFilter(x.createRootFilter(h))}; +// Input 93 /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -2640,21 +2871,11 @@ h=c.createElementNS(c.documentElement.namespaceURI,"div");h.setAttribute("class" @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -gui.PlainTextPasteboard=function(g,l){function f(f,g){f.init(g);return f}this.createPasteOps=function(p){var r=g.getCursorPosition(l),n=r,h=[];p.replace(/\r/g,"").split("\n").forEach(function(d){h.push(f(new ops.OpSplitParagraph,{memberid:l,position:n,moveCursor:!0}));n+=1;h.push(f(new ops.OpInsertText,{memberid:l,position:n,text:d,moveCursor:!0}));n+=d.length});h.push(f(new ops.OpRemoveText,{memberid:l,position:r,length:1}));return h}}; -// Input 88 -runtime.loadClass("core.DomUtils");runtime.loadClass("odf.OdfUtils");runtime.loadClass("odf.OdfNodeFilter");runtime.loadClass("gui.SelectionMover"); -gui.SelectionView=function(g){function l(){var a=q.getRootNode();k!==a&&(k=a,t=k.parentNode.parentNode.parentNode,t.appendChild(w),t.appendChild(x),t.appendChild(v))}function f(a,b){a.style.left=b.left+"px";a.style.top=b.top+"px";a.style.width=b.width+"px";a.style.height=b.height+"px"}function p(a){H=a;w.style.display=x.style.display=v.style.display=!0===a?"block":"none"}function r(a){var b=s.getBoundingClientRect(t),c=q.getOdfCanvas().getZoomLevel(),d={};d.top=s.adaptRangeDifferenceToZoomLevel(a.top- -b.top,c);d.left=s.adaptRangeDifferenceToZoomLevel(a.left-b.left,c);d.bottom=s.adaptRangeDifferenceToZoomLevel(a.bottom-b.top,c);d.right=s.adaptRangeDifferenceToZoomLevel(a.right-b.left,c);d.width=s.adaptRangeDifferenceToZoomLevel(a.width,c);d.height=s.adaptRangeDifferenceToZoomLevel(a.height,c);return d}function n(a){a=a.getBoundingClientRect();return Boolean(a&&0!==a.height)}function h(a){var b=u.getTextElements(a,!0,!1),c=a.cloneRange(),d=a.cloneRange();a=a.cloneRange();if(!b.length)return null; -var e;a:{e=0;var f=b[e],g=c.startContainer===f?c.startOffset:0,h=g;c.setStart(f,g);for(c.setEnd(f,h);!n(c);){if(f.nodeType===Node.ELEMENT_NODE&&h<f.childNodes.length)h=f.childNodes.length;else if(f.nodeType===Node.TEXT_NODE&&h<f.length)h+=1;else if(b[e])f=b[e],e+=1,g=h=0;else{e=!1;break a}c.setStart(f,g);c.setEnd(f,h)}e=!0}if(!e)return null;a:{e=b.length-1;f=b[e];h=g=d.endContainer===f?d.endOffset:f.length||f.childNodes.length;d.setStart(f,g);for(d.setEnd(f,h);!n(d);){if(f.nodeType===Node.ELEMENT_NODE&& -0<g)g=0;else if(f.nodeType===Node.TEXT_NODE&&0<g)g-=1;else if(b[e])f=b[e],e-=1,g=h=f.length||f.childNodes.length;else{b=!1;break a}d.setStart(f,g);d.setEnd(f,h)}b=!0}if(!b)return null;a.setStart(c.startContainer,c.startOffset);a.setEnd(d.endContainer,d.endOffset);return{firstRange:c,lastRange:d,fillerRange:a}}function d(a,b){var c={};c.top=Math.min(a.top,b.top);c.left=Math.min(a.left,b.left);c.right=Math.max(a.right,b.right);c.bottom=Math.max(a.bottom,b.bottom);c.width=c.right-c.left;c.height=c.bottom- -c.top;return c}function m(a,b){b&&0<b.width&&0<b.height&&(a=a?d(a,b):b);return a}function c(a){function b(a){y.setUnfilteredPosition(a,0);return w.acceptNode(a)===B&&t.acceptPosition(y)===B?B:L}function c(a){var d=null;b(a)===B&&(d=s.getBoundingClientRect(a));return d}var d=a.commonAncestorContainer,e=a.startContainer,f=a.endContainer,g=a.startOffset,h=a.endOffset,k,l,n=null,p,r=A.createRange(),t,w=new odf.OdfNodeFilter,v;if(e===d||f===d)return r=a.cloneRange(),n=r.getBoundingClientRect(),r.detach(), -n;for(a=e;a.parentNode!==d;)a=a.parentNode;for(l=f;l.parentNode!==d;)l=l.parentNode;t=q.createRootFilter(e);for(d=a.nextSibling;d&&d!==l;)p=c(d),n=m(n,p),d=d.nextSibling;if(u.isParagraph(a))n=m(n,s.getBoundingClientRect(a));else if(a.nodeType===Node.TEXT_NODE)d=a,r.setStart(d,g),r.setEnd(d,d===l?h:d.length),p=r.getBoundingClientRect(),n=m(n,p);else for(v=A.createTreeWalker(a,NodeFilter.SHOW_TEXT,b,!1),d=v.currentNode=e;d&&d!==f;)r.setStart(d,g),r.setEnd(d,d.length),p=r.getBoundingClientRect(),n=m(n, -p),k=d,g=0,d=v.nextNode();k||(k=e);if(u.isParagraph(l))n=m(n,s.getBoundingClientRect(l));else if(l.nodeType===Node.TEXT_NODE)d=l,r.setStart(d,d===a?g:0),r.setEnd(d,h),p=r.getBoundingClientRect(),n=m(n,p);else for(v=A.createTreeWalker(l,NodeFilter.SHOW_TEXT,b,!1),d=v.currentNode=f;d&&d!==k;)if(r.setStart(d,0),r.setEnd(d,h),p=r.getBoundingClientRect(),n=m(n,p),d=v.previousNode())h=d.length;return n}function e(a,b){var c=a.getBoundingClientRect(),d={width:0};d.top=c.top;d.bottom=c.bottom;d.height=c.height; -d.left=d.right=b?c.right:c.left;return d}function a(){l();if(g.getSelectionType()===ops.OdtCursor.RangeSelection){p(!0);var a=g.getSelectedRange(),b=h(a),k,m,n,q;a.collapsed||!b?p(!1):(p(!0),a=b.firstRange,k=b.lastRange,b=b.fillerRange,m=r(e(a,!1)),q=r(e(k,!0)),n=(n=c(b))?r(n):d(m,q),f(w,{left:m.left,top:m.top,width:Math.max(0,n.width-(m.left-n.left)),height:m.height}),q.top===m.top||q.bottom===m.bottom?x.style.display=v.style.display="none":(f(v,{left:n.left,top:q.top,width:Math.max(0,q.right-n.left), -height:q.height}),f(x,{left:n.left,top:m.top+m.height,width:Math.max(0,parseFloat(w.style.left)+parseFloat(w.style.width)-parseFloat(v.style.left)),height:Math.max(0,q.top-m.bottom)})),a.detach(),k.detach(),b.detach())}else p(!1)}function b(b){b===g&&a()}var q=g.getOdtDocument(),k,t,A=q.getDOM(),w=A.createElement("div"),x=A.createElement("div"),v=A.createElement("div"),u=new odf.OdfUtils,s=new core.DomUtils,H=!0,y=gui.SelectionMover.createPositionIterator(q.getRootNode()),B=NodeFilter.FILTER_ACCEPT, -L=NodeFilter.FILTER_REJECT;this.show=this.rerender=a;this.hide=function(){p(!1)};this.visible=function(){return H};this.destroy=function(a){t.removeChild(w);t.removeChild(x);t.removeChild(v);g.getOdtDocument().unsubscribe(ops.OdtDocument.signalCursorMoved,b);a()};(function(){var a=g.getMemberId();l();w.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",a);x.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",a);v.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid", -a);w.className=x.className=v.className="selectionOverlay";g.getOdtDocument().subscribe(ops.OdtDocument.signalCursorMoved,b)})()}; -// Input 89 +gui.TextController=function(k,h,b,p){function d(b){var d=new ops.OpRemoveText;d.init({memberid:h,position:b.position,length:b.length});return d}function n(b){0>b.length&&(b.position+=b.length,b.length=-b.length);return b}function g(b,d){var c=new core.PositionFilterChain,a=gui.SelectionMover.createPositionIterator(q.getRootElement(b)),g=d?a.nextPosition:a.previousPosition;c.addFilter(q.getPositionFilter());c.addFilter(q.createRootFilter(h));for(a.setUnfilteredPosition(b,0);g();)if(c.acceptPosition(a)=== +r)return!0;return!1}var q=k.getOdtDocument(),r=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.enqueueParagraphSplittingOps=function(){var b=n(q.getCursorSelection(h)),f,c=[];0<b.length&&(f=d(b),c.push(f));f=new ops.OpSplitParagraph;f.init({memberid:h,position:b.position,moveCursor:!0});c.push(f);p&&(b=p(b.position+1),c=c.concat(b));k.enqueue(c);return!0};this.removeTextByBackspaceKey=function(){var b=q.getCursor(h),f=n(q.getCursorSelection(h)),c=null;0===f.length?g(b.getNode(),!1)&&(c=new ops.OpRemoveText, +c.init({memberid:h,position:f.position-1,length:1}),k.enqueue([c])):(c=d(f),k.enqueue([c]));return null!==c};this.removeTextByDeleteKey=function(){var b=q.getCursor(h),f=n(q.getCursorSelection(h)),c=null;0===f.length?g(b.getNode(),!0)&&(c=new ops.OpRemoveText,c.init({memberid:h,position:f.position,length:1}),k.enqueue([c])):(c=d(f),k.enqueue([c]));return null!==c};this.removeCurrentSelection=function(){var b=n(q.getCursorSelection(h));0!==b.length&&(b=d(b),k.enqueue([b]));return!0};this.insertText= +function(g){var f=n(q.getCursorSelection(h)),c,a=[],m=!1;0<f.length&&(c=d(f),a.push(c),m=!0);c=new ops.OpInsertText;c.init({memberid:h,position:f.position,text:g,moveCursor:!0});a.push(c);b&&(g=b(f.position,g.length,m))&&a.push(g);k.enqueue(a)}};(function(){return gui.TextController})(); +// Input 94 /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -2692,13 +2913,40 @@ a);w.className=x.className=v.className="selectionOverlay";g.getOdtDocument().sub @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("gui.SelectionView"); -gui.SelectionViewManager=function(){function g(){return Object.keys(l).map(function(f){return l[f]})}var l={};this.getSelectionView=function(f){return l.hasOwnProperty(f)?l[f]:null};this.getSelectionViews=g;this.removeSelectionView=function(f){l.hasOwnProperty(f)&&(l[f].destroy(function(){}),delete l[f])};this.hideSelectionView=function(f){l.hasOwnProperty(f)&&l[f].hide()};this.showSelectionView=function(f){l.hasOwnProperty(f)&&l[f].show()};this.rerenderSelectionViews=function(){Object.keys(l).forEach(function(f){l[f].visible()&& -l[f].rerender()})};this.registerCursor=function(f,g){var r=f.getMemberId(),n=new gui.SelectionView(f);g?n.show():n.hide();return l[r]=n};this.destroy=function(f){var l=g();(function n(g,d){d?f(d):g<l.length?l[g].destroy(function(d){n(g+1,d)}):f()})(0,void 0)}}; -// Input 90 +gui.UndoManager=function(){};gui.UndoManager.prototype.subscribe=function(k,h){};gui.UndoManager.prototype.unsubscribe=function(k,h){};gui.UndoManager.prototype.setDocument=function(k){};gui.UndoManager.prototype.setInitialState=function(){};gui.UndoManager.prototype.initialize=function(){};gui.UndoManager.prototype.purgeInitialState=function(){};gui.UndoManager.prototype.setPlaybackFunction=function(k){};gui.UndoManager.prototype.hasUndoStates=function(){}; +gui.UndoManager.prototype.hasRedoStates=function(){};gui.UndoManager.prototype.moveForward=function(k){};gui.UndoManager.prototype.moveBackward=function(k){};gui.UndoManager.prototype.onOperationExecuted=function(k){};gui.UndoManager.signalUndoStackChanged="undoStackChanged";gui.UndoManager.signalUndoStateCreated="undoStateCreated";gui.UndoManager.signalUndoStateModified="undoStateModified";(function(){return gui.UndoManager})(); +// Input 95 +(function(){var k=core.PositionFilter.FilterResult.FILTER_ACCEPT;gui.SessionController=function(h,b,p,d){function n(a){var c=K.getCursor(b).getSelectedRange();c.collapsed?a.preventDefault():T.setDataFromRange(a,c)?da.removeCurrentSelection():runtime.log("Cut operation failed")}function g(){return!1!==K.getCursor(b).getSelectedRange().collapsed}function q(a){var c=K.getCursor(b).getSelectedRange();c.collapsed?a.preventDefault():T.setDataFromRange(a,c)||runtime.log("Copy operation failed")}function r(a){var b; +O.clipboardData&&O.clipboardData.getData?b=O.clipboardData.getData("Text"):a.clipboardData&&a.clipboardData.getData&&(b=a.clipboardData.getData("text/plain"));b&&(da.removeCurrentSelection(),h.enqueue(ha.createPasteOps(b)));a.preventDefault?a.preventDefault():a.returnValue=!1}function l(){return!1}function f(a){if(M)M.onOperationExecuted(a)}function c(a){K.emit(ops.OdtDocument.signalUndoStackChanged,a)}function a(){var a=E.getEventTrap(),b,c;return M?(c=E.hasFocus(),M.moveBackward(1),b=K.getOdfCanvas().getSizer(), +Q.containsNode(b,a)||(b.appendChild(a),c&&E.focus()),!0):!1}function m(){var a;return M?(a=E.hasFocus(),M.moveForward(1),a&&E.focus(),!0):!1}function e(){var a=O.getSelection(),b=0<a.rangeCount&&L.selectionToRange(a);R&&b&&(ca=!0,P.clearSelection(),X.setUnfilteredPosition(a.focusNode,a.focusOffset),ia.acceptPosition(X)===k&&(2===ea?L.expandToWordBoundaries(b.range):3<=ea&&L.expandToParagraphBoundaries(b.range),p.setSelectedRange(b.range,b.hasForwardSelection),K.emit(ops.Document.signalCursorMoved, +p)))}function t(a){var c=a.target||a.srcElement||null,d=K.getCursor(b);if(R=null!==c&&Q.containsNode(K.getOdfCanvas().getElement(),c))ca=!1,ia=K.createRootFilter(c),ea=a.detail,d&&a.shiftKey?O.getSelection().collapse(d.getAnchorNode(),0):(a=O.getSelection(),c=d.getSelectedRange(),a.extend?d.hasForwardSelection()?(a.collapse(c.startContainer,c.startOffset),a.extend(c.endContainer,c.endOffset)):(a.collapse(c.endContainer,c.endOffset),a.extend(c.startContainer,c.startOffset)):(a.removeAllRanges(),a.addRange(c.cloneRange()))), +1<ea&&e()}function w(a){var b=K.getRootElement(a),c=K.createRootFilter(b),b=K.createStepIterator(a,0,[c,K.getPositionFilter()],b);b.setPosition(a,a.childNodes.length);return b.roundToNextStep()?{container:b.container(),offset:b.offset()}:null}function z(a){var b;b=(b=O.getSelection())?{anchorNode:b.anchorNode,anchorOffset:b.anchorOffset,focusNode:b.focusNode,focusOffset:b.focusOffset}:null;var c,d;if(!b.anchorNode&&!b.focusNode){d=a.clientX;var e=a.clientY,f=K.getDOMDocument();c=null;f.caretRangeFromPoint? +(d=f.caretRangeFromPoint(d,e),c={container:d.startContainer,offset:d.startOffset}):f.caretPositionFromPoint&&(d=f.caretPositionFromPoint(d,e))&&d.offsetNode&&(c={container:d.offsetNode,offset:d.offset});c&&(b.anchorNode=c.container,b.anchorOffset=c.offset,b.focusNode=b.anchorNode,b.focusOffset=b.anchorOffset)}if(W.isImage(b.focusNode)&&0===b.focusOffset&&W.isCharacterFrame(b.focusNode.parentNode)){if(d=b.focusNode.parentNode,c=d.getBoundingClientRect(),a.clientX>c.right&&(c=w(d)))b.anchorNode=b.focusNode= +c.container,b.anchorOffset=b.focusOffset=c.offset}else W.isImage(b.focusNode.firstChild)&&1===b.focusOffset&&W.isCharacterFrame(b.focusNode)&&(c=w(b.focusNode))&&(b.anchorNode=b.focusNode=c.container,b.anchorOffset=b.focusOffset=c.offset);b.anchorNode&&b.focusNode&&(b=L.selectionToRange(b),L.selectRange(b.range,b.hasForwardSelection,a.detail));E.focus()}function x(a){var b=a.target||a.srcElement||null,c,d;V.processRequests();W.isImage(b)&&W.isCharacterFrame(b.parentNode)&&O.getSelection().isCollapsed? +(L.selectImage(b.parentNode),E.focus()):P.isSelectorElement(b)?E.focus():R&&(ca?(b=p.getSelectedRange(),c=b.collapsed,W.isImage(b.endContainer)&&0===b.endOffset&&W.isCharacterFrame(b.endContainer.parentNode)&&(d=b.endContainer.parentNode,d=w(d))&&(b.setEnd(d.container,d.offset),c&&b.collapse(!1)),L.selectRange(b,p.hasForwardSelection(),a.detail),E.focus()):ma?z(a):Y=runtime.setTimeout(function(){z(a)},0));ea=0;ca=R=!1}function v(a){var c=K.getCursor(b).getSelectedRange();c.collapsed||H.exportRangeToDataTransfer(a.dataTransfer, +c)}function u(){R&&E.focus();ea=0;ca=R=!1}function s(a){x(a)}function A(a){var b=a.target||a.srcElement||null,c=null;"annotationRemoveButton"===b.className?(c=Q.getElementsByTagNameNS(b.parentNode,odf.Namespaces.officens,"annotation")[0],S.removeAnnotation(c),E.focus()):x(a)}function J(a){(a=a.data)&&da.insertText(a)}function G(a){return function(){a();return!0}}function D(a){return function(c){return K.getCursor(b).getSelectionType()===ops.OdtCursor.RangeSelection?a(c):!0}}function F(a){E.unsubscribe("keydown", +y.handleEvent);E.unsubscribe("keypress",aa.handleEvent);E.unsubscribe("keyup",N.handleEvent);E.unsubscribe("copy",q);E.unsubscribe("mousedown",t);E.unsubscribe("mousemove",V.trigger);E.unsubscribe("mouseup",A);E.unsubscribe("contextmenu",s);E.unsubscribe("dragstart",v);E.unsubscribe("dragend",u);E.unsubscribe("click",fa.handleClick);K.unsubscribe(ops.OdtDocument.signalOperationEnd,ga.trigger);K.unsubscribe(ops.Document.signalCursorAdded,$.registerCursor);K.unsubscribe(ops.Document.signalCursorRemoved, +$.removeCursor);K.unsubscribe(ops.OdtDocument.signalOperationEnd,f);a()}var O=runtime.getWindow(),K=h.getOdtDocument(),Z=new core.Async,Q=new core.DomUtils,W=new odf.OdfUtils,H=new gui.MimeDataExporter,T=new gui.Clipboard(H),y=new gui.KeyboardHandler,aa=new gui.KeyboardHandler,N=new gui.KeyboardHandler,R=!1,I=new odf.ObjectNameGenerator(K.getOdfCanvas().odfContainer(),b),ca=!1,ia=null,Y,M=null,E=new gui.EventManager(K),S=new gui.AnnotationController(h,b),U=new gui.DirectFormattingController(h,b,I, +d.directParagraphStylingEnabled),da=new gui.TextController(h,b,U.createCursorStyleOp,U.createParagraphStyleOps),ka=new gui.ImageController(h,b,I),P=new gui.ImageSelector(K.getOdfCanvas()),X=gui.SelectionMover.createPositionIterator(K.getRootNode()),V,ga,ha=new gui.PlainTextPasteboard(K,b),$=new gui.InputMethodEditor(b,E),ea=0,fa=new gui.HyperlinkClickHandler(K.getRootNode),ja=new gui.HyperlinkController(h,b),L=new gui.SelectionController(h,b),B=gui.KeyboardHandler.Modifier,C=gui.KeyboardHandler.KeyCode, +ba=-1!==O.navigator.appVersion.toLowerCase().indexOf("mac"),ma=-1!==["iPad","iPod","iPhone"].indexOf(O.navigator.platform),la;runtime.assert(null!==O,"Expected to be run in an environment which has a global window, like a browser.");this.undo=a;this.redo=m;this.insertLocalCursor=function(){runtime.assert(void 0===h.getOdtDocument().getCursor(b),"Inserting local cursor a second time.");var a=new ops.OpAddCursor;a.init({memberid:b});h.enqueue([a]);E.focus()};this.removeLocalCursor=function(){runtime.assert(void 0!== +h.getOdtDocument().getCursor(b),"Removing local cursor without inserting before.");var a=new ops.OpRemoveCursor;a.init({memberid:b});h.enqueue([a])};this.startEditing=function(){$.subscribe(gui.InputMethodEditor.signalCompositionStart,da.removeCurrentSelection);$.subscribe(gui.InputMethodEditor.signalCompositionEnd,J);E.subscribe("beforecut",g);E.subscribe("cut",n);E.subscribe("beforepaste",l);E.subscribe("paste",r);O.addEventListener("focus",fa.showTextCursor,!1);M&&M.initialize();$.setEditing(!0); +fa.setModifier(ba?gui.HyperlinkClickHandler.Modifier.Meta:gui.HyperlinkClickHandler.Modifier.Ctrl);y.bind(C.Backspace,B.None,G(da.removeTextByBackspaceKey),!0);y.bind(C.Delete,B.None,da.removeTextByDeleteKey);y.bind(C.Tab,B.None,D(function(){da.insertText("\t");return!0}));ba?(y.bind(C.Clear,B.None,da.removeCurrentSelection),y.bind(C.B,B.Meta,D(U.toggleBold)),y.bind(C.I,B.Meta,D(U.toggleItalic)),y.bind(C.U,B.Meta,D(U.toggleUnderline)),y.bind(C.L,B.MetaShift,D(U.alignParagraphLeft)),y.bind(C.E,B.MetaShift, +D(U.alignParagraphCenter)),y.bind(C.R,B.MetaShift,D(U.alignParagraphRight)),y.bind(C.J,B.MetaShift,D(U.alignParagraphJustified)),y.bind(C.C,B.MetaShift,S.addAnnotation),y.bind(C.Z,B.Meta,a),y.bind(C.Z,B.MetaShift,m),y.bind(C.LeftMeta,B.Meta,fa.showPointerCursor),y.bind(C.MetaInMozilla,B.Meta,fa.showPointerCursor),N.bind(C.LeftMeta,B.None,fa.showTextCursor),N.bind(C.MetaInMozilla,B.None,fa.showTextCursor)):(y.bind(C.B,B.Ctrl,D(U.toggleBold)),y.bind(C.I,B.Ctrl,D(U.toggleItalic)),y.bind(C.U,B.Ctrl,D(U.toggleUnderline)), +y.bind(C.L,B.CtrlShift,D(U.alignParagraphLeft)),y.bind(C.E,B.CtrlShift,D(U.alignParagraphCenter)),y.bind(C.R,B.CtrlShift,D(U.alignParagraphRight)),y.bind(C.J,B.CtrlShift,D(U.alignParagraphJustified)),y.bind(C.C,B.CtrlAlt,S.addAnnotation),y.bind(C.Z,B.Ctrl,a),y.bind(C.Z,B.CtrlShift,m),y.bind(C.Ctrl,B.Ctrl,fa.showPointerCursor),N.bind(C.Ctrl,B.None,fa.showTextCursor));aa.setDefault(D(function(a){var b;b=null===a.which||void 0===a.which?String.fromCharCode(a.keyCode):0!==a.which&&0!==a.charCode?String.fromCharCode(a.which): +null;return!b||a.altKey||a.ctrlKey||a.metaKey?!1:(da.insertText(b),!0)}));aa.bind(C.Enter,B.None,D(da.enqueueParagraphSplittingOps))};this.endEditing=function(){$.unsubscribe(gui.InputMethodEditor.signalCompositionStart,da.removeCurrentSelection);$.unsubscribe(gui.InputMethodEditor.signalCompositionEnd,J);E.unsubscribe("cut",n);E.unsubscribe("beforecut",g);E.unsubscribe("paste",r);E.unsubscribe("beforepaste",l);O.removeEventListener("focus",fa.showTextCursor,!1);$.setEditing(!1);fa.setModifier(gui.HyperlinkClickHandler.Modifier.None); +y.bind(C.Backspace,B.None,function(){return!0},!0);y.unbind(C.Delete,B.None);y.unbind(C.Tab,B.None);ba?(y.unbind(C.Clear,B.None),y.unbind(C.B,B.Meta),y.unbind(C.I,B.Meta),y.unbind(C.U,B.Meta),y.unbind(C.L,B.MetaShift),y.unbind(C.E,B.MetaShift),y.unbind(C.R,B.MetaShift),y.unbind(C.J,B.MetaShift),y.unbind(C.C,B.MetaShift),y.unbind(C.Z,B.Meta),y.unbind(C.Z,B.MetaShift),y.unbind(C.LeftMeta,B.Meta),y.unbind(C.MetaInMozilla,B.Meta),N.unbind(C.LeftMeta,B.None),N.unbind(C.MetaInMozilla,B.None)):(y.unbind(C.B, +B.Ctrl),y.unbind(C.I,B.Ctrl),y.unbind(C.U,B.Ctrl),y.unbind(C.L,B.CtrlShift),y.unbind(C.E,B.CtrlShift),y.unbind(C.R,B.CtrlShift),y.unbind(C.J,B.CtrlShift),y.unbind(C.C,B.CtrlAlt),y.unbind(C.Z,B.Ctrl),y.unbind(C.Z,B.CtrlShift),y.unbind(C.Ctrl,B.Ctrl),N.unbind(C.Ctrl,B.None));aa.setDefault(null);aa.unbind(C.Enter,B.None)};this.getInputMemberId=function(){return b};this.getSession=function(){return h};this.setUndoManager=function(a){M&&M.unsubscribe(gui.UndoManager.signalUndoStackChanged,c);if(M=a)M.setDocument(K), +M.setPlaybackFunction(h.enqueue),M.subscribe(gui.UndoManager.signalUndoStackChanged,c)};this.getUndoManager=function(){return M};this.getAnnotationController=function(){return S};this.getDirectFormattingController=function(){return U};this.getHyperlinkController=function(){return ja};this.getImageController=function(){return ka};this.getSelectionController=function(){return L};this.getTextController=function(){return da};this.getEventManager=function(){return E};this.getKeyboardHandlers=function(){return{keydown:y, +keypress:aa}};this.destroy=function(a){var b=[];la&&b.push(la.destroy);b=b.concat([V.destroy,ga.destroy,U.destroy,$.destroy,E.destroy,F]);runtime.clearTimeout(Y);Z.destroyAll(b,a)};V=new core.ScheduledTask(e,0);ga=new core.ScheduledTask(function(){var a=K.getCursor(b);if(a&&a.getSelectionType()===ops.OdtCursor.RegionSelection&&(a=W.getImageElements(a.getSelectedRange())[0])){P.select(a.parentNode);return}P.clearSelection()},0);y.bind(C.Left,B.None,D(L.moveCursorToLeft));y.bind(C.Right,B.None,D(L.moveCursorToRight)); +y.bind(C.Up,B.None,D(L.moveCursorUp));y.bind(C.Down,B.None,D(L.moveCursorDown));y.bind(C.Left,B.Shift,D(L.extendSelectionToLeft));y.bind(C.Right,B.Shift,D(L.extendSelectionToRight));y.bind(C.Up,B.Shift,D(L.extendSelectionUp));y.bind(C.Down,B.Shift,D(L.extendSelectionDown));y.bind(C.Home,B.None,D(L.moveCursorToLineStart));y.bind(C.End,B.None,D(L.moveCursorToLineEnd));y.bind(C.Home,B.Ctrl,D(L.moveCursorToDocumentStart));y.bind(C.End,B.Ctrl,D(L.moveCursorToDocumentEnd));y.bind(C.Home,B.Shift,D(L.extendSelectionToLineStart)); +y.bind(C.End,B.Shift,D(L.extendSelectionToLineEnd));y.bind(C.Up,B.CtrlShift,D(L.extendSelectionToParagraphStart));y.bind(C.Down,B.CtrlShift,D(L.extendSelectionToParagraphEnd));y.bind(C.Home,B.CtrlShift,D(L.extendSelectionToDocumentStart));y.bind(C.End,B.CtrlShift,D(L.extendSelectionToDocumentEnd));ba?(y.bind(C.Left,B.Alt,D(L.moveCursorBeforeWord)),y.bind(C.Right,B.Alt,D(L.moveCursorPastWord)),y.bind(C.Left,B.Meta,D(L.moveCursorToLineStart)),y.bind(C.Right,B.Meta,D(L.moveCursorToLineEnd)),y.bind(C.Home, +B.Meta,D(L.moveCursorToDocumentStart)),y.bind(C.End,B.Meta,D(L.moveCursorToDocumentEnd)),y.bind(C.Left,B.AltShift,D(L.extendSelectionBeforeWord)),y.bind(C.Right,B.AltShift,D(L.extendSelectionPastWord)),y.bind(C.Left,B.MetaShift,D(L.extendSelectionToLineStart)),y.bind(C.Right,B.MetaShift,D(L.extendSelectionToLineEnd)),y.bind(C.Up,B.AltShift,D(L.extendSelectionToParagraphStart)),y.bind(C.Down,B.AltShift,D(L.extendSelectionToParagraphEnd)),y.bind(C.Up,B.MetaShift,D(L.extendSelectionToDocumentStart)), +y.bind(C.Down,B.MetaShift,D(L.extendSelectionToDocumentEnd)),y.bind(C.A,B.Meta,D(L.extendSelectionToEntireDocument))):(y.bind(C.Left,B.Ctrl,D(L.moveCursorBeforeWord)),y.bind(C.Right,B.Ctrl,D(L.moveCursorPastWord)),y.bind(C.Left,B.CtrlShift,D(L.extendSelectionBeforeWord)),y.bind(C.Right,B.CtrlShift,D(L.extendSelectionPastWord)),y.bind(C.A,B.Ctrl,D(L.extendSelectionToEntireDocument)));ma&&(la=new gui.IOSSafariSupport(E));E.subscribe("keydown",y.handleEvent);E.subscribe("keypress",aa.handleEvent);E.subscribe("keyup", +N.handleEvent);E.subscribe("copy",q);E.subscribe("mousedown",t);E.subscribe("mousemove",V.trigger);E.subscribe("mouseup",A);E.subscribe("contextmenu",s);E.subscribe("dragstart",v);E.subscribe("dragend",u);E.subscribe("click",fa.handleClick);K.subscribe(ops.OdtDocument.signalOperationEnd,ga.trigger);K.subscribe(ops.Document.signalCursorAdded,$.registerCursor);K.subscribe(ops.Document.signalCursorRemoved,$.removeCursor);K.subscribe(ops.OdtDocument.signalOperationEnd,f)};return gui.SessionController})(); +// Input 96 /* - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2733,17 +2981,17 @@ l[f].rerender()})};this.registerCursor=function(f,g){var r=f.getMemberId(),n=new @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.DomUtils");runtime.loadClass("gui.UndoManager");runtime.loadClass("gui.UndoStateRules"); -gui.TrivialUndoManager=function(g){function l(){t.emit(gui.UndoManager.signalUndoStackChanged,{undoAvailable:h.hasUndoStates(),redoAvailable:h.hasRedoStates()})}function f(){b!==c&&b!==q[q.length-1]&&q.push(b)}function p(a){var b=a.previousSibling||a.nextSibling;a.parentNode.removeChild(a);d.normalizeTextNodes(b)}function r(a){return Object.keys(a).map(function(b){return a[b]})}function n(b){function c(a){var b=a.spec();if(f[b.memberid])switch(b.optype){case "AddCursor":d[b.memberid]||(d[b.memberid]= -a,delete f[b.memberid],g-=1);break;case "MoveCursor":e[b.memberid]||(e[b.memberid]=a)}}var d={},e={},f={},g,h=b.pop();a.getCursors().forEach(function(a){f[a.getMemberId()]=!0});for(g=Object.keys(f).length;h&&0<g;)h.reverse(),h.forEach(c),h=b.pop();return r(d).concat(r(e))}var h=this,d=new core.DomUtils,m,c=[],e,a,b=[],q=[],k=[],t=new core.EventNotifier([gui.UndoManager.signalUndoStackChanged,gui.UndoManager.signalUndoStateCreated,gui.UndoManager.signalUndoStateModified,gui.TrivialUndoManager.signalDocumentRootReplaced]), -A=g||new gui.UndoStateRules;this.subscribe=function(a,b){t.subscribe(a,b)};this.unsubscribe=function(a,b){t.unsubscribe(a,b)};this.hasUndoStates=function(){return 0<q.length};this.hasRedoStates=function(){return 0<k.length};this.setOdtDocument=function(b){a=b};this.resetInitialState=function(){q.length=0;k.length=0;c.length=0;b.length=0;m=null;l()};this.saveInitialState=function(){var e=a.getOdfCanvas().odfContainer(),g=a.getOdfCanvas().getAnnotationViewManager();g&&g.forgetAnnotations();m=e.rootElement.cloneNode(!0); -a.getOdfCanvas().refreshAnnotations();e=m;d.getElementsByTagNameNS(e,"urn:webodf:names:cursor","cursor").forEach(p);d.getElementsByTagNameNS(e,"urn:webodf:names:cursor","anchor").forEach(p);f();q.unshift(c);b=c=n(q);q.length=0;k.length=0;l()};this.setPlaybackFunction=function(a){e=a};this.onOperationExecuted=function(a){k.length=0;A.isEditOperation(a)&&b===c||!A.isPartOfOperationSet(a,b)?(f(),b=[a],q.push(b),t.emit(gui.UndoManager.signalUndoStateCreated,{operations:b}),l()):(b.push(a),t.emit(gui.UndoManager.signalUndoStateModified, -{operations:b}))};this.moveForward=function(a){for(var c=0,d;a&&k.length;)d=k.pop(),q.push(d),d.forEach(e),a-=1,c+=1;c&&(b=q[q.length-1],l());return c};this.moveBackward=function(d){for(var f=a.getOdfCanvas(),g=f.odfContainer(),h=0;d&&q.length;)k.push(q.pop()),d-=1,h+=1;h&&(g.setRootElement(m.cloneNode(!0)),f.setOdfContainer(g,!0),t.emit(gui.TrivialUndoManager.signalDocumentRootReplaced,{}),a.getCursors().forEach(function(b){a.removeCursor(b.getMemberId())}),c.forEach(e),q.forEach(function(a){a.forEach(e)}), -f.refreshCSS(),b=q[q.length-1]||c,l());return h}};gui.TrivialUndoManager.signalDocumentRootReplaced="documentRootReplaced";(function(){return gui.TrivialUndoManager})(); -// Input 91 +gui.CaretManager=function(k){function h(b){return a.hasOwnProperty(b)?a[b]:null}function b(){return Object.keys(a).map(function(b){return a[b]})}function p(b){var c=a[b];c&&(c.destroy(function(){}),delete a[b])}function d(a){a=a.getMemberId();a===k.getInputMemberId()&&(a=h(a))&&a.refreshCursorBlinking()}function n(){var a=h(k.getInputMemberId());w=!1;a&&a.ensureVisible()}function g(){var a=h(k.getInputMemberId());a&&(a.handleUpdate(),w||(w=!0,t=runtime.setTimeout(n,50)))}function q(a){a.memberId=== +k.getInputMemberId()&&g()}function r(){var a=h(k.getInputMemberId());a&&a.setFocus()}function l(){var a=h(k.getInputMemberId());a&&a.removeFocus()}function f(){var a=h(k.getInputMemberId());a&&a.show()}function c(){var a=h(k.getInputMemberId());a&&a.hide()}var a={},m=new core.Async,e=runtime.getWindow(),t,w=!1;this.registerCursor=function(b,c,d){var e=b.getMemberId();c=new gui.Caret(b,c,d);d=k.getEventManager();a[e]=c;e===k.getInputMemberId()?(runtime.log("Starting to track input on new cursor of "+ +e),b.subscribe(ops.OdtCursor.signalCursorUpdated,g),c.setOverlayElement(d.getEventTrap())):b.subscribe(ops.OdtCursor.signalCursorUpdated,c.handleUpdate);return c};this.getCaret=h;this.getCarets=b;this.destroy=function(g){var h=k.getSession().getOdtDocument(),n=k.getEventManager(),u=b().map(function(a){return a.destroy});runtime.clearTimeout(t);h.unsubscribe(ops.OdtDocument.signalParagraphChanged,q);h.unsubscribe(ops.Document.signalCursorMoved,d);h.unsubscribe(ops.Document.signalCursorRemoved,p);n.unsubscribe("focus", +r);n.unsubscribe("blur",l);e.removeEventListener("focus",f,!1);e.removeEventListener("blur",c,!1);a={};m.destroyAll(u,g)};(function(){var a=k.getSession().getOdtDocument(),b=k.getEventManager();a.subscribe(ops.OdtDocument.signalParagraphChanged,q);a.subscribe(ops.Document.signalCursorMoved,d);a.subscribe(ops.Document.signalCursorRemoved,p);b.subscribe("focus",r);b.subscribe("blur",l);e.addEventListener("focus",f,!1);e.addEventListener("blur",c,!1)})()}; +// Input 97 +gui.EditInfoHandle=function(k){var h=[],b,p=k.ownerDocument,d=p.documentElement.namespaceURI;this.setEdits=function(k){h=k;var g,q,r,l;b.innerHTML="";for(k=0;k<h.length;k+=1)g=p.createElementNS(d,"div"),g.className="editInfo",q=p.createElementNS(d,"span"),q.className="editInfoColor",q.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",h[k].memberid),r=p.createElementNS(d,"span"),r.className="editInfoAuthor",r.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",h[k].memberid), +l=p.createElementNS(d,"span"),l.className="editInfoTime",l.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",h[k].memberid),l.innerHTML=h[k].time,g.appendChild(q),g.appendChild(r),g.appendChild(l),b.appendChild(g)};this.show=function(){b.style.display="block"};this.hide=function(){b.style.display="none"};this.destroy=function(d){k.removeChild(b);d()};b=p.createElementNS(d,"div");b.setAttribute("class","editInfoHandle");b.style.display="none";k.appendChild(b)}; +// Input 98 /* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012 KO GmbH <aditya.bhatt@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2778,40 +3026,55 @@ f.refreshCSS(),b=q[q.length-1]||c,l());return h}};gui.TrivialUndoManager.signalD @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.TrivialOperationRouter");runtime.loadClass("ops.OperationFactory");runtime.loadClass("ops.OdtDocument"); -ops.Session=function(g){var l=new ops.OperationFactory,f=new ops.OdtDocument(g),p=null;this.setOperationFactory=function(f){l=f;p&&p.setOperationFactory(l)};this.setOperationRouter=function(g){p=g;g.setPlaybackFunction(function(g){return g.execute(f)?(f.emit(ops.OdtDocument.signalOperationExecuted,g),!0):!1});g.setOperationFactory(l)};this.getOperationFactory=function(){return l};this.getOdtDocument=function(){return f};this.enqueue=function(f){p.push(f)};this.close=function(g){p.close(function(l){l? -g(l):f.close(g)})};this.destroy=function(g){f.destroy(g)};this.setOperationRouter(new ops.TrivialOperationRouter)}; -// Input 92 +ops.EditInfo=function(k,h){function b(){var b=[],g;for(g in d)d.hasOwnProperty(g)&&b.push({memberid:g,time:d[g].time});b.sort(function(b,d){return b.time-d.time});return b}var p,d={};this.getNode=function(){return p};this.getOdtDocument=function(){return h};this.getEdits=function(){return d};this.getSortedEdits=function(){return b()};this.addEdit=function(b,g){d[b]={time:g}};this.clearEdits=function(){d={}};this.destroy=function(b){k.parentNode&&k.removeChild(p);b()};p=h.getDOMDocument().createElementNS("urn:webodf:names:editinfo", +"editinfo");k.insertBefore(p,k.firstChild)}; +// Input 99 /* - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart - This file is part of WebODF. + 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. - WebODF 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. + 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/>. - WebODF 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. + 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. - You should have received a copy of the GNU Affero General Public License - along with WebODF. If not, see <http://www.gnu.org/licenses/>. - @licend + 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/ */ -runtime.loadClass("core.EventNotifier");runtime.loadClass("core.PositionFilter");runtime.loadClass("ops.Session");runtime.loadClass("ops.OpAddAnnotation");runtime.loadClass("ops.OpRemoveAnnotation");runtime.loadClass("gui.SelectionMover"); -gui.AnnotationController=function(g,l){function f(){var e=h.getCursor(l),e=e&&e.getNode(),a=!1;if(e){a:{for(a=h.getRootNode();e&&e!==a;){if(e.namespaceURI===c&&"annotation"===e.localName){e=!0;break a}e=e.parentNode}e=!1}a=!e}a!==d&&(d=a,m.emit(gui.AnnotationController.annotatableChanged,d))}function p(c){c.getMemberId()===l&&f()}function r(c){c===l&&f()}function n(c){c.getMemberId()===l&&f()}var h=g.getOdtDocument(),d=!1,m=new core.EventNotifier([gui.AnnotationController.annotatableChanged]),c=odf.Namespaces.officens; -this.isAnnotatable=function(){return d};this.addAnnotation=function(){var c=new ops.OpAddAnnotation,a=h.getCursorSelection(l),b=a.length,a=a.position;d&&(a=0<=b?a:a+b,b=Math.abs(b),c.init({memberid:l,position:a,length:b,name:l+Date.now()}),g.enqueue([c]))};this.removeAnnotation=function(c){var a,b;a=h.convertDomPointToCursorStep(c,0)+1;b=h.convertDomPointToCursorStep(c,c.childNodes.length);c=new ops.OpRemoveAnnotation;c.init({memberid:l,position:a,length:b-a});b=new ops.OpMoveCursor;b.init({memberid:l, -position:0<a?a-1:a,length:0});g.enqueue([c,b])};this.subscribe=function(c,a){m.subscribe(c,a)};this.unsubscribe=function(c,a){m.unsubscribe(c,a)};this.destroy=function(c){h.unsubscribe(ops.OdtDocument.signalCursorAdded,p);h.unsubscribe(ops.OdtDocument.signalCursorRemoved,r);h.unsubscribe(ops.OdtDocument.signalCursorMoved,n);c()};h.subscribe(ops.OdtDocument.signalCursorAdded,p);h.subscribe(ops.OdtDocument.signalCursorRemoved,r);h.subscribe(ops.OdtDocument.signalCursorMoved,n);f()}; -gui.AnnotationController.annotatableChanged="annotatable/changed";(function(){return gui.AnnotationController})(); -// Input 93 +gui.EditInfoMarker=function(k,h){function b(b,c){return runtime.setTimeout(function(){g.style.opacity=b},c)}var p=this,d,n,g,q,r,l;this.addEdit=function(d,c){var a=Date.now()-c;k.addEdit(d,c);n.setEdits(k.getSortedEdits());g.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",d);runtime.clearTimeout(r);runtime.clearTimeout(l);1E4>a?(q=b(1,0),r=b(0.5,1E4-a),l=b(0.2,2E4-a)):1E4<=a&&2E4>a?(q=b(0.5,0),l=b(0.2,2E4-a)):q=b(0.2,0)};this.getEdits=function(){return k.getEdits()};this.clearEdits= +function(){k.clearEdits();n.setEdits([]);g.hasAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")&&g.removeAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")};this.getEditInfo=function(){return k};this.show=function(){g.style.display="block"};this.hide=function(){p.hideHandle();g.style.display="none"};this.showHandle=function(){n.show()};this.hideHandle=function(){n.hide()};this.destroy=function(b){runtime.clearTimeout(q);runtime.clearTimeout(r);runtime.clearTimeout(l);d.removeChild(g); +n.destroy(function(c){c?b(c):k.destroy(b)})};(function(){var b=k.getOdtDocument().getDOMDocument();g=b.createElementNS(b.documentElement.namespaceURI,"div");g.setAttribute("class","editInfoMarker");g.onmouseover=function(){p.showHandle()};g.onmouseout=function(){p.hideHandle()};d=k.getNode();d.appendChild(g);n=new gui.EditInfoHandle(d);h||p.hide()})()}; +// Input 100 +gui.ShadowCursor=function(k){var h=k.getDOMDocument().createRange(),b=!0;this.removeFromDocument=function(){};this.getMemberId=function(){return gui.ShadowCursor.ShadowCursorMemberId};this.getSelectedRange=function(){return h};this.setSelectedRange=function(k,d){h=k;b=!1!==d};this.hasForwardSelection=function(){return b};this.getDocument=function(){return k};this.getSelectionType=function(){return ops.OdtCursor.RangeSelection};h.setStart(k.getRootNode(),0)};gui.ShadowCursor.ShadowCursorMemberId=""; +(function(){return gui.ShadowCursor})(); +// Input 101 +gui.SelectionView=function(k){};gui.SelectionView.prototype.rerender=function(){};gui.SelectionView.prototype.show=function(){};gui.SelectionView.prototype.hide=function(){};gui.SelectionView.prototype.destroy=function(k){}; +// Input 102 /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -2849,17 +3112,12 @@ gui.AnnotationController.annotatableChanged="annotatable/changed";(function(){re @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.EventNotifier");runtime.loadClass("core.Utils");runtime.loadClass("odf.OdfUtils");runtime.loadClass("ops.OpAddStyle");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("gui.StyleHelper"); -gui.DirectParagraphStyler=function(g,l,f){function p(){function a(b,d,e){b!==d&&(void 0===c&&(c={}),c[e]=d);return d}var b=k.getCursor(l),b=b&&b.getSelectedRange(),c;v=a(v,b?w.isAlignedLeft(b):!1,"isAlignedLeft");u=a(u,b?w.isAlignedCenter(b):!1,"isAlignedCenter");s=a(s,b?w.isAlignedRight(b):!1,"isAlignedRight");H=a(H,b?w.isAlignedJustified(b):!1,"isAlignedJustified");c&&x.emit(gui.DirectParagraphStyler.paragraphStylingChanged,c)}function r(a){a.getMemberId()===l&&p()}function n(a){a===l&&p()}function h(a){a.getMemberId()=== -l&&p()}function d(){p()}function m(a){var b=k.getCursor(l);b&&k.getParagraphElement(b.getNode())===a.paragraphElement&&p()}function c(a){return a===ops.StepsTranslator.NEXT_STEP}function e(a){var b=k.getCursor(l).getSelectedRange(),b=A.getParagraphElements(b),d=k.getFormatting();b.forEach(function(b){var e=k.convertDomPointToCursorStep(b,0,c),h=b.getAttributeNS(odf.Namespaces.textns,"style-name");b=f.generateStyleName();var m;h&&(m=d.createDerivedStyleObject(h,"paragraph",{}));m=a(m||{});h=new ops.OpAddStyle; -h.init({memberid:l,styleName:b,styleFamily:"paragraph",isAutomaticStyle:!0,setProperties:m});m=new ops.OpSetParagraphStyle;m.init({memberid:l,styleName:b,position:e});g.enqueue([h,m])})}function a(a){e(function(b){return t.mergeObjects(b,a)})}function b(b){a({"style:paragraph-properties":{"fo:text-align":b}})}function q(a,b){var c=k.getFormatting().getDefaultTabStopDistance(),d=b["style:paragraph-properties"],d=(d=d&&d["fo:margin-left"])&&A.parseLength(d);return t.mergeObjects(b,{"style:paragraph-properties":{"fo:margin-left":d&& -d.unit===c.unit?d.value+a*c.value+d.unit:a*c.value+c.unit}})}var k=g.getOdtDocument(),t=new core.Utils,A=new odf.OdfUtils,w=new gui.StyleHelper(k.getFormatting()),x=new core.EventNotifier([gui.DirectParagraphStyler.paragraphStylingChanged]),v,u,s,H;this.isAlignedLeft=function(){return v};this.isAlignedCenter=function(){return u};this.isAlignedRight=function(){return s};this.isAlignedJustified=function(){return H};this.alignParagraphLeft=function(){b("left");return!0};this.alignParagraphCenter=function(){b("center"); -return!0};this.alignParagraphRight=function(){b("right");return!0};this.alignParagraphJustified=function(){b("justify");return!0};this.indent=function(){e(q.bind(null,1));return!0};this.outdent=function(){e(q.bind(null,-1));return!0};this.subscribe=function(a,b){x.subscribe(a,b)};this.unsubscribe=function(a,b){x.unsubscribe(a,b)};this.destroy=function(a){k.unsubscribe(ops.OdtDocument.signalCursorAdded,r);k.unsubscribe(ops.OdtDocument.signalCursorRemoved,n);k.unsubscribe(ops.OdtDocument.signalCursorMoved, -h);k.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,d);k.unsubscribe(ops.OdtDocument.signalParagraphChanged,m);a()};k.subscribe(ops.OdtDocument.signalCursorAdded,r);k.subscribe(ops.OdtDocument.signalCursorRemoved,n);k.subscribe(ops.OdtDocument.signalCursorMoved,h);k.subscribe(ops.OdtDocument.signalParagraphStyleModified,d);k.subscribe(ops.OdtDocument.signalParagraphChanged,m);p()};gui.DirectParagraphStyler.paragraphStylingChanged="paragraphStyling/changed";(function(){return gui.DirectParagraphStyler})(); -// Input 94 +gui.SelectionViewManager=function(k){function h(){return Object.keys(b).map(function(h){return b[h]})}var b={};this.getSelectionView=function(h){return b.hasOwnProperty(h)?b[h]:null};this.getSelectionViews=h;this.removeSelectionView=function(h){b.hasOwnProperty(h)&&(b[h].destroy(function(){}),delete b[h])};this.hideSelectionView=function(h){b.hasOwnProperty(h)&&b[h].hide()};this.showSelectionView=function(h){b.hasOwnProperty(h)&&b[h].show()};this.rerenderSelectionViews=function(){Object.keys(b).forEach(function(h){b[h].rerender()})}; +this.registerCursor=function(h,d){var n=h.getMemberId(),g=new k(h);d?g.show():g.hide();return b[n]=g};this.destroy=function(b){function d(g,h){h?b(h):g<k.length?k[g].destroy(function(b){d(g+1,b)}):b()}var k=h();d(0,void 0)}}; +// Input 103 /* - Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2894,23 +3152,27 @@ h);k.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,d);k.unsubscribe(o @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.EventNotifier");runtime.loadClass("core.Utils");runtime.loadClass("ops.OpApplyDirectStyling");runtime.loadClass("gui.StyleHelper"); -gui.DirectTextStyler=function(g,l){function f(a,b){for(var c=0,d=b[c];d&&a;)a=a[d],c+=1,d=b[c];return b.length===c?a:void 0}function p(a,b){var c=f(a[0],b);return a.every(function(a){return c===f(a,b)})?c:void 0}function r(){var a=u.getCursor(l),a=(a=a&&a.getSelectedRange())&&s.getAppliedStyles(a)||[];a[0]&&y&&(a[0]=v.mergeObjects(a[0],y));return a}function n(){function a(b,d,e){b!==d&&(void 0===c&&(c={}),c[e]=d);return d}var b,c;B=r();L=a(L,B?s.isBold(B):!1,"isBold");I=a(I,B?s.isItalic(B):!1,"isItalic"); -W=a(W,B?s.hasUnderline(B):!1,"hasUnderline");Q=a(Q,B?s.hasStrikeThrough(B):!1,"hasStrikeThrough");b=B&&p(B,["style:text-properties","fo:font-size"]);z=a(z,b&&parseFloat(b),"fontSize");ja=a(ja,B&&p(B,["style:text-properties","style:font-name"]),"fontName");c&&H.emit(gui.DirectTextStyler.textStylingChanged,c)}function h(a){a.getMemberId()===l&&n()}function d(a){a===l&&n()}function m(a){a.getMemberId()===l&&n()}function c(){n()}function e(a){var b=u.getCursor(l);b&&u.getParagraphElement(b.getNode())=== -a.paragraphElement&&n()}function a(a,b){var c=u.getCursor(l);if(!c)return!1;c=s.getAppliedStyles(c.getSelectedRange());b(!a(c));return!0}function b(a){var b=u.getCursorSelection(l),c={"style:text-properties":a};0!==b.length?(a=new ops.OpApplyDirectStyling,a.init({memberid:l,position:b.position,length:b.length,setProperties:c}),g.enqueue([a])):(y=v.mergeObjects(y||{},c),n())}function q(a,c){var d={};d[a]=c;b(d)}function k(a){a=a.spec();y&&a.memberid===l&&"SplitParagraph"!==a.optype&&(y=null,n())}function t(a){q("fo:font-weight", -a?"bold":"normal")}function A(a){q("fo:font-style",a?"italic":"normal")}function w(a){q("style:text-underline-style",a?"solid":"none")}function x(a){q("style:text-line-through-style",a?"solid":"none")}var v=new core.Utils,u=g.getOdtDocument(),s=new gui.StyleHelper(u.getFormatting()),H=new core.EventNotifier([gui.DirectTextStyler.textStylingChanged]),y,B=[],L=!1,I=!1,W=!1,Q=!1,z,ja;this.formatTextSelection=b;this.createCursorStyleOp=function(a,b){var c=null;y&&(c=new ops.OpApplyDirectStyling,c.init({memberid:l, -position:a,length:b,setProperties:y}),y=null,n());return c};this.setBold=t;this.setItalic=A;this.setHasUnderline=w;this.setHasStrikethrough=x;this.setFontSize=function(a){q("fo:font-size",a+"pt")};this.setFontName=function(a){q("style:font-name",a)};this.getAppliedStyles=function(){return B};this.toggleBold=a.bind(this,s.isBold,t);this.toggleItalic=a.bind(this,s.isItalic,A);this.toggleUnderline=a.bind(this,s.hasUnderline,w);this.toggleStrikethrough=a.bind(this,s.hasStrikeThrough,x);this.isBold=function(){return L}; -this.isItalic=function(){return I};this.hasUnderline=function(){return W};this.hasStrikeThrough=function(){return Q};this.fontSize=function(){return z};this.fontName=function(){return ja};this.subscribe=function(a,b){H.subscribe(a,b)};this.unsubscribe=function(a,b){H.unsubscribe(a,b)};this.destroy=function(a){u.unsubscribe(ops.OdtDocument.signalCursorAdded,h);u.unsubscribe(ops.OdtDocument.signalCursorRemoved,d);u.unsubscribe(ops.OdtDocument.signalCursorMoved,m);u.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, -c);u.unsubscribe(ops.OdtDocument.signalParagraphChanged,e);u.unsubscribe(ops.OdtDocument.signalOperationExecuted,k);a()};u.subscribe(ops.OdtDocument.signalCursorAdded,h);u.subscribe(ops.OdtDocument.signalCursorRemoved,d);u.subscribe(ops.OdtDocument.signalCursorMoved,m);u.subscribe(ops.OdtDocument.signalParagraphStyleModified,c);u.subscribe(ops.OdtDocument.signalParagraphChanged,e);u.subscribe(ops.OdtDocument.signalOperationExecuted,k);n()};gui.DirectTextStyler.textStylingChanged="textStyling/changed"; -(function(){return gui.DirectTextStyler})(); -// Input 95 -runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.ObjectNameGenerator"); -gui.ImageManager=function(g,l,f){var p={"image/gif":".gif","image/jpeg":".jpg","image/png":".png"},r=odf.Namespaces.textns,n=g.getOdtDocument(),h=n.getFormatting(),d={};this.insertImage=function(m,c,e,a){var b;runtime.assert(0<e&&0<a,"Both width and height of the image should be greater than 0px.");b=n.getParagraphElement(n.getCursor(l).getNode()).getAttributeNS(r,"style-name");d.hasOwnProperty(b)||(d[b]=h.getContentSize(b,"paragraph"));b=d[b];e*=0.0264583333333334;a*=0.0264583333333334;var q=1,k= -1;e>b.width&&(q=b.width/e);a>b.height&&(k=b.height/a);q=Math.min(q,k);b=e*q;e=a*q;k=n.getOdfCanvas().odfContainer().rootElement.styles;a=m.toLowerCase();var q=p.hasOwnProperty(a)?p[a]:null,t;a=[];runtime.assert(null!==q,"Image type is not supported: "+m);q="Pictures/"+f.generateImageName()+q;t=new ops.OpSetBlob;t.init({memberid:l,filename:q,mimetype:m,content:c});a.push(t);h.getStyleElement("Graphics","graphic",[k])||(m=new ops.OpAddStyle,m.init({memberid:l,styleName:"Graphics",styleFamily:"graphic", -isAutomaticStyle:!1,setProperties:{"style:graphic-properties":{"text:anchor-type":"paragraph","svg:x":"0cm","svg:y":"0cm","style:wrap":"dynamic","style:number-wrapped-paragraphs":"no-limit","style:wrap-contour":"false","style:vertical-pos":"top","style:vertical-rel":"paragraph","style:horizontal-pos":"center","style:horizontal-rel":"paragraph"}}}),a.push(m));m=f.generateStyleName();c=new ops.OpAddStyle;c.init({memberid:l,styleName:m,styleFamily:"graphic",isAutomaticStyle:!0,setProperties:{"style:parent-style-name":"Graphics", -"style:graphic-properties":{"style:vertical-pos":"top","style:vertical-rel":"baseline","style:horizontal-pos":"center","style:horizontal-rel":"paragraph","fo:background-color":"transparent","style:background-transparency":"100%","style:shadow":"none","style:mirror":"none","fo:clip":"rect(0cm, 0cm, 0cm, 0cm)","draw:luminance":"0%","draw:contrast":"0%","draw:red":"0%","draw:green":"0%","draw:blue":"0%","draw:gamma":"100%","draw:color-inversion":"false","draw:image-opacity":"100%","draw:color-mode":"standard"}}}); -a.push(c);t=new ops.OpInsertImage;t.init({memberid:l,position:n.getCursorPosition(l),filename:q,frameWidth:b+"cm",frameHeight:e+"cm",frameStyleName:m,frameName:f.generateFrameName()});a.push(t);g.enqueue(a)}}; -// Input 96 +gui.SessionViewOptions=function(){this.caretBlinksOnRangeSelect=this.caretAvatarsInitiallyVisible=this.editInfoMarkersInitiallyVisible=!0}; +(function(){gui.SessionView=function(k,h,b,p,d){function n(a,b,c){function d(b,c,e){c=b+'[editinfo|memberid="'+a+'"]'+e+c;a:{var f=m.firstChild;for(b=b+'[editinfo|memberid="'+a+'"]'+e+"{";f;){if(f.nodeType===Node.TEXT_NODE&&0===f.data.indexOf(b)){b=f;break a}f=f.nextSibling}b=null}b?b.data=c:m.appendChild(document.createTextNode(c))}d("div.editInfoMarker","{ background-color: "+c+"; }","");d("span.editInfoColor","{ background-color: "+c+"; }","");d("span.editInfoAuthor",'{ content: "'+b+'"; }',":before"); +d("dc|creator","{ background-color: "+c+"; }","");d(".selectionOverlay","{ fill: "+c+"; stroke: "+c+";}","")}function g(a){var b,c;for(c in t)t.hasOwnProperty(c)&&(b=t[c],a?b.show():b.hide())}function q(a){p.getCarets().forEach(function(b){a?b.showHandle():b.hideHandle()})}function r(a){var b=a.getMemberId();a=a.getProperties();n(b,a.fullName,a.color);h===b&&n("","",a.color)}function l(a){var c=a.getMemberId(),e=b.getOdtDocument().getMember(c).getProperties();p.registerCursor(a,z,x);d.registerCursor(a, +!0);if(a=p.getCaret(c))a.setAvatarImageUrl(e.imageUrl),a.setColor(e.color);runtime.log("+++ View here +++ eagerly created an Caret for '"+c+"'! +++")}function f(a){a=a.getMemberId();var b=d.getSelectionView(h),c=d.getSelectionView(gui.ShadowCursor.ShadowCursorMemberId),e=p.getCaret(h);a===h?(c.hide(),b&&b.show(),e&&e.show()):a===gui.ShadowCursor.ShadowCursorMemberId&&(c.show(),b&&b.hide(),e&&e.hide())}function c(a){d.removeSelectionView(a)}function a(a){var c=a.paragraphElement,d=a.memberId;a=a.timeStamp; +var f,g="",h=c.getElementsByTagNameNS(e,"editinfo").item(0);h?(g=h.getAttributeNS(e,"id"),f=t[g]):(g=Math.random().toString(),f=new ops.EditInfo(c,b.getOdtDocument()),f=new gui.EditInfoMarker(f,w),h=c.getElementsByTagNameNS(e,"editinfo").item(0),h.setAttributeNS(e,"id",g),t[g]=f);f.addEdit(d,new Date(a))}var m,e="urn:webodf:names:editinfo",t={},w=void 0!==k.editInfoMarkersInitiallyVisible?Boolean(k.editInfoMarkersInitiallyVisible):!0,z=void 0!==k.caretAvatarsInitiallyVisible?Boolean(k.caretAvatarsInitiallyVisible): +!0,x=void 0!==k.caretBlinksOnRangeSelect?Boolean(k.caretBlinksOnRangeSelect):!0;this.showEditInfoMarkers=function(){w||(w=!0,g(w))};this.hideEditInfoMarkers=function(){w&&(w=!1,g(w))};this.showCaretAvatars=function(){z||(z=!0,q(z))};this.hideCaretAvatars=function(){z&&(z=!1,q(z))};this.getSession=function(){return b};this.getCaret=function(a){return p.getCaret(a)};this.destroy=function(e){var g=b.getOdtDocument(),h=Object.keys(t).map(function(a){return t[a]});g.unsubscribe(ops.Document.signalMemberAdded, +r);g.unsubscribe(ops.Document.signalMemberUpdated,r);g.unsubscribe(ops.Document.signalCursorAdded,l);g.unsubscribe(ops.Document.signalCursorRemoved,c);g.unsubscribe(ops.OdtDocument.signalParagraphChanged,a);g.unsubscribe(ops.Document.signalCursorMoved,f);g.unsubscribe(ops.OdtDocument.signalParagraphChanged,d.rerenderSelectionViews);g.unsubscribe(ops.OdtDocument.signalTableAdded,d.rerenderSelectionViews);g.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,d.rerenderSelectionViews);m.parentNode.removeChild(m); +(function J(a,b){b?e(b):a<h.length?h[a].destroy(function(b){J(a+1,b)}):e()})(0,void 0)};(function(){var e=b.getOdtDocument(),g=document.getElementsByTagName("head").item(0);e.subscribe(ops.Document.signalMemberAdded,r);e.subscribe(ops.Document.signalMemberUpdated,r);e.subscribe(ops.Document.signalCursorAdded,l);e.subscribe(ops.Document.signalCursorRemoved,c);e.subscribe(ops.OdtDocument.signalParagraphChanged,a);e.subscribe(ops.Document.signalCursorMoved,f);e.subscribe(ops.OdtDocument.signalParagraphChanged, +d.rerenderSelectionViews);e.subscribe(ops.OdtDocument.signalTableAdded,d.rerenderSelectionViews);e.subscribe(ops.OdtDocument.signalParagraphStyleModified,d.rerenderSelectionViews);m=document.createElementNS(g.namespaceURI,"style");m.type="text/css";m.media="screen, print, handheld, projection";m.appendChild(document.createTextNode("@namespace editinfo url(urn:webodf:names:editinfo);"));m.appendChild(document.createTextNode("@namespace dc url(http://purl.org/dc/elements/1.1/);"));g.appendChild(m)})()}})(); +// Input 104 +gui.SvgSelectionView=function(k){function h(){var b=a.getRootNode();m!==b&&(m=b,e=m.parentNode.parentNode.parentNode,e.appendChild(z),z.setAttribute("class","selectionOverlay"),z.appendChild(x))}function b(b){var c=u.getBoundingClientRect(e),d=a.getCanvas().getZoomLevel(),f={};f.top=u.adaptRangeDifferenceToZoomLevel(b.top-c.top,d);f.left=u.adaptRangeDifferenceToZoomLevel(b.left-c.left,d);f.bottom=u.adaptRangeDifferenceToZoomLevel(b.bottom-c.top,d);f.right=u.adaptRangeDifferenceToZoomLevel(b.right- +c.left,d);f.width=u.adaptRangeDifferenceToZoomLevel(b.width,d);f.height=u.adaptRangeDifferenceToZoomLevel(b.height,d);return f}function p(a){a=a.getBoundingClientRect();return Boolean(a&&0!==a.height)}function d(a){var b=v.getTextElements(a,!0,!1),c=a.cloneRange(),d=a.cloneRange();a=a.cloneRange();if(!b.length)return null;var e;a:{e=0;var f=b[e],g=c.startContainer===f?c.startOffset:0,h=g;c.setStart(f,g);for(c.setEnd(f,h);!p(c);){if(f.nodeType===Node.ELEMENT_NODE&&h<f.childNodes.length)h=f.childNodes.length; +else if(f.nodeType===Node.TEXT_NODE&&h<f.length)h+=1;else if(b[e])f=b[e],e+=1,g=h=0;else{e=!1;break a}c.setStart(f,g);c.setEnd(f,h)}e=!0}if(!e)return null;a:{e=b.length-1;f=b[e];h=g=d.endContainer===f?d.endOffset:f.nodeType===Node.TEXT_NODE?f.length:f.childNodes.length;d.setStart(f,g);for(d.setEnd(f,h);!p(d);){if(f.nodeType===Node.ELEMENT_NODE&&0<g)g=0;else if(f.nodeType===Node.TEXT_NODE&&0<g)g-=1;else if(b[e])f=b[e],e-=1,g=h=f.length||f.childNodes.length;else{b=!1;break a}d.setStart(f,g);d.setEnd(f, +h)}b=!0}if(!b)return null;a.setStart(c.startContainer,c.startOffset);a.setEnd(d.endContainer,d.endOffset);return{firstRange:c,lastRange:d,fillerRange:a}}function n(a,b){var c={};c.top=Math.min(a.top,b.top);c.left=Math.min(a.left,b.left);c.right=Math.max(a.right,b.right);c.bottom=Math.max(a.bottom,b.bottom);c.width=c.right-c.left;c.height=c.bottom-c.top;return c}function g(a,b){b&&0<b.width&&0<b.height&&(a=a?n(a,b):b);return a}function q(b){function c(a){A.setUnfilteredPosition(a,0);return w.acceptNode(a)=== +J&&s.acceptPosition(A)===J?J:G}function d(a){var b=null;c(a)===J&&(b=u.getBoundingClientRect(a));return b}var e=b.commonAncestorContainer,f=b.startContainer,h=b.endContainer,m=b.startOffset,k=b.endOffset,l,n,p=null,q,r=t.createRange(),s,w=new odf.OdfNodeFilter,x;if(f===e||h===e)return r=b.cloneRange(),p=r.getBoundingClientRect(),r.detach(),p;for(b=f;b.parentNode!==e;)b=b.parentNode;for(n=h;n.parentNode!==e;)n=n.parentNode;s=a.createRootFilter(f);for(e=b.nextSibling;e&&e!==n;)q=d(e),p=g(p,q),e=e.nextSibling; +if(v.isParagraph(b))p=g(p,u.getBoundingClientRect(b));else if(b.nodeType===Node.TEXT_NODE)e=b,r.setStart(e,m),r.setEnd(e,e===n?k:e.length),q=r.getBoundingClientRect(),p=g(p,q);else for(x=t.createTreeWalker(b,NodeFilter.SHOW_TEXT,c,!1),e=x.currentNode=f;e&&e!==h;)r.setStart(e,m),r.setEnd(e,e.length),q=r.getBoundingClientRect(),p=g(p,q),l=e,m=0,e=x.nextNode();l||(l=f);if(v.isParagraph(n))p=g(p,u.getBoundingClientRect(n));else if(n.nodeType===Node.TEXT_NODE)e=n,r.setStart(e,e===b?m:0),r.setEnd(e,k), +q=r.getBoundingClientRect(),p=g(p,q);else for(x=t.createTreeWalker(n,NodeFilter.SHOW_TEXT,c,!1),e=x.currentNode=h;e&&e!==l;)if(r.setStart(e,0),r.setEnd(e,k),q=r.getBoundingClientRect(),p=g(p,q),e=x.previousNode())k=e.length;return p}function r(a,b){var c=a.getBoundingClientRect(),d={width:0};d.top=c.top;d.bottom=c.bottom;d.height=c.height;d.left=d.right=b?c.right:c.left;return d}function l(){var a=k.getSelectedRange(),c;if(c=s&&k.getSelectionType()===ops.OdtCursor.RangeSelection&&!a.collapsed){h(); +var a=d(a),e,f,g,m,l,p,t,u;if(a){c=a.firstRange;e=a.lastRange;f=a.fillerRange;g=b(r(c,!1));l=b(r(e,!0));m=(m=q(f))?b(m):n(g,l);p=m.left;m=g.left+Math.max(0,m.width-(g.left-m.left));t=Math.min(g.top,l.top);u=l.top+l.height;g=[{x:g.left,y:t+g.height},{x:g.left,y:t},{x:m,y:t},{x:m,y:u-l.height},{x:l.right,y:u-l.height},{x:l.right,y:u},{x:p,y:u},{x:p,y:t+g.height},{x:g.left,y:t+g.height}];l="";for(p=0;p<g.length;p+=1)l+=g[p].x+","+g[p].y+" ";x.setAttribute("points",l);c.detach();e.detach();f.detach()}c= +Boolean(a)}z.style.display=c?"block":"none"}function f(a){s&&a===k&&D.trigger()}function c(a){e.removeChild(z);k.getDocument().unsubscribe(ops.Document.signalCursorMoved,f);a()}var a=k.getDocument(),m,e,t=a.getDOMDocument(),w=new core.Async,z=t.createElementNS("http://www.w3.org/2000/svg","svg"),x=t.createElementNS("http://www.w3.org/2000/svg","polygon"),v=new odf.OdfUtils,u=new core.DomUtils,s=!0,A=gui.SelectionMover.createPositionIterator(a.getRootNode()),J=NodeFilter.FILTER_ACCEPT,G=NodeFilter.FILTER_REJECT, +D;this.rerender=function(){s&&D.trigger()};this.show=function(){s=!0;D.trigger()};this.hide=function(){s=!1;D.trigger()};this.destroy=function(a){w.destroyAll([D.destroy,c],a)};(function(){var a=k.getMemberId();D=new core.ScheduledTask(l,0);h();z.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",a);k.getDocument().subscribe(ops.Document.signalCursorMoved,f)})()}; +// Input 105 /* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @@ -2948,45 +3210,13 @@ a.push(c);t=new ops.OpInsertImage;t.init({memberid:l,position:n.getCursorPositio @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.PositionFilter"); -gui.TextManipulator=function(g,l,f){function p(d){var c=new ops.OpRemoveText;c.init({memberid:l,position:d.position,length:d.length});return c}function r(d){0>d.length&&(d.position+=d.length,d.length=-d.length);return d}function n(f,c){var e=new core.PositionFilterChain,a=gui.SelectionMover.createPositionIterator(h.getRootElement(f)),b=c?a.nextPosition:a.previousPosition;e.addFilter("BaseFilter",h.getPositionFilter());e.addFilter("RootFilter",h.createRootFilter(l));for(a.setUnfilteredPosition(f,0);b();)if(e.acceptPosition(a)=== -d)return!0;return!1}var h=g.getOdtDocument(),d=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.enqueueParagraphSplittingOps=function(){var d=r(h.getCursorSelection(l)),c,e=[];0<d.length&&(c=p(d),e.push(c));c=new ops.OpSplitParagraph;c.init({memberid:l,position:d.position,moveCursor:!0});e.push(c);g.enqueue(e);return!0};this.removeTextByBackspaceKey=function(){var d=h.getCursor(l),c=r(h.getCursorSelection(l)),e=null;0===c.length?n(d.getNode(),!1)&&(e=new ops.OpRemoveText,e.init({memberid:l,position:c.position- -1,length:1}),g.enqueue([e])):(e=p(c),g.enqueue([e]));return null!==e};this.removeTextByDeleteKey=function(){var d=h.getCursor(l),c=r(h.getCursorSelection(l)),e=null;0===c.length?n(d.getNode(),!0)&&(e=new ops.OpRemoveText,e.init({memberid:l,position:c.position,length:1}),g.enqueue([e])):(e=p(c),g.enqueue([e]));return null!==e};this.removeCurrentSelection=function(){var d=r(h.getCursorSelection(l));0!==d.length&&(d=p(d),g.enqueue([d]));return!0};this.insertText=function(d){var c=r(h.getCursorSelection(l)), -e,a=[];0<c.length&&(e=p(c),a.push(e));e=new ops.OpInsertText;e.init({memberid:l,position:c.position,text:d,moveCursor:!0});a.push(e);f&&(d=f(c.position,d.length))&&a.push(d);g.enqueue(a)}};(function(){return gui.TextManipulator})(); -// Input 97 -runtime.loadClass("core.DomUtils");runtime.loadClass("core.Async");runtime.loadClass("core.ScheduledTask");runtime.loadClass("odf.OdfUtils");runtime.loadClass("odf.ObjectNameGenerator");runtime.loadClass("ops.OdtCursor");runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("gui.Clipboard");runtime.loadClass("gui.DirectTextStyler");runtime.loadClass("gui.DirectParagraphStyler");runtime.loadClass("gui.KeyboardHandler");runtime.loadClass("gui.ImageManager"); -runtime.loadClass("gui.ImageSelector");runtime.loadClass("gui.TextManipulator");runtime.loadClass("gui.AnnotationController");runtime.loadClass("gui.EventManager");runtime.loadClass("gui.PlainTextPasteboard"); -gui.SessionController=function(){var g=core.PositionFilter.FilterResult.FILTER_ACCEPT;gui.SessionController=function(l,f,p,r){function n(a){a.preventDefault?a.preventDefault():a.returnValue=!1}function h(a,b,c){var d=new ops.OpMoveCursor;d.init({memberid:f,position:a,length:b||0,selectionType:c});return d}function d(a){var b=/[A-Za-z0-9]/,c=gui.SelectionMover.createPositionIterator(D.getRootNode()),d;for(c.setUnfilteredPosition(a.startContainer,a.startOffset);c.previousPosition();){d=c.getCurrentNode(); -if(d.nodeType===Node.TEXT_NODE){if(d=d.data[c.unfilteredDomOffset()],!b.test(d))break}else if(!ia.isTextSpan(d))break;a.setStart(c.container(),c.unfilteredDomOffset())}c.setUnfilteredPosition(a.endContainer,a.endOffset);do if(d=c.getCurrentNode(),d.nodeType===Node.TEXT_NODE){if(d=d.data[c.unfilteredDomOffset()],!b.test(d))break}else if(!ia.isTextSpan(d))break;while(c.nextPosition());a.setEnd(c.container(),c.unfilteredDomOffset())}function m(a){var b=D.getParagraphElement(a.startContainer),c=D.getParagraphElement(a.endContainer); -b&&a.setStart(b,0);c&&(ia.isParagraph(a.endContainer)&&0===a.endOffset?a.setEndBefore(c):a.setEnd(c,c.childNodes.length))}function c(a){a=D.getDistanceFromCursor(f,a,0);var b=null!==a?a+1:null,c;if(b||a)c=D.getCursorPosition(f),a=h(c+a,b-a,ops.OdtCursor.RegionSelection),l.enqueue([a]);K.focus()}function e(a){var b=0<=ha.comparePoints(a.anchorNode,a.anchorOffset,a.focusNode,a.focusOffset),c=a.focusNode.ownerDocument.createRange();b?(c.setStart(a.anchorNode,a.anchorOffset),c.setEnd(a.focusNode,a.focusOffset)): -(c.setStart(a.focusNode,a.focusOffset),c.setEnd(a.anchorNode,a.anchorOffset));return{range:c,hasForwardSelection:b}}function a(a){return function(b){var c=a(b);return function(b,d){return a(d)===c}}}function b(b,c,e){var g=D.getOdfCanvas().getElement(),k;k=ha.containsNode(g,b.startContainer);g=ha.containsNode(g,b.endContainer);if(k||g)if(k&&g&&(2===e?d(b):3<=e&&m(b)),b=c?{anchorNode:b.startContainer,anchorOffset:b.startOffset,focusNode:b.endContainer,focusOffset:b.endOffset}:{anchorNode:b.endContainer, -anchorOffset:b.endOffset,focusNode:b.startContainer,focusOffset:b.startOffset},c=D.convertDomToCursorRange(b,a(ia.getParagraphElement)),b=D.getCursorSelection(f),c.position!==b.position||c.length!==b.length)b=h(c.position,c.length,ops.OdtCursor.RangeSelection),l.enqueue([b])}function q(a){var b=D.getCursorSelection(f),c=D.getCursor(f).getStepCounter();0!==a&&(a=0<a?c.convertForwardStepsBetweenFilters(a,sa,xa):-c.convertBackwardStepsBetweenFilters(-a,sa,xa),a=b.length+a,l.enqueue([h(b.position,a)]))} -function k(a){var b=D.getCursorPosition(f),c=D.getCursor(f).getStepCounter();0!==a&&(a=0<a?c.convertForwardStepsBetweenFilters(a,sa,xa):-c.convertBackwardStepsBetweenFilters(-a,sa,xa),l.enqueue([h(b+a,0)]))}function t(){k(-1);return!0}function A(){k(1);return!0}function w(){q(-1);return!0}function x(){q(1);return!0}function v(a,b){var c=D.getParagraphElement(D.getCursor(f).getNode());runtime.assert(Boolean(c),"SessionController: Cursor outside paragraph");c=D.getCursor(f).getStepCounter().countLinesSteps(a, -sa);b?q(c):k(c)}function u(){v(-1,!1);return!0}function s(){v(1,!1);return!0}function H(){v(-1,!0);return!0}function y(){v(1,!0);return!0}function B(a,b){var c=D.getCursor(f).getStepCounter().countStepsToLineBoundary(a,sa);b?q(c):k(c)}function L(){B(-1,!1);return!0}function I(){B(1,!1);return!0}function W(){B(-1,!0);return!0}function Q(){B(1,!0);return!0}function z(){var a=D.getParagraphElement(D.getCursor(f).getNode()),b,c;runtime.assert(Boolean(a),"SessionController: Cursor outside paragraph"); -c=D.getDistanceFromCursor(f,a,0);b=gui.SelectionMover.createPositionIterator(D.getRootNode());for(b.setUnfilteredPosition(a,0);0===c&&b.previousPosition();)a=b.getCurrentNode(),ia.isParagraph(a)&&(c=D.getDistanceFromCursor(f,a,0));q(c);return!0}function ja(){var a=D.getParagraphElement(D.getCursor(f).getNode()),b,c;runtime.assert(Boolean(a),"SessionController: Cursor outside paragraph");b=gui.SelectionMover.createPositionIterator(D.getRootNode());b.moveToEndOfNode(a);for(c=D.getDistanceFromCursor(f, -b.container(),b.unfilteredDomOffset());0===c&&b.nextPosition();)a=b.getCurrentNode(),ia.isParagraph(a)&&(b.moveToEndOfNode(a),c=D.getDistanceFromCursor(f,b.container(),b.unfilteredDomOffset()));q(c);return!0}function ka(a,b){var c=gui.SelectionMover.createPositionIterator(D.getRootNode());0<a&&c.moveToEnd();c=D.getDistanceFromCursor(f,c.container(),c.unfilteredDomOffset());b?q(c):k(c)}function G(){ka(-1,!1);return!0}function Z(){ka(1,!1);return!0}function O(){ka(-1,!0);return!0}function aa(){ka(1, -!0);return!0}function J(){var a=D.getRootNode(),a=D.convertDomPointToCursorStep(a,a.childNodes.length);l.enqueue([h(0,a)]);return!0}function F(){var a=D.getCursor(f);if(a&&a.getSelectionType()===ops.OdtCursor.RegionSelection&&(a=ia.getImageElements(a.getSelectedRange())[0])){ya.select(a.parentNode);return}ya.clearSelection()}function C(a){var b=D.getCursor(f).getSelectedRange();b.collapsed?a.preventDefault():Da.setDataFromRange(a,b)?oa.removeCurrentSelection():runtime.log("Cut operation failed")} -function Y(){return!1!==D.getCursor(f).getSelectedRange().collapsed}function U(a){var b=D.getCursor(f).getSelectedRange();b.collapsed?a.preventDefault():Da.setDataFromRange(a,b)||runtime.log("Copy operation failed")}function R(a){var b;fa.clipboardData&&fa.clipboardData.getData?b=fa.clipboardData.getData("Text"):a.clipboardData&&a.clipboardData.getData&&(b=a.clipboardData.getData("text/plain"));b&&(oa.removeCurrentSelection(),l.enqueue(Fa.createPasteOps(b)));a.preventDefault?a.preventDefault():a.returnValue= -!1}function P(){return!1}function M(a){if(V)V.onOperationExecuted(a)}function ba(a){D.emit(ops.OdtDocument.signalUndoStackChanged,a)}function la(){return V?(V.moveBackward(1),va.trigger(),!0):!1}function ca(){return V?(V.moveForward(1),va.trigger(),!0):!1}function ma(){var a=fa.getSelection(),b=0<a.rangeCount&&e(a);ra&&b&&(ta=!0,ya.clearSelection(),Ea.setUnfilteredPosition(a.focusNode,a.focusOffset),Ba.acceptPosition(Ea)===g&&(2===wa?d(b.range):3<=wa&&m(b.range),p.setSelectedRange(b.range,b.hasForwardSelection), -D.emit(ops.OdtDocument.signalCursorMoved,p)))}function T(a){var b=a.target||a.srcElement,c=D.getCursor(f);if(ra=b&&ha.containsNode(D.getOdfCanvas().getElement(),b))ta=!1,Ba=D.createRootFilter(b),wa=a.detail,c&&a.shiftKey?fa.getSelection().collapse(c.getAnchorNode(),0):(a=fa.getSelection(),b=c.getSelectedRange(),a.extend?c.hasForwardSelection()?(a.collapse(b.startContainer,b.startOffset),a.extend(b.endContainer,b.endOffset)):(a.collapse(b.endContainer,b.endOffset),a.extend(b.startContainer,b.startOffset)): -(a.removeAllRanges(),a.addRange(b.cloneRange()),D.getOdfCanvas().getElement().setActive())),1<wa&&ma()}function $(a){var d=a.target||a.srcElement,f=a.detail,g=a.clientX,h=a.clientY;za.processRequests();ia.isImage(d)&&ia.isCharacterFrame(d.parentNode)?(c(d.parentNode),K.focus()):ra&&!ya.isSelectorElement(d)&&(ta?(b(p.getSelectedRange(),p.hasForwardSelection(),a.detail),K.focus()):runtime.setTimeout(function(){var a;a=(a=fa.getSelection())?{anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode, -focusOffset:a.focusOffset}:null;var c;if(!a.anchorNode&&!a.focusNode){var d=D.getDOM();c=null;d.caretRangeFromPoint?(d=d.caretRangeFromPoint(g,h),c={container:d.startContainer,offset:d.startOffset}):d.caretPositionFromPoint&&(d=d.caretPositionFromPoint(g,h))&&d.offsetNode&&(c={container:d.offsetNode,offset:d.offset});c&&(a.anchorNode=c.container,a.anchorOffset=c.offset,a.focusNode=a.anchorNode,a.focusOffset=a.anchorOffset)}a.anchorNode&&a.focusNode&&(a=e(a),b(a.range,a.hasForwardSelection,f));K.focus()}, -0));wa=0;ta=ra=!1}function X(){ra&&K.focus();wa=0;ta=ra=!1}function da(a){$(a)}function S(a){var b=a.target||a.srcElement,c=null;"annotationRemoveButton"===b.className?(c=ha.getElementsByTagNameNS(b.parentNode,odf.Namespaces.officens,"annotation")[0],ua.removeAnnotation(c)):$(a)}function ga(a){return function(){a();return!0}}function E(a){return function(b){return D.getCursor(f).getSelectionType()===ops.OdtCursor.RangeSelection?a(b):!0}}var fa=runtime.getWindow(),D=l.getOdtDocument(),pa=new core.Async, -ha=new core.DomUtils,ia=new odf.OdfUtils,Da=new gui.Clipboard,N=new gui.KeyboardHandler,qa=new gui.KeyboardHandler,sa=new core.PositionFilterChain,xa=D.getPositionFilter(),ra=!1,Aa=new odf.ObjectNameGenerator(D.getOdfCanvas().odfContainer(),f),ta=!1,Ba=null,V=null,K=new gui.EventManager(D),ua=new gui.AnnotationController(l,f),na=new gui.DirectTextStyler(l,f),ea=r&&r.directParagraphStylingEnabled?new gui.DirectParagraphStyler(l,f,Aa):null,oa=new gui.TextManipulator(l,f,na.createCursorStyleOp),Ca=new gui.ImageManager(l, -f,Aa),ya=new gui.ImageSelector(D.getOdfCanvas()),Ea=gui.SelectionMover.createPositionIterator(D.getRootNode()),za,va,Fa=new gui.PlainTextPasteboard(D,f),wa=0;runtime.assert(null!==fa,"Expected to be run in an environment which has a global window, like a browser.");sa.addFilter("BaseFilter",xa);sa.addFilter("RootFilter",D.createRootFilter(f));this.selectRange=b;this.moveCursorToLeft=t;this.moveCursorToDocumentBoundary=ka;this.extendSelectionToEntireDocument=J;this.startEditing=function(){var a;D.getOdfCanvas().getElement().classList.add("virtualSelections"); -K.subscribe("keydown",N.handleEvent);K.subscribe("keypress",qa.handleEvent);K.subscribe("keyup",n);K.subscribe("beforecut",Y);K.subscribe("cut",C);K.subscribe("copy",U);K.subscribe("beforepaste",P);K.subscribe("paste",R);K.subscribe("mousedown",T);K.subscribe("mousemove",za.trigger);K.subscribe("mouseup",S);K.subscribe("contextmenu",da);K.subscribe("dragend",X);D.subscribe(ops.OdtDocument.signalOperationExecuted,va.trigger);D.subscribe(ops.OdtDocument.signalOperationExecuted,M);a=new ops.OpAddCursor; -a.init({memberid:f});l.enqueue([a]);V&&V.saveInitialState()};this.endEditing=function(){var a;a=new ops.OpRemoveCursor;a.init({memberid:f});l.enqueue([a]);V&&V.resetInitialState();D.unsubscribe(ops.OdtDocument.signalOperationExecuted,M);D.unsubscribe(ops.OdtDocument.signalOperationExecuted,va.trigger);K.unsubscribe("keydown",N.handleEvent);K.unsubscribe("keypress",qa.handleEvent);K.unsubscribe("keyup",n);K.unsubscribe("cut",C);K.unsubscribe("beforecut",Y);K.unsubscribe("copy",U);K.unsubscribe("paste", -R);K.unsubscribe("beforepaste",P);K.unsubscribe("mousemove",za.trigger);K.unsubscribe("mousedown",T);K.unsubscribe("mouseup",S);K.unsubscribe("contextmenu",da);K.unsubscribe("dragend",X);D.getOdfCanvas().getElement().classList.remove("virtualSelections")};this.getInputMemberId=function(){return f};this.getSession=function(){return l};this.setUndoManager=function(a){V&&V.unsubscribe(gui.UndoManager.signalUndoStackChanged,ba);if(V=a)V.setOdtDocument(D),V.setPlaybackFunction(function(a){a.execute(D)}), -V.subscribe(gui.UndoManager.signalUndoStackChanged,ba)};this.getUndoManager=function(){return V};this.getAnnotationController=function(){return ua};this.getDirectTextStyler=function(){return na};this.getDirectParagraphStyler=function(){return ea};this.getImageManager=function(){return Ca};this.getTextManipulator=function(){return oa};this.getEventManager=function(){return K};this.getKeyboardHandlers=function(){return{keydown:N,keypress:qa}};this.destroy=function(a){var b=[za.destroy,na.destroy];ea&& -b.push(ea.destroy);pa.destroyAll(b,a)};(function(){var a=-1!==fa.navigator.appVersion.toLowerCase().indexOf("mac"),b=gui.KeyboardHandler.Modifier,c=gui.KeyboardHandler.KeyCode;za=new core.ScheduledTask(ma,0);va=new core.ScheduledTask(F,0);N.bind(c.Tab,b.None,E(function(){oa.insertText("\t");return!0}));N.bind(c.Left,b.None,E(t));N.bind(c.Right,b.None,E(A));N.bind(c.Up,b.None,E(u));N.bind(c.Down,b.None,E(s));N.bind(c.Backspace,b.None,ga(oa.removeTextByBackspaceKey));N.bind(c.Delete,b.None,oa.removeTextByDeleteKey); -N.bind(c.Left,b.Shift,E(w));N.bind(c.Right,b.Shift,E(x));N.bind(c.Up,b.Shift,E(H));N.bind(c.Down,b.Shift,E(y));N.bind(c.Home,b.None,E(L));N.bind(c.End,b.None,E(I));N.bind(c.Home,b.Ctrl,E(G));N.bind(c.End,b.Ctrl,E(Z));N.bind(c.Home,b.Shift,E(W));N.bind(c.End,b.Shift,E(Q));N.bind(c.Up,b.CtrlShift,E(z));N.bind(c.Down,b.CtrlShift,E(ja));N.bind(c.Home,b.CtrlShift,E(O));N.bind(c.End,b.CtrlShift,E(aa));a?(N.bind(c.Clear,b.None,oa.removeCurrentSelection),N.bind(c.Left,b.Meta,E(L)),N.bind(c.Right,b.Meta,E(I)), -N.bind(c.Home,b.Meta,E(G)),N.bind(c.End,b.Meta,E(Z)),N.bind(c.Left,b.MetaShift,E(W)),N.bind(c.Right,b.MetaShift,E(Q)),N.bind(c.Up,b.AltShift,E(z)),N.bind(c.Down,b.AltShift,E(ja)),N.bind(c.Up,b.MetaShift,E(O)),N.bind(c.Down,b.MetaShift,E(aa)),N.bind(c.A,b.Meta,E(J)),N.bind(c.B,b.Meta,E(na.toggleBold)),N.bind(c.I,b.Meta,E(na.toggleItalic)),N.bind(c.U,b.Meta,E(na.toggleUnderline)),ea&&(N.bind(c.L,b.MetaShift,E(ea.alignParagraphLeft)),N.bind(c.E,b.MetaShift,E(ea.alignParagraphCenter)),N.bind(c.R,b.MetaShift, -E(ea.alignParagraphRight)),N.bind(c.J,b.MetaShift,E(ea.alignParagraphJustified))),ua&&N.bind(c.C,b.MetaShift,ua.addAnnotation),N.bind(c.Z,b.Meta,la),N.bind(c.Z,b.MetaShift,ca)):(N.bind(c.A,b.Ctrl,E(J)),N.bind(c.B,b.Ctrl,E(na.toggleBold)),N.bind(c.I,b.Ctrl,E(na.toggleItalic)),N.bind(c.U,b.Ctrl,E(na.toggleUnderline)),ea&&(N.bind(c.L,b.CtrlShift,E(ea.alignParagraphLeft)),N.bind(c.E,b.CtrlShift,E(ea.alignParagraphCenter)),N.bind(c.R,b.CtrlShift,E(ea.alignParagraphRight)),N.bind(c.J,b.CtrlShift,E(ea.alignParagraphJustified))), -ua&&N.bind(c.C,b.CtrlAlt,ua.addAnnotation),N.bind(c.Z,b.Ctrl,la),N.bind(c.Z,b.CtrlShift,ca));qa.setDefault(E(function(a){var b;b=null===a.which||void 0===a.which?String.fromCharCode(a.keyCode):0!==a.which&&0!==a.charCode?String.fromCharCode(a.which):null;return!b||a.altKey||a.ctrlKey||a.metaKey?!1:(oa.insertText(b),!0)}));qa.bind(c.Enter,b.None,E(oa.enqueueParagraphSplittingOps))})()};return gui.SessionController}(); -// Input 98 +gui.UndoStateRules=function(){function k(b,h){var g=b.length;this.previous=function(){for(g-=1;0<=g;g-=1)if(h(b[g]))return b[g];return null}}function h(b){b=b.spec();var h;b.hasOwnProperty("position")&&(h=b.position);return h}function b(b){return b.isEdit}function p(b,k,g){if(!g)return g=h(b)-h(k),0===g||1===Math.abs(g);b=h(b);k=h(k);g=h(g);return b-k===k-g}this.isEditOperation=b;this.isPartOfOperationSet=function(d,h){var g=void 0!==d.group,q;if(!d.isEdit||0===h.length)return!0;q=h[h.length-1];if(g&& +d.group===q.group)return!0;a:switch(d.spec().optype){case "RemoveText":case "InsertText":q=!0;break a;default:q=!1}if(q&&h.some(b)){if(g){var r;g=d.spec().optype;q=new k(h,b);var l=q.previous(),f=null,c,a;runtime.assert(Boolean(l),"No edit operations found in state");a=l.group;runtime.assert(void 0!==a,"Operation has no group");for(c=1;l&&l.group===a;){if(g===l.spec().optype){r=l;break}l=q.previous()}if(r){for(l=q.previous();l;){if(l.group!==a){if(2===c)break;a=l.group;c+=1}if(g===l.spec().optype){f= +l;break}l=q.previous()}r=p(d,r,f)}else r=!1;return r}r=d.spec().optype;g=new k(h,b);q=g.previous();runtime.assert(Boolean(q),"No edit operations found in state");r=r===q.spec().optype?p(d,q,g.previous()):!1;return r}return!1}}; +// Input 106 /* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -3021,15 +3251,88 @@ ua&&N.bind(c.C,b.CtrlAlt,ua.addAnnotation),N.bind(c.Z,b.Ctrl,la),N.bind(c.Z,b.Ct @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("gui.Caret"); -gui.CaretManager=function(g){function l(a){return b.hasOwnProperty(a)?b[a]:null}function f(){return Object.keys(b).map(function(a){return b[a]})}function p(a){a===g.getInputMemberId()&&g.getSession().getOdtDocument().getOdfCanvas().getElement().removeAttribute("tabindex");delete b[a]}function r(a){a=a.getMemberId();a===g.getInputMemberId()&&(a=l(a))&&a.refreshCursorBlinking()}function n(){var a=l(g.getInputMemberId());k=!1;a&&a.ensureVisible()}function h(){var a=l(g.getInputMemberId());a&&(a.handleUpdate(), -k||(k=!0,runtime.setTimeout(n,50)))}function d(a){a.memberId===g.getInputMemberId()&&h()}function m(){var a=l(g.getInputMemberId());a&&a.setFocus()}function c(){var a=l(g.getInputMemberId());a&&a.removeFocus()}function e(){var a=l(g.getInputMemberId());a&&a.show()}function a(){var a=l(g.getInputMemberId());a&&a.hide()}var b={},q=runtime.getWindow(),k=!1;this.registerCursor=function(a,c,d){var e=a.getMemberId();c=new gui.Caret(a,c,d);b[e]=c;e===g.getInputMemberId()?(runtime.log("Starting to track input on new cursor of "+ -e),a.handleUpdate=h,g.getSession().getOdtDocument().getOdfCanvas().getElement().setAttribute("tabindex",-1),g.getEventManager().focus()):a.handleUpdate=c.handleUpdate;return c};this.getCaret=l;this.getCarets=f;this.destroy=function(h){var k=g.getSession().getOdtDocument(),l=g.getEventManager(),n=f();k.unsubscribe(ops.OdtDocument.signalParagraphChanged,d);k.unsubscribe(ops.OdtDocument.signalCursorMoved,r);k.unsubscribe(ops.OdtDocument.signalCursorRemoved,p);l.unsubscribe("focus",m);l.unsubscribe("blur", -c);q.removeEventListener("focus",e,!1);q.removeEventListener("blur",a,!1);(function u(a,b){b?h(b):a<n.length?n[a].destroy(function(b){u(a+1,b)}):h()})(0,void 0);b={}};(function(){var b=g.getSession().getOdtDocument(),f=g.getEventManager();b.subscribe(ops.OdtDocument.signalParagraphChanged,d);b.subscribe(ops.OdtDocument.signalCursorMoved,r);b.subscribe(ops.OdtDocument.signalCursorRemoved,p);f.subscribe("focus",m);f.subscribe("blur",c);q.addEventListener("focus",e,!1);q.addEventListener("blur",a,!1)})()}; -// Input 99 +gui.TrivialUndoManager=function(k){function h(a){0<a.length&&(u=!0,m(a),u=!1)}function b(){x.emit(gui.UndoManager.signalUndoStackChanged,{undoAvailable:r.hasUndoStates(),redoAvailable:r.hasRedoStates()})}function p(){t!==a&&t!==w[w.length-1]&&w.push(t)}function d(a){var b=a.previousSibling||a.nextSibling;a.parentNode.removeChild(a);f.normalizeTextNodes(b)}function n(a){return Object.keys(a).map(function(b){return a[b]})}function g(a){function b(a){var e=a.spec();if(f[e.memberid])switch(e.optype){case "AddCursor":c[e.memberid]|| +(c[e.memberid]=a,delete f[e.memberid],g-=1);break;case "MoveCursor":d[e.memberid]||(d[e.memberid]=a)}}var c={},d={},f={},g,h=a.pop();e.getMemberIds().forEach(function(a){f[a]=!0});for(g=Object.keys(f).length;h&&0<g;)h.reverse(),h.forEach(b),h=a.pop();return n(c).concat(n(d))}function q(){var h=c=e.cloneDocumentElement();f.getElementsByTagNameNS(h,l,"cursor").forEach(d);f.getElementsByTagNameNS(h,l,"anchor").forEach(d);p();t=a=g([a].concat(w));w.length=0;z.length=0;b()}var r=this,l="urn:webodf:names:cursor", +f=new core.DomUtils,c,a=[],m,e,t=[],w=[],z=[],x=new core.EventNotifier([gui.UndoManager.signalUndoStackChanged,gui.UndoManager.signalUndoStateCreated,gui.UndoManager.signalUndoStateModified,gui.TrivialUndoManager.signalDocumentRootReplaced]),v=k||new gui.UndoStateRules,u=!1;this.subscribe=function(a,b){x.subscribe(a,b)};this.unsubscribe=function(a,b){x.unsubscribe(a,b)};this.hasUndoStates=function(){return 0<w.length};this.hasRedoStates=function(){return 0<z.length};this.setDocument=function(a){e= +a};this.purgeInitialState=function(){w.length=0;z.length=0;a.length=0;t.length=0;c=null;b()};this.setInitialState=q;this.initialize=function(){c||q()};this.setPlaybackFunction=function(a){m=a};this.onOperationExecuted=function(c){u||(v.isEditOperation(c)&&(t===a||0<z.length)||!v.isPartOfOperationSet(c,t)?(z.length=0,p(),t=[c],w.push(t),x.emit(gui.UndoManager.signalUndoStateCreated,{operations:t}),b()):(t.push(c),x.emit(gui.UndoManager.signalUndoStateModified,{operations:t})))};this.moveForward=function(a){for(var c= +0,e;a&&z.length;)e=z.pop(),w.push(e),h(e),a-=1,c+=1;c&&(t=w[w.length-1],b());return c};this.moveBackward=function(d){for(var f=0;d&&w.length;)z.push(w.pop()),d-=1,f+=1;f&&(e.setDocumentElement(c.cloneNode(!0)),x.emit(gui.TrivialUndoManager.signalDocumentRootReplaced,{}),e.getMemberIds().forEach(function(a){e.removeCursor(a)}),h(a),w.forEach(h),t=w[w.length-1]||a,b());return f}};gui.TrivialUndoManager.signalDocumentRootReplaced="documentRootReplaced";(function(){return gui.TrivialUndoManager})(); +// Input 107 /* - Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +ops.OperationTransformMatrix=function(){function k(b){b.position+=b.length;b.length*=-1}function h(b){var a=0>b.length;a&&k(b);return a}function b(b,a){function d(f){b[f]===a&&e.push(f)}var e=[];b&&["style:parent-style-name","style:next-style-name"].forEach(d);return e}function p(b,a){function d(e){b[e]===a&&delete b[e]}b&&["style:parent-style-name","style:next-style-name"].forEach(d)}function d(b){var a={};Object.keys(b).forEach(function(f){a[f]="object"===typeof b[f]?d(b[f]):b[f]});return a}function n(b, +a,d,e){var f,g=!1,h=!1,k,l=[];e&&e.attributes&&(l=e.attributes.split(","));b&&(d||0<l.length)&&Object.keys(b).forEach(function(a){var e=b[a],f;"object"!==typeof e&&(d&&(f=d[a]),void 0!==f?(delete b[a],h=!0,f===e&&(delete d[a],g=!0)):-1!==l.indexOf(a)&&(delete b[a],h=!0))});if(a&&a.attributes&&(d||0<l.length)){k=a.attributes.split(",");for(e=0;e<k.length;e+=1)if(f=k[e],d&&void 0!==d[f]||l&&-1!==l.indexOf(f))k.splice(e,1),e-=1,h=!0;0<k.length?a.attributes=k.join(","):delete a.attributes}return{majorChanged:g, +minorChanged:h}}function g(b){for(var a in b)if(b.hasOwnProperty(a))return!0;return!1}function q(b){for(var a in b)if(b.hasOwnProperty(a)&&("attributes"!==a||0<b.attributes.length))return!0;return!1}function r(b,a,d,e,f){var h=b?b[f]:null,k=a?a[f]:null,l=d?d[f]:null,p=e?e[f]:null,r;r=n(h,k,l,p);h&&!g(h)&&delete b[f];k&&!q(k)&&delete a[f];l&&!g(l)&&delete d[f];p&&!q(p)&&delete e[f];return r}function l(b,a){return{opSpecsA:[b],opSpecsB:[a]}}var f;f={AddCursor:{AddCursor:l,AddMember:l,AddStyle:l,ApplyDirectStyling:l, +InsertText:l,MoveCursor:l,RemoveCursor:l,RemoveMember:l,RemoveStyle:l,RemoveText:l,SetParagraphStyle:l,SplitParagraph:l,UpdateMember:l,UpdateMetadata:l,UpdateParagraphStyle:l},AddMember:{AddStyle:l,InsertText:l,MoveCursor:l,RemoveCursor:l,RemoveStyle:l,RemoveText:l,SetParagraphStyle:l,SplitParagraph:l,UpdateMetadata:l,UpdateParagraphStyle:l},AddStyle:{AddStyle:l,ApplyDirectStyling:l,InsertText:l,MoveCursor:l,RemoveCursor:l,RemoveMember:l,RemoveStyle:function(c,a){var d,e=[c],f=[a];c.styleFamily=== +a.styleFamily&&(d=b(c.setProperties,a.styleName),0<d.length&&(d={optype:"UpdateParagraphStyle",memberid:a.memberid,timestamp:a.timestamp,styleName:c.styleName,removedProperties:{attributes:d.join(",")}},f.unshift(d)),p(c.setProperties,a.styleName));return{opSpecsA:e,opSpecsB:f}},RemoveText:l,SetParagraphStyle:l,SplitParagraph:l,UpdateMember:l,UpdateMetadata:l,UpdateParagraphStyle:l},ApplyDirectStyling:{ApplyDirectStyling:function(b,a,f){var e,h,k,l,n,p,q,s;l=[b];k=[a];if(!(b.position+b.length<=a.position|| +b.position>=a.position+a.length)){e=f?b:a;h=f?a:b;if(b.position!==a.position||b.length!==a.length)p=d(e),q=d(h);a=r(h.setProperties,null,e.setProperties,null,"style:text-properties");if(a.majorChanged||a.minorChanged)k=[],b=[],l=e.position+e.length,n=h.position+h.length,h.position<e.position?a.minorChanged&&(s=d(q),s.length=e.position-h.position,b.push(s),h.position=e.position,h.length=n-h.position):e.position<h.position&&a.majorChanged&&(s=d(p),s.length=h.position-e.position,k.push(s),e.position= +h.position,e.length=l-e.position),n>l?a.minorChanged&&(p=q,p.position=l,p.length=n-l,b.push(p),h.length=l-h.position):l>n&&a.majorChanged&&(p.position=n,p.length=l-n,k.push(p),e.length=n-e.position),e.setProperties&&g(e.setProperties)&&k.push(e),h.setProperties&&g(h.setProperties)&&b.push(h),f?(l=k,k=b):l=b}return{opSpecsA:l,opSpecsB:k}},InsertText:function(b,a){a.position<=b.position?b.position+=a.text.length:a.position<=b.position+b.length&&(b.length+=a.text.length);return{opSpecsA:[b],opSpecsB:[a]}}, +MoveCursor:l,RemoveCursor:l,RemoveStyle:l,RemoveText:function(b,a){var d=b.position+b.length,e=a.position+a.length,f=[b],g=[a];e<=b.position?b.position-=a.length:a.position<d&&(b.position<a.position?b.length=e<d?b.length-a.length:a.position-b.position:(b.position=a.position,e<d?b.length=d-e:f=[]));return{opSpecsA:f,opSpecsB:g}},SetParagraphStyle:l,SplitParagraph:function(b,a){a.position<b.position?b.position+=1:a.position<b.position+b.length&&(b.length+=1);return{opSpecsA:[b],opSpecsB:[a]}},UpdateMetadata:l, +UpdateParagraphStyle:l},InsertText:{InsertText:function(b,a,d){b.position<a.position?a.position+=b.text.length:b.position>a.position?b.position+=a.text.length:d?a.position+=b.text.length:b.position+=a.text.length;return{opSpecsA:[b],opSpecsB:[a]}},MoveCursor:function(b,a){var d=h(a);b.position<a.position?a.position+=b.text.length:b.position<a.position+a.length&&(a.length+=b.text.length);d&&k(a);return{opSpecsA:[b],opSpecsB:[a]}},RemoveCursor:l,RemoveMember:l,RemoveStyle:l,RemoveText:function(b,a){var d; +d=a.position+a.length;var e=[b],f=[a];d<=b.position?b.position-=a.length:b.position<=a.position?a.position+=b.text.length:(a.length=b.position-a.position,d={optype:"RemoveText",memberid:a.memberid,timestamp:a.timestamp,position:b.position+b.text.length,length:d-b.position},f.unshift(d),b.position=a.position);return{opSpecsA:e,opSpecsB:f}},SplitParagraph:function(b,a,d){if(b.position<a.position)a.position+=b.text.length;else if(b.position>a.position)b.position+=1;else return d?a.position+=b.text.length: +b.position+=1,null;return{opSpecsA:[b],opSpecsB:[a]}},UpdateMember:l,UpdateMetadata:l,UpdateParagraphStyle:l},MoveCursor:{MoveCursor:l,RemoveCursor:function(b,a){return{opSpecsA:b.memberid===a.memberid?[]:[b],opSpecsB:[a]}},RemoveMember:l,RemoveStyle:l,RemoveText:function(b,a){var d=h(b),e=b.position+b.length,f=a.position+a.length;f<=b.position?b.position-=a.length:a.position<e&&(b.position<a.position?b.length=f<e?b.length-a.length:a.position-b.position:(b.position=a.position,b.length=f<e?e-f:0)); +d&&k(b);return{opSpecsA:[b],opSpecsB:[a]}},SetParagraphStyle:l,SplitParagraph:function(b,a){var d=h(b);a.position<b.position?b.position+=1:a.position<b.position+b.length&&(b.length+=1);d&&k(b);return{opSpecsA:[b],opSpecsB:[a]}},UpdateMember:l,UpdateMetadata:l,UpdateParagraphStyle:l},RemoveCursor:{RemoveCursor:function(b,a){var d=b.memberid===a.memberid;return{opSpecsA:d?[]:[b],opSpecsB:d?[]:[a]}},RemoveMember:l,RemoveStyle:l,RemoveText:l,SetParagraphStyle:l,SplitParagraph:l,UpdateMember:l,UpdateMetadata:l, +UpdateParagraphStyle:l},RemoveMember:{RemoveStyle:l,RemoveText:l,SetParagraphStyle:l,SplitParagraph:l,UpdateMetadata:l,UpdateParagraphStyle:l},RemoveStyle:{RemoveStyle:function(b,a){var d=b.styleName===a.styleName&&b.styleFamily===a.styleFamily;return{opSpecsA:d?[]:[b],opSpecsB:d?[]:[a]}},RemoveText:l,SetParagraphStyle:function(b,a){var d,e=[b],f=[a];"paragraph"===b.styleFamily&&b.styleName===a.styleName&&(d={optype:"SetParagraphStyle",memberid:b.memberid,timestamp:b.timestamp,position:a.position, +styleName:""},e.unshift(d),a.styleName="");return{opSpecsA:e,opSpecsB:f}},SplitParagraph:l,UpdateMember:l,UpdateMetadata:l,UpdateParagraphStyle:function(c,a){var d,e=[c],f=[a];"paragraph"===c.styleFamily&&(d=b(a.setProperties,c.styleName),0<d.length&&(d={optype:"UpdateParagraphStyle",memberid:c.memberid,timestamp:c.timestamp,styleName:a.styleName,removedProperties:{attributes:d.join(",")}},e.unshift(d)),c.styleName===a.styleName?f=[]:p(a.setProperties,c.styleName));return{opSpecsA:e,opSpecsB:f}}}, +RemoveText:{RemoveText:function(b,a){var d=b.position+b.length,e=a.position+a.length,f=[b],g=[a];e<=b.position?b.position-=a.length:d<=a.position?a.position-=b.length:a.position<d&&(b.position<a.position?(b.length=e<d?b.length-a.length:a.position-b.position,d<e?(a.position=b.position,a.length=e-d):g=[]):(d<e?a.length-=b.length:a.position<b.position?a.length=b.position-a.position:g=[],e<d?(b.position=a.position,b.length=d-e):f=[]));return{opSpecsA:f,opSpecsB:g}},SplitParagraph:function(b,a){var d= +b.position+b.length,e=[b],f=[a];a.position<=b.position?b.position+=1:a.position<d&&(b.length=a.position-b.position,d={optype:"RemoveText",memberid:b.memberid,timestamp:b.timestamp,position:a.position+1,length:d-a.position},e.unshift(d));b.position+b.length<=a.position?a.position-=b.length:b.position<a.position&&(a.position=b.position);return{opSpecsA:e,opSpecsB:f}},UpdateMember:l,UpdateMetadata:l,UpdateParagraphStyle:l},SetParagraphStyle:{UpdateMember:l,UpdateMetadata:l,UpdateParagraphStyle:l},SplitParagraph:{SplitParagraph:function(b, +a,d){b.position<a.position?a.position+=1:b.position>a.position?b.position+=1:b.position===a.position&&(d?a.position+=1:b.position+=1);return{opSpecsA:[b],opSpecsB:[a]}},UpdateMember:l,UpdateMetadata:l,UpdateParagraphStyle:l},UpdateMember:{UpdateMetadata:l,UpdateParagraphStyle:l},UpdateMetadata:{UpdateMetadata:function(b,a,d){var e,f=[b],h=[a];e=d?b:a;b=d?a:b;n(b.setProperties||null,b.removedProperties||null,e.setProperties||null,e.removedProperties||null);e.setProperties&&g(e.setProperties)||e.removedProperties&& +q(e.removedProperties)||(d?f=[]:h=[]);b.setProperties&&g(b.setProperties)||b.removedProperties&&q(b.removedProperties)||(d?h=[]:f=[]);return{opSpecsA:f,opSpecsB:h}},UpdateParagraphStyle:l},UpdateParagraphStyle:{UpdateParagraphStyle:function(b,a,d){var e,f=[b],h=[a];b.styleName===a.styleName&&(e=d?b:a,b=d?a:b,r(b.setProperties,b.removedProperties,e.setProperties,e.removedProperties,"style:paragraph-properties"),r(b.setProperties,b.removedProperties,e.setProperties,e.removedProperties,"style:text-properties"), +n(b.setProperties||null,b.removedProperties||null,e.setProperties||null,e.removedProperties||null),e.setProperties&&g(e.setProperties)||e.removedProperties&&q(e.removedProperties)||(d?f=[]:h=[]),b.setProperties&&g(b.setProperties)||b.removedProperties&&q(b.removedProperties)||(d?h=[]:f=[]));return{opSpecsA:f,opSpecsB:h}}}};this.passUnchanged=l;this.extendTransformations=function(b){Object.keys(b).forEach(function(a){var d=b[a],e,g=f.hasOwnProperty(a);runtime.log((g?"Extending":"Adding")+" map for optypeA: "+ +a);g||(f[a]={});e=f[a];Object.keys(d).forEach(function(b){var c=e.hasOwnProperty(b);runtime.assert(a<=b,"Wrong order:"+a+", "+b);runtime.log(" "+(c?"Overwriting":"Adding")+" entry for optypeB: "+b);e[b]=d[b]})})};this.transformOpspecVsOpspec=function(b,a){var d=b.optype<=a.optype,e;runtime.log("Crosstransforming:");runtime.log(runtime.toJson(b));runtime.log(runtime.toJson(a));d||(e=b,b=a,a=e);(e=(e=f[b.optype])&&e[a.optype])?(e=e(b,a,!d),d||null===e||(e={opSpecsA:e.opSpecsB,opSpecsB:e.opSpecsA})): +e=null;runtime.log("result:");e?(runtime.log(runtime.toJson(e.opSpecsA)),runtime.log(runtime.toJson(e.opSpecsB))):runtime.log("null");return e}}; +// Input 108 +/* + + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> + + @licstart + This file is part of WebODF. + + WebODF 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. + + WebODF 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 WebODF. If not, see <http://www.gnu.org/licenses/>. + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +ops.OperationTransformer=function(){function k(d){var h=[];d.forEach(function(d){h.push(b.create(d))});return h}function h(b,k){for(var g,q,r=[],l=[];0<b.length&&k;){g=b.shift();g=p.transformOpspecVsOpspec(g,k);if(!g)return null;r=r.concat(g.opSpecsA);if(0===g.opSpecsB.length){r=r.concat(b);k=null;break}for(;1<g.opSpecsB.length;){q=h(b,g.opSpecsB.shift());if(!q)return null;l=l.concat(q.opSpecsB);b=q.opSpecsA}k=g.opSpecsB.pop()}k&&l.push(k);return{opSpecsA:r,opSpecsB:l}}var b,p=new ops.OperationTransformMatrix; +this.setOperationFactory=function(d){b=d};this.getOperationTransformMatrix=function(){return p};this.transform=function(b,n){for(var g,p=[];0<n.length;){g=h(b,n.shift());if(!g)return null;b=g.opSpecsA;p=p.concat(g.opSpecsB)}return{opsA:k(b),opsB:k(p)}}}; +// Input 109 +/* + + Copyright (C) 2013 KO GmbH <copyright@kogmbh.com> @licstart The JavaScript code in this page is free software: you can redistribute it @@ -3064,15 +3367,6 @@ c);q.removeEventListener("focus",e,!1);q.removeEventListener("blur",a,!1);(funct @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("gui.Caret");runtime.loadClass("ops.EditInfo");runtime.loadClass("gui.EditInfoMarker");gui.SessionViewOptions=function(){this.caretBlinksOnRangeSelect=this.caretAvatarsInitiallyVisible=this.editInfoMarkersInitiallyVisible=!0}; -gui.SessionView=function(){return function(g,l,f,p,r){function n(a,b,c){function d(b,c,e){c=b+'[editinfo|memberid="'+a+'"]'+e+c;a:{var f=t.firstChild;for(b=b+'[editinfo|memberid="'+a+'"]'+e+"{";f;){if(f.nodeType===Node.TEXT_NODE&&0===f.data.indexOf(b)){b=f;break a}f=f.nextSibling}b=null}b?b.data=c:t.appendChild(document.createTextNode(c))}d("div.editInfoMarker","{ background-color: "+c+"; }","");d("span.editInfoColor","{ background-color: "+c+"; }","");d("span.editInfoAuthor",'{ content: "'+b+'"; }', -":before");d("dc|creator","{ background-color: "+c+"; }","");d("div.selectionOverlay","{ background-color: "+c+";}","")}function h(a){var b,c;for(c in w)w.hasOwnProperty(c)&&(b=w[c],a?b.show():b.hide())}function d(a){p.getCarets().forEach(function(b){a?b.showHandle():b.hideHandle()})}function m(a){var b=a.getMemberId();a=a.getProperties();n(b,a.fullName,a.color);l===b&&n("","",a.color)}function c(a){var b=a.getMemberId(),c=f.getOdtDocument().getMember(b).getProperties();p.registerCursor(a,v,u);r.registerCursor(a, -!0);if(a=p.getCaret(b))a.setAvatarImageUrl(c.imageUrl),a.setColor(c.color);runtime.log("+++ View here +++ eagerly created an Caret for '"+b+"'! +++")}function e(a){a=a.getMemberId();var b=r.getSelectionView(l),c=r.getSelectionView(gui.ShadowCursor.ShadowCursorMemberId),d=p.getCaret(l);a===l?(c.hide(),b&&b.show(),d&&d.show()):a===gui.ShadowCursor.ShadowCursorMemberId&&(c.show(),b&&b.hide(),d&&d.hide())}function a(a){r.removeSelectionView(a)}function b(a){var b=a.paragraphElement,c=a.memberId;a=a.timeStamp; -var d,e="",g=b.getElementsByTagNameNS(A,"editinfo")[0];g?(e=g.getAttributeNS(A,"id"),d=w[e]):(e=Math.random().toString(),d=new ops.EditInfo(b,f.getOdtDocument()),d=new gui.EditInfoMarker(d,x),g=b.getElementsByTagNameNS(A,"editinfo")[0],g.setAttributeNS(A,"id",e),w[e]=d);d.addEdit(c,new Date(a))}function q(){H=!0}function k(){s=runtime.getWindow().setInterval(function(){H&&(r.rerenderSelectionViews(),H=!1)},200)}var t,A="urn:webodf:names:editinfo",w={},x=void 0!==g.editInfoMarkersInitiallyVisible? -Boolean(g.editInfoMarkersInitiallyVisible):!0,v=void 0!==g.caretAvatarsInitiallyVisible?Boolean(g.caretAvatarsInitiallyVisible):!0,u=void 0!==g.caretBlinksOnRangeSelect?Boolean(g.caretBlinksOnRangeSelect):!0,s,H=!1;this.showEditInfoMarkers=function(){x||(x=!0,h(x))};this.hideEditInfoMarkers=function(){x&&(x=!1,h(x))};this.showCaretAvatars=function(){v||(v=!0,d(v))};this.hideCaretAvatars=function(){v&&(v=!1,d(v))};this.getSession=function(){return f};this.getCaret=function(a){return p.getCaret(a)}; -this.destroy=function(d){var g=f.getOdtDocument(),h=Object.keys(w).map(function(a){return w[a]});g.unsubscribe(ops.OdtDocument.signalMemberAdded,m);g.unsubscribe(ops.OdtDocument.signalMemberUpdated,m);g.unsubscribe(ops.OdtDocument.signalCursorAdded,c);g.unsubscribe(ops.OdtDocument.signalCursorRemoved,a);g.unsubscribe(ops.OdtDocument.signalParagraphChanged,b);g.unsubscribe(ops.OdtDocument.signalCursorMoved,e);g.unsubscribe(ops.OdtDocument.signalParagraphChanged,q);g.unsubscribe(ops.OdtDocument.signalTableAdded, -q);g.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,q);runtime.getWindow().clearInterval(s);t.parentNode.removeChild(t);(function W(a,b){b?d(b):a<h.length?h[a].destroy(function(b){W(a+1,b)}):d()})(0,void 0)};(function(){var d=f.getOdtDocument(),g=document.getElementsByTagName("head")[0];d.subscribe(ops.OdtDocument.signalMemberAdded,m);d.subscribe(ops.OdtDocument.signalMemberUpdated,m);d.subscribe(ops.OdtDocument.signalCursorAdded,c);d.subscribe(ops.OdtDocument.signalCursorRemoved,a);d.subscribe(ops.OdtDocument.signalParagraphChanged, -b);d.subscribe(ops.OdtDocument.signalCursorMoved,e);k();d.subscribe(ops.OdtDocument.signalParagraphChanged,q);d.subscribe(ops.OdtDocument.signalTableAdded,q);d.subscribe(ops.OdtDocument.signalParagraphStyleModified,q);t=document.createElementNS(g.namespaceURI,"style");t.type="text/css";t.media="screen, print, handheld, projection";t.appendChild(document.createTextNode("@namespace editinfo url(urn:webodf:names:editinfo);"));t.appendChild(document.createTextNode("@namespace dc url(http://purl.org/dc/elements/1.1/);")); -g.appendChild(t)})()}}(); -// Input 100 -var webodf_css="@namespace draw url(urn:oasis:names:tc:opendocument:xmlns:drawing:1.0);\n@namespace fo url(urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0);\n@namespace office url(urn:oasis:names:tc:opendocument:xmlns:office:1.0);\n@namespace presentation url(urn:oasis:names:tc:opendocument:xmlns:presentation:1.0);\n@namespace style url(urn:oasis:names:tc:opendocument:xmlns:style:1.0);\n@namespace svg url(urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0);\n@namespace table url(urn:oasis:names:tc:opendocument:xmlns:table:1.0);\n@namespace text url(urn:oasis:names:tc:opendocument:xmlns:text:1.0);\n@namespace webodfhelper url(urn:webodf:names:helper);\n@namespace cursor url(urn:webodf:names:cursor);\n@namespace editinfo url(urn:webodf:names:editinfo);\n@namespace annotation url(urn:webodf:names:annotation);\n@namespace dc url(http://purl.org/dc/elements/1.1/);\n\noffice|document > *, office|document-content > * {\n display: none;\n}\noffice|body, office|document {\n display: inline-block;\n position: relative;\n}\n\ntext|p, text|h {\n display: block;\n padding: 0;\n margin: 0;\n line-height: normal;\n position: relative;\n min-height: 1.3em; /* prevent empty paragraphs and headings from collapsing if they are empty */\n}\n*[webodfhelper|containsparagraphanchor] {\n position: relative;\n}\ntext|s {\n white-space: pre;\n}\ntext|tab {\n display: inline;\n white-space: pre;\n}\ntext|tracked-changes {\n /*Consumers that do not support change tracking, should ignore changes.*/\n display: none;\n}\noffice|binary-data {\n display: none;\n}\noffice|text {\n display: block;\n text-align: left;\n overflow: visible;\n word-wrap: break-word;\n}\n\noffice|text::selection {\n /** Let's not draw selection highlight that overflows into the office|text\n * node when selecting content across several paragraphs\n */\n background: transparent;\n}\n\n.virtualSelections office|document *::selection {\n background: transparent;\n}\n.virtualSelections office|document *::-moz-selection {\n background: transparent;\n}\n\noffice|text * draw|text-box {\n/** only for text documents */\n display: block;\n border: 1px solid #d3d3d3;\n}\noffice|spreadsheet {\n display: block;\n border-collapse: collapse;\n empty-cells: show;\n font-family: sans-serif;\n font-size: 10pt;\n text-align: left;\n page-break-inside: avoid;\n overflow: hidden;\n}\noffice|presentation {\n display: inline-block;\n text-align: left;\n}\n#shadowContent {\n display: inline-block;\n text-align: left;\n}\ndraw|page {\n display: block;\n position: relative;\n overflow: hidden;\n}\npresentation|notes, presentation|footer-decl, presentation|date-time-decl {\n display: none;\n}\n@media print {\n draw|page {\n border: 1pt solid black;\n page-break-inside: avoid;\n }\n presentation|notes {\n /*TODO*/\n }\n}\noffice|spreadsheet text|p {\n border: 0px;\n padding: 1px;\n margin: 0px;\n}\noffice|spreadsheet table|table {\n margin: 3px;\n}\noffice|spreadsheet table|table:after {\n /* show sheet name the end of the sheet */\n /*content: attr(table|name);*/ /* gives parsing error in opera */\n}\noffice|spreadsheet table|table-row {\n counter-increment: row;\n}\noffice|spreadsheet table|table-row:before {\n width: 3em;\n background: #cccccc;\n border: 1px solid black;\n text-align: center;\n content: counter(row);\n display: table-cell;\n}\noffice|spreadsheet table|table-cell {\n border: 1px solid #cccccc;\n}\ntable|table {\n display: table;\n}\ndraw|frame table|table {\n width: 100%;\n height: 100%;\n background: white;\n}\ntable|table-header-rows {\n display: table-header-group;\n}\ntable|table-row {\n display: table-row;\n}\ntable|table-column {\n display: table-column;\n}\ntable|table-cell {\n width: 0.889in;\n display: table-cell;\n word-break: break-all; /* prevent long words from extending out the table cell */\n}\ndraw|frame {\n display: block;\n}\ndraw|image {\n display: block;\n width: 100%;\n height: 100%;\n top: 0px;\n left: 0px;\n background-repeat: no-repeat;\n background-size: 100% 100%;\n -moz-background-size: 100% 100%;\n}\n/* only show the first image in frame */\ndraw|frame > draw|image:nth-of-type(n+2) {\n display: none;\n}\ntext|list:before {\n display: none;\n content:\"\";\n}\ntext|list {\n counter-reset: list;\n}\ntext|list-item {\n display: block;\n}\ntext|number {\n display:none;\n}\n\ntext|a {\n color: blue;\n text-decoration: underline;\n cursor: pointer;\n}\ntext|note-citation {\n vertical-align: super;\n font-size: smaller;\n}\ntext|note-body {\n display: none;\n}\ntext|note:hover text|note-citation {\n background: #dddddd;\n}\ntext|note:hover text|note-body {\n display: block;\n left:1em;\n max-width: 80%;\n position: absolute;\n background: #ffffaa;\n}\nsvg|title, svg|desc {\n display: none;\n}\nvideo {\n width: 100%;\n height: 100%\n}\n\n/* below set up the cursor */\ncursor|cursor {\n display: inline;\n width: 0px;\n height: 1em;\n /* making the position relative enables the avatar to use\n the cursor as reference for its absolute position */\n position: relative;\n z-index: 1;\n}\ncursor|cursor > span {\n /* IMPORTANT: when changing these values ensure DEFAULT_CARET_TOP and DEFAULT_CARET_HEIGHT\n in Caret.js remain in sync */\n display: inline;\n position: absolute;\n top: 5%; /* push down the caret; 0px can do the job, 5% looks better, 10% is a bit over */\n height: 1em;\n border-left: 2px solid black;\n outline: none;\n}\n\ncursor|cursor > div {\n padding: 3px;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n border: none !important;\n border-radius: 5px;\n opacity: 0.3;\n}\n\ncursor|cursor > div > img {\n border-radius: 5px;\n}\n\ncursor|cursor > div.active {\n opacity: 0.8;\n}\n\ncursor|cursor > div:after {\n content: ' ';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 43%;\n}\n\n\n.editInfoMarker {\n position: absolute;\n width: 10px;\n height: 100%;\n left: -20px;\n opacity: 0.8;\n top: 0;\n border-radius: 5px;\n background-color: transparent;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n}\n.editInfoMarker:hover {\n box-shadow: 0px 0px 8px rgba(0, 0, 0, 1);\n}\n\n.editInfoHandle {\n position: absolute;\n background-color: black;\n padding: 5px;\n border-radius: 5px;\n opacity: 0.8;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n bottom: 100%;\n margin-bottom: 10px;\n z-index: 3;\n left: -25px;\n}\n.editInfoHandle:after {\n content: ' ';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 5px;\n}\n.editInfo {\n font-family: sans-serif;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n color: white;\n width: 100%;\n height: 12pt;\n}\n.editInfoColor {\n float: left;\n width: 10pt;\n height: 10pt;\n border: 1px solid white;\n}\n.editInfoAuthor {\n float: left;\n margin-left: 5pt;\n font-size: 10pt;\n text-align: left;\n height: 12pt;\n line-height: 12pt;\n}\n.editInfoTime {\n float: right;\n margin-left: 30pt;\n font-size: 8pt;\n font-style: italic;\n color: yellow;\n height: 12pt;\n line-height: 12pt;\n}\n\n.annotationWrapper {\n display: inline;\n position: relative;\n}\n\n.annotationRemoveButton:before {\n content: '\u00d7';\n color: white;\n padding: 5px;\n line-height: 1em;\n}\n\n.annotationRemoveButton {\n width: 20px;\n height: 20px;\n border-radius: 10px;\n background-color: black;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n position: absolute;\n top: -10px;\n left: -10px;\n z-index: 3;\n text-align: center;\n font-family: sans-serif;\n font-style: normal;\n font-weight: normal;\n text-decoration: none;\n font-size: 15px;\n}\n.annotationRemoveButton:hover {\n cursor: pointer;\n box-shadow: 0px 0px 5px rgba(0, 0, 0, 1);\n}\n\n.annotationNote {\n width: 4cm;\n position: absolute;\n display: inline;\n z-index: 10;\n}\n.annotationNote > office|annotation {\n display: block;\n text-align: left;\n}\n\n.annotationConnector {\n position: absolute;\n display: inline;\n z-index: 2;\n border-top: 1px dashed brown;\n}\n.annotationConnector.angular {\n -moz-transform-origin: left top;\n -webkit-transform-origin: left top;\n -ms-transform-origin: left top;\n transform-origin: left top;\n}\n.annotationConnector.horizontal {\n left: 0;\n}\n.annotationConnector.horizontal:before {\n content: '';\n display: inline;\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: brown transparent transparent transparent;\n top: -1px;\n left: -5px;\n}\n\noffice|annotation {\n width: 100%;\n height: 100%;\n display: none;\n background: rgb(198, 238, 184);\n background: -moz-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -webkit-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -o-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -ms-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: linear-gradient(180deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n box-shadow: 0 3px 4px -3px #ccc;\n}\n\noffice|annotation > dc|creator {\n display: block;\n font-size: 10pt;\n font-weight: normal;\n font-style: normal;\n font-family: sans-serif;\n color: white;\n background-color: brown;\n padding: 4px;\n}\noffice|annotation > dc|date {\n display: block;\n font-size: 10pt;\n font-weight: normal;\n font-style: normal;\n font-family: sans-serif;\n border: 4px solid transparent;\n}\noffice|annotation > text|list {\n display: block;\n padding: 5px;\n}\n\n/* This is very temporary CSS. This must go once\n * we start bundling webodf-default ODF styles for annotations.\n */\noffice|annotation text|p {\n font-size: 10pt;\n color: black;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n font-family: sans-serif;\n}\n\ndc|*::selection {\n background: transparent;\n}\ndc|*::-moz-selection {\n background: transparent;\n}\n\n#annotationsPane {\n background-color: #EAEAEA;\n width: 4cm;\n height: 100%;\n display: none;\n position: absolute;\n outline: 1px solid #ccc;\n}\n\n.annotationHighlight {\n background-color: yellow;\n position: relative;\n}\n\n.selectionOverlay {\n position: absolute;\n z-index: 15;\n opacity: 0.2;\n pointer-events: none;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n}\n\n#imageSelector {\n display: none;\n position: absolute;\n border-style: solid;\n border-color: black;\n}\n\n#imageSelector > div {\n width: 5px;\n height: 5px;\n display: block;\n position: absolute;\n border: 1px solid black;\n background-color: #ffffff;\n}\n\n#imageSelector > .topLeft {\n top: -4px;\n left: -4px;\n}\n\n#imageSelector > .topRight {\n top: -4px;\n right: -4px;\n}\n\n#imageSelector > .bottomRight {\n right: -4px;\n bottom: -4px;\n}\n\n#imageSelector > .bottomLeft {\n bottom: -4px;\n left: -4px;\n}\n\n#imageSelector > .topMiddle {\n top: -4px;\n left: 50%;\n margin-left: -2.5px; /* half of the width defined in #imageSelector > div */\n}\n\n#imageSelector > .rightMiddle {\n top: 50%;\n right: -4px;\n margin-top: -2.5px; /* half of the height defined in #imageSelector > div */\n}\n\n#imageSelector > .bottomMiddle {\n bottom: -4px;\n left: 50%;\n margin-left: -2.5px; /* half of the width defined in #imageSelector > div */\n}\n\n#imageSelector > .leftMiddle {\n top: 50%;\n left: -4px;\n margin-top: -2.5px; /* half of the height defined in #imageSelector > div */\n}\n"; +ops.Server=function(){};ops.Server.prototype.connect=function(k,h){};ops.Server.prototype.networkStatus=function(){};ops.Server.prototype.login=function(k,h,b,p){};ops.Server.prototype.joinSession=function(k,h,b,p){};ops.Server.prototype.leaveSession=function(k,h,b,p){};ops.Server.prototype.getGenesisUrl=function(k){}; +// Input 110 +var webodf_css='@namespace draw url(urn:oasis:names:tc:opendocument:xmlns:drawing:1.0);\n@namespace fo url(urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0);\n@namespace office url(urn:oasis:names:tc:opendocument:xmlns:office:1.0);\n@namespace presentation url(urn:oasis:names:tc:opendocument:xmlns:presentation:1.0);\n@namespace style url(urn:oasis:names:tc:opendocument:xmlns:style:1.0);\n@namespace svg url(urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0);\n@namespace table url(urn:oasis:names:tc:opendocument:xmlns:table:1.0);\n@namespace text url(urn:oasis:names:tc:opendocument:xmlns:text:1.0);\n@namespace webodfhelper url(urn:webodf:names:helper);\n@namespace cursor url(urn:webodf:names:cursor);\n@namespace editinfo url(urn:webodf:names:editinfo);\n@namespace annotation url(urn:webodf:names:annotation);\n@namespace dc url(http://purl.org/dc/elements/1.1/);\n@namespace svgns url(http://www.w3.org/2000/svg);\n\noffice|document > *, office|document-content > * {\n display: none;\n}\noffice|body, office|document {\n display: inline-block;\n position: relative;\n}\n\ntext|p, text|h {\n display: block;\n padding: 0;\n margin: 0;\n line-height: normal;\n position: relative;\n min-height: 1.3em; /* prevent empty paragraphs and headings from collapsing if they are empty */\n}\n*[webodfhelper|containsparagraphanchor] {\n position: relative;\n}\ntext|s {\n white-space: pre;\n}\ntext|tab {\n display: inline;\n white-space: pre;\n}\ntext|tracked-changes {\n /*Consumers that do not support change tracking, should ignore changes.*/\n display: none;\n}\noffice|binary-data {\n display: none;\n}\noffice|text {\n display: block;\n text-align: left;\n overflow: visible;\n word-wrap: break-word;\n}\n\noffice|text::selection {\n /** Let\'s not draw selection highlight that overflows into the office|text\n * node when selecting content across several paragraphs\n */\n background: transparent;\n}\n\noffice|document *::selection {\n background: transparent;\n}\noffice|document *::-moz-selection {\n background: transparent;\n}\n\noffice|text * draw|text-box {\n/** only for text documents */\n display: block;\n border: 1px solid #d3d3d3;\n}\ndraw|frame {\n /** make sure frames are above the main body. */\n z-index: 1;\n}\noffice|spreadsheet {\n display: block;\n border-collapse: collapse;\n empty-cells: show;\n font-family: sans-serif;\n font-size: 10pt;\n text-align: left;\n page-break-inside: avoid;\n overflow: hidden;\n}\noffice|presentation {\n display: inline-block;\n text-align: left;\n}\n#shadowContent {\n display: inline-block;\n text-align: left;\n}\ndraw|page {\n display: block;\n position: relative;\n overflow: hidden;\n}\npresentation|notes, presentation|footer-decl, presentation|date-time-decl {\n display: none;\n}\n@media print {\n draw|page {\n border: 1pt solid black;\n page-break-inside: avoid;\n }\n presentation|notes {\n /*TODO*/\n }\n}\noffice|spreadsheet text|p {\n border: 0px;\n padding: 1px;\n margin: 0px;\n}\noffice|spreadsheet table|table {\n margin: 3px;\n}\noffice|spreadsheet table|table:after {\n /* show sheet name the end of the sheet */\n /*content: attr(table|name);*/ /* gives parsing error in opera */\n}\noffice|spreadsheet table|table-row {\n counter-increment: row;\n}\noffice|spreadsheet table|table-row:before {\n width: 3em;\n background: #cccccc;\n border: 1px solid black;\n text-align: center;\n content: counter(row);\n display: table-cell;\n}\noffice|spreadsheet table|table-cell {\n border: 1px solid #cccccc;\n}\ntable|table {\n display: table;\n}\ndraw|frame table|table {\n width: 100%;\n height: 100%;\n background: white;\n}\ntable|table-header-rows {\n display: table-header-group;\n}\ntable|table-row {\n display: table-row;\n}\ntable|table-column {\n display: table-column;\n}\ntable|table-cell {\n width: 0.889in;\n display: table-cell;\n word-break: break-all; /* prevent long words from extending out the table cell */\n}\ndraw|frame {\n display: block;\n}\ndraw|image {\n display: block;\n width: 100%;\n height: 100%;\n top: 0px;\n left: 0px;\n background-repeat: no-repeat;\n background-size: 100% 100%;\n -moz-background-size: 100% 100%;\n}\n/* only show the first image in frame */\ndraw|frame > draw|image:nth-of-type(n+2) {\n display: none;\n}\ntext|list:before {\n display: none;\n content:"";\n}\ntext|list {\n counter-reset: list;\n}\ntext|list-item {\n display: block;\n}\ntext|number {\n display:none;\n}\n\ntext|a {\n color: blue;\n text-decoration: underline;\n cursor: pointer;\n}\noffice|text[webodfhelper|links="inactive"] text|a {\n cursor: text;\n}\ntext|note-citation {\n vertical-align: super;\n font-size: smaller;\n}\ntext|note-body {\n display: none;\n}\ntext|note:hover text|note-citation {\n background: #dddddd;\n}\ntext|note:hover text|note-body {\n display: block;\n left:1em;\n max-width: 80%;\n position: absolute;\n background: #ffffaa;\n}\nsvg|title, svg|desc {\n display: none;\n}\nvideo {\n width: 100%;\n height: 100%\n}\n\n/* below set up the cursor */\ncursor|cursor {\n display: inline;\n width: 0;\n height: 1em;\n /* making the position relative enables the avatar to use\n the cursor as reference for its absolute position */\n position: relative;\n z-index: 1;\n pointer-events: none;\n}\n\ncursor|cursor > .caret {\n /* IMPORTANT: when changing these values ensure DEFAULT_CARET_TOP and DEFAULT_CARET_HEIGHT\n in Caret.js remain in sync */\n display: inline;\n position: absolute;\n top: 5%; /* push down the caret; 0px can do the job, 5% looks better, 10% is a bit over */\n height: 1em;\n border-left: 2px solid black;\n outline: none;\n}\n\ncursor|cursor > .handle {\n padding: 3px;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n border: none !important;\n border-radius: 5px;\n opacity: 0.3;\n}\n\ncursor|cursor > .handle > img {\n border-radius: 5px;\n}\n\ncursor|cursor > .handle.active {\n opacity: 0.8;\n}\n\ncursor|cursor > .handle:after {\n content: \' \';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 43%;\n}\n\n/** Input Method Editor input pane & behaviours */\n/* not within a cursor */\n#eventTrap {\n height: auto;\n display: block;\n position: absolute;\n width: 1px;\n outline: none;\n opacity: 0;\n color: rgba(255, 255, 255, 0); /* hide the blinking caret by setting the colour to fully transparent */\n overflow: hidden; /* The overflow visibility is used to hide and show characters being entered */\n pointer-events: none;\n}\n\n/* within a cursor */\ncursor|cursor > #composer {\n text-decoration: underline;\n}\n\ncursor|cursor[cursor|composing="true"] > #composer {\n display: inline-block;\n height: auto;\n width: auto;\n}\n\ncursor|cursor[cursor|composing="true"] {\n display: inline-block;\n width: auto;\n height: inherit;\n}\n\ncursor|cursor[cursor|composing="true"] > .caret {\n /* during composition, the caret should be pushed along by the composition text, inline with the text */\n position: static;\n /* as it is now part of an inline-block, it will no longer need correct to top or height values to align properly */\n height: auto !important;\n top: auto !important;\n}\n\neditinfo|editinfo {\n /* Empty or invisible display:inline elements respond very badly to mouse selection.\n Inline blocks are much more reliably selectable in Chrome & friends */\n display: inline-block;\n}\n\n.editInfoMarker {\n position: absolute;\n width: 10px;\n height: 100%;\n left: -20px;\n opacity: 0.8;\n top: 0;\n border-radius: 5px;\n background-color: transparent;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n}\n.editInfoMarker:hover {\n box-shadow: 0px 0px 8px rgba(0, 0, 0, 1);\n}\n\n.editInfoHandle {\n position: absolute;\n background-color: black;\n padding: 5px;\n border-radius: 5px;\n opacity: 0.8;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n bottom: 100%;\n margin-bottom: 10px;\n z-index: 3;\n left: -25px;\n}\n.editInfoHandle:after {\n content: \' \';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 5px;\n}\n.editInfo {\n font-family: sans-serif;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n color: white;\n width: 100%;\n height: 12pt;\n}\n.editInfoColor {\n float: left;\n width: 10pt;\n height: 10pt;\n border: 1px solid white;\n}\n.editInfoAuthor {\n float: left;\n margin-left: 5pt;\n font-size: 10pt;\n text-align: left;\n height: 12pt;\n line-height: 12pt;\n}\n.editInfoTime {\n float: right;\n margin-left: 30pt;\n font-size: 8pt;\n font-style: italic;\n color: yellow;\n height: 12pt;\n line-height: 12pt;\n}\n\n.annotationWrapper {\n display: inline;\n position: relative;\n}\n\n.annotationRemoveButton:before {\n content: \'\u00d7\';\n color: white;\n padding: 5px;\n line-height: 1em;\n}\n\n.annotationRemoveButton {\n width: 20px;\n height: 20px;\n border-radius: 10px;\n background-color: black;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n position: absolute;\n top: -10px;\n left: -10px;\n z-index: 3;\n text-align: center;\n font-family: sans-serif;\n font-style: normal;\n font-weight: normal;\n text-decoration: none;\n font-size: 15px;\n}\n.annotationRemoveButton:hover {\n cursor: pointer;\n box-shadow: 0px 0px 5px rgba(0, 0, 0, 1);\n}\n\n.annotationNote {\n width: 4cm;\n position: absolute;\n display: inline;\n z-index: 10;\n}\n.annotationNote > office|annotation {\n display: block;\n text-align: left;\n}\n\n.annotationConnector {\n position: absolute;\n display: inline;\n z-index: 2;\n border-top: 1px dashed brown;\n}\n.annotationConnector.angular {\n -moz-transform-origin: left top;\n -webkit-transform-origin: left top;\n -ms-transform-origin: left top;\n transform-origin: left top;\n}\n.annotationConnector.horizontal {\n left: 0;\n}\n.annotationConnector.horizontal:before {\n content: \'\';\n display: inline;\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: brown transparent transparent transparent;\n top: -1px;\n left: -5px;\n}\n\noffice|annotation {\n width: 100%;\n height: 100%;\n display: none;\n background: rgb(198, 238, 184);\n background: -moz-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -webkit-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -o-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -ms-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: linear-gradient(180deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n box-shadow: 0 3px 4px -3px #ccc;\n}\n\noffice|annotation > dc|creator {\n display: block;\n font-size: 10pt;\n font-weight: normal;\n font-style: normal;\n font-family: sans-serif;\n color: white;\n background-color: brown;\n padding: 4px;\n}\noffice|annotation > dc|date {\n display: block;\n font-size: 10pt;\n font-weight: normal;\n font-style: normal;\n font-family: sans-serif;\n border: 4px solid transparent;\n color: black;\n}\noffice|annotation > text|list {\n display: block;\n padding: 5px;\n}\n\n/* This is very temporary CSS. This must go once\n * we start bundling webodf-default ODF styles for annotations.\n */\noffice|annotation text|p {\n font-size: 10pt;\n color: black;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n font-family: sans-serif;\n}\n\ndc|*::selection {\n background: transparent;\n}\ndc|*::-moz-selection {\n background: transparent;\n}\n\n#annotationsPane {\n background-color: #EAEAEA;\n width: 4cm;\n height: 100%;\n display: none;\n position: absolute;\n outline: 1px solid #ccc;\n}\n\n.annotationHighlight {\n background-color: yellow;\n position: relative;\n}\n\n.selectionOverlay {\n position: absolute;\n pointer-events: none;\n top: 0;\n left: 0;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 15;\n}\n.selectionOverlay > polygon {\n fill-opacity: 0.3;\n stroke-opacity: 0.8;\n stroke-width: 1;\n fill-rule: evenodd;\n}\n\n#imageSelector {\n display: none;\n position: absolute;\n border-style: solid;\n border-color: black;\n}\n\n#imageSelector > div {\n width: 5px;\n height: 5px;\n display: block;\n position: absolute;\n border: 1px solid black;\n background-color: #ffffff;\n}\n\n#imageSelector > .topLeft {\n top: -4px;\n left: -4px;\n}\n\n#imageSelector > .topRight {\n top: -4px;\n right: -4px;\n}\n\n#imageSelector > .bottomRight {\n right: -4px;\n bottom: -4px;\n}\n\n#imageSelector > .bottomLeft {\n bottom: -4px;\n left: -4px;\n}\n\n#imageSelector > .topMiddle {\n top: -4px;\n left: 50%;\n margin-left: -2.5px; /* half of the width defined in #imageSelector > div */\n}\n\n#imageSelector > .rightMiddle {\n top: 50%;\n right: -4px;\n margin-top: -2.5px; /* half of the height defined in #imageSelector > div */\n}\n\n#imageSelector > .bottomMiddle {\n bottom: -4px;\n left: 50%;\n margin-left: -2.5px; /* half of the width defined in #imageSelector > div */\n}\n\n#imageSelector > .leftMiddle {\n top: 50%;\n left: -4px;\n margin-top: -2.5px; /* half of the height defined in #imageSelector > div */\n}\n\ndiv.customScrollbars::-webkit-scrollbar\n{\n width: 8px;\n height: 8px;\n background-color: transparent;\n}\n\ndiv.customScrollbars::-webkit-scrollbar-track\n{\n background-color: transparent;\n}\n\ndiv.customScrollbars::-webkit-scrollbar-thumb\n{\n background-color: #444;\n border-radius: 4px;\n}\n'; |