diff --git a/js/editor/Editor.js b/js/editor/Editor.js index 2210bcc6..e63538fe 100644 --- a/js/editor/Editor.js +++ b/js/editor/Editor.js @@ -58,8 +58,9 @@ define("webodf/editor/Editor", [ * cursorAddedCallback:function(!string)=, * cursorRemovedCallback:function(!string)=, * registerCallbackForShutdown:function(!function())= }} args + * @param {!ops.Server=} server */ - function Editor(args) { + function Editor(args, server) { var self = this, // Private @@ -86,13 +87,6 @@ define("webodf/editor/Editor", [ return myResources[key]; } - runtime.currentDirectory = function () { - return "../../webodf/lib"; - }; - runtime.libraryPaths = function () { - return [ runtime.currentDirectory() ]; - }; - /** * prepare all gui elements and load the given document. * after loading is completed, the given callback is called. @@ -272,10 +266,12 @@ define("webodf/editor/Editor", [ self.loadSession = function (sessionId, editorReadyCallback) { initGuiAndDoc("/session/" + sessionId + "/genesis", function () { // use the nowjs op-router when connected - opRouter = opRouter || new ops.NowjsOperationRouter(sessionId, memberid); +// opRouter = opRouter || new ops.NowjsOperationRouter(sessionId, memberid, server); + opRouter = opRouter || new ops.PullBoxOperationRouter(sessionId, memberid, server); session.setOperationRouter(opRouter); - userModel = userModel || new ops.NowjsUserModel(); +// userModel = userModel || new ops.NowjsUserModel(server); + userModel = userModel || new ops.PullBoxUserModel(server); session.setUserModel(userModel); opRouter.requestReplay(function done() { diff --git a/js/editor/EditorSession.js b/js/editor/EditorSession.js index 4565e3a3..57da7fb8 100644 --- a/js/editor/EditorSession.js +++ b/js/editor/EditorSession.js @@ -44,8 +44,10 @@ define("webodf/editor/EditorSession", [ runtime.loadClass("ops.OdtDocument"); runtime.loadClass("ops.Session"); - runtime.loadClass("ops.NowjsOperationRouter"); - runtime.loadClass("ops.NowjsUserModel"); +// runtime.loadClass("ops.NowjsOperationRouter"); +// runtime.loadClass("ops.NowjsUserModel"); + runtime.loadClass("ops.PullBoxOperationRouter"); + runtime.loadClass("ops.PullBoxUserModel"); runtime.loadClass("odf.OdfCanvas"); runtime.loadClass("gui.CaretFactory"); runtime.loadClass("gui.Caret"); diff --git a/js/editor/PullBoxSessionList.js b/js/editor/PullBoxSessionList.js new file mode 100644 index 00000000..21795b57 --- /dev/null +++ b/js/editor/PullBoxSessionList.js @@ -0,0 +1,159 @@ +/** + * @license + * Copyright (C) 2013 KO GmbH + * + * @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. + * + * 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: http://gitorious.org/webodf/webodf/ + */ + +/*global ops, runtime */ + +function PullBoxSessionList(server) { + "use strict"; + + var cachedSessionData = {}, + subscribers = [], + /** HACK: allow to stop pulling, so that does not mess up the logs + * Remove before merging to master */ + pullingActive = true; + + function onSessionData(sessionData) { + var i, + isNew = ! cachedSessionData.hasOwnProperty(sessionData.id); + + // cache + cachedSessionData[sessionData.id] = sessionData; + runtime.log("get session data for:"+sessionData.title+", is new:"+isNew); + + for (i = 0; i < subscribers.length; i += 1) { + if (isNew) { + subscribers[i].onCreated(sessionData); + } else { + subscribers[i].onUpdated(sessionData); + } + } + } + + function onSessionRemoved(sessionId) { + var i; + + if (cachedSessionData.hasOwnProperty(sessionId)) { + delete cachedSessionData[sessionId]; + + for (i = 0; i < subscribers.length; i += 1) { + subscribers[i].onRemoved(sessionId); + } + } + } + + function pullSessionList() { + if (!pullingActive) { return; } + + server.call("session-list", function(responseData) { + var response = runtime.fromJson(responseData), + sessionList, i, + unupdatedSessions = {}; + + runtime.log("session-list reply: " + responseData); + + if (response.hasOwnProperty("session_list")) { + // collect known sessions + for (i in cachedSessionData) { + if (cachedSessionData.hasOwnProperty(i)) { + unupdatedSessions[i] = ""; // some dummy value, unused + } + } + + // add/update with all delivered sessions + sessionList = response.session_list; + for (i = 0; i < sessionList.length; i++) { + if (unupdatedSessions.hasOwnProperty(sessionList[i].id)) { + delete unupdatedSessions[sessionList[i].id]; + } + onSessionData(sessionList[i]); + } + + // remove unupdated sessions + for (i in unupdatedSessions) { + if (unupdatedSessions.hasOwnProperty(i)) { + onSessionRemoved(i); + } + } + + // next update in 5 secs + runtime.getWindow().setTimeout(pullSessionList, 5000); + } else { + runtime.log("Meh, sessionlist data broken: " + responseData); + } + }); + } + + this.getSessions = function (subscriber) { + var i, + sessionList = []; + + if (subscriber) { + subscribers.push(subscriber); + } + + for (i in cachedSessionData) { + if (cachedSessionData.hasOwnProperty(i)) { + sessionList.push(cachedSessionData[i]); + } + } + + return sessionList; + }; + + this.unsubscribe = function (subscriber) { + var i; + + for (i=0; i - + * @license + * Copyright (C) 2012-2013 KO GmbH + * * @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 @@ -34,86 +35,16 @@ /*global ops, runtime */ -function SessionList(net) { - "use strict"; +/** + * A model which provides information about sessions. + * @interface + */ +SessionList = function SessionList() {"use strict"; }; - var cachedSessionData = {}, - subscribers = []; - - function onSessionData(sessionData) { - var i, - isNew = ! cachedSessionData.hasOwnProperty(sessionData.id); - - // cache - cachedSessionData[sessionData.id] = sessionData; - runtime.log("get session data for:"+sessionData.title+", is new:"+isNew); - - for (i = 0; i < subscribers.length; i += 1) { - if (isNew) { - subscribers[i].onCreated(sessionData); - } else { - subscribers[i].onUpdated(sessionData); - } - } - } - - function onSessionRemoved(sessionId) { - var i; - - if (cachedSessionData.hasOwnProperty(sessionId)) { - delete cachedSessionData[sessionId]; - - for (i = 0; i < subscribers.length; i += 1) { - subscribers[i].onRemoved(sessionId); - } - } - } - - this.getSessions = function (subscriber) { - var i, - sessionList = []; - - if (subscriber) { - subscribers.push(subscriber); - } - - for (i in cachedSessionData) { - if (cachedSessionData.hasOwnProperty(i)) { - sessionList.push(cachedSessionData[i]); - } - } - - return sessionList; - }; - - this.unsubscribe = function (subscriber) { - var i; - - for (i=0; i 8000) { - // game over - runtime.log("connection to server timed out."); - callback("timeout"); - return; - } - accumulated_waiting_time += 100; - runtime.getWindow().setTimeout(later_cb, 100); - } else { - runtime.log("connection to collaboration server established."); - callback("ready"); - } + function connectNetwork(backend, callback) { + if (backend === "pullbox") { + runtime.loadClass("ops.PullBoxServer"); + server = new ops.PullBoxServer(); + } else if (backend === "nowjs") { + runtime.loadClass("ops.NowjsServer"); + server = new ops.NowjsServer(); + } else if (backend === "owncloud") { + runtime.loadClass("ops.PullBoxServer"); + server = new ops.PullBoxServer({url: "../../ajax/otpoll.php"}); + } else { + callback("unavailable"); } - later_cb(); + server.connect(8000, callback); + } + + /** + * try to auto-sense the server-backend. + * + * NOT IMPLEMENTED / MIGHT BE NICE TO HAVE... + * for now: try to connect to pullbox backend + * + * @param {!function(!string)} callback + * @return {undefined} + */ + function detectNetwork(callback) { + connectNetwork("pullbox", callback); } /** @@ -192,7 +204,7 @@ var webodfEditor = (function () { */ function createLocalEditor(docUrl, editorOptions, editorReadyCallback) { var pos; - running = true; + booting = true; editorOptions = editorOptions || {}; editorOptions.memberid = "localuser"; editorOptions.loadCallback = load; @@ -207,7 +219,6 @@ var webodfEditor = (function () { function (Editor) { editorInstance = new Editor(editorOptions); editorInstance.initAndLoadDocument(docUrl, function (editorSession) { - editorSession.sessionController.setUndoManager(new gui.TrivialUndoManager()); editorSession.startEditing(); editorReadyCallback(editorInstance); }); @@ -239,7 +250,7 @@ var webodfEditor = (function () { function (Editor) { // TODO: the networkSecurityToken needs to be retrieved via now.login // (but this is to be implemented later) - editorInstance = new Editor(editorOptions); + editorInstance = new Editor(editorOptions, server); // load the document and get called back when it's live editorInstance.loadSession(sessionId, function (editorSession) { @@ -262,10 +273,9 @@ var webodfEditor = (function () { * @returns {undefined} */ function startLoginProcess(callback) { - var userid, token, - net = runtime.getNetwork(); + var userid, token; - running = true; + booting = true; runtime.assert(editorInstance === null, "cannot boot with instanciated editor"); @@ -278,7 +288,8 @@ var webodfEditor = (function () { function showSessions() { var sessionListDiv = document.getElementById("sessionList"), - sessionList = new SessionList(net), +// sessionList = new NowjsSessionList(server), + sessionList = new PullBoxSessionList(server), sessionListView = new SessionListView(sessionList, sessionListDiv, enterSession); // hide login view @@ -301,7 +312,7 @@ var webodfEditor = (function () { } function onLoginSubmit() { - net.login(document.loginForm.login.value, document.loginForm.password.value, loginSuccess, loginFail); + server.login(document.loginForm.login.value, document.loginForm.password.value, loginSuccess, loginFail); // block the submit button, we already dealt with the input return false; @@ -334,7 +345,7 @@ var webodfEditor = (function () { */ function boot(args) { var editorOptions = {}, loginProcedure = startLoginProcess; - runtime.assert(!running, "editor creation already in progress"); + runtime.assert(!booting, "editor creation already in progress"); args = args || {}; @@ -391,7 +402,7 @@ var webodfEditor = (function () { if (args.collaborative === "auto") { runtime.log("detecting network..."); - waitForNetwork(function (state) { + detectNetwork(function (state) { if (state === "ready") { runtime.log("... network available."); handleNetworkedSituation(); @@ -400,11 +411,10 @@ var webodfEditor = (function () { handleNonNetworkedSituation(); } }); - } else if ((args.collaborative === "true") || - (args.collaborative === "1") || - (args.collaborative === "yes")) { - runtime.log("starting collaborative editor."); - waitForNetwork(function (state) { + } else if ((args.collaborative === "pullbox") || + (args.collaborative === "owncloud")) { + runtime.log("starting collaborative editor for ["+args.collaborative+"]."); + connectNetwork(args.collaborative, function (state) { if (state === "ready") { handleNetworkedSituation(); } @@ -415,16 +425,7 @@ var webodfEditor = (function () { } } - function shutdown() { - running = false; - editorInstance = null; - loadedFilename = null; - } - // exposed API - return { - boot: boot, - shutdown: shutdown - }; + return { boot: boot }; }()); diff --git a/js/editor/widgets/simpleStyles.js b/js/editor/widgets/simpleStyles.js index 2299af0c..d1755c6e 100644 --- a/js/editor/widgets/simpleStyles.js +++ b/js/editor/widgets/simpleStyles.js @@ -116,10 +116,12 @@ define("webodf/editor/widgets/simpleStyles", appliedStyles.forEach(function(appliedStyle) { var textProperties = appliedStyle['style:text-properties']; - fontWeight = fontWeight || textProperties['fo:font-weight'] === 'bold'; - fontStyle = fontStyle || textProperties['fo:font-style'] === 'italic'; - underline = underline || textProperties['style:text-underline-style'] === 'solid'; - strikethrough = strikethrough || textProperties['style:text-line-through-style'] === 'solid'; + if (textProperties) { + fontWeight = fontWeight || textProperties['fo:font-weight'] === 'bold'; + fontStyle = fontStyle || textProperties['fo:font-style'] === 'italic'; + underline = underline || textProperties['style:text-underline-style'] === 'solid'; + strikethrough = strikethrough || textProperties['style:text-line-through-style'] === 'solid'; + } }); // The 3rd parameter is false to avoid firing onChange when setting the value diff --git a/js/office.js b/js/office.js index 2287b6f1..46b0ed69 100644 --- a/js/office.js +++ b/js/office.js @@ -59,7 +59,7 @@ var officeMain = { webodfEditor.boot( { - collaborative: 0, + collaborative: "owncloud", docUrl: doclocation, callback: function() { // initialized. diff --git a/js/webodf-debug.js b/js/webodf-debug.js index 082e0655..12d5da0a 100644 --- a/js/webodf-debug.js +++ b/js/webodf-debug.js @@ -549,13 +549,6 @@ function BrowserRuntime(logoutput) { }; this.getWindow = function() { return window - }; - this.getNetwork = function() { - var now = this.getVariable("now"); - if(now === undefined) { - return{networkStatus:"unavailable"} - } - return now } } function NodeJSRuntime() { @@ -705,9 +698,6 @@ function NodeJSRuntime() { this.getWindow = function() { return null }; - this.getNetwork = function() { - return{networkStatus:"unavailable"} - }; function init() { var DOMParser = require("xmldom").DOMParser; parser = new DOMParser; @@ -892,9 +882,6 @@ function RhinoRuntime() { this.exit = quit; this.getWindow = function() { return null - }; - this.getNetwork = function() { - return{networkStatus:"unavailable"} } } var runtime = function() { @@ -3027,8 +3014,71 @@ core.LoopWatchDog = function LoopWatchDog(timeout, maxChecks) { } this.check = check }; +core.DomUtils = function DomUtils() { + function splitBoundaries(range) { + var modifiedNodes = [], splitStart; + if(range.endOffset !== 0 && range.endContainer.nodeType === Node.TEXT_NODE && range.endOffset !== range.endContainer.length) { + modifiedNodes.push(range.endContainer.splitText(range.endOffset)); + modifiedNodes.push(range.endContainer) + } + if(range.startOffset !== 0 && range.startContainer.nodeType === Node.TEXT_NODE && range.startOffset !== range.startContainer.length) { + splitStart = range.startContainer.splitText(range.startOffset); + modifiedNodes.push(range.startContainer); + modifiedNodes.push(splitStart); + range.setStart(splitStart, 0) + } + return modifiedNodes + } + this.splitBoundaries = splitBoundaries; + function mergeTextNodes(node1, node2) { + if(node1.nodeType === Node.TEXT_NODE) { + if(node1.length === 0) { + node1.parentNode.removeChild(node1) + }else { + if(node2.nodeType === Node.TEXT_NODE) { + node2.insertData(0, node1.data); + node1.parentNode.removeChild(node1); + return node2 + } + } + } + return node1 + } + function normalizeTextNodes(node) { + if(node && node.nextSibling) { + node = mergeTextNodes(node, node.nextSibling) + } + if(node && node.previousSibling) { + mergeTextNodes(node.previousSibling, node) + } + } + this.normalizeTextNodes = normalizeTextNodes; + function rangeContainsNode(limits, node) { + var range = node.ownerDocument.createRange(), nodeLength = node.nodeType === Node.TEXT_NODE ? node.length : node.childNodes.length, result; + range.setStart(limits.startContainer, limits.startOffset); + range.setEnd(limits.endContainer, limits.endOffset); + result = range.comparePoint(node, 0) === 0 && range.comparePoint(node, nodeLength) === 0; + range.detach(); + return result + } + this.rangeContainsNode = rangeContainsNode; + function mergeIntoParent(targetNode) { + var parent = targetNode.parentNode; + while(targetNode.firstChild) { + parent.insertBefore(targetNode.firstChild, targetNode) + } + parent.removeChild(targetNode); + return parent + } + this.mergeIntoParent = mergeIntoParent; + function getElementsByTagNameNS(node, namespace, tagName) { + return Array.prototype.slice.call(node.getElementsByTagNameNS(namespace, tagName)) + } + this.getElementsByTagNameNS = getElementsByTagNameNS +}; +runtime.loadClass("core.DomUtils"); core.Cursor = function Cursor(document, memberId) { - var self = this, cursorns = "urn:webodf:names:cursor", cursorNode = document.createElementNS(cursorns, "cursor"), anchorNode = document.createElementNS(cursorns, "anchor"), forwardSelection, recentlyModifiedNodes = [], selectedRange, isCollapsed; + var self = this, cursorns = "urn:webodf:names:cursor", cursorNode = document.createElementNS(cursorns, "cursor"), anchorNode = document.createElementNS(cursorns, "anchor"), forwardSelection, recentlyModifiedNodes = [], selectedRange, isCollapsed, domUtils = new core.DomUtils; function putIntoTextNode(node, container, offset) { runtime.assert(Boolean(container), "putCursorIntoTextNode: invalid container"); var parent = container.parentNode; @@ -3056,33 +3106,11 @@ core.Cursor = function Cursor(document, memberId) { } function removeNode(node) { if(node.parentNode) { - recentlyModifiedNodes.push({prev:node.previousSibling, next:node.nextSibling}); + recentlyModifiedNodes.push(node.previousSibling); + recentlyModifiedNodes.push(node.nextSibling); node.parentNode.removeChild(node) } } - function mergeTextNodes(node1, node2) { - if(node1.nodeType === Node.TEXT_NODE) { - if(node1.length === 0) { - node1.parentNode.removeChild(node1) - }else { - if(node2.nodeType === Node.TEXT_NODE) { - node2.insertData(0, node1.data); - node1.parentNode.removeChild(node1) - } - } - } - } - function mergeAdjacentTextNodes() { - recentlyModifiedNodes.forEach(function(nodePair) { - if(nodePair.prev && nodePair.prev.nextSibling) { - mergeTextNodes(nodePair.prev, nodePair.prev.nextSibling) - } - if(nodePair.next && nodePair.next.previousSibling) { - mergeTextNodes(nodePair.next.previousSibling, nodePair.next) - } - }); - recentlyModifiedNodes.length = 0 - } function putNode(node, container, offset) { var text, element; if(container.nodeType === Node.TEXT_NODE) { @@ -3094,7 +3122,8 @@ core.Cursor = function Cursor(document, memberId) { putIntoContainer(node, element, offset) } } - recentlyModifiedNodes.push({prev:node.previousSibling, next:node.nextSibling}) + recentlyModifiedNodes.push(node.previousSibling); + recentlyModifiedNodes.push(node.nextSibling) } function getStartNode() { return forwardSelection ? anchorNode : cursorNode @@ -3135,11 +3164,13 @@ core.Cursor = function Cursor(document, memberId) { putNode(getEndNode(), (range.endContainer), range.endOffset); putNode(getStartNode(), (range.startContainer), range.startOffset) } - mergeAdjacentTextNodes() + recentlyModifiedNodes.forEach(domUtils.normalizeTextNodes); + recentlyModifiedNodes.length = 0 }; this.remove = function() { removeNode(cursorNode); - mergeAdjacentTextNodes() + recentlyModifiedNodes.forEach(domUtils.normalizeTextNodes); + recentlyModifiedNodes.length = 0 }; function init() { cursorNode.setAttributeNS(cursorns, "memberId", memberId); @@ -3506,8 +3537,11 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa if(walker.nextSibling() !== null) { currentPos = 0 }else { - walker.parentNode(); - currentPos = 1 + if(walker.parentNode()) { + currentPos = 1 + }else { + return false + } } } } @@ -3525,8 +3559,7 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa var moved = true; if(currentPos === 0) { if(walker.previousSibling() === null) { - walker.parentNode(); - if(walker.currentNode === root) { + if(!walker.parentNode() || walker.currentNode === root) { walker.firstChild(); return false } @@ -6369,11 +6402,12 @@ odf.OdfUtils = function OdfUtils() { @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ +runtime.loadClass("core.DomUtils"); runtime.loadClass("core.LoopWatchDog"); runtime.loadClass("odf.Namespaces"); runtime.loadClass("odf.OdfUtils"); -odf.TextStyleApplicator = function TextStyleApplicator(formatting, automaticStyles) { - var nextTextNodes, odfUtils = new odf.OdfUtils, textns = odf.Namespaces.textns, stylens = odf.Namespaces.stylens, textProperties = "style:text-properties", webodfns = "urn:webodf:names:scope"; +odf.TextStyleApplicator = function TextStyleApplicator(newStylePrefix, formatting, automaticStyles) { + var nextTextNodes, odfUtils = new odf.OdfUtils, 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") { @@ -6407,7 +6441,7 @@ odf.TextStyleApplicator = function TextStyleApplicator(formatting, automaticStyl styleNode.setAttributeNS(stylens, "style:family", "text"); styleNode.setAttributeNS(webodfns, "scope", "document-content") } - formatting.updateStyle(styleNode, info, true); + formatting.updateStyle(styleNode, info, newStylePrefix); automaticStyles.appendChild(styleNode); return styleNode } @@ -6423,49 +6457,6 @@ odf.TextStyleApplicator = function TextStyleApplicator(formatting, automaticStyl container.setAttributeNS(textns, "text:style-name", name) } } - function containsNode(limits, node) { - var range = node.ownerDocument.createRange(), nodeLength = node.nodeType === Node.TEXT_NODE ? node.length : node.childNodes.length, result; - range.setStart(limits.startContainer, limits.startOffset); - range.setEnd(limits.endContainer, limits.endOffset); - result = range.comparePoint(node, 0) === 0 && range.comparePoint(node, nodeLength) === 0; - range.detach(); - return result - } - function splitBoundaries(range) { - var newNode; - if(range.endOffset !== 0 && range.endContainer.nodeType === Node.TEXT_NODE && range.endOffset !== range.endContainer.length) { - nextTextNodes.push(range.endContainer.splitText(range.endOffset)); - nextTextNodes.push(range.endContainer) - } - if(range.startOffset !== 0 && range.startContainer.nodeType === Node.TEXT_NODE && range.startOffset !== range.startContainer.length) { - newNode = range.startContainer.splitText(range.startOffset); - nextTextNodes.push(range.startContainer); - nextTextNodes.push(newNode); - range.setStart(newNode, 0) - } - } - function mergeTextNodes(node1, node2) { - if(node1.nodeType === Node.TEXT_NODE) { - if(node1.length === 0) { - node1.parentNode.removeChild(node1) - }else { - if(node2.nodeType === Node.TEXT_NODE) { - node2.insertData(0, node1.data); - node1.parentNode.removeChild(node1); - return node2 - } - } - } - return node1 - } - function cleanupTextNode(node) { - if(node.nextSibling) { - node = mergeTextNodes(node, node.nextSibling) - } - if(node.previousSibling) { - mergeTextNodes(node.previousSibling, node) - } - } function moveToNewSpan(startNode, limits) { var document = startNode.ownerDocument, originalContainer = startNode.parentNode, styledContainer, trailingContainer, moveTrailing, node = startNode, nextNode, loopGuard = new core.LoopWatchDog(1E3); if(odfUtils.isParagraph(originalContainer)) { @@ -6473,7 +6464,7 @@ odf.TextStyleApplicator = function TextStyleApplicator(formatting, automaticStyl originalContainer.insertBefore(styledContainer, startNode); moveTrailing = false }else { - if(startNode.previousSibling && !containsNode(limits, startNode.previousSibling)) { + if(startNode.previousSibling && !domUtils.rangeContainsNode(limits, startNode.previousSibling)) { styledContainer = originalContainer.cloneNode(false); originalContainer.parentNode.insertBefore(styledContainer, originalContainer.nextSibling); moveTrailing = true @@ -6482,7 +6473,7 @@ odf.TextStyleApplicator = function TextStyleApplicator(formatting, automaticStyl moveTrailing = true } } - while(node && (node === startNode || containsNode(limits, node))) { + while(node && (node === startNode || domUtils.rangeContainsNode(limits, node))) { loopGuard.check(); nextNode = node.nextSibling; if(node.parentNode !== styledContainer) { @@ -6504,12 +6495,11 @@ odf.TextStyleApplicator = function TextStyleApplicator(formatting, automaticStyl } this.applyStyle = function(range, info) { var textNodes, isStyled, container, styleCache, styleLookup, textPropsOnly = {}, limits; - runtime.assert(Boolean(info[textProperties]), "applyStyle without any text properties"); + runtime.assert(info && info[textProperties], "applyStyle without any text properties"); textPropsOnly[textProperties] = info[textProperties]; styleCache = new StyleManager(textPropsOnly); styleLookup = new StyleLookup(textPropsOnly); - nextTextNodes = []; - splitBoundaries(range); + nextTextNodes = domUtils.splitBoundaries(range); textNodes = odfUtils.getTextNodes(range, false); limits = {startContainer:range.startContainer, startOffset:range.startOffset, endContainer:range.endContainer, endOffset:range.endOffset}; textNodes.forEach(function(n) { @@ -6519,7 +6509,7 @@ odf.TextStyleApplicator = function TextStyleApplicator(formatting, automaticStyl styleCache.applyStyleToContainer(container) } }); - nextTextNodes.forEach(cleanupTextNode); + nextTextNodes.forEach(domUtils.normalizeTextNodes); nextTextNodes = null } }; @@ -7761,6 +7751,14 @@ runtime.loadClass("odf.OdfUtils"); runtime.loadClass("odf.TextStyleApplicator"); odf.Formatting = function Formatting() { var self = this, odfContainer, styleInfo = new odf.StyleInfo, svgns = odf.Namespaces.svgns, stylens = odf.Namespaces.stylens, textns = odf.Namespaces.textns, odfUtils = new odf.OdfUtils; + function hashString(value) { + var hash = 0, i, l; + for(i = 0, l = value.length;i < l;i += 1) { + hash = (hash << 5) - hash + value.charCodeAt(i); + hash |= 0 + } + return hash + } function mergeRecursive(destination, source) { Object.keys(source).forEach(function(p) { try { @@ -7965,8 +7963,8 @@ odf.Formatting = function Formatting() { styleChain = buildStyleChain(node); return styleChain ? calculateAppliedStyle(styleChain) : undefined }; - this.applyStyle = function(range, info) { - var textStyles = new odf.TextStyleApplicator(self, odfContainer.rootElement.automaticStyles); + this.applyStyle = function(memberId, range, info) { + var textStyles = new odf.TextStyleApplicator("auto" + hashString(memberId) + "_", self, odfContainer.rootElement.automaticStyles); textStyles.applyStyle(range, info) }; function getAllStyleNames() { @@ -7984,15 +7982,15 @@ odf.Formatting = function Formatting() { }); return styleNames } - this.updateStyle = function(styleNode, info, autoGenerateName) { + this.updateStyle = function(styleNode, info, newStylePrefix) { var name, existingNames, startIndex; mapObjOntoNode(styleNode, info); name = styleNode.getAttributeNS(stylens, "name"); - if(autoGenerateName || !name) { + if(newStylePrefix) { existingNames = getAllStyleNames(); - startIndex = Math.floor(Math.random() * 1E8); + startIndex = 0; do { - name = "auto" + startIndex; + name = newStylePrefix + startIndex; startIndex += 1 }while(existingNames.indexOf(name) !== -1); styleNode.setAttributeNS(stylens, "style:name", name) @@ -8033,6 +8031,7 @@ odf.Formatting = function Formatting() { @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ +runtime.loadClass("core.DomUtils"); runtime.loadClass("odf.OdfContainer"); runtime.loadClass("odf.Formatting"); runtime.loadClass("xmldom.XPath"); @@ -8190,7 +8189,7 @@ odf.OdfCanvas = function() { listenEvent(element, "keyup", checkSelection); listenEvent(element, "keydown", checkSelection) } - 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, xmlns = odf.Namespaces.xmlns, presentationns = odf.Namespaces.presentationns, window = runtime.getWindow(), xpath = new xmldom.XPath, utils = new odf.OdfUtils, shadowContent; + 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, xmlns = odf.Namespaces.xmlns, presentationns = odf.Namespaces.presentationns, window = runtime.getWindow(), xpath = new xmldom.XPath, utils = new odf.OdfUtils, domUtils = new core.DomUtils, shadowContent; function clear(element) { while(element.firstChild) { element.removeChild(element.firstChild) @@ -8391,12 +8390,12 @@ odf.OdfCanvas = function() { } } } - spaces = Array.prototype.slice.call(odffragment.getElementsByTagNameNS(textns, "s")); + spaces = domUtils.getElementsByTagNameNS(odffragment, textns, "s"); spaces.forEach(expandSpaceElement) } function expandTabElements(odffragment) { var tabs; - tabs = Array.prototype.slice.call(odffragment.getElementsByTagNameNS(textns, "tab")); + tabs = domUtils.getElementsByTagNameNS(odffragment, textns, "tab"); tabs.forEach(function(tab) { tab.textContent = "\t" }) @@ -8917,6 +8916,227 @@ odf.CommandLineTools = function CommandLineTools() { odfcanvas.load(inputfilepath) } }; +/* + + Copyright (C) 2013 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/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) { +}; +/* + + Copyright (C) 2013 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +ops.NowjsServer = function NowjsServer() { + var nowObject; + this.getNowObject = function() { + return nowObject + }; + this.connect = function(timeout, callback) { + var accumulatedWaitingTime = 0; + if(nowObject) { + return + } + nowObject = runtime.getVariable("now"); + if(nowObject === undefined) { + nowObject = {networkStatus:"unavailable"} + } + function laterCb() { + if(nowObject.networkStatus === "unavailable") { + runtime.log("connection to server unavailable."); + callback("unavailable"); + return + } + if(nowObject.networkStatus !== "ready") { + if(accumulatedWaitingTime > timeout) { + runtime.log("connection to server timed out."); + callback("timeout"); + return + } + accumulatedWaitingTime += 100; + runtime.getWindow().setTimeout(laterCb, 100) + }else { + runtime.log("connection to collaboration server established."); + callback("ready") + } + } + laterCb() + }; + this.networkStatus = function() { + return nowObject ? nowObject.networkStatus : "unavailable" + }; + this.login = function(login, password, successCb, failCb) { + if(!nowObject) { + failCb("Not connected to server") + }else { + nowObject.login(login, password, successCb, failCb) + } + } +}; +/* + + Copyright (C) 2013 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +runtime.loadClass("core.Base64"); +runtime.loadClass("core.ByteArrayWriter"); +ops.PullBoxServer = function PullBoxServer(args) { + var self = this, token, base64 = new core.Base64; + args = args || {}; + args.url = args.url || "/WSER"; + function call(message, cb) { + var xhr = new XMLHttpRequest, byteArrayWriter = new core.ByteArrayWriter("utf8"), data; + function handleResult() { + if(xhr.readyState === 4) { + if((xhr.status < 200 || xhr.status >= 300) && xhr.status === 0) { + runtime.log("Status " + String(xhr.status) + ": " + xhr.responseText || xhr.statusText) + } + cb(xhr.responseText) + } + } + runtime.log("Sending message to server: " + message); + byteArrayWriter.appendString(message); + data = byteArrayWriter.getByteArray(); + xhr.open("POST", args.url, true); + xhr.onreadystatechange = handleResult; + if(data.buffer && !xhr.sendAsBinary) { + data = data.buffer + }else { + data = runtime.byteArrayToString(data, "binary") + } + try { + if(xhr.sendAsBinary) { + xhr.sendAsBinary(data) + }else { + xhr.send(data) + } + }catch(e) { + runtime.log("Problem with calling server: " + e + " " + data); + cb(e.message) + } + } + this.call = call; + this.getBase64 = function() { + return base64 + }; + this.getToken = function() { + return token + }; + this.connect = function(timeout, callback) { + var accumulatedWaitingTime = 0; + callback("ready") + }; + this.networkStatus = function() { + return"ready" + }; + this.login = function(login, password, successCb, failCb) { + call("login:" + base64.toBase64(login) + ":" + base64.toBase64(password), function(responseData) { + var response = (runtime.fromJson(responseData)); + runtime.log("Login reply: " + responseData); + if(response.hasOwnProperty("token")) { + token = response.token; + runtime.log("Caching token: " + self.getToken()); + successCb(response) + }else { + failCb(responseData) + } + }) + } +}; /* Copyright (C) 2012-2013 KO GmbH @@ -8955,6 +9175,8 @@ ops.Operation = function Operation() { }; ops.Operation.prototype.init = function(data) { }; +ops.Operation.prototype.transform = function(otherOp, hasPriority) { +}; ops.Operation.prototype.execute = function(odtDocument) { }; ops.Operation.prototype.spec = function() { @@ -8994,11 +9216,14 @@ ops.Operation.prototype.spec = function() { @source: http://gitorious.org/webodf/webodf/ */ ops.OpAddCursor = function OpAddCursor() { - var memberid, timestamp; + var self = this, memberid, timestamp; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp }; + this.transform = function(otherOp, hasPriority) { + return[self] + }; this.execute = function(odtDocument) { var cursor = odtDocument.getCursor(memberid); if(cursor) { @@ -9049,14 +9274,17 @@ ops.OpAddCursor = function OpAddCursor() { */ runtime.loadClass("odf.OdfUtils"); ops.OpApplyStyle = function OpApplyStyle() { - var memberid, timestamp, position, length, info, odfUtils = new odf.OdfUtils, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; + var self = this, memberid, timestamp, position, length, info, odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; - position = data.position; - length = data.length; + position = parseInt(data.position, 10); + length = parseInt(data.length, 10); info = data.info }; + this.transform = function(otherOp, hasPriority) { + return null + }; function getRange(odtDocument) { var point1 = length >= 0 ? position : position + length, point2 = length >= 0 ? position + length : position, p1 = odtDocument.getIteratorAtPosition(point1), p2 = length ? odtDocument.getIteratorAtPosition(point2) : p1, range = odtDocument.getDOM().createRange(); range.setStart(p1.container(), p1.unfilteredDomOffset()); @@ -9068,9 +9296,10 @@ ops.OpApplyStyle = function OpApplyStyle() { return range.comparePoint(node, 0) <= 0 && range.comparePoint(node, nodeLength) >= 0 } function getImpactedParagraphs(range) { - var outerContainer = range.commonAncestorContainer, impactedParagraphs; - impactedParagraphs = Array.prototype.slice.call(outerContainer.getElementsByTagNameNS(textns, "p")); - impactedParagraphs = impactedParagraphs.concat(Array.prototype.slice.call(outerContainer.getElementsByTagNameNS(textns, "h"))); + var outerContainer = range.commonAncestorContainer, impactedParagraphs = []; + if(outerContainer.nodeType === Node.ELEMENT_NODE) { + impactedParagraphs = domUtils.getElementsByTagNameNS(outerContainer, textns, "p").concat(domUtils.getElementsByTagNameNS(outerContainer, textns, "h")) + } while(outerContainer && !odfUtils.isParagraph(outerContainer)) { outerContainer = outerContainer.parentNode } @@ -9083,7 +9312,7 @@ ops.OpApplyStyle = function OpApplyStyle() { } this.execute = function(odtDocument) { var range = getRange(odtDocument), impactedParagraphs = getImpactedParagraphs(range); - odtDocument.getFormatting().applyStyle(range, info); + odtDocument.getFormatting().applyStyle(memberid, range, info); range.detach(); odtDocument.getOdfCanvas().refreshCSS(); impactedParagraphs.forEach(function(n) { @@ -9130,11 +9359,18 @@ ops.OpApplyStyle = function OpApplyStyle() { @source: http://gitorious.org/webodf/webodf/ */ ops.OpRemoveCursor = function OpRemoveCursor() { - var memberid, timestamp; + var self = this, optype = "RemoveCursor", memberid, timestamp; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp }; + this.transform = function(otherOp, hasPriority) { + var otherOpspec = otherOp.spec(); + if(otherOpspec.optype === optype && otherOpspec.memberid === memberid) { + return[] + } + return[self] + }; this.execute = function(odtDocument) { if(!odtDocument.removeCursor(memberid)) { return false @@ -9142,7 +9378,7 @@ ops.OpRemoveCursor = function OpRemoveCursor() { return true }; this.spec = function() { - return{optype:"RemoveCursor", memberid:memberid, timestamp:timestamp} + return{optype:optype, memberid:memberid, timestamp:timestamp} } }; /* @@ -9180,12 +9416,12 @@ ops.OpRemoveCursor = function OpRemoveCursor() { @source: http://gitorious.org/webodf/webodf/ */ ops.OpMoveCursor = function OpMoveCursor() { - var memberid, timestamp, position, length; + var self = this, memberid, timestamp, position, length; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; - position = data.position; - length = data.length || 0 + position = parseInt(data.position, 10); + length = data.length !== undefined ? parseInt(data.length, 10) : 0 }; function countSteps(number, stepCounter, positionFilter) { if(number > 0) { @@ -9196,6 +9432,48 @@ ops.OpMoveCursor = function OpMoveCursor() { } return 0 } + this.merge = function(otherOpspec) { + if(otherOpspec.optype === "MoveCursor" && otherOpspec.memberid === memberid) { + position = otherOpspec.position; + length = otherOpspec.length; + timestamp = otherOpspec.timestamp; + return true + } + return false + }; + this.transform = function(otherOp, hasPriority) { + var otherOpspec = otherOp.spec(), otherOpType = otherOpspec.optype, result = [self]; + if(otherOpType === "RemoveText") { + if(otherOpspec.position + otherOpspec.length <= position) { + position -= otherOpspec.length + }else { + if(otherOpspec.position < position) { + position = otherOpspec.position + } + } + }else { + if(otherOpType === "SplitParagraph") { + if(otherOpspec.position < position) { + position += 1 + } + }else { + if(otherOpType === "InsertText") { + if(otherOpspec.position < position) { + position += otherOpspec.text.length + } + }else { + if(otherOpType === "RemoveCursor" && otherOpspec.memberid === memberid) { + result = [] + }else { + if(otherOpType === "InsertTable") { + result = null + } + } + } + } + } + return result + }; this.execute = function(odtDocument) { var cursor = odtDocument.getCursor(memberid), oldPosition = odtDocument.getCursorPosition(memberid), positionFilter = odtDocument.getPositionFilter(), number = position - oldPosition, stepsToSelectionStart, stepsToSelectionEnd, stepCounter; if(!cursor) { @@ -9216,18 +9494,57 @@ ops.OpMoveCursor = function OpMoveCursor() { } }; ops.OpInsertTable = function OpInsertTable() { - var memberid, timestamp, initialRows, initialColumns, position, tableName, tableStyleName, tableColumnStyleName, tableCellStyleMatrix, tablens = "urn:oasis:names:tc:opendocument:xmlns:table:1.0", textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; + var self = this, optype = "InsertTable", memberid, timestamp, initialRows, initialColumns, position, tableName, tableStyleName, tableColumnStyleName, tableCellStyleMatrix, tablens = "urn:oasis:names:tc:opendocument:xmlns:table:1.0", textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; - position = data.position; - initialRows = data.initialRows; - initialColumns = data.initialColumns; + position = parseInt(data.position, 10); + initialRows = parseInt(data.initialRows, 10); + initialColumns = parseInt(data.initialColumns, 10); tableName = data.tableName; tableStyleName = data.tableStyleName; tableColumnStyleName = data.tableColumnStyleName; tableCellStyleMatrix = data.tableCellStyleMatrix }; + this.transform = function(otherOp, hasPriority) { + var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, result = [self]; + if(otherOptype === optype) { + result = null + }else { + if(otherOptype === "SplitParagraph") { + if(otherOpspec.position < position) { + position += 1 + }else { + if(otherOpspec.position === position && !hasPriority) { + position += 1; + return null + } + } + }else { + if(otherOptype === "InsertText") { + if(otherOpspec.position < position) { + position += otherOpspec.text.length + }else { + if(otherOpspec.position === position && !hasPriority) { + position += otherOpspec.text.length; + return null + } + } + }else { + if(otherOptype === "RemoveText") { + if(otherOpspec.position + otherOpspec.length <= position) { + position -= otherOpspec.length + }else { + if(otherOpspec.position < position) { + position = otherOpspec.position + } + } + } + } + } + } + return result + }; function getCellStyleName(row, column) { var rowStyles; if(tableCellStyleMatrix.length === 1) { @@ -9306,7 +9623,7 @@ ops.OpInsertTable = function OpInsertTable() { return false }; this.spec = function() { - return{optype:"InsertTable", memberid:memberid, timestamp:timestamp, position:position, initialRows:initialRows, initialColumns:initialColumns, tableName:tableName, tableStyleName:tableStyleName, tableColumnStyleName:tableColumnStyleName, tableCellStyleMatrix:tableCellStyleMatrix} + return{optype:optype, memberid:memberid, timestamp:timestamp, position:position, initialRows:initialRows, initialColumns:initialColumns, tableName:tableName, tableStyleName:tableStyleName, tableColumnStyleName:tableColumnStyleName, tableCellStyleMatrix:tableCellStyleMatrix} } }; /* @@ -9344,13 +9661,60 @@ ops.OpInsertTable = function OpInsertTable() { @source: http://gitorious.org/webodf/webodf/ */ ops.OpInsertText = function OpInsertText() { - var memberid, timestamp, position, text; + var self = this, optype = "InsertText", memberid, timestamp, position, text; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; - position = data.position; + position = parseInt(data.position, 10); text = data.text }; + this.merge = function(otherOpspec) { + if(otherOpspec.optype === optype && otherOpspec.memberid === memberid && otherOpspec.position === position + text.length) { + text = text + otherOpspec.text; + timestamp = otherOpspec.timestamp; + return true + } + return false + }; + this.transform = function(otherOp, hasPriority) { + var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, result = [self]; + if(otherOptype === optype) { + if(otherOpspec.position < position) { + position += otherOpspec.text.length + }else { + if(otherOpspec.position === position && !hasPriority) { + position += otherOpspec.text.length; + return null + } + } + }else { + if(otherOptype === "SplitParagraph") { + if(otherOpspec.position < position) { + position += 1 + }else { + if(otherOpspec.position === position && !hasPriority) { + position += 1; + return null + } + } + }else { + if(otherOptype === "InsertTable") { + result = null + }else { + if(otherOptype === "RemoveText") { + if(otherOpspec.position + otherOpspec.length <= position) { + position -= otherOpspec.length + }else { + if(otherOpspec.position < position) { + position = otherOpspec.position + } + } + } + } + } + } + return result + }; function triggerLayoutInWebkit(odtDocument, textNode) { var parent = textNode.parentNode, next = textNode.nextSibling, impactedCursors = []; odtDocument.getCursors().forEach(function(cursor) { @@ -9401,7 +9765,7 @@ ops.OpInsertText = function OpInsertText() { return false }; this.spec = function() { - return{optype:"InsertText", memberid:memberid, timestamp:timestamp, position:position, text:text} + return{optype:optype, memberid:memberid, timestamp:timestamp, position:position, text:text} } }; /* @@ -9438,8 +9802,10 @@ ops.OpInsertText = function OpInsertText() { @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ +runtime.loadClass("odf.OdfUtils"); +runtime.loadClass("core.DomUtils"); ops.OpRemoveText = function OpRemoveText() { - var memberid, timestamp, position, length, text, odfUtils, editinfons = "urn:webodf:names:editinfo"; + var self = this, optype = "RemoveText", memberid, timestamp, position, length, text, odfUtils = new odf.OdfUtils, domUtils, editinfons = "urn:webodf:names:editinfo"; this.init = function(data) { runtime.assert(data.length >= 0, "OpRemoveText only supports positive lengths"); memberid = data.memberid; @@ -9447,28 +9813,52 @@ ops.OpRemoveText = function OpRemoveText() { position = parseInt(data.position, 10); length = parseInt(data.length, 10); text = data.text; - odfUtils = new odf.OdfUtils + odfUtils = new odf.OdfUtils; + domUtils = new core.DomUtils }; - function fixCursorPositions(odtDocument) { - var cursors, stepCounter, steps, filter, i; - cursors = odtDocument.getCursors(); - filter = odtDocument.getPositionFilter(); - for(i in cursors) { - if(cursors.hasOwnProperty(i)) { - stepCounter = cursors[i].getStepCounter(); - if(!stepCounter.isPositionWalkable(filter)) { - steps = -stepCounter.countBackwardSteps(1, filter); - if(steps === 0) { - steps = stepCounter.countForwardSteps(1, filter) + this.transform = function(otherOp, hasPriority) { + var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, end = position + length, otherOpspecEnd, same = otherOpspec.memberid === memberid, secondOp, secondOpspec, result = [self]; + if(otherOptype === optype) { + otherOpspecEnd = otherOpspec.position + otherOpspec.length; + if(otherOpspecEnd <= position) { + position -= otherOpspec.length + }else { + if(otherOpspec.position < end) { + if(position < otherOpspec.position) { + if(otherOpspecEnd < end) { + length = length - otherOpspec.length + }else { + length = otherOpspec.position - position + } + }else { + if(otherOpspecEnd < end) { + position = otherOpspec.position; + length = end - otherOpspecEnd + }else { + result = [] + } } - cursors[i].move(steps); - if(i === memberid) { - odtDocument.emit(ops.OdtDocument.signalCursorMoved, cursors[i]) + } + } + }else { + if(otherOptype === "InsertText") { + if(otherOpspec.position <= position) { + position += otherOpspec.text.length + } + }else { + if(otherOptype === "SplitParagraph") { + if(otherOpspec.position <= position) { + position += 1 + } + }else { + if(otherOptype === "InsertTable") { + result = null } } } } - } + return result + }; function isEmpty(node) { var childNode; if(!odfUtils.isParagraph(node) && (odfUtils.isGroupingElement(node) || odfUtils.isCharacterElement(node)) && node.textContent.length === 0) { @@ -9508,14 +9898,6 @@ ops.OpRemoveText = function OpRemoveText() { parent.parentNode.removeChild(parent) } } - function mergeIntoParent(node) { - var parent = node.parentNode; - while(node.firstChild) { - parent.insertBefore(node.firstChild, node) - } - parent.removeChild(node); - return parent - } function getPreprocessedNeighborhood(odtDocument, position, length) { odtDocument.upgradeWhitespacesAtPosition(position); var domPosition = odtDocument.getPositionInTextNode(position), initialTextNode = domPosition.textNode, initialTextOffset = domPosition.offset, initialParentElement = initialTextNode.parentNode, paragraphElement = odtDocument.getParagraphElement(initialParentElement), remainingLength = length, neighborhood, difference; @@ -9565,9 +9947,9 @@ ops.OpRemoveText = function OpRemoveText() { }else { if(currentLength <= remainingLength) { currentParent.removeChild(currentTextNode); - fixCursorPositions(odtDocument); + odtDocument.fixCursorPositions(memberid); while(isEmpty(currentParent)) { - currentParent = mergeIntoParent(currentParent) + currentParent = domUtils.mergeIntoParent(currentParent) } remainingLength -= currentLength; neighborhood.splice(0, 1) @@ -9578,14 +9960,14 @@ ops.OpRemoveText = function OpRemoveText() { } } } - fixCursorPositions(odtDocument); + odtDocument.fixCursorPositions(memberid); odtDocument.getOdfCanvas().refreshSize(); odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:paragraphElement, memberId:memberid, timeStamp:timestamp}); odtDocument.emit(ops.OdtDocument.signalCursorMoved, odtDocument.getCursor(memberid)); return true }; this.spec = function() { - return{optype:"RemoveText", memberid:memberid, timestamp:timestamp, position:position, length:length, text:text} + return{optype:optype, memberid:memberid, timestamp:timestamp, position:position, length:length, text:text} } }; /* @@ -9623,12 +10005,53 @@ ops.OpRemoveText = function OpRemoveText() { @source: http://gitorious.org/webodf/webodf/ */ ops.OpSplitParagraph = function OpSplitParagraph() { - var memberid, timestamp, position, odfUtils; + var self = this, optype = "SplitParagraph", memberid, timestamp, position, odfUtils = new odf.OdfUtils; + function isListItem(node) { + return node && node.localName === "list-item" && node.namespaceURI === "urn:oasis:names:tc:opendocument:xmlns:text:1.0" + } this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; - position = data.position; - odfUtils = new odf.OdfUtils + position = parseInt(data.position, 10) + }; + this.transform = function(otherOp, hasPriority) { + var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, result = [self]; + if(otherOptype === optype) { + if(otherOpspec.position < position) { + position += 1 + }else { + if(otherOpspec.position === position && !hasPriority) { + position += 1; + return null + } + } + }else { + if(otherOptype === "InsertText") { + if(otherOpspec.position < position) { + position += otherOpspec.text.length + }else { + if(otherOpspec.position === position && !hasPriority) { + position += otherOpspec.text.length; + return null + } + } + }else { + if(otherOptype === "InsertTable") { + result = null + }else { + if(otherOptype === "RemoveText") { + if(otherOpspec.position + otherOpspec.length <= position) { + position -= otherOpspec.length + }else { + if(otherOpspec.position < position) { + position = otherOpspec.position + } + } + } + } + } + } + return result }; this.execute = function(odtDocument) { var domPosition, paragraphNode, targetNode, node, splitNode, splitChildNode, keptChildNode; @@ -9679,13 +10102,14 @@ ops.OpSplitParagraph = function OpSplitParagraph() { if(odfUtils.isListItem(splitChildNode)) { splitChildNode = splitChildNode.childNodes[0] } + odtDocument.fixCursorPositions(memberid); odtDocument.getOdfCanvas().refreshSize(); odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:paragraphNode, memberId:memberid, timeStamp:timestamp}); odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:splitChildNode, memberId:memberid, timeStamp:timestamp}); return true }; this.spec = function() { - return{optype:"SplitParagraph", memberid:memberid, timestamp:timestamp, position:position} + return{optype:optype, memberid:memberid, timestamp:timestamp, position:position} } }; /* @@ -9723,13 +10147,22 @@ ops.OpSplitParagraph = function OpSplitParagraph() { @source: http://gitorious.org/webodf/webodf/ */ ops.OpSetParagraphStyle = function OpSetParagraphStyle() { - var memberid, timestamp, position, styleName, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; + var self = this, optype = "SetParagraphStyle", memberid, timestamp, position, styleName, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; position = data.position; styleName = data.styleName }; + this.transform = function(otherOp, hasPriority) { + var otherOpspec = otherOp.spec(), otherOpType = otherOpspec.optype; + if(otherOpType === "DeleteParagraphStyle") { + if(otherOpspec.styleName === styleName) { + styleName = "" + } + } + return[self] + }; this.execute = function(odtDocument) { var domPosition, paragraphNode; domPosition = odtDocument.getPositionInTextNode(position); @@ -9749,7 +10182,7 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() { return false }; this.spec = function() { - return{optype:"SetParagraphStyle", memberid:memberid, timestamp:timestamp, position:position, styleName:styleName} + return{optype:optype, memberid:memberid, timestamp:timestamp, position:position, styleName:styleName} } }; /* @@ -9787,9 +10220,10 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() { @source: http://gitorious.org/webodf/webodf/ */ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { - var memberid, timestamp, styleName, setProperties, removedProperties, fons = "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0", stylens = "urn:oasis:names:tc:opendocument:xmlns:style:1.0", svgns = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0", textPropertyMapping = [{propertyName:"fontSize", attrNs:fons, attrPrefix:"fo", attrLocaName:"font-size", unit:"pt"}, {propertyName:"fontName", attrNs:stylens, attrPrefix:"style", attrLocaName:"font-name"}, {propertyName:"color", attrNs:fons, - attrPrefix:"fo", attrLocaName:"color"}, {propertyName:"backgroundColor", attrNs:fons, attrPrefix:"fo", attrLocaName:"background-color"}, {propertyName:"fontWeight", attrNs:fons, attrPrefix:"fo", attrLocaName:"font-weight"}, {propertyName:"fontStyle", attrNs:fons, attrPrefix:"fo", attrLocaName:"font-style"}, {propertyName:"underline", attrNs:stylens, attrPrefix:"style", attrLocaName:"text-underline-style"}, {propertyName:"strikethrough", attrNs:stylens, attrPrefix:"style", attrLocaName:"text-line-through-style"}], - paragraphPropertyMapping = [{propertyName:"topMargin", attrNs:fons, attrPrefix:"fo", attrLocaName:"margin-top", unit:"mm"}, {propertyName:"bottomMargin", attrNs:fons, attrPrefix:"fo", attrLocaName:"margin-bottom", unit:"mm"}, {propertyName:"leftMargin", attrNs:fons, attrPrefix:"fo", attrLocaName:"margin-left", unit:"mm"}, {propertyName:"rightMargin", attrNs:fons, attrPrefix:"fo", attrLocaName:"margin-right", unit:"mm"}, {propertyName:"textAlign", attrNs:fons, attrPrefix:"fo", attrLocaName:"text-align"}]; + var self = this, optype = "UpdateParagraphStyle", memberid, timestamp, styleName, setProperties, removedProperties, fons = "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0", stylens = "urn:oasis:names:tc:opendocument:xmlns:style:1.0", svgns = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0", textPropertyMapping = [{propertyName:"fontSize", attrNs:fons, attrPrefix:"fo", attrLocaName:"font-size", unit:"pt"}, {propertyName:"fontName", attrNs:stylens, attrPrefix:"style", attrLocaName:"font-name"}, + {propertyName:"color", attrNs:fons, attrPrefix:"fo", attrLocaName:"color"}, {propertyName:"backgroundColor", attrNs:fons, attrPrefix:"fo", attrLocaName:"background-color"}, {propertyName:"fontWeight", attrNs:fons, attrPrefix:"fo", attrLocaName:"font-weight"}, {propertyName:"fontStyle", attrNs:fons, attrPrefix:"fo", attrLocaName:"font-style"}, {propertyName:"underline", attrNs:stylens, attrPrefix:"style", attrLocaName:"text-underline-style"}, {propertyName:"strikethrough", attrNs:stylens, attrPrefix:"style", + attrLocaName:"text-line-through-style"}], paragraphPropertyMapping = [{propertyName:"topMargin", attrNs:fons, attrPrefix:"fo", attrLocaName:"margin-top", unit:"mm"}, {propertyName:"bottomMargin", attrNs:fons, attrPrefix:"fo", attrLocaName:"margin-bottom", unit:"mm"}, {propertyName:"leftMargin", attrNs:fons, attrPrefix:"fo", attrLocaName:"margin-left", unit:"mm"}, {propertyName:"rightMargin", attrNs:fons, attrPrefix:"fo", attrLocaName:"margin-right", unit:"mm"}, {propertyName:"textAlign", attrNs:fons, + attrPrefix:"fo", attrLocaName:"text-align"}]; function setPropertiesInStyleNode(node, properties, propertyMapping) { var i, m, value; for(i = 0;i < propertyMapping.length;i += 1) { @@ -9809,6 +10243,35 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { } } } + function dropShadowedProperties(properties, removedPropertyNames, shadowingProperties, shadowingRemovedPropertyNames, propertyMapping) { + var i, propertyName, p; + if(!properties && !removedPropertyNames || !shadowingProperties && !shadowingRemovedPropertyNames) { + return + } + for(i = 0;i < propertyMapping.length;i += 1) { + propertyName = propertyMapping[i].propertyName; + if(shadowingProperties && shadowingProperties[propertyName] !== undefined || shadowingRemovedPropertyNames && shadowingRemovedPropertyNames.indexOf(propertyName) !== -1) { + if(properties) { + delete properties[propertyName] + } + if(removedPropertyNames) { + p = removedPropertyNames.indexOf(propertyName); + if(p !== -1) { + removedPropertyNames.splice(p, 1) + } + } + } + } + } + function hasProperties(properties) { + var i; + for(i in properties) { + if(properties.hasOwnProperty(i)) { + return true + } + } + return false + } this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; @@ -9816,6 +10279,27 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { setProperties = data.setProperties; removedProperties = data.removedProperties }; + this.transform = function(otherOp, hasPriority) { + var otherOpspec = otherOp.spec(), otherOpType = otherOpspec.optype; + if(otherOpType === optype) { + if(otherOpspec.styleName === styleName) { + if(!hasPriority) { + dropShadowedProperties(setProperties ? setProperties.paragraphProperties : null, removedProperties ? removedProperties.paragraphPropertyNames : null, otherOpspec.setProperties ? otherOpspec.setProperties.paragraphProperties : null, otherOpspec.removedProperties ? otherOpspec.removedProperties.paragraphPropertyNames : null, paragraphPropertyMapping); + dropShadowedProperties(setProperties ? setProperties.textProperties : null, removedProperties ? removedProperties.textPropertyNames : null, otherOpspec.setProperties ? otherOpspec.setProperties.textProperties : null, otherOpspec.removedProperties ? otherOpspec.removedProperties.textPropertyNames : null, textPropertyMapping); + if(!(setProperties && (hasProperties(setProperties.textProperties) || hasProperties(setProperties.paragraphProperties))) && !(removedProperties && (removedProperties.textPropertyNames.length > 0 || removedProperties.paragraphPropertyNames.length > 0))) { + return[] + } + } + } + }else { + if(otherOpType === "DeleteParagraphStyle") { + if(otherOpspec.styleName === styleName) { + return[] + } + } + } + return[self] + }; this.execute = function(odtDocument) { var styleNode, paragraphPropertiesNode, textPropertiesNode, fontFaceNode; styleNode = odtDocument.getParagraphStyleElement(styleName); @@ -9865,7 +10349,7 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { return false }; this.spec = function() { - return{optype:"UpdateParagraphStyle", memberid:memberid, timestamp:timestamp, styleName:styleName, setProperties:setProperties, removedProperties:removedProperties} + return{optype:optype, memberid:memberid, timestamp:timestamp, styleName:styleName, setProperties:setProperties, removedProperties:removedProperties} } }; /* @@ -9903,7 +10387,7 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { @source: http://gitorious.org/webodf/webodf/ */ ops.OpCloneParagraphStyle = function OpCloneParagraphStyle() { - var memberid, timestamp, styleName, newStyleName, newStyleDisplayName, stylens = "urn:oasis:names:tc:opendocument:xmlns:style:1.0"; + var self = this, memberid, timestamp, styleName, newStyleName, newStyleDisplayName, stylens = "urn:oasis:names:tc:opendocument:xmlns:style:1.0"; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; @@ -9911,6 +10395,13 @@ ops.OpCloneParagraphStyle = function OpCloneParagraphStyle() { newStyleName = data.newStyleName; newStyleDisplayName = data.newStyleDisplayName }; + this.transform = function(otherOp, hasPriority) { + var otherSpec = otherOp.spec(); + if((otherSpec.optype === "UpdateParagraphStyle" || otherSpec.optype === "DeleteParagraphStyle") && otherSpec.styleName === styleName) { + return null + } + return[self] + }; this.execute = function(odtDocument) { var styleNode = odtDocument.getParagraphStyleElement(styleName), newStyleNode; if(!styleNode) { @@ -9967,12 +10458,30 @@ ops.OpCloneParagraphStyle = function OpCloneParagraphStyle() { @source: http://gitorious.org/webodf/webodf/ */ ops.OpDeleteParagraphStyle = function OpDeleteParagraphStyle() { - var memberid, timestamp, styleName; + var self = this, optype = "DeleteParagraphStyle", memberid, timestamp, styleName; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; styleName = data.styleName }; + this.transform = function(otherOp, hasPriority) { + var otherOpspec = otherOp.spec(), otherOpType = otherOpspec.optype, removeStyleOp; + if(otherOpType === optype) { + if(otherOpspec.styleName === styleName) { + return[] + } + }else { + if(otherOpType === "SetParagraphStyle") { + if(otherOpspec.styleName === styleName) { + otherOpspec.styleName = ""; + removeStyleOp = new ops.OpSetParagraphStyle; + removeStyleOp.init(otherOpspec); + return[removeStyleOp, self] + } + } + } + return[self] + }; this.execute = function(odtDocument) { var styleNode = odtDocument.getParagraphStyleElement(styleName); if(!styleNode) { @@ -9984,7 +10493,7 @@ ops.OpDeleteParagraphStyle = function OpDeleteParagraphStyle() { return true }; this.spec = function() { - return{optype:"DeleteParagraphStyle", memberid:memberid, timestamp:timestamp, styleName:styleName} + return{optype:optype, memberid:memberid, timestamp:timestamp, styleName:styleName} } }; /* @@ -10034,61 +10543,28 @@ runtime.loadClass("ops.OpUpdateParagraphStyle"); runtime.loadClass("ops.OpCloneParagraphStyle"); runtime.loadClass("ops.OpDeleteParagraphStyle"); ops.OperationFactory = function OperationFactory() { - var self = this; + var specs; + this.register = function(specName, specConstructor) { + specs[specName] = specConstructor + }; this.create = function(spec) { - var op = null; - if(spec.optype === "AddCursor") { - op = new ops.OpAddCursor - }else { - if(spec.optype === "ApplyStyle") { - op = new ops.OpApplyStyle - }else { - if(spec.optype === "InsertTable") { - op = new ops.OpInsertTable - }else { - if(spec.optype === "InsertText") { - op = new ops.OpInsertText - }else { - if(spec.optype === "RemoveText") { - op = new ops.OpRemoveText - }else { - if(spec.optype === "SplitParagraph") { - op = new ops.OpSplitParagraph - }else { - if(spec.optype === "SetParagraphStyle") { - op = new ops.OpSetParagraphStyle - }else { - if(spec.optype === "UpdateParagraphStyle") { - op = new ops.OpUpdateParagraphStyle - }else { - if(spec.optype === "CloneParagraphStyle") { - op = new ops.OpCloneParagraphStyle - }else { - if(spec.optype === "DeleteParagraphStyle") { - op = new ops.OpDeleteParagraphStyle - }else { - if(spec.optype === "MoveCursor") { - op = new ops.OpMoveCursor - }else { - if(spec.optype === "RemoveCursor") { - op = new ops.OpRemoveCursor - } - } - } - } - } - } - } - } - } - } - } - } - if(op) { + var op = null, specConstructor = specs[spec.optype]; + if(specConstructor) { + op = specConstructor(spec); op.init(spec) } return op + }; + function constructor(OperationType) { + return function() { + return new OperationType + } } + function init() { + specs = {AddCursor:constructor(ops.OpAddCursor), ApplyStyle:constructor(ops.OpApplyStyle), InsertTable:constructor(ops.OpInsertTable), InsertText:constructor(ops.OpInsertText), RemoveText:constructor(ops.OpRemoveText), SplitParagraph:constructor(ops.OpSplitParagraph), SetParagraphStyle:constructor(ops.OpSetParagraphStyle), UpdateParagraphStyle:constructor(ops.OpUpdateParagraphStyle), CloneParagraphStyle:constructor(ops.OpCloneParagraphStyle), DeleteParagraphStyle:constructor(ops.OpDeleteParagraphStyle), + MoveCursor:constructor(ops.OpMoveCursor), RemoveCursor:constructor(ops.OpRemoveCursor)} + } + init() }; runtime.loadClass("core.Cursor"); runtime.loadClass("core.PositionIterator"); @@ -10397,6 +10873,120 @@ gui.SelectionMover.createPositionIterator = function(rootNode) { (function() { return gui.SelectionMover })(); +/* + + Copyright (C) 2013 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +runtime.loadClass("ops.OpAddCursor"); +runtime.loadClass("ops.OpRemoveCursor"); +runtime.loadClass("ops.OpMoveCursor"); +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.OpCloneParagraphStyle"); +runtime.loadClass("ops.OpDeleteParagraphStyle"); +ops.OperationTransformer = function OperationTransformer() { + var self = this, operationFactory; + function transformOpVsOp(opA, opB) { + var oldOpB, opATransformResult, opBTransformResult; + runtime.log("Crosstransforming:"); + runtime.log(runtime.toJson(opA.spec())); + runtime.log(runtime.toJson(opB.spec())); + oldOpB = operationFactory.create(opB.spec()); + opBTransformResult = opB.transform(opA, true); + opATransformResult = opA.transform(oldOpB, false); + if(!opATransformResult || !opBTransformResult) { + return null + } + return{opsA:opATransformResult, opsB:opBTransformResult} + } + function transformOpListVsOp(opsA, opB) { + var b, transformResult, transformListResult, transformedOpsA = [], transformedOpsB = []; + while(opsA.length > 0 && opB) { + transformResult = transformOpVsOp(opsA.shift(), (opB)); + if(!transformResult) { + return null + } + transformedOpsA = transformedOpsA.concat(transformResult.opsA); + if(transformResult.opsB.length === 0) { + transformedOpsA = transformedOpsA.concat(opsA); + opB = null; + break + } + if(transformResult.opsB.length > 1) { + for(b = 0;b < transformResult.opsB.length - 1;b += 1) { + transformListResult = transformOpListVsOp(opsA, transformResult.opsB[b]); + if(!transformListResult) { + return null + } + transformedOpsB = transformedOpsB.concat(transformListResult.opsB); + opsA = transformListResult.opsA + } + } + opB = transformResult.opsB.pop() + } + if(opB) { + transformedOpsB.push(opB) + } + return{opsA:transformedOpsA, opsB:transformedOpsB} + } + this.setOperationFactory = function(f) { + operationFactory = f + }; + this.transform = function(opspecsA, opspecsB) { + var c, s, opsA = [], clientOp, transformedClientOps, serverOp, oldServerOp, transformResult, transformedOpsB = []; + for(c = 0;c < opspecsA.length;c += 1) { + clientOp = operationFactory.create(opspecsA[c]); + if(!clientOp) { + return null + } + opsA.push(clientOp) + } + for(s = 0;s < opspecsB.length;s += 1) { + serverOp = operationFactory.create(opspecsB[s]); + transformResult = transformOpListVsOp(opsA, serverOp); + if(!transformResult) { + return null + } + opsA = transformResult.opsA; + transformedOpsB = transformedOpsB.concat(transformResult.opsB) + } + return{opsA:opsA, opsB:transformedOpsB} + } +}; runtime.loadClass("core.Cursor"); runtime.loadClass("gui.SelectionMover"); ops.OdtCursor = function OdtCursor(memberId, odtDocument) { @@ -10770,6 +11360,103 @@ gui.ClickHandler.signalTripleClick = "tripleClick"; (function() { return gui.ClickHandler })(); +/* + + Copyright (C) 2012-2013 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/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 = modifiers.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() + }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, Shift:8, MetaShift:9, CtrlShift:10, AltShift:12}; +gui.KeyboardHandler.KeyCode = {Backspace:8, Enter:13, End:35, Home:36, Left:37, Up:38, Right:39, Down:40, Delete:46, Z:90}; +(function() { + return gui.KeyboardHandler +})(); gui.Clipboard = function Clipboard() { this.setDataFromRange = function(e, range) { var result = true, setDataResult, clipboard = e.clipboardData, window = runtime.getWindow(), serializer, dom, newNode, fragmentContainer; @@ -10805,10 +11492,11 @@ runtime.loadClass("ops.OpRemoveText"); runtime.loadClass("ops.OpSplitParagraph"); runtime.loadClass("ops.OpSetParagraphStyle"); runtime.loadClass("gui.ClickHandler"); +runtime.loadClass("gui.KeyboardHandler"); runtime.loadClass("gui.Clipboard"); gui.SessionController = function() { gui.SessionController = function SessionController(session, inputMemberId) { - var self = this, odfUtils = new odf.OdfUtils, isMacOS = runtime.getWindow().navigator.appVersion.toLowerCase().indexOf("mac") !== -1, clipboard = new gui.Clipboard, clickHandler = new gui.ClickHandler, undoManager; + var self = this, odtDocument = session.getOdtDocument(), odfUtils = new odf.OdfUtils, clipboard = new gui.Clipboard, clickHandler = new gui.ClickHandler, keyDownHandler = new gui.KeyboardHandler, keyPressHandler = new gui.KeyboardHandler, undoManager; function listenEvent(eventTarget, eventType, eventHandler, includeDirect) { var onVariant = "on" + eventType, bound = false; if(eventTarget.attachEvent) { @@ -10844,8 +11532,13 @@ gui.SessionController = function() { function dummyHandler(e) { cancelEvent(e) } + function createOpMoveCursor(position, length) { + var op = new ops.OpMoveCursor; + op.init({memberid:inputMemberId, position:position, length:length || 0}); + return op + } function countStepsToNode(targetNode, targetOffset) { - var odtDocument = session.getOdtDocument(), iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), canvasElement = odtDocument.getOdfCanvas().getElement(), node; + var iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), canvasElement = odtDocument.getOdfCanvas().getElement(), node; node = targetNode; if(!node) { return @@ -10866,18 +11559,17 @@ gui.SessionController = function() { iterator.setUnfilteredPosition(targetNode, targetOffset); return odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()) } - function moveCursor() { - var selection = runtime.getWindow().getSelection(), odtDocument = session.getOdtDocument(), oldPosition = odtDocument.getCursorPosition(inputMemberId), stepsToAnchor, stepsToFocus, op; + function select() { + var selection = runtime.getWindow().getSelection(), oldPosition = odtDocument.getCursorPosition(inputMemberId), stepsToAnchor, stepsToFocus, op; stepsToAnchor = countStepsToNode(selection.anchorNode, selection.anchorOffset); stepsToFocus = countStepsToNode(selection.focusNode, selection.focusOffset); if(stepsToFocus !== 0 || stepsToAnchor !== 0) { - op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:oldPosition + stepsToAnchor, length:stepsToFocus - stepsToAnchor}); + op = createOpMoveCursor(oldPosition + stepsToAnchor, stepsToFocus - stepsToAnchor); session.enqueue(op) } } function selectWord() { - var odtDocument = session.getOdtDocument(), iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), cursorNode = odtDocument.getCursor(inputMemberId).getNode(), oldPosition = odtDocument.getCursorPosition(inputMemberId), alphaNumeric = /[A-Za-z0-9]/, stepsToStart = 0, stepsToEnd = 0, currentNode, i, c, op; + var iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), cursorNode = odtDocument.getCursor(inputMemberId).getNode(), oldPosition = odtDocument.getCursorPosition(inputMemberId), alphaNumeric = /[A-Za-z0-9]/, stepsToStart = 0, stepsToEnd = 0, currentNode, i, c, op; iterator.setUnfilteredPosition(cursorNode, 0); if(iterator.previousPosition()) { currentNode = iterator.getCurrentNode(); @@ -10907,59 +11599,95 @@ gui.SessionController = function() { } } if(stepsToStart !== 0 || stepsToEnd !== 0) { - op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:oldPosition + stepsToStart, length:Math.abs(stepsToStart) + Math.abs(stepsToEnd)}); + op = createOpMoveCursor(oldPosition + stepsToStart, Math.abs(stepsToStart) + Math.abs(stepsToEnd)); session.enqueue(op) } } function selectParagraph() { - var odtDocument = session.getOdtDocument(), iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), oldPosition = odtDocument.getCursorPosition(inputMemberId), stepsToStart, stepsToEnd, op; + var iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), oldPosition = odtDocument.getCursorPosition(inputMemberId), stepsToStart, stepsToEnd, op; stepsToStart = odtDocument.getDistanceFromCursor(inputMemberId, paragraphNode, 0); iterator.moveToEndOfNode(paragraphNode); stepsToEnd = odtDocument.getDistanceFromCursor(inputMemberId, paragraphNode, iterator.unfilteredDomOffset()); if(stepsToStart !== 0 || stepsToEnd !== 0) { - op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:oldPosition + stepsToStart, length:Math.abs(stepsToStart) + Math.abs(stepsToEnd)}); + op = createOpMoveCursor(oldPosition + stepsToStart, Math.abs(stepsToStart) + Math.abs(stepsToEnd)); session.enqueue(op) } } - function createOpMoveCursor(steps) { - var op = new ops.OpMoveCursor, oldPosition = session.getOdtDocument().getCursorPosition(inputMemberId); - op.init({memberid:inputMemberId, position:oldPosition + steps}); - return op - } - function extendSelection(increment) { - var op = new ops.OpMoveCursor, selection = session.getOdtDocument().getCursorSelection(inputMemberId); - op.init({memberid:inputMemberId, position:selection.position, length:selection.length + increment}); - return op - } - function extendSelectionByLines(lines) { - var odtDocument = session.getOdtDocument(), paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), selection, steps, op = null; - runtime.assert(Boolean(paragraphNode), "SessionController: Cursor outside paragraph"); - steps = odtDocument.getCursor(inputMemberId).getStepCounter().countLinesSteps(lines, odtDocument.getPositionFilter()); - if(steps !== 0) { - selection = session.getOdtDocument().getCursorSelection(inputMemberId); - op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:selection.position, length:selection.length + steps}) + function sessionEnqueue(op) { + if(op) { + session.enqueue(op) } - return op } - function createOpMoveCursorByLines(lines) { - var odtDocument = session.getOdtDocument(), paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), oldPosition, steps, op = null; - runtime.assert(Boolean(paragraphNode), "SessionController: Cursor outside paragraph"); - steps = odtDocument.getCursor(inputMemberId).getStepCounter().countLinesSteps(lines, odtDocument.getPositionFilter()); - if(steps !== 0) { - oldPosition = odtDocument.getCursorPosition(inputMemberId); - op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:oldPosition + steps}) + function createOpMoveCursorByAdjustment(posAdjust, lenAdjust) { + var selection = odtDocument.getCursorSelection(inputMemberId), newPos, newLen; + if(posAdjust === 0 && lenAdjust === 0) { + return null } - return op + newPos = selection.position + posAdjust; + newLen = lenAdjust !== 0 ? selection.length + lenAdjust : 0; + return createOpMoveCursor(newPos, newLen) + } + function moveCursorToLeft() { + sessionEnqueue(createOpMoveCursorByAdjustment(-1, 0)); + return true + } + function moveCursorToRight() { + sessionEnqueue(createOpMoveCursorByAdjustment(1, 0)); + return true + } + function extendSelectionToLeft() { + sessionEnqueue(createOpMoveCursorByAdjustment(0, -1)); + return true + } + function extendSelectionToRight() { + sessionEnqueue(createOpMoveCursorByAdjustment(0, 1)); + return true + } + function createOpMoveCursorDirection(direction, extend) { + var paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), steps, op; + runtime.assert(Boolean(paragraphNode), "SessionController: Cursor outside paragraph"); + steps = odtDocument.getCursor(inputMemberId).getStepCounter().countLinesSteps(direction, odtDocument.getPositionFilter()); + return extend ? createOpMoveCursorByAdjustment(0, steps) : createOpMoveCursorByAdjustment(steps, 0) + } + function moveCursorUp() { + sessionEnqueue(createOpMoveCursorDirection(-1, false)); + return true + } + function moveCursorDown() { + sessionEnqueue(createOpMoveCursorDirection(1, false)); + return true + } + function extendSelectionUp() { + sessionEnqueue(createOpMoveCursorDirection(-1, true)); + return true + } + function extendSelectionDown() { + sessionEnqueue(createOpMoveCursorDirection(1, true)); + return true + } + function createOpMoveCursorLineBoundary(direction, extend) { + var steps = odtDocument.getCursor(inputMemberId).getStepCounter().countStepsToLineBoundary(direction, odtDocument.getPositionFilter()); + return extend ? createOpMoveCursorByAdjustment(0, steps) : createOpMoveCursorByAdjustment(steps, 0) + } + function moveCursorToLineStart() { + sessionEnqueue(createOpMoveCursorLineBoundary(-1, false)); + return true + } + function moveCursorToLineEnd() { + sessionEnqueue(createOpMoveCursorLineBoundary(1, false)); + return true + } + function extendSelectionToLineStart() { + sessionEnqueue(createOpMoveCursorLineBoundary(-1, true)); + return true + } + function extendSelectionToLineEnd() { + sessionEnqueue(createOpMoveCursorLineBoundary(1, true)); + return true } function extendSelectionToParagraphStart() { - var odtDocument = session.getOdtDocument(), paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), iterator, node, selection, steps, op = null; - if(!paragraphNode) { - return op - } + 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); @@ -10969,18 +11697,12 @@ gui.SessionController = function() { steps = odtDocument.getDistanceFromCursor(inputMemberId, node, 0) } } - if(steps !== 0) { - selection = odtDocument.getCursorSelection(inputMemberId); - op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:selection.position, length:selection.length + steps}) - } - return op + sessionEnqueue(createOpMoveCursorByAdjustment(0, steps)); + return true } function extendSelectionToParagraphEnd() { - var odtDocument = session.getOdtDocument(), paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), iterator, node, selection, steps, op = null; - if(!paragraphNode) { - return op - } + 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()); @@ -10991,63 +11713,32 @@ gui.SessionController = function() { steps = odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()) } } - if(steps !== 0) { - selection = odtDocument.getCursorSelection(inputMemberId); - op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:selection.position, length:selection.length + steps}) - } - return op + sessionEnqueue(createOpMoveCursorByAdjustment(0, steps)); + return true } - function moveToLineBoundary(direction) { - var odtDocument = session.getOdtDocument(), oldPosition = odtDocument.getCursorPosition(inputMemberId), steps, op = null; - steps = odtDocument.getCursor(inputMemberId).getStepCounter().countStepsToLineBoundary(direction, odtDocument.getPositionFilter()); - if(steps !== 0) { - op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:oldPosition + steps}) + function createOpMoveCursorDocument(direction, extend) { + var iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), steps; + if(direction > 0) { + iterator.moveToEnd() } - return op - } - function extendSelectionToDocumentEnd() { - var odtDocument = session.getOdtDocument(), iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), selection, steps, op = null; - iterator.moveToEnd(); steps = odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()); - if(steps !== 0) { - selection = odtDocument.getCursorSelection(inputMemberId); - op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:selection.position, length:selection.length + steps}) - } - return op - } - function extendSelectionToDocumentStart() { - var odtDocument = session.getOdtDocument(), selection, steps, op = null; - steps = odtDocument.getDistanceFromCursor(inputMemberId, odtDocument.getRootNode(), 0); - if(steps !== 0) { - selection = odtDocument.getCursorSelection(inputMemberId); - op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:selection.position, length:selection.length + steps}) - } - return op - } - function moveCursorToDocumentEnd() { - var odtDocument = session.getOdtDocument(), iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), oldPosition, steps, op = null; - iterator.moveToEnd(); - steps = odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()); - if(steps !== 0) { - oldPosition = odtDocument.getCursorPosition(inputMemberId); - op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:oldPosition + steps, length:0}) - } - return op + return extend ? createOpMoveCursorByAdjustment(0, steps) : createOpMoveCursorByAdjustment(steps, 0) } function moveCursorToDocumentStart() { - var odtDocument = session.getOdtDocument(), oldPosition, steps, op = null; - steps = odtDocument.getDistanceFromCursor(inputMemberId, odtDocument.getRootNode(), 0); - if(steps !== 0) { - oldPosition = odtDocument.getCursorPosition(inputMemberId); - op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:oldPosition + steps, length:0}) - } - return op + sessionEnqueue(createOpMoveCursorDocument(-1, false)); + return true + } + function moveCursorToDocumentEnd() { + sessionEnqueue(createOpMoveCursorDocument(1, false)); + return true + } + function extendSelectionToDocumentStart() { + sessionEnqueue(createOpMoveCursorDocument(-1, true)); + return true + } + function extendSelectionToDocumentEnd() { + sessionEnqueue(createOpMoveCursorDocument(1, true)); + return true } function toForwardSelection(selection) { if(selection.length < 0) { @@ -11061,8 +11752,8 @@ gui.SessionController = function() { op.init({memberid:inputMemberId, position:selection.position, length:selection.length}); return op } - function createOpRemoveTextByBackspaceKey() { - var odtDocument = session.getOdtDocument(), selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op = null; + function removeTextByBackspaceKey() { + var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op = null; if(selection.length === 0) { if(selection.position > 0 && odtDocument.getPositionInTextNode(selection.position - 1)) { op = new ops.OpRemoveText; @@ -11071,10 +11762,11 @@ gui.SessionController = function() { }else { op = createOpRemoveSelection(selection) } - return op + sessionEnqueue(op); + return true } - function createOpRemoveTextByDeleteKey() { - var odtDocument = session.getOdtDocument(), selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op = null; + function removeTextByDeleteKey() { + var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op = null; if(selection.length === 0) { if(odtDocument.getPositionInTextNode(selection.position + 1)) { op = new ops.OpRemoveText; @@ -11083,119 +11775,21 @@ gui.SessionController = function() { }else { op = createOpRemoveSelection(selection) } - return op + sessionEnqueue(op); + return op !== null } function enqueueParagraphSplittingOps() { - var odtDocument = session.getOdtDocument(), position = odtDocument.getCursorPosition(inputMemberId), isAtEndOfParagraph = false, paragraphNode, styleName, nextStyleName, op; + var position = odtDocument.getCursorPosition(inputMemberId), isAtEndOfParagraph = false, paragraphNode, styleName, nextStyleName, op; op = new ops.OpSplitParagraph; op.init({memberid:inputMemberId, position:position}); - session.enqueue(op) + session.enqueue(op); + return true } function maintainCursorSelection() { - var cursor = session.getOdtDocument().getCursor(inputMemberId), selection = runtime.getWindow().getSelection(); + var cursor = odtDocument.getCursor(inputMemberId), selection = runtime.getWindow().getSelection(); selection.removeAllRanges(); selection.addRange(cursor.getSelectedRange().cloneRange()) } - function handleKeyDown(e) { - var keyCode = e.keyCode, op = null, handled = false; - if(keyCode === 37) { - op = e.shiftKey ? extendSelection(-1) : createOpMoveCursor(-1); - handled = true - }else { - if(keyCode === 39) { - op = e.shiftKey ? extendSelection(1) : createOpMoveCursor(1); - handled = true - }else { - if(keyCode === 38) { - if(isMacOS && e.altKey && e.shiftKey || e.ctrlKey && e.shiftKey) { - op = extendSelectionToParagraphStart() - }else { - if(e.metaKey && e.shiftKey) { - op = extendSelectionToDocumentStart() - }else { - if(e.shiftKey) { - op = extendSelectionByLines(-1) - }else { - op = createOpMoveCursorByLines(-1) - } - } - } - handled = true - }else { - if(keyCode === 40) { - if(isMacOS && e.altKey && e.shiftKey || e.ctrlKey && e.shiftKey) { - op = extendSelectionToParagraphEnd() - }else { - if(e.metaKey && e.shiftKey) { - op = extendSelectionToDocumentEnd() - }else { - if(e.shiftKey) { - op = extendSelectionByLines(1) - }else { - op = createOpMoveCursorByLines(1) - } - } - } - handled = true - }else { - if(keyCode === 36) { - if(!isMacOS && e.ctrlKey && e.shiftKey) { - op = extendSelectionToDocumentStart() - }else { - if(isMacOS && e.metaKey || e.ctrlKey) { - op = moveCursorToDocumentStart() - }else { - op = moveToLineBoundary(-1) - } - } - handled = true - }else { - if(keyCode === 35) { - if(!isMacOS && e.ctrlKey && e.shiftKey) { - op = extendSelectionToDocumentEnd() - }else { - if(isMacOS && e.metaKey || e.ctrlKey) { - op = moveCursorToDocumentEnd() - }else { - op = moveToLineBoundary(1) - } - } - handled = true - }else { - if(keyCode === 8) { - op = createOpRemoveTextByBackspaceKey(); - handled = true - }else { - if(keyCode === 46) { - op = createOpRemoveTextByDeleteKey(); - handled = op !== null - }else { - if(undoManager && keyCode === 90) { - if(!isMacOS && e.ctrlKey || isMacOS && e.metaKey) { - if(e.shiftKey) { - undoManager.moveForward(1) - }else { - undoManager.moveBackward(1) - } - maintainCursorSelection(); - handled = true - } - } - } - } - } - } - } - } - } - } - if(op) { - session.enqueue(op) - } - if(handled) { - cancelEvent(e) - } - } function stringFromKeyPress(event) { if(event.which === null) { return String.fromCharCode(event.keyCode) @@ -11205,22 +11799,8 @@ gui.SessionController = function() { } return null } - function handleKeyPress(e) { - var op, text = stringFromKeyPress(e); - if(e.keyCode === 13) { - enqueueParagraphSplittingOps(); - cancelEvent(e) - }else { - if(text && !(e.altKey || e.ctrlKey || e.metaKey)) { - op = new ops.OpInsertText; - op.init({memberid:inputMemberId, position:session.getOdtDocument().getCursorPosition(inputMemberId), text:text}); - session.enqueue(op); - cancelEvent(e) - } - } - } function handleCut(e) { - var cursor = session.getOdtDocument().getCursor(inputMemberId), selectedRange = cursor.getSelectedRange(), selection, op; + var cursor = odtDocument.getCursor(inputMemberId), selectedRange = cursor.getSelectedRange(), selection, op; if(selectedRange.collapsed) { return } @@ -11234,7 +11814,7 @@ gui.SessionController = function() { } } function handleBeforeCut() { - var cursor = session.getOdtDocument().getCursor(inputMemberId), selectedRange = cursor.getSelectedRange(); + var cursor = odtDocument.getCursor(inputMemberId), selectedRange = cursor.getSelectedRange(); return!(selectedRange.collapsed === false) } function handlePaste(e) { @@ -11248,7 +11828,7 @@ gui.SessionController = function() { } if(plainText) { op = new ops.OpInsertText; - op.init({memberid:inputMemberId, position:session.getOdtDocument().getCursorPosition(inputMemberId), text:plainText}); + op.init({memberid:inputMemberId, position:odtDocument.getCursorPosition(inputMemberId), text:plainText}); session.enqueue(op); cancelEvent(e) } @@ -11262,13 +11842,29 @@ gui.SessionController = function() { } } function forwardUndoStackChange(e) { - session.getOdtDocument().emit(ops.OdtDocument.signalUndoStackChanged, e) + odtDocument.emit(ops.OdtDocument.signalUndoStackChanged, e) + } + function undo() { + if(undoManager) { + undoManager.moveBackward(1); + maintainCursorSelection(); + return true + } + return false + } + function redo() { + if(undoManager) { + undoManager.moveForward(1); + maintainCursorSelection(); + return true + } + return false } this.startEditing = function() { - var canvasElement, op, odtDocument = session.getOdtDocument(); + var canvasElement, op; canvasElement = odtDocument.getOdfCanvas().getElement(); - listenEvent(canvasElement, "keydown", handleKeyDown); - listenEvent(canvasElement, "keypress", handleKeyPress); + listenEvent(canvasElement, "keydown", keyDownHandler.handleEvent); + listenEvent(canvasElement, "keypress", keyPressHandler.handleEvent); listenEvent(canvasElement, "keyup", dummyHandler); listenEvent(canvasElement, "beforecut", handleBeforeCut, true); listenEvent(canvasElement, "mouseup", clickHandler.handleMouseUp); @@ -11285,12 +11881,12 @@ gui.SessionController = function() { } }; this.endEditing = function() { - var canvasElement, op, odtDocument = session.getOdtDocument(); + var canvasElement, op; odtDocument.unsubscribe(ops.OdtDocument.signalOperationExecuted, updateUndoStack); odtDocument.unsubscribe(ops.OdtDocument.signalOperationExecuted, maintainCursorSelection); canvasElement = odtDocument.getOdfCanvas().getElement(); - removeEvent(canvasElement, "keydown", handleKeyDown); - removeEvent(canvasElement, "keypress", handleKeyPress); + removeEvent(canvasElement, "keydown", keyDownHandler.handleEvent); + removeEvent(canvasElement, "keypress", keyPressHandler.handleEvent); removeEvent(canvasElement, "keyup", dummyHandler); removeEvent(canvasElement, "cut", handleCut); removeEvent(canvasElement, "beforecut", handleBeforeCut); @@ -11316,9 +11912,9 @@ gui.SessionController = function() { } undoManager = manager; if(undoManager) { - undoManager.setOdtDocument(session.getOdtDocument()); + undoManager.setOdtDocument(odtDocument); undoManager.setPlaybackFunction(function(op) { - op.execute(session.getOdtDocument()) + op.execute(odtDocument) }); undoManager.subscribe(gui.UndoManager.signalUndoStackChanged, forwardUndoStackChange) } @@ -11327,7 +11923,52 @@ gui.SessionController = function() { return undoManager }; function init() { - clickHandler.subscribe(gui.ClickHandler.signalSingleClick, moveCursor); + var isMacOS = runtime.getWindow().navigator.appVersion.toLowerCase().indexOf("mac") !== -1, modifier = gui.KeyboardHandler.Modifier, keyCode = gui.KeyboardHandler.KeyCode; + keyDownHandler.bind(keyCode.Left, modifier.None, moveCursorToLeft); + keyDownHandler.bind(keyCode.Right, modifier.None, moveCursorToRight); + keyDownHandler.bind(keyCode.Up, modifier.None, moveCursorUp); + keyDownHandler.bind(keyCode.Down, modifier.None, moveCursorDown); + keyDownHandler.bind(keyCode.Backspace, modifier.None, removeTextByBackspaceKey); + keyDownHandler.bind(keyCode.Delete, modifier.None, removeTextByDeleteKey); + keyDownHandler.bind(keyCode.Left, modifier.Shift, extendSelectionToLeft); + keyDownHandler.bind(keyCode.Right, modifier.Shift, extendSelectionToRight); + keyDownHandler.bind(keyCode.Up, modifier.Shift, extendSelectionUp); + keyDownHandler.bind(keyCode.Down, modifier.Shift, extendSelectionDown); + keyDownHandler.bind(keyCode.Home, modifier.None, moveCursorToLineStart); + keyDownHandler.bind(keyCode.End, modifier.None, moveCursorToLineEnd); + keyDownHandler.bind(keyCode.Home, modifier.Ctrl, moveCursorToDocumentStart); + keyDownHandler.bind(keyCode.End, modifier.Ctrl, moveCursorToDocumentEnd); + keyDownHandler.bind(keyCode.Home, modifier.Shift, extendSelectionToLineStart); + keyDownHandler.bind(keyCode.End, modifier.Shift, extendSelectionToLineEnd); + keyDownHandler.bind(keyCode.Up, modifier.CtrlShift, extendSelectionToParagraphStart); + keyDownHandler.bind(keyCode.Down, modifier.CtrlShift, extendSelectionToParagraphEnd); + keyDownHandler.bind(keyCode.Home, modifier.CtrlShift, extendSelectionToDocumentStart); + keyDownHandler.bind(keyCode.End, modifier.CtrlShift, extendSelectionToDocumentEnd); + if(isMacOS) { + keyDownHandler.bind(keyCode.Left, modifier.Meta, moveCursorToLineStart); + keyDownHandler.bind(keyCode.Right, modifier.Meta, moveCursorToLineEnd); + keyDownHandler.bind(keyCode.Home, modifier.Meta, moveCursorToDocumentStart); + keyDownHandler.bind(keyCode.End, modifier.Meta, moveCursorToDocumentEnd); + keyDownHandler.bind(keyCode.Left, modifier.MetaShift, extendSelectionToLineStart); + keyDownHandler.bind(keyCode.Right, modifier.MetaShift, extendSelectionToLineEnd); + keyDownHandler.bind(keyCode.Up, modifier.AltShift, extendSelectionToParagraphStart); + keyDownHandler.bind(keyCode.Down, modifier.AltShift, extendSelectionToParagraphEnd); + keyDownHandler.bind(keyCode.Up, modifier.MetaShift, extendSelectionToDocumentStart); + keyDownHandler.bind(keyCode.Down, modifier.MetaShift, extendSelectionToDocumentEnd); + keyDownHandler.bind(keyCode.Z, modifier.Meta, undo); + keyDownHandler.bind(keyCode.Z, modifier.MetaShift, redo) + }else { + keyDownHandler.bind(keyCode.Z, modifier.Ctrl, undo); + keyDownHandler.bind(keyCode.Z, modifier.CtrlShift, redo) + } + keyPressHandler.setDefault(function(e) { + var text = stringFromKeyPress(e), op = new ops.OpInsertText; + op.init({memberid:inputMemberId, position:odtDocument.getCursorPosition(inputMemberId), text:text}); + session.enqueue(op); + return true + }); + keyPressHandler.bind(keyCode.Enter, modifier.None, enqueueParagraphSplittingOps); + clickHandler.subscribe(gui.ClickHandler.signalSingleClick, select); clickHandler.subscribe(gui.ClickHandler.signalDoubleClick, selectWord); clickHandler.subscribe(gui.ClickHandler.signalTripleClick, selectParagraph) } @@ -11387,8 +12028,8 @@ ops.TrivialUserModel = function TrivialUserModel() { this.unsubscribeUserDetailsUpdates = function(memberId, subscriber) { } }; -ops.NowjsUserModel = function NowjsUserModel() { - var cachedUserData = {}, memberDataSubscribers = {}, net = runtime.getNetwork(); +ops.NowjsUserModel = function NowjsUserModel(server) { + var cachedUserData = {}, memberDataSubscribers = {}, nowObject = server.getNowObject(); function userIdFromMemberId(memberId) { return memberId.split("___")[0] } @@ -11415,7 +12056,7 @@ ops.NowjsUserModel = function NowjsUserModel() { }else { subscribers.push({memberId:memberId, subscriber:subscriber}); if(subscribers.length === 1) { - net.subscribeUserDetailsUpdates(userId) + nowObject.subscribeUserDetailsUpdates(userId) } } if(userData) { @@ -11438,14 +12079,157 @@ ops.NowjsUserModel = function NowjsUserModel() { runtime.log("no more subscribers for: " + memberId); delete memberDataSubscribers[userId]; delete cachedUserData[userId]; - net.unsubscribeUserDetailsUpdates(userId) + nowObject.unsubscribeUserDetailsUpdates(userId) } } }; - net.updateUserDetails = function(userId, udata) { + nowObject.updateUserDetails = function(userId, udata) { cacheUserDatum(userId, udata ? {userid:udata.uid, fullname:udata.fullname, imageurl:"/user/" + udata.avatarId + "/avatar.png", color:udata.color} : null) }; - runtime.assert(net.networkStatus === "ready", "network not ready") + runtime.assert(nowObject.networkStatus === "ready", "network not ready") +}; +/* + + Copyright (C) 2013 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +ops.PullBoxUserModel = function PullBoxUserModel(server) { + var cachedUserData = {}, memberDataSubscribers = {}, serverPullingActivated = false, pullingIntervall = 2E4; + function userIdFromMemberId(memberId) { + return memberId.split("___")[0] + } + function cacheUserDatum(userData) { + var subscribers, i; + subscribers = memberDataSubscribers[userData.userid]; + if(subscribers) { + cachedUserData[userData.userid] = userData; + for(i = 0;i < subscribers.length;i += 1) { + subscribers[i].subscriber(subscribers[i].memberId, userData) + } + } + } + function pullUserData() { + var base64 = server.getBase64(), i, userIds = []; + for(i in memberDataSubscribers) { + if(memberDataSubscribers.hasOwnProperty(i)) { + userIds.push(i) + } + } + runtime.log("user-list request for : " + userIds.join(",")); + server.call("user-list:" + base64.toBase64(server.getToken()) + ":" + userIds.join(","), function(responseData) { + var response = (runtime.fromJson(responseData)), userList, newUserData, oldUserData; + runtime.log("user-list reply: " + responseData); + if(response.hasOwnProperty("userdata_list")) { + userList = response.userdata_list; + for(i = 0;i < userList.length;i += 1) { + newUserData = {userid:userList[i].uid, fullname:userList[i].fullname, imageurl:"/user/" + userList[i].avatarId + "/avatar.png", color:userList[i].color}; + oldUserData = cachedUserData.hasOwnProperty(userList[i].uid) ? cachedUserData[userList[i].uid] : null; + if(!oldUserData || oldUserData.fullname !== newUserData.fullname || oldUserData.imageurl !== newUserData.imageurl || oldUserData.color !== newUserData.color) { + cacheUserDatum(newUserData) + } + } + }else { + runtime.log("Meh, userlist data broken: " + responseData) + } + }) + } + function periodicPullUserData() { + if(!serverPullingActivated) { + return + } + pullUserData(); + runtime.setTimeout(periodicPullUserData, pullingIntervall) + } + function activatePeriodicUserDataPulling() { + if(serverPullingActivated) { + return + } + serverPullingActivated = true; + runtime.setTimeout(periodicPullUserData, pullingIntervall) + } + function deactivatePeriodicUserDataPulling() { + var key; + if(!serverPullingActivated) { + return + } + for(key in memberDataSubscribers) { + if(memberDataSubscribers.hasOwnProperty(key)) { + return + } + } + serverPullingActivated = false + } + this.getUserDetailsAndUpdates = function(memberId, subscriber) { + var userId = userIdFromMemberId(memberId), userData = cachedUserData[userId], subscribers = memberDataSubscribers[userId] = memberDataSubscribers[userId] || [], i; + runtime.assert(subscriber !== undefined, "missing callback"); + for(i = 0;i < subscribers.length;i += 1) { + if(subscribers[i].subscriber === subscriber && subscribers[i].memberId === memberId) { + break + } + } + if(i < subscribers.length) { + runtime.log("double subscription request for " + memberId + " in PullBoxUserModel::getUserDetailsAndUpdates") + }else { + subscribers.push({memberId:memberId, subscriber:subscriber}); + if(subscribers.length === 1) { + pullUserData() + } + } + if(userData) { + subscriber(memberId, userData) + } + activatePeriodicUserDataPulling() + }; + this.unsubscribeUserDetailsUpdates = function(memberId, subscriber) { + var i, userId = userIdFromMemberId(memberId), subscribers = memberDataSubscribers[userId]; + runtime.assert(subscriber !== undefined, "missing subscriber parameter or null"); + runtime.assert(subscribers, "tried to unsubscribe when no one is subscribed ('" + memberId + "')"); + if(subscribers) { + for(i = 0;i < subscribers.length;i += 1) { + if(subscribers[i].subscriber === subscriber && subscribers[i].memberId === memberId) { + break + } + } + runtime.assert(i < subscribers.length, "tried to unsubscribe when not subscribed for memberId '" + memberId + "'"); + subscribers.splice(i, 1); + if(subscribers.length === 0) { + runtime.log("no more subscribers for: " + memberId); + delete memberDataSubscribers[userId]; + delete cachedUserData[userId]; + deactivatePeriodicUserDataPulling() + } + } + }; + runtime.assert(server.networkStatus() === "ready", "network not ready") }; /* @@ -11538,8 +12322,8 @@ ops.TrivialOperationRouter = function TrivialOperationRouter() { playbackFunction(timedOp) } }; -ops.NowjsOperationRouter = function NowjsOperationRouter(sessionId, memberid) { - var self = this, operationFactory, playbackFunction, net = runtime.getNetwork(), last_server_seq = -1, reorder_queue = {}, sends_since_server_op = 0, router_sequence = 1E3; +ops.NowjsOperationRouter = function NowjsOperationRouter(sessionId, memberid, server) { + var self = this, operationFactory, playbackFunction, nowObject = server.getNowObject(), last_server_seq = -1, reorder_queue = {}, sends_since_server_op = 0, router_sequence = 1E3; function nextNonce() { runtime.assert(memberid !== null, "Router sequence N/A without memberid"); router_sequence += 1; @@ -11576,12 +12360,12 @@ ops.NowjsOperationRouter = function NowjsOperationRouter(sessionId, memberid) { runtime.log("ignoring invalid incoming opspec: " + opspec) } } - net.ping = function(pong) { + nowObject.ping = function(pong) { if(memberid !== null) { pong(memberid) } }; - net.receiveOp = function(op_session_id, opspec) { + nowObject.receiveOp = function(op_session_id, opspec) { if(op_session_id === sessionId) { receiveOpFromNetwork(opspec) } @@ -11592,10 +12376,10 @@ ops.NowjsOperationRouter = function NowjsOperationRouter(sessionId, memberid) { opspec.parent_op = last_server_seq + "+" + sends_since_server_op; sends_since_server_op += 1; runtime.log("op out: " + runtime.toJson(opspec)); - net.deliverOp(sessionId, opspec) + nowObject.deliverOp(sessionId, opspec) }; this.requestReplay = function(done_cb) { - net.requestReplay(sessionId, function(opspec) { + nowObject.requestReplay(sessionId, function(opspec) { runtime.log("replaying: " + runtime.toJson(opspec)); receiveOpFromNetwork(opspec) }, function(count) { @@ -11606,13 +12390,245 @@ ops.NowjsOperationRouter = function NowjsOperationRouter(sessionId, memberid) { }) }; function init() { - net.memberid = memberid; - net.joinSession(sessionId, function(sessionJoinSuccess) { + nowObject.memberid = memberid; + nowObject.joinSession(sessionId, function(sessionJoinSuccess) { runtime.assert(sessionJoinSuccess, "Trying to join a session which does not exists or where we are already in") }) } init() }; +/* + + Copyright (C) 2013 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +runtime.loadClass("ops.OperationTransformer"); +ops.PullBoxOperationRouter = function PullBoxOperationRouter(sessionId, memberId, server) { + var self = this, operationFactory, singleTimeCallbackOnCompleteServerOpSpecsPlay, playbackFunction, pullingTimeOutFlag = null, triggerPushingOpsActivated = false, playUnplayedServerOpSpecsTriggered = false, syncLock = false, hasUnresolvableConflict = false, lastServerSeq = "", unsyncedClientOpspecQueue = [], unplayedServerOpspecQueue = [], operationTransformer = new ops.OperationTransformer, replayTime = 500, pushingIntervall = 3E3, pullingIntervall = 8E3; + function compressOpSpecs(opspecs) { + var i, j, op, result = []; + i = 0; + while(i < opspecs.length) { + op = operationFactory.create(opspecs[i]); + if(op !== null && op.merge) { + for(j = i + 1;j < opspecs.length;j += 1) { + if(!op.merge(opspecs[j])) { + break + } + runtime.log("Merged: " + opspecs[i].optype + " with " + opspecs[j].optype) + } + result.push(op.spec()); + i = j + }else { + result.push(opspecs[i]); + i += 1 + } + } + runtime.log("Merged: from " + opspecs.length + " to " + result.length + " specs"); + return result + } + function playUnplayedServerOpSpecs() { + function doPlayUnplayedServerOpSpecs() { + var opspec, op, startTime; + playUnplayedServerOpSpecsTriggered = false; + startTime = (new Date).getTime(); + while(unplayedServerOpspecQueue.length > 0) { + if((new Date).getTime() - startTime > replayTime) { + break + } + opspec = unplayedServerOpspecQueue.shift(); + op = operationFactory.create(opspec); + runtime.log(" op in: " + runtime.toJson(opspec)); + if(op !== null) { + playbackFunction(op) + }else { + runtime.log("ignoring invalid incoming opspec: " + opspec) + } + } + if(unplayedServerOpspecQueue.length > 0) { + playUnplayedServerOpSpecsTriggered = true; + runtime.getWindow().setTimeout(doPlayUnplayedServerOpSpecs, 1) + }else { + if(singleTimeCallbackOnCompleteServerOpSpecsPlay) { + singleTimeCallbackOnCompleteServerOpSpecsPlay(); + singleTimeCallbackOnCompleteServerOpSpecsPlay = null + } + } + } + if(playUnplayedServerOpSpecsTriggered) { + return + } + doPlayUnplayedServerOpSpecs() + } + function receiveOpSpecsFromNetwork(opspecs) { + unplayedServerOpspecQueue = unplayedServerOpspecQueue.concat(opspecs) + } + function handleOpsSyncConflict(serverOpspecs) { + var i, transformResult; + if(!serverOpspecs) { + runtime.assert(false, "no opspecs received!"); + return false + } + transformResult = operationTransformer.transform(unsyncedClientOpspecQueue, (serverOpspecs)); + if(!transformResult) { + return false + } + for(i = 0;i < transformResult.opsB.length;i += 1) { + unplayedServerOpspecQueue.push(transformResult.opsB[i].spec()) + } + unsyncedClientOpspecQueue = []; + for(i = 0;i < transformResult.opsA.length;i += 1) { + unsyncedClientOpspecQueue.push(transformResult.opsA[i].spec()) + } + return true + } + function syncOps() { + function triggerPullingOps() { + var flag = {active:true}; + pullingTimeOutFlag = flag; + runtime.getWindow().setTimeout(function() { + runtime.log("Pulling activated:" + flag.active); + pullingTimeOutFlag = null; + if(flag.active) { + syncOps() + } + }, pullingIntervall) + } + function doSyncOps() { + var base64 = server.getBase64(), syncedClientOpspecs; + if(syncLock || hasUnresolvableConflict) { + return + } + syncLock = true; + syncedClientOpspecs = unsyncedClientOpspecQueue; + unsyncedClientOpspecQueue = []; + server.call("sync-ops:" + base64.toBase64(server.getToken()) + ":" + base64.toBase64(sessionId) + ":" + base64.toBase64(memberId) + ":" + base64.toBase64(String(lastServerSeq)) + ":" + runtime.toJson(syncedClientOpspecs), function(responseData) { + var shouldRetryInstantly = false, response = (runtime.fromJson(responseData)); + runtime.log("sync-ops reply: " + responseData); + if(response.result === "newOps") { + if(response.ops.length > 0) { + if(unsyncedClientOpspecQueue.length === 0) { + receiveOpSpecsFromNetwork(compressOpSpecs(response.ops)) + }else { + runtime.log("meh, have new ops locally meanwhile, have to do transformations."); + hasUnresolvableConflict = !handleOpsSyncConflict(compressOpSpecs(response.ops)) + } + lastServerSeq = response.headSeq + } + }else { + if(response.result === "added") { + runtime.log("All added to server"); + lastServerSeq = response.headSeq + }else { + if(response.result === "conflict") { + unsyncedClientOpspecQueue = syncedClientOpspecs.concat(unsyncedClientOpspecQueue); + runtime.log("meh, server has new ops meanwhile, have to do transformations."); + hasUnresolvableConflict = !handleOpsSyncConflict(compressOpSpecs(response.ops)); + lastServerSeq = response.headSeq; + if(!hasUnresolvableConflict) { + shouldRetryInstantly = true + } + }else { + runtime.assert(false, "Unexpected result on sync-ops call: " + response.result) + } + } + } + syncLock = false; + if(hasUnresolvableConflict) { + runtime.assert(false, "Sorry to tell:\n" + "we hit a pair of operations in a state which yet need to be supported for transformation against each other.\n" + "Client disconnected from session, no further editing accepted.\n\n" + "Please reconnect manually for now.") + }else { + if(shouldRetryInstantly) { + doSyncOps() + }else { + runtime.log("Preparing next: " + (unsyncedClientOpspecQueue.length === 0)); + if(unsyncedClientOpspecQueue.length === 0) { + triggerPullingOps() + } + } + playUnplayedServerOpSpecs() + } + }) + } + doSyncOps() + } + function triggerPushingOps() { + if(syncLock || triggerPushingOpsActivated) { + return + } + triggerPushingOpsActivated = true; + if(pullingTimeOutFlag) { + pullingTimeOutFlag.active = false + } + runtime.getWindow().setTimeout(function() { + runtime.log("Pushing activated"); + triggerPushingOpsActivated = false; + syncOps() + }, pushingIntervall) + } + this.requestReplay = function(done_cb) { + singleTimeCallbackOnCompleteServerOpSpecsPlay = done_cb; + syncOps() + }; + this.setOperationFactory = function(f) { + operationFactory = f; + operationTransformer.setOperationFactory(f) + }; + this.setPlaybackFunction = function(playback_func) { + playbackFunction = playback_func + }; + this.push = function(op) { + var timedOp, opspec = op.spec(); + if(hasUnresolvableConflict) { + return + } + if(unplayedServerOpspecQueue.length > 0) { + return + } + opspec.timestamp = (new Date).getTime(); + timedOp = operationFactory.create(opspec); + playbackFunction(timedOp); + unsyncedClientOpspecQueue.push(opspec); + triggerPushingOps() + }; + function init() { + var base64 = server.getBase64(); + server.call("join-session:" + base64.toBase64(server.getToken()) + ":" + base64.toBase64(sessionId) + ":" + base64.toBase64(memberId), function(responseData) { + var response = Boolean(runtime.fromJson(responseData)); + runtime.log("join-session reply: " + responseData); + runtime.assert(response, "Trying to join a session which does not exists or where we are already in") + }) + } + init() +}; gui.EditInfoHandle = function EditInfoHandle(parentElement) { var edits = [], handle, document = (parentElement.ownerDocument), htmlns = document.documentElement.namespaceURI, editinfons = "urn:webodf:names:editinfo"; function renderEdits() { @@ -12425,6 +13441,8 @@ 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 })(); @@ -12466,6 +13484,7 @@ gui.UndoStateRules = function UndoStateRules() { function getOpType(op) { return op.spec().optype } + this.getOpType = getOpType; function getOpPosition(op) { return op.spec().position } @@ -12555,8 +13574,8 @@ gui.UndoStateRules = function UndoStateRules() { */ runtime.loadClass("gui.UndoManager"); runtime.loadClass("gui.UndoStateRules"); -gui.TrivialUndoManager = function TrivialUndoManager() { - var self = this, initialDoc, initialState, playFunc, odtDocument, currentUndoState = [], undoStates = [], redoStates = [], eventNotifier = new core.EventNotifier([gui.UndoManager.signalUndoStackChanged]), undoRules = new gui.UndoStateRules; +gui.TrivialUndoManager = function TrivialUndoManager(defaultRules) { + var self = this, 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()}) } @@ -12613,9 +13632,11 @@ gui.TrivialUndoManager = function TrivialUndoManager() { completeCurrentUndoState(); currentUndoState = [op]; undoStates.push(currentUndoState); + eventNotifier.emit(gui.UndoManager.signalUndoStateCreated, {operations:currentUndoState}); emitStackChange() }else { - currentUndoState.push(op) + currentUndoState.push(op); + eventNotifier.emit(gui.UndoManager.signalUndoStateModified, {operations:currentUndoState}) } }; this.moveForward = function(states) { @@ -12643,6 +13664,7 @@ gui.TrivialUndoManager = function TrivialUndoManager() { 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()) }); @@ -12657,6 +13679,10 @@ gui.TrivialUndoManager = function TrivialUndoManager() { return moved } }; +gui.TrivialUndoManager.signalDocumentRootReplaced = "documentRootReplaced"; +(function() { + return gui.TrivialUndoManager +})(); /* Copyright (C) 2012-2013 KO GmbH @@ -12964,6 +13990,26 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { return null } }; + this.fixCursorPositions = function(localMemberId) { + var cursors, stepCounter, steps, filter, i; + cursors = self.getCursors(); + filter = self.getPositionFilter(); + for(i in cursors) { + if(cursors.hasOwnProperty(i)) { + stepCounter = cursors[i].getStepCounter(); + if(!stepCounter.isPositionWalkable(filter)) { + steps = -stepCounter.countBackwardSteps(1, filter); + if(steps === 0) { + steps = stepCounter.countForwardSteps(1, filter) + } + cursors[i].move(steps); + if(i === localMemberId) { + self.emit(ops.OdtDocument.signalCursorMoved, cursors[i]) + } + } + } + } + }; this.getWalkableParagraphLength = function(paragraph) { var iterator = getIteratorAtPosition(0), length = 0; iterator.setUnfilteredPosition(paragraph, 0); @@ -13122,21 +14168,30 @@ runtime.loadClass("ops.TrivialOperationRouter"); runtime.loadClass("ops.OperationFactory"); runtime.loadClass("ops.OdtDocument"); ops.Session = function Session(odfCanvas) { - var self = this, odtDocument = new ops.OdtDocument(odfCanvas), userModel = new ops.TrivialUserModel, operationRouter = null; + var self = this, operationFactory = new ops.OperationFactory, odtDocument = new ops.OdtDocument(odfCanvas), userModel = new ops.TrivialUserModel, operationRouter = null; this.setUserModel = function(uModel) { userModel = uModel }; + this.setOperationFactory = function(opFactory) { + operationFactory = opFactory; + if(operationRouter) { + operationRouter.setOperationFactory(operationFactory) + } + }; this.setOperationRouter = function(opRouter) { operationRouter = opRouter; opRouter.setPlaybackFunction(function(op) { op.execute(odtDocument); odtDocument.emit(ops.OdtDocument.signalOperationExecuted, op) }); - opRouter.setOperationFactory(new ops.OperationFactory) + opRouter.setOperationFactory(operationFactory) }; this.getUserModel = function() { return userModel }; + this.getOperationFactory = function() { + return operationFactory + }; this.getOdtDocument = function() { return odtDocument }; diff --git a/js/webodf.js b/js/webodf.js index 67274e59..b067fad1 100644 --- a/js/webodf.js +++ b/js/webodf.js @@ -36,80 +36,80 @@ */ var core={},gui={},xmldom={},odf={},ops={}; // Input 1 -function Runtime(){}Runtime.ByteArray=function(e){};Runtime.prototype.getVariable=function(e){};Runtime.prototype.toJson=function(e){};Runtime.prototype.fromJson=function(e){};Runtime.ByteArray.prototype.slice=function(e,k){};Runtime.ByteArray.prototype.length=0;Runtime.prototype.byteArrayFromArray=function(e){};Runtime.prototype.byteArrayFromString=function(e,k){};Runtime.prototype.byteArrayToString=function(e,k){};Runtime.prototype.concatByteArrays=function(e,k){}; -Runtime.prototype.read=function(e,k,l,p){};Runtime.prototype.readFile=function(e,k,l){};Runtime.prototype.readFileSync=function(e,k){};Runtime.prototype.loadXML=function(e,k){};Runtime.prototype.writeFile=function(e,k,l){};Runtime.prototype.isFile=function(e,k){};Runtime.prototype.getFileSize=function(e,k){};Runtime.prototype.deleteFile=function(e,k){};Runtime.prototype.log=function(e,k){};Runtime.prototype.setTimeout=function(e,k){};Runtime.prototype.libraryPaths=function(){}; -Runtime.prototype.type=function(){};Runtime.prototype.getDOMImplementation=function(){};Runtime.prototype.parseXML=function(e){};Runtime.prototype.getWindow=function(){};Runtime.prototype.assert=function(e,k,l){};var IS_COMPILED_CODE=!0; -Runtime.byteArrayToString=function(e,k){function l(h){var b="",f,d=h.length;for(f=0;fa?b+=String.fromCharCode(a):(f+=1,n=h[f],194<=a&&224>a?b+=String.fromCharCode((a&31)<<6|n&63):(f+=1,q=h[f],224<=a&&240>a?b+=String.fromCharCode((a&15)<<12|(n&63)<<6|q&63):(f+=1,g=h[f],240<=a&&245>a&&(a=(a&7)<<18|(n&63)<<12|(q&63)<<6|g&63,a-=65536,b+=String.fromCharCode((a>>10)+55296,(a&1023)+56320))))); -return b}var r;"utf8"===k?r=p(e):("binary"!==k&&this.log("Unsupported encoding: "+k),r=l(e));return r};Runtime.getVariable=function(e){try{return eval(e)}catch(k){}};Runtime.toJson=function(e){return JSON.stringify(e)};Runtime.fromJson=function(e){return JSON.parse(e)};Runtime.getFunctionName=function(e){return void 0===e.name?(e=/function\s+(\w+)/.exec(e))&&e[1]:e.name}; -function BrowserRuntime(e){function k(h,b){var f,d,a;void 0!==b?a=h:b=h;e?(d=e.ownerDocument,a&&(f=d.createElement("span"),f.className=a,f.appendChild(d.createTextNode(a)),e.appendChild(f),e.appendChild(d.createTextNode(" "))),f=d.createElement("span"),0n?(d[q]=n,q+=1):2048>n?(d[q]=192|n>>>6,d[q+1]=128|n&63,q+=2):(d[q]=224|n>>>12&15,d[q+1]=128|n>>>6&63,d[q+2]=128|n&63,q+=3)}else for("binary"!==b&&l.log("unknown encoding: "+b),f=h.length,d=new l.ByteArray(f),a=0;ad.status||0===d.status?f(null):f("Status "+String(d.status)+": "+d.responseText||d.statusText):f("File "+h+" is empty."))}; -b=b.buffer&&!d.sendAsBinary?b.buffer:l.byteArrayToString(b,"binary");try{d.sendAsBinary?d.sendAsBinary(b):d.send(b)}catch(a){l.log("HUH? "+a+" "+b),f(a.message)}};this.deleteFile=function(h,b){delete p[h];var f=new XMLHttpRequest;f.open("DELETE",h,!0);f.onreadystatechange=function(){4===f.readyState&&(200>f.status&&300<=f.status?b(f.responseText):b(null))};f.send(null)};this.loadXML=function(h,b){var f=new XMLHttpRequest;f.open("GET",h,!0);f.overrideMimeType&&f.overrideMimeType("text/xml");f.onreadystatechange= -function(){4===f.readyState&&(0!==f.status||f.responseText?200===f.status||0===f.status?b(null,f.responseXML):b(f.responseText):b("File "+h+" is empty."))};try{f.send(null)}catch(d){b(d.message)}};this.isFile=function(h,b){l.getFileSize(h,function(f){b(-1!==f)})};this.getFileSize=function(h,b){var f=new XMLHttpRequest;f.open("HEAD",h,!0);f.onreadystatechange=function(){if(4===f.readyState){var d=f.getResponseHeader("Content-Length");d?b(parseInt(d,10)):b(-1)}};f.send(null)};this.log=k;this.assert= -function(h,b,f){if(!h)throw k("alert","ASSERTION FAILED:\n"+b),f&&f(),b;};this.setTimeout=function(h,b){setTimeout(function(){h()},b)};this.libraryPaths=function(){return["lib"]};this.setCurrentDirectory=function(h){};this.type=function(){return"BrowserRuntime"};this.getDOMImplementation=function(){return window.document.implementation};this.parseXML=function(h){return(new DOMParser).parseFromString(h,"text/xml")};this.exit=function(h){k("Calling exit with code "+String(h)+", but exit() is not implemented.")}; -this.getWindow=function(){return window};this.getNetwork=function(){var h=this.getVariable("now");return void 0===h?{networkStatus:"unavailable"}:h}} -function NodeJSRuntime(){function e(b,d,a){b=p.resolve(r,b);"binary"!==d?l.readFile(b,d,a):l.readFile(b,null,a)}var k=this,l=require("fs"),p=require("path"),r="",h,b;this.ByteArray=function(b){return new Buffer(b)};this.byteArrayFromArray=function(b){var d=new Buffer(b.length),a,n=b.length;for(a=0;a").implementation} -function RhinoRuntime(){function e(b,f){var d;void 0!==f?d=b:f=b;"alert"===d&&print("\n!!!!! ALERT !!!!!");print(f);"alert"===d&&print("!!!!! ALERT !!!!!")}var k=this,l=Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance(),p,r,h="";l.setValidating(!1);l.setNamespaceAware(!0);l.setExpandEntityReferences(!1);l.setSchema(null);r=Packages.org.xml.sax.EntityResolver({resolveEntity:function(b,f){var d=new Packages.java.io.FileReader(f);return new Packages.org.xml.sax.InputSource(d)}});p=l.newDocumentBuilder(); -p.setEntityResolver(r);this.ByteArray=function(b){return[b]};this.byteArrayFromArray=function(b){return b};this.byteArrayFromString=function(b,f){var d=[],a,n=b.length;for(a=0;ab?a+=String.fromCharCode(b):(e+=1,s=g[e],194<=b&&224>b?a+=String.fromCharCode((b&31)<<6|s&63):(e+=1,m=g[e],224<=b&&240>b?a+=String.fromCharCode((b&15)<<12|(s&63)<<6|m&63):(e+=1,k=g[e],240<=b&&245>b&&(b=(b&7)<<18|(s&63)<<12|(m&63)<<6|k&63,b-=65536,a+=String.fromCharCode((b>>10)+55296,(b&1023)+56320))))); +return a}var p;"utf8"===l?p=q(h):("binary"!==l&&this.log("Unsupported encoding: "+l),p=f(h));return p};Runtime.getVariable=function(h){try{return eval(h)}catch(l){}};Runtime.toJson=function(h){return JSON.stringify(h)};Runtime.fromJson=function(h){return JSON.parse(h)};Runtime.getFunctionName=function(h){return void 0===h.name?(h=/function\s+(\w+)/.exec(h))&&h[1]:h.name}; +function BrowserRuntime(h){function l(g,a){var e,d,b;void 0!==a?b=g:a=g;h?(d=h.ownerDocument,b&&(e=d.createElement("span"),e.className=b,e.appendChild(d.createTextNode(b)),h.appendChild(e),h.appendChild(d.createTextNode(" "))),e=d.createElement("span"),0s?(d[m]=s,m+=1):2048>s?(d[m]=192|s>>>6,d[m+1]=128|s&63,m+=2):(d[m]=224|s>>>12&15,d[m+1]=128|s>>>6&63,d[m+2]=128|s&63,m+=3)}else for("binary"!==a&&f.log("unknown encoding: "+a),e=g.length,d=new f.ByteArray(e),b=0;bd.status||0===d.status?e(null):e("Status "+String(d.status)+": "+d.responseText||d.statusText):e("File "+g+" is empty."))}; +a=a.buffer&&!d.sendAsBinary?a.buffer:f.byteArrayToString(a,"binary");try{d.sendAsBinary?d.sendAsBinary(a):d.send(a)}catch(b){f.log("HUH? "+b+" "+a),e(b.message)}};this.deleteFile=function(g,a){delete q[g];var e=new XMLHttpRequest;e.open("DELETE",g,!0);e.onreadystatechange=function(){4===e.readyState&&(200>e.status&&300<=e.status?a(e.responseText):a(null))};e.send(null)};this.loadXML=function(g,a){var e=new XMLHttpRequest;e.open("GET",g,!0);e.overrideMimeType&&e.overrideMimeType("text/xml");e.onreadystatechange= +function(){4===e.readyState&&(0!==e.status||e.responseText?200===e.status||0===e.status?a(null,e.responseXML):a(e.responseText):a("File "+g+" is empty."))};try{e.send(null)}catch(d){a(d.message)}};this.isFile=function(g,a){f.getFileSize(g,function(e){a(-1!==e)})};this.getFileSize=function(g,a){var e=new XMLHttpRequest;e.open("HEAD",g,!0);e.onreadystatechange=function(){if(4===e.readyState){var d=e.getResponseHeader("Content-Length");d?a(parseInt(d,10)):a(-1)}};e.send(null)};this.log=l;this.assert= +function(g,a,e){if(!g)throw l("alert","ASSERTION FAILED:\n"+a),e&&e(),a;};this.setTimeout=function(g,a){setTimeout(function(){g()},a)};this.libraryPaths=function(){return["lib"]};this.setCurrentDirectory=function(g){};this.type=function(){return"BrowserRuntime"};this.getDOMImplementation=function(){return window.document.implementation};this.parseXML=function(g){return(new DOMParser).parseFromString(g,"text/xml")};this.exit=function(g){l("Calling exit with code "+String(g)+", but exit() is not implemented.")}; +this.getWindow=function(){return window}} +function NodeJSRuntime(){function h(a,d,b){a=q.resolve(p,a);"binary"!==d?f.readFile(a,d,b):f.readFile(a,null,b)}var l=this,f=require("fs"),q=require("path"),p="",g,a;this.ByteArray=function(a){return new Buffer(a)};this.byteArrayFromArray=function(a){var d=new Buffer(a.length),b,s=a.length;for(b=0;b").implementation} +function RhinoRuntime(){function h(a,e){var d;void 0!==e?d=a:e=a;"alert"===d&&print("\n!!!!! ALERT !!!!!");print(e);"alert"===d&&print("!!!!! ALERT !!!!!")}var l=this,f=Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance(),q,p,g="";f.setValidating(!1);f.setNamespaceAware(!0);f.setExpandEntityReferences(!1);f.setSchema(null);p=Packages.org.xml.sax.EntityResolver({resolveEntity:function(a,e){var d=new Packages.java.io.FileReader(e);return new Packages.org.xml.sax.InputSource(d)}});q=f.newDocumentBuilder(); +q.setEntityResolver(p);this.ByteArray=function(a){return[a]};this.byteArrayFromArray=function(a){return a};this.byteArrayFromString=function(a,e){var d=[],b,s=a.length;for(b=0;b>>18],b+=u[c>>>12&63],b+=u[c>>>6&63],b+=u[c&63];m===g+1?(c=a[m]<<4,b+=u[c>>>6],b+=u[c&63],b+="=="):m===g&&(c=a[m]<<10|a[m+1]<<2,b+=u[c>>>12],b+=u[c>>>6&63],b+=u[c&63],b+="=");return b}function l(a){a=a.replace(/[^A-Za-z0-9+\/]+/g,"");var b=[],c=a.length%4,m,g=a.length,q;for(m=0;m>16,q>>8&255,q&255);b.length-=[0,0,2,1][c];return b}function p(a){var b=[],c,m=a.length,g;for(c=0;cg?b.push(g):2048>g?b.push(192|g>>>6,128|g&63):b.push(224|g>>>12&15,128|g>>>6&63,128|g&63);return b}function r(a){var b=[],c,m=a.length,g,q,s;for(c=0;cg?b.push(g):(c+=1,q=a[c],224>g?b.push((g&31)<<6|q&63):(c+=1,s=a[c],b.push((g&15)<<12|(q&63)<<6|s&63)));return b}function h(a){return k(e(a))} -function b(a){return String.fromCharCode.apply(String,l(a))}function f(a){return r(e(a))}function d(a){a=r(a);for(var c="",b=0;bb?m+=String.fromCharCode(b):(s+=1,g=a.charCodeAt(s)&255,224>b?m+=String.fromCharCode((b&31)<<6|g&63):(s+=1,q=a.charCodeAt(s)&255,m+=String.fromCharCode((b&15)<<12|(g&63)<<6|q&63)));return m}function n(b,c){function m(){var d= -s+g;d>b.length&&(d=b.length);q+=a(b,s,d);s=d;d=s===b.length;c(q,d)&&!d&&runtime.setTimeout(m,0)}var g=1E5,q="",s=0;b.lengthb;b+=1)a.push(65+b);for(b=0;26>b;b+=1)a.push(97+b);for(b= -0;10>b;b+=1)a.push(48+b);a.push(43);a.push(47);return a})();var t=function(a){var b={},c,m;c=0;for(m=a.length;c>>18],c+=t[a>>>12&63],c+=t[a>>>6&63],c+=t[a&63];m===n+1?(a=b[m]<<4,c+=t[a>>>6],c+=t[a&63],c+="=="):m===n&&(a=b[m]<<10|b[m+1]<<2,c+=t[a>>>12],c+=t[a>>>6&63],c+=t[a&63],c+="=");return c}function f(b){b=b.replace(/[^A-Za-z0-9+\/]+/g,"");var a=[],c=b.length%4,m,n=b.length,d;for(m=0;m>16,d>>8&255,d&255);a.length-=[0,0,2,1][c];return a}function q(b){var a=[],c,m=b.length,n;for(c=0;cn?a.push(n):2048>n?a.push(192|n>>>6,128|n&63):a.push(224|n>>>12&15,128|n>>>6&63,128|n&63);return a}function p(b){var a=[],c,m=b.length,n,d,k;for(c=0;cn?a.push(n):(c+=1,d=b[c],224>n?a.push((n&31)<<6|d&63):(c+=1,k=b[c],a.push((n&15)<<12|(d&63)<<6|k&63)));return a}function g(b){return l(h(b))} +function a(b){return String.fromCharCode.apply(String,f(b))}function e(b){return p(h(b))}function d(b){b=p(b);for(var a="",c=0;ca?m+=String.fromCharCode(a):(k+=1,n=b.charCodeAt(k)&255,224>a?m+=String.fromCharCode((a&31)<<6|n&63):(k+=1,d=b.charCodeAt(k)&255,m+=String.fromCharCode((a&15)<<12|(n&63)<<6|d&63)));return m}function s(a,c){function m(){var e= +k+n;e>a.length&&(e=a.length);d+=b(a,k,e);k=e;e=k===a.length;c(d,e)&&!e&&runtime.setTimeout(m,0)}var n=1E5,d="",k=0;a.lengtha;a+=1)b.push(65+a);for(a=0;26>a;a+=1)b.push(97+a);for(a= +0;10>a;a+=1)b.push(48+a);b.push(43);b.push(47);return b})();var r=function(b){var a={},c,m;c=0;for(m=b.length;c>>8):(oa(b&255),oa(b>>>8))},qa=function(){v=(v<<5^c[y+3-1]&255)&8191;w=s[32768+v];s[y&32767]=w;s[32768+v]=y},ba=function(a,b){A>16-b?(m|=a<>16-A,A+=b-16):(m|=a<a;a++)c[a]=c[a+32768];J-=32768;y-=32768;x-=32768;for(a=0;8192>a;a++)b=s[32768+a],s[32768+a]=32768<=b?b-32768:0;for(a=0;32768>a;a++)b=s[a],s[a]=32768<=b?b-32768:0;m+=32768}C||(a=Aa(c,y+D,m),0>=a?C=!0:D+=a)},Ba=function(a){var b=G,m=y,g,q=O,d=32506=F&&(b>>=2);do if(g=a,c[g+q]===e&&c[g+q-1]===n&&c[g]===c[m]&&c[++g]===c[m+1]){m+= -2;g++;do++m;while(c[m]===c[++g]&&c[++m]===c[++g]&&c[++m]===c[++g]&&c[++m]===c[++g]&&c[++m]===c[++g]&&c[++m]===c[++g]&&c[++m]===c[++g]&&c[++m]===c[++g]&&mq){J=a;q=g;if(258<=g)break;n=c[m+q-1];e=c[m+q]}}while((a=s[a&32767])>d&&0!==--b);return q},ka=function(a,b){t[aa++]=b;0===a?K[b].fc++:(a--,K[z[b]+256+1].fc++,H[(256>a?ca[a]:ca[256+(a>>7)])&255].fc++,u[la++]=a,ga|=ia);ia<<=1;0===(aa&7)&&(da[sa++]=ga,ga=0,ia=1);if(2g;g++)c+= -H[g].fc*(5+ja[g]);c>>=3;if(la>=1,c<<=1;while(0<--b);return c>>1},Da=function(a,b){var c=[];c.length=16;var m=0,g;for(g=1;15>=g;g++)m=m+S[g-1]<<1,c[g]=m;for(m=0;m<=b;m++)g=a[m].dl,0!==g&&(a[m].fc=Ca(c[g]++,g))},xa=function(a){var b=a.dyn_tree,c=a.static_tree,m=a.elems, -g,q=-1,s=m;R=0;N=573;for(g=0;gR;)g=T[++R]=2>q?++q:0,b[g].fc=1,V[g]=0,ea--,null!==c&&(ha-=c[g].dl);a.max_code=q;for(g=R>>1;1<=g;g--)wa(b,g);do g=T[1],T[1]=T[R--],wa(b,1),c=T[1],T[--N]=g,T[--N]=c,b[s].fc=b[g].fc+b[c].fc,V[s]=V[g]>V[c]+1?V[g]:V[c]+1,b[g].dl=b[c].dl=s,T[1]=s++,wa(b,1);while(2<=R);T[--N]=T[1];s=a.dyn_tree;g=a.extra_bits;var m=a.extra_base,c=a.max_code,d=a.max_length,t=a.static_tree,n,e,f,u,h=0;for(e=0;15>=e;e++)S[e]=0;s[T[N]].dl= -0;for(a=N+1;573>a;a++)n=T[a],e=s[s[n].dl].dl+1,e>d&&(e=d,h++),s[n].dl=e,n>c||(S[e]++,f=0,n>=m&&(f=g[n-m]),u=s[n].fc,ea+=u*(e+f),null!==t&&(ha+=u*(t[n].dl+f)));if(0!==h){do{for(e=d-1;0===S[e];)e--;S[e]--;S[e+1]+=2;S[d]--;h-=2}while(0c||(s[g].dl!==e&&(ea+=(e-s[g].dl)*s[g].fc,s[g].fc=e),n--)}Da(b,q)},Ea=function(a,b){var c,m=-1,g,q=a[0].dl,s=0,d=7,n=4;0===q&&(d=138,n=3);a[b+1].dl=65535;for(c=0;c<=b;c++)g=q,q=a[c+1].dl,++s=s?W[17].fc++:W[18].fc++,s=0,m=g,0===q?(d=138,n=3):g===q?(d=6,n=3):(d=7,n=4))},Fa=function(){8c?ca[c]:ca[256+(c>>7)])&255,fa(d,b),n=ja[d],0!==n&&(c-=Y[d],ba(c,n))),s>>=1;while(m=s?(fa(17,W),ba(s-3,3)):(fa(18,W),ba(s-11,7));s=0;m=g;0===q?(d=138,n=3):g===q?(d=6,n=3):(d=7,n=4)}},Ia=function(){var a;for(a=0;286>a;a++)K[a].fc=0;for(a=0;30>a;a++)H[a].fc=0;for(a=0;19>a;a++)W[a].fc=0;K[256].fc=1;ga=aa=la=sa=ea=ha=0;ia=1},ra=function(a){var b,m,g,q;q=y-x;da[sa]=ga;xa(L);xa(I);Ea(K,L.max_code);Ea(H,I.max_code);xa(M);for(g=18;3<=g&&0=== -W[ya[g]].dl;g--);ea+=3*(g+1)+14;b=ea+3+7>>3;m=ha+3+7>>3;m<=b&&(b=m);if(q+4<=b&&0<=x)for(ba(0+a,3),Fa(),pa(q),pa(~q),g=0;gb.len&&(d=b.len);for(t=0;tn-q&&(d=n-q);for(t=0;tu;u++)for($[u]=h,f=0;f<1<u;u++)for(Y[u]=h,f=0;f<1<>=7;30>u;u++)for(Y[u]=h<<7,f=0;f<1<=f;f++)S[f]=0;for(f=0;143>=f;)U[f++].dl=8,S[8]++;for(;255>=f;)U[f++].dl=9,S[9]++;for(;279>=f;)U[f++].dl=7,S[7]++;for(;287>=f;)U[f++].dl=8,S[8]++;Da(U,287);for(f=0;30>f;f++)Z[f].dl=5,Z[f].fc=Ca(f,5);Ia()}for(f=0;8192>f;f++)s[32768+f]=0;X=na[Q].max_lazy;F=na[Q].good_length;G=na[Q].max_chain;x=y=0;D=Aa(c,0, -65536);if(0>=D)C=!0,D=0;else{for(C=!1;262>D&&!C;)va();for(f=v=0;2>f;f++)v=(v<<5^c[f]&255)&8191}b=null;q=n=0;3>=Q?(O=2,E=0):(E=2,B=0);g=!1}d=!0;if(0===D)return g=!0,0}if((f=Ja(a,t,e))===e)return e;if(g)return f;if(3>=Q)for(;0!==D&&null===b;){qa();0!==w&&32506>=y-w&&(E=Ba(w),E>D&&(E=D));if(3<=E)if(u=ka(y-J,E-3),D-=E,E<=X){E--;do y++,qa();while(0!==--E);y++}else y+=E,E=0,v=c[y]&255,v=(v<<5^c[y+1]&255)&8191;else u=ka(0,c[y]&255),D--,y++;u&&(ra(0),x=y);for(;262>D&&!C;)va()}else for(;0!==D&&null===b;){qa(); -O=E;P=J;E=2;0!==w&&(O=y-w)&&(E=Ba(w),E>D&&(E=D),3===E&&4096D&&!C;)va()}0===D&&(0!==B&&ka(0,c[y-1]&255),ra(1),g=!0);return f+Ja(a,f+t,e-f)};this.deflate=function(m,g){var q,n;ma=m;ta=0;"undefined"===String(typeof g)&&(g=6);(q=g)?1>q?q=1:9q;q++)K[q]=new e;H=[];H.length=61;for(q=0;61>q;q++)H[q]=new e;U=[];U.length=288;for(q=0;288>q;q++)U[q]=new e;Z=[];Z.length=30;for(q=0;30>q;q++)Z[q]=new e;W=[];W.length=39;for(q=0;39>q;q++)W[q]=new e;L=new k;I=new k;M=new k;S=[];S.length=16;T=[];T.length=573;V=[];V.length=573;z=[];z.length=256;ca=[];ca.length=512;$=[];$.length=29;Y=[];Y.length=30;da=[];da.length=1024}for(var l=Array(1024),p=[];0<(q=La(l,0,l.length));){var G= -[];G.length=q;for(n=0;n>>8):(oa(a&255),oa(a>>>8))},qa=function(){u=(u<<5^c[z+3-1]&255)&8191;w=x[32768+u];x[z&32767]=w;x[32768+u]=z},da=function(b,a){C>16-a?(n|=b<>16-C,C+=a-16):(n|=b<b;b++)c[b]=c[b+32768];H-=32768;z-=32768;y-=32768;for(b=0;8192>b;b++)a=x[32768+b],x[32768+b]=32768<=a?a-32768:0;for(b=0;32768>b;b++)a=x[b],x[b]=32768<=a?a-32768:0;m+=32768}D||(b=Aa(c,z+G,m),0>=b?D=!0:G+=b)},Ba=function(b){var a=T,m=z,n,d=O,k=32506=ca&&(a>>=2);do if(n=b,c[n+d]===g&&c[n+d-1]===r&&c[n]===c[m]&&c[++n]===c[m+1]){m+= +2;n++;do++m;while(c[m]===c[++n]&&c[++m]===c[++n]&&c[++m]===c[++n]&&c[++m]===c[++n]&&c[++m]===c[++n]&&c[++m]===c[++n]&&c[++m]===c[++n]&&c[++m]===c[++n]&&md){H=b;d=n;if(258<=n)break;r=c[m+d-1];g=c[m+d]}}while((b=x[b&32767])>k&&0!==--a);return d},la=function(b,a){r[Z++]=a;0===b?U[a].fc++:(b--,U[v[a]+256+1].fc++,W[(256>b?aa[b]:aa[256+(b>>7)])&255].fc++,t[X++]=b,ha|=ja);ja<<=1;0===(Z&7)&&(M[sa++]=ha,ha=0,ja=1);if(2n;n++)c+=W[n].fc* +(5+ka[n]);c>>=3;if(X>=1,c<<=1;while(0<--a);return c>>1},Da=function(b,a){var c=[];c.length=16;var m=0,n;for(n=1;15>=n;n++)m=m+P[n-1]<<1,c[n]=m;for(m=0;m<=a;m++)n=b[m].dl,0!==n&&(b[m].fc=Ca(c[n]++,n))},xa=function(b){var a=b.dyn_tree,c=b.static_tree,m=b.elems,n,d=-1, +k=m;Y=0;E=573;for(n=0;nY;)n=Q[++Y]=2>d?++d:0,a[n].fc=1,$[n]=0,ea--,null!==c&&(ia-=c[n].dl);b.max_code=d;for(n=Y>>1;1<=n;n--)wa(a,n);do n=Q[1],Q[1]=Q[Y--],wa(a,1),c=Q[1],Q[--E]=n,Q[--E]=c,a[k].fc=a[n].fc+a[c].fc,$[k]=$[n]>$[c]+1?$[n]:$[c]+1,a[n].dl=a[c].dl=k,Q[1]=k++,wa(a,1);while(2<=Y);Q[--E]=Q[1];k=b.dyn_tree;n=b.extra_bits;var m=b.extra_base,c=b.max_code,e=b.max_length,r=b.static_tree,x,g,s,f,t=0;for(g=0;15>=g;g++)P[g]=0;k[Q[E]].dl=0;for(b= +E+1;573>b;b++)x=Q[b],g=k[k[x].dl].dl+1,g>e&&(g=e,t++),k[x].dl=g,x>c||(P[g]++,s=0,x>=m&&(s=n[x-m]),f=k[x].fc,ea+=f*(g+s),null!==r&&(ia+=f*(r[x].dl+s)));if(0!==t){do{for(g=e-1;0===P[g];)g--;P[g]--;P[g+1]+=2;P[e]--;t-=2}while(0c||(k[n].dl!==g&&(ea+=(g-k[n].dl)*k[n].fc,k[n].fc=g),x--)}Da(a,d)},Ea=function(b,a){var c,m=-1,n,k=b[0].dl,d=0,e=7,g=4;0===k&&(e=138,g=3);b[a+1].dl=65535;for(c=0;c<=a;c++)n=k,k=b[c+1].dl,++d=d?R[17].fc++:R[18].fc++,d=0,m=n,0===k?(e=138,g=3):n===k?(e=6,g=3):(e=7,g=4))},Fa=function(){8c?aa[c]:aa[256+(c>>7)])&255,fa(e,a),g=ka[e],0!==g&&(c-=L[e],da(c,g))),d>>=1;while(m=k?(fa(17,R),da(k-3,3)):(fa(18,R),da(k-11,7));k=0;m=n;0===d?(e=138,g=3):n===d?(e=6,g=3):(e=7,g=4)}},Ia=function(){var b;for(b=0;286>b;b++)U[b].fc=0;for(b=0;30>b;b++)W[b].fc=0;for(b=0;19>b;b++)R[b].fc=0;U[256].fc=1;ha=Z=X=sa=ea=ia=0;ja=1},ra=function(b){var a,n,m,k;k=z-y;M[sa]=ha;xa(I);xa(B);Ea(U,I.max_code);Ea(W,B.max_code);xa(J);for(m=18;3<=m&&0===R[ya[m]].dl;m--); +ea+=3*(m+1)+14;a=ea+3+7>>3;n=ia+3+7>>3;n<=a&&(a=n);if(k+4<=a&&0<=y)for(da(0+b,3),Fa(),pa(k),pa(~k),m=0;ma.len&&(e=a.len);for(r=0;rs-m&&(e=s-m);for(r=0;rt;t++)for(ga[t]= +f,r=0;r<1<t;t++)for(L[t]=f,r=0;r<1<>=7;30>t;t++)for(L[t]=f<<7,r=0;r<1<=r;r++)P[r]=0;for(r=0;143>=r;)N[r++].dl=8,P[8]++;for(;255>=r;)N[r++].dl=9,P[9]++;for(;279>=r;)N[r++].dl=7,P[7]++;for(;287>=r;)N[r++].dl=8,P[8]++;Da(N,287);for(r=0;30>r;r++)S[r].dl=5,S[r].fc=Ca(r,5);Ia()}for(r=0;8192>r;r++)x[32768+r]=0;ba=na[V].max_lazy;ca=na[V].good_length;T=na[V].max_chain;y=z=0;G=Aa(c,0,65536);if(0>=G)D= +!0,G=0;else{for(D=!1;262>G&&!D;)va();for(r=u=0;2>r;r++)u=(u<<5^c[r]&255)&8191}a=null;m=s=0;3>=V?(O=2,F=0):(F=2,A=0);k=!1}d=!0;if(0===G)return k=!0,0}if((r=Ja(b,e,g))===g)return g;if(k)return r;if(3>=V)for(;0!==G&&null===a;){qa();0!==w&&32506>=z-w&&(F=Ba(w),F>G&&(F=G));if(3<=F)if(t=la(z-H,F-3),G-=F,F<=ba){F--;do z++,qa();while(0!==--F);z++}else z+=F,F=0,u=c[z]&255,u=(u<<5^c[z+1]&255)&8191;else t=la(0,c[z]&255),G--,z++;t&&(ra(0),y=z);for(;262>G&&!D;)va()}else for(;0!==G&&null===a;){qa();O=F;K=H;F=2; +0!==w&&(O=z-w)&&(F=Ba(w),F>G&&(F=G),3===F&&4096G&&!D;)va()}0===G&&(0!==A&&la(0,c[z-1]&255),ra(1),k=!0);return r+Ja(b,r+e,g-r)};this.deflate=function(m,n){var k,f;ma=m;ta=0;"undefined"===String(typeof n)&&(n=6);(k=n)?1>k?k=1:9k;k++)U[k]=new h;W=[];W.length=61;for(k=0;61>k;k++)W[k]=new h;N=[];N.length=288;for(k=0;288>k;k++)N[k]=new h;S=[];S.length=30;for(k=0;30>k;k++)S[k]=new h;R=[];R.length=39;for(k=0;39>k;k++)R[k]=new h;I=new l;B=new l;J=new l;P=[];P.length=16;Q=[];Q.length=573;$=[];$.length=573;v=[];v.length=256;aa=[];aa.length=512;ga=[];ga.length=29;L=[];L.length=30;M=[];M.length=1024}for(var s=Array(1024),q=[];0<(k=La(s,0,s.length));){var u= +[];u.length=k;for(f=0;f>8&255])};this.appendUInt32LE=function(e){k.appendArray([e&255,e>>8&255,e>>16&255,e>>24&255])};this.appendString=function(k){l=runtime.concatByteArrays(l, -runtime.byteArrayFromString(k,e))};this.getLength=function(){return l.length};this.getByteArray=function(){return l}}; +core.ByteArrayWriter=function(h){var l=this,f=new runtime.ByteArray(0);this.appendByteArrayWriter=function(q){f=runtime.concatByteArrays(f,q.getByteArray())};this.appendByteArray=function(q){f=runtime.concatByteArrays(f,q)};this.appendArray=function(q){f=runtime.concatByteArrays(f,runtime.byteArrayFromArray(q))};this.appendUInt16LE=function(f){l.appendArray([f&255,f>>8&255])};this.appendUInt32LE=function(f){l.appendArray([f&255,f>>8&255,f>>16&255,f>>24&255])};this.appendString=function(q){f=runtime.concatByteArrays(f, +runtime.byteArrayFromString(q,h))};this.getLength=function(){return f.length};this.getByteArray=function(){return f}}; // Input 6 -core.RawInflate=function(){var e,k,l=null,p,r,h,b,f,d,a,n,q,g,c,u,t,s,m=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],A=[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],x=[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],v=[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],P=[16,17,18, -0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],B=function(){this.list=this.next=null},E=function(){this.n=this.b=this.e=0;this.t=null},O=function(a,b,c,m,g,q){this.BMAX=16;this.N_MAX=288;this.status=0;this.root=null;this.m=0;var s=Array(this.BMAX+1),d,n,t,e,f,u,h,k=Array(this.BMAX+1),l,p,r,G=new E,A=Array(this.BMAX);e=Array(this.N_MAX);var v,x=Array(this.BMAX+1),C,w,X;X=this.root=null;for(f=0;ff&&(q=f);for(C=1<(C-=s[u])){this.status=2;this.m=q;return}if(0>(C-=s[f]))this.status=2,this.m=q;else{s[f]+=C;x[1]=u=0;l=s;p=1;for(r=2;0<--f;)x[r++]=u+=l[p++];l=a;f=p=0;do 0!=(u=l[p++])&&(e[x[u]++]=f);while(++fv+k[1+e];){v+=k[1+e];e++;w=(w=t-v)>q?q:w;if((n=1<<(u=h-v))>a+1)for(n-=a+1,r=h;++ud&&v>v-k[e],A[e-1][u].e=G.e,A[e-1][u].b=G.b,A[e-1][u].n=G.n,A[e-1][u].t=G.t)}G.b=h-v;p>=b?G.e=99:l[p]l[p]?16:15,G.n=l[p++]): -(G.e=g[l[p]-c],G.n=m[l[p++]-c]);n=1<>v;u>=1)f^=u;for(f^=u;(f&(1<>=a;b-=a},D=function(b,m,s){var d,t,h;if(0==s)return 0;for(h=0;;){y(c);t=q.list[J(c)];for(d=t.e;16 -d;d++)k[P[d]]=0;c=7;d=new O(k,19,19,null,null,c);if(0!=d.status)return-1;q=d.root;c=d.m;t=e+h;for(s=n=0;sd)k[s++]=n=d;else if(16==d){y(2);d=3+J(2);C(2);if(s+d>t)return-1;for(;0t)return-1;for(;0I;I++)L[I]=8;for(;256>I;I++)L[I]=9;for(;280>I;I++)L[I]=7;for(;288>I;I++)L[I]=8;r=7;I=new O(L,288,257,A,x,r);if(0!=I.status){alert("HufBuild error: "+I.status);B=-1;break b}l=I.root;r=I.m;for(I=0;30>I;I++)L[I]=5;G=5;I=new O(L,30,0,v,w,G);if(1f&&(k=f);for(G=1<(G-=d[t])){this.status=2;this.m=k;return}if(0>(G-=d[f]))this.status=2,this.m=k;else{d[f]+=G;w[1]=t=0;q=d;l=1;for(h=2;0<--f;)w[h++]=t+=q[l++];q=b;f=l=0;do 0!=(t=q[l++])&&(x[w[t]++]=f);while(++fy+p[1+x];){y+=p[1+x];x++;z=(z=g-y)>k?k:z;if((r=1<<(t=s-y))>b+1)for(r-=b+1,h=s;++te&&y>y-p[x],C[x-1][t].e=u.e,C[x-1][t].b=u.b,C[x-1][t].n=u.n,C[x-1][t].t=u.t)}u.b=s-y;l>=a?u.e=99:q[l]q[l]?16:15,u.n=q[l++]): +(u.e=m[q[l]-c],u.n=n[q[l++]-c]);r=1<>y;t>=1)f^=t;for(f^=t;(f&(1<>=b;a-=b},G=function(a,n,d){var r,f,g;if(0==d)return 0;for(g=0;;){z(c);f=m.list[H(c)];for(r=f.e;16 +r;r++)p[K[r]]=0;c=7;r=new O(p,19,19,null,null,c);if(0!=r.status)return-1;m=r.root;c=r.m;f=x+s;for(d=e=0;dr)p[d++]=e=r;else if(16==r){z(2);r=3+H(2);D(2);if(d+r>f)return-1;for(;0f)return-1;for(;0B;B++)I[B]=8;for(;256>B;B++)I[B]=9;for(;280>B;B++)I[B]=7;for(;288>B;B++)I[B]=8;p=7;B=new O(I,288,257,C,y,p);if(0!=B.status){alert("HufBuild error: "+B.status);N=-1;break b}f=B.root;p=B.m;for(B=0;30>B;B++)I[B]=5;T=5;B=new O(I,30,0,u,w,T);if(1e))throw runtime.log("alert","watchdog timeout"),"timeout!";if(0k))throw runtime.log("alert","watchdog loop overflow"),"loop overflow";}}; +core.LoopWatchDog=function(h,l){var f=Date.now(),q=0;this.check=function(){var p;if(h&&(p=Date.now(),p-f>h))throw runtime.log("alert","watchdog timeout"),"timeout!";if(0l))throw runtime.log("alert","watchdog loop overflow"),"loop overflow";}}; // Input 8 -core.Cursor=function(e,k){function l(b){b.parentNode&&(a.push({prev:b.previousSibling,next:b.nextSibling}),b.parentNode.removeChild(b))}function p(a,b){a.nodeType===Node.TEXT_NODE&&(0===a.length?a.parentNode.removeChild(a):b.nodeType===Node.TEXT_NODE&&(b.insertData(0,a.data),a.parentNode.removeChild(a)))}function r(){a.forEach(function(a){a.prev&&a.prev.nextSibling&&p(a.prev,a.prev.nextSibling);a.next&&a.next.previousSibling&&p(a.next.previousSibling,a.next)});a.length=0}function h(b,c,q){if(c.nodeType=== -Node.TEXT_NODE){runtime.assert(Boolean(c),"putCursorIntoTextNode: invalid container");var d=c.parentNode;runtime.assert(Boolean(d),"putCursorIntoTextNode: container without parent");runtime.assert(0<=q&&q<=c.length,"putCursorIntoTextNode: offset is out of bounds");0===q?d.insertBefore(b,c):(q!==c.length&&c.splitText(q),d.insertBefore(b,c.nextSibling))}else if(c.nodeType===Node.ELEMENT_NODE){runtime.assert(Boolean(c),"putCursorIntoContainer: invalid container");for(d=c.firstChild;null!==d&&0 @@ -186,112 +191,112 @@ c;(q=a.collapsed)?(l(f),l(b),h(b,a.startContainer,a.startOffset)):(l(f),l(b),h(d @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -core.EventNotifier=function(e){var k={};this.emit=function(e,p){var r,h;runtime.assert(k.hasOwnProperty(e),'unknown event fired "'+e+'"');h=k[e];for(r=0;r1/g?"-0":String(g),e(a+" should be "+b+". Was "+n+".")):e(a+" should be "+b+" (of type "+typeof b+"). Was "+g+" (of type "+typeof g+").")}var b=0,f;f=function(b,a){var n=Object.keys(b),q=Object.keys(a);n.sort();q.sort();return k(n,q)&&Object.keys(b).every(function(g){var c= -b[g],q=a[g];return r(c,q)?!0:(e(c+" should be "+q+" for key "+g),!1)})};this.areNodesEqual=p;this.shouldBeNull=function(b,a){h(b,a,"null")};this.shouldBeNonNull=function(b,a){var n,q;try{q=eval(a)}catch(g){n=g}n?e(a+" should be non-null. Threw exception "+n):null!==q?runtime.log("pass",a+" is non-null."):e(a+" should be non-null. Was "+q)};this.shouldBe=h;this.countFailedTests=function(){return b}}; -core.UnitTester=function(){function e(e,k){return""+e+""}var k=0,l={};this.runTests=function(p,r,h){function b(c){if(0===c.length)l[f]=n,k+=d.countFailedTests(),r();else{g=c[0];var m=Runtime.getFunctionName(g);runtime.log("Running "+m);u=d.countFailedTests();a.setUp();g(function(){a.tearDown();n[m]=u===d.countFailedTests();b(c.slice(1))})}}var f=Runtime.getFunctionName(p),d=new core.UnitTestRunner,a=new p(d),n={},q,g,c,u,t="BrowserRuntime"=== -runtime.type();if(l.hasOwnProperty(f))runtime.log("Test "+f+" has already run.");else{t?runtime.log("Running "+e(f,'runSuite("'+f+'");')+": "+a.description()+""):runtime.log("Running "+f+": "+a.description);c=a.tests();for(q=0;qRunning "+e(p,'runTest("'+f+'","'+p+'")')+""):runtime.log("Running "+p),u=d.countFailedTests(),a.setUp(),g(),a.tearDown(),n[p]=u===d.countFailedTests()); -b(a.asyncTests())}};this.countFailedTests=function(){return k};this.results=function(){return l}}; +core.EventNotifier=function(h){var l={};this.emit=function(f,q){var p,g;runtime.assert(l.hasOwnProperty(f),'unknown event fired "'+f+'"');g=l[f];for(p=0;p "+b.length),runtime.assert(0<=g,"Error in setPosition: "+g+" < 0"),g===b.length&&(a=void 0,d.nextSibling()?a=0:d.parentNode()&&(a=1),runtime.assert(void 0!==a,"Error in setPosition: position not valid.")),!0;c=n(b);g1/k?"-0":String(k),h(b+" should be "+a+". Was "+e+".")):h(b+" should be "+a+" (of type "+typeof a+"). Was "+k+" (of type "+typeof k+").")}var a=0,e;e=function(a,b){var e=Object.keys(a),m=Object.keys(b);e.sort();m.sort();return l(e,m)&&Object.keys(a).every(function(m){var c= +a[m],e=b[m];return p(c,e)?!0:(h(c+" should be "+e+" for key "+m),!1)})};this.areNodesEqual=q;this.shouldBeNull=function(a,b){g(a,b,"null")};this.shouldBeNonNull=function(a,b){var e,m;try{m=eval(b)}catch(k){e=k}e?h(b+" should be non-null. Threw exception "+e):null!==m?runtime.log("pass",b+" is non-null."):h(b+" should be non-null. Was "+m)};this.shouldBe=g;this.countFailedTests=function(){return a}}; +core.UnitTester=function(){function h(f,p){return""+f+""}var l=0,f={};this.runTests=function(q,p,g){function a(c){if(0===c.length)f[e]=s,l+=d.countFailedTests(),p();else{k=c[0];var n=Runtime.getFunctionName(k);runtime.log("Running "+n);t=d.countFailedTests();b.setUp();k(function(){b.tearDown();s[n]=t===d.countFailedTests();a(c.slice(1))})}}var e=Runtime.getFunctionName(q),d=new core.UnitTestRunner,b=new q(d),s={},m,k,c,t,r="BrowserRuntime"=== +runtime.type();if(f.hasOwnProperty(e))runtime.log("Test "+e+" has already run.");else{r?runtime.log("Running "+h(e,'runSuite("'+e+'");')+": "+b.description()+""):runtime.log("Running "+e+": "+b.description);c=b.tests();for(m=0;mRunning "+h(q,'runTest("'+e+'","'+q+'")')+""):runtime.log("Running "+q),t=d.countFailedTests(),b.setUp(),k(),b.tearDown(),s[q]=t===d.countFailedTests()); +a(b.asyncTests())}};this.countFailedTests=function(){return l};this.results=function(){return f}}; // Input 12 -runtime.loadClass("core.PositionIterator");core.PositionFilter=function(){};core.PositionFilter.FilterResult={FILTER_ACCEPT:1,FILTER_REJECT:2,FILTER_SKIP:3};core.PositionFilter.prototype.acceptPosition=function(e){};(function(){return core.PositionFilter})(); +core.PositionIterator=function(h,l,f,q){function p(){this.acceptNode=function(b){return b.nodeType===Node.TEXT_NODE&&0===b.length?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}function g(b){this.acceptNode=function(a){return a.nodeType===Node.TEXT_NODE&&0===a.length?NodeFilter.FILTER_REJECT:b.acceptNode(a)}}function a(){var a=d.currentNode.nodeType;b=a===Node.TEXT_NODE?d.currentNode.length-1:a===Node.ELEMENT_NODE?1:0}var e=this,d,b,s;this.nextPosition=function(){if(d.currentNode===h)return!1; +if(0===b&&d.currentNode.nodeType===Node.ELEMENT_NODE)null===d.firstChild()&&(b=1);else if(d.currentNode.nodeType===Node.TEXT_NODE&&b+1 "+a.length),runtime.assert(0<=k,"Error in setPosition: "+k+" < 0"),k===a.length&&(b=void 0,d.nextSibling()?b=0:d.parentNode()&&(b=1),runtime.assert(void 0!==b,"Error in setPosition: position not valid.")),!0;c=s(a);k>>8^s;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 h(a,b){var c,m,g,d,q,n,f,e=this;this.load=function(b){if(void 0!==e.data)b(null,e.data);else{var c=q+34+m+g+256;c+f>u&&(c=u-f);runtime.read(a,f,c,function(c,m){if(c||null===m)b(c,m);else a:{var g=m,f=new core.ByteArray(g),t=f.readUInt32LE(),u;if(67324752!==t)b("File entry signature is wrong."+t.toString()+" "+g.length.toString(),null);else{f.pos+=22;t=f.readUInt16LE();u=f.readUInt16LE();f.pos+=t+u; -if(d){g=g.slice(f.pos,f.pos+q);if(q!==g.length){b("The amount of compressed bytes read was "+g.length.toString()+" instead of "+q.toString()+" for "+e.filename+" in "+a+".",null);break a}g=s(g,n)}else g=g.slice(f.pos,f.pos+n);n!==g.length?b("The amount of bytes read was "+g.length.toString()+" instead of "+n.toString()+" for "+e.filename+" in "+a+".",null):(e.data=g,b(null,g))}}})}};this.set=function(a,b,c,m){e.filename=a;e.data=b;e.compressed=c;e.date=m};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,d=b.readUInt16LE(),this.date=p(b.readUInt32LE()),b.readUInt32LE(),q=b.readUInt32LE(),n=b.readUInt32LE(),m=b.readUInt16LE(),g=b.readUInt16LE(),c=b.readUInt16LE(),b.pos+=8,f=b.readUInt32LE(),this.filename=runtime.byteArrayToString(b.data.slice(b.pos,b.pos+m),"utf8"),b.pos+=m+g+c))}function b(a,b){if(22!==a.length)b("Central directory length should be 22.", -m);else{var g=new core.ByteArray(a),s;s=g.readUInt32LE();101010256!==s?b("Central directory signature is wrong: "+s.toString(),m):(s=g.readUInt16LE(),0!==s?b("Zip files with non-zero disk numbers are not supported.",m):(s=g.readUInt16LE(),0!==s?b("Zip files with non-zero disk numbers are not supported.",m):(s=g.readUInt16LE(),t=g.readUInt16LE(),s!==t?b("Number of entries is inconsistent.",m):(s=g.readUInt32LE(),g=g.readUInt16LE(),g=u-22-s,runtime.read(e,g,u-g,function(a,g){if(a||null===g)b(a,m);else a:{var s= -new core.ByteArray(g),d,f;c=[];for(d=0;du?k("File '"+e+"' cannot be read.",m):runtime.read(e,u-22,22,function(a,c){a||null===k||null===c?k(a,m):b(c,k)})})}; -// Input 15 -core.CSSUnits=function(){var e={"in":1,cm:2.54,mm:25.4,pt:72,pc:12};this.convert=function(k,l,p){return k*e[p]/e[l]};this.convertMeasure=function(e,l){var p,r;e&&l?(p=parseFloat(e),r=e.replace(p.toString(),""),p=this.convert(p,r,l)):p="";return p.toString()};this.getUnits=function(e){return e.substr(e.length-2,e.length)}}; +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,n,r=a.length,k=0,k=0;c=-1;for(n=0;n>>8^k;return c^-1}function q(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 p(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 g(a,b){var c,n,k,r,d,m,e,f=this;this.load=function(b){if(void 0!==f.data)b(null,f.data);else{var c=d+34+n+k+256;c+e>t&&(c=t-e);runtime.read(a,e,c,function(c,n){if(c||null===n)b(c,n);else a:{var k=n,e=new core.ByteArray(k),g=e.readUInt32LE(),t;if(67324752!==g)b("File entry signature is wrong."+g.toString()+" "+k.length.toString(),null);else{e.pos+=22;g=e.readUInt16LE();t=e.readUInt16LE();e.pos+=g+t; +if(r){k=k.slice(e.pos,e.pos+d);if(d!==k.length){b("The amount of compressed bytes read was "+k.length.toString()+" instead of "+d.toString()+" for "+f.filename+" in "+a+".",null);break a}k=x(k,m)}else k=k.slice(e.pos,e.pos+m);m!==k.length?b("The amount of bytes read was "+k.length.toString()+" instead of "+m.toString()+" for "+f.filename+" in "+a+".",null):(f.data=k,b(null,k))}}})}};this.set=function(a,b,c,n){f.filename=a;f.data=b;f.compressed=c;f.date=n};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,r=b.readUInt16LE(),this.date=q(b.readUInt32LE()),b.readUInt32LE(),d=b.readUInt32LE(),m=b.readUInt32LE(),n=b.readUInt16LE(),k=b.readUInt16LE(),c=b.readUInt16LE(),b.pos+=8,e=b.readUInt32LE(),this.filename=runtime.byteArrayToString(b.data.slice(b.pos,b.pos+n),"utf8"),b.pos+=n+k+c))}function a(a,b){if(22!==a.length)b("Central directory length should be 22.", +n);else{var k=new core.ByteArray(a),d;d=k.readUInt32LE();101010256!==d?b("Central directory signature is wrong: "+d.toString(),n):(d=k.readUInt16LE(),0!==d?b("Zip files with non-zero disk numbers are not supported.",n):(d=k.readUInt16LE(),0!==d?b("Zip files with non-zero disk numbers are not supported.",n):(d=k.readUInt16LE(),r=k.readUInt16LE(),d!==r?b("Number of entries is inconsistent.",n):(d=k.readUInt32LE(),k=k.readUInt16LE(),k=t-22-d,runtime.read(h,k,t-k,function(a,k){if(a||null===k)b(a,n);else a:{var d= +new core.ByteArray(k),m,e;c=[];for(m=0;mt?l("File '"+h+"' cannot be read.",n):runtime.read(h,t-22,22,function(b,c){b||null===l||null===c?l(b,n):a(c,l)})})}; // Input 16 -xmldom.LSSerializerFilter=function(){}; +core.CSSUnits=function(){var h={"in":1,cm:2.54,mm:25.4,pt:72,pc:12};this.convert=function(l,f,q){return l*h[q]/h[f]};this.convertMeasure=function(l,f){var q,p;l&&f?(q=parseFloat(l),p=l.replace(q.toString(),""),q=this.convert(q,p,f)):q="";return q.toString()};this.getUnits=function(l){return l.substr(l.length-2,l.length)}}; // Input 17 -"function"!==typeof Object.create&&(Object.create=function(e){var k=function(){};k.prototype=e;return new k}); -xmldom.LSSerializer=function(){function e(e){var h=e||{},b=function(a){var b={},g;for(g in a)a.hasOwnProperty(g)&&(b[a[g]]=g);return b}(e),f=[h],d=[b],a=0;this.push=function(){a+=1;h=f[a]=Object.create(h);b=d[a]=Object.create(b)};this.pop=function(){f[a]=void 0;d[a]=void 0;a-=1;h=f[a];b=d[a]};this.getLocalNamespaceDefinitions=function(){return b};this.getQName=function(a){var d=a.namespaceURI,g=0,c;if(!d)return a.localName;if(c=b[d])return c+":"+a.localName;do{c||!a.prefix?(c="ns"+g,g+=1):c=a.prefix; -if(h[c]===d)break;if(!h[c]){h[c]=d;b[d]=c;break}c=null}while(null===c);return c+":"+a.localName}}function k(e){return e.replace(/&/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""")}function l(e,h){var b="",f=p.filter?p.filter.acceptNode(h):NodeFilter.FILTER_ACCEPT,d;if(f===NodeFilter.FILTER_ACCEPT&&h.nodeType===Node.ELEMENT_NODE){e.push();d=e.getQName(h);var a,n=h.attributes,q,g,c,u="",t;a="<"+d;q=n.length;for(g=0;g")}if(f===NodeFilter.FILTER_ACCEPT||f===NodeFilter.FILTER_SKIP){for(f=h.firstChild;f;)b+=l(e,f),f=f.nextSibling;h.nodeValue&&(b+=k(h.nodeValue))}d&&(b+="",e.pop());return b}var p=this;this.filter=null;this.writeToString=function(k,h){if(!k)return"";var b=new e(h);return l(b,k)}}; +xmldom.LSSerializerFilter=function(){}; // Input 18 -xmldom.RelaxNGParser=function(){function e(a,b){this.message=function(){b&&(a+=1===b.nodeType?" Element ":" Node ",a+=b.nodeName,b.nodeValue&&(a+=" with value '"+b.nodeValue+"'"),a+=".");return a}}function k(a){if(2>=a.e.length)return a;var b={name:a.name,e:a.e.slice(0,2)};return k({name:a.name,e:[b].concat(a.e.slice(2))})}function l(a){a=a.split(":",2);var b="",d;1===a.length?a=["",a[0]]:b=a[0];for(d in f)f[d]===b&&(a[0]=d);return a}function p(a,b){for(var d=0,g,c,f=a.name;a.e&&d/g,">").replace(/'/g,"'").replace(/"/g,""")}function f(p,g){var a="",e=q.filter?q.filter.acceptNode(g):NodeFilter.FILTER_ACCEPT,d;if(e===NodeFilter.FILTER_ACCEPT&&g.nodeType===Node.ELEMENT_NODE){p.push();d=p.getQName(g);var b,s=g.attributes,m,k,c,t="",r;b="<"+d;m=s.length;for(k=0;k")}if(e===NodeFilter.FILTER_ACCEPT||e===NodeFilter.FILTER_SKIP){for(e=g.firstChild;e;)a+=f(p,e),e=e.nextSibling;g.nodeValue&&(a+=l(g.nodeValue))}d&&(a+="",p.pop());return a}var q=this;this.filter=null;this.writeToString=function(p,g){if(!p)return"";var a=new h(g);return f(a,p)}}; // Input 19 -runtime.loadClass("xmldom.RelaxNGParser"); -xmldom.RelaxNG=function(){function e(a){return function(){var b;return function(){void 0===b&&(b=a());return b}}()}function k(a,b){return function(){var c={},m=0;return function(g){var s=g.hash||g.toString(),d;d=c[s];if(void 0!==d)return d;c[s]=d=b(g);d.hash=a+m.toString();m+=1;return d}}()}function l(a){return function(){var b={};return function(c){var m,g;g=b[c.localName];if(void 0===g)b[c.localName]=g={};else if(m=g[c.namespaceURI],void 0!==m)return m;return g[c.namespaceURI]=m=a(c)}}()}function p(a, -b,c){return function(){var m={},g=0;return function(s,d){var e=b&&b(s,d),f,t;if(void 0!==e)return e;e=s.hash||s.toString();f=d.hash||d.toString();t=m[e];if(void 0===t)m[e]=t={};else if(e=t[f],void 0!==e)return e;t[f]=e=c(s,d);e.hash=a+g.toString();g+=1;return e}}()}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 h(a,b){return{type:"element",nc:a,nullable:!1,textDeriv:function(){return v},startTagOpenDeriv:function(m){return a.contains(m)? -c(b,w):v},attDeriv:function(a,b){return v},startTagCloseDeriv:function(){return this}}}function b(){return{type:"list",nullable:!1,hash:"list",textDeriv:function(a,b){return w}}}function f(b,c,m,g){if(c===v)return v;if(g>=m.length)return c;0===g&&(g=0);for(var s=m.item(g);s.namespaceURI===a;){g+=1;if(g>=m.length)return c;s=m.item(g)}return s=f(b,c.attDeriv(b,m.item(g)),m,g+1)}function d(b,a,c){c.e[0].a?(b.push(c.e[0].text),a.push(c.e[0].a.ns)):d(b,a,c.e[0]);c.e[1].a?(b.push(c.e[1].text),a.push(c.e[1].a.ns)): -d(b,a,c.e[1])}var a="http://www.w3.org/2000/xmlns/",n,q,g,c,u,t,s,m,A,x,v={type:"notAllowed",nullable:!1,hash:"notAllowed",textDeriv:function(){return v},startTagOpenDeriv:function(){return v},attDeriv:function(){return v},startTagCloseDeriv:function(){return v},endTagDeriv:function(){return v}},w={type:"empty",nullable:!0,hash:"empty",textDeriv:function(){return v},startTagOpenDeriv:function(){return v},attDeriv:function(b,a){return v},startTagCloseDeriv:function(){return w},endTagDeriv:function(){return v}}, -P={type:"text",nullable:!0,hash:"text",textDeriv:function(){return P},startTagOpenDeriv:function(){return v},attDeriv:function(){return v},startTagCloseDeriv:function(){return P},endTagDeriv:function(){return v}},B,E,O;n=p("choice",function(b,a){if(b===v)return a;if(a===v||b===a)return b},function(b,a){var c={},m;r(c,{p1:b,p2:a});a=b=void 0;for(m in c)c.hasOwnProperty(m)&&(void 0===b?b=c[m]:a=void 0===a?c[m]:n(a,c[m]));return function(a,b){return{type:"choice",p1:a,p2:b,nullable:a.nullable||b.nullable, -textDeriv:function(c,m){return n(a.textDeriv(c,m),b.textDeriv(c,m))},startTagOpenDeriv:l(function(c){return n(a.startTagOpenDeriv(c),b.startTagOpenDeriv(c))}),attDeriv:function(c,m){return n(a.attDeriv(c,m),b.attDeriv(c,m))},startTagCloseDeriv:e(function(){return n(a.startTagCloseDeriv(),b.startTagCloseDeriv())}),endTagDeriv:e(function(){return n(a.endTagDeriv(),b.endTagDeriv())})}}(b,a)});q=function(a,b,c){return function(){var m={},g=0;return function(s,d){var e=b&&b(s,d),f,t;if(void 0!==e)return e; -e=s.hash||s.toString();f=d.hash||d.toString();e=a.e.length)return a;var d={name:a.name,e:a.e.slice(0,2)};return l({name:a.name,e:[d].concat(a.e.slice(2))})}function f(a){a=a.split(":",2);var d="",m;1===a.length?a=["",a[0]]:d=a[0];for(m in e)e[m]===d&&(a[0]=m);return a}function q(a,d){for(var e=0,k,c,g=a.name;a.e&&eNode.ELEMENT_NODE;){if(a!==Node.COMMENT_NODE&&(a!==Node.TEXT_NODE||!/^\s+$/.test(f.currentNode.nodeValue)))return[new e("Not allowed node of type "+ -a+".")];a=(d=f.nextSibling())?d.nodeType:0}if(!d)return[new e("Missing element "+b.names)];if(b.names&&-1===b.names.indexOf(h[d.namespaceURI]+":"+d.localName))return[new e("Found "+d.nodeName+" instead of "+b.names+".",d)];if(f.firstChild()){for(n=k(b.e[1],f,d);f.nextSibling();)if(a=f.currentNode.nodeType,!(f.currentNode&&f.currentNode.nodeType===Node.TEXT_NODE&&/^\s+$/.test(f.currentNode.nodeValue)||a===Node.COMMENT_NODE))return[new e("Spurious content.",f.currentNode)];if(f.parentNode()!==d)return[new e("Implementation error.")]}else n= -k(b.e[1],f,d);f.nextSibling();return n}var p,r,h;r=function(b,f,d,a){var n=b.name,q=null;if("text"===n)a:{for(var g=(b=f.currentNode)?b.nodeType:0;b!==d&&3!==g;){if(1===g){q=[new e("Element not allowed here.",b)];break a}g=(b=f.nextSibling())?b.nodeType:0}f.nextSibling();q=null}else if("data"===n)q=null;else if("value"===n)a!==b.text&&(q=[new e("Wrong value, should be '"+b.text+"', not '"+a+"'",d)]);else if("list"===n)q=null;else if("attribute"===n)a:{if(2!==b.e.length)throw"Attribute with wrong # of elements: "+ -b.e.length;n=b.localnames.length;for(q=0;q=n.length)return c;0===k&&(k=0);for(var d=n.item(k);d.namespaceURI===b;){k+=1;if(k>=n.length)return c;d=n.item(k)}return d=e(a,c.attDeriv(a,n.item(k)),n,k+1)}function d(a,b,c){c.e[0].a?(a.push(c.e[0].text),b.push(c.e[0].a.ns)):d(a,b,c.e[0]);c.e[1].a?(a.push(c.e[1].text),b.push(c.e[1].a.ns)): +d(a,b,c.e[1])}var b="http://www.w3.org/2000/xmlns/",s,m,k,c,t,r,x,n,C,y,u={type:"notAllowed",nullable:!1,hash:"notAllowed",textDeriv:function(){return u},startTagOpenDeriv:function(){return u},attDeriv:function(){return u},startTagCloseDeriv:function(){return u},endTagDeriv:function(){return u}},w={type:"empty",nullable:!0,hash:"empty",textDeriv:function(){return u},startTagOpenDeriv:function(){return u},attDeriv:function(a,b){return u},startTagCloseDeriv:function(){return w},endTagDeriv:function(){return u}}, +K={type:"text",nullable:!0,hash:"text",textDeriv:function(){return K},startTagOpenDeriv:function(){return u},attDeriv:function(){return u},startTagCloseDeriv:function(){return K},endTagDeriv:function(){return u}},A,F,O;s=q("choice",function(a,b){if(a===u)return b;if(b===u||a===b)return a},function(a,b){var c={},n;p(c,{p1:a,p2:b});b=a=void 0;for(n in c)c.hasOwnProperty(n)&&(void 0===a?a=c[n]:b=void 0===b?c[n]:s(b,c[n]));return function(a,b){return{type:"choice",p1:a,p2:b,nullable:a.nullable||b.nullable, +textDeriv:function(c,n){return s(a.textDeriv(c,n),b.textDeriv(c,n))},startTagOpenDeriv:f(function(c){return s(a.startTagOpenDeriv(c),b.startTagOpenDeriv(c))}),attDeriv:function(c,n){return s(a.attDeriv(c,n),b.attDeriv(c,n))},startTagCloseDeriv:h(function(){return s(a.startTagCloseDeriv(),b.startTagCloseDeriv())}),endTagDeriv:h(function(){return s(a.endTagDeriv(),b.endTagDeriv())})}}(a,b)});m=function(a,b,c){return function(){var n={},k=0;return function(d,r){var e=b&&b(d,r),m,f;if(void 0!==e)return e; +e=d.hash||d.toString();m=r.hash||r.toString();eNode.ELEMENT_NODE;){if(b!==Node.COMMENT_NODE&&(b!==Node.TEXT_NODE||!/^\s+$/.test(e.currentNode.nodeValue)))return[new h("Not allowed node of type "+ +b+".")];b=(d=e.nextSibling())?d.nodeType:0}if(!d)return[new h("Missing element "+a.names)];if(a.names&&-1===a.names.indexOf(g[d.namespaceURI]+":"+d.localName))return[new h("Found "+d.nodeName+" instead of "+a.names+".",d)];if(e.firstChild()){for(f=l(a.e[1],e,d);e.nextSibling();)if(b=e.currentNode.nodeType,!(e.currentNode&&e.currentNode.nodeType===Node.TEXT_NODE&&/^\s+$/.test(e.currentNode.nodeValue)||b===Node.COMMENT_NODE))return[new h("Spurious content.",e.currentNode)];if(e.parentNode()!==d)return[new h("Implementation error.")]}else f= +l(a.e[1],e,d);e.nextSibling();return f}var q,p,g;p=function(a,e,d,b){var g=a.name,m=null;if("text"===g)a:{for(var k=(a=e.currentNode)?a.nodeType:0;a!==d&&3!==k;){if(1===k){m=[new h("Element not allowed here.",a)];break a}k=(a=e.nextSibling())?a.nodeType:0}e.nextSibling();m=null}else if("data"===g)m=null;else if("value"===g)b!==a.text&&(m=[new h("Wrong value, should be '"+a.text+"', not '"+b+"'",d)]);else if("list"===g)m=null;else if("attribute"===g)a:{if(2!==a.e.length)throw"Attribute with wrong # of elements: "+ +a.e.length;g=a.localnames.length;for(m=0;m=s&&c.push(k(a.substring(b,d)))):"["===a[d]&&(0>=s&&(b=d+1),s+=1),d+=1;return d};xmldom.XPathIterator.prototype.next=function(){};xmldom.XPathIterator.prototype.reset=function(){};a=function(a,g,c){var d,e,s,m;for(d=0;d=f&&c.push(l(a.substring(b,d)))):"["===a[d]&&(0>=f&&(b=d+1),f+=1),d+=1;return d};xmldom.XPathIterator.prototype.next=function(){};xmldom.XPathIterator.prototype.reset=function(){};b=function(b,d,c){var f,r,g,n;for(f=0;f @@ -326,19 +331,19 @@ function(){this.getODFElementsWithXPath=d};return xmldom.XPath}(); @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -odf.Namespaces=function(){function e(e){return k[e]||null}var k={draw:"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",fo:"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",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"},l;e.lookupNamespaceURI=e;l=function(){};l.forEachPrefix=function(e){for(var l in k)k.hasOwnProperty(l)&&e(l,k[l])};l.resolvePrefix=e;l.namespaceMap=k;l.drawns="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0";l.fons="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0";l.officens="urn:oasis:names:tc:opendocument:xmlns:office:1.0";l.presentationns="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0";l.stylens= -"urn:oasis:names:tc:opendocument:xmlns:style:1.0";l.svgns="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0";l.tablens="urn:oasis:names:tc:opendocument:xmlns:table:1.0";l.textns="urn:oasis:names:tc:opendocument:xmlns:text:1.0";l.xlinkns="http://www.w3.org/1999/xlink";l.xmlns="http://www.w3.org/XML/1998/namespace";return l}(); -// Input 25 +odf.Namespaces=function(){function h(f){return l[f]||null}var l={draw:"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",fo:"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",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"},f;h.lookupNamespaceURI=h;f=function(){};f.forEachPrefix=function(f){for(var p in l)l.hasOwnProperty(p)&&f(p,l[p])};f.resolvePrefix=h;f.namespaceMap=l;f.drawns="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0";f.fons="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0";f.officens="urn:oasis:names:tc:opendocument:xmlns:office:1.0";f.presentationns="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0";f.stylens= +"urn:oasis:names:tc:opendocument:xmlns:style:1.0";f.svgns="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0";f.tablens="urn:oasis:names:tc:opendocument:xmlns:table:1.0";f.textns="urn:oasis:names:tc:opendocument:xmlns:text:1.0";f.xlinkns="http://www.w3.org/1999/xlink";f.xmlns="http://www.w3.org/XML/1998/namespace";return f}(); +// Input 26 runtime.loadClass("xmldom.XPath"); -odf.StyleInfo=function(){function e(a,b){for(var c=g[a.localName],m=c&&c[a.namespaceURI],d=m?m.length:0,f,c=0;c - - @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. - - 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: http://gitorious.org/webodf/webodf/ -*/ -odf.OdfUtils=function(){function e(a){var b=a&&a.localName;return("p"===b||"h"===b)&&a.namespaceURI===u}function k(a){return/^[ \t\r\n]+$/.test(a)}function l(a){var b=a&&a.localName;return("span"===b||"p"===b||"h"===b)&&a.namespaceURI===u}function p(a){var b=a&&a.localName,c,d=!1;b&&(c=a.namespaceURI,c===u?d="s"===b||"tab"===b||"line-break"===b:c===t&&(d="frame"===b&&"as-char"===a.getAttributeNS(u,"anchor-type")));return d}function r(a){for(;null!==a.firstChild&&l(a);)a=a.firstChild;return a}function h(a){for(;null!== -a.lastChild&&l(a);)a=a.lastChild;return a}function b(a){for(;!e(a)&&null===a.previousSibling;)a=a.parentNode;return e(a)?null:h(a.previousSibling)}function f(a){for(;!e(a)&&null===a.nextSibling;)a=a.parentNode;return e(a)?null:r(a.nextSibling)}function d(a){for(var c=!1;a;)if(a.nodeType===Node.TEXT_NODE)if(0===a.length)a=b(a);else return!k(a.data.substr(a.length-1,1));else if(p(a)){c=!0;break}else a=b(a);return c}function a(a){var c=!1;for(a=a&&h(a);a;){if(a.nodeType===Node.TEXT_NODE&&0=b.value||"%"===b.unit)?null:b;return b||c(a)};this.parseFoLineHeight=function(a){var b;b=(b=g(a))&&(0>b.value||"%"=== -b.unit)?null:b;return b||c(a)};this.getTextNodes=function(a,b){var c=a.startContainer.ownerDocument,d=c.createRange(),g=[],e;e=c.createTreeWalker(a.commonAncestorContainer.nodeType===Node.TEXT_NODE?a.commonAncestorContainer.parentNode:a.commonAncestorContainer,NodeFilter.SHOW_ALL,function(c){d.selectNodeContents(c);if(!1===b&&c.nodeType===Node.TEXT_NODE){if(0>=a.compareBoundaryPoints(a.START_TO_START,d)&&0<=a.compareBoundaryPoints(a.END_TO_END,d))return NodeFilter.FILTER_ACCEPT}else if(-1===a.compareBoundaryPoints(a.END_TO_START, -d)&&1===a.compareBoundaryPoints(a.START_TO_END,d))return c.nodeType===Node.TEXT_NODE?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT},!1);e.currentNode=a.startContainer.previousSibling||a.startContainer.parentNode;for(c=e.nextNode();c;)g.push(c),c=e.nextNode();d.detach();return g}}; +en:"notes",ans:"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",a:"style-name"},{ens:b,en:"handout-master",ans:"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",a:"style-name"},{ens:b,en:"master-page",ans:"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",a:"style-name"}],"list-style":[{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"list",ans:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",a:"style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"numbered-paragraph", +ans:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",a:"style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"list-item",ans:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",a:"style-override"},{ens:b,en:"style",ans:b,a:"list-style-name"},{ens:b,en:"style",ans:b,a:"data-style-name"},{ens:b,en:"style",ans:b,a:"percentage-data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0",en:"date-time-decl",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0", +en:"creation-date",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"creation-time",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"database-display",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"date",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"editing-duration",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"expression", +ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"meta-field",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"modification-date",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"modification-time",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"print-date",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"print-time",ans:b, +a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"table-formula",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"time",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"user-defined",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"user-field-get",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"user-field-input",ans:b,a:"data-style-name"}, +{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"variable-get",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"variable-input",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"variable-set",ans:b,a:"data-style-name"}],data:[{ens:b,en:"style",ans:b,a:"data-style-name"},{ens:b,en:"style",ans:b,a:"percentage-data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0",en:"date-time-decl",ans:b,a:"data-style-name"}, +{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"creation-date",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"creation-time",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"database-display",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"date",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"editing-duration",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0", +en:"expression",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"meta-field",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"modification-date",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"modification-time",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"print-date",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"print-time", +ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"table-formula",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"time",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"user-defined",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"user-field-get",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"user-field-input",ans:b,a:"data-style-name"}, +{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"variable-get",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"variable-input",ans:b,a:"data-style-name"},{ens:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",en:"variable-set",ans:b,a:"data-style-name"}],"page-layout":[{ens:"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0",en:"notes",ans:b,a:"page-layout-name"},{ens:b,en:"handout-master",ans:b,a:"page-layout-name"},{ens:b,en:"master-page",ans:b, +a:"page-layout-name"}]},k,c=new xmldom.XPath;this.UsedStyleList=function(a,c){var e={};this.uses=function(a){var c=a.localName,d=a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:drawing:1.0","name")||a.getAttributeNS(b,"name");a="style"===c?a.getAttributeNS(b,"family"):"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"===a.namespaceURI?"data":c;return(a=e[a])?0=b.value||"%"===b.unit)?null:b;return b||c(a)};this.parseFoLineHeight=function(a){var b;b=(b=k(a))&&(0>b.value||"%"=== +b.unit)?null:b;return b||c(a)};this.getTextNodes=function(a,b){var c=a.startContainer.ownerDocument,d=c.createRange(),e=[],k;k=c.createTreeWalker(a.commonAncestorContainer.nodeType===Node.TEXT_NODE?a.commonAncestorContainer.parentNode:a.commonAncestorContainer,NodeFilter.SHOW_ALL,function(c){d.selectNodeContents(c);if(!1===b&&c.nodeType===Node.TEXT_NODE){if(0>=a.compareBoundaryPoints(a.START_TO_START,d)&&0<=a.compareBoundaryPoints(a.END_TO_END,d))return NodeFilter.FILTER_ACCEPT}else if(-1===a.compareBoundaryPoints(a.END_TO_START, +d)&&1===a.compareBoundaryPoints(a.START_TO_END,d))return c.nodeType===Node.TEXT_NODE?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT},!1);k.currentNode=a.startContainer.previousSibling||a.startContainer.parentNode;for(c=k.nextNode();c;)e.push(c),c=k.nextNode();d.detach();return e}}; // Input 28 /* @@ -515,49 +478,13 @@ d.push(b),a.setStart(b,0))}function b(a,b){if(a.nodeType===Node.TEXT_NODE)if(0== @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfUtils");runtime.loadClass("xmldom.XPath");runtime.loadClass("core.CSSUnits"); -odf.Style2CSS=function(){function e(a){var b={},c,d;if(!a)return b;for(a=a.firstChild;a;){if(d=a.namespaceURI!==u||"style"!==a.localName&&"default-style"!==a.localName?a.namespaceURI===s&&"list-style"===a.localName?"list":a.namespaceURI!==u||"page-layout"!==a.localName&&"default-page-layout"!==a.localName?void 0:"page":a.getAttributeNS(u,"family"))(c=a.getAttributeNS&&a.getAttributeNS(u,"name"))||(c=""),d=b[d]=b[d]||{},d[c]=a;a=a.nextSibling}return b}function k(a,b){if(!b||!a)return null;if(a[b])return a[b]; -var c,d;for(c in a)if(a.hasOwnProperty(c)&&(d=k(a[c].derivedStyles,b)))return d;return null}function l(a,b,c){var d=b[a],g,e;d&&(g=d.getAttributeNS(u,"parent-style-name"),e=null,g&&(e=k(c,g),!e&&b[g]&&(l(g,b,c),e=b[g],b[g]=null)),e?(e.derivedStyles||(e.derivedStyles={}),e.derivedStyles[a]=d):c[a]=d)}function p(a,b){for(var c in a)a.hasOwnProperty(c)&&(l(c,a,b),a[c]=null)}function r(a,b){var c=x[a],d;if(null===c)return null;d=b?"["+c+'|style-name="'+b+'"]':"["+c+"|style-name]";"presentation"===c&& -(c="draw",d=b?'[presentation|style-name="'+b+'"]':"[presentation|style-name]");return c+"|"+v[a].join(d+","+c+"|")+d}function h(a,b,c){var d=[],g,e;d.push(r(a,b));for(g in c.derivedStyles)if(c.derivedStyles.hasOwnProperty(g))for(e in b=h(a,g,c.derivedStyles[g]),b)b.hasOwnProperty(e)&&d.push(b[e]);return d}function b(a,b,c){if(!a)return null;for(a=a.firstChild;a;){if(a.namespaceURI===b&&a.localName===c)return b=a;a=a.nextSibling}return null}function f(a,b){var c="",d,g;for(d in b)b.hasOwnProperty(d)&& -(d=b[d],(g=a.getAttributeNS(d[0],d[1]))&&(c+=d[2]+":"+g+";"));return c}function d(a){return(a=b(a,u,"text-properties"))?Q.parseFoFontSize(a.getAttributeNS(c,"font-size")):null}function a(a){a=a.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,function(a,b,c,d){return b+b+c+c+d+d});return(a=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(a))?{r:parseInt(a[1],16),g:parseInt(a[2],16),b:parseInt(a[3],16)}:null}function n(a,b,c,d){b='text|list[text|style-name="'+b+'"]';var g=c.getAttributeNS(s,"level"),e;c= -Q.getFirstNonWhitespaceChild(c);c=Q.getFirstNonWhitespaceChild(c);var m;c&&(e=c.attributes,m=e["fo:text-indent"]?e["fo:text-indent"].value:void 0,e=e["fo:margin-left"]?e["fo:margin-left"].value:void 0);m||(m="-0.6cm");c="-"===m.charAt(0)?m.substring(1):"-"+m;for(g=g&&parseInt(g,10);1 text|list-item > text|list",g-=1;g=b+" > text|list-item > *:not(text|list):first-child";void 0!==e&&(e=g+"{margin-left:"+e+";}",a.insertRule(e,a.cssRules.length));d=b+" > text|list-item > *:not(text|list):first-child:before{"+ -d+";";d+="counter-increment:list;";d+="margin-left:"+m+";";d+="width:"+c+";";d+="display:inline-block}";try{a.insertRule(d,a.cssRules.length)}catch(f){throw f;}}function q(e,k,t,l){if("list"===k)for(var p=l.firstChild,r,v;p;){if(p.namespaceURI===s)if(r=p,"list-level-style-number"===p.localName){var N=r;v=N.getAttributeNS(u,"num-format");var x=N.getAttributeNS(u,"num-suffix"),z={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},N=N.getAttributeNS(u,"num-prefix")||"",N=z.hasOwnProperty(v)? -N+(" counter(list, "+z[v]+")"):v?N+("'"+v+"';"):N+" ''";x&&(N+=" '"+x+"'");v="content: "+N+";";n(e,t,r,v)}else"list-level-style-image"===p.localName?(v="content: none;",n(e,t,r,v)):"list-level-style-bullet"===p.localName&&(v="content: '"+r.getAttributeNS(s,"bullet-char")+"';",n(e,t,r,v));p=p.nextSibling}else if("page"===k)if(x=r=t="",p=l.getElementsByTagNameNS(u,"page-layout-properties")[0],r=p.parentNode.parentNode.parentNode.masterStyles,x="",t+=f(p,D),v=p.getElementsByTagNameNS(u,"background-image"), -0c)break;g=g.nextSibling}a.insertBefore(b,g)}}}function r(a){this.OdfContainer=a}function h(a,b,c,d){var g=this;this.size=0;this.type=null;this.name=a;this.container=c;this.onchange=this.onreadystatechange=this.document=this.mimetype=this.url=null;this.EMPTY=0;this.LOADING=1;this.DONE=2;this.state=this.EMPTY;this.load=function(){null!== -d&&(this.mimetype=b,d.loadAsDataURL(a,b,function(a,b){a&&runtime.log(a);g.url=b;if(g.onchange)g.onchange(g);if(g.onstatereadychange)g.onstatereadychange(g)}))};this.abort=function(){}}function b(a){this.length=0;this.item=function(a){}}var f=new odf.StyleInfo,d="urn:oasis:names:tc:opendocument:xmlns:office:1.0",a="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0",n="urn:webodf:names:scope",q="meta settings scripts font-face-decls styles automatic-styles master-styles body".split(" "),g=(new Date).getTime()+ -"_webodf_",c=new core.Base64;r.prototype=new function(){};r.prototype.constructor=r;r.namespaceURI=d;r.localName="document";h.prototype.load=function(){};h.prototype.getUrl=function(){return this.data?"data:;base64,"+c.toBase64(this.data):null};odf.OdfContainer=function t(c,m){function q(a){for(var b=a.firstChild,c;b;)c=b.nextSibling,b.nodeType===Node.ELEMENT_NODE?q(b):b.nodeType===Node.PROCESSING_INSTRUCTION_NODE&&a.removeChild(b),b=c}function k(a,b){for(var c=a&&a.firstChild;c;)c.nodeType===Node.ELEMENT_NODE&& -c.setAttributeNS(n,"scope",b),c=c.nextSibling}function v(a,b){var c=null,d,g,e;if(a)for(c=a.cloneNode(!0),d=c.firstChild;d;)g=d.nextSibling,d.nodeType===Node.ELEMENT_NODE&&(e=d.getAttributeNS(n,"scope"))&&e!==b&&c.removeChild(d),d=g;return c}function w(a){var b=M.rootElement.ownerDocument,c;if(a){q(a.documentElement);try{c=b.importNode(a.documentElement,!0)}catch(d){}}return c}function P(a){M.state=a;if(M.onchange)M.onchange(M);if(M.onstatereadychange)M.onstatereadychange(M)}function B(a){R=null; -M.rootElement=a;a.fontFaceDecls=e(a,d,"font-face-decls");a.styles=e(a,d,"styles");a.automaticStyles=e(a,d,"automatic-styles");a.masterStyles=e(a,d,"master-styles");a.body=e(a,d,"body");a.meta=e(a,d,"meta")}function E(a){a=w(a);var b=M.rootElement;a&&"document-styles"===a.localName&&a.namespaceURI===d?(b.fontFaceDecls=e(a,d,"font-face-decls"),p(b,b.fontFaceDecls),b.styles=e(a,d,"styles"),p(b,b.styles),b.automaticStyles=e(a,d,"automatic-styles"),k(b.automaticStyles,"document-styles"),p(b,b.automaticStyles), -b.masterStyles=e(a,d,"master-styles"),p(b,b.masterStyles),f.prefixStyleNames(b.automaticStyles,g,b.masterStyles)):P(t.INVALID)}function O(a){a=w(a);var b,c,g;if(a&&"document-content"===a.localName&&a.namespaceURI===d){b=M.rootElement;c=e(a,d,"font-face-decls");if(b.fontFaceDecls&&c)for(g=c.firstChild;g;)b.fontFaceDecls.appendChild(g),g=c.firstChild;else c&&(b.fontFaceDecls=c,p(b,c));c=e(a,d,"automatic-styles");k(c,"document-content");if(b.automaticStyles&&c)for(g=c.firstChild;g;)b.automaticStyles.appendChild(g), -g=c.firstChild;else c&&(b.automaticStyles=c,p(b,c));b.body=e(a,d,"body");p(b,b.body)}else P(t.INVALID)}function y(a){a=w(a);var b;a&&("document-meta"===a.localName&&a.namespaceURI===d)&&(b=M.rootElement,b.meta=e(a,d,"meta"),p(b,b.meta))}function J(a){a=w(a);var b;a&&("document-settings"===a.localName&&a.namespaceURI===d)&&(b=M.rootElement,b.settings=e(a,d,"settings"),p(b,b.settings))}function C(b){b=w(b);var c;if(b&&"manifest"===b.localName&&b.namespaceURI===a)for(c=M.rootElement,c.manifest=b,b=c.manifest.firstChild;b;)b.nodeType=== -Node.ELEMENT_NODE&&("file-entry"===b.localName&&b.namespaceURI===a)&&(T[b.getAttributeNS(a,"full-path")]=b.getAttributeNS(a,"media-type")),b=b.nextSibling}function D(a){var b=a.shift(),c,d;b?(c=b[0],d=b[1],S.loadAsDOM(c,function(b,c){d(c);M.state!==t.INVALID&&D(a)})):P(t.DONE)}function G(a){var b="";odf.Namespaces.forEachPrefix(function(a,c){b+=" xmlns:"+a+'="'+c+'"'});return''}function X(){var a=new xmldom.LSSerializer, -b=G("document-meta");a.filter=new l;b+=a.writeToString(M.rootElement.meta,odf.Namespaces.namespaceMap);return b+""}function Q(b,c){var d=document.createElementNS(a,"manifest:file-entry");d.setAttributeNS(a,"manifest:full-path",b);d.setAttributeNS(a,"manifest:media-type",c);return d}function F(){var b=runtime.parseXML(''),c=e(b,a,"manifest"),d=new xmldom.LSSerializer,g;for(g in T)T.hasOwnProperty(g)&&c.appendChild(Q(g, -T[g]));d.filter=new l;return'\n'+d.writeToString(b,odf.Namespaces.namespaceMap)}function K(){var a=new xmldom.LSSerializer,b=G("document-settings");a.filter=new l;b+=a.writeToString(M.rootElement.settings,odf.Namespaces.namespaceMap);return b+""}function H(){var a=odf.Namespaces.namespaceMap,b=new xmldom.LSSerializer,c=v(M.rootElement.automaticStyles,"document-styles"),d=M.rootElement.masterStyles&&M.rootElement.masterStyles.cloneNode(!0), -e=G("document-styles");f.removePrefixFromStyleNames(c,g,d);b.filter=new l(d,c);e+=b.writeToString(M.rootElement.fontFaceDecls,a);e+=b.writeToString(M.rootElement.styles,a);e+=b.writeToString(c,a);e+=b.writeToString(d,a);return e+""}function U(){var a=odf.Namespaces.namespaceMap,b=new xmldom.LSSerializer,c=v(M.rootElement.automaticStyles,"document-content"),d=G("document-content");b.filter=new l(M.rootElement.body,c);d+=b.writeToString(c,a);d+=b.writeToString(M.rootElement.body, -a);return d+""}function Z(a,b){runtime.loadXML(a,function(a,c){if(a)b(a);else{var g=w(c);g&&"document"===g.localName&&g.namespaceURI===d?(B(g),P(t.DONE)):P(t.INVALID)}})}function W(){function a(b,c){var e;c||(c=b);e=document.createElementNS(d,c);g[b]=e;g.appendChild(e)}var b=new core.Zip("",null),c=runtime.byteArrayFromString("application/vnd.oasis.opendocument.text","utf8"),g=M.rootElement,e=document.createElementNS(d,"text");b.save("mimetype",c,!1,new Date);a("meta");a("settings"); -a("scripts");a("fontFaceDecls","font-face-decls");a("styles");a("automaticStyles","automatic-styles");a("masterStyles","master-styles");a("body");g.body.appendChild(e);P(t.DONE);return b}function L(){var a,b=new Date;a=runtime.byteArrayFromString(K(),"utf8");S.save("settings.xml",a,!0,b);a=runtime.byteArrayFromString(X(),"utf8");S.save("meta.xml",a,!0,b);a=runtime.byteArrayFromString(H(),"utf8");S.save("styles.xml",a,!0,b);a=runtime.byteArrayFromString(U(),"utf8");S.save("content.xml",a,!0,b);a=runtime.byteArrayFromString(F(), -"utf8");S.save("META-INF/manifest.xml",a,!0,b)}function I(a,b){L();S.writeAs(a,function(a){b(a)})}var M=this,S,T={},R;this.onstatereadychange=m;this.parts=this.rootElement=this.state=this.onchange=null;this.setRootElement=B;this.getContentElement=function(){var a;R||(a=M.rootElement.body,R=a.getElementsByTagNameNS(d,"text")[0]||a.getElementsByTagNameNS(d,"presentation")[0]||a.getElementsByTagNameNS(d,"spreadsheet")[0]);return R};this.getDocumentType=function(){var a=M.getContentElement();return a&& -a.localName};this.getPart=function(a){return new h(a,T[a],M,S)};this.getPartData=function(a,b){S.load(a,b)};this.createByteArray=function(a,b){L();S.createByteArray(a,b)};this.saveAs=I;this.save=function(a){I(c,a)};this.getUrl=function(){return c};this.state=t.LOADING;this.rootElement=function(a){var b=document.createElementNS(a.namespaceURI,a.localName),c;a=new a;for(c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b}(r);this.parts=new b(this);S=c?new core.Zip(c,function(a,b){S=b;a?Z(c,function(b){a&& -(S.error=a+"\n"+b,P(t.INVALID))}):D([["styles.xml",E],["content.xml",O],["meta.xml",y],["settings.xml",J],["META-INF/manifest.xml",C]])}):W()};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 30 /* Copyright (C) 2012-2013 KO GmbH @@ -592,10 +519,48 @@ a.localName};this.getPart=function(a){return new h(a,T[a],M,S)};this.getPartData @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("core.Base64");runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.OdfContainer"); -odf.FontLoader=function(){function e(k,h,b,f,d){var a,n=0,q;for(q in k)if(k.hasOwnProperty(q)){if(n===b){a=q;break}n+=1}if(!a)return d();h.getPartData(k[a].href,function(g,c){if(g)runtime.log(g);else{var n="@font-face { font-family: '"+(k[a].family||a)+"'; src: url(data:application/x-font-ttf;charset=binary;base64,"+p.convertUTF8ArrayToBase64(c)+') format("truetype"); }';try{f.insertRule(n,f.cssRules.length)}catch(q){runtime.log("Problem inserting rule in CSS: "+runtime.toJson(q)+"\nRule: "+n)}}e(k, -h,b+1,f,d)})}function k(k,h,b){e(k,h,0,b,function(){})}var l=new xmldom.XPath,p=new core.Base64;odf.FontLoader=function(){this.loadFonts=function(e,h){for(var b=e.rootElement.fontFaceDecls;h.cssRules.length;)h.deleteRule(h.cssRules.length-1);if(b){var f={},d,a,n,q;if(b)for(b=l.getODFElementsWithXPath(b,"style:font-face[svg:font-face-src]",odf.Namespaces.resolvePrefix),d=0;d text|list-item > text|list",e-=1;e=b+" > text|list-item > *:not(text|list):first-child";void 0!==k&&(k=e+"{margin-left:"+k+";}",a.insertRule(k,a.cssRules.length));d=b+" > text|list-item > *:not(text|list):first-child:before{"+ +d+";";d+="counter-increment:list;";d+="margin-left:"+n+";";d+="width:"+c+";";d+="display:inline-block}";try{a.insertRule(d,a.cssRules.length)}catch(f){throw f;}}function m(f,r,p,l){if("list"===r)for(var q=l.firstChild,h,u;q;){if(q.namespaceURI===x)if(h=q,"list-level-style-number"===q.localName){var E=h;u=E.getAttributeNS(t,"num-format");var y=E.getAttributeNS(t,"num-suffix"),v={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},E=E.getAttributeNS(t,"num-prefix")||"",E=v.hasOwnProperty(u)? +E+(" counter(list, "+v[u]+")"):u?E+("'"+u+"';"):E+" ''";y&&(E+=" '"+y+"'");u="content: "+E+";";s(f,p,h,u)}else"list-level-style-image"===q.localName?(u="content: none;",s(f,p,h,u)):"list-level-style-bullet"===q.localName&&(u="content: '"+h.getAttributeNS(x,"bullet-char")+"';",s(f,p,h,u));q=q.nextSibling}else if("page"===r)if(y=h=p="",q=l.getElementsByTagNameNS(t,"page-layout-properties")[0],h=q.parentNode.parentNode.parentNode.masterStyles,y="",p+=e(q,G),u=q.getElementsByTagNameNS(t,"background-image"), +0c)break;e=e.nextSibling}a.insertBefore(b,e)}}}function p(a){this.OdfContainer=a}function g(a,b,c,d){var e=this;this.size=0;this.type=null;this.name=a;this.container=c;this.onchange=this.onreadystatechange=this.document=this.mimetype=this.url=null;this.EMPTY=0;this.LOADING=1;this.DONE=2;this.state=this.EMPTY;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)}))};this.abort=function(){}}function a(a){this.length=0;this.item=function(a){}}var e=new odf.StyleInfo,d="urn:oasis:names:tc:opendocument:xmlns:office:1.0",b="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0",s="urn:webodf:names:scope",m="meta settings scripts font-face-decls styles automatic-styles master-styles body".split(" "),k=(new Date).getTime()+ +"_webodf_",c=new core.Base64;p.prototype=new function(){};p.prototype.constructor=p;p.namespaceURI=d;p.localName="document";g.prototype.load=function(){};g.prototype.getUrl=function(){return this.data?"data:;base64,"+c.toBase64(this.data):null};odf.OdfContainer=function r(c,n){function m(a){for(var b=a.firstChild,c;b;)c=b.nextSibling,b.nodeType===Node.ELEMENT_NODE?m(b):b.nodeType===Node.PROCESSING_INSTRUCTION_NODE&&a.removeChild(b),b=c}function l(a,b){for(var c=a&&a.firstChild;c;)c.nodeType===Node.ELEMENT_NODE&& +c.setAttributeNS(s,"scope",b),c=c.nextSibling}function u(a,b){var c=null,d,e,k;if(a)for(c=a.cloneNode(!0),d=c.firstChild;d;)e=d.nextSibling,d.nodeType===Node.ELEMENT_NODE&&(k=d.getAttributeNS(s,"scope"))&&k!==b&&c.removeChild(d),d=e;return c}function w(a){var b=J.rootElement.ownerDocument,c;if(a){m(a.documentElement);try{c=b.importNode(a.documentElement,!0)}catch(d){}}return c}function K(a){J.state=a;if(J.onchange)J.onchange(J);if(J.onstatereadychange)J.onstatereadychange(J)}function A(a){Y=null; +J.rootElement=a;a.fontFaceDecls=h(a,d,"font-face-decls");a.styles=h(a,d,"styles");a.automaticStyles=h(a,d,"automatic-styles");a.masterStyles=h(a,d,"master-styles");a.body=h(a,d,"body");a.meta=h(a,d,"meta")}function F(a){a=w(a);var b=J.rootElement;a&&"document-styles"===a.localName&&a.namespaceURI===d?(b.fontFaceDecls=h(a,d,"font-face-decls"),q(b,b.fontFaceDecls),b.styles=h(a,d,"styles"),q(b,b.styles),b.automaticStyles=h(a,d,"automatic-styles"),l(b.automaticStyles,"document-styles"),q(b,b.automaticStyles), +b.masterStyles=h(a,d,"master-styles"),q(b,b.masterStyles),e.prefixStyleNames(b.automaticStyles,k,b.masterStyles)):K(r.INVALID)}function O(a){a=w(a);var b,c,e;if(a&&"document-content"===a.localName&&a.namespaceURI===d){b=J.rootElement;c=h(a,d,"font-face-decls");if(b.fontFaceDecls&&c)for(e=c.firstChild;e;)b.fontFaceDecls.appendChild(e),e=c.firstChild;else c&&(b.fontFaceDecls=c,q(b,c));c=h(a,d,"automatic-styles");l(c,"document-content");if(b.automaticStyles&&c)for(e=c.firstChild;e;)b.automaticStyles.appendChild(e), +e=c.firstChild;else c&&(b.automaticStyles=c,q(b,c));b.body=h(a,d,"body");q(b,b.body)}else K(r.INVALID)}function z(a){a=w(a);var b;a&&("document-meta"===a.localName&&a.namespaceURI===d)&&(b=J.rootElement,b.meta=h(a,d,"meta"),q(b,b.meta))}function H(a){a=w(a);var b;a&&("document-settings"===a.localName&&a.namespaceURI===d)&&(b=J.rootElement,b.settings=h(a,d,"settings"),q(b,b.settings))}function D(a){a=w(a);var c;if(a&&"manifest"===a.localName&&a.namespaceURI===b)for(c=J.rootElement,c.manifest=a,a=c.manifest.firstChild;a;)a.nodeType=== +Node.ELEMENT_NODE&&("file-entry"===a.localName&&a.namespaceURI===b)&&(Q[a.getAttributeNS(b,"full-path")]=a.getAttributeNS(b,"media-type")),a=a.nextSibling}function G(a){var b=a.shift(),c,d;b?(c=b[0],d=b[1],P.loadAsDOM(c,function(b,c){d(c);J.state!==r.INVALID&&G(a)})):K(r.DONE)}function T(a){var b="";odf.Namespaces.forEachPrefix(function(a,c){b+=" xmlns:"+a+'="'+c+'"'});return''}function ba(){var a=new xmldom.LSSerializer, +b=T("document-meta");a.filter=new f;b+=a.writeToString(J.rootElement.meta,odf.Namespaces.namespaceMap);return b+""}function V(a,c){var d=document.createElementNS(b,"manifest:file-entry");d.setAttributeNS(b,"manifest:full-path",a);d.setAttributeNS(b,"manifest:media-type",c);return d}function ca(){var a=runtime.parseXML(''),c=h(a,b,"manifest"),d=new xmldom.LSSerializer,e;for(e in Q)Q.hasOwnProperty(e)&&c.appendChild(V(e, +Q[e]));d.filter=new f;return'\n'+d.writeToString(a,odf.Namespaces.namespaceMap)}function U(){var a=new xmldom.LSSerializer,b=T("document-settings");a.filter=new f;b+=a.writeToString(J.rootElement.settings,odf.Namespaces.namespaceMap);return b+""}function W(){var a=odf.Namespaces.namespaceMap,b=new xmldom.LSSerializer,c=u(J.rootElement.automaticStyles,"document-styles"),d=J.rootElement.masterStyles&&J.rootElement.masterStyles.cloneNode(!0), +n=T("document-styles");e.removePrefixFromStyleNames(c,k,d);b.filter=new f(d,c);n+=b.writeToString(J.rootElement.fontFaceDecls,a);n+=b.writeToString(J.rootElement.styles,a);n+=b.writeToString(c,a);n+=b.writeToString(d,a);return n+""}function N(){var a=odf.Namespaces.namespaceMap,b=new xmldom.LSSerializer,c=u(J.rootElement.automaticStyles,"document-content"),d=T("document-content");b.filter=new f(J.rootElement.body,c);d+=b.writeToString(c,a);d+=b.writeToString(J.rootElement.body, +a);return d+""}function S(a,b){runtime.loadXML(a,function(a,c){if(a)b(a);else{var e=w(c);e&&"document"===e.localName&&e.namespaceURI===d?(A(e),K(r.DONE)):K(r.INVALID)}})}function R(){function a(b,c){var k;c||(c=b);k=document.createElementNS(d,c);e[b]=k;e.appendChild(k)}var b=new core.Zip("",null),c=runtime.byteArrayFromString("application/vnd.oasis.opendocument.text","utf8"),e=J.rootElement,k=document.createElementNS(d,"text");b.save("mimetype",c,!1,new Date);a("meta");a("settings"); +a("scripts");a("fontFaceDecls","font-face-decls");a("styles");a("automaticStyles","automatic-styles");a("masterStyles","master-styles");a("body");e.body.appendChild(k);K(r.DONE);return b}function I(){var a,b=new Date;a=runtime.byteArrayFromString(U(),"utf8");P.save("settings.xml",a,!0,b);a=runtime.byteArrayFromString(ba(),"utf8");P.save("meta.xml",a,!0,b);a=runtime.byteArrayFromString(W(),"utf8");P.save("styles.xml",a,!0,b);a=runtime.byteArrayFromString(N(),"utf8");P.save("content.xml",a,!0,b);a= +runtime.byteArrayFromString(ca(),"utf8");P.save("META-INF/manifest.xml",a,!0,b)}function B(a,b){I();P.writeAs(a,function(a){b(a)})}var J=this,P,Q={},Y;this.onstatereadychange=n;this.parts=this.rootElement=this.state=this.onchange=null;this.setRootElement=A;this.getContentElement=function(){var a;Y||(a=J.rootElement.body,Y=a.getElementsByTagNameNS(d,"text")[0]||a.getElementsByTagNameNS(d,"presentation")[0]||a.getElementsByTagNameNS(d,"spreadsheet")[0]);return Y};this.getDocumentType=function(){var a= +J.getContentElement();return a&&a.localName};this.getPart=function(a){return new g(a,Q[a],J,P)};this.getPartData=function(a,b){P.load(a,b)};this.createByteArray=function(a,b){I();P.createByteArray(a,b)};this.saveAs=B;this.save=function(a){B(c,a)};this.getUrl=function(){return c};this.state=r.LOADING;this.rootElement=function(a){var b=document.createElementNS(a.namespaceURI,a.localName),c;a=new a;for(c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b}(p);this.parts=new a(this);P=c?new core.Zip(c,function(a, +b){P=b;a?S(c,function(b){a&&(P.error=a+"\n"+b,K(r.INVALID))}):G([["styles.xml",F],["content.xml",O],["meta.xml",z],["settings.xml",H],["META-INF/manifest.xml",D]])}):R()};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 31 /* @@ -631,16 +596,10 @@ a=l.getODFElementsWithXPath(a,"svg:font-face-src/svg:font-face-uri",odf.Namespac @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfContainer");runtime.loadClass("odf.StyleInfo");runtime.loadClass("odf.OdfUtils");runtime.loadClass("odf.TextStyleApplicator"); -odf.Formatting=function(){function e(a,b){Object.keys(b).forEach(function(c){try{a[c]=b[c].constructor===Object?e(a[c],b[c]):b[c]}catch(d){a[c]=b[c]}});return a}function k(b,d,e){var f;e=e||[a.rootElement.automaticStyles,a.rootElement.styles];for(f=e.shift();f;){for(f=f.firstChild;f;){if(f.nodeType===Node.ELEMENT_NODE&&(f.namespaceURI===g&&"style"===f.localName&&f.getAttributeNS(g,"family")===d&&f.getAttributeNS(g,"name")===b||"list-style"===d&&f.namespaceURI===c&&"list-style"===f.localName&&f.getAttributeNS(g, -"name")===b))return f;f=f.nextSibling}f=e.shift()}return null}function l(a){for(var b={},c=a.firstChild;c;){if(c.nodeType===Node.ELEMENT_NODE&&c.namespaceURI===g)for(b[c.nodeName]={},a=0;a text|list-item > *:first-child:before {";if(B=F.getAttributeNS(v,"style-name")){F=p[B];K=y.getFirstNonWhitespaceChild(F);F=void 0;if("list-level-style-number"===K.localName){F=K.getAttributeNS(m,"num-format");B=K.getAttributeNS(m,"num-suffix");var L="",L={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"}, -$=void 0,$=K.getAttributeNS(m,"num-prefix")||"",$=L.hasOwnProperty(F)?$+(" counter(list, "+L[F]+")"):F?$+("'"+F+"';"):$+" ''";B&&($+=" '"+B+"'");F=L="content: "+$+";"}else"list-level-style-image"===K.localName?F="content: none;":"list-level-style-bullet"===K.localName&&(F="content: '"+K.getAttributeNS(v,"bullet-char")+"';");K=F}if(Q){for(F=k[Q];F;)Q=F,F=k[Q];z+="counter-increment:"+Q+";";K?(K=K.replace("list",Q),z+=K):z+="content:counter("+Q+");"}else Q="",K?(K=K.replace("list",w),z+=K):z+="content: counter("+ -w+");",z+="counter-increment:"+w+";",e.insertRule("text|list#"+w+" {counter-reset:"+w+"}",e.cssRules.length);z+="}";k[w]=Q;z&&e.insertRule(z,e.cssRules.length)}q.insertBefore(J,q.firstChild);A();if(!c&&(e=[U],N.hasOwnProperty("statereadychange")))for(q=N.statereadychange,K=0;K @@ -741,11 +680,40 @@ odf.CommandLineTools=function(){this.roundTrip=function(e,k,l){new odf.OdfContai @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.Operation=function(){};ops.Operation.prototype.init=function(e){};ops.Operation.prototype.execute=function(e){};ops.Operation.prototype.spec=function(){}; +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"); +odf.OdfCanvas=function(){function h(){function a(d){c=!0;runtime.setTimeout(function(){try{d()}catch(e){runtime.log(e)}c=!1;0 text|list-item > *:first-child:before {";if(E=A.getAttributeNS(u,"style-name")){A=q[E];B=z.getFirstNonWhitespaceChild(A);A=void 0;if("list-level-style-number"===B.localName){A=B.getAttributeNS(n,"num-format");E=B.getAttributeNS(n,"num-suffix");var H="",H={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"}, +I=void 0,I=B.getAttributeNS(n,"num-prefix")||"",I=H.hasOwnProperty(A)?I+(" counter(list, "+H[A]+")"):A?I+("'"+A+"';"):I+" ''";E&&(I+=" '"+E+"'");A=H="content: "+I+";"}else"list-level-style-image"===B.localName?A="content: none;":"list-level-style-bullet"===B.localName&&(A="content: '"+B.getAttributeNS(u,"bullet-char")+"';");B=A}if(v){for(A=h[v];A;)v=A,A=h[v];L+="counter-increment:"+v+";";B?(B=B.replace("list",v),L+=B):L+="content:counter("+v+");"}else v="",B?(B=B.replace("list",w),L+=B):L+="content: counter("+ +w+");",L+="counter-increment:"+w+";",k.insertRule("text|list#"+w+" {counter-reset:"+w+"}",k.cssRules.length);L+="}";h[w]=v;L&&k.insertRule(L,k.cssRules.length)}m.insertBefore(D,m.firstChild);C();if(!c&&(k=[S],$.hasOwnProperty("statereadychange")))for(m=$.statereadychange,B=0;B + Copyright (C) 2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -777,11 +745,11 @@ ops.Operation=function(){};ops.Operation.prototype.init=function(e){};ops.Operat @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.OpAddCursor=function(){var e,k;this.init=function(l){e=l.memberid;k=l.timestamp};this.execute=function(k){var p=k.getCursor(e);if(p)return!1;p=new ops.OdtCursor(e,k);k.addCursor(p);k.emit(ops.OdtDocument.signalCursorAdded,p);return!0};this.spec=function(){return{optype:"AddCursor",memberid:e,timestamp:k}}}; +ops.Server=function(){};ops.Server.prototype.connect=function(h,l){};ops.Server.prototype.networkStatus=function(){};ops.Server.prototype.login=function(h,l,f,q){}; // Input 36 /* - Copyright (C) 2012-2013 KO GmbH + Copyright (C) 2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -813,14 +781,12 @@ ops.OpAddCursor=function(){var e,k;this.init=function(l){e=l.memberid;k=l.timest @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("odf.OdfUtils"); -ops.OpApplyStyle=function(){function e(b){var a=0<=h?r+h:r,e=b.getIteratorAtPosition(0<=h?r:r+h),a=h?b.getIteratorAtPosition(a):e;b=b.getDOM().createRange();b.setStart(e.container(),e.unfilteredDomOffset());b.setEnd(a.container(),a.unfilteredDomOffset());return b}function k(b){var a=b.commonAncestorContainer,e;e=Array.prototype.slice.call(a.getElementsByTagNameNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","p"));for(e=e.concat(Array.prototype.slice.call(a.getElementsByTagNameNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","h")));a&& -!f.isParagraph(a);)a=a.parentNode;a&&e.push(a);return e.filter(function(a){var g=a.nodeType===Node.TEXT_NODE?a.length:a.childNodes.length;return 0>=b.comparePoint(a,0)&&0<=b.comparePoint(a,g)})}var l,p,r,h,b,f=new odf.OdfUtils;this.init=function(d){l=d.memberid;p=d.timestamp;r=d.position;h=d.length;b=d.info};this.execute=function(d){var a=e(d),f=k(a);d.getFormatting().applyStyle(a,b);a.detach();d.getOdfCanvas().refreshCSS();f.forEach(function(a){d.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a, -memberId:l,timeStamp:p})});return!0};this.spec=function(){return{optype:"ApplyStyle",memberid:l,timestamp:p,position:r,length:h,info:b}}}; +ops.NowjsServer=function(){var h;this.getNowObject=function(){return h};this.connect=function(l,f){function q(){"unavailable"===h.networkStatus?(runtime.log("connection to server unavailable."),f("unavailable")):"ready"!==h.networkStatus?p>l?(runtime.log("connection to server timed out."),f("timeout")):(p+=100,runtime.getWindow().setTimeout(q,100)):(runtime.log("connection to collaboration server established."),f("ready"))}var p=0;h||(h=runtime.getVariable("now"),void 0===h&&(h={networkStatus:"unavailable"}), +q())};this.networkStatus=function(){return h?h.networkStatus:"unavailable"};this.login=function(l,f,q,p){h?h.login(l,f,q,p):p("Not connected to server")}}; // Input 37 /* - Copyright (C) 2012-2013 KO GmbH + Copyright (C) 2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -852,7 +818,10 @@ memberId:l,timeStamp:p})});return!0};this.spec=function(){return{optype:"ApplySt @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.OpRemoveCursor=function(){var e,k;this.init=function(l){e=l.memberid;k=l.timestamp};this.execute=function(k){return k.removeCursor(e)?!0:!1};this.spec=function(){return{optype:"RemoveCursor",memberid:e,timestamp:k}}}; +runtime.loadClass("core.Base64");runtime.loadClass("core.ByteArrayWriter"); +ops.PullBoxServer=function(h){function l(f,a){var e=new XMLHttpRequest,d=new core.ByteArrayWriter("utf8");runtime.log("Sending message to server: "+f);d.appendString(f);d=d.getByteArray();e.open("POST",h.url,!0);e.onreadystatechange=function(){4===e.readyState&&((200>e.status||300<=e.status)&&0===e.status&&runtime.log("Status "+String(e.status)+": "+e.responseText||e.statusText),a(e.responseText))};d=d.buffer&&!e.sendAsBinary?d.buffer:runtime.byteArrayToString(d,"binary");try{e.sendAsBinary?e.sendAsBinary(d): +e.send(d)}catch(b){runtime.log("Problem with calling server: "+b+" "+d),a(b.message)}}var f=this,q,p=new core.Base64;h=h||{};h.url=h.url||"/WSER";this.call=l;this.getBase64=function(){return p};this.getToken=function(){return q};this.connect=function(f,a){a("ready")};this.networkStatus=function(){return"ready"};this.login=function(g,a,e,d){l("login:"+p.toBase64(g)+":"+p.toBase64(a),function(a){var g=runtime.fromJson(a);runtime.log("Login reply: "+a);g.hasOwnProperty("token")?(q=g.token,runtime.log("Caching token: "+ +f.getToken()),e(g)):d(a)})}}; // Input 38 /* @@ -888,13 +857,43 @@ ops.OpRemoveCursor=function(){var e,k;this.init=function(l){e=l.memberid;k=l.tim @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.OpMoveCursor=function(){var e,k,l,p;this.init=function(r){e=r.memberid;k=r.timestamp;l=r.position;p=r.length||0};this.execute=function(k){var h=k.getCursor(e),b=k.getCursorPosition(e),f=k.getPositionFilter(),d=l-b;if(!h)return!1;b=h.getStepCounter();d=0d?-b.countBackwardSteps(-d,f):0;h.move(d);p&&(f=0p?-b.countBackwardSteps(-p,f):0,h.move(f,!0));k.emit(ops.OdtDocument.signalCursorMoved,h);return!0};this.spec=function(){return{optype:"MoveCursor", -memberid:e,timestamp:k,position:l,length:p}}}; +ops.Operation=function(){};ops.Operation.prototype.init=function(h){};ops.Operation.prototype.transform=function(h,l){};ops.Operation.prototype.execute=function(h){};ops.Operation.prototype.spec=function(){}; // Input 39 -ops.OpInsertTable=function(){function e(b,d){var g;if(1===a.length)g=a[0];else if(3===a.length)switch(b){case 0:g=a[0];break;case p-1:g=a[2];break;default:g=a[1]}else g=a[b];if(1===g.length)return g[0];if(3===g.length)switch(d){case 0:return g[0];case r-1:return g[2];default:return g[1]}return g[d]}var k,l,p,r,h,b,f,d,a;this.init=function(e){k=e.memberid;l=e.timestamp;h=e.position;p=e.initialRows;r=e.initialColumns;b=e.tableName;f=e.tableStyleName;d=e.tableColumnStyleName;a=e.tableCellStyleMatrix}; -this.execute=function(a){var q=a.getPositionInTextNode(h),g=a.getRootNode();if(q){var c=a.getDOM(),u=c.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table"),t=c.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table-column"),s,m,A,x;f&&u.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:style-name",f);b&&u.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:name",b);t.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0", -"table:number-columns-repeated",r);d&&t.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:style-name",d);u.appendChild(t);for(A=0;A + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +ops.OpAddCursor=function(){var h=this,l,f;this.init=function(h){l=h.memberid;f=h.timestamp};this.transform=function(f,l){return[h]};this.execute=function(f){var h=f.getCursor(l);if(h)return!1;h=new ops.OdtCursor(l,f);f.addCursor(h);f.emit(ops.OdtDocument.signalCursorAdded,h);return!0};this.spec=function(){return{optype:"AddCursor",memberid:l,timestamp:f}}}; // Input 40 /* @@ -930,9 +929,10 @@ this.execute=function(a){var q=a.getPositionInTextNode(h),g=a.getRootNode();if(q @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.OpInsertText=function(){function e(e,b){var f=b.parentNode,d=b.nextSibling,a=[];e.getCursors().forEach(function(d){var e=d.getSelectedRange();!e||e.startContainer!==b&&e.endContainer!==b||a.push({cursor:d,startContainer:e.startContainer,startOffset:e.startOffset,endContainer:e.endContainer,endOffset:e.endOffset})});f.removeChild(b);f.insertBefore(b,d);a.forEach(function(a){var b=a.cursor.getSelectedRange();b.setStart(a.startContainer,a.startOffset);b.setEnd(a.endContainer,a.endOffset)})}var k, -l,p,r;this.init=function(e){k=e.memberid;l=e.timestamp;p=e.position;r=e.text};this.execute=function(h){var b,f=r.split(" "),d,a,n,q,g=h.getRootNode().ownerDocument,c;if(b=h.getPositionInTextNode(p,k)){a=b.textNode;n=a.parentNode;q=a.nextSibling;d=b.offset;b=h.getParagraphElement(a);d!==a.length&&(q=a.splitText(d));0=a.comparePoint(d,0)&&0<=a.comparePoint(d,c)})}var f,q,p,g,a,e=new odf.OdfUtils,d=new core.DomUtils;this.init=function(b){f=b.memberid;q=b.timestamp;p=parseInt(b.position,10);g=parseInt(b.length,10);a=b.info};this.transform=function(a,d){return null};this.execute=function(b){var d=h(b),e=l(d);b.getFormatting().applyStyle(f,d,a);d.detach();b.getOdfCanvas().refreshCSS(); +e.forEach(function(a){b.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a,memberId:f,timeStamp:q})});return!0};this.spec=function(){return{optype:"ApplyStyle",memberid:f,timestamp:q,position:p,length:g,info:a}}}; // Input 41 /* @@ -968,11 +968,7 @@ q),0=h.textNode.length?null:h.textNode.splitText(h.offset));for(h=h.textNode;h!==f;)if(h=h.parentNode,d=h.cloneNode(!1),n){for(a&& -d.appendChild(a);n.nextSibling;)d.appendChild(n.nextSibling);h.parentNode.insertBefore(d,h.nextSibling);n=h;a=d}else h.parentNode.insertBefore(d,h),n=d,a=h;p.isListItem(a)&&(a=a.childNodes[0]);r.getOdfCanvas().refreshSize();r.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:b,memberId:e,timeStamp:k});r.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a,memberId:e,timeStamp:k});return!0};this.spec=function(){return{optype:"SplitParagraph",memberid:e,timestamp:k,position:l}}}; +ops.OpMoveCursor=function(){var h=this,l,f,q,p;this.init=function(g){l=g.memberid;f=g.timestamp;q=parseInt(g.position,10);p=void 0!==g.length?parseInt(g.length,10):0};this.merge=function(g){return"MoveCursor"===g.optype&&g.memberid===l?(q=g.position,p=g.length,f=g.timestamp,!0):!1};this.transform=function(f,a){var e=f.spec(),d=e.optype,b=[h];"RemoveText"===d?e.position+e.length<=q?q-=e.length:e.positionb?-e.countBackwardSteps(-b,d):0;a.move(b);p&&(d=0p?-e.countBackwardSteps(-p,d):0,a.move(d,!0));f.emit(ops.OdtDocument.signalCursorMoved,a);return!0};this.spec=function(){return{optype:"MoveCursor",memberid:l, +timestamp:f,position:q,length:p}}}; // Input 43 -/* - - Copyright (C) 2012-2013 KO GmbH - - @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. - - 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: http://gitorious.org/webodf/webodf/ -*/ -ops.OpSetParagraphStyle=function(){var e,k,l,p;this.init=function(r){e=r.memberid;k=r.timestamp;l=r.position;p=r.styleName};this.execute=function(r){var h;if(h=r.getPositionInTextNode(l))if(h=r.getParagraphElement(h.textNode))return""!==p?h.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","text:style-name",p):h.removeAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","style-name"),r.getOdfCanvas().refreshSize(),r.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:h, -timeStamp:k,memberId:e}),!0;return!1};this.spec=function(){return{optype:"SetParagraphStyle",memberid:e,timestamp:k,position:l,styleName:p}}}; +ops.OpInsertTable=function(){function h(a,b){var c;if(1===s.length)c=s[0];else if(3===s.length)switch(a){case 0:c=s[0];break;case p-1:c=s[2];break;default:c=s[1]}else c=s[a];if(1===c.length)return c[0];if(3===c.length)switch(b){case 0:return c[0];case g-1:return c[2];default:return c[1]}return c[b]}var l=this,f,q,p,g,a,e,d,b,s;this.init=function(m){f=m.memberid;q=m.timestamp;a=parseInt(m.position,10);p=parseInt(m.initialRows,10);g=parseInt(m.initialColumns,10);e=m.tableName;d=m.tableStyleName;b=m.tableColumnStyleName; +s=m.tableCellStyleMatrix};this.transform=function(b,d){var c=b.spec(),e=c.optype,f=[l];if("InsertTable"===e)f=null;else if("SplitParagraph"===e)if(c.position=a.textNode.length?null:a.textNode.splitText(a.offset));for(a=a.textNode;a!==d;)if(a=a.parentNode,b=a.cloneNode(!1),m){for(h&&b.appendChild(h);m.nextSibling;)b.appendChild(m.nextSibling);a.parentNode.insertBefore(b, +a.nextSibling);m=a;h=b}else a.parentNode.insertBefore(b,a),m=b,h=a;p.isListItem(h)&&(h=h.childNodes[0]);g.fixCursorPositions(l);g.getOdfCanvas().refreshSize();g.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:e,memberId:l,timeStamp:f});g.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:h,memberId:l,timeStamp:f});return!0};this.spec=function(){return{optype:"SplitParagraph",memberid:l,timestamp:f,position:q}}}; // Input 47 /* @@ -1198,25 +1166,219 @@ ops.OpDeleteParagraphStyle=function(){var e,k,l;this.init=function(p){e=p.member @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpApplyStyle");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");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.OpCloneParagraphStyle");runtime.loadClass("ops.OpDeleteParagraphStyle"); -ops.OperationFactory=function(){this.create=function(e){var k=null;"AddCursor"===e.optype?k=new ops.OpAddCursor:"ApplyStyle"===e.optype?k=new ops.OpApplyStyle:"InsertTable"===e.optype?k=new ops.OpInsertTable:"InsertText"===e.optype?k=new ops.OpInsertText:"RemoveText"===e.optype?k=new ops.OpRemoveText:"SplitParagraph"===e.optype?k=new ops.OpSplitParagraph:"SetParagraphStyle"===e.optype?k=new ops.OpSetParagraphStyle:"UpdateParagraphStyle"===e.optype?k=new ops.OpUpdateParagraphStyle:"CloneParagraphStyle"=== -e.optype?k=new ops.OpCloneParagraphStyle:"DeleteParagraphStyle"===e.optype?k=new ops.OpDeleteParagraphStyle:"MoveCursor"===e.optype?k=new ops.OpMoveCursor:"RemoveCursor"===e.optype&&(k=new ops.OpRemoveCursor);k&&k.init(e);return k}}; +ops.OpSetParagraphStyle=function(){var h=this,l,f,q,p;this.init=function(g){l=g.memberid;f=g.timestamp;q=g.position;p=g.styleName};this.transform=function(f,a){var e=f.spec();"DeleteParagraphStyle"===e.optype&&e.styleName===p&&(p="");return[h]};this.execute=function(g){var a;if(a=g.getPositionInTextNode(q))if(a=g.getParagraphElement(a.textNode))return""!==p?a.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","text:style-name",p):a.removeAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0", +"style-name"),g.getOdfCanvas().refreshSize(),g.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a,timeStamp:f,memberId:l}),!0;return!1};this.spec=function(){return{optype:"SetParagraphStyle",memberid:l,timestamp:f,position:q,styleName:p}}}; // Input 48 -runtime.loadClass("core.Cursor");runtime.loadClass("core.PositionIterator");runtime.loadClass("core.PositionFilter");runtime.loadClass("core.LoopWatchDog");runtime.loadClass("odf.OdfUtils"); -gui.SelectionMover=function(e,k){function l(){c.setUnfilteredPosition(e.getNode(),0);return c}function p(a,b,c){var d;c.setStart(a,b);d=c.getClientRects()[0];if(!d)if(d={},a.childNodes[b-1]){c.setStart(a,b-1);c.setEnd(a,b);b=c.getClientRects()[0];if(!b){for(c=b=0;a&&a.nodeType===Node.ELEMENT_NODE;)b+=a.offsetLeft-a.scrollLeft,c+=a.offsetTop-a.scrollTop,a=a.parentNode;b={top:c,left:b}}d.top=b.top;d.left=b.right;d.bottom=b.bottom}else a.nodeType===Node.TEXT_NODE?(a.previousSibling&&(d=a.previousSibling.getClientRects()[0]), -d||(c.setStart(a,0),c.setEnd(a,b),d=c.getClientRects()[0])):d=a.getClientRects()[0];return{top:d.top,left:d.left,bottom:d.bottom}}function r(a,b,c){var d=a,g=l(),f,h=k.ownerDocument.createRange(),n=e.getSelectedRange()?e.getSelectedRange().cloneRange():k.ownerDocument.createRange(),q;for(f=p(e.getNode(),0,h);0a?-1:1;for(a=Math.abs(a);0h?n.previousPosition():n.nextPosition());)if(U.check(),1===f.acceptPosition(n)&&(r+=1,q=n.container(),G=p(q,n.unfilteredDomOffset(),H),G.top!==Q)){if(G.top!==K&& -K!==Q)break;K=G.top;G=Math.abs(F-G.left);if(null===t||Ga?(f=c.previousPosition,n=-1):(f=c.nextPosition,n=1);for(h=p(c.container(),c.unfilteredDomOffset(),r);f.call(c);)if(b.acceptPosition(c)===NodeFilter.FILTER_ACCEPT){if(g.getParagraphElement(c.getCurrentNode())!== -d)break;q=p(c.container(),c.unfilteredDomOffset(),r);if(q.bottom!==h.bottom&&(h=q.top>=h.top&&q.bottomh.bottom,!h))break;e+=n;h=q}r.detach();return e}function n(a,b){for(var c=0,d;a.parentNode!==b;)runtime.assert(null!==a.parentNode,"parent is null"),a=a.parentNode;for(d=b.firstChild;d!==a;)c+=1,d=d.nextSibling;return c}function q(a,b,c){runtime.assert(null!==a,"SelectionMover.countStepsToPosition called with element===null");var d=l(),e=d.container(),g=d.unfilteredDomOffset(), -f=0,h=new core.LoopWatchDog(1E3);d.setUnfilteredPosition(a,b);a=d.container();runtime.assert(Boolean(a),"SelectionMover.countStepsToPosition: positionIterator.container() returned null");b=d.unfilteredDomOffset();d.setUnfilteredPosition(e,g);var e=a,g=b,k=d.container(),p=d.unfilteredDomOffset();if(e===k)e=p-g;else{var q=e.compareDocumentPosition(k);2===q?q=-1:4===q?q=1:10===q?(g=n(e,k),q=ge)for(;d.nextPosition()&&(h.check(),1===c.acceptPosition(d)&&(f+=1),d.container()!== -a||d.unfilteredDomOffset()!==b););else if(0 + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +ops.OpUpdateParagraphStyle=function(){function h(a,b,d){var e,f,g;for(e=0;e=e&&(f=-p.movePointBackward(-e,b));l.handleUpdate();return f};this.handleUpdate=function(){};this.getStepCounter=function(){return p.getStepCounter()};this.getMemberId=function(){return e};this.getNode=function(){return r.getNode()};this.getAnchorNode=function(){return r.getAnchorNode()};this.getSelectedRange=function(){return r.getSelectedRange()}; -this.getOdtDocument=function(){return k};r=new core.Cursor(k.getDOM(),e);p=new gui.SelectionMover(r,k.getRootNode())}; +/* + + Copyright (C) 2012-2013 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +ops.OpCloneParagraphStyle=function(){var h=this,l,f,q,p,g;this.init=function(a){l=a.memberid;f=a.timestamp;q=a.styleName;p=a.newStyleName;g=a.newStyleDisplayName};this.transform=function(a,e){var d=a.spec();return"UpdateParagraphStyle"!==d.optype&&"DeleteParagraphStyle"!==d.optype||d.styleName!==q?[h]:null};this.execute=function(a){var e=a.getParagraphStyleElement(q),d;if(!e)return!1;d=e.cloneNode(!0);d.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:style:1.0","style:name",p);g?d.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:style:1.0", +"style:display-name",g):d.removeAttributeNS("urn:oasis:names:tc:opendocument:xmlns:style:1.0","display-name");e.parentNode.appendChild(d);a.getOdfCanvas().refreshCSS();a.emit(ops.OdtDocument.signalStyleCreated,p);return!0};this.spec=function(){return{optype:"CloneParagraphStyle",memberid:l,timestamp:f,styleName:q,newStyleName:p,newStyleDisplayName:g}}}; // Input 50 +/* + + Copyright (C) 2012-2013 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +ops.OpDeleteParagraphStyle=function(){var h=this,l,f,q;this.init=function(h){l=h.memberid;f=h.timestamp;q=h.styleName};this.transform=function(f,g){var a=f.spec(),e=a.optype;if("DeleteParagraphStyle"===e){if(a.styleName===q)return[]}else if("SetParagraphStyle"===e&&a.styleName===q)return a.styleName="",e=new ops.OpSetParagraphStyle,e.init(a),[e,h];return[h]};this.execute=function(f){var g=f.getParagraphStyleElement(q);if(!g)return!1;g.parentNode.removeChild(g);f.getOdfCanvas().refreshCSS();f.emit(ops.OdtDocument.signalStyleDeleted, +q);return!0};this.spec=function(){return{optype:"DeleteParagraphStyle",memberid:l,timestamp:f,styleName:q}}}; +// Input 51 +/* + + Copyright (C) 2012-2013 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpApplyStyle");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");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.OpCloneParagraphStyle");runtime.loadClass("ops.OpDeleteParagraphStyle"); +ops.OperationFactory=function(){function h(f){return function(){return new f}}var l;this.register=function(f,h){l[f]=h};this.create=function(f){var h=null,p=l[f.optype];p&&(h=p(f),h.init(f));return h};l={AddCursor:h(ops.OpAddCursor),ApplyStyle:h(ops.OpApplyStyle),InsertTable:h(ops.OpInsertTable),InsertText:h(ops.OpInsertText),RemoveText:h(ops.OpRemoveText),SplitParagraph:h(ops.OpSplitParagraph),SetParagraphStyle:h(ops.OpSetParagraphStyle),UpdateParagraphStyle:h(ops.OpUpdateParagraphStyle),CloneParagraphStyle:h(ops.OpCloneParagraphStyle), +DeleteParagraphStyle:h(ops.OpDeleteParagraphStyle),MoveCursor:h(ops.OpMoveCursor),RemoveCursor:h(ops.OpRemoveCursor)}}; +// Input 52 +runtime.loadClass("core.Cursor");runtime.loadClass("core.PositionIterator");runtime.loadClass("core.PositionFilter");runtime.loadClass("core.LoopWatchDog");runtime.loadClass("odf.OdfUtils"); +gui.SelectionMover=function(h,l){function f(){c.setUnfilteredPosition(h.getNode(),0);return c}function q(a,b,c){var d;c.setStart(a,b);d=c.getClientRects()[0];if(!d)if(d={},a.childNodes[b-1]){c.setStart(a,b-1);c.setEnd(a,b);b=c.getClientRects()[0];if(!b){for(c=b=0;a&&a.nodeType===Node.ELEMENT_NODE;)b+=a.offsetLeft-a.scrollLeft,c+=a.offsetTop-a.scrollTop,a=a.parentNode;b={top:c,left:b}}d.top=b.top;d.left=b.right;d.bottom=b.bottom}else a.nodeType===Node.TEXT_NODE?(a.previousSibling&&(d=a.previousSibling.getClientRects()[0]), +d||(c.setStart(a,0),c.setEnd(a,b),d=c.getClientRects()[0])):d=a.getClientRects()[0];return{top:d.top,left:d.left,bottom:d.bottom}}function p(a,b,c){var d=a,e=f(),k,g=l.ownerDocument.createRange(),m=h.getSelectedRange()?h.getSelectedRange().cloneRange():l.ownerDocument.createRange(),p;for(k=q(h.getNode(),0,g);0a?-1:1;for(a=Math.abs(a);0m?h.previousPosition():h.nextPosition());)if(N.check(),1===g.acceptPosition(h)&&(r+=1,p=h.container(),T=q(p,h.unfilteredDomOffset(),W),T.top!==V)){if(T.top!== +U&&U!==V)break;U=T.top;T=Math.abs(ca-T.left);if(null===s||Ta?(g=c.previousPosition,m=-1):(g=c.nextPosition,m=1);for(h=q(c.container(),c.unfilteredDomOffset(),r);g.call(c);)if(b.acceptPosition(c)===NodeFilter.FILTER_ACCEPT){if(k.getParagraphElement(c.getCurrentNode())!== +d)break;p=q(c.container(),c.unfilteredDomOffset(),r);if(p.bottom!==h.bottom&&(h=p.top>=h.top&&p.bottomh.bottom,!h))break;e+=m;h=p}r.detach();return e}function s(a,b){for(var c=0,d;a.parentNode!==b;)runtime.assert(null!==a.parentNode,"parent is null"),a=a.parentNode;for(d=b.firstChild;d!==a;)c+=1,d=d.nextSibling;return c}function m(a,b,c){runtime.assert(null!==a,"SelectionMover.countStepsToPosition called with element===null");var d=f(),e=d.container(),k=d.unfilteredDomOffset(), +g=0,m=new core.LoopWatchDog(1E3);d.setUnfilteredPosition(a,b);a=d.container();runtime.assert(Boolean(a),"SelectionMover.countStepsToPosition: positionIterator.container() returned null");b=d.unfilteredDomOffset();d.setUnfilteredPosition(e,k);var e=a,k=b,h=d.container(),l=d.unfilteredDomOffset();if(e===h)e=l-k;else{var p=e.compareDocumentPosition(h);2===p?p=-1:4===p?p=1:10===p?(k=s(e,h),p=ke)for(;d.nextPosition()&&(m.check(),1===c.acceptPosition(d)&&(g+=1),d.container()!== +a||d.unfilteredDomOffset()!==b););else if(0 + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");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.OpCloneParagraphStyle");runtime.loadClass("ops.OpDeleteParagraphStyle"); +ops.OperationTransformer=function(){function h(f,q){for(var p,g,a,e=[],d=[];0=g&&(e=-q.movePointBackward(-g,a));f.handleUpdate();return e};this.handleUpdate=function(){};this.getStepCounter=function(){return q.getStepCounter()};this.getMemberId=function(){return h};this.getNode=function(){return p.getNode()};this.getAnchorNode=function(){return p.getAnchorNode()};this.getSelectedRange=function(){return p.getSelectedRange()}; +this.getOdtDocument=function(){return l};p=new core.Cursor(l.getDOM(),h);q=new gui.SelectionMover(p,l.getRootNode())}; +// Input 55 /* Copyright (C) 2012 KO GmbH @@ -1251,91 +1413,26 @@ this.getOdtDocument=function(){return k};r=new core.Cursor(k.getDOM(),e);p=new g @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.EditInfo=function(e,k){function l(){var e=[],b;for(b in r)r.hasOwnProperty(b)&&e.push({memberid:b,time:r[b].time});e.sort(function(b,d){return b.time-d.time});return e}var p,r={};this.getNode=function(){return p};this.getOdtDocument=function(){return k};this.getEdits=function(){return r};this.getSortedEdits=function(){return l()};this.addEdit=function(e,b){var f,d=e.split("___")[0];if(!r[e])for(f in r)if(r.hasOwnProperty(f)&&f.split("___")[0]===d){delete r[f];break}r[e]={time:b}};this.clearEdits= -function(){r={}};p=k.getDOM().createElementNS("urn:webodf:names:editinfo","editinfo");e.insertBefore(p,e.firstChild)}; -// Input 51 -gui.Avatar=function(e,k){var l=this,p,r,h;this.setColor=function(b){r.style.borderColor=b};this.setImageUrl=function(b){l.isVisible()?r.src=b:h=b};this.isVisible=function(){return"block"===p.style.display};this.show=function(){h&&(r.src=h,h=void 0);p.style.display="block"};this.hide=function(){p.style.display="none"};this.markAsFocussed=function(b){p.className=b?"active":""};(function(){var b=e.ownerDocument,f=b.documentElement.namespaceURI;p=b.createElementNS(f,"div");r=b.createElementNS(f,"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=k?"block":"none";e.appendChild(p)})()}; -// Input 52 -runtime.loadClass("gui.Avatar");runtime.loadClass("ops.OdtCursor"); -gui.Caret=function(e,k){function l(){f&&b.parentNode&&!d&&(d=!0,r.style.borderColor="transparent"===r.style.borderColor?a:"transparent",runtime.setTimeout(function(){d=!1;l()},500))}function p(a){var b;if("string"===typeof a){if(""===a)return 0;b=/^(\d+)(\.\d+)?px$/.exec(a);runtime.assert(null!==b,"size ["+a+"] does not have unit px.");return parseFloat(b[1])}return a}var r,h,b,f=!1,d=!1,a="";this.setFocus=function(){f=!0;h.markAsFocussed(!0);l()};this.removeFocus=function(){f=!1;h.markAsFocussed(!1); -r.style.borderColor=a};this.setAvatarImageUrl=function(a){h.setImageUrl(a)};this.setColor=function(b){a!==b&&(a=b,"transparent"!==r.style.borderColor&&(r.style.borderColor=a),h.setColor(a))};this.getCursor=function(){return e};this.getFocusElement=function(){return r};this.toggleHandleVisibility=function(){h.isVisible()?h.hide():h.show()};this.showHandle=function(){h.show()};this.hideHandle=function(){h.hide()};this.ensureVisible=function(){var a,b,d,c,f,h,k,m=e.getOdtDocument().getOdfCanvas().getElement().parentNode; -f=k=r;d=runtime.getWindow();runtime.assert(null!==d,"Expected to be run in an environment which has a global window, like a browser.");do{f=f.parentElement;if(!f)break;h=d.getComputedStyle(f,null)}while("block"!==h.display);h=f;f=c=0;if(h&&m){b=!1;do{d=h.offsetParent;for(a=h.parentNode;a!==d;){if(a===m){a=h;var l=m,x=0;b=0;var v=void 0,w=runtime.getWindow();for(runtime.assert(null!==w,"Expected to be run in an environment which has a global window, like a browser.");a&&a!==l;)v=w.getComputedStyle(a, -null),x+=p(v.marginLeft)+p(v.borderLeftWidth)+p(v.paddingLeft),b+=p(v.marginTop)+p(v.borderTopWidth)+p(v.paddingTop),a=a.parentElement;a=x;c+=a;f+=b;b=!0;break}a=a.parentNode}if(b)break;c+=p(h.offsetLeft);f+=p(h.offsetTop);h=d}while(h&&h!==m);d=c;c=f}else c=d=0;d+=k.offsetLeft;c+=k.offsetTop;f=d-5;h=c-5;d=d+k.scrollWidth-1+5;k=c+k.scrollHeight-1+5;hm.scrollTop+m.clientHeight-1&&(m.scrollTop=k-m.clientHeight+1);fm.scrollLeft+m.clientWidth- -1&&(m.scrollLeft=d-m.clientWidth+1)};(function(){var a=e.getOdtDocument().getDOM();r=a.createElementNS(a.documentElement.namespaceURI,"span");b=e.getNode();b.appendChild(r);h=new gui.Avatar(b,k)})()}; -// Input 53 -runtime.loadClass("core.EventNotifier"); -gui.ClickHandler=function(){function e(){l=0;p=null}var k,l=0,p=null,r=new core.EventNotifier([gui.ClickHandler.signalSingleClick,gui.ClickHandler.signalDoubleClick,gui.ClickHandler.signalTripleClick]);this.subscribe=function(e,b){r.subscribe(e,b)};this.handleMouseUp=function(h){var b=runtime.getWindow();p&&p.x===h.screenX&&p.y===h.screenY?(l+=1,1===l?r.emit(gui.ClickHandler.signalSingleClick,void 0):2===l?r.emit(gui.ClickHandler.signalDoubleClick,void 0):3===l&&(b.clearTimeout(k),r.emit(gui.ClickHandler.signalTripleClick, -void 0),e())):(r.emit(gui.ClickHandler.signalSingleClick,void 0),l=1,p={x:h.screenX,y:h.screenY},b.clearTimeout(k),k=b.setTimeout(e,400))}};gui.ClickHandler.signalSingleClick="click";gui.ClickHandler.signalDoubleClick="doubleClick";gui.ClickHandler.signalTripleClick="tripleClick";(function(){return gui.ClickHandler})(); -// Input 54 -gui.Clipboard=function(){this.setDataFromRange=function(e,k){var l=!0,p,r=e.clipboardData,h=runtime.getWindow(),b,f;!r&&h&&(r=h.clipboardData);r?(h=new XMLSerializer,b=runtime.getDOMImplementation().createDocument("","",null),p=b.importNode(k.cloneContents(),!0),f=b.createElement("span"),f.appendChild(p),b.appendChild(f),p=r.setData("text/plain",k.toString()),l=l&&p,p=r.setData("text/html",h.serializeToString(b)),l=l&&p,e.preventDefault()):l=!1;return l}};(function(){return gui.Clipboard})(); -// Input 55 -runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");runtime.loadClass("ops.OpInsertText");runtime.loadClass("ops.OpRemoveText");runtime.loadClass("ops.OpSplitParagraph");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("gui.ClickHandler");runtime.loadClass("gui.Clipboard"); -gui.SessionController=function(){gui.SessionController=function(e,k){function l(a,b,c,d){var e="on"+b,g=!1;a.attachEvent&&(g=a.attachEvent(e,c));!g&&a.addEventListener&&(a.addEventListener(b,c,!1),g=!0);g&&!d||!a.hasOwnProperty(e)||(a[e]=c)}function p(a,b,c){var d="on"+b;a.detachEvent&&a.detachEvent(d,c);a.removeEventListener&&a.removeEventListener(b,c,!1);a[d]===c&&(a[d]=null)}function r(a){a.preventDefault?a.preventDefault():a.returnValue=!1}function h(a){r(a)}function b(a,b){var c=e.getOdtDocument(), -d=gui.SelectionMover.createPositionIterator(c.getRootNode()),g=c.getOdfCanvas().getElement(),f;if(f=a){for(;f!==g&&!("urn:webodf:names:cursor"===f.namespaceURI&&"cursor"===f.localName||"urn:webodf:names:editinfo"===f.namespaceURI&&"editinfo"===f.localName);)if(f=f.parentNode,!f)return;f!==g&&a!==f&&(a=f.parentNode,b=Array.prototype.indexOf.call(a.childNodes,f));d.setUnfilteredPosition(a,b);return c.getDistanceFromCursor(k,d.container(),d.unfilteredDomOffset())}}function f(a){var b=new ops.OpMoveCursor, -c=e.getOdtDocument().getCursorPosition(k);b.init({memberid:k,position:c+a});return b}function d(a){var b=new ops.OpMoveCursor,c=e.getOdtDocument().getCursorSelection(k);b.init({memberid:k,position:c.position,length:c.length+a});return b}function a(a){var b=e.getOdtDocument(),c=b.getParagraphElement(b.getCursor(k).getNode()),d=null;runtime.assert(Boolean(c),"SessionController: Cursor outside paragraph");b=b.getCursor(k).getStepCounter().countLinesSteps(a,b.getPositionFilter());0!==b&&(a=e.getOdtDocument().getCursorSelection(k), -d=new ops.OpMoveCursor,d.init({memberid:k,position:a.position,length:a.length+b}));return d}function n(a){var b=e.getOdtDocument(),c=b.getParagraphElement(b.getCursor(k).getNode()),d=null;runtime.assert(Boolean(c),"SessionController: Cursor outside paragraph");a=b.getCursor(k).getStepCounter().countLinesSteps(a,b.getPositionFilter());0!==a&&(b=b.getCursorPosition(k),d=new ops.OpMoveCursor,d.init({memberid:k,position:b+a}));return d}function q(a){var b=e.getOdtDocument(),c=b.getCursorPosition(k),d= -null;a=b.getCursor(k).getStepCounter().countStepsToLineBoundary(a,b.getPositionFilter());0!==a&&(d=new ops.OpMoveCursor,d.init({memberid:k,position:c+a}));return d}function g(){var a=e.getOdtDocument(),b=gui.SelectionMover.createPositionIterator(a.getRootNode()),c=null;b.moveToEnd();b=a.getDistanceFromCursor(k,b.container(),b.unfilteredDomOffset());0!==b&&(a=a.getCursorSelection(k),c=new ops.OpMoveCursor,c.init({memberid:k,position:a.position,length:a.length+b}));return c}function c(){var a=e.getOdtDocument(), -b,c=null;b=a.getDistanceFromCursor(k,a.getRootNode(),0);0!==b&&(a=a.getCursorSelection(k),c=new ops.OpMoveCursor,c.init({memberid:k,position:a.position,length:a.length+b}));return c}function u(a){0>a.length&&(a.position+=a.length,a.length=-a.length);return a}function t(a){var b=new ops.OpRemoveText;b.init({memberid:k,position:a.position,length:a.length});return b}function s(){var a=e.getOdtDocument().getCursor(k),b=runtime.getWindow().getSelection();b.removeAllRanges();b.addRange(a.getSelectedRange().cloneRange())} -function m(b){var m=b.keyCode,h=null,l=!1;if(37===m)h=b.shiftKey?d(-1):f(-1),l=!0;else if(39===m)h=b.shiftKey?d(1):f(1),l=!0;else if(38===m){if(y&&b.altKey&&b.shiftKey||b.ctrlKey&&b.shiftKey){var l=e.getOdtDocument(),p=l.getParagraphElement(l.getCursor(k).getNode()),v,h=null;if(p){m=l.getDistanceFromCursor(k,p,0);v=gui.SelectionMover.createPositionIterator(l.getRootNode());for(v.setUnfilteredPosition(p,0);0===m&&v.previousPosition();)p=v.getCurrentNode(),O.isParagraph(p)&&(m=l.getDistanceFromCursor(k, -p,0));0!==m&&(l=l.getCursorSelection(k),h=new ops.OpMoveCursor,h.init({memberid:k,position:l.position,length:l.length+m}))}}else h=b.metaKey&&b.shiftKey?c():b.shiftKey?a(-1):n(-1);l=!0}else if(40===m){if(y&&b.altKey&&b.shiftKey||b.ctrlKey&&b.shiftKey){h=e.getOdtDocument();v=h.getParagraphElement(h.getCursor(k).getNode());m=null;if(v){l=gui.SelectionMover.createPositionIterator(h.getRootNode());l.moveToEndOfNode(v);for(v=h.getDistanceFromCursor(k,l.container(),l.unfilteredDomOffset());0===v&&l.nextPosition();)p= -l.getCurrentNode(),O.isParagraph(p)&&(l.moveToEndOfNode(p),v=h.getDistanceFromCursor(k,l.container(),l.unfilteredDomOffset()));0!==v&&(h=h.getCursorSelection(k),m=new ops.OpMoveCursor,m.init({memberid:k,position:h.position,length:h.length+v}))}h=m}else h=b.metaKey&&b.shiftKey?g():b.shiftKey?a(1):n(1);l=!0}else 36===m?(!y&&b.ctrlKey&&b.shiftKey?h=c():y&&b.metaKey||b.ctrlKey?(l=e.getOdtDocument(),h=null,m=l.getDistanceFromCursor(k,l.getRootNode(),0),0!==m&&(l=l.getCursorPosition(k),h=new ops.OpMoveCursor, -h.init({memberid:k,position:l+m,length:0}))):h=q(-1),l=!0):35===m?(!y&&b.ctrlKey&&b.shiftKey?h=g():y&&b.metaKey||b.ctrlKey?(h=e.getOdtDocument(),l=gui.SelectionMover.createPositionIterator(h.getRootNode()),m=null,l.moveToEnd(),l=h.getDistanceFromCursor(k,l.container(),l.unfilteredDomOffset()),0!==l&&(h=h.getCursorPosition(k),m=new ops.OpMoveCursor,m.init({memberid:k,position:h+l,length:0})),h=m):h=q(1),l=!0):8===m?(m=e.getOdtDocument(),h=u(m.getCursorSelection(k)),l=null,0===h.length?0 - - @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. - - 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: http://gitorious.org/webodf/webodf/ -*/ -ops.TrivialUserModel=function(){var e={bob:{memberid:"bob",fullname:"Bob Pigeon",color:"red",imageurl:"avatar-pigeon.png"},alice:{memberid:"alice",fullname:"Alice Bee",color:"green",imageurl:"avatar-flower.png"},you:{memberid:"you",fullname:"I, Robot",color:"blue",imageurl:"avatar-joe.png"}};this.getUserDetailsAndUpdates=function(k,l){var p=k.split("___")[0];l(k,e[p]||null)};this.unsubscribeUserDetailsUpdates=function(e,l){}}; +runtime.loadClass("gui.Avatar");runtime.loadClass("ops.OdtCursor"); +gui.Caret=function(h,l){function f(){e&&a.parentNode&&!d&&(d=!0,p.style.borderColor="transparent"===p.style.borderColor?b:"transparent",runtime.setTimeout(function(){d=!1;f()},500))}function q(a){var b;if("string"===typeof a){if(""===a)return 0;b=/^(\d+)(\.\d+)?px$/.exec(a);runtime.assert(null!==b,"size ["+a+"] does not have unit px.");return parseFloat(b[1])}return a}var p,g,a,e=!1,d=!1,b="";this.setFocus=function(){e=!0;g.markAsFocussed(!0);f()};this.removeFocus=function(){e=!1;g.markAsFocussed(!1); +p.style.borderColor=b};this.setAvatarImageUrl=function(a){g.setImageUrl(a)};this.setColor=function(a){b!==a&&(b=a,"transparent"!==p.style.borderColor&&(p.style.borderColor=b),g.setColor(b))};this.getCursor=function(){return h};this.getFocusElement=function(){return p};this.toggleHandleVisibility=function(){g.isVisible()?g.hide():g.show()};this.showHandle=function(){g.show()};this.hideHandle=function(){g.hide()};this.ensureVisible=function(){var a,b,d,c,e,f,g,n=h.getOdtDocument().getOdfCanvas().getElement().parentNode; +e=g=p;d=runtime.getWindow();runtime.assert(null!==d,"Expected to be run in an environment which has a global window, like a browser.");do{e=e.parentElement;if(!e)break;f=d.getComputedStyle(e,null)}while("block"!==f.display);f=e;e=c=0;if(f&&n){b=!1;do{d=f.offsetParent;for(a=f.parentNode;a!==d;){if(a===n){a=f;var l=n,y=0;b=0;var u=void 0,w=runtime.getWindow();for(runtime.assert(null!==w,"Expected to be run in an environment which has a global window, like a browser.");a&&a!==l;)u=w.getComputedStyle(a, +null),y+=q(u.marginLeft)+q(u.borderLeftWidth)+q(u.paddingLeft),b+=q(u.marginTop)+q(u.borderTopWidth)+q(u.paddingTop),a=a.parentElement;a=y;c+=a;e+=b;b=!0;break}a=a.parentNode}if(b)break;c+=q(f.offsetLeft);e+=q(f.offsetTop);f=d}while(f&&f!==n);d=c;c=e}else c=d=0;d+=g.offsetLeft;c+=g.offsetTop;e=d-5;f=c-5;d=d+g.scrollWidth-1+5;g=c+g.scrollHeight-1+5;fn.scrollTop+n.clientHeight-1&&(n.scrollTop=g-n.clientHeight+1);en.scrollLeft+n.clientWidth- +1&&(n.scrollLeft=d-n.clientWidth+1)};(function(){var b=h.getOdtDocument().getDOM();p=b.createElementNS(b.documentElement.namespaceURI,"span");a=h.getNode();a.appendChild(p);g=new gui.Avatar(a,l)})()}; // Input 58 -ops.NowjsUserModel=function(){var e={},k={},l=runtime.getNetwork();this.getUserDetailsAndUpdates=function(p,r){var h=p.split("___")[0],b=e[h],f=k[h]=k[h]||[],d;runtime.assert(void 0!==r,"missing callback");for(d=0;d + Copyright (C) 2012-2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1367,56 +1464,33 @@ function(l,r){var h=r?{userid:r.uid,fullname:r.fullname,imageurl:"/user/"+r.avat @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFactory=function(e){};ops.OperationRouter.prototype.setPlaybackFunction=function(e){};ops.OperationRouter.prototype.push=function(e){}; +gui.KeyboardHandler=function(){function h(f,g){g||(g=g.None);return f+":"+g}var l=gui.KeyboardHandler.Modifier,f=null,q={};this.setDefault=function(h){f=h};this.bind=function(f,g,a){f=h(f,g);runtime.assert(!1===q.hasOwnProperty(f),"tried to overwrite the callback handler of key combo: "+f);q[f]=a};this.unbind=function(f,g){var a=h(f,g);delete q[a]};this.reset=function(){f=null;q={}};this.handleEvent=function(p){var g=p.keyCode,a=l.None;p.metaKey&&(a|=l.Meta);p.ctrlKey&&(a|=l.Ctrl);p.altKey&&(a|=l.Alt); +p.shiftKey&&(a|=l.Shift);g=h(g,a);g=q[g];a=!1;g?a=g():null!==f&&(a=f(p));a&&(p.preventDefault?p.preventDefault():p.returnValue=!1)}};gui.KeyboardHandler.Modifier={None:0,Meta:1,Ctrl:2,Alt:4,Shift:8,MetaShift:9,CtrlShift:10,AltShift:12};gui.KeyboardHandler.KeyCode={Backspace:8,Enter:13,End:35,Home:36,Left:37,Up:38,Right:39,Down:40,Delete:46,Z:90};(function(){return gui.KeyboardHandler})(); // Input 60 -/* - - Copyright (C) 2012 KO GmbH - - @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. - - 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: http://gitorious.org/webodf/webodf/ -*/ -ops.TrivialOperationRouter=function(){var e,k;this.setOperationFactory=function(l){e=l};this.setPlaybackFunction=function(e){k=e};this.push=function(l){l=l.spec();l.timestamp=(new Date).getTime();l=e.create(l);k(l)}}; +gui.Clipboard=function(){this.setDataFromRange=function(h,l){var f=!0,q,p=h.clipboardData,g=runtime.getWindow(),a,e;!p&&g&&(p=g.clipboardData);p?(g=new XMLSerializer,a=runtime.getDOMImplementation().createDocument("","",null),q=a.importNode(l.cloneContents(),!0),e=a.createElement("span"),e.appendChild(q),a.appendChild(e),q=p.setData("text/plain",l.toString()),f=f&&q,q=p.setData("text/html",g.serializeToString(a)),f=f&&q,h.preventDefault()):f=!1;return f}};(function(){return gui.Clipboard})(); // Input 61 -ops.NowjsOperationRouter=function(e,k){function l(a){var e;e=p.create(a);runtime.log(" op in: "+runtime.toJson(a));if(null!==e)if(a=Number(a.server_seq),runtime.assert(!isNaN(a),"server seq is not a number"),a===b+1)for(r(e),b=a,d=0,e=b+1;f.hasOwnProperty(e);e+=1)r(f[e]),delete f[e],runtime.log("op with server seq "+a+" taken from hold (reordered)");else runtime.assert(a!==b+1,"received incorrect order from server"),runtime.assert(!f.hasOwnProperty(a),"reorder_queue has incoming op"),runtime.log("op with server seq "+ -a+" put on hold"),f[a]=e;else runtime.log("ignoring invalid incoming opspec: "+a)}var p,r,h=runtime.getNetwork(),b=-1,f={},d=0,a=1E3;this.setOperationFactory=function(a){p=a};this.setPlaybackFunction=function(a){r=a};h.ping=function(a){null!==k&&a(k)};h.receiveOp=function(a,b){a===e&&l(b)};this.push=function(f){f=f.spec();runtime.assert(null!==k,"Router sequence N/A without memberid");a+=1;f.client_nonce="C:"+k+":"+a;f.parent_op=b+"+"+d;d+=1;runtime.log("op out: "+runtime.toJson(f));h.deliverOp(e, -f)};this.requestReplay=function(a){h.requestReplay(e,function(a){runtime.log("replaying: "+runtime.toJson(a));l(a)},function(b){runtime.log("replay done ("+b+" ops).");a&&a()})};(function(){h.memberid=k;h.joinSession(e,function(a){runtime.assert(a,"Trying to join a session which does not exists or where we are already in")})})()}; +runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");runtime.loadClass("ops.OpInsertText");runtime.loadClass("ops.OpRemoveText");runtime.loadClass("ops.OpSplitParagraph");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("gui.ClickHandler");runtime.loadClass("gui.KeyboardHandler");runtime.loadClass("gui.Clipboard"); +gui.SessionController=function(){gui.SessionController=function(h,l){function f(a,b,c,d){var e="on"+b,f=!1;a.attachEvent&&(f=a.attachEvent(e,c));!f&&a.addEventListener&&(a.addEventListener(b,c,!1),f=!0);f&&!d||!a.hasOwnProperty(e)||(a[e]=c)}function q(a,b,c){var d="on"+b;a.detachEvent&&a.detachEvent(d,c);a.removeEventListener&&a.removeEventListener(b,c,!1);a[d]===c&&(a[d]=null)}function p(a){a.preventDefault?a.preventDefault():a.returnValue=!1}function g(a,b){var c=new ops.OpMoveCursor;c.init({memberid:l, +position:a,length:b||0});return c}function a(a,b){var c=gui.SelectionMover.createPositionIterator(v.getRootNode()),d=v.getOdfCanvas().getElement(),e;if(e=a){for(;e!==d&&!("urn:webodf:names:cursor"===e.namespaceURI&&"cursor"===e.localName||"urn:webodf:names:editinfo"===e.namespaceURI&&"editinfo"===e.localName);)if(e=e.parentNode,!e)return;e!==d&&a!==e&&(a=e.parentNode,b=Array.prototype.indexOf.call(a.childNodes,e));c.setUnfilteredPosition(a,b);return v.getDistanceFromCursor(l,c.container(),c.unfilteredDomOffset())}} +function e(){var b=runtime.getWindow().getSelection(),c=v.getCursorPosition(l),d;d=a(b.anchorNode,b.anchorOffset);b=a(b.focusNode,b.focusOffset);if(0!==b||0!==d)c=g(c+d,b-d),h.enqueue(c)}function d(){var a=gui.SelectionMover.createPositionIterator(v.getRootNode()),b=v.getCursor(l).getNode(),c=v.getCursorPosition(l),d=/[A-Za-z0-9]/,e=0,f=0,k,n,m;a.setUnfilteredPosition(b,0);if(a.previousPosition()&&(k=a.getCurrentNode(),k.nodeType===Node.TEXT_NODE))for(n=k.data.length-1;0<=n;n-=1)if(m=k.data[n],d.test(m))e-= +1;else break;a.setUnfilteredPosition(b,0);if(a.nextPosition()&&(k=a.getCurrentNode(),k.nodeType===Node.TEXT_NODE))for(n=0;na.length&&(a.position+=a.length,a.length=-a.length);return a}function U(a){var b=new ops.OpRemoveText;b.init({memberid:l,position:a.position,length:a.length});return b}function W(){var a=ca(v.getCursorSelection(l)),b=null;0===a.length?0p?(l(1,0),f=l(0.5,1E4-p),d=l(0.2,2E4-p)):1E4<=p&&2E4>p?(l(0.5,0),d=l(0.2,2E4-p)):l(0.2,0)};this.getEdits=function(){return e.getEdits()};this.clearEdits=function(){e.clearEdits(); -h.setEdits([]);b.hasAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")&&b.removeAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")};this.getEditInfo=function(){return e};this.show=function(){b.style.display="block"};this.hide=function(){p.hideHandle();b.style.display="none"};this.showHandle=function(){h.show()};this.hideHandle=function(){h.hide()};(function(){var a=e.getOdtDocument().getDOM();b=a.createElementNS(a.documentElement.namespaceURI,"div");b.setAttribute("class","editInfoMarker"); -b.onmouseover=function(){p.showHandle()};b.onmouseout=function(){p.hideHandle()};r=e.getNode();r.appendChild(b);h=new gui.EditInfoHandle(r);k||p.hide()})()}; -// Input 64 /* Copyright (C) 2012 KO GmbH @@ -1451,17 +1525,15 @@ b.onmouseover=function(){p.showHandle()};b.onmouseout=function(){p.hideHandle()} @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("gui.Caret");runtime.loadClass("ops.TrivialUserModel");runtime.loadClass("ops.EditInfo");runtime.loadClass("gui.EditInfoMarker"); -gui.SessionView=function(){return function(e,k,l){function p(a,b,c){c=c.split("___")[0];return a+"."+b+'[editinfo|memberid^="'+c+'"]'}function r(a,b,c){function d(b,c,e){e=p(b,c,a)+e;a:{var g=q.firstChild;for(b=p(b,c,a);g;){if(g.nodeType===Node.TEXT_NODE&&0===g.data.indexOf(b)){b=g;break a}g=g.nextSibling}b=null}b?b.data=e:q.appendChild(document.createTextNode(e))}d("div","editInfoMarker","{ background-color: "+c+"; }");d("span","editInfoColor","{ background-color: "+c+"; }");d("span","editInfoAuthor", -':before { content: "'+b+'"; }')}function h(a){var b,c;for(c in g)g.hasOwnProperty(c)&&(b=g[c],a?b.show():b.hide())}function b(a){var b,c;for(c in n)n.hasOwnProperty(c)&&(b=n[c],a?b.showHandle():b.hideHandle())}function f(a,b){var c=n[a];void 0===b?runtime.log('UserModel sent undefined data for member "'+a+'".'):(null===b&&(b={memberid:a,fullname:"Unknown Identity",color:"black",imageurl:"avatar-joe.png"}),c&&(c.setAvatarImageUrl(b.imageurl),c.setColor(b.color)),r(a,b.fullname,b.color))}function d(a){var b= -l.createCaret(a,u);a=a.getMemberId();var c=k.getUserModel();n[a]=b;f(a,null);c.getUserDetailsAndUpdates(a,f);runtime.log("+++ View here +++ eagerly created an Caret for '"+a+"'! +++")}function a(a){var b=!1,c;delete n[a];for(c in g)if(g.hasOwnProperty(c)&&g[c].getEditInfo().getEdits().hasOwnProperty(a)){b=!0;break}b||k.getUserModel().unsubscribeUserDetailsUpdates(a,f)}var n={},q,g={},c=void 0!==e.editInfoMarkersInitiallyVisible?e.editInfoMarkersInitiallyVisible:!0,u=void 0!==e.caretAvatarsInitiallyVisible? -e.caretAvatarsInitiallyVisible:!0;this.showEditInfoMarkers=function(){c||(c=!0,h(c))};this.hideEditInfoMarkers=function(){c&&(c=!1,h(c))};this.showCaretAvatars=function(){u||(u=!0,b(u))};this.hideCaretAvatars=function(){u&&(u=!1,b(u))};this.getSession=function(){return k};this.getCaret=function(a){return n[a]};(function(){var b=k.getOdtDocument(),e=document.getElementsByTagName("head")[0];b.subscribe(ops.OdtDocument.signalCursorAdded,d);b.subscribe(ops.OdtDocument.signalCursorRemoved,a);b.subscribe(ops.OdtDocument.signalParagraphChanged, -function(a){var b=a.paragraphElement,d=a.memberId;a=a.timeStamp;var e,f="",h=b.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo")[0];h?(f=h.getAttributeNS("urn:webodf:names:editinfo","id"),e=g[f]):(f=Math.random().toString(),e=new ops.EditInfo(b,k.getOdtDocument()),e=new gui.EditInfoMarker(e,c),h=b.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo")[0],h.setAttributeNS("urn:webodf:names:editinfo","id",f),g[f]=e);e.addEdit(d,new Date(a))});q=document.createElementNS(e.namespaceURI, -"style");q.type="text/css";q.media="screen, print, handheld, projection";q.appendChild(document.createTextNode("@namespace editinfo url(urn:webodf:names:editinfo);"));e.appendChild(q)})()}}(); +ops.TrivialUserModel=function(){var h={bob:{memberid:"bob",fullname:"Bob Pigeon",color:"red",imageurl:"avatar-pigeon.png"},alice:{memberid:"alice",fullname:"Alice Bee",color:"green",imageurl:"avatar-flower.png"},you:{memberid:"you",fullname:"I, Robot",color:"blue",imageurl:"avatar-joe.png"}};this.getUserDetailsAndUpdates=function(l,f){var q=l.split("___")[0];f(l,h[q]||null)};this.unsubscribeUserDetailsUpdates=function(h,f){}}; +// Input 64 +ops.NowjsUserModel=function(h){var l={},f={},q=h.getNowObject();this.getUserDetailsAndUpdates=function(h,g){var a=h.split("___")[0],e=l[a],d=f[a]=f[a]||[],b;runtime.assert(void 0!==g,"missing callback");for(b=0;b + Copyright (C) 2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1493,25 +1565,11 @@ function(a){var b=a.paragraphElement,d=a.memberId;a=a.timeStamp;var e,f="",h=b.g @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("gui.Caret");gui.CaretFactory=function(e){this.createCaret=function(k,l){var p=k.getMemberId(),r=e.getSession().getOdtDocument(),h=r.getOdfCanvas().getElement(),b=new gui.Caret(k,l);p===e.getInputMemberId()&&(runtime.log("Starting to track input on new cursor of "+p),r.subscribe(ops.OdtDocument.signalParagraphChanged,function(e){e.memberId===p&&b.ensureVisible()}),k.handleUpdate=b.ensureVisible,h.setAttribute("tabindex",0),h.onfocus=b.setFocus,h.onblur=b.removeFocus,h.focus());return b}}; +ops.PullBoxUserModel=function(h){function l(){var a=h.getBase64(),e,d=[];for(e in p)p.hasOwnProperty(e)&&d.push(e);runtime.log("user-list request for : "+d.join(","));h.call("user-list:"+a.toBase64(h.getToken())+":"+d.join(","),function(a){var d=runtime.fromJson(a),f;runtime.log("user-list reply: "+a);if(d.hasOwnProperty("userdata_list"))for(a=d.userdata_list,e=0;ee?-1:e-1})};l.slideChange=function(e){var k=l.getPages(l.odf_canvas.odfContainer().rootElement),h=-1,b=0;k.forEach(function(e){e=e[1];e.hasAttribute("slide_current")&&(h=b,e.removeAttribute("slide_current"));b+=1});e=e(h,k.length);-1===e&&(e=h);k[e][1].setAttribute("slide_current","1"); -document.getElementById("pagelist").selectedIndex=e;"cont"===l.slide_mode&&window.scrollBy(0,k[e][1].getBoundingClientRect().top-30)};l.selectSlide=function(e){l.slideChange(function(l,h){return e>=h||0>e?-1:e})};l.scrollIntoContView=function(e){var k=l.getPages(l.odf_canvas.odfContainer().rootElement);0!==k.length&&window.scrollBy(0,k[e][1].getBoundingClientRect().top-30)};l.getPages=function(e){e=e.getElementsByTagNameNS(odf.Namespaces.drawns,"page");var l=[],h;for(h=0;h=a.rangeCount||!t)||(a=a.getRangeAt(0),t.setPoint(a.startContainer,a.startOffset))}function h(){var a=e.ownerDocument.defaultView.getSelection(),b,c;a.removeAllRanges();t&&t.node()&&(b=t.node(),c=b.ownerDocument.createRange(), -c.setStart(b,t.position()),c.collapse(!0),a.addRange(c))}function b(a){var b=a.charCode||a.keyCode;if(t=null,t&&37===b)r(),t.stepBackward(),h();else if(16<=b&&20>=b||33<=b&&40>=b)return;p(a)}function f(a){}function d(a){e.ownerDocument.defaultView.getSelection().getRangeAt(0);p(a)}function a(b){for(var c=b.firstChild;c&&c!==b;)c.nodeType===Node.ELEMENT_NODE&&a(c),c=c.nextSibling||c.parentNode;var d,e,g,c=b.attributes;d="";for(g=c.length-1;0<=g;g-=1)e=c.item(g),d=d+" "+e.nodeName+'="'+e.nodeValue+ -'"';b.setAttribute("customns_name",b.nodeName);b.setAttribute("customns_atts",d);c=b.firstChild;for(e=/^\s*$/;c&&c!==b;)d=c,c=c.nextSibling||c.parentNode,d.nodeType===Node.TEXT_NODE&&e.test(d.nodeValue)&&d.parentNode.removeChild(d)}function n(a,b){for(var c=a.firstChild,d,e,g;c&&c!==a;){if(c.nodeType===Node.ELEMENT_NODE)for(n(c,b),d=c.attributes,g=d.length-1;0<=g;g-=1)e=d.item(g),"http://www.w3.org/2000/xmlns/"!==e.namespaceURI||b[e.nodeValue]||(b[e.nodeValue]=e.localName);c=c.nextSibling||c.parentNode}} -function q(){var a=e.ownerDocument.createElement("style"),b;b={};n(e,b);var c={},d,f,h=0;for(d in b)if(b.hasOwnProperty(d)&&d){f=b[d];if(!f||c.hasOwnProperty(f)||"xmlns"===f){do f="ns"+h,h+=1;while(c.hasOwnProperty(f));b[d]=f}c[f]=!0}a.type="text/css";b="@namespace customns url(customns);\n"+g;a.appendChild(e.ownerDocument.createTextNode(b));k=k.parentNode.replaceChild(a,k)}var g,c,u,t=null;e.id||(e.id="xml"+String(Math.random()).substring(2));c="#"+e.id+" ";g=c+"*,"+c+":visited, "+c+":link {display:block; margin: 0px; margin-left: 10px; font-size: medium; color: black; background: white; font-variant: normal; font-weight: normal; font-style: normal; font-family: sans-serif; text-decoration: none; white-space: pre-wrap; height: auto; width: auto}\n"+ -c+":before {color: blue; content: '<' attr(customns_name) attr(customns_atts) '>';}\n"+c+":after {color: blue; content: '';}\n"+c+"{overflow: auto;}\n";(function(a){l(a,"click",d);l(a,"keydown",b);l(a,"keypress",f);l(a,"drop",p);l(a,"dragend",p);l(a,"beforepaste",p);l(a,"paste",p)})(e);this.updateCSS=q;this.setXML=function(b){b=b.documentElement||b;u=b=e.ownerDocument.importNode(b,!0);for(a(b);e.lastChild;)e.removeChild(e.lastChild);e.appendChild(b);q();t=new core.PositionIterator(b)}; -this.getXML=function(){return u}}; -// Input 68 /* Copyright (C) 2013 KO GmbH @@ -1546,8 +1604,47 @@ this.getXML=function(){return u}}; @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -gui.UndoManager=function(){};gui.UndoManager.prototype.subscribe=function(e,k){};gui.UndoManager.prototype.unsubscribe=function(e,k){};gui.UndoManager.prototype.setOdtDocument=function(e){};gui.UndoManager.prototype.saveInitialState=function(){};gui.UndoManager.prototype.resetInitialState=function(){};gui.UndoManager.prototype.setPlaybackFunction=function(e){};gui.UndoManager.prototype.hasUndoStates=function(){};gui.UndoManager.prototype.hasRedoStates=function(){}; -gui.UndoManager.prototype.moveForward=function(e){};gui.UndoManager.prototype.moveBackward=function(e){};gui.UndoManager.prototype.onOperationExecuted=function(e){};gui.UndoManager.signalUndoStackChanged="undoStackChanged";(function(){return gui.UndoManager})(); +ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFactory=function(h){};ops.OperationRouter.prototype.setPlaybackFunction=function(h){};ops.OperationRouter.prototype.push=function(h){}; +// Input 67 +/* + + Copyright (C) 2012 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +ops.TrivialOperationRouter=function(){var h,l;this.setOperationFactory=function(f){h=f};this.setPlaybackFunction=function(f){l=f};this.push=function(f){f=f.spec();f.timestamp=(new Date).getTime();f=h.create(f);l(f)}}; +// Input 68 +ops.NowjsOperationRouter=function(h,l,f){function q(a){var f;f=p.create(a);runtime.log(" op in: "+runtime.toJson(a));if(null!==f)if(a=Number(a.server_seq),runtime.assert(!isNaN(a),"server seq is not a number"),a===e+1)for(g(f),e=a,b=0,f=e+1;d.hasOwnProperty(f);f+=1)g(d[f]),delete d[f],runtime.log("op with server seq "+a+" taken from hold (reordered)");else runtime.assert(a!==e+1,"received incorrect order from server"),runtime.assert(!d.hasOwnProperty(a),"reorder_queue has incoming op"),runtime.log("op with server seq "+ +a+" put on hold"),d[a]=f;else runtime.log("ignoring invalid incoming opspec: "+a)}var p,g,a=f.getNowObject(),e=-1,d={},b=0,s=1E3;this.setOperationFactory=function(a){p=a};this.setPlaybackFunction=function(a){g=a};a.ping=function(a){null!==l&&a(l)};a.receiveOp=function(a,b){a===h&&q(b)};this.push=function(d){d=d.spec();runtime.assert(null!==l,"Router sequence N/A without memberid");s+=1;d.client_nonce="C:"+l+":"+s;d.parent_op=e+"+"+b;b+=1;runtime.log("op out: "+runtime.toJson(d));a.deliverOp(h,d)}; +this.requestReplay=function(b){a.requestReplay(h,function(a){runtime.log("replaying: "+runtime.toJson(a));q(a)},function(a){runtime.log("replay done ("+a+" ops).");b&&b()})};(function(){a.memberid=l;a.joinSession(h,function(a){runtime.assert(a,"Trying to join a session which does not exists or where we are already in")})})()}; // Input 69 /* @@ -1583,9 +1680,191 @@ gui.UndoManager.prototype.moveForward=function(e){};gui.UndoManager.prototype.mo @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -gui.UndoStateRules=function(){function e(e){switch(e.spec().optype){case "MoveCursor":case "AddCursor":case "RemoveCursor":return!1;default:return!0}}this.isEditOperation=e;this.isPartOfOperationSet=function(k,l){if(e(k)){if(0===l.length)return!0;var p;if(p=e(l[l.length-1]))a:{p=l.filter(e);var r=k.spec().optype,h;b:switch(r){case "RemoveText":case "InsertText":h=!0;break b;default:h=!1}if(h&&r===p[0].spec().optype){if(1===p.length){p=!0;break a}r=p[p.length-2].spec().position;p=p[p.length-1].spec().position; -h=k.spec().position;if(p===h-(p-r)){p=!0;break a}}p=!1}return p}return!0}}; +runtime.loadClass("ops.OperationTransformer"); +ops.PullBoxOperationRouter=function(h,l,f){function q(a){var b,c,e,f=[];for(b=0;bm?(f(1,0),e=f(0.5,1E4-m),d=f(0.2,2E4-m)):1E4<=m&&2E4>m?(f(0.5,0),d=f(0.2,2E4-m)):f(0.2,0)};this.getEdits=function(){return h.getEdits()};this.clearEdits=function(){h.clearEdits(); +g.setEdits([]);a.hasAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")&&a.removeAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")};this.getEditInfo=function(){return h};this.show=function(){a.style.display="block"};this.hide=function(){q.hideHandle();a.style.display="none"};this.showHandle=function(){g.show()};this.hideHandle=function(){g.hide()};(function(){var b=h.getOdtDocument().getDOM();a=b.createElementNS(b.documentElement.namespaceURI,"div");a.setAttribute("class","editInfoMarker"); +a.onmouseover=function(){q.showHandle()};a.onmouseout=function(){q.hideHandle()};p=h.getNode();p.appendChild(a);g=new gui.EditInfoHandle(p);l||q.hide()})()}; +// Input 72 +/* + + Copyright (C) 2012 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +runtime.loadClass("gui.Caret");runtime.loadClass("ops.TrivialUserModel");runtime.loadClass("ops.EditInfo");runtime.loadClass("gui.EditInfoMarker"); +gui.SessionView=function(){return function(h,l,f){function q(a,b,c){c=c.split("___")[0];return a+"."+b+'[editinfo|memberid^="'+c+'"]'}function p(a,b,c){function d(b,c,e){e=q(b,c,a)+e;a:{var f=m.firstChild;for(b=q(b,c,a);f;){if(f.nodeType===Node.TEXT_NODE&&0===f.data.indexOf(b)){b=f;break a}f=f.nextSibling}b=null}b?b.data=e:m.appendChild(document.createTextNode(e))}d("div","editInfoMarker","{ background-color: "+c+"; }");d("span","editInfoColor","{ background-color: "+c+"; }");d("span","editInfoAuthor", +':before { content: "'+b+'"; }')}function g(a){var b,c;for(c in k)k.hasOwnProperty(c)&&(b=k[c],a?b.show():b.hide())}function a(a){var b,c;for(c in s)s.hasOwnProperty(c)&&(b=s[c],a?b.showHandle():b.hideHandle())}function e(a,b){var c=s[a];void 0===b?runtime.log('UserModel sent undefined data for member "'+a+'".'):(null===b&&(b={memberid:a,fullname:"Unknown Identity",color:"black",imageurl:"avatar-joe.png"}),c&&(c.setAvatarImageUrl(b.imageurl),c.setColor(b.color)),p(a,b.fullname,b.color))}function d(a){var b= +f.createCaret(a,t);a=a.getMemberId();var c=l.getUserModel();s[a]=b;e(a,null);c.getUserDetailsAndUpdates(a,e);runtime.log("+++ View here +++ eagerly created an Caret for '"+a+"'! +++")}function b(a){var b=!1,c;delete s[a];for(c in k)if(k.hasOwnProperty(c)&&k[c].getEditInfo().getEdits().hasOwnProperty(a)){b=!0;break}b||l.getUserModel().unsubscribeUserDetailsUpdates(a,e)}var s={},m,k={},c=void 0!==h.editInfoMarkersInitiallyVisible?h.editInfoMarkersInitiallyVisible:!0,t=void 0!==h.caretAvatarsInitiallyVisible? +h.caretAvatarsInitiallyVisible:!0;this.showEditInfoMarkers=function(){c||(c=!0,g(c))};this.hideEditInfoMarkers=function(){c&&(c=!1,g(c))};this.showCaretAvatars=function(){t||(t=!0,a(t))};this.hideCaretAvatars=function(){t&&(t=!1,a(t))};this.getSession=function(){return l};this.getCaret=function(a){return s[a]};(function(){var a=l.getOdtDocument(),e=document.getElementsByTagName("head")[0];a.subscribe(ops.OdtDocument.signalCursorAdded,d);a.subscribe(ops.OdtDocument.signalCursorRemoved,b);a.subscribe(ops.OdtDocument.signalParagraphChanged, +function(a){var b=a.paragraphElement,d=a.memberId;a=a.timeStamp;var e,f="",g=b.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo")[0];g?(f=g.getAttributeNS("urn:webodf:names:editinfo","id"),e=k[f]):(f=Math.random().toString(),e=new ops.EditInfo(b,l.getOdtDocument()),e=new gui.EditInfoMarker(e,c),g=b.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo")[0],g.setAttributeNS("urn:webodf:names:editinfo","id",f),k[f]=e);e.addEdit(d,new Date(a))});m=document.createElementNS(e.namespaceURI, +"style");m.type="text/css";m.media="screen, print, handheld, projection";m.appendChild(document.createTextNode("@namespace editinfo url(urn:webodf:names:editinfo);"));e.appendChild(m)})()}}(); +// Input 73 +/* + + Copyright (C) 2012 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +runtime.loadClass("gui.Caret");gui.CaretFactory=function(h){this.createCaret=function(l,f){var q=l.getMemberId(),p=h.getSession().getOdtDocument(),g=p.getOdfCanvas().getElement(),a=new gui.Caret(l,f);q===h.getInputMemberId()&&(runtime.log("Starting to track input on new cursor of "+q),p.subscribe(ops.OdtDocument.signalParagraphChanged,function(e){e.memberId===q&&a.ensureVisible()}),l.handleUpdate=a.ensureVisible,g.setAttribute("tabindex",0),g.onfocus=a.setFocus,g.onblur=a.removeFocus,g.focus());return a}}; +// Input 74 +runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.Namespaces"); +gui.PresenterUI=function(){var h=new xmldom.XPath;return function(l){var f=this;f.setInitialSlideMode=function(){f.startSlideMode("single")};f.keyDownHandler=function(h){if(!h.target.isContentEditable&&"input"!==h.target.nodeName)switch(h.keyCode){case 84:f.toggleToolbar();break;case 37:case 8:f.prevSlide();break;case 39:case 32:f.nextSlide();break;case 36:f.firstSlide();break;case 35:f.lastSlide()}};f.root=function(){return f.odf_canvas.odfContainer().rootElement};f.firstSlide=function(){f.slideChange(function(f, +h){return 0})};f.lastSlide=function(){f.slideChange(function(f,h){return h-1})};f.nextSlide=function(){f.slideChange(function(f,h){return f+1f?-1:f-1})};f.slideChange=function(h){var l=f.getPages(f.odf_canvas.odfContainer().rootElement),g=-1,a=0;l.forEach(function(e){e=e[1];e.hasAttribute("slide_current")&&(g=a,e.removeAttribute("slide_current"));a+=1});h=h(g,l.length);-1===h&&(h=g);l[h][1].setAttribute("slide_current","1"); +document.getElementById("pagelist").selectedIndex=h;"cont"===f.slide_mode&&window.scrollBy(0,l[h][1].getBoundingClientRect().top-30)};f.selectSlide=function(h){f.slideChange(function(f,g){return h>=g||0>h?-1:h})};f.scrollIntoContView=function(h){var l=f.getPages(f.odf_canvas.odfContainer().rootElement);0!==l.length&&window.scrollBy(0,l[h][1].getBoundingClientRect().top-30)};f.getPages=function(f){f=f.getElementsByTagNameNS(odf.Namespaces.drawns,"page");var h=[],g;for(g=0;g=a.rangeCount||!r)||(a=a.getRangeAt(0),r.setPoint(a.startContainer,a.startOffset))}function g(){var a=h.ownerDocument.defaultView.getSelection(),b,c;a.removeAllRanges();r&&r.node()&&(b=r.node(),c=b.ownerDocument.createRange(), +c.setStart(b,r.position()),c.collapse(!0),a.addRange(c))}function a(a){var b=a.charCode||a.keyCode;if(r=null,r&&37===b)p(),r.stepBackward(),g();else if(16<=b&&20>=b||33<=b&&40>=b)return;q(a)}function e(a){}function d(a){h.ownerDocument.defaultView.getSelection().getRangeAt(0);q(a)}function b(a){for(var c=a.firstChild;c&&c!==a;)c.nodeType===Node.ELEMENT_NODE&&b(c),c=c.nextSibling||c.parentNode;var d,e,f,c=a.attributes;d="";for(f=c.length-1;0<=f;f-=1)e=c.item(f),d=d+" "+e.nodeName+'="'+e.nodeValue+ +'"';a.setAttribute("customns_name",a.nodeName);a.setAttribute("customns_atts",d);c=a.firstChild;for(e=/^\s*$/;c&&c!==a;)d=c,c=c.nextSibling||c.parentNode,d.nodeType===Node.TEXT_NODE&&e.test(d.nodeValue)&&d.parentNode.removeChild(d)}function s(a,b){for(var c=a.firstChild,d,e,f;c&&c!==a;){if(c.nodeType===Node.ELEMENT_NODE)for(s(c,b),d=c.attributes,f=d.length-1;0<=f;f-=1)e=d.item(f),"http://www.w3.org/2000/xmlns/"!==e.namespaceURI||b[e.nodeValue]||(b[e.nodeValue]=e.localName);c=c.nextSibling||c.parentNode}} +function m(){var a=h.ownerDocument.createElement("style"),b;b={};s(h,b);var c={},d,e,f=0;for(d in b)if(b.hasOwnProperty(d)&&d){e=b[d];if(!e||c.hasOwnProperty(e)||"xmlns"===e){do e="ns"+f,f+=1;while(c.hasOwnProperty(e));b[d]=e}c[e]=!0}a.type="text/css";b="@namespace customns url(customns);\n"+k;a.appendChild(h.ownerDocument.createTextNode(b));l=l.parentNode.replaceChild(a,l)}var k,c,t,r=null;h.id||(h.id="xml"+String(Math.random()).substring(2));c="#"+h.id+" ";k=c+"*,"+c+":visited, "+c+":link {display:block; margin: 0px; margin-left: 10px; font-size: medium; color: black; background: white; font-variant: normal; font-weight: normal; font-style: normal; font-family: sans-serif; text-decoration: none; white-space: pre-wrap; height: auto; width: auto}\n"+ +c+":before {color: blue; content: '<' attr(customns_name) attr(customns_atts) '>';}\n"+c+":after {color: blue; content: '';}\n"+c+"{overflow: auto;}\n";(function(b){f(b,"click",d);f(b,"keydown",a);f(b,"keypress",e);f(b,"drop",q);f(b,"dragend",q);f(b,"beforepaste",q);f(b,"paste",q)})(h);this.updateCSS=m;this.setXML=function(a){a=a.documentElement||a;t=a=h.ownerDocument.importNode(a,!0);for(b(a);h.lastChild;)h.removeChild(h.lastChild);h.appendChild(a);m();r=new core.PositionIterator(a)}; +this.getXML=function(){return t}}; +// Input 76 +/* + + Copyright (C) 2013 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +gui.UndoManager=function(){};gui.UndoManager.prototype.subscribe=function(h,l){};gui.UndoManager.prototype.unsubscribe=function(h,l){};gui.UndoManager.prototype.setOdtDocument=function(h){};gui.UndoManager.prototype.saveInitialState=function(){};gui.UndoManager.prototype.resetInitialState=function(){};gui.UndoManager.prototype.setPlaybackFunction=function(h){};gui.UndoManager.prototype.hasUndoStates=function(){};gui.UndoManager.prototype.hasRedoStates=function(){}; +gui.UndoManager.prototype.moveForward=function(h){};gui.UndoManager.prototype.moveBackward=function(h){};gui.UndoManager.prototype.onOperationExecuted=function(h){};gui.UndoManager.signalUndoStackChanged="undoStackChanged";gui.UndoManager.signalUndoStateCreated="undoStateCreated";gui.UndoManager.signalUndoStateModified="undoStateModified";(function(){return gui.UndoManager})(); +// Input 77 +/* + + Copyright (C) 2013 KO GmbH + + @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. + + 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: http://gitorious.org/webodf/webodf/ +*/ +gui.UndoStateRules=function(){function h(f){return f.spec().optype}function l(f){switch(h(f)){case "MoveCursor":case "AddCursor":case "RemoveCursor":return!1;default:return!0}}this.getOpType=h;this.isEditOperation=l;this.isPartOfOperationSet=function(f,q){if(l(f)){if(0===q.length)return!0;var p;if(p=l(q[q.length-1]))a:{p=q.filter(l);var g=h(f),a;b:switch(g){case "RemoveText":case "InsertText":a=!0;break b;default:a=!1}if(a&&g===h(p[0])){if(1===p.length){p=!0;break a}g=p[p.length-2].spec().position; +p=p[p.length-1].spec().position;a=f.spec().position;if(p===a-(p-g)){p=!0;break a}}p=!1}return p}return!0}}; +// Input 78 /* Copyright (C) 2013 KO GmbH @@ -1621,10 +1900,11 @@ h=k.spec().position;if(p===h-(p-r)){p=!0;break a}}p=!1}return p}return!0}}; @source: http://gitorious.org/webodf/webodf/ */ runtime.loadClass("gui.UndoManager");runtime.loadClass("gui.UndoStateRules"); -gui.TrivialUndoManager=function(){function e(){n.emit(gui.UndoManager.signalUndoStackChanged,{undoAvailable:l.hasUndoStates(),redoAvailable:l.hasRedoStates()})}function k(){f!==r&&f!==d[d.length-1]&&d.push(f)}var l=this,p,r,h,b,f=[],d=[],a=[],n=new core.EventNotifier([gui.UndoManager.signalUndoStackChanged]),q=new gui.UndoStateRules;this.subscribe=function(a,b){n.subscribe(a,b)};this.unsubscribe=function(a,b){n.unsubscribe(a,b)};this.hasUndoStates=function(){return 0 @@ -1660,22 +1940,22 @@ f.push(b)};this.moveForward=function(b){for(var c=0,k;b&&a.length;)k=a.pop(),d.p @source: http://gitorious.org/webodf/webodf/ */ runtime.loadClass("core.EventNotifier");runtime.loadClass("odf.OdfUtils"); -ops.OdtDocument=function(e){function k(){var a=e.odfContainer().getContentElement(),b=a&&a.localName;runtime.assert("text"===b,"Unsupported content element type '"+b+"'for OdtDocument");return a}function l(a){var b=gui.SelectionMover.createPositionIterator(k());for(a+=1;0=e;e+=1)c=b.container(),d=b.unfilteredDomOffset(),c.nodeType===Node.TEXT_NODE&&(" "===c.data[d]&&a.isSignificantWhitespace(c,d))&&h(c,d),b.nextPosition()};this.getParagraphStyleElement=r;this.getParagraphElement=p;this.getParagraphStyleAttributes= -function(a){return(a=r(a))?e.getFormatting().getInheritedStyleAttributes(a):null};this.getPositionInTextNode=function(a,b){var e=gui.SelectionMover.createPositionIterator(k()),f=null,h,m=0,l=null;runtime.assert(0<=a,"position must be >= 0");1===d.acceptPosition(e)?(h=e.container(),h.nodeType===Node.TEXT_NODE&&(f=h,m=0)):a+=1;for(;0=e;e+=1)c=a.container(),d=a.unfilteredDomOffset(),c.nodeType===Node.TEXT_NODE&&(" "===c.data[d]&&b.isSignificantWhitespace(c,d))&&g(c,d),a.nextPosition()};this.getParagraphStyleElement=p;this.getParagraphElement=q;this.getParagraphStyleAttributes= +function(a){return(a=p(a))?h.getFormatting().getInheritedStyleAttributes(a):null};this.getPositionInTextNode=function(a,b){var e=gui.SelectionMover.createPositionIterator(l()),f=null,g,h=0,m=null;runtime.assert(0<=a,"position must be >= 0");1===d.acceptPosition(e)?(g=e.container(),g.nodeType===Node.TEXT_NODE&&(f=g,h=0)):a+=1;for(;0 @@ -1711,6 +1991,7 @@ ops.OdtDocument.signalOperationExecuted="operation/executed";ops.OdtDocument.sig @source: http://gitorious.org/webodf/webodf/ */ runtime.loadClass("ops.TrivialUserModel");runtime.loadClass("ops.TrivialOperationRouter");runtime.loadClass("ops.OperationFactory");runtime.loadClass("ops.OdtDocument"); -ops.Session=function(e){var k=new ops.OdtDocument(e),l=new ops.TrivialUserModel,p=null;this.setUserModel=function(e){l=e};this.setOperationRouter=function(e){p=e;e.setPlaybackFunction(function(e){e.execute(k);k.emit(ops.OdtDocument.signalOperationExecuted,e)});e.setOperationFactory(new ops.OperationFactory)};this.getUserModel=function(){return l};this.getOdtDocument=function(){return k};this.enqueue=function(e){p.push(e)};this.setOperationRouter(new ops.TrivialOperationRouter)}; -// Input 73 +ops.Session=function(h){var l=new ops.OperationFactory,f=new ops.OdtDocument(h),q=new ops.TrivialUserModel,p=null;this.setUserModel=function(f){q=f};this.setOperationFactory=function(f){l=f;p&&p.setOperationFactory(l)};this.setOperationRouter=function(g){p=g;g.setPlaybackFunction(function(a){a.execute(f);f.emit(ops.OdtDocument.signalOperationExecuted,a)});g.setOperationFactory(l)};this.getUserModel=function(){return q};this.getOperationFactory=function(){return l};this.getOdtDocument=function(){return f}; +this.enqueue=function(f){p.push(f)};this.setOperationRouter(new ops.TrivialOperationRouter)}; +// Input 81 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 runtimens url(urn:webodf); /* namespace for runtime only */\n@namespace cursor url(urn:webodf:names:cursor);\n@namespace editinfo url(urn:webodf:names:editinfo);\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*[runtimens|containsparagraphanchor] {\n position: relative;\n}\ntext|s {\n white-space: pre;\n}\ntext|tab {\n display: inline;\n white-space: pre;\n}\ntext|line-break {\n content: \" \";\n display: block;\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|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}\ncursor|cursor > span {\n display: inline;\n position: absolute;\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";