diff --git a/ajax/otpoll.php b/ajax/otpoll.php index df3df90b..0d85e497 100644 --- a/ajax/otpoll.php +++ b/ajax/otpoll.php @@ -50,50 +50,6 @@ try{ $command = $request->getParam('command'); switch ($command){ - case 'query_memberdata_list': - $ids = $request->getParam('args/member_ids'); - - $member = new Db_Member(); - $members = $member->getCollectionBy('member_id', $ids); - - $response["memberdata_list"] = array_map( - function($x){ - $x['display_name'] = \OCP\User::getDisplayName($x['uid']); - - // Do we have OC_Avatar in out disposal? - if (!class_exists('\OC_Avatar') || \OC_Config::getValue('enable_avatars', true) !== true){ - //$x['avatar_url'] = \OCP\Util::linkToRoute('documents_user_avatar'); - $x['avatar_url'] = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw=='; - } else { - // https://github.com/owncloud/documents/issues/51 - // Temporary stub - - $x['avatar_url'] = $x['uid']; - - /* - $avatar = new \OC_Avatar($x['uid']); - $image = $avatar->get(64); - // User has an avatar - if ($image instanceof \OC_Image) { - $x['avatar_url'] = \OC_Helper::linkToRoute( - 'core_avatar_get', - array( 'user' => $x['uid'], 'size' => 64) - ) . '?requesttoken=' . \OC::$session->get('requesttoken'); - } else { - //shortcircuit if it's not an image - $x['avatar_url'] = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw=='; - } - - */ - } - - - return $x; - }, - $members - ); - - break; case 'sync_ops': $seqHead = (string) $request->getParam('args/seq_head'); if (!is_null($seqHead)){ diff --git a/ajax/userController.php b/ajax/userController.php index 783d411a..21646219 100644 --- a/ajax/userController.php +++ b/ajax/userController.php @@ -32,6 +32,8 @@ class UserController extends Controller{ $memberData = $member->getData(); if ($memberData['es_id']===$esId){ $member->deactivate(array($args['member_id'])); + $op = new Db_Op(); + $op->removeMember($esId, $args['member_id']); } } \OCP\JSON::success(); diff --git a/js/3rdparty/webodf/editor/Editor.js b/js/3rdparty/webodf/editor/Editor.js index 3ffb0ba6..e05638b6 100644 --- a/js/3rdparty/webodf/editor/Editor.js +++ b/js/3rdparty/webodf/editor/Editor.js @@ -124,7 +124,20 @@ define("webodf/editor/Editor", [ * @return {undefined} */ this.openDocument = function (docUrl, memberId, editorReadyCallback) { - initDocLoading(docUrl, memberId, editorReadyCallback); + initDocLoading(docUrl, memberId, function () { + runtime.loadClass("ops.OpAddMember"); + var op = new ops.OpAddMember(); + op.init({ + memberid: memberId, + setProperties: { + fullName: runtime.tr("Unknown Author"), + color: "black", + imageUrl: "avatar-joe.png" + } + }); + session.enqueue([op]); + editorReadyCallback(); + }); }; /** @@ -134,6 +147,14 @@ define("webodf/editor/Editor", [ */ this.closeDocument = function (callback) { runtime.assert(session, "session should exist here."); + runtime.loadClass("ops.OpRemoveMember"); + + var op = new ops.OpRemoveMember(); + op.init({ + memberid: editorSession.sessionController.getInputMemberId() + }); + session.enqueue([op]); + session.close(function (err) { if (err) { callback(err); @@ -195,16 +216,12 @@ define("webodf/editor/Editor", [ */ this.openSession = function (sessionId, memberId, editorReadyCallback) { initDocLoading(server.getGenesisUrl(sessionId), memberId, function () { - var opRouter, memberModel; - // overwrite router and member model + // overwrite router // TODO: serverFactory should be a backendFactory, // and there should be a backendFactory for local editing - opRouter = serverFactory.createOperationRouter(sessionId, memberId, server, odfCanvas.odfContainer()); + var opRouter = serverFactory.createOperationRouter(sessionId, memberId, server, odfCanvas.odfContainer()); session.setOperationRouter(opRouter); - memberModel = serverFactory.createMemberModel(sessionId, server); - session.setMemberModel(memberModel); - opRouter.requestReplay(function done() { editorReadyCallback(); }); diff --git a/js/3rdparty/webodf/editor/EditorSession.js b/js/3rdparty/webodf/editor/EditorSession.js index 575eb89d..b96f4a7e 100644 --- a/js/3rdparty/webodf/editor/EditorSession.js +++ b/js/3rdparty/webodf/editor/EditorSession.js @@ -82,8 +82,11 @@ define("webodf/editor/EditorSession", [ domUtils = new core.DomUtils(), eventNotifier = new core.EventNotifier([ EditorSession.signalMemberAdded, + EditorSession.signalMemberUpdated, EditorSession.signalMemberRemoved, + EditorSession.signalCursorAdded, EditorSession.signalCursorMoved, + EditorSession.signalCursorRemoved, EditorSession.signalParagraphChanged, EditorSession.signalCommonStyleCreated, EditorSession.signalCommonStyleDeleted, @@ -211,13 +214,25 @@ define("webodf/editor/EditorSession", [ paragraphRange.detach(); } + function onMemberAdded(member) { + self.emit(EditorSession.signalMemberAdded, member.getMemberId()); + } + + function onMemberUpdated(member) { + self.emit(EditorSession.signalMemberUpdated, member.getMemberId()); + } + + function onMemberRemoved(memberId) { + self.emit(EditorSession.signalMemberRemoved, memberId); + } + function onCursorAdded(cursor) { - self.emit(EditorSession.signalMemberAdded, cursor.getMemberId()); + self.emit(EditorSession.signalCursorAdded, cursor.getMemberId()); trackCursor(cursor); } function onCursorRemoved(memberId) { - self.emit(EditorSession.signalMemberRemoved, memberId); + self.emit(EditorSession.signalCursorRemoved, memberId); } function onCursorMoved(cursor) { @@ -267,14 +282,6 @@ define("webodf/editor/EditorSession", [ eventNotifier.unsubscribe(eventid, cb); }; - this.getMemberDetailsAndUpdates = function (memberId, subscriber) { - return session.getMemberModel().getMemberDetailsAndUpdates(memberId, subscriber); - }; - - this.unsubscribeMemberDetailsUpdates = function (memberId, subscriber) { - return session.getMemberModel().unsubscribeMemberDetailsUpdates(memberId, subscriber); - }; - this.getCursorPosition = function () { return odtDocument.getCursorPosition(localMemberId); }; @@ -513,6 +520,14 @@ define("webodf/editor/EditorSession", [ self.sessionController.getImageManager().insertImage(mimetype, content, width, height); }; + /** + * @param {!string} memberId + * @return {?ops.Member} + */ + this.getMember = function (memberId) { + return odtDocument.getMember(memberId); + }; + /** * @param {!function(!Object=)} callback, passing an error object in case of error * @return {undefined} @@ -522,6 +537,9 @@ define("webodf/editor/EditorSession", [ head.removeChild(fontStyles); + odtDocument.unsubscribe(ops.OdtDocument.signalMemberAdded, onMemberAdded); + odtDocument.unsubscribe(ops.OdtDocument.signalMemberUpdated, onMemberUpdated); + odtDocument.unsubscribe(ops.OdtDocument.signalMemberRemoved, onMemberRemoved); odtDocument.unsubscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); @@ -578,6 +596,9 @@ define("webodf/editor/EditorSession", [ self.availableFonts = getAvailableFonts(); selectionViewManager.registerCursor(shadowCursor, true); // Custom signals, that make sense in the Editor context. We do not want to expose webodf's ops signals to random bits of the editor UI. + odtDocument.subscribe(ops.OdtDocument.signalMemberAdded, onMemberAdded); + odtDocument.subscribe(ops.OdtDocument.signalMemberUpdated, onMemberUpdated); + odtDocument.subscribe(ops.OdtDocument.signalMemberRemoved, onMemberRemoved); odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); @@ -592,7 +613,10 @@ define("webodf/editor/EditorSession", [ }; /**@const*/EditorSession.signalMemberAdded = "memberAdded"; + /**@const*/EditorSession.signalMemberUpdated = "memberUpdated"; /**@const*/EditorSession.signalMemberRemoved = "memberRemoved"; + /**@const*/EditorSession.signalCursorAdded = "cursorAdded"; + /**@const*/EditorSession.signalCursorRemoved = "cursorRemoved"; /**@const*/EditorSession.signalCursorMoved = "cursorMoved"; /**@const*/EditorSession.signalParagraphChanged = "paragraphChanged"; /**@const*/EditorSession.signalCommonStyleCreated = "styleCreated"; diff --git a/js/3rdparty/webodf/editor/MemberListView.js b/js/3rdparty/webodf/editor/MemberListView.js index 231db2d7..f9fbb830 100644 --- a/js/3rdparty/webodf/editor/MemberListView.js +++ b/js/3rdparty/webodf/editor/MemberListView.js @@ -73,14 +73,14 @@ define("webodf/editor/MemberListView", while (node) { if (node.localName === "img") { // update avatar image - node.src = memberDetails.imageurl; + node.src = memberDetails.imageUrl; // update border color node.style.borderColor = memberDetails.color; - } else if (node.localName === "span" && memberDetails.imageurl){ - $(node).avatar(memberDetails.imageurl, 60); + } else if (node.localName === "span" && memberDetails.imageUrl){ + $(node).avatar(memberDetails.imageUrl, 60); node.style.borderColor = memberDetails.color; } else if (node.localName === "div") { - node.setAttribute('fullname', memberDetails.fullname); + node.setAttribute('fullname', memberDetails.fullName); } node = node.nextSibling; } @@ -142,8 +142,21 @@ define("webodf/editor/MemberListView", * @return {undefined} */ function addMember(memberId) { + var member = editorSession.getMember(memberId), + properties = member.getProperties(); createAvatarButton(memberId); - editorSession.getMemberDetailsAndUpdates(memberId, updateAvatarButton); + updateAvatarButton(memberId, properties); + } + + /** + * @param {!string} memberId + * @return {undefined} + */ + function updateMember(memberId) { + var member = editorSession.getMember(memberId), + properties = member.getProperties(); + + updateAvatarButton(memberId, properties); } /** @@ -151,7 +164,6 @@ define("webodf/editor/MemberListView", * @return {undefined} */ function removeMember(memberId) { - editorSession.unsubscribeMemberDetailsUpdates(memberId, updateAvatarButton); removeAvatarButton(memberId); } @@ -161,14 +173,12 @@ define("webodf/editor/MemberListView", if (editorSession) { // unsubscribe from editorSession editorSession.unsubscribe(EditorSession.signalMemberAdded, addMember); + editorSession.unsubscribe(EditorSession.signalMemberUpdated, updateMember); editorSession.unsubscribe(EditorSession.signalMemberRemoved, removeMember); // remove all current avatars node = memberListDiv.firstChild; while (node) { nextNode = node.nextSibling; - if (node.memberId) { - editorSession.unsubscribeMemberDetailsUpdates(node.memberId, updateAvatarButton); - } memberListDiv.removeChild(node); node = nextNode; } @@ -185,6 +195,7 @@ define("webodf/editor/MemberListView", editorSession = session; if (editorSession) { editorSession.subscribe(EditorSession.signalMemberAdded, addMember); + editorSession.subscribe(EditorSession.signalMemberUpdated, updateMember); editorSession.subscribe(EditorSession.signalMemberRemoved, removeMember); } }; diff --git a/js/3rdparty/webodf/editor/server/ServerFactory.js b/js/3rdparty/webodf/editor/server/ServerFactory.js index e60c16d4..c028c426 100644 --- a/js/3rdparty/webodf/editor/server/ServerFactory.js +++ b/js/3rdparty/webodf/editor/server/ServerFactory.js @@ -57,13 +57,6 @@ ServerFactory.prototype.createServer = function () {"use strict"; }; */ ServerFactory.prototype.createOperationRouter = function (sessionId, memberId, server, odfContainer) {"use strict"; }; -/** - * @param {!string} sessionId - * @param {!ops.Server} server - * @return {!ops.MemberModel} - */ -ServerFactory.prototype.createMemberModel = function (sessionId, server) {"use strict"; }; - /** * @param {!ops.Server} server * @return {!SessionList} diff --git a/js/3rdparty/webodf/editor/server/owncloud/ServerFactory.js b/js/3rdparty/webodf/editor/server/owncloud/ServerFactory.js index c8111cfa..7c4e1067 100644 --- a/js/3rdparty/webodf/editor/server/owncloud/ServerFactory.js +++ b/js/3rdparty/webodf/editor/server/owncloud/ServerFactory.js @@ -27,10 +27,9 @@ define("webodf/editor/server/owncloud/ServerFactory", [ "webodf/editor/server/pullbox/Server", - "webodf/editor/server/pullbox/MemberModel", "webodf/editor/server/pullbox/OperationRouter", "webodf/editor/server/pullbox/SessionList"], - function (PullBoxServer, PullBoxMemberModel, PullBoxOperationRouter, PullBoxSessionList) { + function (PullBoxServer, PullBoxOperationRouter, PullBoxSessionList) { "use strict"; /** @@ -54,9 +53,6 @@ define("webodf/editor/server/owncloud/ServerFactory", [ this.createOperationRouter = function (sid, mid, server, odfContainer) { return new PullBoxOperationRouter(sid, mid, server, odfContainer); }; - this.createMemberModel = function (sid, server) { - return new PullBoxMemberModel(sid, server); - }; this.createSessionList = function (server) { return new PullBoxSessionList(server); }; diff --git a/js/3rdparty/webodf/editor/server/pullbox/MemberModel.js b/js/3rdparty/webodf/editor/server/pullbox/MemberModel.js deleted file mode 100644 index 9303a1cf..00000000 --- a/js/3rdparty/webodf/editor/server/pullbox/MemberModel.js +++ /dev/null @@ -1,279 +0,0 @@ -/** - * @license - * Copyright (C) 2013 KO GmbH - * - * @licstart - * This file is part of WebODF. - * - * WebODF is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License (GNU AGPL) - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * WebODF is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with WebODF. If not, see . - * @licend - * - * @source: http://www.webodf.org/ - * @source: https://github.com/kogmbh/WebODF/ - */ - -/*global runtime, ops*/ - -define("webodf/editor/server/pullbox/MemberModel", [], function () { - "use strict"; - - /** - * @constructor - * @implements ops.MemberModel - */ - return function PullBoxMemberModel(sessionId, server) { - - var cachedMemberData = {}, - memberDataSubscribers = {}, - isServerPullingActivated = false, - isServerPullingOpen = true, - serverPullingTimeoutId = null, - isInstantPullingRequested = false, - isPulling = false, - /**@const*/pullingIntervall = 20000; - - - /** - * @param {!Object} memberData - */ - function cacheMemberDatum(memberData) { - var subscribers, - i; - - // notify all subscribers who are interested in this data - subscribers = memberDataSubscribers[memberData.memberid]; - if (subscribers) { - // cache - cachedMemberData[memberData.memberid] = memberData; - - for (i = 0; i < subscribers.length; i += 1) { - subscribers[i](memberData.memberid, memberData); - } - } - } - - function pullMemberData() { - var i, - memberIds = Object.keys(memberDataSubscribers); - - if (!isServerPullingOpen || isPulling) { - return; - } - - // no more timeout or instant pull request in any case - serverPullingTimeoutId = null; - isInstantPullingRequested = false; - // set lock - isPulling = true; - - runtime.log("member-list request for : " + memberIds.join(",")); - - server.call({ - command: 'query_memberdata_list', - args: { - es_id: sessionId, - member_ids: memberIds - } - }, function(responseData) { - var response = /**@type {{memberdata_list:Array.<{uid,member_id,display_name,avatar_url,color}>}}*/(runtime.fromJson(responseData)), - memberDataList, - newMemberData, oldMemberData; - - // unlock - isPulling = false; - - // meanwhile closed/disactivated? - if (!isServerPullingOpen || !isServerPullingActivated) { - return; - } - - runtime.log("member-list reply: " + responseData); - - if (response.hasOwnProperty("memberdata_list")) { - - // add/update with all delivered memberdata - memberDataList = response.memberdata_list; - for (i = 0; i < memberDataList.length; i+=1) { - newMemberData = { - memberid: memberDataList[i].member_id, - fullname: memberDataList[i].display_name, - imageurl: memberDataList[i].avatar_url, - color: memberDataList[i].color - }; - - oldMemberData = cachedMemberData.hasOwnProperty(newMemberData.memberid) ? cachedMemberData[newMemberData.memberid] : null; - if (!oldMemberData || - oldMemberData.fullname !== newMemberData.fullname || - oldMemberData.imageurl !== newMemberData.imageurl || - oldMemberData.color !== newMemberData.color) { - cacheMemberDatum(newMemberData); - } - } - } else { - runtime.log("Meh, memberdata list broken: " + responseData); - } - - // trigger the next pulling - if (isInstantPullingRequested) { - pullMemberData(); - } else { - serverPullingTimeoutId = runtime.setTimeout(pullMemberData, pullingIntervall); - } - }); - } - - /** - * Activates the pulling - * @return {undefined} - */ - function pullNewMemberData() { - // cancel any running pulling timeout - if (serverPullingTimeoutId !== null) { - runtime.clearTimeout(serverPullingTimeoutId); - } - - isInstantPullingRequested = true; - isServerPullingActivated = true; - - pullMemberData(); - } - - /** - * Deactivates the pulling if there are no more subscribers - * @return {undefined} - */ - function deactivatePeriodicMemberDataPulling() { - var key; - - if (!isServerPullingActivated) { - return; - } - - // check if there is no more subscription - for(key in memberDataSubscribers) { - if (memberDataSubscribers.hasOwnProperty(key)) { - // still subscribers, cannot deactivate yet - return; - } - } - - isServerPullingActivated = false; - // cancel any running pulling timeout - if (serverPullingTimeoutId !== null) { - runtime.clearTimeout(serverPullingTimeoutId); - } - } - - /** - * callback is called as soon as the memberdata is available and after that - * on every memberdata update. - * a parameter `null` passed to the callback means that the member is finally - * not known. - * - * @param {!string} memberId - * @param {!function(!string, ?Object)} subscriber - * @return {undefined} - */ - this.getMemberDetailsAndUpdates = function (memberId, subscriber) { - var /**@type{Object}*/ - memberData = cachedMemberData[memberId], - subscribers = memberDataSubscribers[memberId] || [], - i; - memberDataSubscribers[memberId] = subscribers; - - runtime.assert(subscriber !== undefined, "missing callback"); - - // detect double subscription - for (i=0; i= 3 - data = runtime.byteArrayToString(data, "binary"); - } try { - if (xhr.sendAsBinary) { - xhr.sendAsBinary(data); - } else { - xhr.send(data); - } + xhr.send(messageString); } catch (e) { runtime.log("Problem with calling server: " + e + " " + data); cb(e.message); diff --git a/js/3rdparty/webodf/editor/server/pullbox/ServerFactory.js b/js/3rdparty/webodf/editor/server/pullbox/ServerFactory.js index dc07ba64..b2b5478c 100644 --- a/js/3rdparty/webodf/editor/server/pullbox/ServerFactory.js +++ b/js/3rdparty/webodf/editor/server/pullbox/ServerFactory.js @@ -27,10 +27,9 @@ define("webodf/editor/server/pullbox/ServerFactory", [ "webodf/editor/server/pullbox/Server", - "webodf/editor/server/pullbox/MemberModel", "webodf/editor/server/pullbox/OperationRouter", "webodf/editor/server/pullbox/SessionList"], - function (PullBoxServer, PullBoxMemberModel, PullBoxOperationRouter, PullBoxSessionList) { + function (PullBoxServer, PullBoxOperationRouter, PullBoxSessionList) { "use strict"; /** @@ -44,9 +43,6 @@ define("webodf/editor/server/pullbox/ServerFactory", [ this.createOperationRouter = function (sid, mid, server, odfContainer) { return new PullBoxOperationRouter(sid, mid, server, odfContainer); }; - this.createMemberModel = function (sid, server) { - return new PullBoxMemberModel(sid, server); - }; this.createSessionList = function (server) { return new PullBoxSessionList(server); }; diff --git a/js/3rdparty/webodf/editor/widgets/annotation.js b/js/3rdparty/webodf/editor/widgets/annotation.js index 013d199b..cf2d506c 100644 --- a/js/3rdparty/webodf/editor/widgets/annotation.js +++ b/js/3rdparty/webodf/editor/widgets/annotation.js @@ -48,7 +48,7 @@ define("webodf/editor/widgets/annotation", [ var self = this, widget = {}, addAnnotationButton, - annotationManager; + annotationController; addAnnotationButton = new Button({ @@ -57,8 +57,8 @@ define("webodf/editor/widgets/annotation", [ showLabel: false, iconClass: 'dijitIconBookmark', onClick: function () { - if (annotationManager) { - annotationManager.addAnnotation(); + if (annotationController) { + annotationController.addAnnotation(); self.onToolDone(); } } @@ -83,14 +83,14 @@ define("webodf/editor/widgets/annotation", [ } this.setEditorSession = function (session) { - if (annotationManager) { - annotationManager.unsubscribe(gui.AnnotationManager.annotatableChanged, onAnnotatableChanged); + if (annotationController) { + annotationController.unsubscribe(gui.AnnotationController.annotatableChanged, onAnnotatableChanged); } - annotationManager = session && session.sessionController.getAnnotationManager(); - if (annotationManager) { - annotationManager.subscribe(gui.AnnotationManager.annotatableChanged, onAnnotatableChanged); + annotationController = session && session.sessionController.getAnnotationController(); + if (annotationController) { + annotationController.subscribe(gui.AnnotationController.annotatableChanged, onAnnotatableChanged); } - onAnnotatableChanged(annotationManager && annotationManager.isAnnotatable()); + onAnnotatableChanged(annotationController && annotationController.isAnnotatable()); }; this.onToolDone = function () {}; diff --git a/js/3rdparty/webodf/webodf-debug.js b/js/3rdparty/webodf/webodf-debug.js index 3e014e51..52a5ea3d 100644 --- a/js/3rdparty/webodf/webodf-debug.js +++ b/js/3rdparty/webodf/webodf-debug.js @@ -43,25 +43,16 @@ var odf = {}; var ops = {}; function Runtime() { } -Runtime.ByteArray = function(size) { -}; Runtime.prototype.getVariable = function(name) { }; Runtime.prototype.toJson = function(anything) { }; Runtime.prototype.fromJson = function(jsonstr) { }; -Runtime.ByteArray.prototype.slice = function(start, end) { -}; -Runtime.ByteArray.prototype.length = 0; -Runtime.prototype.byteArrayFromArray = function(array) { -}; Runtime.prototype.byteArrayFromString = function(string, encoding) { }; Runtime.prototype.byteArrayToString = function(bytearray, encoding) { }; -Runtime.prototype.concatByteArrays = function(bytearray1, bytearray2) { -}; Runtime.prototype.read = function(path, offset, length, callback) { }; Runtime.prototype.readFile = function(path, encoding, callback) { @@ -106,34 +97,38 @@ Runtime.byteArrayToString = function(bytearray, encoding) { return s } function utf8ByteArrayToString(bytearray) { - var s = "", i, l = bytearray.length, c0, c1, c2, c3, codepoint; + var s = "", i, l = bytearray.length, chars = [], c0, c1, c2, c3, codepoint; for(i = 0;i < l;i += 1) { - c0 = bytearray[i]; + c0 = (bytearray[i]); if(c0 < 128) { - s += String.fromCharCode(c0) + chars.push(c0) }else { i += 1; - c1 = bytearray[i]; + c1 = (bytearray[i]); if(c0 >= 194 && c0 < 224) { - s += String.fromCharCode((c0 & 31) << 6 | c1 & 63) + chars.push((c0 & 31) << 6 | c1 & 63) }else { i += 1; - c2 = bytearray[i]; + c2 = (bytearray[i]); if(c0 >= 224 && c0 < 240) { - s += String.fromCharCode((c0 & 15) << 12 | (c1 & 63) << 6 | c2 & 63) + chars.push((c0 & 15) << 12 | (c1 & 63) << 6 | c2 & 63) }else { i += 1; - c3 = bytearray[i]; + c3 = (bytearray[i]); if(c0 >= 240 && c0 < 245) { codepoint = (c0 & 7) << 18 | (c1 & 63) << 12 | (c2 & 63) << 6 | c3 & 63; codepoint -= 65536; - s += String.fromCharCode((codepoint >> 10) + 55296, (codepoint & 1023) + 56320) + chars.push((codepoint >> 10) + 55296, (codepoint & 1023) + 56320) } } } } + if(chars.length === 1E3) { + s += String.fromCharCode.apply(null, chars); + chars.length = 0 + } } - return s + return s + String.fromCharCode.apply(null, chars) } var result; if(encoding === "utf8") { @@ -168,50 +163,14 @@ Runtime.getFunctionName = function getFunctionName(f) { return f.name }; function BrowserRuntime(logoutput) { - var self = this, cache = {}, useNativeArray = window.ArrayBuffer && window.Uint8Array; - if(useNativeArray) { - Uint8Array.prototype.slice = function(begin, end) { - if(end === undefined) { - if(begin === undefined) { - begin = 0 - } - end = this.length - } - var view = this.subarray(begin, end), array, i; - end -= begin; - array = new Uint8Array(new ArrayBuffer(end)); - for(i = 0;i < end;i += 1) { - array[i] = view[i] - } - return array - } - } - this.ByteArray = useNativeArray ? function ByteArray(size) { - return new Uint8Array(new ArrayBuffer(size)) - } : function ByteArray(size) { - var a = []; - a.length = size; - return a - }; - this.concatByteArrays = useNativeArray ? function(bytearray1, bytearray2) { - var i, l1 = bytearray1.length, l2 = bytearray2.length, a = new this.ByteArray(l1 + l2); - for(i = 0;i < l1;i += 1) { - a[i] = bytearray1[i] - } - for(i = 0;i < l2;i += 1) { - a[i + l1] = bytearray2[i] - } - return a - } : function(bytearray1, bytearray2) { - return bytearray1.concat(bytearray2) - }; + var self = this, cache = {}; function utf8ByteArrayFromString(string) { var l = string.length, bytearray, i, n, j = 0; for(i = 0;i < l;i += 1) { n = string.charCodeAt(i); j += 1 + (n > 128) + (n > 2048) } - bytearray = new self.ByteArray(j); + bytearray = new Uint8Array(new ArrayBuffer(j)); j = 0; for(i = 0;i < l;i += 1) { n = string.charCodeAt(i); @@ -234,15 +193,12 @@ function BrowserRuntime(logoutput) { return bytearray } function byteArrayFromString(string) { - var l = string.length, a = new self.ByteArray(l), i; + var l = string.length, a = new Uint8Array(new ArrayBuffer(l)), i; for(i = 0;i < l;i += 1) { a[i] = string.charCodeAt(i) & 255 } return a } - this.byteArrayFromArray = function(array) { - return array.slice() - }; this.byteArrayFromString = function(string, encoding) { var result; if(encoding === "utf8") { @@ -301,38 +257,49 @@ function BrowserRuntime(logoutput) { throw message; } } - function readFile(path, encoding, callback) { - if(cache.hasOwnProperty(path)) { - callback(null, cache[path]); - return + function arrayToUint8Array(buffer) { + var l = buffer.length, i, a = new Uint8Array(new ArrayBuffer(l)); + for(i = 0;i < l;i += 1) { + a[i] = buffer[i] } - var xhr = new XMLHttpRequest; - function handleResult() { - var data; - if(xhr.readyState === 4) { - if(xhr.status === 0 && !xhr.responseText) { - callback("File " + path + " is empty.") + return a + } + function handleXHRResult(path, encoding, xhr) { + var data, r, d, a; + if(xhr.status === 0 && !xhr.responseText) { + r = {err:"File " + path + " is empty.", data:null} + }else { + if(xhr.status === 200 || xhr.status === 0) { + if(xhr.response && typeof xhr.response !== "string") { + if(encoding === "binary") { + d = (xhr.response); + data = new Uint8Array(d) + }else { + data = String(xhr.response) + } }else { - if(xhr.status === 200 || xhr.status === 0) { - if(encoding === "binary") { - if(xhr.responseBody !== null && String(typeof VBArray) !== "undefined") { - data = (new VBArray(xhr.responseBody)).toArray() - }else { - data = self.byteArrayFromString(xhr.responseText, "binary") - } + if(encoding === "binary") { + if(xhr.responseBody !== null && String(typeof VBArray) !== "undefined") { + a = (new VBArray(xhr.responseBody)).toArray(); + data = arrayToUint8Array(a) }else { - data = xhr.responseText + data = self.byteArrayFromString(xhr.responseText, "binary") } - cache[path] = data; - callback(null, data) }else { - callback(xhr.responseText || xhr.statusText) + data = xhr.responseText } } + cache[path] = data; + r = {err:null, data:data} + }else { + r = {err:xhr.responseText || xhr.statusText, data:null} } } - xhr.open("GET", path, true); - xhr.onreadystatechange = handleResult; + return r + } + function createXHR(path, encoding, async) { + var xhr = new XMLHttpRequest; + xhr.open("GET", path, async); if(xhr.overrideMimeType) { if(encoding !== "binary") { xhr.overrideMimeType("text/plain; charset=" + encoding) @@ -340,77 +307,59 @@ function BrowserRuntime(logoutput) { xhr.overrideMimeType("text/plain; charset=x-user-defined") } } - try { - xhr.send(null) - }catch(e) { - callback(e.message) - } + return xhr } - function read(path, offset, length, callback) { + function readFile(path, encoding, callback) { if(cache.hasOwnProperty(path)) { - callback(null, cache[path].slice(offset, offset + length)); + callback(null, cache[path]); return } - var xhr = new XMLHttpRequest; + var xhr = createXHR(path, encoding, true); function handleResult() { - var data; + var r; if(xhr.readyState === 4) { - if(xhr.status === 0 && !xhr.responseText) { - callback("File " + path + " is empty.") - }else { - if(xhr.status === 200 || xhr.status === 0) { - if(xhr.response) { - data = (xhr.response); - data = new Uint8Array(data) - }else { - if(xhr.responseBody !== null && String(typeof VBArray) !== "undefined") { - data = (new VBArray(xhr.responseBody)).toArray() - }else { - data = self.byteArrayFromString(xhr.responseText, "binary") - } - } - cache[path] = data; - callback(null, data.slice(offset, offset + length)) - }else { - callback(xhr.responseText || xhr.statusText) - } - } + r = handleXHRResult(path, encoding, xhr); + callback(r.err, r.data) } } - xhr.open("GET", path, true); xhr.onreadystatechange = handleResult; - if(xhr.overrideMimeType) { - xhr.overrideMimeType("text/plain; charset=x-user-defined") - } - xhr.responseType = "arraybuffer"; try { xhr.send(null) }catch(e) { - callback(e.message) + callback(e.message, null) } } - function readFileSync(path, encoding) { - var xhr = new XMLHttpRequest, result; - xhr.open("GET", path, false); - if(xhr.overrideMimeType) { - if(encoding !== "binary") { - xhr.overrideMimeType("text/plain; charset=" + encoding) - }else { - xhr.overrideMimeType("text/plain; charset=x-user-defined") + function read(path, offset, length, callback) { + readFile(path, "binary", function(err, result) { + var r = null; + if(result) { + if(typeof result === "string") { + throw"This should not happen."; + } + r = (result.subarray(offset, offset + length)) } - } + callback(err, r) + }) + } + function readFileSync(path, encoding) { + var xhr = createXHR(path, encoding, false), r; try { xhr.send(null); - if(xhr.status === 200 || xhr.status === 0) { - result = xhr.responseText + r = handleXHRResult(path, encoding, xhr); + if(r.err) { + throw r.err; } - }catch(ignore) { + if(r.data === null) { + throw"No data read from " + path + "."; + } + }catch(e) { + throw e; } - return result + return r.data } function writeFile(path, data, callback) { cache[path] = data; - var xhr = new XMLHttpRequest; + var xhr = new XMLHttpRequest, d; function handleResult() { if(xhr.readyState === 4) { if(xhr.status === 0 && !xhr.responseText) { @@ -427,15 +376,15 @@ function BrowserRuntime(logoutput) { xhr.open("PUT", path, true); xhr.onreadystatechange = handleResult; if(data.buffer && !xhr.sendAsBinary) { - data = data.buffer + d = data.buffer }else { - data = self.byteArrayToString(data, "binary") + d = self.byteArrayToString(data, "binary") } try { if(xhr.sendAsBinary) { - xhr.sendAsBinary(data) + xhr.sendAsBinary(d) }else { - xhr.send(data) + xhr.send(d) } }catch(e) { self.log("HUH? " + e + " " + data); @@ -462,12 +411,12 @@ function BrowserRuntime(logoutput) { function handleResult() { if(xhr.readyState === 4) { if(xhr.status === 0 && !xhr.responseText) { - callback("File " + path + " is empty.") + callback("File " + path + " is empty.", null) }else { if(xhr.status === 200 || xhr.status === 0) { callback(null, xhr.responseXML) }else { - callback(xhr.responseText) + callback(xhr.responseText, null) } } } @@ -480,7 +429,7 @@ function BrowserRuntime(logoutput) { try { xhr.send(null) }catch(e) { - callback(e.message) + callback(e.message, null) } } function isFile(path, callback) { @@ -489,6 +438,10 @@ function BrowserRuntime(logoutput) { }) } function getFileSize(path, callback) { + if(cache.hasOwnProperty(path) && typeof cache[path] !== "string") { + callback(cache[path].length); + return + } var xhr = new XMLHttpRequest; xhr.open("HEAD", path, true); xhr.onreadystatechange = function() { @@ -552,28 +505,21 @@ function BrowserRuntime(logoutput) { } function NodeJSRuntime() { var self = this, fs = require("fs"), pathmod = require("path"), currentDirectory = "", parser, domImplementation; - this.ByteArray = function(size) { - return new Buffer(size) - }; - this.byteArrayFromArray = function(array) { - var ba = new Buffer(array.length), i, l = array.length; + function bufferToUint8Array(buffer) { + var l = buffer.length, i, a = new Uint8Array(new ArrayBuffer(l)); for(i = 0;i < l;i += 1) { - ba[i] = array[i] + a[i] = buffer[i] } - return ba - }; - this.concatByteArrays = function(a, b) { - var ba = new Buffer(a.length + b.length); - a.copy(ba, 0, 0); - b.copy(ba, a.length, 0); - return ba - }; + return a + } this.byteArrayFromString = function(string, encoding) { - return new Buffer(string, encoding) - }; - this.byteArrayToString = function(bytearray, encoding) { - return bytearray.toString(encoding) + var buf = new Buffer(string, encoding), i, l = buf.length, a = new Uint8Array(new ArrayBuffer(l)); + for(i = 0;i < l;i += 1) { + a[i] = buf[i] + } + return a }; + this.byteArrayToString = Runtime.byteArrayToString; this.getVariable = Runtime.getVariable; this.fromJson = Runtime.fromJson; this.toJson = Runtime.toJson; @@ -584,26 +530,46 @@ function NodeJSRuntime() { }) } function readFile(path, encoding, callback) { + function convert(err, data) { + if(err) { + return callback(err, null) + } + if(!data) { + return callback("No data for " + path + ".", null) + } + var d; + if(typeof data === "string") { + d = (data); + return callback(err, d) + } + d = (data); + callback(err, bufferToUint8Array(d)) + } path = pathmod.resolve(currentDirectory, path); if(encoding !== "binary") { - fs.readFile(path, encoding, callback) + fs.readFile(path, encoding, convert) }else { - fs.readFile(path, null, callback) + fs.readFile(path, null, convert) } } this.readFile = readFile; function loadXML(path, callback) { readFile(path, "utf-8", function(err, data) { if(err) { - return callback(err) + return callback(err, null) } - callback(null, self.parseXML(data)) + if(!data) { + return callback("No data for " + path + ".", null) + } + var d = (data); + callback(null, self.parseXML(d)) }) } this.loadXML = loadXML; this.writeFile = function(path, data, callback) { + var buf = new Buffer(data); path = pathmod.resolve(currentDirectory, path); - fs.writeFile(path, data, "binary", function(err) { + fs.writeFile(path, buf, "binary", function(err) { callback(err || null) }) }; @@ -615,24 +581,28 @@ function NodeJSRuntime() { path = pathmod.resolve(currentDirectory, path); fs.open(path, "r+", 666, function(err, fd) { if(err) { - callback(err); + callback(err, null); return } var buffer = new Buffer(length); fs.read(fd, buffer, 0, length, offset, function(err) { fs.close(fd); - callback(err, buffer) + callback(err, bufferToUint8Array(buffer)) }) }) }; this.readFileSync = function(path, encoding) { - if(!encoding) { - return"" + var enc = encoding === "binary" ? null : encoding, r = fs.readFileSync(path, enc), s; + if(r === null) { + throw"File " + path + " could not be read."; } if(encoding === "binary") { - return fs.readFileSync(path, null) + s = (r); + s = bufferToUint8Array(s) + }else { + s = (r) } - return fs.readFileSync(path, encoding) + return s }; this.isFile = isFile; this.getFileSize = function(path, callback) { @@ -714,21 +684,16 @@ function RhinoRuntime() { dom.setExpandEntityReferences(false); dom.setSchema(null); entityresolver = Packages.org.xml.sax.EntityResolver({resolveEntity:function(publicId, systemId) { - var file, open = function(path) { + var file; + function open(path) { var reader = new Packages.java.io.FileReader(path), source = new Packages.org.xml.sax.InputSource(reader); return source - }; + } file = systemId; return open(file) }}); builder = dom.newDocumentBuilder(); builder.setEntityResolver(entityresolver); - this.ByteArray = function ByteArray(size) { - return[size] - }; - this.byteArrayFromArray = function(array) { - return array - }; this.byteArrayFromString = function(string, encoding) { var a = [], i, l = string.length; for(i = 0;i < l;i += 1) { @@ -740,9 +705,6 @@ function RhinoRuntime() { this.getVariable = Runtime.getVariable; this.fromJson = Runtime.fromJson; this.toJson = Runtime.toJson; - this.concatByteArrays = function(bytearray1, bytearray2) { - return bytearray1.concat(bytearray2) - }; function loadXML(path, callback) { var file = new Packages.java.io.File(path), xmlDocument; try { @@ -825,7 +787,11 @@ function RhinoRuntime() { if(!encoding) { return"" } - return readFile(path, encoding) + var s = readFile(path, encoding); + if(s === null) { + throw"File could not be read."; + } + return s }; this.isFile = isFile; this.getFileSize = function(path, callback) { @@ -930,7 +896,7 @@ var runtime = function() { return } function getPathFromManifests(classpath) { - var path = classpath.replace(/\./g, "/") + ".js", dirs = runtime.libraryPaths(), i, dir, code; + var path = classpath.replace(/\./g, "/") + ".js", dirs = runtime.libraryPaths(), i, dir, code, codestr; if(runtime.currentDirectory) { dirs.push(runtime.currentDirectory()) } @@ -940,7 +906,8 @@ var runtime = function() { try { code = runtime.readFileSync(dirs[i] + "/manifest.js", "utf8"); if(code && code.length) { - dircontents[dir] = eval(code) + codestr = (code); + dircontents[dir] = eval(codestr) }else { dircontents[dir] = null } @@ -1033,11 +1000,16 @@ var runtime = function() { } return } - if(err || codestring === null) { + if(err) { runtime.log(err); runtime.exit(1) }else { - inner_run.apply(null, argv) + if(codestring === null) { + runtime.log("No code found for " + script); + runtime.exit(1) + }else { + inner_run.apply(null, argv) + } } }) } @@ -1051,16 +1023,17 @@ var runtime = function() { } } })(String(typeof arguments) !== "undefined" && arguments); -core.Base64 = function() { - var b64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", b64tab = function(bin) { +function makeBase64() { + function makeB64tab(bin) { var t = {}, i, l; for(i = 0, l = bin.length;i < l;i += 1) { t[bin.charAt(i)] = i } return t - }(b64chars), convertUTF16StringToBase64, convertBase64ToUTF16String, window = runtime.getWindow(), btoa, atob; + } + var b64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", b64tab = makeB64tab(b64chars), convertUTF16StringToBase64, convertBase64ToUTF16String, window = runtime.getWindow(), btoa, atob; function stringToArray(s) { - var a = [], i, l = s.length; + var i, l = s.length, a = new Uint8Array(new ArrayBuffer(l)); for(i = 0;i < l;i += 1) { a[i] = s.charCodeAt(i) & 255 } @@ -1070,22 +1043,22 @@ core.Base64 = function() { var n, b64 = "", i, l = bin.length - 2; for(i = 0;i < l;i += 3) { n = bin[i] << 16 | bin[i + 1] << 8 | bin[i + 2]; - b64 += b64chars[n >>> 18]; - b64 += b64chars[n >>> 12 & 63]; - b64 += b64chars[n >>> 6 & 63]; - b64 += b64chars[n & 63] + b64 += (b64chars[n >>> 18]); + b64 += (b64chars[n >>> 12 & 63]); + b64 += (b64chars[n >>> 6 & 63]); + b64 += (b64chars[n & 63]) } if(i === l + 1) { n = bin[i] << 4; - b64 += b64chars[n >>> 6]; - b64 += b64chars[n & 63]; + b64 += (b64chars[n >>> 6]); + b64 += (b64chars[n & 63]); b64 += "==" }else { if(i === l) { n = bin[i] << 10 | bin[i + 1] << 2; - b64 += b64chars[n >>> 12]; - b64 += b64chars[n >>> 6 & 63]; - b64 += b64chars[n & 63]; + b64 += (b64chars[n >>> 12]); + b64 += (b64chars[n >>> 6 & 63]); + b64 += (b64chars[n & 63]); b64 += "=" } } @@ -1093,49 +1066,55 @@ core.Base64 = function() { } function convertBase64ToUTF8Array(b64) { b64 = b64.replace(/[^A-Za-z0-9+\/]+/g, ""); - var bin = [], padlen = b64.length % 4, i, l = b64.length, n; + var l = b64.length, bin = new Uint8Array(new ArrayBuffer(3 * l)), padlen = b64.length % 4, o = 0, i, n; for(i = 0;i < l;i += 4) { n = (b64tab[b64.charAt(i)] || 0) << 18 | (b64tab[b64.charAt(i + 1)] || 0) << 12 | (b64tab[b64.charAt(i + 2)] || 0) << 6 | (b64tab[b64.charAt(i + 3)] || 0); - bin.push(n >> 16, n >> 8 & 255, n & 255) + bin[o] = n >> 16; + bin[o + 1] = n >> 8 & 255; + bin[o + 2] = n & 255; + o += 3 } - bin.length -= [0, 0, 2, 1][padlen]; - return bin + l = 3 * l - [0, 0, 2, 1][padlen]; + return bin.subarray(0, l) } function convertUTF16ArrayToUTF8Array(uni) { - var bin = [], i, l = uni.length, n; + var i, n, l = uni.length, o = 0, bin = new Uint8Array(new ArrayBuffer(3 * l)); for(i = 0;i < l;i += 1) { - n = uni[i]; + n = (uni[i]); if(n < 128) { - bin.push(n) + bin[o++] = n }else { if(n < 2048) { - bin.push(192 | n >>> 6, 128 | n & 63) + bin[o++] = 192 | n >>> 6; + bin[o++] = 128 | n & 63 }else { - bin.push(224 | n >>> 12 & 15, 128 | n >>> 6 & 63, 128 | n & 63) + bin[o++] = 224 | n >>> 12 & 15; + bin[o++] = 128 | n >>> 6 & 63; + bin[o++] = 128 | n & 63 } } } - return bin + return bin.subarray(0, o) } function convertUTF8ArrayToUTF16Array(bin) { - var uni = [], i, l = bin.length, c0, c1, c2; + var i, c0, c1, c2, l = bin.length, uni = new Uint8Array(new ArrayBuffer(l)), o = 0; for(i = 0;i < l;i += 1) { - c0 = bin[i]; + c0 = (bin[i]); if(c0 < 128) { - uni.push(c0) + uni[o++] = c0 }else { i += 1; - c1 = bin[i]; + c1 = (bin[i]); if(c0 < 224) { - uni.push((c0 & 31) << 6 | c1 & 63) + uni[o++] = (c0 & 31) << 6 | c1 & 63 }else { i += 1; - c2 = bin[i]; - uni.push((c0 & 15) << 12 | (c1 & 63) << 6 | c2 & 63) + c2 = (bin[i]); + uni[o++] = (c0 & 15) << 12 | (c1 & 63) << 6 | c2 & 63 } } } - return uni + return uni.subarray(0, o) } function convertUTF8StringToBase64(bin) { return convertUTF8ArrayToBase64(stringToArray(bin)) @@ -1149,13 +1128,13 @@ core.Base64 = function() { function convertUTF8ArrayToUTF16String(bin) { var b = convertUTF8ArrayToUTF16Array(bin), r = "", i = 0, chunksize = 45E3; while(i < b.length) { - r += String.fromCharCode.apply(String, b.slice(i, i + chunksize)); + r += String.fromCharCode.apply(String, b.subarray(i, i + chunksize)); i += chunksize } return r } function convertUTF8StringToUTF16String_internal(bin, i, end) { - var str = "", c0, c1, c2, j; + var c0, c1, c2, j, str = ""; for(j = i;j < end;j += 1) { c0 = bin.charCodeAt(j) & 255; if(c0 < 128) { @@ -1207,9 +1186,7 @@ core.Base64 = function() { return String.fromCharCode.apply(String, convertUTF16ArrayToUTF8Array(stringToArray(uni))) } if(window && window.btoa) { - btoa = function(b) { - return window.btoa(b) - }; + btoa = window.btoa; convertUTF16StringToBase64 = function(uni) { return btoa(convertUTF16StringToUTF8String(uni)) } @@ -1220,9 +1197,7 @@ core.Base64 = function() { } } if(window && window.atob) { - atob = function(a) { - return window.atob(a) - }; + atob = window.atob; convertBase64ToUTF16String = function(b64) { var b = atob(b64); return convertUTF8StringToUTF16String_internal(b, 0, b.length) @@ -1233,7 +1208,7 @@ core.Base64 = function() { return convertUTF8ArrayToUTF16String(convertBase64ToUTF8Array(b64)) } } - function Base64() { + core.Base64 = function Base64() { this.convertUTF8ArrayToBase64 = convertUTF8ArrayToBase64; this.convertByteArrayToBase64 = convertUTF8ArrayToBase64; this.convertBase64ToUTF8Array = convertBase64ToUTF8Array; @@ -1270,10 +1245,12 @@ core.Base64 = function() { return convertBase64ToUTF16String(a.replace(/[\-_]/g, function(m0) { return m0 === "-" ? "+" : "/" })) - } - } - return Base64 -}(); + }; + return this + }; + return core.Base64 +} +core.Base64 = makeBase64(); core.RawDeflate = function() { var zip_WSIZE = 32768, zip_STORED_BLOCK = 0, zip_STATIC_TREES = 1, zip_DYN_TREES = 2, zip_DEFAULT_LEVEL = 6, zip_FULL_SEARCH = true, zip_INBUFSIZ = 32768, zip_INBUF_EXTRA = 64, zip_OUTBUFSIZ = 1024 * 8, zip_window_size = 2 * zip_WSIZE, zip_MIN_MATCH = 3, zip_MAX_MATCH = 258, zip_BITS = 16, zip_LIT_BUFSIZE = 8192, zip_HASH_BITS = 13, zip_DIST_BUFSIZE = zip_LIT_BUFSIZE, zip_HASH_SIZE = 1 << zip_HASH_BITS, zip_HASH_MASK = zip_HASH_SIZE - 1, zip_WMASK = zip_WSIZE - 1, zip_NIL = 0, zip_TOO_FAR = 4096, zip_MIN_LOOKAHEAD = zip_MAX_MATCH + zip_MIN_MATCH + 1, zip_MAX_DIST = zip_WSIZE - zip_MIN_LOOKAHEAD, zip_SMALLEST = 1, zip_MAX_BITS = 15, zip_MAX_BL_BITS = 7, zip_LENGTH_CODES = 29, zip_LITERALS = 256, zip_END_BLOCK = 256, zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES, zip_D_CODES = 30, zip_BL_CODES = 19, zip_REP_3_6 = 16, zip_REPZ_3_10 = 17, zip_REPZ_11_138 = 18, zip_HEAP_SIZE = 2 * zip_L_CODES + 1, zip_H_SHIFT = parseInt((zip_HASH_BITS + zip_MIN_MATCH - 1) / zip_MIN_MATCH, 10), zip_free_queue, @@ -2297,7 +2274,7 @@ core.RawDeflate = function() { aout[aout.length] = cbuf.join(""); i = zip_deflate_internal(buff, 0, buff.length) } - zip_deflate_data = null; + zip_deflate_data = ""; return aout.join("") }; this.deflate = zip_deflate @@ -2317,15 +2294,30 @@ core.ByteArray = function ByteArray(data) { } }; core.ByteArrayWriter = function ByteArrayWriter(encoding) { - var self = this, data = new runtime.ByteArray(0); + var self = this, length = 0, bufferSize = 1024, data = new Uint8Array(new ArrayBuffer(bufferSize)); + function expand(extraLength) { + var newData; + if(extraLength > bufferSize - length) { + bufferSize = Math.max(2 * bufferSize, length + extraLength); + newData = new Uint8Array(new ArrayBuffer(bufferSize)); + newData.set(data); + data = newData + } + } this.appendByteArrayWriter = function(writer) { - data = runtime.concatByteArrays(data, writer.getByteArray()) + self.appendByteArray(writer.getByteArray()) }; this.appendByteArray = function(array) { - data = runtime.concatByteArrays(data, array) + var l = array.length; + expand(l); + data.set(array, length); + length += l }; this.appendArray = function(array) { - data = runtime.concatByteArrays(data, runtime.byteArrayFromArray(array)) + var l = array.length; + expand(l); + data.set(array, length); + length += l }; this.appendUInt16LE = function(value) { self.appendArray([value & 255, value >> 8 & 255]) @@ -2334,13 +2326,15 @@ core.ByteArrayWriter = function ByteArrayWriter(encoding) { self.appendArray([value & 255, value >> 8 & 255, value >> 16 & 255, value >> 24 & 255]) }; this.appendString = function(string) { - data = runtime.concatByteArrays(data, runtime.byteArrayFromString(string, encoding)) + self.appendByteArray(runtime.byteArrayFromString(string, encoding)) }; this.getLength = function() { - return data.length + return length }; this.getByteArray = function() { - return data + var a = new Uint8Array(new ArrayBuffer(length)); + a.set(data.subarray(0, length)); + return a } }; core.RawInflate = function RawInflate() { @@ -2941,7 +2935,7 @@ core.RawInflate = function RawInflate() { zip_inflate_start(); zip_inflate_data = data; zip_inflate_pos = 0; - var buff = new runtime.ByteArray(size); + var buff = new Uint8Array(new ArrayBuffer(size)); zip_inflate_internal(buff, 0, size); zip_inflate_data = null; return buff @@ -3073,75 +3067,103 @@ core.Utils = function Utils() { @source: https://github.com/kogmbh/WebODF/ */ (function() { - var rangeClientRectsBug; - function rangeClientRectsUntransformedBug(document) { - var range, directBoundingRect, rangeBoundingRect, testContainer, testElement; - if(rangeClientRectsBug === undefined) { - testContainer = document.createElement("div"); - testContainer.style.position = "absolute"; - testContainer.style.left = "-99999px"; - testContainer.style.transform = "scale(2)"; - testContainer.style["-webkit-transform"] = "scale(2)"; - testElement = document.createElement("div"); - testElement.style.width = "10px"; - testElement.style.height = "10px"; - testContainer.appendChild(testElement); - document.body.appendChild(testContainer); - range = testElement.ownerDocument.createRange(); - directBoundingRect = testElement.getBoundingClientRect(); - range.selectNode(testElement); - rangeBoundingRect = range.getBoundingClientRect(); - rangeClientRectsBug = directBoundingRect.height !== rangeBoundingRect.height; - range.detach(); - document.body.removeChild(testContainer) - } - return rangeClientRectsBug + var browserQuirks; + function getBrowserQuirks() { + var range, directBoundingRect, rangeBoundingRect, testContainer, testElement, detectedQuirks, window, document; + if(browserQuirks === undefined) { + window = runtime.getWindow(); + document = window && window.document; + browserQuirks = {rangeBCRIgnoresElementBCR:false, unscaledRangeClientRects:false}; + if(document) { + testContainer = document.createElement("div"); + testContainer.style.position = "absolute"; + testContainer.style.left = "-99999px"; + testContainer.style.transform = "scale(2)"; + testContainer.style["-webkit-transform"] = "scale(2)"; + testElement = document.createElement("div"); + testContainer.appendChild(testElement); + document.body.appendChild(testContainer); + range = document.createRange(); + range.selectNode(testElement); + browserQuirks.rangeBCRIgnoresElementBCR = range.getClientRects().length === 0; + testElement.appendChild(document.createTextNode("Rect transform test")); + directBoundingRect = testElement.getBoundingClientRect(); + rangeBoundingRect = range.getBoundingClientRect(); + browserQuirks.unscaledRangeClientRects = Math.abs(directBoundingRect.height - rangeBoundingRect.height) > 2; + range.detach(); + document.body.removeChild(testContainer); + detectedQuirks = Object.keys(browserQuirks).map(function(quirk) { + return quirk + ":" + String(browserQuirks[quirk]) + }).join(", "); + runtime.log("Detected browser quirks - " + detectedQuirks) + } + } + return browserQuirks } core.DomUtils = function DomUtils() { + var sharedRange = null; + function getSharedRange(doc) { + var range; + if(sharedRange) { + range = sharedRange + }else { + sharedRange = range = (doc.createRange()) + } + return range + } function findStablePoint(container, offset) { - if(offset < container.childNodes.length) { - container = container.childNodes[offset]; + var c = container; + if(offset < c.childNodes.length) { + c = c.childNodes.item(offset); offset = 0; - while(container.firstChild) { - container = container.firstChild + while(c.firstChild) { + c = c.firstChild } }else { - while(container.lastChild) { - container = container.lastChild; - offset = container.nodeType === Node.TEXT_NODE ? container.textContent.length : container.childNodes.length + while(c.lastChild) { + c = c.lastChild; + offset = c.nodeType === Node.TEXT_NODE ? c.textContent.length : c.childNodes.length } } - return{container:container, offset:offset} + return{container:c, offset:offset} } function splitBoundaries(range) { - var modifiedNodes = [], end, splitStart; + var modifiedNodes = [], end, splitStart, node, text; if(range.startContainer.nodeType === Node.TEXT_NODE || range.endContainer.nodeType === Node.TEXT_NODE) { - end = findStablePoint(range.endContainer, range.endOffset); + end = range.endContainer && findStablePoint(range.endContainer, range.endOffset); range.setEnd(end.container, end.offset); - 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) + node = range.endContainer; + if(range.endOffset !== 0 && node.nodeType === Node.TEXT_NODE) { + text = (node); + if(range.endOffset !== text.length) { + modifiedNodes.push(text.splitText(range.endOffset)); + modifiedNodes.push(text) + } } - 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) + node = range.startContainer; + if(range.startOffset !== 0 && node.nodeType === Node.TEXT_NODE) { + text = (node); + if(range.startOffset !== text.length) { + splitStart = text.splitText(range.startOffset); + modifiedNodes.push(text); + modifiedNodes.push(splitStart); + range.setStart(splitStart, 0) + } } } return modifiedNodes } this.splitBoundaries = splitBoundaries; function containsRange(container, insideRange) { - return container.compareBoundaryPoints(container.START_TO_START, insideRange) <= 0 && container.compareBoundaryPoints(container.END_TO_END, insideRange) >= 0 + return container.compareBoundaryPoints(Range.START_TO_START, insideRange) <= 0 && container.compareBoundaryPoints(Range.END_TO_END, insideRange) >= 0 } this.containsRange = containsRange; function rangesIntersect(range1, range2) { - return range1.compareBoundaryPoints(range1.END_TO_START, range2) <= 0 && range1.compareBoundaryPoints(range1.START_TO_END, range2) >= 0 + return range1.compareBoundaryPoints(Range.END_TO_START, range2) <= 0 && range1.compareBoundaryPoints(Range.START_TO_END, range2) >= 0 } this.rangesIntersect = rangesIntersect; function getNodesInRange(range, nodeFilter) { - var document = range.startContainer.ownerDocument, elements = [], root = (range.commonAncestorContainer), n, filterResult, treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ALL, nodeFilter, false); + var document = range.startContainer.ownerDocument, elements = [], rangeRoot = range.commonAncestorContainer, root = (rangeRoot.nodeType === Node.TEXT_NODE ? rangeRoot.parentNode : rangeRoot), n, filterResult, treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ALL, nodeFilter, false); treeWalker.currentNode = range.startContainer; n = range.startContainer; while(n) { @@ -3165,16 +3187,18 @@ core.Utils = function Utils() { } this.getNodesInRange = getNodesInRange; function mergeTextNodes(node, nextNode) { - var mergedNode = null; + var mergedNode = null, text, nextText; if(node.nodeType === Node.TEXT_NODE) { - if(node.length === 0) { - node.parentNode.removeChild(node); + text = (node); + if(text.length === 0) { + text.parentNode.removeChild(text); if(nextNode.nodeType === Node.TEXT_NODE) { mergedNode = nextNode } }else { if(nextNode.nodeType === Node.TEXT_NODE) { - node.appendData(nextNode.data); + nextText = (nextNode); + text.appendData(nextText.data); nextNode.parentNode.removeChild(nextNode) } mergedNode = node @@ -3192,11 +3216,13 @@ core.Utils = function Utils() { } this.normalizeTextNodes = normalizeTextNodes; function rangeContainsNode(limits, node) { - var range = node.ownerDocument.createRange(), nodeLength = node.nodeType === Node.TEXT_NODE ? node.length : node.childNodes.length, result; + var range = node.ownerDocument.createRange(), nodeRange = node.ownerDocument.createRange(), result; range.setStart(limits.startContainer, limits.startOffset); range.setEnd(limits.endContainer, limits.endOffset); - result = range.comparePoint(node, 0) === 0 && range.comparePoint(node, nodeLength) === 0; + nodeRange.selectNodeContents(node); + result = containsRange(range, nodeRange); range.detach(); + nodeRange.detach(); return result } this.rangeContainsNode = rangeContainsNode; @@ -3227,14 +3253,20 @@ core.Utils = function Utils() { } this.getElementsByTagNameNS = getElementsByTagNameNS; function rangeIntersectsNode(range, node) { - var nodeLength = node.nodeType === Node.TEXT_NODE ? node.length : node.childNodes.length; - return range.comparePoint(node, 0) <= 0 && range.comparePoint(node, nodeLength) >= 0 + var nodeRange = node.ownerDocument.createRange(), result; + nodeRange.selectNodeContents(node); + result = rangesIntersect(range, nodeRange); + nodeRange.detach(); + return result } this.rangeIntersectsNode = rangeIntersectsNode; function containsNode(parent, descendant) { - return parent === descendant || parent.contains(descendant) + return parent === descendant || (parent).contains((descendant)) } this.containsNode = containsNode; + function containsNodeForBrokenWebKit(parent, descendant) { + return parent === descendant || Boolean(parent.compareDocumentPosition(descendant) & Node.DOCUMENT_POSITION_CONTAINED_BY) + } function getPositionInContainingNode(node, container) { var offset = 0, n; while(node.parentNode !== container) { @@ -3271,22 +3303,87 @@ core.Utils = function Utils() { return comparison } this.comparePoints = comparePoints; - function containsNodeForBrokenWebKit(parent, descendant) { - return parent === descendant || Boolean(parent.compareDocumentPosition(descendant) & Node.DOCUMENT_POSITION_CONTAINED_BY) - } - this.areRangeRectanglesTransformed = function(document) { - return!rangeClientRectsUntransformedBug(document) - }; function adaptRangeDifferenceToZoomLevel(inputNumber, zoomLevel) { - var window = runtime.getWindow(), document = window && window.document; - if(document && rangeClientRectsUntransformedBug(document)) { + if(getBrowserQuirks().unscaledRangeClientRects) { return inputNumber } return inputNumber / zoomLevel } this.adaptRangeDifferenceToZoomLevel = adaptRangeDifferenceToZoomLevel; + function getBoundingClientRect(node) { + var doc = (node.ownerDocument), quirks = getBrowserQuirks(), range, element; + if(quirks.unscaledRangeClientRects === false || quirks.rangeBCRIgnoresElementBCR) { + if(node.nodeType === Node.ELEMENT_NODE) { + element = (node); + return element.getBoundingClientRect() + } + } + range = getSharedRange(doc); + range.selectNode(node); + return range.getBoundingClientRect() + } + this.getBoundingClientRect = getBoundingClientRect; + function mapKeyValObjOntoNode(node, properties, nsResolver) { + Object.keys(properties).forEach(function(key) { + var parts = key.split(":"), prefix = parts[0], localName = parts[1], ns = nsResolver(prefix), value = properties[key], element; + if(ns) { + element = node.getElementsByTagNameNS(ns, localName)[0]; + if(!element) { + element = node.ownerDocument.createElementNS(ns, key); + node.appendChild(element) + } + element.textContent = value + }else { + runtime.log("Key ignored: " + key) + } + }) + } + this.mapKeyValObjOntoNode = mapKeyValObjOntoNode; + function removeKeyElementsFromNode(node, propertyNames, nsResolver) { + propertyNames.forEach(function(propertyName) { + var parts = propertyName.split(":"), prefix = parts[0], localName = parts[1], ns = nsResolver(prefix), element; + if(ns) { + element = node.getElementsByTagNameNS(ns, localName)[0]; + if(element) { + element.parentNode.removeChild(element) + }else { + runtime.log("Element for " + propertyName + " not found.") + } + }else { + runtime.log("Property Name ignored: " + propertyName) + } + }) + } + this.removeKeyElementsFromNode = removeKeyElementsFromNode; + function getKeyValRepresentationOfNode(node, prefixResolver) { + var properties = {}, currentSibling = node.firstElementChild, prefix; + while(currentSibling) { + prefix = prefixResolver(currentSibling.namespaceURI); + if(prefix) { + properties[prefix + ":" + currentSibling.localName] = currentSibling.textContent + } + currentSibling = currentSibling.nextElementSibling + } + return properties + } + this.getKeyValRepresentationOfNode = getKeyValRepresentationOfNode; + function mapObjOntoNode(node, properties, nsResolver) { + Object.keys(properties).forEach(function(key) { + var parts = key.split(":"), prefix = parts[0], localName = parts[1], ns = nsResolver(prefix), value = properties[key], element; + if(typeof value === "object" && Object.keys(value).length) { + element = node.getElementsByTagNameNS(ns, localName)[0] || node.ownerDocument.createElementNS(ns, key); + node.appendChild(element); + mapObjOntoNode(element, value, nsResolver) + }else { + if(ns) { + node.setAttributeNS(ns, key, value) + } + } + }) + } + this.mapObjOntoNode = mapObjOntoNode; function init(self) { - var window = runtime.getWindow(), appVersion, webKitOrSafari, ie; + var appVersion, webKitOrSafari, ie, window = runtime.getWindow(); if(window === null) { return } @@ -3303,7 +3400,7 @@ core.Utils = function Utils() { })(); runtime.loadClass("core.DomUtils"); core.Cursor = function Cursor(document, memberId) { - var cursorns = "urn:webodf:names:cursor", cursorNode = document.createElementNS(cursorns, "cursor"), anchorNode = document.createElementNS(cursorns, "anchor"), forwardSelection, recentlyModifiedNodes = [], selectedRange, isCollapsed, domUtils = new core.DomUtils; + var cursorns = "urn:webodf:names:cursor", cursorNode = document.createElementNS(cursorns, "cursor"), anchorNode = document.createElementNS(cursorns, "anchor"), forwardSelection, recentlyModifiedNodes = [], selectedRange = null, isCollapsed, domUtils = new core.DomUtils; function putIntoTextNode(node, container, offset) { runtime.assert(Boolean(container), "putCursorIntoTextNode: invalid container"); var parent = container.parentNode; @@ -3332,7 +3429,7 @@ core.Cursor = function Cursor(document, memberId) { putIntoTextNode(node, (container), offset) }else { if(container.nodeType === Node.ELEMENT_NODE) { - container.insertBefore(node, container.childNodes[offset]) + container.insertBefore(node, container.childNodes.item(offset)) } } recentlyModifiedNodes.push(node.previousSibling); @@ -3457,9 +3554,11 @@ core.EventNotifier = function EventNotifier(eventIds) { runtime.log('event "' + eventId + '" unsubscribed.') }; function init() { - var i; + var i, eventId; for(i = 0;i < eventIds.length;i += 1) { - eventListener[eventIds[i]] = [] + eventId = eventIds[i]; + runtime.assert(!eventListener.hasOwnProperty(eventId), 'Duplicated event ids: "' + eventId + '" registered more than once.'); + eventListener[eventId] = [] } } init() @@ -3689,7 +3788,7 @@ core.UnitTester = function UnitTester() { return"" + text + "" } this.runTests = function(TestClass, callback, testNames) { - var testName = Runtime.getFunctionName(TestClass), tname, runner = new core.UnitTestRunner, test = new TestClass(runner), testResults = {}, i, t, tests, lastFailCount, testNameString = "testName", inBrowser = runtime.type() === "BrowserRuntime"; + var testName = Runtime.getFunctionName(TestClass) || "", tname, runner = new core.UnitTestRunner, test = new TestClass(runner), testResults = {}, i, t, tests, lastFailCount, testNameString = "testName", inBrowser = runtime.type() === "BrowserRuntime"; if(results.hasOwnProperty(testName)) { runtime.log("Test " + testName + " has already run."); return @@ -3745,33 +3844,36 @@ core.UnitTester = function UnitTester() { } }; core.PositionIterator = function PositionIterator(root, whatToShow, filter, expandEntityReferences) { + var self = this, walker, currentPos, nodeFilter, TEXT_NODE = Node.TEXT_NODE, ELEMENT_NODE = Node.ELEMENT_NODE, FILTER_ACCEPT = NodeFilter.FILTER_ACCEPT, FILTER_REJECT = NodeFilter.FILTER_REJECT; function EmptyTextNodeFilter() { this.acceptNode = function(node) { - if(node.nodeType === Node.TEXT_NODE && node.length === 0) { - return NodeFilter.FILTER_REJECT + var text = (node); + if(!node || node.nodeType === TEXT_NODE && text.length === 0) { + return FILTER_REJECT } - return NodeFilter.FILTER_ACCEPT + return FILTER_ACCEPT } } function FilteredEmptyTextNodeFilter(filter) { this.acceptNode = function(node) { - if(node.nodeType === Node.TEXT_NODE && node.length === 0) { - return NodeFilter.FILTER_REJECT + var text = (node); + if(!node || node.nodeType === TEXT_NODE && text.length === 0) { + return FILTER_REJECT } return filter.acceptNode(node) } } - var self = this, walker, currentPos, nodeFilter; this.nextPosition = function() { - if(walker.currentNode === root) { + var currentNode = walker.currentNode, nodeType = currentNode.nodeType, text = (currentNode); + if(currentNode === root) { return false } - if(currentPos === 0 && walker.currentNode.nodeType === Node.ELEMENT_NODE) { + if(currentPos === 0 && nodeType === ELEMENT_NODE) { if(walker.firstChild() === null) { currentPos = 1 } }else { - if(walker.currentNode.nodeType === Node.TEXT_NODE && currentPos + 1 < walker.currentNode.length) { + if(nodeType === TEXT_NODE && currentPos + 1 < text.length) { currentPos += 1 }else { if(walker.nextSibling() !== null) { @@ -3788,11 +3890,11 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa return true }; function setAtEnd() { - var type = walker.currentNode.nodeType; - if(type === Node.TEXT_NODE) { - currentPos = walker.currentNode.length - 1 + var text = (walker.currentNode), type = text.nodeType; + if(type === TEXT_NODE) { + currentPos = text.length - 1 }else { - currentPos = type === Node.ELEMENT_NODE ? 1 : 0 + currentPos = type === ELEMENT_NODE ? 1 : 0 } } function previousNode() { @@ -3808,17 +3910,17 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa return true } this.previousPosition = function() { - var moved = true; + var moved = true, currentNode = walker.currentNode; if(currentPos === 0) { moved = previousNode() }else { - if(walker.currentNode.nodeType === Node.TEXT_NODE) { + if(currentNode.nodeType === TEXT_NODE) { currentPos -= 1 }else { if(walker.lastChild() !== null) { setAtEnd() }else { - if(walker.currentNode === root) { + if(currentNode === root) { moved = false }else { currentPos = 0 @@ -3830,21 +3932,21 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa }; this.previousNode = previousNode; this.container = function() { - var n = walker.currentNode, t = n.nodeType; - if(currentPos === 0 && t !== Node.TEXT_NODE) { - return(n.parentNode) + var n = (walker.currentNode), t = n.nodeType; + if(currentPos === 0 && t !== TEXT_NODE) { + n = (n.parentNode) } return n }; this.rightNode = function() { - var n = walker.currentNode, nodeType = n.nodeType; - if(nodeType === Node.TEXT_NODE && currentPos === n.length) { + var n = walker.currentNode, text = (n), nodeType = n.nodeType; + if(nodeType === TEXT_NODE && currentPos === text.length) { n = n.nextSibling; - while(n && nodeFilter(n) !== 1) { + while(n && nodeFilter(n) !== FILTER_ACCEPT) { n = n.nextSibling } }else { - if(nodeType === Node.ELEMENT_NODE && currentPos === 1) { + if(nodeType === ELEMENT_NODE && currentPos === 1) { n = null } } @@ -3854,13 +3956,13 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa var n = walker.currentNode; if(currentPos === 0) { n = n.previousSibling; - while(n && nodeFilter(n) !== 1) { + while(n && nodeFilter(n) !== FILTER_ACCEPT) { n = n.previousSibling } }else { - if(n.nodeType === Node.ELEMENT_NODE) { + if(n.nodeType === ELEMENT_NODE) { n = n.lastChild; - while(n && nodeFilter(n) !== 1) { + while(n && nodeFilter(n) !== FILTER_ACCEPT) { n = n.previousSibling } } @@ -3868,10 +3970,11 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa return n }; this.getCurrentNode = function() { - return walker.currentNode + var n = (walker.currentNode); + return n }; this.unfilteredDomOffset = function() { - if(walker.currentNode.nodeType === Node.TEXT_NODE) { + if(walker.currentNode.nodeType === TEXT_NODE) { return currentPos } var c = 0, n = walker.currentNode; @@ -3897,37 +4000,38 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa return sibling }; this.setUnfilteredPosition = function(container, offset) { - var filterResult, node; + var filterResult, node, text; runtime.assert(container !== null && container !== undefined, "PositionIterator.setUnfilteredPosition called without container"); walker.currentNode = container; - if(container.nodeType === Node.TEXT_NODE) { + if(container.nodeType === TEXT_NODE) { currentPos = offset; - runtime.assert(offset <= container.length, "Error in setPosition: " + offset + " > " + container.length); + text = (container); + runtime.assert(offset <= text.length, "Error in setPosition: " + offset + " > " + text.length); runtime.assert(offset >= 0, "Error in setPosition: " + offset + " < 0"); - if(offset === container.length) { - currentPos = undefined; + if(offset === text.length) { if(walker.nextSibling()) { currentPos = 0 }else { if(walker.parentNode()) { currentPos = 1 + }else { + runtime.assert(false, "Error in setUnfilteredPosition: position not valid.") } } - runtime.assert(currentPos !== undefined, "Error in setPosition: position not valid.") } return true } filterResult = nodeFilter(container); node = container.parentNode; - while(node && (node !== root && filterResult === NodeFilter.FILTER_ACCEPT)) { + while(node && (node !== root && filterResult === FILTER_ACCEPT)) { filterResult = nodeFilter(node); - if(filterResult !== NodeFilter.FILTER_ACCEPT) { + if(filterResult !== FILTER_ACCEPT) { walker.currentNode = node } node = node.parentNode } if(offset < container.childNodes.length && filterResult !== NodeFilter.FILTER_REJECT) { - walker.currentNode = container.childNodes[offset]; + walker.currentNode = (container.childNodes.item(offset)); filterResult = nodeFilter(walker.currentNode); currentPos = 0 }else { @@ -3936,10 +4040,10 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa if(filterResult === NodeFilter.FILTER_REJECT) { currentPos = 1 } - if(filterResult !== NodeFilter.FILTER_ACCEPT) { + if(filterResult !== FILTER_ACCEPT) { return self.nextPosition() } - runtime.assert(nodeFilter(walker.currentNode) === NodeFilter.FILTER_ACCEPT, "PositionIterater.setUnfilteredPosition call resulted in an non-visible node being set"); + runtime.assert(nodeFilter(walker.currentNode) === FILTER_ACCEPT, "PositionIterater.setUnfilteredPosition call resulted in an non-visible node being set"); return true }; this.moveToEnd = function() { @@ -3947,8 +4051,10 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa currentPos = 1 }; this.moveToEndOfNode = function(node) { - if(node.nodeType === Node.TEXT_NODE) { - self.setUnfilteredPosition(node, node.length) + var text; + if(node.nodeType === TEXT_NODE) { + text = (node); + self.setUnfilteredPosition(text, text.length) }else { walker.currentNode = node; currentPos = 1 @@ -3967,6 +4073,7 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa nodeFilter = (f.acceptNode); nodeFilter.acceptNode = nodeFilter; whatToShow = whatToShow || 4294967295; + runtime.assert(root.nodeType !== Node.TEXT_NODE, "Internet Explorer doesn't allow tree walker roots to be text nodes"); walker = root.ownerDocument.createTreeWalker(root, whatToShow, nodeFilter, expandEntityReferences); currentPos = 0; if(walker.firstChild() === null) { @@ -4126,14 +4233,14 @@ core.Zip = function Zip(url, entriesReadCallback) { eextralen = estream.readUInt16LE(); estream.pos += filenamelen + eextralen; if(compressionMethod) { - data = data.slice(estream.pos, estream.pos + compressedSize); + data = data.subarray(estream.pos, estream.pos + compressedSize); if(compressedSize !== data.length) { callback("The amount of compressed bytes read was " + data.length.toString() + " instead of " + compressedSize.toString() + " for " + entry.filename + " in " + url + ".", null); return } data = inflate(data, uncompressedSize) }else { - data = data.slice(estream.pos, estream.pos + uncompressedSize) + data = data.subarray(estream.pos, estream.pos + uncompressedSize) } if(uncompressedSize !== data.length) { callback("The amount of bytes read was " + data.length.toString() + " instead of " + uncompressedSize.toString() + " for " + entry.filename + " in " + url + ".", null); @@ -4187,7 +4294,7 @@ core.Zip = function Zip(url, entriesReadCallback) { commentlen = stream.readUInt16LE(); stream.pos += 8; offset = stream.readUInt32LE(); - this.filename = runtime.byteArrayToString(stream.data.slice(stream.pos, stream.pos + namelen), "utf8"); + this.filename = runtime.byteArrayToString(stream.data.subarray(stream.pos, stream.pos + namelen), "utf8"); stream.pos += namelen + extralen + commentlen } function handleCentralDirectory(data, callback) { @@ -4279,7 +4386,7 @@ core.Zip = function Zip(url, entriesReadCallback) { } function loadAsDataURL(filename, mimetype, callback) { load(filename, function(err, data) { - if(err) { + if(err || !data) { return callback(err, null) } var p = data, chunksize = 45E3, i = 0, dataurl; @@ -4300,7 +4407,7 @@ core.Zip = function Zip(url, entriesReadCallback) { } dataurl = "data:" + mimetype + ";base64,"; while(i < data.length) { - dataurl += base64.convertUTF8ArrayToBase64(p.slice(i, Math.min(i + chunksize, p.length))); + dataurl += base64.convertUTF8ArrayToBase64(p.subarray(i, Math.min(i + chunksize, p.length))); i += chunksize } callback(null, dataurl) @@ -4460,7 +4567,7 @@ core.Zip = function Zip(url, entriesReadCallback) { }) }; core.CSSUnits = function CSSUnits() { - var sizemap = {"in":1, "cm":2.54, "mm":25.4, "pt":72, "pc":12}; + var self = this, sizemap = {"in":1, "cm":2.54, "mm":25.4, "pt":72, "pc":12}; this.convert = function(value, oldUnit, newUnit) { return value * sizemap[newUnit] / sizemap[oldUnit] }; @@ -4469,11 +4576,11 @@ core.CSSUnits = function CSSUnits() { if(measure && newUnit) { value = parseFloat(measure); oldUnit = measure.replace(value.toString(), ""); - newMeasure = this.convert(value, oldUnit, newUnit) + newMeasure = self.convert(value, oldUnit, newUnit).toString() }else { newMeasure = "" } - return newMeasure.toString() + return newMeasure }; this.getUnits = function(measure) { return measure.substr(measure.length - 2, measure.length) @@ -4554,7 +4661,7 @@ xmldom.LSSerializer = function LSSerializer() { return s } function startElement(ns, qname, element) { - var s = "", atts = element.attributes, length, i, attr, attstr = "", accept, prefix, nsmap; + var s = "", atts = (element.attributes), length, i, attr, attstr = "", accept, prefix, nsmap; s += "<" + qname; length = atts.length; for(i = 0;i < length;i += 1) { @@ -5711,7 +5818,7 @@ xmldom.RelaxNG2 = function RelaxNG2() { }; this.validate = function validate(walker, callback) { walker.currentNode = walker.root; - var errors = validatePattern(start.e[0], walker, walker.root); + var errors = validatePattern(start.e[0], walker, (walker.root)); callback(errors) }; this.init = function init(start1, nsmap1) { @@ -6049,7 +6156,7 @@ gui.AnnotationViewManager = function AnnotationViewManager(odfCanvas, odfFragmen return Math.sqrt(xs + ys) } function renderAnnotation(annotation) { - var annotationNote = annotation.node.parentNode, connectorHorizontal = annotationNote.nextSibling, connectorAngular = connectorHorizontal.nextSibling, annotationWrapper = annotationNote.parentNode, connectorAngle = 0, previousAnnotation = annotations[annotations.indexOf(annotation) - 1], previousRect, creatorNode = annotation.node.getElementsByTagNameNS(odf.Namespaces.dcns, "creator")[0], creatorName, zoomLevel = odfCanvas.getZoomLevel(); + var annotationNote = annotation.node.parentNode, connectorHorizontal = annotationNote.nextSibling, connectorAngular = connectorHorizontal.nextSibling, annotationWrapper = annotationNote.parentNode, connectorAngle = 0, previousAnnotation = annotations[annotations.indexOf(annotation) - 1], previousRect, zoomLevel = odfCanvas.getZoomLevel(); annotationNote.style.left = (annotationsPane.getBoundingClientRect().left - annotationWrapper.getBoundingClientRect().left) / zoomLevel + "px"; annotationNote.style.width = annotationsPane.getBoundingClientRect().width / zoomLevel + "px"; connectorHorizontal.style.width = parseFloat(annotationNote.style.left) - CONNECTOR_MARGIN + "px"; @@ -6067,20 +6174,7 @@ gui.AnnotationViewManager = function AnnotationViewManager(odfCanvas, odfFragmen connectorAngular.style.transform = "rotate(" + connectorAngle + "rad)"; connectorAngular.style.MozTransform = "rotate(" + connectorAngle + "rad)"; connectorAngular.style.WebkitTransform = "rotate(" + connectorAngle + "rad)"; - connectorAngular.style.msTransform = "rotate(" + connectorAngle + "rad)"; - if(creatorNode) { - creatorName = window.getComputedStyle((creatorNode), ":before").content; - if(creatorName && creatorName !== "none") { - if(/^["'].*["']$/.test(creatorName)) { - creatorName = creatorName.substring(1, creatorName.length - 1) - } - if(creatorNode.firstChild) { - creatorNode.firstChild.nodeValue = creatorName - }else { - creatorNode.appendChild(doc.createTextNode(creatorName)) - } - } - } + connectorAngular.style.msTransform = "rotate(" + connectorAngle + "rad)" } function showAnnotationsPane(show) { var sizer = odfCanvas.getSizer(); @@ -6227,9 +6321,9 @@ odf.OdfNodeFilter = function OdfNodeFilter() { @source: https://github.com/kogmbh/WebODF/ */ odf.Namespaces = function() { - var dbns = "urn:oasis:names:tc:opendocument:xmlns:database:1.0", dcns = "http://purl.org/dc/elements/1.1/", dr3dns = "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0", drawns = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0", chartns = "urn:oasis:names:tc:opendocument:xmlns:chart:1.0", fons = "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0", formns = "urn:oasis:names:tc:opendocument:xmlns:form:1.0", numberns = "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0", officens = "urn:oasis:names:tc:opendocument:xmlns:office:1.0", - presentationns = "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0", stylens = "urn:oasis:names:tc:opendocument:xmlns:style:1.0", svgns = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0", tablens = "urn:oasis:names:tc:opendocument:xmlns:table:1.0", textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", xlinkns = "http://www.w3.org/1999/xlink", xmlns = "http://www.w3.org/XML/1998/namespace", namespaceMap = {"db":dbns, "dc":dcns, "dr3d":dr3dns, "draw":drawns, "chart":chartns, - "fo":fons, "form":formns, "numberns":numberns, "office":officens, "presentation":presentationns, "style":stylens, "svg":svgns, "table":tablens, "text":textns, "xlink":xlinkns, "xml":xmlns}, namespaces; + var dbns = "urn:oasis:names:tc:opendocument:xmlns:database:1.0", dcns = "http://purl.org/dc/elements/1.1/", metans = "urn:oasis:names:tc:opendocument:xmlns:meta:1.0", dr3dns = "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0", drawns = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0", chartns = "urn:oasis:names:tc:opendocument:xmlns:chart:1.0", fons = "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0", formns = "urn:oasis:names:tc:opendocument:xmlns:form:1.0", numberns = "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0", + officens = "urn:oasis:names:tc:opendocument:xmlns:office:1.0", presentationns = "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0", stylens = "urn:oasis:names:tc:opendocument:xmlns:style:1.0", svgns = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0", tablens = "urn:oasis:names:tc:opendocument:xmlns:table:1.0", textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", xlinkns = "http://www.w3.org/1999/xlink", xmlns = "http://www.w3.org/XML/1998/namespace", namespaceMap = {"db":dbns, + "dc":dcns, "meta":metans, "dr3d":dr3dns, "draw":drawns, "chart":chartns, "fo":fons, "form":formns, "numberns":numberns, "office":officens, "presentation":presentationns, "style":stylens, "svg":svgns, "table":tablens, "text":textns, "xlink":xlinkns, "xml":xmlns}, namespaces; function forEachPrefix(cb) { var prefix; for(prefix in namespaceMap) { @@ -6241,14 +6335,26 @@ odf.Namespaces = function() { function resolvePrefix(prefix) { return namespaceMap[prefix] || null } + function lookupPrefix(namespaceURI) { + var foundPrefix, prefix; + for(prefix in namespaceMap) { + if(namespaceMap.hasOwnProperty(prefix) && namespaceMap[prefix] === namespaceURI) { + foundPrefix = prefix; + break + } + } + return foundPrefix + } resolvePrefix.lookupNamespaceURI = resolvePrefix; namespaces = function Namespaces() { }; namespaces.forEachPrefix = forEachPrefix; namespaces.resolvePrefix = resolvePrefix; + namespaces.lookupPrefix = lookupPrefix; namespaces.namespaceMap = namespaceMap; namespaces.dbns = dbns; namespaces.dcns = dcns; + namespaces.metans = metans; namespaces.dr3dns = dr3dns; namespaces.drawns = drawns; namespaces.chartns = chartns; @@ -6712,17 +6818,17 @@ odf.OdfUtils = function OdfUtils() { return r } this.isCharacterElement = isCharacterElement; - function isWhitespaceElement(e) { + function isSpaceElement(e) { var n = e && e.localName, ns, r = false; if(n) { ns = e.namespaceURI; if(ns === textns) { - r = n === "s" || n === "tab" + r = n === "s" } } return r } - this.isWhitespaceElement = isWhitespaceElement; + this.isSpaceElement = isSpaceElement; function firstChild(node) { while(node.firstChild !== null && isGroupingElement(node)) { node = node.firstChild @@ -6751,7 +6857,7 @@ odf.OdfUtils = function OdfUtils() { return isParagraph(node) ? null : firstChild((node.nextSibling)) } this.nextNode = nextNode; - function scanLeftForNonWhitespace(node) { + function scanLeftForNonSpace(node) { var r = false; while(node) { if(node.nodeType === Node.TEXT_NODE) { @@ -6762,7 +6868,7 @@ odf.OdfUtils = function OdfUtils() { } }else { if(isCharacterElement(node)) { - r = isWhitespaceElement(node) === false; + r = isSpaceElement(node) === false; node = null }else { node = previousNode(node) @@ -6771,7 +6877,7 @@ odf.OdfUtils = function OdfUtils() { } return r } - this.scanLeftForNonWhitespace = scanLeftForNonWhitespace; + this.scanLeftForNonSpace = scanLeftForNonSpace; function lookLeftForCharacter(node) { var text, r = 0; if(node.nodeType === Node.TEXT_NODE && node.length > 0) { @@ -6780,7 +6886,7 @@ odf.OdfUtils = function OdfUtils() { r = 1 }else { if(text.length === 1) { - r = scanLeftForNonWhitespace(previousNode(node)) ? 2 : 0 + r = scanLeftForNonSpace(previousNode(node)) ? 2 : 0 }else { r = isODFWhitespace(text.substr(text.length - 2, 1)) ? 0 : 2 } @@ -6859,7 +6965,7 @@ odf.OdfUtils = function OdfUtils() { result = true } }else { - if(scanLeftForNonWhitespace(previousNode(textNode))) { + if(scanLeftForNonSpace(previousNode(textNode))) { result = true } } @@ -6871,7 +6977,7 @@ odf.OdfUtils = function OdfUtils() { this.isSignificantWhitespace = isSignificantWhitespace; this.isDowngradableSpaceElement = function(node) { if(node.namespaceURI === textns && node.localName === "s") { - return scanLeftForNonWhitespace(previousNode(node)) && scanRightForAnyCharacter(nextNode(node)) + return scanLeftForNonSpace(previousNode(node)) && scanRightForAnyCharacter(nextNode(node)) } return false }; @@ -7888,6 +7994,58 @@ odf.Style2CSS = function Style2CSS() { } } }; +/* + + Copyright (C) 2013 KO GmbH + + @licstart + This file is part of WebODF. + + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +runtime.loadClass("odf.Namespaces"); +runtime.loadClass("core.DomUtils"); +odf.MetadataManager = function MetadataManager(metaElement) { + var domUtils = new core.DomUtils, metadata = {}; + function setMetadata(setProperties, removedProperties) { + if(setProperties) { + Object.keys(setProperties).forEach(function(key) { + metadata[key] = setProperties[key] + }); + domUtils.mapKeyValObjOntoNode(metaElement, setProperties, odf.Namespaces.resolvePrefix) + } + if(removedProperties) { + removedProperties.forEach(function(name) { + delete metadata[name] + }); + domUtils.removeKeyElementsFromNode(metaElement, removedProperties, odf.Namespaces.resolvePrefix) + } + } + this.setMetadata = setMetadata; + this.incrementEditingCycles = function() { + var cycles = parseInt(metadata["meta:editing-cycles"] || 0, 10) + 1; + setMetadata({"meta:editing-cycles":cycles}, null) + }; + function init() { + metadata = domUtils.getKeyValRepresentationOfNode(metaElement, odf.Namespaces.lookupPrefix) + } + init() +}; /* Copyright (C) 2012-2013 KO GmbH @@ -7931,8 +8089,9 @@ runtime.loadClass("xmldom.LSSerializer"); runtime.loadClass("odf.StyleInfo"); runtime.loadClass("odf.Namespaces"); runtime.loadClass("odf.OdfNodeFilter"); +runtime.loadClass("odf.MetadataManager"); odf.OdfContainer = function() { - var styleInfo = new odf.StyleInfo, officens = "urn:oasis:names:tc:opendocument:xmlns:office:1.0", manifestns = "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0", webodfns = "urn:webodf:names:scope", stylens = odf.Namespaces.stylens, nodeorder = ["meta", "settings", "scripts", "font-face-decls", "styles", "automatic-styles", "master-styles", "body"], automaticStylePrefix = (new Date).getTime() + "_webodf_", base64 = new core.Base64, documentStylesScope = "document-styles", documentContentScope = + var styleInfo = new odf.StyleInfo, metadataManager, officens = "urn:oasis:names:tc:opendocument:xmlns:office:1.0", manifestns = "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0", webodfns = "urn:webodf:names:scope", stylens = odf.Namespaces.stylens, nodeorder = ["meta", "settings", "scripts", "font-face-decls", "styles", "automatic-styles", "master-styles", "body"], automaticStylePrefix = (new Date).getTime() + "_webodf_", base64 = new core.Base64, documentStylesScope = "document-styles", documentContentScope = "document-content"; function getDirectChild(node, ns, name) { node = node ? node.firstChild : null; @@ -8164,6 +8323,9 @@ odf.OdfContainer = function() { } return copy } + function initializeMetadataManager(metaRootElement) { + metadataManager = new odf.MetadataManager(metaRootElement) + } function importRootNode(xmldoc) { var doc = self.rootElement.ownerDocument, node; if(xmldoc) { @@ -8263,7 +8425,8 @@ odf.OdfContainer = function() { } root = self.rootElement; root.meta = getDirectChild(node, officens, "meta"); - setChild(root, root.meta) + setChild(root, root.meta); + initializeMetadataManager(root.meta) } function handleSettingsXml(xmldoc) { var node = importRootNode(xmldoc), root; @@ -8402,12 +8565,23 @@ odf.OdfContainer = function() { var content = self.getContentElement(); return content && content.localName }; + this.getMetadataManager = function() { + return metadataManager + }; this.getPart = function(partname) { return new OdfPart(partname, partMimetypes[partname], self, zip) }; this.getPartData = function(url, callback) { zip.load(url, callback) }; + function updateMetadataForSaving() { + var generatorString, window = runtime.getWindow(); + generatorString = "WebODF/" + (String(typeof webodf_version) !== "undefined" ? webodf_version : "FromSource"); + if(window) { + generatorString = generatorString + " " + window.navigator.userAgent + } + metadataManager.setMetadata({"meta:generator":generatorString}) + } function createEmptyTextDocument() { var emptyzip = new core.Zip("", null), data = runtime.byteArrayFromString("application/vnd.oasis.opendocument.text", "utf8"), root = self.rootElement, text = document.createElementNS(officens, "text"); emptyzip.save("mimetype", data, false, new Date); @@ -8429,11 +8603,13 @@ odf.OdfContainer = function() { addToplevelElement("masterStyles", "master-styles"); addToplevelElement("body"); root.body.appendChild(text); + initializeMetadataManager(root.meta); setState(OdfContainer.DONE); return emptyzip } function fillZip() { var data, date = new Date; + updateMetadataForSaving(); data = runtime.byteArrayFromString(serializeSettingsXml(), "utf8"); zip.save("settings.xml", data, true, date); data = runtime.byteArrayFromString(serializeMetaXml(), "utf8"); @@ -8596,7 +8772,11 @@ odf.FontLoader = function() { if(err) { runtime.log(err) }else { - addFontToCSS(name, embeddedFontDeclarations[name], fontdata, stylesheet) + if(!fontdata) { + runtime.log("missing font data for " + embeddedFontDeclarations[name].href) + }else { + addFontToCSS(name, embeddedFontDeclarations[name], fontdata, stylesheet) + } } loadFontIntoCSS(embeddedFontDeclarations, odfContainer, pos + 1, stylesheet, callback) }) @@ -8765,7 +8945,7 @@ 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, numberns = odf.Namespaces.numberns, fons = odf.Namespaces.fons, odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils, utils = new core.Utils, builtInDefaultStyleAttributesByFamily = {"paragraph":{"style:paragraph-properties":{"fo:text-align":"left"}}}, defaultPageFormatSettings = {width:21.001, height:29.7, margin:2, padding:0}; - function getBuiltInDefaultStyleAttributes(styleFamily) { + function getSystemDefaultStyleAttributes(styleFamily) { var result, builtInDefaultStyleAttributes = builtInDefaultStyleAttributesByFamily[styleFamily]; if(builtInDefaultStyleAttributes) { result = utils.mergeObjects({}, builtInDefaultStyleAttributes) @@ -8774,6 +8954,7 @@ odf.Formatting = function Formatting() { } return result } + this.getSystemDefaultStyleAttributes = getSystemDefaultStyleAttributes; this.setOdfContainer = function(odfcontainer) { odfContainer = odfcontainer }; @@ -8873,20 +9054,6 @@ odf.Formatting = function Formatting() { return propertiesMap } this.getStyleAttributes = getStyleAttributes; - function mapObjOntoNode(node, properties) { - Object.keys(properties).forEach(function(key) { - var parts = key.split(":"), prefix = parts[0], localName = parts[1], ns = odf.Namespaces.resolvePrefix(prefix), value = properties[key], element; - if(typeof value === "object" && Object.keys(value).length) { - element = node.getElementsByTagNameNS(ns, localName)[0] || node.ownerDocument.createElementNS(ns, key); - node.appendChild(element); - mapObjOntoNode(element, value) - }else { - if(ns) { - node.setAttributeNS(ns, key, value) - } - } - }) - } function getInheritedStyleAttributes(styleNode, includeSystemDefault) { var styleListElement = odfContainer.rootElement.styles, parentStyleName, propertiesMap, inheritedPropertiesMap = {}, styleFamily = styleNode.getAttributeNS(stylens, "family"), node = styleNode; while(node) { @@ -8905,7 +9072,7 @@ odf.Formatting = function Formatting() { inheritedPropertiesMap = utils.mergeObjects(propertiesMap, inheritedPropertiesMap) } if(includeSystemDefault) { - propertiesMap = getBuiltInDefaultStyleAttributes(styleFamily); + propertiesMap = getSystemDefaultStyleAttributes(styleFamily); if(propertiesMap) { inheritedPropertiesMap = utils.mergeObjects(propertiesMap, inheritedPropertiesMap) } @@ -8994,7 +9161,7 @@ odf.Formatting = function Formatting() { }; this.updateStyle = function(styleNode, properties) { var fontName, fontFaceNode; - mapObjOntoNode(styleNode, properties); + domUtils.mapObjOntoNode(styleNode, properties, odf.Namespaces.resolvePrefix); fontName = properties["style:text-properties"] && properties["style:text-properties"]["style:font-name"]; if(fontName && !getFontMap().hasOwnProperty(fontName)) { fontFaceNode = styleNode.ownerDocument.createElementNS(stylens, "style:font-face"); @@ -9789,7 +9956,7 @@ odf.OdfCanvas = function() { odf.OdfCanvas = function OdfCanvas(element) { runtime.assert(element !== null && element !== undefined, "odf.OdfCanvas constructor needs DOM element"); runtime.assert(element.ownerDocument !== null && element.ownerDocument !== undefined, "odf.OdfCanvas constructor needs DOM"); - var self = this, doc = (element.ownerDocument), odfcontainer, formatting = new odf.Formatting, selectionWatcher = new SelectionWatcher(element), pageSwitcher, sizer, annotationsPane, allowAnnotations = false, annotationManager, webodfcss, fontcss, stylesxmlcss, positioncss, shadowContent, zoomLevel = 1, eventHandlers = {}, loadingQueue = new LoadingQueue; + var self = this, doc = (element.ownerDocument), odfcontainer, formatting = new odf.Formatting, selectionWatcher = new SelectionWatcher(element), pageSwitcher, sizer, annotationsPane, allowAnnotations = false, annotationViewManager, webodfcss, fontcss, stylesxmlcss, positioncss, shadowContent, zoomLevel = 1, eventHandlers = {}, loadingQueue = new LoadingQueue; function loadImages(container, odffragment, stylesheet) { var i, images, node; function loadImage(name, container, node, stylesheet) { @@ -9893,9 +10060,9 @@ odf.OdfCanvas = function() { } for(i = 0;i < annotationNodes.length;i += 1) { currentAnnotationName = annotationNodes[i].getAttributeNS(officens, "name"); - annotationManager.addAnnotation({node:annotationNodes[i], end:annotationEnds.filter(matchAnnotationEnd)[0] || null}) + annotationViewManager.addAnnotation({node:annotationNodes[i], end:annotationEnds.filter(matchAnnotationEnd)[0] || null}) } - annotationManager.rerenderAnnotations() + annotationViewManager.rerenderAnnotations() } function handleAnnotations(odfnode) { if(allowAnnotations) { @@ -9903,15 +10070,15 @@ odf.OdfCanvas = function() { sizer.appendChild(annotationsPane); fixContainerSize() } - if(annotationManager) { - annotationManager.forgetAnnotations() + if(annotationViewManager) { + annotationViewManager.forgetAnnotations() } - annotationManager = new gui.AnnotationViewManager(self, odfnode.body, annotationsPane); + annotationViewManager = new gui.AnnotationViewManager(self, odfnode.body, annotationsPane); modifyAnnotations(odfnode.body) }else { if(annotationsPane.parentNode) { sizer.removeChild(annotationsPane); - annotationManager.forgetAnnotations(); + annotationViewManager.forgetAnnotations(); fixContainerSize() } } @@ -9992,15 +10159,15 @@ odf.OdfCanvas = function() { this.getFormatting = function() { return formatting }; - this.getAnnotationManager = function() { - return annotationManager + this.getAnnotationViewManager = function() { + return annotationViewManager }; this.refreshAnnotations = function() { handleAnnotations(odfcontainer.rootElement) }; this.rerenderAnnotations = function() { - if(annotationManager) { - annotationManager.rerenderAnnotations() + if(annotationViewManager) { + annotationViewManager.rerenderAnnotations() } }; this.getSizer = function() { @@ -10015,13 +10182,13 @@ odf.OdfCanvas = function() { } }; this.addAnnotation = function(annotation) { - if(annotationManager) { - annotationManager.addAnnotation(annotation) + if(annotationViewManager) { + annotationViewManager.addAnnotation(annotation) } }; this.forgetAnnotations = function() { - if(annotationManager) { - annotationManager.forgetAnnotations() + if(annotationViewManager) { + annotationViewManager.forgetAnnotations() } }; this.setZoomLevel = function(zoom) { @@ -10149,15 +10316,81 @@ odf.CommandLineTools = function CommandLineTools() { 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. + This file is part of WebODF. - You should have received a copy of the GNU Affero General Public License - along with this code. If not, see . + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +ops.Member = function Member(memberId, properties) { + var props = {}; + function getMemberId() { + return memberId + } + function getProperties() { + return props + } + function setProperties(newProperties) { + Object.keys(newProperties).forEach(function(key) { + props[key] = newProperties[key] + }) + } + function removeProperties(removedProperties) { + delete removedProperties.fullName; + delete removedProperties.color; + delete removedProperties.imageUrl; + Object.keys(removedProperties).forEach(function(key) { + if(props.hasOwnProperty(key)) { + delete props[key] + } + }) + } + this.getMemberId = getMemberId; + this.getProperties = getProperties; + this.setProperties = setProperties; + this.removeProperties = removeProperties; + function init() { + runtime.assert(Boolean(memberId), "No memberId was supplied!"); + if(!properties.fullName) { + properties.fullName = runtime.tr("Unknown Author") + } + if(!properties.color) { + properties.color = "black" + } + if(!properties.imageUrl) { + properties.imageUrl = "avatar-joe.png" + } + props = properties + } + 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. + + You should have received a copy of the GNU Affero General Public License + along with this code. If not, see . As additional permission under GNU AGPL version 3 section 7, you may distribute non-source (e.g., minimized or compacted) forms of @@ -10236,6 +10469,7 @@ ops.Operation = function Operation() { }; ops.Operation.prototype.init = function(data) { }; +ops.Operation.prototype.isEdit; ops.Operation.prototype.execute = function(odtDocument) { }; ops.Operation.prototype.spec = function() { @@ -10283,6 +10517,7 @@ ops.OpAddCursor = function OpAddCursor() { memberid = data.memberid; timestamp = data.timestamp }; + this.isEdit = false; this.execute = function(odtDocument) { var cursor = odtDocument.getCursor(memberid); if(cursor) { @@ -10384,23 +10619,36 @@ gui.StyleHelper = function StyleHelper(formatting) { }; function hasParagraphPropertyValue(range, propertyName, propertyValues) { var nodes = odfUtils.getParagraphElements(range), isStyleChecked = {}, isDefaultParagraphStyleChecked = false, paragraphStyleName, paragraphStyleElement, paragraphStyleAttributes, properties; + function pickDefaultParagraphStyleElement() { + isDefaultParagraphStyleChecked = true; + paragraphStyleElement = formatting.getDefaultStyleElement("paragraph"); + if(!paragraphStyleElement) { + paragraphStyleElement = null + } + } while(nodes.length > 0) { paragraphStyleName = nodes[0].getAttributeNS(textns, "style-name"); if(paragraphStyleName) { if(!isStyleChecked[paragraphStyleName]) { paragraphStyleElement = formatting.getStyleElement(paragraphStyleName, "paragraph"); - isStyleChecked[paragraphStyleName] = true + isStyleChecked[paragraphStyleName] = true; + if(!paragraphStyleElement && !isDefaultParagraphStyleChecked) { + pickDefaultParagraphStyleElement() + } } }else { if(!isDefaultParagraphStyleChecked) { - isDefaultParagraphStyleChecked = true; - paragraphStyleElement = formatting.getDefaultStyleElement("paragraph") + pickDefaultParagraphStyleElement() }else { paragraphStyleElement = undefined } } - if(paragraphStyleElement) { - paragraphStyleAttributes = formatting.getInheritedStyleAttributes((paragraphStyleElement), true); + if(paragraphStyleElement !== undefined) { + if(paragraphStyleElement === null) { + paragraphStyleAttributes = formatting.getSystemDefaultStyleAttributes("paragraph") + }else { + paragraphStyleAttributes = formatting.getInheritedStyleAttributes((paragraphStyleElement), true) + } properties = paragraphStyleAttributes["style:paragraph-properties"]; if(properties && propertyValues.indexOf(properties[propertyName]) === -1) { return false @@ -10471,6 +10719,7 @@ ops.OpApplyDirectStyling = function OpApplyDirectStyling() { length = parseInt(data.length, 10); setProperties = data.setProperties }; + this.isEdit = true; 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()); @@ -10536,6 +10785,7 @@ ops.OpRemoveCursor = function OpRemoveCursor() { memberid = data.memberid; timestamp = data.timestamp }; + this.isEdit = false; this.execute = function(odtDocument) { if(!odtDocument.removeCursor(memberid)) { return false @@ -10592,6 +10842,7 @@ ops.OpMoveCursor = function OpMoveCursor() { length = data.length || 0; selectionType = data.selectionType || ops.OdtCursor.RangeSelection }; + this.isEdit = false; this.execute = function(odtDocument) { var cursor = odtDocument.getCursor(memberid), selectedRange; if(!cursor) { @@ -10653,6 +10904,7 @@ ops.OpSetBlob = function OpSetBlob() { mimetype = data.mimetype; content = data.content }; + this.isEdit = true; this.execute = function(odtDocument) { odtDocument.getOdfCanvas().odfContainer().setBlob(filename, mimetype, content); return true @@ -10705,6 +10957,7 @@ ops.OpRemoveBlob = function OpRemoveBlob() { timestamp = data.timestamp; filename = data.filename }; + this.isEdit = true; this.execute = function(odtDocument) { odtDocument.getOdfCanvas().odfContainer().removeBlob(filename); return true @@ -10762,6 +11015,7 @@ ops.OpInsertImage = function OpInsertImage() { frameStyleName = data.frameStyleName; frameName = data.frameName }; + this.isEdit = true; function createFrameElement(document) { var imageNode = document.createElementNS(drawns, "draw:image"), frameNode = document.createElementNS(drawns, "draw:frame"); imageNode.setAttributeNS(xlinkns, "xlink:href", filename); @@ -10850,6 +11104,7 @@ ops.OpInsertTable = function OpInsertTable() { tableColumnStyleName = data.tableColumnStyleName; tableCellStyleMatrix = data.tableCellStyleMatrix }; + this.isEdit = true; function getCellStyleName(row, column) { var rowStyles; if(tableCellStyleMatrix.length === 1) { @@ -10978,6 +11233,7 @@ ops.OpInsertText = function OpInsertText() { position = data.position; text = data.text }; + this.isEdit = true; function triggerLayoutInWebkit(textNode) { var parent = textNode.parentNode, next = textNode.nextSibling; parent.removeChild(textNode); @@ -11115,6 +11371,7 @@ ops.OpRemoveText = function OpRemoveText() { odfNodeNamespaceMap[odf.Namespaces.tablens] = true; odfNodeNamespaceMap[odf.Namespaces.textns] = true }; + this.isEdit = true; function CollapsingRules(rootNode) { function isOdfNode(node) { return odfNodeNamespaceMap.hasOwnProperty(node.namespaceURI) @@ -11260,6 +11517,7 @@ ops.OpSplitParagraph = function OpSplitParagraph() { position = data.position; odfUtils = new odf.OdfUtils }; + this.isEdit = true; this.execute = function(odtDocument) { var domPosition, paragraphNode, targetNode, node, splitNode, splitChildNode, keptChildNode; odtDocument.upgradeWhitespacesAtPosition(position); @@ -11370,6 +11628,7 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() { position = data.position; styleName = data.styleName }; + this.isEdit = true; this.execute = function(odtDocument) { var iterator, paragraphNode; iterator = odtDocument.getIteratorAtPosition(position); @@ -11445,6 +11704,7 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { setProperties = data.setProperties; removedProperties = data.removedProperties }; + this.isEdit = true; this.execute = function(odtDocument) { var formatting = odtDocument.getFormatting(), styleNode, paragraphPropertiesNode, textPropertiesNode; if(styleName !== "") { @@ -11532,6 +11792,7 @@ ops.OpAddStyle = function OpAddStyle() { isAutomaticStyle = data.isAutomaticStyle === "true" || data.isAutomaticStyle === true; setProperties = data.setProperties }; + this.isEdit = true; this.execute = function(odtDocument) { var odfContainer = odtDocument.getOdfCanvas().odfContainer(), formatting = odtDocument.getFormatting(), dom = odtDocument.getDOM(), styleNode = dom.createElementNS(stylens, "style:style"); if(!styleNode) { @@ -11602,6 +11863,7 @@ ops.OpRemoveStyle = function OpRemoveStyle() { styleName = data.styleName; styleFamily = data.styleFamily }; + this.isEdit = true; this.execute = function(odtDocument) { var styleNode = odtDocument.getStyleElement(styleName, styleFamily); if(!styleNode) { @@ -11662,12 +11924,14 @@ ops.OpAddAnnotation = function OpAddAnnotation() { length = parseInt(data.length, 10) || 0; name = data.name }; + this.isEdit = true; function createAnnotationNode(odtDocument, date) { var annotationNode, creatorNode, dateNode, listNode, listItemNode, paragraphNode, doc = odtDocument.getDOM(); annotationNode = doc.createElementNS(odf.Namespaces.officens, "office:annotation"); annotationNode.setAttributeNS(odf.Namespaces.officens, "office:name", name); creatorNode = doc.createElementNS(odf.Namespaces.dcns, "dc:creator"); creatorNode.setAttributeNS("urn:webodf:names:editinfo", "editinfo:memberid", memberid); + creatorNode.textContent = odtDocument.getMember(memberid).getProperties().fullName; dateNode = doc.createElementNS(odf.Namespaces.dcns, "dc:date"); dateNode.appendChild(doc.createTextNode(date.toISOString())); listNode = doc.createElementNS(odf.Namespaces.textns, "text:list"); @@ -11777,6 +12041,7 @@ ops.OpRemoveAnnotation = function OpRemoveAnnotation() { length = parseInt(data.length, 10); domUtils = new core.DomUtils }; + this.isEdit = true; this.execute = function(odtDocument) { var iterator = odtDocument.getIteratorAtPosition(position), container = iterator.container(), annotationName, annotationNode, annotationEnd, cursors; while(!(container.namespaceURI === odf.Namespaces.officens && container.localName === "annotation")) { @@ -11810,6 +12075,221 @@ ops.OpRemoveAnnotation = function OpRemoveAnnotation() { return{optype:"RemoveAnnotation", memberid:memberid, timestamp:timestamp, position:position, length:length} } }; +/* + + Copyright (C) 2013 KO GmbH + + @licstart + This file is part of WebODF. + + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +runtime.loadClass("ops.Member"); +ops.OpAddMember = function OpAddMember() { + var memberid, timestamp, setProperties; + this.init = function(data) { + memberid = data.memberid; + timestamp = parseInt(data.timestamp, 10); + setProperties = data.setProperties + }; + this.isEdit = false; + this.execute = function(odtDocument) { + if(odtDocument.getMember(memberid)) { + return false + } + var member = new ops.Member(memberid, setProperties); + odtDocument.addMember(member); + odtDocument.emit(ops.OdtDocument.signalMemberAdded, member); + return true + }; + this.spec = function() { + return{optype:"AddMember", memberid:memberid, timestamp:timestamp, setProperties:setProperties} + } +}; +/* + + Copyright (C) 2013 KO GmbH + + @licstart + This file is part of WebODF. + + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +runtime.loadClass("ops.Member"); +runtime.loadClass("xmldom.XPath"); +ops.OpUpdateMember = function OpUpdateMember() { + var memberid, timestamp, setProperties, removedProperties, doc; + this.init = function(data) { + memberid = data.memberid; + timestamp = parseInt(data.timestamp, 10); + setProperties = data.setProperties; + removedProperties = data.removedProperties + }; + this.isEdit = false; + function updateCreators() { + var xpath = new xmldom.XPath, xp = "//dc:creator[@editinfo:memberid='" + memberid + "']", creators = xpath.getODFElementsWithXPath(doc.getRootNode(), xp, function(prefix) { + if(prefix === "editinfo") { + return"urn:webodf:names:editinfo" + } + return odf.Namespaces.resolvePrefix(prefix) + }), i; + for(i = 0;i < creators.length;i += 1) { + creators[i].textContent = setProperties.fullName + } + } + this.execute = function(odtDocument) { + doc = odtDocument; + var member = odtDocument.getMember(memberid); + if(!member) { + return false + } + if(removedProperties) { + member.removeProperties(removedProperties) + } + if(setProperties) { + member.setProperties(setProperties); + if(setProperties.fullName) { + updateCreators() + } + } + odtDocument.emit(ops.OdtDocument.signalMemberUpdated, member); + return true + }; + this.spec = function() { + return{optype:"UpdateMember", memberid:memberid, timestamp:timestamp, setProperties:setProperties, removedProperties:removedProperties} + } +}; +/* + + Copyright (C) 2013 KO GmbH + + @licstart + This file is part of WebODF. + + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +runtime.loadClass("ops.Member"); +ops.OpRemoveMember = function OpRemoveMember() { + var memberid, timestamp; + this.init = function(data) { + memberid = data.memberid; + timestamp = parseInt(data.timestamp, 10) + }; + this.isEdit = false; + this.execute = function(odtDocument) { + if(!odtDocument.getMember(memberid)) { + return false + } + odtDocument.removeMember(memberid); + odtDocument.emit(ops.OdtDocument.signalMemberRemoved, memberid); + return true + }; + this.spec = function() { + return{optype:"RemoveMember", memberid:memberid, timestamp:timestamp} + } +}; +/* + + Copyright (C) 2013 KO GmbH + + @licstart + This file is part of WebODF. + + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +ops.OpUpdateMetadata = function OpUpdateMetadata() { + var memberid, timestamp, setProperties, removedProperties; + this.init = function(data) { + memberid = data.memberid; + timestamp = parseInt(data.timestamp, 10); + setProperties = data.setProperties; + removedProperties = data.removedProperties + }; + this.isEdit = true; + this.execute = function(odtDocument) { + var metadataManager = odtDocument.getOdfCanvas().odfContainer().getMetadataManager(), removedPropertiesArray = [], blockedProperties = ["dc:date", "dc:creator", "meta:editing-cycles"]; + if(setProperties) { + blockedProperties.forEach(function(el) { + if(setProperties[el]) { + return false + } + }) + } + if(removedProperties) { + blockedProperties.forEach(function(el) { + if(removedPropertiesArray.indexOf(el) !== -1) { + return false + } + }); + removedPropertiesArray = removedProperties.attributes.split(",") + } + metadataManager.setMetadata(setProperties, removedPropertiesArray); + return true + }; + this.spec = function() { + return{optype:"UpdateMetadata", memberid:memberid, timestamp:timestamp, setProperties:setProperties, removedProperties:removedProperties} + } +}; /* Copyright (C) 2012-2013 KO GmbH @@ -11847,6 +12327,9 @@ ops.OpRemoveAnnotation = function OpRemoveAnnotation() { @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ +runtime.loadClass("ops.OpAddMember"); +runtime.loadClass("ops.OpUpdateMember"); +runtime.loadClass("ops.OpRemoveMember"); runtime.loadClass("ops.OpAddCursor"); runtime.loadClass("ops.OpApplyDirectStyling"); runtime.loadClass("ops.OpRemoveCursor"); @@ -11864,6 +12347,7 @@ runtime.loadClass("ops.OpAddStyle"); runtime.loadClass("ops.OpRemoveStyle"); runtime.loadClass("ops.OpAddAnnotation"); runtime.loadClass("ops.OpRemoveAnnotation"); +runtime.loadClass("ops.OpUpdateMetadata"); ops.OperationFactory = function OperationFactory() { var specs; this.register = function(specName, specConstructor) { @@ -11883,8 +12367,8 @@ ops.OperationFactory = function OperationFactory() { } } function init() { - specs = {AddCursor:constructor(ops.OpAddCursor), ApplyDirectStyling:constructor(ops.OpApplyDirectStyling), SetBlob:constructor(ops.OpSetBlob), RemoveBlob:constructor(ops.OpRemoveBlob), InsertImage:constructor(ops.OpInsertImage), InsertTable:constructor(ops.OpInsertTable), InsertText:constructor(ops.OpInsertText), RemoveText:constructor(ops.OpRemoveText), SplitParagraph:constructor(ops.OpSplitParagraph), SetParagraphStyle:constructor(ops.OpSetParagraphStyle), UpdateParagraphStyle:constructor(ops.OpUpdateParagraphStyle), - AddStyle:constructor(ops.OpAddStyle), RemoveStyle:constructor(ops.OpRemoveStyle), MoveCursor:constructor(ops.OpMoveCursor), RemoveCursor:constructor(ops.OpRemoveCursor), AddAnnotation:constructor(ops.OpAddAnnotation), RemoveAnnotation:constructor(ops.OpRemoveAnnotation)} + specs = {AddMember:constructor(ops.OpAddMember), UpdateMember:constructor(ops.OpUpdateMember), RemoveMember:constructor(ops.OpRemoveMember), AddCursor:constructor(ops.OpAddCursor), ApplyDirectStyling:constructor(ops.OpApplyDirectStyling), SetBlob:constructor(ops.OpSetBlob), RemoveBlob:constructor(ops.OpRemoveBlob), InsertImage:constructor(ops.OpInsertImage), InsertTable:constructor(ops.OpInsertTable), InsertText:constructor(ops.OpInsertText), RemoveText:constructor(ops.OpRemoveText), SplitParagraph:constructor(ops.OpSplitParagraph), + SetParagraphStyle:constructor(ops.OpSetParagraphStyle), UpdateParagraphStyle:constructor(ops.OpUpdateParagraphStyle), AddStyle:constructor(ops.OpAddStyle), RemoveStyle:constructor(ops.OpRemoveStyle), MoveCursor:constructor(ops.OpMoveCursor), RemoveCursor:constructor(ops.OpRemoveCursor), AddAnnotation:constructor(ops.OpAddAnnotation), RemoveAnnotation:constructor(ops.OpRemoveAnnotation), UpdateMetadata:constructor(ops.OpUpdateMetadata)} } init() }; @@ -11992,7 +12476,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { if(extend) { c = iterator.container(); o = iterator.unfilteredDomOffset(); - if(selectionRange.comparePoint(c, o) === -1) { + if(domUtils.comparePoints(selectionRange.startContainer, selectionRange.startOffset, c, o) === -1) { selectionRange.setStart(c, o); isForwardSelection = false }else { @@ -12230,7 +12714,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { gui.SelectionMover.createPositionIterator = function(rootNode) { function CursorFilter() { this.acceptNode = function(node) { - if(node.namespaceURI === "urn:webodf:names:cursor" || node.namespaceURI === "urn:webodf:names:editinfo") { + if(!node || (node.namespaceURI === "urn:webodf:names:cursor" || node.namespaceURI === "urn:webodf:names:editinfo")) { return NodeFilter.FILTER_REJECT } return NodeFilter.FILTER_ACCEPT @@ -12596,7 +13080,7 @@ runtime.loadClass("odf.OdfUtils"); runtime.loadClass("core.PositionFilter"); runtime.loadClass("odf.OdfUtils"); ops.TextPositionFilter = function TextPositionFilter(getRootNode) { - var odfUtils = new odf.OdfUtils, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT; + var odfUtils = new odf.OdfUtils, ELEMENT_NODE = Node.ELEMENT_NODE, TEXT_NODE = Node.TEXT_NODE, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT; function checkLeftRight(container, leftNode, rightNode) { var r, firstPos, rightOfChar; if(leftNode) { @@ -12624,10 +13108,10 @@ ops.TextPositionFilter = function TextPositionFilter(getRootNode) { } this.acceptPosition = function(iterator) { var container = iterator.container(), nodeType = container.nodeType, offset, text, leftChar, rightChar, leftNode, rightNode, r; - if(nodeType !== Node.ELEMENT_NODE && nodeType !== Node.TEXT_NODE) { + if(nodeType !== ELEMENT_NODE && nodeType !== TEXT_NODE) { return FILTER_REJECT } - if(nodeType === Node.TEXT_NODE) { + if(nodeType === TEXT_NODE) { if(!odfUtils.isGroupingElement(container.parentNode) || odfUtils.isWithinTrackedChanges(container.parentNode, getRootNode())) { return FILTER_REJECT } @@ -12635,12 +13119,12 @@ ops.TextPositionFilter = function TextPositionFilter(getRootNode) { text = container.data; runtime.assert(offset !== text.length, "Unexpected offset."); if(offset > 0) { - leftChar = text.substr(offset - 1, 1); + leftChar = text[offset - 1]; if(!odfUtils.isODFWhitespace(leftChar)) { return FILTER_ACCEPT } if(offset > 1) { - leftChar = text.substr(offset - 2, 1); + leftChar = text[offset - 2]; if(!odfUtils.isODFWhitespace(leftChar)) { r = FILTER_ACCEPT }else { @@ -12650,14 +13134,14 @@ ops.TextPositionFilter = function TextPositionFilter(getRootNode) { } }else { leftNode = odfUtils.previousNode(container); - if(odfUtils.scanLeftForNonWhitespace(leftNode)) { + if(odfUtils.scanLeftForNonSpace(leftNode)) { r = FILTER_ACCEPT } } if(r === FILTER_ACCEPT) { return odfUtils.isTrailingWhitespace(container, offset) ? FILTER_REJECT : FILTER_ACCEPT } - rightChar = text.substr(offset, 1); + rightChar = text[offset]; if(odfUtils.isODFWhitespace(rightChar)) { return FILTER_REJECT } @@ -12746,17 +13230,17 @@ ops.OperationTransformMatrix = function OperationTransformMatrix() { }); return result } - function dropShadowedAttributes(minorSetProperties, minorRemovedProperties, majorSetProperties, majorRemovedProperties) { - var value, i, name, majorChanged = false, minorChanged = false, shadowingPropertyValue, removedPropertyNames, majorRemovedPropertyNames = majorRemovedProperties && majorRemovedProperties.attributes ? majorRemovedProperties.attributes.split(",") : []; + function dropOverruledAndUnneededAttributes(minorSetProperties, minorRemovedProperties, majorSetProperties, majorRemovedProperties) { + var value, i, name, majorChanged = false, minorChanged = false, overrulingPropertyValue, removedPropertyNames, majorRemovedPropertyNames = majorRemovedProperties && majorRemovedProperties.attributes ? majorRemovedProperties.attributes.split(",") : []; if(minorSetProperties && (majorSetProperties || majorRemovedPropertyNames.length > 0)) { Object.keys(minorSetProperties).forEach(function(key) { value = minorSetProperties[key]; if(typeof value !== "object") { - shadowingPropertyValue = majorSetProperties && majorSetProperties[key]; - if(shadowingPropertyValue !== undefined) { + overrulingPropertyValue = majorSetProperties && majorSetProperties[key]; + if(overrulingPropertyValue !== undefined) { delete minorSetProperties[key]; minorChanged = true; - if(shadowingPropertyValue === value) { + if(overrulingPropertyValue === value) { delete majorSetProperties[key]; majorChanged = true } @@ -12807,9 +13291,9 @@ ops.OperationTransformMatrix = function OperationTransformMatrix() { } return false } - function dropShadowedProperties(minorOpspec, majorOpspec, propertiesName) { + function dropOverruledAndUnneededProperties(minorOpspec, majorOpspec, propertiesName) { var minorSP = minorOpspec.setProperties ? minorOpspec.setProperties[propertiesName] : null, minorRP = minorOpspec.removedProperties ? minorOpspec.removedProperties[propertiesName] : null, majorSP = majorOpspec.setProperties ? majorOpspec.setProperties[propertiesName] : null, majorRP = majorOpspec.removedProperties ? majorOpspec.removedProperties[propertiesName] : null, result; - result = dropShadowedAttributes(minorSP, minorRP, majorSP, majorRP); + result = dropOverruledAndUnneededAttributes(minorSP, minorRP, majorSP, majorRP); if(minorSP && !hasProperties(minorSP)) { delete minorOpspec.setProperties[propertiesName] } @@ -12845,7 +13329,7 @@ ops.OperationTransformMatrix = function OperationTransformMatrix() { originalMajorSpec = cloneOpspec(majorSpec); originalMinorSpec = cloneOpspec(minorSpec) } - dropResult = dropShadowedProperties(minorSpec, majorSpec, "style:text-properties"); + dropResult = dropOverruledAndUnneededProperties(minorSpec, majorSpec, "style:text-properties"); if(dropResult.majorChanged || dropResult.minorChanged) { majorSpecResult = []; minorSpecResult = []; @@ -13019,9 +13503,9 @@ ops.OperationTransformMatrix = function OperationTransformMatrix() { if(updateParagraphStyleSpecA.styleName === updateParagraphStyleSpecB.styleName) { majorSpec = hasAPriority ? updateParagraphStyleSpecA : updateParagraphStyleSpecB; minorSpec = hasAPriority ? updateParagraphStyleSpecB : updateParagraphStyleSpecA; - dropShadowedProperties(minorSpec, majorSpec, "style:paragraph-properties"); - dropShadowedProperties(minorSpec, majorSpec, "style:text-properties"); - dropShadowedAttributes(minorSpec.setProperties || null, minorSpec.removedProperties || null, majorSpec.setProperties || null, majorSpec.removedProperties || null); + dropOverruledAndUnneededProperties(minorSpec, majorSpec, "style:paragraph-properties"); + dropOverruledAndUnneededProperties(minorSpec, majorSpec, "style:text-properties"); + dropOverruledAndUnneededAttributes(minorSpec.setProperties || null, minorSpec.removedProperties || null, majorSpec.setProperties || null, majorSpec.removedProperties || null); if(!(majorSpec.setProperties && hasProperties(majorSpec.setProperties)) && !(majorSpec.removedProperties && hasRemovedProperties(majorSpec.removedProperties))) { if(hasAPriority) { updateParagraphStyleSpecAResult = [] @@ -13039,6 +13523,27 @@ ops.OperationTransformMatrix = function OperationTransformMatrix() { } return{opSpecsA:updateParagraphStyleSpecAResult, opSpecsB:updateParagraphStyleSpecBResult} } + function transformUpdateMetadataUpdateMetadata(updateMetadataSpecA, updateMetadataSpecB, hasAPriority) { + var majorSpec, minorSpec, updateMetadataSpecAResult = [updateMetadataSpecA], updateMetadataSpecBResult = [updateMetadataSpecB]; + majorSpec = hasAPriority ? updateMetadataSpecA : updateMetadataSpecB; + minorSpec = hasAPriority ? updateMetadataSpecB : updateMetadataSpecA; + dropOverruledAndUnneededAttributes(minorSpec.setProperties || null, minorSpec.removedProperties || null, majorSpec.setProperties || null, majorSpec.removedProperties || null); + if(!(majorSpec.setProperties && hasProperties(majorSpec.setProperties)) && !(majorSpec.removedProperties && hasRemovedProperties(majorSpec.removedProperties))) { + if(hasAPriority) { + updateMetadataSpecAResult = [] + }else { + updateMetadataSpecBResult = [] + } + } + if(!(minorSpec.setProperties && hasProperties(minorSpec.setProperties)) && !(minorSpec.removedProperties && hasRemovedProperties(minorSpec.removedProperties))) { + if(hasAPriority) { + updateMetadataSpecBResult = [] + }else { + updateMetadataSpecAResult = [] + } + } + return{opSpecsA:updateMetadataSpecAResult, opSpecsB:updateMetadataSpecBResult} + } function transformSplitParagraphSplitParagraph(splitParagraphSpecA, splitParagraphSpecB, hasAPriority) { if(splitParagraphSpecA.position < splitParagraphSpecB.position) { splitParagraphSpecB.position += 1 @@ -13202,11 +13707,14 @@ ops.OperationTransformMatrix = function OperationTransformMatrix() { function passUnchanged(opSpecA, opSpecB) { return{opSpecsA:[opSpecA], opSpecsB:[opSpecB]} } - var transformations = {"AddCursor":{"AddCursor":passUnchanged, "AddStyle":passUnchanged, "ApplyDirectStyling":passUnchanged, "InsertText":passUnchanged, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "AddStyle":{"AddStyle":passUnchanged, "ApplyDirectStyling":passUnchanged, "InsertText":passUnchanged, "MoveCursor":passUnchanged, - "RemoveCursor":passUnchanged, "RemoveStyle":transformAddStyleRemoveStyle, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "ApplyDirectStyling":{"ApplyDirectStyling":transformApplyDirectStylingApplyDirectStyling, "InsertText":transformApplyDirectStylingInsertText, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":transformApplyDirectStylingRemoveText, "SetParagraphStyle":passUnchanged, - "SplitParagraph":transformApplyDirectStylingSplitParagraph, "UpdateParagraphStyle":passUnchanged}, "InsertText":{"InsertText":transformInsertTextInsertText, "MoveCursor":transformInsertTextMoveCursor, "RemoveCursor":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":transformInsertTextRemoveText, "SplitParagraph":transformInsertTextSplitParagraph, "UpdateParagraphStyle":passUnchanged}, "MoveCursor":{"MoveCursor":passUnchanged, "RemoveCursor":transformMoveCursorRemoveCursor, "RemoveStyle":passUnchanged, - "RemoveText":transformMoveCursorRemoveText, "SetParagraphStyle":passUnchanged, "SplitParagraph":transformMoveCursorSplitParagraph, "UpdateParagraphStyle":passUnchanged}, "RemoveCursor":{"RemoveCursor":transformRemoveCursorRemoveCursor, "RemoveStyle":passUnchanged, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "RemoveStyle":{"RemoveStyle":transformRemoveStyleRemoveStyle, "RemoveText":passUnchanged, "SetParagraphStyle":transformRemoveStyleSetParagraphStyle, - "SplitParagraph":passUnchanged, "UpdateParagraphStyle":transformRemoveStyleUpdateParagraphStyle}, "RemoveText":{"RemoveText":transformRemoveTextRemoveText, "SplitParagraph":transformRemoveTextSplitParagraph, "UpdateParagraphStyle":passUnchanged}, "SetParagraphStyle":{"UpdateParagraphStyle":passUnchanged}, "SplitParagraph":{"SplitParagraph":transformSplitParagraphSplitParagraph, "UpdateParagraphStyle":passUnchanged}, "UpdateParagraphStyle":{"UpdateParagraphStyle":transformUpdateParagraphStyleUpdateParagraphStyle}}; + var transformations = {"AddCursor":{"AddCursor":passUnchanged, "AddMember":passUnchanged, "AddStyle":passUnchanged, "ApplyDirectStyling":passUnchanged, "InsertText":passUnchanged, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveMember":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "AddMember":{"AddStyle":passUnchanged, + "InsertText":passUnchanged, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "AddStyle":{"AddStyle":passUnchanged, "ApplyDirectStyling":passUnchanged, "InsertText":passUnchanged, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveMember":passUnchanged, "RemoveStyle":transformAddStyleRemoveStyle, + "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "ApplyDirectStyling":{"ApplyDirectStyling":transformApplyDirectStylingApplyDirectStyling, "InsertText":transformApplyDirectStylingInsertText, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":transformApplyDirectStylingRemoveText, "SetParagraphStyle":passUnchanged, + "SplitParagraph":transformApplyDirectStylingSplitParagraph, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "InsertText":{"InsertText":transformInsertTextInsertText, "MoveCursor":transformInsertTextMoveCursor, "RemoveCursor":passUnchanged, "RemoveMember":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":transformInsertTextRemoveText, "SplitParagraph":transformInsertTextSplitParagraph, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, + "MoveCursor":{"MoveCursor":passUnchanged, "RemoveCursor":transformMoveCursorRemoveCursor, "RemoveMember":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":transformMoveCursorRemoveText, "SetParagraphStyle":passUnchanged, "SplitParagraph":transformMoveCursorSplitParagraph, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "RemoveCursor":{"RemoveCursor":transformRemoveCursorRemoveCursor, "RemoveMember":passUnchanged, "RemoveStyle":passUnchanged, + "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "RemoveMember":{"RemoveStyle":passUnchanged, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "RemoveStyle":{"RemoveStyle":transformRemoveStyleRemoveStyle, "RemoveText":passUnchanged, "SetParagraphStyle":transformRemoveStyleSetParagraphStyle, + "SplitParagraph":passUnchanged, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":transformRemoveStyleUpdateParagraphStyle}, "RemoveText":{"RemoveText":transformRemoveTextRemoveText, "SplitParagraph":transformRemoveTextSplitParagraph, "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "SetParagraphStyle":{"UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "SplitParagraph":{"SplitParagraph":transformSplitParagraphSplitParagraph, + "UpdateMember":passUnchanged, "UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "UpdateMember":{"UpdateMetadata":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "UpdateMetadata":{"UpdateMetadata":transformUpdateMetadataUpdateMetadata, "UpdateParagraphStyle":passUnchanged}, "UpdateParagraphStyle":{"UpdateParagraphStyle":transformUpdateParagraphStyleUpdateParagraphStyle}}; this.passUnchanged = passUnchanged; this.extendTransformations = function(moreTransformations) { Object.keys(moreTransformations).forEach(function(optypeA) { @@ -13635,14 +14143,6 @@ gui.Caret = function Caret(cursor, avatarInitiallyVisible, blinkOnRangeSelect) { } return selectionRectangle } - function getSpanBoundingClientRect() { - var range, rangeRect; - range = span.ownerDocument.createRange(); - range.selectNode(span); - rangeRect = range.getBoundingClientRect(); - range.detach(); - return rangeRect - } function handleUpdate() { var selectionRect = getSelectionRect(), zoomLevel = cursor.getOdtDocument().getOdfCanvas().getZoomLevel(), caretRect; if(isShown && cursor.getSelectionType() === ops.OdtCursor.RangeSelection) { @@ -13652,7 +14152,7 @@ gui.Caret = function Caret(cursor, avatarInitiallyVisible, blinkOnRangeSelect) { } if(selectionRect) { span.style.top = "0"; - caretRect = getSpanBoundingClientRect(); + caretRect = domUtils.getBoundingClientRect(span); if(selectionRect.height < MIN_CARET_HEIGHT_PX) { selectionRect = {top:selectionRect.top - (MIN_CARET_HEIGHT_PX - selectionRect.height) / 2, height:MIN_CARET_HEIGHT_PX} } @@ -14664,35 +15164,22 @@ gui.TextManipulator = function TextManipulator(session, inputMemberId, directSty 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. - - You should have received a copy of the GNU Affero General Public License - along with this code. If not, see . + This file is part of WebODF. - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. - This license applies to this entire compilation. + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . @licend + @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ @@ -14701,8 +15188,8 @@ runtime.loadClass("core.PositionFilter"); runtime.loadClass("ops.OpAddAnnotation"); runtime.loadClass("ops.OpRemoveAnnotation"); runtime.loadClass("gui.SelectionMover"); -gui.AnnotationManager = function AnnotationManager(session, inputMemberId) { - var odtDocument = session.getOdtDocument(), isAnnotatable = false, eventNotifier = new core.EventNotifier([gui.AnnotationManager.annotatableChanged]), officens = odf.Namespaces.officens; +gui.AnnotationController = function AnnotationController(session, inputMemberId) { + var odtDocument = session.getOdtDocument(), isAnnotatable = false, eventNotifier = new core.EventNotifier([gui.AnnotationController.annotatableChanged]), officens = odf.Namespaces.officens; function isWithinAnnotation(node, container) { while(node && node !== container) { if(node.namespaceURI === officens && node.localName === "annotation") { @@ -14716,7 +15203,7 @@ gui.AnnotationManager = function AnnotationManager(session, inputMemberId) { var cursor = odtDocument.getCursor(inputMemberId), cursorNode = cursor && cursor.getNode(), newIsAnnotatable = cursorNode && !isWithinAnnotation(cursorNode, odtDocument.getRootNode()); if(newIsAnnotatable !== isAnnotatable) { isAnnotatable = newIsAnnotatable; - eventNotifier.emit(gui.AnnotationManager.annotatableChanged, isAnnotatable) + eventNotifier.emit(gui.AnnotationController.annotatableChanged, isAnnotatable) } } function onCursorAdded(cursor) { @@ -14777,12 +15264,28 @@ gui.AnnotationManager = function AnnotationManager(session, inputMemberId) { } init() }; -gui.AnnotationManager.annotatableChanged = "annotatable/changed"; +gui.AnnotationController.annotatableChanged = "annotatable/changed"; (function() { - return gui.AnnotationManager + return gui.AnnotationController })(); gui.EventManager = function EventManager(odtDocument) { - var canvasElement = odtDocument.getOdfCanvas().getElement(), window = runtime.getWindow(), bindToDirectHandler = {"beforecut":true, "beforepaste":true}, bindToWindow = {"mousedown":true, "mouseup":true}; + var canvasElement = odtDocument.getOdfCanvas().getElement(), window = runtime.getWindow(), bindToDirectHandler = {"beforecut":true, "beforepaste":true}, bindToWindow; + function EventDelegate() { + var self = this, recentEvents = []; + this.handlers = []; + this.isSubscribed = false; + this.handleEvent = function(e) { + if(recentEvents.indexOf(e) === -1) { + recentEvents.push(e); + self.handlers.forEach(function(handler) { + handler(e) + }); + runtime.setTimeout(function() { + recentEvents.splice(recentEvents.indexOf(e), 1) + }, 0) + } + } + } function WindowScrollState(window) { var x = window.scrollX, y = window.scrollY; this.restore = function() { @@ -14826,18 +15329,27 @@ gui.EventManager = function EventManager(odtDocument) { } } this.subscribe = function(eventName, handler) { - var element = canvasElement; - if(bindToWindow[eventName] && window) { - element = window + var delegate = window && bindToWindow[eventName]; + if(delegate) { + delegate.handlers.push(handler); + if(!delegate.isSubscribed) { + delegate.isSubscribed = true; + listenEvent((window), eventName, delegate.handleEvent); + listenEvent(canvasElement, eventName, delegate.handleEvent) + } + }else { + listenEvent(canvasElement, eventName, handler) } - listenEvent(element, eventName, handler) }; this.unsubscribe = function(eventName, handler) { - var element = canvasElement; - if(bindToWindow[eventName] && window) { - element = window + var delegate = window && bindToWindow[eventName], handlerIndex = delegate && delegate.handlers.indexOf(handler); + if(delegate) { + if(handlerIndex !== -1) { + delegate.handlers.splice(handlerIndex, 1) + } + }else { + removeEvent(canvasElement, eventName, handler) } - removeEvent(element, eventName, handler) }; function hasFocus() { var activeElement = odtDocument.getDOM().activeElement; @@ -14865,7 +15377,11 @@ gui.EventManager = function EventManager(odtDocument) { scrollParent.restore() } } + }; + function init() { + bindToWindow = {"mousedown":new EventDelegate, "mouseup":new EventDelegate} } + init() }; runtime.loadClass("core.DomUtils"); runtime.loadClass("core.Async"); @@ -14882,15 +15398,15 @@ runtime.loadClass("gui.KeyboardHandler"); runtime.loadClass("gui.ImageManager"); runtime.loadClass("gui.ImageSelector"); runtime.loadClass("gui.TextManipulator"); -runtime.loadClass("gui.AnnotationManager"); +runtime.loadClass("gui.AnnotationController"); runtime.loadClass("gui.EventManager"); runtime.loadClass("gui.PlainTextPasteboard"); gui.SessionController = function() { var FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT; gui.SessionController = function SessionController(session, inputMemberId, shadowCursor, args) { var window = (runtime.getWindow()), odtDocument = session.getOdtDocument(), async = new core.Async, domUtils = new core.DomUtils, odfUtils = new odf.OdfUtils, clipboard = new gui.Clipboard, keyDownHandler = new gui.KeyboardHandler, keyPressHandler = new gui.KeyboardHandler, keyboardMovementsFilter = new core.PositionFilterChain, baseFilter = odtDocument.getPositionFilter(), clickStartedWithinContainer = false, objectNameGenerator = new odf.ObjectNameGenerator(odtDocument.getOdfCanvas().odfContainer(), - inputMemberId), isMouseMoved = false, mouseDownRootFilter = null, undoManager = null, eventManager = new gui.EventManager(odtDocument), annotationManager = new gui.AnnotationManager(session, inputMemberId), directTextStyler = new gui.DirectTextStyler(session, inputMemberId), directParagraphStyler = args && args.directParagraphStylingEnabled ? new gui.DirectParagraphStyler(session, inputMemberId, objectNameGenerator) : null, createCursorStyleOp = (directTextStyler.createCursorStyleOp), textManipulator = - new gui.TextManipulator(session, inputMemberId, createCursorStyleOp), imageManager = new gui.ImageManager(session, inputMemberId, objectNameGenerator), imageSelector = new gui.ImageSelector(odtDocument.getOdfCanvas()), shadowCursorIterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), drawShadowCursorTask, pasteHandler = new gui.PlainTextPasteboard(odtDocument, inputMemberId); + inputMemberId), isMouseMoved = false, mouseDownRootFilter = null, undoManager = null, eventManager = new gui.EventManager(odtDocument), annotationController = new gui.AnnotationController(session, inputMemberId), directTextStyler = new gui.DirectTextStyler(session, inputMemberId), directParagraphStyler = args && args.directParagraphStylingEnabled ? new gui.DirectParagraphStyler(session, inputMemberId, objectNameGenerator) : null, createCursorStyleOp = (directTextStyler.createCursorStyleOp), textManipulator = + new gui.TextManipulator(session, inputMemberId, createCursorStyleOp), imageManager = new gui.ImageManager(session, inputMemberId, objectNameGenerator), imageSelector = new gui.ImageSelector(odtDocument.getOdfCanvas()), shadowCursorIterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), drawShadowCursorTask, suppressFocusEvent = false, pasteHandler = new gui.PlainTextPasteboard(odtDocument, inputMemberId); runtime.assert(window !== null, "Expected to be run in an environment which has a global window, like a browser."); keyboardMovementsFilter.addFilter("BaseFilter", baseFilter); keyboardMovementsFilter.addFilter("RootFilter", odtDocument.createRootFilter(inputMemberId)); @@ -15207,8 +15723,13 @@ gui.SessionController = function() { selection.extend(range.startContainer, range.startOffset) } }else { + suppressFocusEvent = true; selection.removeAllRanges(); - selection.addRange(range.cloneRange()) + selection.addRange(range.cloneRange()); + odtDocument.getOdfCanvas().getElement().setActive(); + runtime.setTimeout(function() { + suppressFocusEvent = false + }, 0) } } }else { @@ -15216,7 +15737,9 @@ gui.SessionController = function() { } } function delayedMaintainCursor() { - runtime.setTimeout(maintainCursorSelection, 0) + if(suppressFocusEvent === false) { + runtime.setTimeout(maintainCursorSelection, 0) + } } function stringFromKeyPress(event) { if(event.which === null || event.which === undefined) { @@ -15340,7 +15863,7 @@ gui.SessionController = function() { var target = getTarget(event), annotationNode = null; if(target.className === "annotationRemoveButton") { annotationNode = domUtils.getElementsByTagNameNS(target.parentNode, odf.Namespaces.officens, "annotation")[0]; - annotationManager.removeAnnotation(annotationNode) + annotationController.removeAnnotation(annotationNode) }else { handleMouseClickEvent(event) } @@ -15431,8 +15954,8 @@ gui.SessionController = function() { this.getUndoManager = function() { return undoManager }; - this.getAnnotationManager = function() { - return annotationManager + this.getAnnotationController = function() { + return annotationController }; this.getDirectTextStyler = function() { return directTextStyler @@ -15523,8 +16046,8 @@ gui.SessionController = function() { keyDownHandler.bind(keyCode.R, modifier.MetaShift, rangeSelectionOnly(directParagraphStyler.alignParagraphRight)); keyDownHandler.bind(keyCode.J, modifier.MetaShift, rangeSelectionOnly(directParagraphStyler.alignParagraphJustified)) } - if(annotationManager) { - keyDownHandler.bind(keyCode.C, modifier.MetaShift, annotationManager.addAnnotation) + if(annotationController) { + keyDownHandler.bind(keyCode.C, modifier.MetaShift, annotationController.addAnnotation) } keyDownHandler.bind(keyCode.Z, modifier.Meta, undo); keyDownHandler.bind(keyCode.Z, modifier.MetaShift, redo) @@ -15539,8 +16062,8 @@ gui.SessionController = function() { keyDownHandler.bind(keyCode.R, modifier.CtrlShift, rangeSelectionOnly(directParagraphStyler.alignParagraphRight)); keyDownHandler.bind(keyCode.J, modifier.CtrlShift, rangeSelectionOnly(directParagraphStyler.alignParagraphJustified)) } - if(annotationManager) { - keyDownHandler.bind(keyCode.C, modifier.CtrlAlt, annotationManager.addAnnotation) + if(annotationController) { + keyDownHandler.bind(keyCode.C, modifier.CtrlAlt, annotationController.addAnnotation) } keyDownHandler.bind(keyCode.Z, modifier.Ctrl, undo); keyDownHandler.bind(keyCode.Z, modifier.CtrlShift, redo) @@ -15559,98 +16082,6 @@ gui.SessionController = function() { }; return gui.SessionController }(); -/* - - 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. - - You should have received a copy of the GNU Affero General Public License - along with this code. If not, see . - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: https://github.com/kogmbh/WebODF/ -*/ -ops.MemberModel = function MemberModel() { -}; -ops.MemberModel.prototype.getMemberDetailsAndUpdates = function(memberId, subscriber) { -}; -ops.MemberModel.prototype.unsubscribeMemberDetailsUpdates = function(memberId, subscriber) { -}; -ops.MemberModel.prototype.close = function(callback) { -}; -/* - - 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. - - You should have received a copy of the GNU Affero General Public License - along with this code. If not, see . - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: https://github.com/kogmbh/WebODF/ -*/ -ops.TrivialMemberModel = function TrivialMemberModel() { - this.getMemberDetailsAndUpdates = function(memberId, subscriber) { - subscriber(memberId, {memberid:memberId, fullname:runtime.tr("Unknown Author"), color:"black", imageurl:"avatar-joe.png"}) - }; - this.unsubscribeMemberDetailsUpdates = function(memberId, subscriber) { - }; - this.close = function(cb) { - cb() - } -}; /* Copyright (C) 2013 KO GmbH @@ -15970,7 +16401,6 @@ gui.EditInfoMarker = function EditInfoMarker(editInfo, initialVisibility) { @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("gui.Caret"); -runtime.loadClass("ops.TrivialMemberModel"); runtime.loadClass("ops.EditInfo"); runtime.loadClass("gui.EditInfoMarker"); gui.SessionViewOptions = function() { @@ -16009,7 +16439,6 @@ gui.SessionView = function() { setStyle("div.editInfoMarker", "{ background-color: " + color + "; }", ""); setStyle("span.editInfoColor", "{ background-color: " + color + "; }", ""); setStyle("span.editInfoAuthor", '{ content: "' + name + '"; }', ":before"); - setStyle("dc|creator", '{ content: "' + name + '"; display: none;}', ":before"); setStyle("dc|creator", "{ background-color: " + color + "; }", ""); setStyle("div.selectionOverlay", "{ background-color: " + color + ";}", "") } @@ -16084,27 +16513,22 @@ gui.SessionView = function() { this.getCaret = function(memberid) { return caretManager.getCaret(memberid) }; - function renderMemberData(memberId, memberData) { - var caret = caretManager.getCaret(memberId); - if(!memberData) { - runtime.log('MemberModel sent undefined data for member "' + memberId + '".'); - return - } - if(caret) { - caret.setAvatarImageUrl(memberData.imageurl); - caret.setColor(memberData.color) - } - setAvatarInfoStyle(memberId, memberData.fullname, memberData.color); + function renderMemberData(member) { + var memberId = member.getMemberId(), properties = member.getProperties(); + setAvatarInfoStyle(memberId, properties.fullName, properties.color); if(localMemberId === memberId) { - setAvatarInfoStyle("", memberData.fullname, memberData.color) + setAvatarInfoStyle("", "", properties.color) } } function onCursorAdded(cursor) { - var memberId = cursor.getMemberId(), memberModel = session.getMemberModel(); + var memberId = cursor.getMemberId(), properties = session.getOdtDocument().getMember(memberId).getProperties(), caret; caretManager.registerCursor(cursor, showCaretAvatars, blinkOnRangeSelect); selectionViewManager.registerCursor(cursor, true); - renderMemberData(memberId, null); - memberModel.getMemberDetailsAndUpdates(memberId, renderMemberData); + caret = caretManager.getCaret(memberId); + if(caret) { + caret.setAvatarImageUrl(properties.imageUrl); + caret.setColor(properties.color) + } runtime.log("+++ View here +++ eagerly created an Caret for '" + memberId + "'! +++") } function onCursorMoved(cursor) { @@ -16126,17 +16550,7 @@ gui.SessionView = function() { } } function onCursorRemoved(memberid) { - var hasMemberEditInfo = false, keyname; - for(keyname in editInfoMap) { - if(editInfoMap.hasOwnProperty(keyname) && editInfoMap[keyname].getEditInfo().getEdits().hasOwnProperty(memberid)) { - hasMemberEditInfo = true; - break - } - } - selectionViewManager.removeSelectionView(memberid); - if(!hasMemberEditInfo) { - session.getMemberModel().unsubscribeMemberDetailsUpdates(memberid, renderMemberData) - } + selectionViewManager.removeSelectionView(memberid) } function onParagraphChanged(info) { highlightEdit(info.paragraphElement, info.memberId, info.timeStamp) @@ -16156,9 +16570,11 @@ gui.SessionView = function() { runtime.getWindow().clearInterval(rerenderIntervalId) } this.destroy = function(callback) { - var odtDocument = session.getOdtDocument(), memberModel = session.getMemberModel(), editInfoArray = Object.keys(editInfoMap).map(function(keyname) { + var odtDocument = session.getOdtDocument(), editInfoArray = Object.keys(editInfoMap).map(function(keyname) { return editInfoMap[keyname] }); + odtDocument.unsubscribe(ops.OdtDocument.signalMemberAdded, renderMemberData); + odtDocument.unsubscribe(ops.OdtDocument.signalMemberUpdated, renderMemberData); odtDocument.unsubscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); @@ -16167,9 +16583,6 @@ gui.SessionView = function() { odtDocument.unsubscribe(ops.OdtDocument.signalTableAdded, requestRerenderOfSelectionViews); odtDocument.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, requestRerenderOfSelectionViews); stopRerenderLoop(); - caretManager.getCarets().forEach(function(caret) { - memberModel.unsubscribeMemberDetailsUpdates(caret.getCursor().getMemberId(), renderMemberData) - }); avatarInfoStyles.parentNode.removeChild(avatarInfoStyles); (function destroyEditInfo(i, err) { if(err) { @@ -16187,6 +16600,8 @@ gui.SessionView = function() { }; function init() { var odtDocument = session.getOdtDocument(), head = document.getElementsByTagName("head")[0]; + odtDocument.subscribe(ops.OdtDocument.signalMemberAdded, renderMemberData); + odtDocument.subscribe(ops.OdtDocument.signalMemberUpdated, renderMemberData); odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); @@ -16482,16 +16897,7 @@ gui.UndoStateRules = function UndoStateRules() { return op.spec().position } function isEditOperation(op) { - switch(getOpType(op)) { - case "MoveCursor": - ; - case "AddCursor": - ; - case "RemoveCursor": - return false; - default: - return true - } + return op.isEdit } this.isEditOperation = isEditOperation; function canAggregateOperation(optype) { @@ -16655,9 +17061,9 @@ gui.TrivialUndoManager = function TrivialUndoManager(defaultRules) { emitStackChange() }; this.saveInitialState = function() { - var odfContainer = odtDocument.getOdfCanvas().odfContainer(), annotationManager = odtDocument.getOdfCanvas().getAnnotationManager(); - if(annotationManager) { - annotationManager.forgetAnnotations() + var odfContainer = odtDocument.getOdfCanvas().odfContainer(), annotationViewManager = odtDocument.getOdfCanvas().getAnnotationViewManager(); + if(annotationViewManager) { + annotationViewManager.forgetAnnotations() } initialDoc = odfContainer.rootElement.cloneNode(true); odtDocument.getOdfCanvas().refreshAnnotations(); @@ -16734,14 +17140,16 @@ runtime.loadClass("odf.OdfUtils"); runtime.loadClass("odf.OdfNodeFilter"); runtime.loadClass("gui.SelectionMover"); gui.SelectionView = function SelectionView(cursor) { - var odtDocument = cursor.getOdtDocument(), root = odtDocument.getRootNode().parentNode.parentNode, doc = odtDocument.getDOM(), overlayTop = doc.createElement("div"), overlayMiddle = doc.createElement("div"), overlayBottom = doc.createElement("div"), odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils, isVisible = true, clientRectRange = doc.createRange(), positionIterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), areRangeClientRectsScaled = domUtils.areRangeRectanglesTransformed(doc), - FILTER_ACCEPT = NodeFilter.FILTER_ACCEPT, FILTER_REJECT = NodeFilter.FILTER_REJECT; - function getBoundingClientRect(node) { - if(areRangeClientRectsScaled && node.nodeType === Node.ELEMENT_NODE) { - return node.getBoundingClientRect() + var odtDocument = cursor.getOdtDocument(), documentRoot, root, doc = odtDocument.getDOM(), overlayTop = doc.createElement("div"), overlayMiddle = doc.createElement("div"), overlayBottom = doc.createElement("div"), odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils, isVisible = true, positionIterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), FILTER_ACCEPT = NodeFilter.FILTER_ACCEPT, FILTER_REJECT = NodeFilter.FILTER_REJECT; + function addOverlays() { + var newDocumentRoot = odtDocument.getRootNode(); + if(documentRoot !== newDocumentRoot) { + documentRoot = newDocumentRoot; + root = documentRoot.parentNode.parentNode.parentNode; + root.appendChild(overlayTop); + root.appendChild(overlayMiddle); + root.appendChild(overlayBottom) } - clientRectRange.selectNode(node); - return clientRectRange.getBoundingClientRect() } function setRect(div, rect) { div.style.left = rect.left + "px"; @@ -16756,7 +17164,7 @@ gui.SelectionView = function SelectionView(cursor) { overlayTop.style.display = overlayMiddle.style.display = overlayBottom.style.display = display } function translateRect(rect) { - var rootRect = getBoundingClientRect(root), zoomLevel = odtDocument.getOdfCanvas().getZoomLevel(), resultRect = {}; + var rootRect = domUtils.getBoundingClientRect(root), zoomLevel = odtDocument.getOdfCanvas().getZoomLevel(), resultRect = {}; resultRect.top = domUtils.adaptRangeDifferenceToZoomLevel(rect.top - rootRect.top, zoomLevel); resultRect.left = domUtils.adaptRangeDifferenceToZoomLevel(rect.left - rootRect.left, zoomLevel); resultRect.bottom = domUtils.adaptRangeDifferenceToZoomLevel(rect.bottom - rootRect.top, zoomLevel); @@ -16866,7 +17274,7 @@ gui.SelectionView = function SelectionView(cursor) { function getRectFromNodeAfterFiltering(node) { var rect = null; if(acceptNode(node) === FILTER_ACCEPT) { - rect = getBoundingClientRect(node) + rect = domUtils.getBoundingClientRect(node) } return rect } @@ -16892,36 +17300,52 @@ gui.SelectionView = function SelectionView(cursor) { currentNode = currentNode.nextSibling } if(odfUtils.isParagraph(firstSibling)) { - grownRect = checkAndGrowOrCreateRect(grownRect, getBoundingClientRect(firstSibling)) + grownRect = checkAndGrowOrCreateRect(grownRect, domUtils.getBoundingClientRect(firstSibling)) }else { - treeWalker = doc.createTreeWalker(firstSibling, NodeFilter.SHOW_TEXT, acceptNode); - currentNode = treeWalker.currentNode = firstNode; - while(currentNode && currentNode !== lastNode) { + if(firstSibling.nodeType === Node.TEXT_NODE) { + currentNode = firstSibling; range.setStart(currentNode, firstOffset); - range.setEnd(currentNode, currentNode.length); + range.setEnd(currentNode, currentNode === lastSibling ? lastOffset : currentNode.length); currentRect = range.getBoundingClientRect(); - grownRect = checkAndGrowOrCreateRect(grownRect, currentRect); - lastMeasuredNode = currentNode; - firstOffset = 0; - currentNode = treeWalker.nextNode() + grownRect = checkAndGrowOrCreateRect(grownRect, currentRect) + }else { + treeWalker = doc.createTreeWalker(firstSibling, NodeFilter.SHOW_TEXT, acceptNode, false); + currentNode = treeWalker.currentNode = firstNode; + while(currentNode && currentNode !== lastNode) { + range.setStart(currentNode, firstOffset); + range.setEnd(currentNode, currentNode.length); + currentRect = range.getBoundingClientRect(); + grownRect = checkAndGrowOrCreateRect(grownRect, currentRect); + lastMeasuredNode = currentNode; + firstOffset = 0; + currentNode = treeWalker.nextNode() + } } } if(!lastMeasuredNode) { lastMeasuredNode = firstNode } if(odfUtils.isParagraph(lastSibling)) { - grownRect = checkAndGrowOrCreateRect(grownRect, getBoundingClientRect(firstSibling)) + grownRect = checkAndGrowOrCreateRect(grownRect, domUtils.getBoundingClientRect(lastSibling)) }else { - treeWalker = doc.createTreeWalker(lastSibling, NodeFilter.SHOW_TEXT, acceptNode); - currentNode = treeWalker.currentNode = lastNode; - while(currentNode && currentNode !== lastMeasuredNode) { - range.setStart(currentNode, 0); + if(lastSibling.nodeType === Node.TEXT_NODE) { + currentNode = lastSibling; + range.setStart(currentNode, currentNode === firstSibling ? firstOffset : 0); range.setEnd(currentNode, lastOffset); currentRect = range.getBoundingClientRect(); - grownRect = checkAndGrowOrCreateRect(grownRect, currentRect); - currentNode = treeWalker.previousNode(); - if(currentNode) { - lastOffset = currentNode.length + grownRect = checkAndGrowOrCreateRect(grownRect, currentRect) + }else { + treeWalker = doc.createTreeWalker(lastSibling, NodeFilter.SHOW_TEXT, acceptNode, false); + currentNode = treeWalker.currentNode = lastNode; + while(currentNode && currentNode !== lastMeasuredNode) { + range.setStart(currentNode, 0); + range.setEnd(currentNode, lastOffset); + currentRect = range.getBoundingClientRect(); + grownRect = checkAndGrowOrCreateRect(grownRect, currentRect); + currentNode = treeWalker.previousNode(); + if(currentNode) { + lastOffset = currentNode.length + } } } } @@ -16966,6 +17390,7 @@ gui.SelectionView = function SelectionView(cursor) { } } function rerender() { + addOverlays(); if(cursor.getSelectionType() === ops.OdtCursor.RangeSelection) { showOverlays(true); repositionOverlays(cursor.getSelectedRange()) @@ -16995,9 +17420,7 @@ gui.SelectionView = function SelectionView(cursor) { }; function init() { var editinfons = "urn:webodf:names:editinfo", memberid = cursor.getMemberId(); - root.appendChild(overlayTop); - root.appendChild(overlayMiddle); - root.appendChild(overlayBottom); + addOverlays(); overlayTop.setAttributeNS(editinfons, "editinfo:memberid", memberid); overlayMiddle.setAttributeNS(editinfons, "editinfo:memberid", memberid); overlayBottom.setAttributeNS(editinfons, "editinfo:memberid", memberid); @@ -17155,9 +17578,10 @@ runtime.loadClass("gui.SelectionMover"); runtime.loadClass("core.PositionFilterChain"); runtime.loadClass("ops.StepsTranslator"); runtime.loadClass("ops.TextPositionFilter"); +runtime.loadClass("ops.Member"); ops.OdtDocument = function OdtDocument(odfCanvas) { - var self = this, odfUtils, domUtils, cursors = {}, eventNotifier = new core.EventNotifier([ops.OdtDocument.signalCursorAdded, ops.OdtDocument.signalCursorRemoved, ops.OdtDocument.signalCursorMoved, ops.OdtDocument.signalParagraphChanged, ops.OdtDocument.signalParagraphStyleModified, ops.OdtDocument.signalCommonStyleCreated, ops.OdtDocument.signalCommonStyleDeleted, ops.OdtDocument.signalTableAdded, ops.OdtDocument.signalOperationExecuted, ops.OdtDocument.signalUndoStackChanged, ops.OdtDocument.signalStepsInserted, - ops.OdtDocument.signalStepsRemoved]), FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT, filter, stepsTranslator; + var self = this, odfUtils, domUtils, cursors = {}, members = {}, eventNotifier = new core.EventNotifier([ops.OdtDocument.signalMemberAdded, ops.OdtDocument.signalMemberUpdated, ops.OdtDocument.signalMemberRemoved, ops.OdtDocument.signalCursorAdded, ops.OdtDocument.signalCursorRemoved, ops.OdtDocument.signalCursorMoved, ops.OdtDocument.signalParagraphChanged, ops.OdtDocument.signalParagraphStyleModified, ops.OdtDocument.signalCommonStyleCreated, ops.OdtDocument.signalCommonStyleDeleted, ops.OdtDocument.signalTableAdded, + ops.OdtDocument.signalOperationExecuted, ops.OdtDocument.signalUndoStackChanged, ops.OdtDocument.signalStepsInserted, ops.OdtDocument.signalStepsRemoved]), FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT, filter, stepsTranslator, lastEditingOp, unsupportedMetadataRemoved = false; function getRootNode() { var element = odfCanvas.odfContainer().getContentElement(), localName = element && element.localName; runtime.assert(localName === "text", "Unsupported content element type '" + localName + "' for OdtDocument"); @@ -17276,6 +17700,20 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { } return null } + function handleOperationExecuted(op) { + var spec = op.spec(), memberId = spec.memberid, date = (new Date(spec.timestamp)).toISOString(), metadataManager = odfCanvas.odfContainer().getMetadataManager(), fullName; + if(op.isEdit) { + fullName = self.getMember(memberId).getProperties().fullName; + metadataManager.setMetadata({"dc:creator":fullName, "dc:date":date}, null); + if(!lastEditingOp) { + metadataManager.incrementEditingCycles(); + if(!unsupportedMetadataRemoved) { + metadataManager.setMetadata(null, ["meta:editing-duration", "meta:document-statistic"]) + } + } + lastEditingOp = op + } + } function upgradeWhitespaceToElement(textNode, offset) { runtime.assert(textNode.data[offset] === " ", "upgradeWhitespaceToElement: textNode.data[offset] should be a literal space"); var space = textNode.ownerDocument.createElementNS(odf.Namespaces.textns, "text:s"); @@ -17390,6 +17828,16 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { return odfCanvas }; this.getRootNode = getRootNode; + this.addMember = function(member) { + runtime.assert(members[member.getMemberId()] === undefined, "This member already exists"); + members[member.getMemberId()] = member + }; + this.getMember = function(memberId) { + return members.hasOwnProperty(memberId) ? members[memberId] : null + }; + this.removeMember = function(memberId) { + delete members[memberId] + }; this.getCursor = function(memberid) { return cursors[memberid] }; @@ -17420,21 +17868,6 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { } return false }; - this.getMetaData = function(metadataId) { - var node = odfCanvas.odfContainer().rootElement.firstChild; - while(node && node.localName !== "meta") { - node = node.nextSibling - } - node = node && node.firstChild; - while(node && node.localName !== metadataId) { - node = node.nextSibling - } - node = node && node.firstChild; - while(node && node.nodeType !== Node.TEXT_NODE) { - node = node.nextSibling - } - return node ? node.data : null - }; this.getFormatting = function() { return odfCanvas.getFormatting() }; @@ -17462,10 +17895,14 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { domUtils = new core.DomUtils; stepsTranslator = new ops.StepsTranslator(getRootNode, gui.SelectionMover.createPositionIterator, filter, 500); eventNotifier.subscribe(ops.OdtDocument.signalStepsInserted, stepsTranslator.handleStepsInserted); - eventNotifier.subscribe(ops.OdtDocument.signalStepsRemoved, stepsTranslator.handleStepsRemoved) + eventNotifier.subscribe(ops.OdtDocument.signalStepsRemoved, stepsTranslator.handleStepsRemoved); + eventNotifier.subscribe(ops.OdtDocument.signalOperationExecuted, handleOperationExecuted) } init() }; +ops.OdtDocument.signalMemberAdded = "member/added"; +ops.OdtDocument.signalMemberUpdated = "member/updated"; +ops.OdtDocument.signalMemberRemoved = "member/removed"; ops.OdtDocument.signalCursorAdded = "cursor/added"; ops.OdtDocument.signalCursorRemoved = "cursor/removed"; ops.OdtDocument.signalCursorMoved = "cursor/moved"; @@ -17518,15 +17955,11 @@ ops.OdtDocument.signalStepsRemoved = "steps/removed"; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.TrivialMemberModel"); runtime.loadClass("ops.TrivialOperationRouter"); runtime.loadClass("ops.OperationFactory"); runtime.loadClass("ops.OdtDocument"); ops.Session = function Session(odfCanvas) { - var self = this, operationFactory = new ops.OperationFactory, odtDocument = new ops.OdtDocument(odfCanvas), memberModel = new ops.TrivialMemberModel, operationRouter = null; - this.setMemberModel = function(uModel) { - memberModel = uModel - }; + var self = this, operationFactory = new ops.OperationFactory, odtDocument = new ops.OdtDocument(odfCanvas), operationRouter = null; this.setOperationFactory = function(opFactory) { operationFactory = opFactory; if(operationRouter) { @@ -17541,9 +17974,6 @@ ops.Session = function Session(odfCanvas) { }); opRouter.setOperationFactory(operationFactory) }; - this.getMemberModel = function() { - return memberModel - }; this.getOperationFactory = function() { return operationFactory }; @@ -17558,13 +17988,7 @@ ops.Session = function Session(odfCanvas) { if(err) { callback(err) }else { - memberModel.close(function(err) { - if(err) { - callback(err) - }else { - odtDocument.close(callback) - } - }) + odtDocument.close(callback) } }) }; @@ -17577,4 +18001,5 @@ ops.Session = function Session(odfCanvas) { init() }; var webodf_css = "@namespace draw url(urn:oasis:names:tc:opendocument:xmlns:drawing:1.0);\n@namespace fo url(urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0);\n@namespace office url(urn:oasis:names:tc:opendocument:xmlns:office:1.0);\n@namespace presentation url(urn:oasis:names:tc:opendocument:xmlns:presentation:1.0);\n@namespace style url(urn:oasis:names:tc:opendocument:xmlns:style:1.0);\n@namespace svg url(urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0);\n@namespace table url(urn:oasis:names:tc:opendocument:xmlns:table:1.0);\n@namespace text url(urn:oasis:names:tc:opendocument:xmlns:text:1.0);\n@namespace webodfhelper url(urn:webodf:names:helper);\n@namespace cursor url(urn:webodf:names:cursor);\n@namespace editinfo url(urn:webodf:names:editinfo);\n@namespace annotation url(urn:webodf:names:annotation);\n@namespace dc url(http://purl.org/dc/elements/1.1/);\n\noffice|document > *, office|document-content > * {\n display: none;\n}\noffice|body, office|document {\n display: inline-block;\n position: relative;\n}\n\ntext|p, text|h {\n display: block;\n padding: 0;\n margin: 0;\n line-height: normal;\n position: relative;\n min-height: 1.3em; /* prevent empty paragraphs and headings from collapsing if they are empty */\n}\n*[webodfhelper|containsparagraphanchor] {\n position: relative;\n}\ntext|s {\n white-space: pre;\n}\ntext|tab {\n display: inline;\n white-space: pre;\n}\ntext|tracked-changes {\n /*Consumers that do not support change tracking, should ignore changes.*/\n display: none;\n}\noffice|binary-data {\n display: none;\n}\noffice|text {\n display: block;\n text-align: left;\n overflow: visible;\n word-wrap: break-word;\n}\n\noffice|text::selection {\n /** Let's not draw selection highlight that overflows into the office|text\n * node when selecting content across several paragraphs\n */\n background: transparent;\n}\n\n.virtualSelections office|document *::selection {\n background: transparent;\n}\n.virtualSelections office|document *::-moz-selection {\n background: transparent;\n}\n\noffice|text * draw|text-box {\n/** only for text documents */\n display: block;\n border: 1px solid #d3d3d3;\n}\noffice|spreadsheet {\n display: block;\n border-collapse: collapse;\n empty-cells: show;\n font-family: sans-serif;\n font-size: 10pt;\n text-align: left;\n page-break-inside: avoid;\n overflow: hidden;\n}\noffice|presentation {\n display: inline-block;\n text-align: left;\n}\n#shadowContent {\n display: inline-block;\n text-align: left;\n}\ndraw|page {\n display: block;\n position: relative;\n overflow: hidden;\n}\npresentation|notes, presentation|footer-decl, presentation|date-time-decl {\n display: none;\n}\n@media print {\n draw|page {\n border: 1pt solid black;\n page-break-inside: avoid;\n }\n presentation|notes {\n /*TODO*/\n }\n}\noffice|spreadsheet text|p {\n border: 0px;\n padding: 1px;\n margin: 0px;\n}\noffice|spreadsheet table|table {\n margin: 3px;\n}\noffice|spreadsheet table|table:after {\n /* show sheet name the end of the sheet */\n /*content: attr(table|name);*/ /* gives parsing error in opera */\n}\noffice|spreadsheet table|table-row {\n counter-increment: row;\n}\noffice|spreadsheet table|table-row:before {\n width: 3em;\n background: #cccccc;\n border: 1px solid black;\n text-align: center;\n content: counter(row);\n display: table-cell;\n}\noffice|spreadsheet table|table-cell {\n border: 1px solid #cccccc;\n}\ntable|table {\n display: table;\n}\ndraw|frame table|table {\n width: 100%;\n height: 100%;\n background: white;\n}\ntable|table-header-rows {\n display: table-header-group;\n}\ntable|table-row {\n display: table-row;\n}\ntable|table-column {\n display: table-column;\n}\ntable|table-cell {\n width: 0.889in;\n display: table-cell;\n word-break: break-all; /* prevent long words from extending out the table cell */\n}\ndraw|frame {\n display: block;\n}\ndraw|image {\n display: block;\n width: 100%;\n height: 100%;\n top: 0px;\n left: 0px;\n background-repeat: no-repeat;\n background-size: 100% 100%;\n -moz-background-size: 100% 100%;\n}\n/* only show the first image in frame */\ndraw|frame > draw|image:nth-of-type(n+2) {\n display: none;\n}\ntext|list:before {\n display: none;\n content:\"\";\n}\ntext|list {\n counter-reset: list;\n}\ntext|list-item {\n display: block;\n}\ntext|number {\n display:none;\n}\n\ntext|a {\n color: blue;\n text-decoration: underline;\n cursor: pointer;\n}\ntext|note-citation {\n vertical-align: super;\n font-size: smaller;\n}\ntext|note-body {\n display: none;\n}\ntext|note:hover text|note-citation {\n background: #dddddd;\n}\ntext|note:hover text|note-body {\n display: block;\n left:1em;\n max-width: 80%;\n position: absolute;\n background: #ffffaa;\n}\nsvg|title, svg|desc {\n display: none;\n}\nvideo {\n width: 100%;\n height: 100%\n}\n\n/* below set up the cursor */\ncursor|cursor {\n display: inline;\n width: 0px;\n height: 1em;\n /* making the position relative enables the avatar to use\n the cursor as reference for its absolute position */\n position: relative;\n z-index: 1;\n}\ncursor|cursor > span {\n /* IMPORTANT: when changing these values ensure DEFAULT_CARET_TOP and DEFAULT_CARET_HEIGHT\n in Caret.js remain in sync */\n display: inline;\n position: absolute;\n top: 5%; /* push down the caret; 0px can do the job, 5% looks better, 10% is a bit over */\n height: 1em;\n border-left: 2px solid black;\n outline: none;\n}\n\ncursor|cursor > div {\n padding: 3px;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n border: none !important;\n border-radius: 5px;\n opacity: 0.3;\n}\n\ncursor|cursor > div > img {\n border-radius: 5px;\n}\n\ncursor|cursor > div.active {\n opacity: 0.8;\n}\n\ncursor|cursor > div:after {\n content: ' ';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 43%;\n}\n\n\n.editInfoMarker {\n position: absolute;\n width: 10px;\n height: 100%;\n left: -20px;\n opacity: 0.8;\n top: 0;\n border-radius: 5px;\n background-color: transparent;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n}\n.editInfoMarker:hover {\n box-shadow: 0px 0px 8px rgba(0, 0, 0, 1);\n}\n\n.editInfoHandle {\n position: absolute;\n background-color: black;\n padding: 5px;\n border-radius: 5px;\n opacity: 0.8;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n bottom: 100%;\n margin-bottom: 10px;\n z-index: 3;\n left: -25px;\n}\n.editInfoHandle:after {\n content: ' ';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 5px;\n}\n.editInfo {\n font-family: sans-serif;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n color: white;\n width: 100%;\n height: 12pt;\n}\n.editInfoColor {\n float: left;\n width: 10pt;\n height: 10pt;\n border: 1px solid white;\n}\n.editInfoAuthor {\n float: left;\n margin-left: 5pt;\n font-size: 10pt;\n text-align: left;\n height: 12pt;\n line-height: 12pt;\n}\n.editInfoTime {\n float: right;\n margin-left: 30pt;\n font-size: 8pt;\n font-style: italic;\n color: yellow;\n height: 12pt;\n line-height: 12pt;\n}\n\n.annotationWrapper {\n display: inline;\n position: relative;\n}\n\n.annotationRemoveButton:before {\n content: '\u00d7';\n color: white;\n padding: 5px;\n line-height: 1em;\n}\n\n.annotationRemoveButton {\n width: 20px;\n height: 20px;\n border-radius: 10px;\n background-color: black;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n position: absolute;\n top: -10px;\n left: -10px;\n z-index: 3;\n text-align: center;\n font-family: sans-serif;\n font-style: normal;\n font-weight: normal;\n text-decoration: none;\n font-size: 15px;\n}\n.annotationRemoveButton:hover {\n cursor: pointer;\n box-shadow: 0px 0px 5px rgba(0, 0, 0, 1);\n}\n\n.annotationNote {\n width: 4cm;\n position: absolute;\n display: inline;\n z-index: 10;\n}\n.annotationNote > office|annotation {\n display: block;\n text-align: left;\n}\n\n.annotationConnector {\n position: absolute;\n display: inline;\n z-index: 2;\n border-top: 1px dashed brown;\n}\n.annotationConnector.angular {\n -moz-transform-origin: left top;\n -webkit-transform-origin: left top;\n -ms-transform-origin: left top;\n transform-origin: left top;\n}\n.annotationConnector.horizontal {\n left: 0;\n}\n.annotationConnector.horizontal:before {\n content: '';\n display: inline;\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: brown transparent transparent transparent;\n top: -1px;\n left: -5px;\n}\n\noffice|annotation {\n width: 100%;\n height: 100%;\n display: none;\n background: rgb(198, 238, 184);\n background: -moz-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -webkit-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -o-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -ms-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: linear-gradient(180deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n box-shadow: 0 3px 4px -3px #ccc;\n}\n\noffice|annotation > dc|creator {\n display: block;\n font-size: 10pt;\n font-weight: normal;\n font-style: normal;\n font-family: sans-serif;\n color: white;\n background-color: brown;\n padding: 4px;\n}\noffice|annotation > dc|date {\n display: block;\n font-size: 10pt;\n font-weight: normal;\n font-style: normal;\n font-family: sans-serif;\n border: 4px solid transparent;\n}\noffice|annotation > text|list {\n display: block;\n padding: 5px;\n}\n\n/* This is very temporary CSS. This must go once\n * we start bundling webodf-default ODF styles for annotations.\n */\noffice|annotation text|p {\n font-size: 10pt;\n color: black;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n font-family: sans-serif;\n}\n\ndc|*::selection {\n background: transparent;\n}\ndc|*::-moz-selection {\n background: transparent;\n}\n\n#annotationsPane {\n background-color: #EAEAEA;\n width: 4cm;\n height: 100%;\n display: none;\n position: absolute;\n outline: 1px solid #ccc;\n}\n\n.annotationHighlight {\n background-color: yellow;\n position: relative;\n}\n\n.selectionOverlay {\n position: absolute;\n z-index: 15;\n opacity: 0.2;\n pointer-events: none;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n}\n\n#imageSelector {\n display: none;\n position: absolute;\n border-style: solid;\n border-color: black;\n}\n\n#imageSelector > div {\n width: 5px;\n height: 5px;\n display: block;\n position: absolute;\n border: 1px solid black;\n background-color: #ffffff;\n}\n\n#imageSelector > .topLeft {\n top: -4px;\n left: -4px;\n}\n\n#imageSelector > .topRight {\n top: -4px;\n right: -4px;\n}\n\n#imageSelector > .bottomRight {\n right: -4px;\n bottom: -4px;\n}\n\n#imageSelector > .bottomLeft {\n bottom: -4px;\n left: -4px;\n}\n\n#imageSelector > .topMiddle {\n top: -4px;\n left: 50%;\n margin-left: -2.5px; /* half of the width defined in #imageSelector > div */\n}\n\n#imageSelector > .rightMiddle {\n top: 50%;\n right: -4px;\n margin-top: -2.5px; /* half of the height defined in #imageSelector > div */\n}\n\n#imageSelector > .bottomMiddle {\n bottom: -4px;\n left: 50%;\n margin-left: -2.5px; /* half of the width defined in #imageSelector > div */\n}\n\n#imageSelector > .leftMiddle {\n top: 50%;\n left: -4px;\n margin-top: -2.5px; /* half of the height defined in #imageSelector > div */\n}\n"; +var webodf_version = "0.4.2-1451-gc9cf878"; diff --git a/js/3rdparty/webodf/webodf.js b/js/3rdparty/webodf/webodf.js index ec4dc8f5..306f4d94 100644 --- a/js/3rdparty/webodf/webodf.js +++ b/js/3rdparty/webodf/webodf.js @@ -39,79 +39,79 @@ */ var core={},gui={},xmldom={},odf={},ops={}; // Input 1 -function Runtime(){}Runtime.ByteArray=function(h){};Runtime.prototype.getVariable=function(h){};Runtime.prototype.toJson=function(h){};Runtime.prototype.fromJson=function(h){};Runtime.ByteArray.prototype.slice=function(h,m){};Runtime.ByteArray.prototype.length=0;Runtime.prototype.byteArrayFromArray=function(h){};Runtime.prototype.byteArrayFromString=function(h,m){};Runtime.prototype.byteArrayToString=function(h,m){};Runtime.prototype.concatByteArrays=function(h,m){}; -Runtime.prototype.read=function(h,m,e,p){};Runtime.prototype.readFile=function(h,m,e){};Runtime.prototype.readFileSync=function(h,m){};Runtime.prototype.loadXML=function(h,m){};Runtime.prototype.writeFile=function(h,m,e){};Runtime.prototype.isFile=function(h,m){};Runtime.prototype.getFileSize=function(h,m){};Runtime.prototype.deleteFile=function(h,m){};Runtime.prototype.log=function(h,m){};Runtime.prototype.setTimeout=function(h,m){};Runtime.prototype.clearTimeout=function(h){}; -Runtime.prototype.libraryPaths=function(){};Runtime.prototype.type=function(){};Runtime.prototype.getDOMImplementation=function(){};Runtime.prototype.parseXML=function(h){};Runtime.prototype.getWindow=function(){};Runtime.prototype.assert=function(h,m,e){};var IS_COMPILED_CODE=!0; -Runtime.byteArrayToString=function(h,m){function e(e){var a="",d,f=e.length;for(d=0;db?a+=String.fromCharCode(b):(d+=1,k=e[d],194<=b&&224>b?a+=String.fromCharCode((b&31)<<6|k&63):(d+=1,c=e[d],224<=b&&240>b?a+=String.fromCharCode((b&15)<<12|(k&63)<<6|c&63):(d+=1,g=e[d],240<=b&&245>b&&(b=(b&7)<<18|(k&63)<<12|(c&63)<<6|g&63,b-=65536,a+=String.fromCharCode((b>>10)+55296,(b&1023)+56320))))); -return a}var l;"utf8"===m?l=p(h):("binary"!==m&&this.log("Unsupported encoding: "+m),l=e(h));return l};Runtime.getVariable=function(h){try{return eval(h)}catch(m){}};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 m(a,d){var f,b,k;void 0!==d?k=a:d=a;h?(b=h.ownerDocument,k&&(f=b.createElement("span"),f.className=k,f.appendChild(b.createTextNode(k)),h.appendChild(f),h.appendChild(b.createTextNode(" "))),f=b.createElement("span"),0c?(b[g]=c,g+=1):2048>c?(b[g]=192|c>>>6,b[g+1]=128|c&63,g+=2):(b[g]=224|c>>>12&15,b[g+1]=128|c>>>6&63,b[g+2]=128|c&63,g+=3)}else for("binary"!== -d&&p.log("unknown encoding: "+d),f=a.length,b=new p.ByteArray(f),k=0;kb.status||0===b.status?f(null):f("Status "+String(b.status)+": "+b.responseText|| -b.statusText):f("File "+a+" is empty."))};d=d.buffer&&!b.sendAsBinary?d.buffer:p.byteArrayToString(d,"binary");try{b.sendAsBinary?b.sendAsBinary(d):b.send(d)}catch(k){p.log("HUH? "+k+" "+d),f(k.message)}};this.deleteFile=function(a,d){delete l[a];var f=new XMLHttpRequest;f.open("DELETE",a,!0);f.onreadystatechange=function(){4===f.readyState&&(200>f.status&&300<=f.status?d(f.responseText):d(null))};f.send(null)};this.loadXML=function(a,d){var f=new XMLHttpRequest;f.open("GET",a,!0);f.overrideMimeType&& -f.overrideMimeType("text/xml");f.onreadystatechange=function(){4===f.readyState&&(0!==f.status||f.responseText?200===f.status||0===f.status?d(null,f.responseXML):d(f.responseText):d("File "+a+" is empty."))};try{f.send(null)}catch(b){d(b.message)}};this.isFile=function(a,d){p.getFileSize(a,function(a){d(-1!==a)})};this.getFileSize=function(a,d){var f=new XMLHttpRequest;f.open("HEAD",a,!0);f.onreadystatechange=function(){if(4===f.readyState){var b=f.getResponseHeader("Content-Length");b?d(parseInt(b, -10)):e(a,"binary",function(b,c){b?d(-1):d(c.length)})}};f.send(null)};this.log=m;this.assert=function(a,d,f){if(!a)throw m("alert","ASSERTION FAILED:\n"+d),f&&f(),d;};this.setTimeout=function(a,d){return setTimeout(function(){a()},d)};this.clearTimeout=function(a){clearTimeout(a)};this.libraryPaths=function(){return["lib"]};this.setCurrentDirectory=function(){};this.type=function(){return"BrowserRuntime"};this.getDOMImplementation=function(){return window.document.implementation};this.parseXML=function(a){return(new DOMParser).parseFromString(a, -"text/xml")};this.exit=function(a){m("Calling exit with code "+String(a)+", but exit() is not implemented.")};this.getWindow=function(){return window}} -function NodeJSRuntime(){function h(d,a,b){d=p.resolve(l,d);"binary"!==a?e.readFile(d,a,b):e.readFile(d,null,b)}var m=this,e=require("fs"),p=require("path"),l="",q,a;this.ByteArray=function(d){return new Buffer(d)};this.byteArrayFromArray=function(d){var a=new Buffer(d.length),b,k=d.length;for(b=0;b").implementation} -function RhinoRuntime(){function h(a,d){var f;void 0!==d?f=a:d=a;"alert"===f&&print("\n!!!!! ALERT !!!!!");print(d);"alert"===f&&print("!!!!! ALERT !!!!!")}var m=this,e=Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance(),p,l,q="";e.setValidating(!1);e.setNamespaceAware(!0);e.setExpandEntityReferences(!1);e.setSchema(null);l=Packages.org.xml.sax.EntityResolver({resolveEntity:function(a,d){var f=new Packages.java.io.FileReader(d);return new Packages.org.xml.sax.InputSource(f)}});p=e.newDocumentBuilder(); -p.setEntityResolver(l);this.ByteArray=function(a){return[a]};this.byteArrayFromArray=function(a){return a};this.byteArrayFromString=function(a,d){var f=[],b,k=a.length;for(b=0;bk?d.push(k):(p+=1,a=c[p],194<=k&&224>k?d.push((k&31)<<6|a&63):(p+=1,e=c[p],224<=k&&240>k?d.push((k&15)<<12|(a&63)<<6|e&63):(p+=1,h=c[p],240<=k&&245>k&&(k=(k&7)<<18|(a&63)<<12|(e&63)<<6|h&63,k-=65536,d.push((k>>10)+55296,(k&1023)+56320))))),1E3===d.length&&(b+=String.fromCharCode.apply(null, +d),d.length=0);return b+String.fromCharCode.apply(null,d)}var f;"utf8"===l?f=m(g):("binary"!==l&&this.log("Unsupported encoding: "+l),f=c(g));return f};Runtime.getVariable=function(g){try{return eval(g)}catch(l){}};Runtime.toJson=function(g){return JSON.stringify(g)};Runtime.fromJson=function(g){return JSON.parse(g)};Runtime.getFunctionName=function(g){return void 0===g.name?(g=/function\s+(\w+)/.exec(g))&&g[1]:g.name}; +function BrowserRuntime(g){function l(b,r){var d,k,a;void 0!==r?a=b:r=b;g?(k=g.ownerDocument,a&&(d=k.createElement("span"),d.className=a,d.appendChild(k.createTextNode(a)),g.appendChild(d),g.appendChild(k.createTextNode(" "))),d=k.createElement("span"),0e?(k[h]=e,h+=1):2048>e?(k[h]=192|e>>>6,k[h+1]=128|e&63,h+=2):(k[h]=224|e>>>12&15,k[h+1]=128|e>>>6&63,k[h+2]=128|e&63,h+=3)}else for("binary"!==c&&n.log("unknown encoding: "+c),d=b.length,k=new Uint8Array(new ArrayBuffer(d)),a=0;ak.status||0===k.status?d(null):d("Status "+String(k.status)+": "+k.responseText||k.statusText):d("File "+c+" is empty."))};a=r.buffer&&!k.sendAsBinary?r.buffer:n.byteArrayToString(r,"binary");try{k.sendAsBinary?k.sendAsBinary(a):k.send(a)}catch(e){n.log("HUH? "+e+" "+r),d(e.message)}};this.deleteFile=function(c,r){delete b[c];var d=new XMLHttpRequest;d.open("DELETE",c,!0);d.onreadystatechange=function(){4===d.readyState&& +(200>d.status&&300<=d.status?r(d.responseText):r(null))};d.send(null)};this.loadXML=function(b,c){var d=new XMLHttpRequest;d.open("GET",b,!0);d.overrideMimeType&&d.overrideMimeType("text/xml");d.onreadystatechange=function(){4===d.readyState&&(0!==d.status||d.responseText?200===d.status||0===d.status?c(null,d.responseXML):c(d.responseText,null):c("File "+b+" is empty.",null))};try{d.send(null)}catch(k){c(k.message,null)}};this.isFile=function(b,c){n.getFileSize(b,function(d){c(-1!==d)})};this.getFileSize= +function(c,r){if(b.hasOwnProperty(c)&&"string"!==typeof b[c])r(b[c].length);else{var d=new XMLHttpRequest;d.open("HEAD",c,!0);d.onreadystatechange=function(){if(4===d.readyState){var b=d.getResponseHeader("Content-Length");b?r(parseInt(b,10)):f(c,"binary",function(a,e){a?r(-1):r(e.length)})}};d.send(null)}};this.log=l;this.assert=function(b,c,d){if(!b)throw l("alert","ASSERTION FAILED:\n"+c),d&&d(),c;};this.setTimeout=function(b,c){return setTimeout(function(){b()},c)};this.clearTimeout=function(b){clearTimeout(b)}; +this.libraryPaths=function(){return["lib"]};this.setCurrentDirectory=function(){};this.type=function(){return"BrowserRuntime"};this.getDOMImplementation=function(){return window.document.implementation};this.parseXML=function(b){return(new DOMParser).parseFromString(b,"text/xml")};this.exit=function(b){l("Calling exit with code "+String(b)+", but exit() is not implemented.")};this.getWindow=function(){return window}} +function NodeJSRuntime(){function g(b){var d=b.length,k,a=new Uint8Array(new ArrayBuffer(d));for(k=0;k").implementation} +function RhinoRuntime(){function g(b,c){var f;void 0!==c?f=b:c=b;"alert"===f&&print("\n!!!!! ALERT !!!!!");print(c);"alert"===f&&print("!!!!! ALERT !!!!!")}var l=this,c=Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance(),m,f,n="";c.setValidating(!1);c.setNamespaceAware(!0);c.setExpandEntityReferences(!1);c.setSchema(null);f=Packages.org.xml.sax.EntityResolver({resolveEntity:function(b,c){var f=new Packages.java.io.FileReader(c);return new Packages.org.xml.sax.InputSource(f)}});m=c.newDocumentBuilder(); +m.setEntityResolver(f);this.byteArrayFromString=function(b,c){var f=[],d,k=b.length;for(d=0;d>>18],b+=r[g>>>12&63],b+=r[g>>>6&63],b+=r[g&63];a===d+1?(g=c[a]<<4,b+=r[g>>>6],b+=r[g&63],b+="=="):a===d&&(g=c[a]<<10|c[a+1]<<2,b+=r[g>>>12],b+=r[g>>>6&63],b+=r[g&63],b+="=");return b}function e(c){c=c.replace(/[^A-Za-z0-9+\/]+/g,"");var g=[],b=c.length%4,a,d=c.length,n;for(a=0;a>16,n>>8&255,n&255);g.length-=[0,0,2,1][b];return g}function p(c){var g=[],b,a=c.length,d;for(b=0;bd?g.push(d):2048>d?g.push(192|d>>>6,128|d&63):g.push(224|d>>>12&15,128|d>>>6&63,128|d&63);return g}function l(c){var g=[],b,a=c.length,d,n,f;for(b=0;bd?g.push(d):(b+=1,n=c[b],224>d?g.push((d&31)<<6|n&63):(b+=1,f=c[b],g.push((d&15)<<12|(n&63)<<6|f&63)));return g}function q(c){return m(h(c))} -function a(c){return String.fromCharCode.apply(String,e(c))}function d(c){return l(h(c))}function f(c){c=l(c);for(var g="",b=0;bg?a+=String.fromCharCode(g):(f+=1,d=c.charCodeAt(f)&255,224>g?a+=String.fromCharCode((g&31)<<6|d&63):(f+=1,n=c.charCodeAt(f)&255,a+=String.fromCharCode((g&15)<<12|(d&63)<<6|n&63)));return a}function k(c,g){function a(){var k= -f+d;k>c.length&&(k=c.length);n+=b(c,f,k);f=k;k=f===c.length;g(n,k)&&!k&&runtime.setTimeout(a,0)}var d=1E5,n="",f=0;c.length>>18],h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[e>>>12&63],h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[e>>>6&63],h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[e& +63];b===d+1?(e=a[b]<<4,h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[e>>>6],h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[e&63],h+="=="):b===d&&(e=a[b]<<10|a[b+1]<<2,h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[e>>>12],h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[e>>>6&63],h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[e&63],h+="=");return h}function c(a){a=a.replace(/[^A-Za-z0-9+\/]+/g, +"");var e=a.length,h=new Uint8Array(new ArrayBuffer(3*e)),b=a.length%4,d=0,c,k;for(c=0;c>16,h[d+1]=k>>8&255,h[d+2]=k&255,d+=3;e=3*e-[0,0,2,1][b];return h.subarray(0,e)}function m(a){var e,h,b=a.length,d=0,c=new Uint8Array(new ArrayBuffer(3*b));for(e=0;eh?c[d++]=h:(2048>h?c[d++]=192|h>>>6:(c[d++]=224|h>>>12&15,c[d++]=128|h>>>6&63),c[d++]=128|h&63);return c.subarray(0, +d)}function f(a){var e,h,b,d,c=a.length,k=new Uint8Array(new ArrayBuffer(c)),q=0;for(e=0;eh?k[q++]=h:(e+=1,b=a[e],224>h?k[q++]=(h&31)<<6|b&63:(e+=1,d=a[e],k[q++]=(h&15)<<12|(b&63)<<6|d&63));return k.subarray(0,q)}function n(a){return l(g(a))}function b(a){return String.fromCharCode.apply(String,c(a))}function p(a){return f(g(a))}function r(a){a=f(a);for(var e="",h=0;he?k+=String.fromCharCode(e):(c+=1,b=a.charCodeAt(c)&255,224>e?k+=String.fromCharCode((e&31)<<6|b&63):(c+=1,d=a.charCodeAt(c)&255,k+=String.fromCharCode((e&15)<<12|(b&63)<<6|d&63)));return k}function k(a,e){function h(){var k=c+1E5;k>a.length&&(k=a.length);b+=d(a,c,k);c=k;k=c===a.length;e(b,k)&&!k&&runtime.setTimeout(h,0)}var b="",c=0;1E5>a.length?e(d(a,0,a.length),!0):("string"!==typeof a&&(a=a.slice()),h())}function a(a){return m(g(a))}function e(a){return String.fromCharCode.apply(String, +m(a))}function h(a){return String.fromCharCode.apply(String,m(g(a)))}var q=function(a){var e={},h,b;h=0;for(b=a.length;h>>8):(ea(g&255),ea(g>>>8))},pa=function(){t=(t<<5^n[z+3-1]&255)&8191;s=y[32768+t];y[z&32767]=s;y[32768+t]=z},aa=function(c,g){w>16-g?(x|=c<>16-w,w+=g-16):(x|=c<c;c++)n[c]=n[c+32768];M-=32768;z-=32768;v-=32768;for(c=0;8192>c;c++)g=y[32768+c],y[32768+c]=32768<=g?g-32768:0;for(c=0;32768>c;c++)g=y[c],y[c]=32768<=g?g-32768:0;b+=32768}H||(c=Aa(n,z+R,b),0>=c?H=!0:R+=c)},xa=function(c){var g=Z,b=z,a,d=I,f=32506=ka&&(g>>=2);do if(a=c,n[a+d]===r&&n[a+d-1]===e&&n[a]===n[b]&&n[++a]===n[b+1]){b+= -2;a++;do++b;while(n[b]===n[++a]&&n[++b]===n[++a]&&n[++b]===n[++a]&&n[++b]===n[++a]&&n[++b]===n[++a]&&n[++b]===n[++a]&&n[++b]===n[++a]&&n[++b]===n[++a]&&bd){M=c;d=a;if(258<=a)break;e=n[b+d-1];r=n[b+d]}c=y[c&32767]}while(c>f&&0!==--g);return d},qa=function(c,g){u[U++]=g;0===c?ba[g].fc++:(c--,ba[T[g]+256+1].fc++,ga[(256>c?P[c]:P[256+(c>>7)])&255].fc++,r[J++]=c,fa|=W);W<<=1;0===(U&7)&&(F[ia++]=fa,fa=0,W=1);if(2d;d++)b+=ga[d].fc* -(5+ma[d]);b>>=3;if(J>=1,b<<=1;while(0<--g);return b>>1},Ea=function(c,g){var b=[];b.length=16;var a=0,d;for(d=1;15>=d;d++)a=a+Q[d-1]<<1,b[d]=a;for(a=0;a<=g;a++)d=c[a].dl,0!==d&&(c[a].fc=Da(b[d]++,d))},Ca=function(c){var g=c.dyn_tree,b=c.static_tree,a=c.elems,d,n=-1, -f=a;ca=0;oa=573;for(d=0;dca;)d=O[++ca]=2>n?++n:0,g[d].fc=1,da[d]=0,ha--,null!==b&&(B-=b[d].dl);c.max_code=n;for(d=ca>>1;1<=d;d--)ya(g,d);do d=O[1],O[1]=O[ca--],ya(g,1),b=O[1],O[--oa]=d,O[--oa]=b,g[f].fc=g[d].fc+g[b].fc,da[f]=da[d]>da[b]+1?da[d]:da[b]+1,g[d].dl=g[b].dl=f,O[1]=f++,ya(g,1);while(2<=ca);O[--oa]=O[1];f=c.dyn_tree;d=c.extra_bits;var a=c.extra_base,b=c.max_code,k=c.max_length,e=c.static_tree,r,s,h,C,l=0;for(s=0;15>=s;s++)Q[s]=0;f[O[oa]].dl= -0;for(c=oa+1;573>c;c++)r=O[c],s=f[f[r].dl].dl+1,s>k&&(s=k,l++),f[r].dl=s,r>b||(Q[s]++,h=0,r>=a&&(h=d[r-a]),C=f[r].fc,ha+=C*(s+h),null!==e&&(B+=C*(e[r].dl+h)));if(0!==l){do{for(s=k-1;0===Q[s];)s--;Q[s]--;Q[s+1]+=2;Q[k]--;l-=2}while(0b||(f[d].dl!==s&&(ha+=(s-f[d].dl)*f[d].fc,f[d].fc=s),r--)}Ea(g,n)},Fa=function(c,g){var b,a=-1,d,n=c[0].dl,f=0,k=7,e=4;0===n&&(k=138,e=3);c[g+1].dl=65535;for(b=0;b<=g;b++)d=n,n=c[b+1].dl,++f=f?V[17].fc++:V[18].fc++,f=0,a=d,0===n?(k=138,e=3):d===n?(k=6,e=3):(k=7,e=4))},Ga=function(){8b?P[b]:P[256+(b>>7)])&255,K(k,g),e=ma[k],0!==e&&(b-=$[k],aa(b,e))),f>>=1;while(a=f?(K(17,V),aa(f-3,3)):(K(18,V),aa(f-11,7));f=0;a=d;0===n?(k=138,e=3):d===n?(k=6,e=3):(k=7,e=4)}},Ja=function(){var c;for(c=0;286>c;c++)ba[c].fc=0;for(c=0;30>c;c++)ga[c].fc=0;for(c=0;19>c;c++)V[c].fc=0;ba[256].fc=1;fa=U=J=ia=ha=B=0;W=1},Ba=function(c){var g,b,a,d;d=z-v;F[ia]=fa;Ca(N);Ca(L);Fa(ba,N.max_code);Fa(ga,L.max_code);Ca(G);for(a=18;3<=a&&0===V[va[a]].dl;a--); -ha+=3*(a+1)+14;g=ha+3+7>>3;b=B+3+7>>3;b<=g&&(g=b);if(d+4<=g&&0<=v)for(aa(0+c,3),Ga(),X(d),X(~d),a=0;aa.len&&(e=a.len);for(r=0;rk-c&&(e=k-c);for(r=0;rl;l++)for(ra[l]= -h,r=0;r<1<l;l++)for($[l]=h,r=0;r<1<>=7;30>l;l++)for($[l]=h<<7,r=0;r<1<=r;r++)Q[r]=0;for(r=0;143>=r;)S[r++].dl=8,Q[8]++;for(;255>=r;)S[r++].dl=9,Q[9]++;for(;279>=r;)S[r++].dl=7,Q[7]++;for(;287>=r;)S[r++].dl=8,Q[8]++;Ea(S,287);for(r=0;30>r;r++)Y[r].dl=5,Y[r].fc=Da(r,5);Ja()}for(r=0;8192>r;r++)y[32768+r]=0;ja=wa[E].max_lazy;ka=wa[E].good_length;Z=wa[E].max_chain;v=z=0;R=Aa(n,0,65536);if(0>=R)H=!0, -R=0;else{for(H=!1;262>R&&!H;)ua();for(r=t=0;2>r;r++)t=(t<<5^n[r]&255)&8191}a=null;c=k=0;3>=E?(I=2,C=0):(C=2,A=0);g=!1}f=!0;if(0===R)return g=!0,0}r=Ka(b,d,e);if(r===e)return e;if(g)return r;if(3>=E)for(;0!==R&&null===a;){pa();0!==s&&32506>=z-s&&(C=xa(s),C>R&&(C=R));if(3<=C)if(l=qa(z-M,C-3),R-=C,C<=ja){C--;do z++,pa();while(0!==--C);z++}else z+=C,C=0,t=n[z]&255,t=(t<<5^n[z+1]&255)&8191;else l=qa(0,n[z]&255),R--,z++;l&&(Ba(0),v=z);for(;262>R&&!H;)ua()}else for(;0!==R&&null===a;){pa();I=C;D=M;C=2;0!== -s&&I=z-s&&(C=xa(s),C>R&&(C=R),3===C&&4096R&&!H;)ua()}0===R&&(0!==A&&qa(0,n[z-1]&255),Ba(1),g=!0);return r+Ka(b,r+d,e-r)};this.deflate=function(c,g){var k,e;sa=c;la=0;"undefined"===String(typeof g)&&(g=6);(k=g)?1>k?k=1:9k;k++)ba[k]=new h;ga=[];ga.length=61;for(k=0;61>k;k++)ga[k]=new h;S=[];S.length=288;for(k=0;288>k;k++)S[k]=new h;Y=[];Y.length=30;for(k=0;30>k;k++)Y[k]=new h;V=[];V.length=39;for(k=0;39>k;k++)V[k]=new h;N=new m;L=new m;G=new m;Q=[];Q.length=16;O=[];O.length=573;da=[];da.length=573;T=[];T.length=256;P=[];P.length=512;ra=[];ra.length=29;$=[];$.length=30;F=[];F.length=1024}var s=Array(1024),C=[],p=[];for(k=La(s,0,s.length);0>>8):(da(e&255),da(e>>>8))},qa=function(){t=(t<<5^h[z+3-1]&255)&8191;s=x[32768+t];x[z&32767]=s;x[32768+t]=z},aa=function(a,e){y>16-e?(v|=a<>16-y,y+=e-16):(v|=a<a;a++)h[a]=h[a+32768];K-=32768;z-=32768;w-=32768;for(a=0;8192>a;a++)e=x[32768+a],x[32768+a]=32768<=e?e-32768:0;for(a=0;32768>a;a++)e=x[a],x[a]=32768<=e?e-32768:0;b+=32768}F||(a=Aa(h,z+Q,b),0>=a?F=!0:Q+=a)},ya=function(a){var e=$,b=z,d,c=M,k=32506=ma&&(e>>=2);do if(d=a,h[d+c]===s&&h[d+c-1]===f&&h[d]===h[b]&&h[++d]===h[b+1]){b+= +2;d++;do++b;while(h[b]===h[++d]&&h[++b]===h[++d]&&h[++b]===h[++d]&&h[++b]===h[++d]&&h[++b]===h[++d]&&h[++b]===h[++d]&&h[++b]===h[++d]&&h[++b]===h[++d]&&bc){K=a;c=d;if(258<=d)break;f=h[b+c-1];s=h[b+c]}a=x[a&32767]}while(a>k&&0!==--e);return c},ra=function(a,e){u[U++]=e;0===a?ba[e].fc++:(a--,ba[T[e]+256+1].fc++,ga[(256>a?P[a]:P[256+(a>>7)])&255].fc++,q[H++]=a,fa|=W);W<<=1;0===(U&7)&&(E[la++]=fa,fa=0,W=1);if(2d;d++)h+=ga[d].fc* +(5+oa[d]);h>>=3;if(H>=1,h<<=1;while(0<--e);return h>>1},Ea=function(a,e){var h=[];h.length=16;var b=0,d;for(d=1;15>=d;d++)b=b+N[d-1]<<1,h[d]=b;for(b=0;b<=e;b++)d=a[b].dl,0!==d&&(a[b].fc=Ba(h[d]++,d))},Da=function(a){var e=a.dyn_tree,h=a.static_tree,b=a.elems,d,c=-1, +k=b;Z=0;ka=573;for(d=0;dZ;)d=O[++Z]=2>c?++c:0,e[d].fc=1,ca[d]=0,ja--,null!==h&&(C-=h[d].dl);a.max_code=c;for(d=Z>>1;1<=d;d--)xa(e,d);do d=O[1],O[1]=O[Z--],xa(e,1),h=O[1],O[--ka]=d,O[--ka]=h,e[k].fc=e[d].fc+e[h].fc,ca[k]=ca[d]>ca[h]+1?ca[d]:ca[h]+1,e[d].dl=e[h].dl=k,O[1]=k++,xa(e,1);while(2<=Z);O[--ka]=O[1];k=a.dyn_tree;d=a.extra_bits;var b=a.extra_base,h=a.max_code,q=a.max_length,f=a.static_tree,s,g,l,p,B=0;for(g=0;15>=g;g++)N[g]=0;k[O[ka]].dl= +0;for(a=ka+1;573>a;a++)s=O[a],g=k[k[s].dl].dl+1,g>q&&(g=q,B++),k[s].dl=g,s>h||(N[g]++,l=0,s>=b&&(l=d[s-b]),p=k[s].fc,ja+=p*(g+l),null!==f&&(C+=p*(f[s].dl+l)));if(0!==B){do{for(g=q-1;0===N[g];)g--;N[g]--;N[g+1]+=2;N[q]--;B-=2}while(0h||(k[d].dl!==g&&(ja+=(g-k[d].dl)*k[d].fc,k[d].fc=g),s--)}Ea(e,c)},Fa=function(a,e){var h,b=-1,d,c=a[0].dl,k=0,q=7,f=4;0===c&&(q=138,f=3);a[e+1].dl=65535;for(h=0;h<=e;h++)d=c,c=a[h+1].dl,++k=k?V[17].fc++:V[18].fc++,k=0,b=d,0===c?(q=138,f=3):d===c?(q=6,f=3):(q=7,f=4))},Ga=function(){8h?P[h]:P[256+(h>>7)])&255,J(f,e),g=oa[f],0!==g&&(h-=ea[f],aa(h,g))),k>>=1;while(b=k?(J(17,V),aa(k-3,3)):(J(18,V),aa(k-11,7));k=0;b=d;0===c?(q=138,f=3):d===c?(q=6,f=3):(q=7,f=4)}},Ja=function(){var a;for(a=0;286>a;a++)ba[a].fc=0;for(a=0;30>a;a++)ga[a].fc=0;for(a=0;19>a;a++)V[a].fc=0;ba[256].fc=1;fa=U=H=la=ja=C=0;W=1},Ca=function(a){var e,b,d,c;c=z-w;E[la]=fa;Da(G);Da(I);Fa(ba,G.max_code);Fa(ga,I.max_code);Da(ha);for(d=18;3<=d&&0===V[va[d]].dl;d--); +ja+=3*(d+1)+14;e=ja+3+7>>3;b=C+3+7>>3;b<=e&&(e=b);if(c+4<=e&&0<=w)for(aa(0+a,3),Ga(),X(c),X(~c),d=0;db.len&&(f=b.len);for(g=0;gk-a&&(f=k-a);for(g=0;g +l;l++)for(L[l]=g,f=0;f<1<l;l++)for(ea[l]=g,f=0;f<1<>=7;30>l;l++)for(ea[l]=g<<7,f=0;f<1<=f;f++)N[f]=0;for(f=0;143>=f;)S[f++].dl=8,N[8]++;for(;255>=f;)S[f++].dl=9,N[9]++;for(;279>=f;)S[f++].dl=7,N[7]++;for(;287>=f;)S[f++].dl=8,N[8]++;Ea(S,287);for(f=0;30>f;f++)Y[f].dl=5,Y[f].fc=Ba(f,5);Ja()}for(f=0;8192>f;f++)x[32768+f]=0;ia=wa[R].max_lazy;ma=wa[R].good_length;$=wa[R].max_chain;w=z=0;Q=Aa(h,0,65536); +if(0>=Q)F=!0,Q=0;else{for(F=!1;262>Q&&!F;)ua();for(f=t=0;2>f;f++)t=(t<<5^h[f]&255)&8191}b=null;a=k=0;3>=R?(M=2,B=0):(B=2,A=0);e=!1}r=!0;if(0===Q)return e=!0,0}f=Ka(d,c,q);if(f===q)return q;if(e)return f;if(3>=R)for(;0!==Q&&null===b;){qa();0!==s&&32506>=z-s&&(B=ya(s),B>Q&&(B=Q));if(3<=B)if(l=ra(z-K,B-3),Q-=B,B<=ia){B--;do z++,qa();while(0!==--B);z++}else z+=B,B=0,t=h[z]&255,t=(t<<5^h[z+1]&255)&8191;else l=ra(0,h[z]&255),Q--,z++;l&&(Ca(0),w=z);for(;262>Q&&!F;)ua()}else for(;0!==Q&&null===b;){qa();M= +B;D=K;B=2;0!==s&&M=z-s&&(B=ya(s),B>Q&&(B=Q),3===B&&4096Q&&!F;)ua()}0===Q&&(0!==A&&ra(0,h[z-1]&255),Ca(1),e=!0);return f+Ka(d,f+c,q-f)};this.deflate=function(a,e){var c,k;sa=a;na=0;"undefined"===String(typeof e)&&(e=6);(c=e)?1>c?c=1:9c;c++)ba[c]=new g;ga=[];ga.length=61;for(c=0;61>c;c++)ga[c]=new g;S=[];S.length=288;for(c=0;288>c;c++)S[c]=new g;Y=[];Y.length=30;for(c=0;30>c;c++)Y[c]=new g;V=[];V.length=39;for(c=0;39>c;c++)V[c]=new g;G=new l;I=new l;ha=new l;N=[];N.length=16;O=[];O.length=573;ca=[];ca.length=573;T=[];T.length=256;P=[];P.length=512;L=[];L.length=29;ea=[];ea.length=30;E=[];E.length=1024}var s=Array(1024),B=[],m=[];for(c=La(s, +0,s.length);0>8&255])};this.appendUInt32LE=function(e){m.appendArray([e&255,e>>8&255,e>>16&255,e>>24&255])};this.appendString=function(m){e=runtime.concatByteArrays(e, -runtime.byteArrayFromString(m,h))};this.getLength=function(){return e.length};this.getByteArray=function(){return e}}; +core.ByteArrayWriter=function(g){function l(b){b>f-m&&(f=Math.max(2*f,m+b),b=new Uint8Array(new ArrayBuffer(f)),b.set(n),n=b)}var c=this,m=0,f=1024,n=new Uint8Array(new ArrayBuffer(f));this.appendByteArrayWriter=function(b){c.appendByteArray(b.getByteArray())};this.appendByteArray=function(b){var c=b.length;l(c);n.set(b,m);m+=c};this.appendArray=function(b){var c=b.length;l(c);n.set(b,m);m+=c};this.appendUInt16LE=function(b){c.appendArray([b&255,b>>8&255])};this.appendUInt32LE=function(b){c.appendArray([b& +255,b>>8&255,b>>16&255,b>>24&255])};this.appendString=function(b){c.appendByteArray(runtime.byteArrayFromString(b,g))};this.getLength=function(){return m};this.getByteArray=function(){var b=new Uint8Array(new ArrayBuffer(m));b.set(n.subarray(0,m));return b}}; // Input 6 -core.RawInflate=function(){var h,m,e=null,p,l,q,a,d,f,b,k,c,g,n,r,u,y,x=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],w=[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],v=[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],t=[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],s=[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],D=[16,17,18, -0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],A=function(){this.list=this.next=null},C=function(){this.n=this.b=this.e=0;this.t=null},I=function(c,g,b,a,d,n){this.BMAX=16;this.N_MAX=288;this.status=0;this.root=null;this.m=0;var f=Array(this.BMAX+1),k,e,r,s,h,l,m,p=Array(this.BMAX+1),q,M,x,u=new C,t=Array(this.BMAX);s=Array(this.N_MAX);var v,H=Array(this.BMAX+1),z,I,w;w=this.root=null;for(h=0;hh&&(n=h);for(z=1<(z-=f[l])){this.status=2;this.m=n;return}if(0>(z-=f[h]))this.status=2,this.m=n;else{f[h]+=z;H[1]=l=0;q=f;M=1;for(x=2;0<--h;)H[x++]=l+=q[M++];q=c;h=M=0;do 0!=(l=q[M++])&&(s[H[l]++]=h);while(++hv+p[1+s];){v+=p[1+s];s++;I=(I=r-v)>n?n:I;if((e=1<<(l=m-v))>c+1)for(e-=c+1,x=m;++lk&&v>v-p[s],t[s-1][l].e=u.e,t[s-1][l].b=u.b,t[s-1][l].n=u.n,t[s-1][l].t=u.t)}u.b=m-v;M>=g?u.e=99:q[M]q[M]?16:15,u.n=q[M++]): -(u.e=d[q[M]-b],u.n=a[q[M++]-b]);e=1<>v;l>=1)h^=l;for(h^=l;(h&(1<>=c;a-=c},R=function(a,f,e){var l,s,C;if(0==e)return 0;for(C=0;;){z(n);s=c.list[M(n)];for(l=s.e;16 -k;k++)p[D[k]]=0;n=7;k=new I(p,19,19,null,null,n);if(0!=k.status)return-1;c=k.root;n=k.m;l=C+m;for(f=e=0;fk)p[f++]=e=k;else if(16==k){z(2);k=3+M(2);H(2);if(f+k>l)return-1;for(;0l)return-1;for(;0L;L++)N[L]=8;for(;256>L;L++)N[L]=9;for(;280>L;L++)N[L]=7;for(;288>L;L++)N[L]=8;l=7;L=new I(N,288,257,w,v,l);if(0!=L.status){alert("HufBuild error: "+L.status);S=-1;break b}e=L.root;l=L.m;for(L=0;30>L;L++)N[L]=5;Z=5;L=new I(N,30,0,t,s,Z);if(1l&&(c=l);for(v=1<(v-=k[p])){this.status=2;this.m=c;return}if(0>(v-=k[l]))this.status=2,this.m=c;else{k[l]+=v;x[1]=p=0;n=k;w=1;for(u=2;0<--l;)x[u++]=p+=n[w++];n=a;l=w=0;do 0!=(p=n[w++])&&(s[x[p]++]=l);while(++lK+r[1+s];){K+=r[1+s];s++;F=(F=g-K)>c?c:F;if((f=1<<(p=m-K))>a+1)for(f-=a+1,u=m;++pq&&K>K-r[s],z[s-1][p].e=t.e,z[s-1][p].b=t.b,z[s-1][p].n=t.n,z[s-1][p].t=t.t)}t.b=m-K;w>=e?t.e=99:n[w]n[w]?16:15,t.n=n[w++]): +(t.e=d[n[w]-h],t.n=b[n[w++]-h]);f=1<>K;p>=1)l^=p;for(l^=p;(l&(1<>=a;b-=a},Q=function(b,c,f){var s,B,m;if(0==f)return 0;for(m=0;;){z(h);B=a.list[K(h)];for(s=B.e;16 +f;f++)r[D[f]]=0;h=7;f=new M(r,19,19,null,null,h);if(0!=f.status)return-1;a=f.root;h=f.m;l=B+m;for(k=g=0;kf)r[k++]=g=f;else if(16==f){z(2);f=3+K(2);F(2);if(k+f>l)return-1;for(;0l)return-1;for(;0I;I++)G[I]=8;for(;256>I;I++)G[I]=9;for(;280>I;I++)G[I]=7;for(;288>I;I++)G[I]=8;f=7;I=new M(G,288,257,y,w,f);if(0!=I.status){alert("HufBuild error: "+I.status);S=-1;break b}c=I.root;f=I.m;for(I=0;30>I;I++)G[I]=5;$=5;I=new M(G,30,0,t,s,$); +if(1h))throw runtime.log("alert","watchdog timeout"),"timeout!";if(0m))throw runtime.log("alert","watchdog loop overflow"),"loop overflow";}}; +core.LoopWatchDog=function(g,l){var c=Date.now(),m=0;this.check=function(){var f;if(g&&(f=Date.now(),f-c>g))throw runtime.log("alert","watchdog timeout"),"timeout!";if(0l))throw runtime.log("alert","watchdog loop overflow"),"loop overflow";}}; // Input 8 -core.Utils=function(){function h(m,e){e&&Array.isArray(e)?m=(m||[]).concat(e.map(function(e){return h({},e)})):e&&"object"===typeof e?(m=m||{},Object.keys(e).forEach(function(p){m[p]=h(m[p],e[p])})):m=e;return m}this.hashString=function(h){var e=0,p,l;p=0;for(l=h.length;p=a.compareBoundaryPoints(a.START_TO_START, -f)&&0<=a.compareBoundaryPoints(a.END_TO_END,f)};this.rangesIntersect=function(a,f){return 0>=a.compareBoundaryPoints(a.END_TO_START,f)&&0<=a.compareBoundaryPoints(a.START_TO_END,f)};this.getNodesInRange=function(a,f){var b=[],k,c,g=a.startContainer.ownerDocument.createTreeWalker(a.commonAncestorContainer,NodeFilter.SHOW_ALL,f,!1);for(k=g.currentNode=a.startContainer;k;){c=f(k);if(c===NodeFilter.FILTER_ACCEPT)b.push(k);else if(c===NodeFilter.FILTER_REJECT)break;k=k.parentNode}b.reverse();for(k=g.nextNode();k;)b.push(k), -k=g.nextNode();return b};this.normalizeTextNodes=function(a){a&&a.nextSibling&&(a=e(a,a.nextSibling));a&&a.previousSibling&&e(a.previousSibling,a)};this.rangeContainsNode=function(a,f){var b=f.ownerDocument.createRange(),k=f.nodeType===Node.TEXT_NODE?f.length:f.childNodes.length;b.setStart(a.startContainer,a.startOffset);b.setEnd(a.endContainer,a.endOffset);k=0===b.comparePoint(f,0)&&0===b.comparePoint(f,k);b.detach();return k};this.mergeIntoParent=m;this.removeUnwantedNodes=l;this.getElementsByTagNameNS= -function(a,f,b){return Array.prototype.slice.call(a.getElementsByTagNameNS(f,b))};this.rangeIntersectsNode=function(a,f){var b=f.nodeType===Node.TEXT_NODE?f.length:f.childNodes.length;return 0>=a.comparePoint(f,0)&&0<=a.comparePoint(f,b)};this.containsNode=function(a,f){return a===f||a.contains(f)};this.comparePoints=function(a,f,b,k){if(a===b)return k-f;var c=a.compareDocumentPosition(b);2===c?c=-1:4===c?c=1:10===c?(f=q(a,b),c=f=a.compareBoundaryPoints(Range.START_TO_START,e)&&0<=a.compareBoundaryPoints(Range.END_TO_END,e)}function l(a,e){return 0>=a.compareBoundaryPoints(Range.END_TO_START,e)&&0<= +a.compareBoundaryPoints(Range.START_TO_END,e)}function f(a,e){var h=null;a.nodeType===Node.TEXT_NODE&&(0===a.length?(a.parentNode.removeChild(a),e.nodeType===Node.TEXT_NODE&&(h=e)):(e.nodeType===Node.TEXT_NODE&&(a.appendData(e.data),e.parentNode.removeChild(e)),h=a));return h}function n(a){for(var e=a.parentNode;a.firstChild;)e.insertBefore(a.firstChild,a);e.removeChild(a);return e}function b(a,e){for(var h=a.parentNode,d=a.firstChild,c;d;)c=d.nextSibling,b(d,e),d=c;e(a)&&(h=n(a));return h}function p(a, +e){return a===e||Boolean(a.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_CONTAINED_BY)}function r(a,e){for(var h=0,b;a.parentNode!==e;)runtime.assert(null!==a.parentNode,"parent is null"),a=a.parentNode;for(b=e.firstChild;b!==a;)h+=1,b=b.nextSibling;return h}function d(a,e,h){Object.keys(e).forEach(function(b){var c=b.split(":"),k=c[1],f=h(c[0]),c=e[b];"object"===typeof c&&Object.keys(c).length?(b=a.getElementsByTagNameNS(f,k)[0]||a.ownerDocument.createElementNS(f,b),a.appendChild(b),d(b,c,h)): +f&&a.setAttributeNS(f,b,c)})}var k=null;this.splitBoundaries=function(a){var e=[],h,b;if(a.startContainer.nodeType===Node.TEXT_NODE||a.endContainer.nodeType===Node.TEXT_NODE){if(h=a.endContainer){h=a.endOffset;b=a.endContainer;if(h";return runtime.parseXML(e)}; -core.UnitTestRunner=function(){function h(f){a+=1;runtime.log("fail",f)}function m(a,b){var d;try{if(a.length!==b.length)return h("array of length "+a.length+" should be "+b.length+" long"),!1;for(d=0;d1/g?"-0":String(g),h(b+" should be "+a+". Was "+d+".")):h(b+" should be "+a+" (of type "+typeof a+"). Was "+g+" (of type "+typeof g+").")}var a=0,d;d=function(a,b){var d=Object.keys(a),c=Object.keys(b);d.sort();c.sort();return m(d,c)&&Object.keys(a).every(function(c){var d=a[c],k=b[c];return l(d,k)?!0:(h(d+" should be "+k+" for key "+c),!1)})};this.areNodesEqual=p;this.shouldBeNull=function(a,b){q(a,b,"null")}; -this.shouldBeNonNull=function(a,b){var d,c;try{c=eval(b)}catch(g){d=g}d?h(b+" should be non-null. Threw exception "+d):null!==c?runtime.log("pass",b+" is non-null."):h(b+" should be non-null. Was "+c)};this.shouldBe=q;this.countFailedTests=function(){return a}}; -core.UnitTester=function(){function h(e,h){return""+e+""}var m=0,e={};this.runTests=function(p,l,q){function a(c){if(0===c.length)e[d]=k,m+=f.countFailedTests(),l();else{g=c[0];var n=Runtime.getFunctionName(g);runtime.log("Running "+n);r=f.countFailedTests();b.setUp();g(function(){b.tearDown();k[n]=r===f.countFailedTests();a(c.slice(1))})}}var d=Runtime.getFunctionName(p),f=new core.UnitTestRunner,b=new p(f),k={},c,g,n,r,u="BrowserRuntime"=== -runtime.type();if(e.hasOwnProperty(d))runtime.log("Test "+d+" has already run.");else{u?runtime.log("Running "+h(d,'runSuite("'+d+'");')+": "+b.description()+""):runtime.log("Running "+d+": "+b.description);n=b.tests();for(c=0;cRunning "+h(p,'runTest("'+d+'","'+p+'")')+""):runtime.log("Running "+p),r=f.countFailedTests(),b.setUp(),g(),b.tearDown(),k[p]=r===f.countFailedTests()); -a(b.asyncTests())}};this.countFailedTests=function(){return m};this.results=function(){return e}}; +core.UnitTest.provideTestAreaDiv=function(){var g=runtime.getWindow().document,l=g.getElementById("testarea");runtime.assert(!l,'Unclean test environment, found a div with id "testarea".');l=g.createElement("div");l.setAttribute("id","testarea");g.body.appendChild(l);return l}; +core.UnitTest.cleanupTestAreaDiv=function(){var g=runtime.getWindow().document,l=g.getElementById("testarea");runtime.assert(!!l&&l.parentNode===g.body,'Test environment broken, found no div with id "testarea" below body.');g.body.removeChild(l)};core.UnitTest.createOdtDocument=function(g,l){var c="",c=c+"";return runtime.parseXML(c)}; +core.UnitTestRunner=function(){function g(c){b+=1;runtime.log("fail",c)}function l(b,d){var c;try{if(b.length!==d.length)return g("array of length "+b.length+" should be "+d.length+" long"),!1;for(c=0;c1/e?"-0":String(e),g(d+" should be "+b+". Was "+c+".")):g(d+" should be "+b+" (of type "+typeof b+"). Was "+e+" (of type "+typeof e+").")}var b=0,p;p=function(b,d){var c=Object.keys(b),a=Object.keys(d);c.sort();a.sort();return l(c,a)&&Object.keys(b).every(function(a){var h=b[a],c=d[a];return f(h,c)?!0:(g(h+" should be "+c+" for key "+a),!1)})};this.areNodesEqual=m;this.shouldBeNull=function(b,d){n(b,d,"null")}; +this.shouldBeNonNull=function(b,d){var c,a;try{a=eval(d)}catch(e){c=e}c?g(d+" should be non-null. Threw exception "+c):null!==a?runtime.log("pass",d+" is non-null."):g(d+" should be non-null. Was "+a)};this.shouldBe=n;this.countFailedTests=function(){return b}}; +core.UnitTester=function(){function g(c,f){return""+c+""}var l=0,c={};this.runTests=function(m,f,n){function b(a){if(0===a.length)c[p]=k,l+=r.countFailedTests(),f();else{e=a[0];var h=Runtime.getFunctionName(e);runtime.log("Running "+h);q=r.countFailedTests();d.setUp();e(function(){d.tearDown();k[h]=q===r.countFailedTests();b(a.slice(1))})}}var p=Runtime.getFunctionName(m)||"",r=new core.UnitTestRunner,d=new m(r),k={},a,e,h,q,u="BrowserRuntime"=== +runtime.type();if(c.hasOwnProperty(p))runtime.log("Test "+p+" has already run.");else{u?runtime.log("Running "+g(p,'runSuite("'+p+'");')+": "+d.description()+""):runtime.log("Running "+p+": "+d.description);h=d.tests();for(a=0;aRunning "+g(m,'runTest("'+p+'","'+m+'")')+""):runtime.log("Running "+m),q=r.countFailedTests(),d.setUp(),e(),d.tearDown(),k[m]=q===r.countFailedTests()); +b(d.asyncTests())}};this.countFailedTests=function(){return l};this.results=function(){return c}}; // Input 13 -core.PositionIterator=function(h,m,e,p){function l(){this.acceptNode=function(c){return c.nodeType===Node.TEXT_NODE&&0===c.length?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}function q(c){this.acceptNode=function(a){return a.nodeType===Node.TEXT_NODE&&0===a.length?NodeFilter.FILTER_REJECT:c.acceptNode(a)}}function a(){var c=b.currentNode.nodeType;k=c===Node.TEXT_NODE?b.currentNode.length-1:c===Node.ELEMENT_NODE?1:0}function d(){if(null===b.previousSibling()){if(!b.parentNode()||b.currentNode=== -h)return b.firstChild(),!1;k=0}else a();return!0}var f=this,b,k,c;this.nextPosition=function(){if(b.currentNode===h)return!1;if(0===k&&b.currentNode.nodeType===Node.ELEMENT_NODE)null===b.firstChild()&&(k=1);else if(b.currentNode.nodeType===Node.TEXT_NODE&&k+1 "+a.length),runtime.assert(0<=d,"Error in setPosition: "+d+" < 0"),d===a.length&&(k=void 0,b.nextSibling()?k=0:b.parentNode()&&(k=1),runtime.assert(void 0!==k,"Error in setPosition: position not valid.")),!0;e=c(a);for(l=a.parentNode;l&&l!==h&&e===NodeFilter.FILTER_ACCEPT;)e= -c(l),e!==NodeFilter.FILTER_ACCEPT&&(b.currentNode=l),l=l.parentNode;d "+b.length),runtime.assert(0<=h,"Error in setPosition: "+h+" < 0"),h===b.length&&(d.nextSibling()?k=0:d.parentNode()?k=1:runtime.assert(!1,"Error in setUnfilteredPosition: position not valid.")),!0;c=a(b);for(f=b.parentNode;f&&f!==g&&c===q;)c=a(f),c!==q&&(d.currentNode=f),f=f.parentNode;h>>8^n;return b^-1}function p(c){return new Date((c>>25&127)+1980,(c>>21&15)-1,c>>16&31,c>>11&15,c>>5&63,(c&31)<<1)}function l(c){var a=c.getFullYear();return 1980>a?0:a-1980<< -25|c.getMonth()+1<<21|c.getDate()<<16|c.getHours()<<11|c.getMinutes()<<5|c.getSeconds()>>1}function q(c,a){var b,g,d,n,f,k,e,h=this;this.load=function(a){if(void 0!==h.data)a(null,h.data);else{var b=f+34+g+d+256;b+e>r&&(b=r-e);runtime.read(c,e,b,function(b,g){if(b||null===g)a(b,g);else a:{var d=g,e=new core.ByteArray(d),r=e.readUInt32LE(),l;if(67324752!==r)a("File entry signature is wrong."+r.toString()+" "+d.length.toString(),null);else{e.pos+=22;r=e.readUInt16LE();l=e.readUInt16LE();e.pos+=r+l; -if(n){d=d.slice(e.pos,e.pos+f);if(f!==d.length){a("The amount of compressed bytes read was "+d.length.toString()+" instead of "+f.toString()+" for "+h.filename+" in "+c+".",null);break a}d=y(d,k)}else d=d.slice(e.pos,e.pos+k);k!==d.length?a("The amount of bytes read was "+d.length.toString()+" instead of "+k.toString()+" for "+h.filename+" in "+c+".",null):(h.data=d,a(null,d))}}})}};this.set=function(c,a,b,g){h.filename=c;h.data=a;h.compressed=b;h.date=g};this.error=null;a&&(b=a.readUInt32LE(),33639248!== -b?this.error="Central directory entry has wrong signature at position "+(a.pos-4).toString()+' for file "'+c+'": '+a.data.length.toString():(a.pos+=6,n=a.readUInt16LE(),this.date=p(a.readUInt32LE()),a.readUInt32LE(),f=a.readUInt32LE(),k=a.readUInt32LE(),g=a.readUInt16LE(),d=a.readUInt16LE(),b=a.readUInt16LE(),a.pos+=8,e=a.readUInt32LE(),this.filename=runtime.byteArrayToString(a.data.slice(a.pos,a.pos+g),"utf8"),a.pos+=g+d+b))}function a(c,a){if(22!==c.length)a("Central directory length should be 22.", -x);else{var b=new core.ByteArray(c),g;g=b.readUInt32LE();101010256!==g?a("Central directory signature is wrong: "+g.toString(),x):(g=b.readUInt16LE(),0!==g?a("Zip files with non-zero disk numbers are not supported.",x):(g=b.readUInt16LE(),0!==g?a("Zip files with non-zero disk numbers are not supported.",x):(g=b.readUInt16LE(),u=b.readUInt16LE(),g!==u?a("Number of entries is inconsistent.",x):(g=b.readUInt32LE(),b=b.readUInt16LE(),b=r-22-g,runtime.read(h,b,r-b,function(c,b){if(c||null===b)a(c,x);else a:{var g= -new core.ByteArray(b),d,f;n=[];for(d=0;dr?m("File '"+h+"' cannot be read.",x):runtime.read(h,r-22,22,function(c,b){c||null===m||null===b?m(c,x):a(b,m)})})}; +2932959818,3654703836,1088359270,936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117],e,h,d=a.length,c=0,c=0;e=-1;for(h=0;h>>8^c;return e^-1}function m(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 f(a){var b=a.getFullYear();return 1980>b?0:b-1980<< +25|a.getMonth()+1<<21|a.getDate()<<16|a.getHours()<<11|a.getMinutes()<<5|a.getSeconds()>>1}function n(a,b){var e,h,d,c,k,f,g,l=this;this.load=function(b){if(void 0!==l.data)b(null,l.data);else{var e=k+34+h+d+256;e+g>q&&(e=q-g);runtime.read(a,g,e,function(e,h){if(e||null===h)b(e,h);else a:{var d=h,g=new core.ByteArray(d),q=g.readUInt32LE(),s;if(67324752!==q)b("File entry signature is wrong."+q.toString()+" "+d.length.toString(),null);else{g.pos+=22;q=g.readUInt16LE();s=g.readUInt16LE();g.pos+=q+s; +if(c){d=d.subarray(g.pos,g.pos+k);if(k!==d.length){b("The amount of compressed bytes read was "+d.length.toString()+" instead of "+k.toString()+" for "+l.filename+" in "+a+".",null);break a}d=x(d,f)}else d=d.subarray(g.pos,g.pos+f);f!==d.length?b("The amount of bytes read was "+d.length.toString()+" instead of "+f.toString()+" for "+l.filename+" in "+a+".",null):(l.data=d,b(null,d))}}})}};this.set=function(a,b,e,d){l.filename=a;l.data=b;l.compressed=e;l.date=d};this.error=null;b&&(e=b.readUInt32LE(), +33639248!==e?this.error="Central directory entry has wrong signature at position "+(b.pos-4).toString()+' for file "'+a+'": '+b.data.length.toString():(b.pos+=6,c=b.readUInt16LE(),this.date=m(b.readUInt32LE()),b.readUInt32LE(),k=b.readUInt32LE(),f=b.readUInt32LE(),h=b.readUInt16LE(),d=b.readUInt16LE(),e=b.readUInt16LE(),b.pos+=8,g=b.readUInt32LE(),this.filename=runtime.byteArrayToString(b.data.subarray(b.pos,b.pos+h),"utf8"),b.pos+=h+d+e))}function b(a,b){if(22!==a.length)b("Central directory length should be 22.", +v);else{var e=new core.ByteArray(a),d;d=e.readUInt32LE();101010256!==d?b("Central directory signature is wrong: "+d.toString(),v):(d=e.readUInt16LE(),0!==d?b("Zip files with non-zero disk numbers are not supported.",v):(d=e.readUInt16LE(),0!==d?b("Zip files with non-zero disk numbers are not supported.",v):(d=e.readUInt16LE(),u=e.readUInt16LE(),d!==u?b("Number of entries is inconsistent.",v):(d=e.readUInt32LE(),e=e.readUInt16LE(),e=q-22-d,runtime.read(g,e,q-e,function(a,e){if(a||null===e)b(a,v);else a:{var d= +new core.ByteArray(e),c,k;h=[];for(c=0;cq?l("File '"+g+"' cannot be read.",v):runtime.read(g,q-22,22,function(a,e){a||null===l||null===e?l(a,v):b(e,l)})})}; // Input 19 -core.CSSUnits=function(){var h={"in":1,cm:2.54,mm:25.4,pt:72,pc:12};this.convert=function(m,e,p){return m*h[p]/h[e]};this.convertMeasure=function(h,e){var p,l;h&&e?(p=parseFloat(h),l=h.replace(p.toString(),""),p=this.convert(p,l,e)):p="";return p.toString()};this.getUnits=function(h){return h.substr(h.length-2,h.length)}}; +core.CSSUnits=function(){var g=this,l={"in":1,cm:2.54,mm:25.4,pt:72,pc:12};this.convert=function(c,g,f){return c*l[f]/l[g]};this.convertMeasure=function(c,l){var f,n;c&&l?(f=parseFloat(c),n=c.replace(f.toString(),""),f=g.convert(f,n,l).toString()):f="";return f};this.getUnits=function(c){return c.substr(c.length-2,c.length)}}; // Input 20 xmldom.LSSerializerFilter=function(){}; // Input 21 -"function"!==typeof Object.create&&(Object.create=function(h){var m=function(){};m.prototype=h;return new m}); -xmldom.LSSerializer=function(){function h(e){var h=e||{},a=function(a){var c={},b;for(b in a)a.hasOwnProperty(b)&&(c[a[b]]=b);return c}(e),d=[h],f=[a],b=0;this.push=function(){b+=1;h=d[b]=Object.create(h);a=f[b]=Object.create(a)};this.pop=function(){d[b]=void 0;f[b]=void 0;b-=1;h=d[b];a=f[b]};this.getLocalNamespaceDefinitions=function(){return a};this.getQName=function(b){var c=b.namespaceURI,g=0,d;if(!c)return b.localName;if(d=a[c])return d+":"+b.localName;do{d||!b.prefix?(d="ns"+g,g+=1):d=b.prefix; -if(h[d]===c)break;if(!h[d]){h[d]=c;a[c]=d;break}d=null}while(null===d);return d+":"+b.localName}}function m(e){return e.replace(/&/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""")}function e(h,q){var a="",d=p.filter?p.filter.acceptNode(q):NodeFilter.FILTER_ACCEPT,f;if(d===NodeFilter.FILTER_ACCEPT&&q.nodeType===Node.ELEMENT_NODE){h.push();f=h.getQName(q);var b,k=q.attributes,c,g,n,r="",u;b="<"+f;c=k.length;for(g=0;g")}if(d===NodeFilter.FILTER_ACCEPT||d===NodeFilter.FILTER_SKIP){for(d=q.firstChild;d;)a+=e(h,d),d=d.nextSibling;q.nodeValue&&(a+=m(q.nodeValue))}f&&(a+="",h.pop());return a}var p=this;this.filter=null;this.writeToString=function(l,m){if(!l)return"";var a=new h(m);return e(a,l)}}; +"function"!==typeof Object.create&&(Object.create=function(g){var l=function(){};l.prototype=g;return new l}); +xmldom.LSSerializer=function(){function g(c){var g=c||{},b=function(b){var a={},e;for(e in b)b.hasOwnProperty(e)&&(a[b[e]]=e);return a}(c),l=[g],m=[b],d=0;this.push=function(){d+=1;g=l[d]=Object.create(g);b=m[d]=Object.create(b)};this.pop=function(){l[d]=void 0;m[d]=void 0;d-=1;g=l[d];b=m[d]};this.getLocalNamespaceDefinitions=function(){return b};this.getQName=function(d){var a=d.namespaceURI,e=0,h;if(!a)return d.localName;if(h=b[a])return h+":"+d.localName;do{h||!d.prefix?(h="ns"+e,e+=1):h=d.prefix; +if(g[h]===a)break;if(!g[h]){g[h]=a;b[a]=h;break}h=null}while(null===h);return h+":"+d.localName}}function l(c){return c.replace(/&/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""")}function c(f,g){var b="",p=m.filter?m.filter.acceptNode(g):NodeFilter.FILTER_ACCEPT,r;if(p===NodeFilter.FILTER_ACCEPT&&g.nodeType===Node.ELEMENT_NODE){f.push();r=f.getQName(g);var d,k=g.attributes,a,e,h,q="",u;d="<"+r;a=k.length;for(e=0;e")}if(p===NodeFilter.FILTER_ACCEPT||p===NodeFilter.FILTER_SKIP){for(p=g.firstChild;p;)b+=c(f,p),p=p.nextSibling;g.nodeValue&&(b+=l(g.nodeValue))}r&&(b+="",f.pop());return b}var m=this;this.filter=null;this.writeToString=function(f,l){if(!f)return"";var b=new g(l);return c(b,f)}}; // Input 22 -xmldom.RelaxNGParser=function(){function h(a,d){this.message=function(){d&&(a+=1===d.nodeType?" Element ":" Node ",a+=d.nodeName,d.nodeValue&&(a+=" with value '"+d.nodeValue+"'"),a+=".");return a}}function m(a){if(2>=a.e.length)return a;var d={name:a.name,e:a.e.slice(0,2)};return m({name:a.name,e:[d].concat(a.e.slice(2))})}function e(a){a=a.split(":",2);var f="",c;1===a.length?a=["",a[0]]:f=a[0];for(c in d)d[c]===f&&(a[0]=c);return a}function p(a,d){for(var c=0,g,f,h=a.name;a.e&&c=b.e.length)return b;var c={name:b.name,e:b.e.slice(0,2)};return l({name:b.name,e:[c].concat(b.e.slice(2))})}function c(b){b=b.split(":",2);var c="",a;1===b.length?b=["",b[0]]:c=b[0];for(a in p)p[a]===c&&(b[0]=a);return b}function m(b,k){for(var a=0,e,h,f=b.name;b.e&&a=g.length)return c;0===f&&(f=0);for(var n=g.item(f);n.namespaceURI===b;){f+=1;if(f>=g.length)return c;n=g.item(f)}return n=d(a,c.attDeriv(a,g.item(f)),g,f+1)}function f(a,c,g){g.e[0].a?(a.push(g.e[0].text),c.push(g.e[0].a.ns)):f(a,c,g.e[0]);g.e[1].a?(a.push(g.e[1].text),c.push(g.e[1].a.ns)): -f(a,c,g.e[1])}var b="http://www.w3.org/2000/xmlns/",k,c,g,n,r,u,y,x,w,v,t={type:"notAllowed",nullable:!1,hash:"notAllowed",textDeriv:function(){return t},startTagOpenDeriv:function(){return t},attDeriv:function(){return t},startTagCloseDeriv:function(){return t},endTagDeriv:function(){return t}},s={type:"empty",nullable:!0,hash:"empty",textDeriv:function(){return t},startTagOpenDeriv:function(){return t},attDeriv:function(){return t},startTagCloseDeriv:function(){return s},endTagDeriv:function(){return t}}, -D={type:"text",nullable:!0,hash:"text",textDeriv:function(){return D},startTagOpenDeriv:function(){return t},attDeriv:function(){return t},startTagCloseDeriv:function(){return D},endTagDeriv:function(){return t}},A,C,I;k=p("choice",function(a,c){if(a===t)return c;if(c===t||a===c)return a},function(a,c){var g={},b;l(g,{p1:a,p2:c});c=a=void 0;for(b in g)g.hasOwnProperty(b)&&(void 0===a?a=g[b]:c=void 0===c?g[b]:k(c,g[b]));return function(a,c){return{type:"choice",p1:a,p2:c,nullable:a.nullable||c.nullable, -textDeriv:function(g,b){return k(a.textDeriv(g,b),c.textDeriv(g,b))},startTagOpenDeriv:e(function(g){return k(a.startTagOpenDeriv(g),c.startTagOpenDeriv(g))}),attDeriv:function(g,b){return k(a.attDeriv(g,b),c.attDeriv(g,b))},startTagCloseDeriv:h(function(){return k(a.startTagCloseDeriv(),c.startTagCloseDeriv())}),endTagDeriv:h(function(){return k(a.endTagDeriv(),c.endTagDeriv())})}}(a,c)});c=function(a,c,g){return function(){var b={},d=0;return function(f,n){var e=c&&c(f,n),k,h;if(void 0!==e)return e; -e=f.hash||f.toString();k=n.hash||n.toString();e=e.length)return b;0===c&&(c=0);for(var h=e.item(c);h.namespaceURI===d;){c+=1;if(c>=e.length)return b;h=e.item(c)}return h=p(a,b.attDeriv(a,e.item(c)),e,c+1)}function r(a,b,e){e.e[0].a?(a.push(e.e[0].text),b.push(e.e[0].a.ns)):r(a,b,e.e[0]);e.e[1].a?(a.push(e.e[1].text),b.push(e.e[1].a.ns)): +r(a,b,e.e[1])}var d="http://www.w3.org/2000/xmlns/",k,a,e,h,q,u,x,v,y,w,t={type:"notAllowed",nullable:!1,hash:"notAllowed",textDeriv:function(){return t},startTagOpenDeriv:function(){return t},attDeriv:function(){return t},startTagCloseDeriv:function(){return t},endTagDeriv:function(){return t}},s={type:"empty",nullable:!0,hash:"empty",textDeriv:function(){return t},startTagOpenDeriv:function(){return t},attDeriv:function(){return t},startTagCloseDeriv:function(){return s},endTagDeriv:function(){return t}}, +D={type:"text",nullable:!0,hash:"text",textDeriv:function(){return D},startTagOpenDeriv:function(){return t},attDeriv:function(){return t},startTagCloseDeriv:function(){return D},endTagDeriv:function(){return t}},A,B,M;k=m("choice",function(a,b){if(a===t)return b;if(b===t||a===b)return a},function(a,b){var e={},h;f(e,{p1:a,p2:b});b=a=void 0;for(h in e)e.hasOwnProperty(h)&&(void 0===a?a=e[h]:b=void 0===b?e[h]:k(b,e[h]));return function(a,b){return{type:"choice",p1:a,p2:b,nullable:a.nullable||b.nullable, +textDeriv:function(e,c){return k(a.textDeriv(e,c),b.textDeriv(e,c))},startTagOpenDeriv:c(function(e){return k(a.startTagOpenDeriv(e),b.startTagOpenDeriv(e))}),attDeriv:function(e,c){return k(a.attDeriv(e,c),b.attDeriv(e,c))},startTagCloseDeriv:g(function(){return k(a.startTagCloseDeriv(),b.startTagCloseDeriv())}),endTagDeriv:g(function(){return k(a.endTagDeriv(),b.endTagDeriv())})}}(a,b)});a=function(a,b,e){return function(){var c={},h=0;return function(d,k){var f=b&&b(d,k),g,l;if(void 0!==f)return f; +f=d.hash||d.toString();g=k.hash||k.toString();fNode.ELEMENT_NODE;){if(b!==Node.COMMENT_NODE&&(b!==Node.TEXT_NODE||!/^\s+$/.test(d.currentNode.nodeValue)))return[new h("Not allowed node of type "+ -b+".")];b=(f=d.nextSibling())?f.nodeType:0}if(!f)return[new h("Missing element "+a.names)];if(a.names&&-1===a.names.indexOf(q[f.namespaceURI]+":"+f.localName))return[new h("Found "+f.nodeName+" instead of "+a.names+".",f)];if(d.firstChild()){for(e=m(a.e[1],d,f);d.nextSibling();)if(b=d.currentNode.nodeType,!(d.currentNode&&d.currentNode.nodeType===Node.TEXT_NODE&&/^\s+$/.test(d.currentNode.nodeValue)||b===Node.COMMENT_NODE))return[new h("Spurious content.",d.currentNode)];if(d.parentNode()!==f)return[new h("Implementation error.")]}else e= -m(a.e[1],d,f);d.nextSibling();return e}var p,l,q;l=function(a,d,f,b){var k=a.name,c=null;if("text"===k)a:{for(var g=(a=d.currentNode)?a.nodeType:0;a!==f&&3!==g;){if(1===g){c=[new h("Element not allowed here.",a)];break a}g=(a=d.nextSibling())?a.nodeType:0}d.nextSibling();c=null}else if("data"===k)c=null;else if("value"===k)b!==a.text&&(c=[new h("Wrong value, should be '"+a.text+"', not '"+b+"'",f)]);else if("list"===k)c=null;else if("attribute"===k)a:{if(2!==a.e.length)throw"Attribute with wrong # of elements: "+ -a.e.length;k=a.localnames.length;for(c=0;cNode.ELEMENT_NODE;){if(d!==Node.COMMENT_NODE&&(d!==Node.TEXT_NODE||!/^\s+$/.test(c.currentNode.nodeValue)))return[new g("Not allowed node of type "+ +d+".")];d=(f=c.nextSibling())?f.nodeType:0}if(!f)return[new g("Missing element "+b.names)];if(b.names&&-1===b.names.indexOf(n[f.namespaceURI]+":"+f.localName))return[new g("Found "+f.nodeName+" instead of "+b.names+".",f)];if(c.firstChild()){for(k=l(b.e[1],c,f);c.nextSibling();)if(d=c.currentNode.nodeType,!(c.currentNode&&c.currentNode.nodeType===Node.TEXT_NODE&&/^\s+$/.test(c.currentNode.nodeValue)||d===Node.COMMENT_NODE))return[new g("Spurious content.",c.currentNode)];if(c.parentNode()!==f)return[new g("Implementation error.")]}else k= +l(b.e[1],c,f);c.nextSibling();return k}var m,f,n;f=function(b,p,m,d){var k=b.name,a=null;if("text"===k)a:{for(var e=(b=p.currentNode)?b.nodeType:0;b!==m&&3!==e;){if(1===e){a=[new g("Element not allowed here.",b)];break a}e=(b=p.nextSibling())?b.nodeType:0}p.nextSibling();a=null}else if("data"===k)a=null;else if("value"===k)d!==b.text&&(a=[new g("Wrong value, should be '"+b.text+"', not '"+d+"'",m)]);else if("list"===k)a=null;else if("attribute"===k)a:{if(2!==b.e.length)throw"Attribute with wrong # of elements: "+ +b.e.length;k=b.localnames.length;for(a=0;a=k&&d.push(m(a.substring(b,f)))):"["===a[f]&&(0>=k&&(b=f+1),k+=1),f+=1;return f};xmldom.XPathIterator.prototype.next=function(){};xmldom.XPathIterator.prototype.reset=function(){};b=function(c,b,f){var e,k,h,m;for(e=0;e=k&&c.push(l(a.substring(b,d)))):"["===a[d]&&(0>=k&&(b=d+1),k+=1),d+=1;return d};xmldom.XPathIterator.prototype.next=function(){};xmldom.XPathIterator.prototype.reset=function(){};d=function(a,e,c){var d,k,g,l;for(d=0;d=(p.getBoundingClientRect().top-v.bottom)/q?n.style.top=Math.abs(p.getBoundingClientRect().top-v.bottom)/q+20+"px":n.style.top="0px");m.style.left=l.getBoundingClientRect().width/q+"px";var l=m.style,p=m.getBoundingClientRect().left/q,w=m.getBoundingClientRect().top/q,v=n.getBoundingClientRect().left/q,t=n.getBoundingClientRect().top/q,s=0,D= -0,s=v-p,s=s*s,D=t-w,D=D*D,p=Math.sqrt(s+D);l.width=p+"px";q=Math.asin((n.getBoundingClientRect().top-m.getBoundingClientRect().top)/(q*parseFloat(m.style.width)));m.style.transform="rotate("+q+"rad)";m.style.MozTransform="rotate("+q+"rad)";m.style.WebkitTransform="rotate("+q+"rad)";m.style.msTransform="rotate("+q+"rad)";b&&(q=k.getComputedStyle(b,":before").content)&&"none"!==q&&(/^["'].*["']$/.test(q)&&(q=q.substring(1,q.length-1)),b.firstChild?b.firstChild.nodeValue=q:b.appendChild(f.createTextNode(q)))}} -var d=[],f=m.ownerDocument,b=new odf.OdfUtils,k=runtime.getWindow();runtime.assert(Boolean(k),"Expected to be run in an environment which has a global window, like a browser.");this.rerenderAnnotations=a;this.addAnnotation=function(c){l(!0);d.push({node:c.node,end:c.end});q();var b=f.createElement("div"),e=f.createElement("div"),k=f.createElement("div"),h=f.createElement("div"),m=f.createElement("div"),x=c.node;b.className="annotationWrapper";x.parentNode.insertBefore(b,x);e.className="annotationNote"; -e.appendChild(x);m.className="annotationRemoveButton";e.appendChild(m);k.className="annotationConnector horizontal";h.className="annotationConnector angular";b.appendChild(e);b.appendChild(k);b.appendChild(h);c.end&&p(c);a()};this.forgetAnnotations=function(){for(;d.length;){var a=d[0],b=d.indexOf(a),e=a.node,k=e.parentNode.parentNode;"div"===k.localName&&(k.parentNode.insertBefore(e,k),k.parentNode.removeChild(k));a=a.node.getAttributeNS(odf.Namespaces.officens,"name");a=f.querySelectorAll('span.annotationHighlight[annotation="'+ -a+'"]');k=e=void 0;for(e=0;e=(l.getBoundingClientRect().top-n.bottom)/b?d.style.top=Math.abs(l.getBoundingClientRect().top-n.bottom)/b+20+"px":d.style.top="0px");k.style.left=f.getBoundingClientRect().width/b+"px";var f=k.style,l=k.getBoundingClientRect().left/b,m=k.getBoundingClientRect().top/b,n=d.getBoundingClientRect().left/b,r=d.getBoundingClientRect().top/b,t=0,s=0,t=n-l,t=t*t,s=r-m,s=s*s,l=Math.sqrt(t+s);f.width=l+"px";m=Math.asin((d.getBoundingClientRect().top- +k.getBoundingClientRect().top)/(b*parseFloat(k.style.width)));k.style.transform="rotate("+m+"rad)";k.style.MozTransform="rotate("+m+"rad)";k.style.WebkitTransform="rotate("+m+"rad)";k.style.msTransform="rotate("+m+"rad)"}}var p=[],r=l.ownerDocument,d=new odf.OdfUtils,k=runtime.getWindow();runtime.assert(Boolean(k),"Expected to be run in an environment which has a global window, like a browser.");this.rerenderAnnotations=b;this.addAnnotation=function(a){f(!0);p.push({node:a.node,end:a.end});n();var e= +r.createElement("div"),c=r.createElement("div"),d=r.createElement("div"),k=r.createElement("div"),g=r.createElement("div"),l=a.node;e.className="annotationWrapper";l.parentNode.insertBefore(e,l);c.className="annotationNote";c.appendChild(l);g.className="annotationRemoveButton";c.appendChild(g);d.className="annotationConnector horizontal";k.className="annotationConnector angular";e.appendChild(c);e.appendChild(d);e.appendChild(k);a.end&&m(a);b()};this.forgetAnnotations=function(){for(;p.length;){var a= +p[0],b=p.indexOf(a),c=a.node,d=c.parentNode.parentNode;"div"===d.localName&&(d.parentNode.insertBefore(c,d),d.parentNode.removeChild(d));a=a.node.getAttributeNS(odf.Namespaces.officens,"name");a=r.querySelectorAll('span.annotationHighlight[annotation="'+a+'"]');d=c=void 0;for(c=0;ca.value||"%"===a.unit)?null:a}function w(a){return(a=y(a))&&"%"!==a.unit?null:a}function v(a){switch(a.namespaceURI){case odf.Namespaces.drawns:case odf.Namespaces.svgns:case odf.Namespaces.dr3dns:return!1;case odf.Namespaces.textns:switch(a.localName){case "note-body":case "ruby-text":return!1}break; -case odf.Namespaces.officens:switch(a.localName){case "annotation":case "binary-data":case "event-listeners":return!1}break;default:switch(a.localName){case "editinfo":return!1}}return!0}var t=odf.Namespaces.textns,s=odf.Namespaces.drawns,D=/^\s*$/,A=new core.DomUtils;this.isImage=h;this.isCharacterFrame=m;this.isTextSpan=function(a){return"span"===(a&&a.localName)&&a.namespaceURI===t};this.isParagraph=e;this.getParagraphElement=p;this.isWithinTrackedChanges=function(a,c){for(;a&&a!==c;){if(a.namespaceURI=== -t&&"tracked-changes"===a.localName)return!0;a=a.parentNode}return!1};this.isListItem=function(a){return"list-item"===(a&&a.localName)&&a.namespaceURI===t};this.isLineBreak=function(a){return"line-break"===(a&&a.localName)&&a.namespaceURI===t};this.isODFWhitespace=l;this.isGroupingElement=q;this.isCharacterElement=a;this.isWhitespaceElement=d;this.firstChild=f;this.lastChild=b;this.previousNode=k;this.nextNode=c;this.scanLeftForNonWhitespace=g;this.lookLeftForCharacter=function(c){var b;b=0;c.nodeType=== -Node.TEXT_NODE&&0=c.value||"%"===c.unit)?null:c;return c||w(a)};this.parseFoLineHeight=function(a){return x(a)||w(a)};this.getImpactedParagraphs= -function(a){var c=a.commonAncestorContainer,b=[];for(c.nodeType===Node.ELEMENT_NODE&&(b=A.getElementsByTagNameNS(c,t,"p").concat(A.getElementsByTagNameNS(c,t,"h")));c&&!e(c);)c=c.parentNode;c&&b.push(c);return b.filter(function(c){return A.rangeIntersectsNode(a,c)})};this.getTextNodes=function(a,c){var b=a.startContainer.ownerDocument.createRange(),g;g=A.getNodesInRange(a,function(g){b.selectNodeContents(g);if(g.nodeType===Node.TEXT_NODE){if(c&&A.rangesIntersect(a,b)||A.containsRange(a,b))return Boolean(p(g)&& -(!l(g.textContent)||u(g,0)))?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}else if(A.rangesIntersect(a,b)&&v(g))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});b.detach();return g};this.getTextElements=function(c,b,g){var d=c.startContainer.ownerDocument.createRange(),f;f=A.getNodesInRange(c,function(f){d.selectNodeContents(f);if(a(f.parentNode))return NodeFilter.FILTER_REJECT;if(f.nodeType===Node.TEXT_NODE){if(b&&A.rangesIntersect(c,d)||A.containsRange(c,d))if(g||Boolean(p(f)&& -(!l(f.textContent)||u(f,0))))return NodeFilter.FILTER_ACCEPT}else if(a(f)){if(b&&A.rangesIntersect(c,d)||A.containsRange(c,d))return NodeFilter.FILTER_ACCEPT}else if(v(f)||q(f))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});d.detach();return f};this.getParagraphElements=function(a){var c=a.startContainer.ownerDocument.createRange(),b;b=A.getNodesInRange(a,function(b){c.selectNodeContents(b);if(e(b)){if(A.rangesIntersect(a,c))return NodeFilter.FILTER_ACCEPT}else if(v(b)||q(b))return NodeFilter.FILTER_SKIP; -return NodeFilter.FILTER_REJECT});c.detach();return b};this.getImageElements=function(a){var c=a.startContainer.ownerDocument.createRange(),b;b=A.getNodesInRange(a,function(b){c.selectNodeContents(b);return h(b)&&A.containsRange(a,c)?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP});c.detach();return b}}; +odf.OdfUtils=function(){function g(a){return"image"===(a&&a.localName)&&a.namespaceURI===s}function l(a){return"frame"===(a&&a.localName)&&a.namespaceURI===s&&"as-char"===a.getAttributeNS(t,"anchor-type")}function c(a){var b=a&&a.localName;return("p"===b||"h"===b)&&a.namespaceURI===t}function m(a){for(;a&&!c(a);)a=a.parentNode;return a}function f(a){return/^[ \t\r\n]+$/.test(a)}function n(a){var b=a&&a.localName;return/^(span|p|h|a|meta)$/.test(b)&&a.namespaceURI===t||"span"===b&&"annotationHighlight"=== +a.className?!0:!1}function b(a){var b=a&&a.localName,c;c=!1;b&&(c=a.namespaceURI,c=c===t?"s"===b||"tab"===b||"line-break"===b:l(a));return c}function p(a){var b=a&&a.localName,c=!1;b&&(a=a.namespaceURI,a===t&&(c="s"===b));return c}function r(a){for(;null!==a.firstChild&&n(a);)a=a.firstChild;return a}function d(a){for(;null!==a.lastChild&&n(a);)a=a.lastChild;return a}function k(a){for(;!c(a)&&null===a.previousSibling;)a=a.parentNode;return c(a)?null:d(a.previousSibling)}function a(a){for(;!c(a)&&null=== +a.nextSibling;)a=a.parentNode;return c(a)?null:r(a.nextSibling)}function e(a){for(var c=!1;a;)if(a.nodeType===Node.TEXT_NODE)if(0===a.length)a=k(a);else return!f(a.data.substr(a.length-1,1));else b(a)?(c=!1===p(a),a=null):a=k(a);return c}function h(c){var e=!1;for(c=c&&r(c);c;){if(c.nodeType===Node.TEXT_NODE&&0a.value||"%"===a.unit)?null:a}function y(a){return(a=x(a))&&"%"!==a.unit?null:a}function w(a){switch(a.namespaceURI){case odf.Namespaces.drawns:case odf.Namespaces.svgns:case odf.Namespaces.dr3dns:return!1;case odf.Namespaces.textns:switch(a.localName){case "note-body":case "ruby-text":return!1}break; +case odf.Namespaces.officens:switch(a.localName){case "annotation":case "binary-data":case "event-listeners":return!1}break;default:switch(a.localName){case "editinfo":return!1}}return!0}var t=odf.Namespaces.textns,s=odf.Namespaces.drawns,D=/^\s*$/,A=new core.DomUtils;this.isImage=g;this.isCharacterFrame=l;this.isTextSpan=function(a){return"span"===(a&&a.localName)&&a.namespaceURI===t};this.isParagraph=c;this.getParagraphElement=m;this.isWithinTrackedChanges=function(a,b){for(;a&&a!==b;){if(a.namespaceURI=== +t&&"tracked-changes"===a.localName)return!0;a=a.parentNode}return!1};this.isListItem=function(a){return"list-item"===(a&&a.localName)&&a.namespaceURI===t};this.isLineBreak=function(a){return"line-break"===(a&&a.localName)&&a.namespaceURI===t};this.isODFWhitespace=f;this.isGroupingElement=n;this.isCharacterElement=b;this.isSpaceElement=p;this.firstChild=r;this.lastChild=d;this.previousNode=k;this.nextNode=a;this.scanLeftForNonSpace=e;this.lookLeftForCharacter=function(a){var c;c=0;a.nodeType===Node.TEXT_NODE&& +0=b.value||"%"===b.unit)?null:b;return b||y(a)};this.parseFoLineHeight=function(a){return v(a)||y(a)};this.getImpactedParagraphs=function(a){var b= +a.commonAncestorContainer,e=[];for(b.nodeType===Node.ELEMENT_NODE&&(e=A.getElementsByTagNameNS(b,t,"p").concat(A.getElementsByTagNameNS(b,t,"h")));b&&!c(b);)b=b.parentNode;b&&e.push(b);return e.filter(function(b){return A.rangeIntersectsNode(a,b)})};this.getTextNodes=function(a,b){var c=a.startContainer.ownerDocument.createRange(),e;e=A.getNodesInRange(a,function(e){c.selectNodeContents(e);if(e.nodeType===Node.TEXT_NODE){if(b&&A.rangesIntersect(a,c)||A.containsRange(a,c))return Boolean(m(e)&&(!f(e.textContent)|| +u(e,0)))?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}else if(A.rangesIntersect(a,c)&&w(e))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});c.detach();return e};this.getTextElements=function(a,c,e){var d=a.startContainer.ownerDocument.createRange(),h;h=A.getNodesInRange(a,function(h){d.selectNodeContents(h);if(b(h.parentNode))return NodeFilter.FILTER_REJECT;if(h.nodeType===Node.TEXT_NODE){if(c&&A.rangesIntersect(a,d)||A.containsRange(a,d))if(e||Boolean(m(h)&&(!f(h.textContent)|| +u(h,0))))return NodeFilter.FILTER_ACCEPT}else if(b(h)){if(c&&A.rangesIntersect(a,d)||A.containsRange(a,d))return NodeFilter.FILTER_ACCEPT}else if(w(h)||n(h))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});d.detach();return h};this.getParagraphElements=function(a){var b=a.startContainer.ownerDocument.createRange(),e;e=A.getNodesInRange(a,function(e){b.selectNodeContents(e);if(c(e)){if(A.rangesIntersect(a,b))return NodeFilter.FILTER_ACCEPT}else if(w(e)||n(e))return NodeFilter.FILTER_SKIP; +return NodeFilter.FILTER_REJECT});b.detach();return e};this.getImageElements=function(a){var b=a.startContainer.ownerDocument.createRange(),c;c=A.getNodesInRange(a,function(c){b.selectNodeContents(c);return g(c)&&A.containsRange(a,b)?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP});b.detach();return c}}; // Input 31 /* @@ -637,8 +640,8 @@ return NodeFilter.FILTER_REJECT});c.detach();return b};this.getImageElements=fun @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.OdfUtils"); -odf.TextSerializer=function(){function h(p){var l="",q=m.filter?m.filter.acceptNode(p):NodeFilter.FILTER_ACCEPT,a=p.nodeType,d;if(q===NodeFilter.FILTER_ACCEPT||q===NodeFilter.FILTER_SKIP)for(d=p.firstChild;d;)l+=h(d),d=d.nextSibling;q===NodeFilter.FILTER_ACCEPT&&(a===Node.ELEMENT_NODE&&e.isParagraph(p)?l+="\n":a===Node.TEXT_NODE&&p.textContent&&(l+=p.textContent));return l}var m=this,e=new odf.OdfUtils;this.filter=null;this.writeToString=function(e){if(!e)return"";e=h(e);"\n"===e[e.length-1]&&(e= -e.substr(0,e.length-1));return e}}; +odf.TextSerializer=function(){function g(m){var f="",n=l.filter?l.filter.acceptNode(m):NodeFilter.FILTER_ACCEPT,b=m.nodeType,p;if(n===NodeFilter.FILTER_ACCEPT||n===NodeFilter.FILTER_SKIP)for(p=m.firstChild;p;)f+=g(p),p=p.nextSibling;n===NodeFilter.FILTER_ACCEPT&&(b===Node.ELEMENT_NODE&&c.isParagraph(m)?f+="\n":b===Node.TEXT_NODE&&m.textContent&&(f+=m.textContent));return f}var l=this,c=new odf.OdfUtils;this.filter=null;this.writeToString=function(c){if(!c)return"";c=g(c);"\n"===c[c.length-1]&&(c= +c.substr(0,c.length-1));return c}}; // Input 32 /* @@ -678,10 +681,10 @@ e.substr(0,e.length-1));return e}}; @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils");runtime.loadClass("core.LoopWatchDog");runtime.loadClass("odf.Namespaces"); -odf.TextStyleApplicator=function(h,m,e){function p(a){function d(a,b){return"object"===typeof a&&"object"===typeof b?Object.keys(a).every(function(f){return d(a[f],b[f])}):a===b}this.isStyleApplied=function(c){c=m.getAppliedStylesForElement(c);return d(a,c)}}function l(a){var k={};this.applyStyleToContainer=function(c){var g;g=c.getAttributeNS(d,"style-name");var n=c.ownerDocument;g=g||"";if(!k.hasOwnProperty(g)){var l=g,q;q=g?m.createDerivedStyleObject(g,"text",a):a;n=n.createElementNS(f,"style:style"); -m.updateStyle(n,q);n.setAttributeNS(f,"style:name",h.generateStyleName());n.setAttributeNS(f,"style:family","text");n.setAttributeNS("urn:webodf:names:scope","scope","document-content");e.appendChild(n);k[l]=n}g=k[g].getAttributeNS(f,"name");c.setAttributeNS(d,"text:style-name",g)}}function q(b,f){var c=b.ownerDocument,g=b.parentNode,e,h,l=new core.LoopWatchDog(1E4);h=[];"span"!==g.localName||g.namespaceURI!==d?(e=c.createElementNS(d,"text:span"),g.insertBefore(e,b),g=!1):(b.previousSibling&&!a.rangeContainsNode(f, -g.firstChild)?(e=g.cloneNode(!1),g.parentNode.insertBefore(e,g.nextSibling)):e=g,g=!0);h.push(b);for(c=b.nextSibling;c&&a.rangeContainsNode(f,c);)l.check(),h.push(c),c=c.nextSibling;h.forEach(function(a){a.parentNode!==e&&e.appendChild(a)});if(c&&g)for(h=e.cloneNode(!1),e.parentNode.insertBefore(h,e.nextSibling);c;)l.check(),g=c.nextSibling,h.appendChild(c),c=g;return e}var a=new core.DomUtils,d=odf.Namespaces.textns,f=odf.Namespaces.stylens;this.applyStyle=function(a,d,c){var g={},f,e,h,m;runtime.assert(c&& -c["style:text-properties"],"applyStyle without any text properties");g["style:text-properties"]=c["style:text-properties"];h=new l(g);m=new p(g);a.forEach(function(a){f=m.isStyleApplied(a);!1===f&&(e=q(a,d),h.applyStyleToContainer(e))})}}; +odf.TextStyleApplicator=function(g,l,c){function m(b){function c(a,b){return"object"===typeof a&&"object"===typeof b?Object.keys(a).every(function(d){return c(a[d],b[d])}):a===b}this.isStyleApplied=function(a){a=l.getAppliedStylesForElement(a);return c(b,a)}}function f(b){var f={};this.applyStyleToContainer=function(a){var e;e=a.getAttributeNS(p,"style-name");var h=a.ownerDocument;e=e||"";if(!f.hasOwnProperty(e)){var m=e,n;n=e?l.createDerivedStyleObject(e,"text",b):b;h=h.createElementNS(r,"style:style"); +l.updateStyle(h,n);h.setAttributeNS(r,"style:name",g.generateStyleName());h.setAttributeNS(r,"style:family","text");h.setAttributeNS("urn:webodf:names:scope","scope","document-content");c.appendChild(h);f[m]=h}e=f[e].getAttributeNS(r,"name");a.setAttributeNS(p,"text:style-name",e)}}function n(c,f){var a=c.ownerDocument,e=c.parentNode,h,g,l=new core.LoopWatchDog(1E4);g=[];"span"!==e.localName||e.namespaceURI!==p?(h=a.createElementNS(p,"text:span"),e.insertBefore(h,c),e=!1):(c.previousSibling&&!b.rangeContainsNode(f, +e.firstChild)?(h=e.cloneNode(!1),e.parentNode.insertBefore(h,e.nextSibling)):h=e,e=!0);g.push(c);for(a=c.nextSibling;a&&b.rangeContainsNode(f,a);)l.check(),g.push(a),a=a.nextSibling;g.forEach(function(a){a.parentNode!==h&&h.appendChild(a)});if(a&&e)for(g=h.cloneNode(!1),h.parentNode.insertBefore(g,h.nextSibling);a;)l.check(),e=a.nextSibling,g.appendChild(a),a=e;return h}var b=new core.DomUtils,p=odf.Namespaces.textns,r=odf.Namespaces.stylens;this.applyStyle=function(b,c,a){var e={},h,g,l,p;runtime.assert(a&& +a["style:text-properties"],"applyStyle without any text properties");e["style:text-properties"]=a["style:text-properties"];l=new f(e);p=new m(e);b.forEach(function(a){h=p.isStyleApplied(a);!1===h&&(g=n(a,c),l.applyStyleToContainer(g))})}}; // Input 33 /* @@ -721,30 +724,57 @@ c["style:text-properties"],"applyStyle without any text properties");g["style:te @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfUtils");runtime.loadClass("xmldom.XPath");runtime.loadClass("core.CSSUnits"); -odf.Style2CSS=function(){function h(a){var c={},b,g;if(!a)return c;for(a=a.firstChild;a;){if(g=a.namespaceURI!==r||"style"!==a.localName&&"default-style"!==a.localName?a.namespaceURI===x&&"list-style"===a.localName?"list":a.namespaceURI!==r||"page-layout"!==a.localName&&"default-page-layout"!==a.localName?void 0:"page":a.getAttributeNS(r,"family"))(b=a.getAttributeNS&&a.getAttributeNS(r,"name"))||(b=""),g=c[g]=c[g]||{},g[b]=a;a=a.nextSibling}return c}function m(a,c){if(!c||!a)return null;if(a[c])return a[c]; -var b,g;for(b in a)if(a.hasOwnProperty(b)&&(g=m(a[b].derivedStyles,c)))return g;return null}function e(a,c,b){var g=c[a],d,f;g&&(d=g.getAttributeNS(r,"parent-style-name"),f=null,d&&(f=m(b,d),!f&&c[d]&&(e(d,c,b),f=c[d],c[d]=null)),f?(f.derivedStyles||(f.derivedStyles={}),f.derivedStyles[a]=g):b[a]=g)}function p(a,c){for(var b in a)a.hasOwnProperty(b)&&(e(b,a,c),a[b]=null)}function l(a,c){var b=t[a],g;if(null===b)return null;g=c?"["+b+'|style-name="'+c+'"]':"";"presentation"===b&&(b="draw",g=c?'[presentation|style-name="'+ -c+'"]':"");return b+"|"+s[a].join(g+","+b+"|")+g}function q(a,c,b){var g=[],d,f;g.push(l(a,c));for(d in b.derivedStyles)if(b.derivedStyles.hasOwnProperty(d))for(f in c=q(a,d,b.derivedStyles[d]),c)c.hasOwnProperty(f)&&g.push(c[f]);return g}function a(a,c,b){if(!a)return null;for(a=a.firstChild;a;){if(a.namespaceURI===c&&a.localName===b)return c=a;a=a.nextSibling}return null}function d(a,c){var b="",g,d;for(g in c)if(c.hasOwnProperty(g)&&(g=c[g],d=a.getAttributeNS(g[0],g[1]))){d=d.trim();if(E.hasOwnProperty(g[1])){var f= -d.indexOf(" "),e=void 0,k=void 0;-1!==f?(e=d.substring(0,f),k=d.substring(f)):(e=d,k="");(e=ba.parseLength(e))&&"pt"===e.unit&&0.75>e.value&&(d="0.75pt"+k)}g[2]&&(b+=g[2]+":"+d+";")}return b}function f(c){return(c=a(c,r,"text-properties"))?ba.parseFoFontSize(c.getAttributeNS(n,"font-size")):null}function b(a){a=a.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,function(a,c,b,g){return c+c+b+b+g+g});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 k(a,c,b,g){c='text|list[text|style-name="'+c+'"]';var d=b.getAttributeNS(x,"level"),f;b=ba.getFirstNonWhitespaceChild(b);b=ba.getFirstNonWhitespaceChild(b);var e;b&&(f=b.attributes,e=f["fo:text-indent"]?f["fo:text-indent"].value:void 0,f=f["fo:margin-left"]?f["fo:margin-left"].value:void 0);e||(e="-0.6cm");b="-"===e.charAt(0)?e.substring(1):"-"+e;for(d=d&&parseInt(d,10);1 text|list-item > text|list",d-=1;d=c+" > text|list-item > *:not(text|list):first-child";void 0!== -f&&(f=d+"{margin-left:"+f+";}",a.insertRule(f,a.cssRules.length));g=c+" > text|list-item > *:not(text|list):first-child:before{"+g+";";g+="counter-increment:list;";g+="margin-left:"+e+";";g+="width:"+b+";";g+="display:inline-block}";try{a.insertRule(g,a.cssRules.length)}catch(k){throw k;}}function c(e,h,l,m){if("list"===h)for(var s=m.firstChild,p,u;s;){if(s.namespaceURI===x)if(p=s,"list-level-style-number"===s.localName){var t=p;u=t.getAttributeNS(r,"num-format");var P=t.getAttributeNS(r,"num-suffix"), -E={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},t=t.getAttributeNS(r,"num-prefix")||"",t=E.hasOwnProperty(u)?t+(" counter(list, "+E[u]+")"):u?t+("'"+u+"';"):t+" ''";P&&(t+=" '"+P+"'");u="content: "+t+";";k(e,l,p,u)}else"list-level-style-image"===s.localName?(u="content: none;",k(e,l,p,u)):"list-level-style-bullet"===s.localName&&(u="content: '"+p.getAttributeNS(x,"bullet-char")+"';",k(e,l,p,u));s=s.nextSibling}else if("page"===h)if(P=p=l="",s=m.getElementsByTagNameNS(r, -"page-layout-properties")[0],p=s.parentNode.parentNode.parentNode.masterStyles,P="",l+=d(s,Z),u=s.getElementsByTagNameNS(r,"background-image"),0f.value&&(d="0.75pt"+k)}e[2]&&(c+=e[2]+":"+d+";")}return c}function r(a){return(a=b(a,q,"text-properties"))?ba.parseFoFontSize(a.getAttributeNS(h,"font-size")):null}function d(a){a=a.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,function(a,b,c,e){return b+b+c+c+e+e});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 k(a,b,c,e){b='text|list[text|style-name="'+b+'"]';var d=c.getAttributeNS(v,"level"),h;c=ba.getFirstNonWhitespaceChild(c);c=ba.getFirstNonWhitespaceChild(c);var f;c&&(h=c.attributes,f=h["fo:text-indent"]?h["fo:text-indent"].value:void 0,h=h["fo:margin-left"]?h["fo:margin-left"].value:void 0);f||(f="-0.6cm");c="-"===f.charAt(0)?f.substring(1):"-"+f;for(d=d&&parseInt(d,10);1 text|list-item > text|list",d-=1;d=b+" > text|list-item > *:not(text|list):first-child";void 0!== +h&&(h=d+"{margin-left:"+h+";}",a.insertRule(h,a.cssRules.length));e=b+" > text|list-item > *:not(text|list):first-child:before{"+e+";";e+="counter-increment:list;";e+="margin-left:"+f+";";e+="width:"+c+";";e+="display:inline-block}";try{a.insertRule(e,a.cssRules.length)}catch(k){throw k;}}function a(c,f,g,l){if("list"===f)for(var s=l.firstChild,m,t;s;){if(s.namespaceURI===v)if(m=s,"list-level-style-number"===s.localName){var u=m;t=u.getAttributeNS(q,"num-format");var P=u.getAttributeNS(q,"num-suffix"), +L={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},u=u.getAttributeNS(q,"num-prefix")||"",u=L.hasOwnProperty(t)?u+(" counter(list, "+L[t]+")"):t?u+("'"+t+"';"):u+" ''";P&&(u+=" '"+P+"'");t="content: "+u+";";k(c,g,m,t)}else"list-level-style-image"===s.localName?(t="content: none;",k(c,g,m,t)):"list-level-style-bullet"===s.localName&&(t="content: '"+m.getAttributeNS(v,"bullet-char")+"';",k(c,g,m,t));s=s.nextSibling}else if("page"===f)if(P=m=g="",s=l.getElementsByTagNameNS(q, +"page-layout-properties")[0],m=s.parentNode.parentNode.parentNode.masterStyles,P="",g+=p(s,$),t=s.getElementsByTagNameNS(q,"background-image"),0 + + @licstart + This file is part of WebODF. + + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +runtime.loadClass("odf.Namespaces");runtime.loadClass("core.DomUtils"); +odf.MetadataManager=function(g){function l(f,l){f&&(Object.keys(f).forEach(function(b){m[b]=f[b]}),c.mapKeyValObjOntoNode(g,f,odf.Namespaces.resolvePrefix));l&&(l.forEach(function(b){delete m[b]}),c.removeKeyElementsFromNode(g,l,odf.Namespaces.resolvePrefix))}var c=new core.DomUtils,m={};this.setMetadata=l;this.incrementEditingCycles=function(){var c=parseInt(m["meta:editing-cycles"]||0,10)+1;l({"meta:editing-cycles":c},null)};m=c.getKeyValRepresentationOfNode(g,odf.Namespaces.lookupPrefix)}; +// Input 35 /* Copyright (C) 2012-2013 KO GmbH @@ -782,31 +812,32 @@ p;if(p=a(m,r,"drawing-page-properties"))u=""+d(p,I),"true"===p.getAttributeNS(v, @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.Base64");runtime.loadClass("core.Zip");runtime.loadClass("xmldom.LSSerializer");runtime.loadClass("odf.StyleInfo");runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfNodeFilter"); -odf.OdfContainer=function(){function h(a,c,b){for(a=a?a.firstChild:null;a;){if(a.localName===b&&a.namespaceURI===c)return a;a=a.nextSibling}return null}function m(a){var c,d=b.length;for(c=0;cb)break;f=f.nextSibling}a.insertBefore(c,f)}}}function q(a){this.OdfContainer= -a}function a(a,c,b,d){var f=this;this.size=0;this.type=null;this.name=a;this.container=b;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=c,d.loadAsDataURL(a,c,function(a,c){a&&runtime.log(a);f.url=c;if(f.onchange)f.onchange(f);if(f.onstatereadychange)f.onstatereadychange(f)}))}}var d=new odf.StyleInfo,f=odf.Namespaces.stylens,b="meta settings scripts font-face-decls styles automatic-styles master-styles body".split(" "), -k=(new Date).getTime()+"_webodf_",c=new core.Base64;q.prototype=new function(){};q.prototype.constructor=q;q.namespaceURI="urn:oasis:names:tc:opendocument:xmlns:office:1.0";q.localName="document";a.prototype.load=function(){};a.prototype.getUrl=function(){return this.data?"data:;base64,"+c.toBase64(this.data):null};odf.OdfContainer=function n(b,m){function y(a){for(var c=a.firstChild,b;c;)b=c.nextSibling,c.nodeType===Node.ELEMENT_NODE?y(c):c.nodeType===Node.PROCESSING_INSTRUCTION_NODE&&a.removeChild(c), -c=b}function x(a,c){for(var b=a&&a.firstChild;b;)b.nodeType===Node.ELEMENT_NODE&&b.setAttributeNS("urn:webodf:names:scope","scope",c),b=b.nextSibling}function w(a,c){function b(a,c,d){var f=0,e;for(e=a=a.replace(/\d+$/,"");c.hasOwnProperty(e)||d.hasOwnProperty(e);)f+=1,e=a+f;return e}function d(a){var c={};for(a=a.firstChild;a;)a.nodeType===Node.ELEMENT_NODE&&a.namespaceURI===f&&"font-face"===a.localName&&(h=a.getAttributeNS(f,"name"),c[h]=a),a=a.nextSibling;return c}var e,k,h,l,n,m,s={};n=d(a);m= -d(c);for(e=c.firstChild;e;)k=e.nextSibling,e.nodeType===Node.ELEMENT_NODE&&e.namespaceURI===f&&"font-face"===e.localName&&(h=e.getAttributeNS(f,"name"),n.hasOwnProperty(h)?e.isEqualNode(n[h])||(l=b(h,n,m),e.setAttributeNS(f,"style:name",l),a.appendChild(e),n[l]=e,delete m[h],s[h]=l):(a.appendChild(e),n[h]=e,delete m[h])),e=k;return s}function v(a,c){var b=null,d,f,e;if(a)for(b=a.cloneNode(!0),d=b.firstChild;d;)f=d.nextSibling,d.nodeType===Node.ELEMENT_NODE&&(e=d.getAttributeNS("urn:webodf:names:scope", -"scope"))&&e!==c&&b.removeChild(d),d=f;return b}function t(a,c){var b=null,e,k,h,l={};if(a)for(c.forEach(function(a){d.collectUsedFontFaces(l,a)}),b=a.cloneNode(!0),e=b.firstChild;e;)k=e.nextSibling,e.nodeType===Node.ELEMENT_NODE&&(h=e.getAttributeNS(f,"name"),l[h]||b.removeChild(e)),e=k;return b}function s(a){var c=G.rootElement.ownerDocument,b;if(a){y(a.documentElement);try{b=c.importNode(a.documentElement,!0)}catch(d){}}return b}function D(a){G.state=a;if(G.onchange)G.onchange(G);if(G.onstatereadychange)G.onstatereadychange(G)} -function A(a){ca=null;G.rootElement=a;a.fontFaceDecls=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls");a.styles=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles");a.automaticStyles=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles");a.masterStyles=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles");a.body=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");a.meta=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", -"meta")}function C(a){a=s(a);var c=G.rootElement;a&&"document-styles"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI?(c.fontFaceDecls=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls"),l(c,c.fontFaceDecls),c.styles=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles"),l(c,c.styles),c.automaticStyles=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles"),x(c.automaticStyles,"document-styles"),l(c,c.automaticStyles), -c.masterStyles=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles"),l(c,c.masterStyles),d.prefixStyleNames(c.automaticStyles,k,c.masterStyles)):D(n.INVALID)}function I(a){a=s(a);var c,b,f;if(a&&"document-content"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI){c=G.rootElement;b=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls");c.fontFaceDecls&&b?f=w(c.fontFaceDecls,b):b&&(c.fontFaceDecls=b,l(c,b));b=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", -"automatic-styles");x(b,"document-content");f&&d.changeFontFaceNames(b,f);if(c.automaticStyles&&b)for(f=b.firstChild;f;)c.automaticStyles.appendChild(f),f=b.firstChild;else b&&(c.automaticStyles=b,l(c,b));c.body=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");l(c,c.body)}else D(n.INVALID)}function z(a){a=s(a);var c;a&&"document-meta"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&(c=G.rootElement,c.meta=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", -"meta"),l(c,c.meta))}function M(a){a=s(a);var c;a&&"document-settings"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&(c=G.rootElement,c.settings=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","settings"),l(c,c.settings))}function H(a){a=s(a);var c;if(a&&"manifest"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"===a.namespaceURI)for(c=G.rootElement,c.manifest=a,a=c.manifest.firstChild;a;)a.nodeType===Node.ELEMENT_NODE&&"file-entry"=== -a.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"===a.namespaceURI&&(O[a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","full-path")]=a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","media-type")),a=a.nextSibling}function R(a){var c=a.shift(),b,d;c?(b=c[0],d=c[1],Q.loadAsDOM(b,function(c,b){d(b);c||G.state===n.INVALID||R(a)})):D(n.DONE)}function Z(a){var c="";odf.Namespaces.forEachPrefix(function(a,b){c+=" xmlns:"+a+'="'+b+'"'});return''}function ja(){var a=new xmldom.LSSerializer,c=Z("document-meta");a.filter=new odf.OdfNodeFilter;c+=a.writeToString(G.rootElement.meta,odf.Namespaces.namespaceMap);return c+""}function E(a,c){var b=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest:file-entry");b.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest:full-path",a);b.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0", -"manifest:media-type",c);return b}function ka(){var a=runtime.parseXML(''),c=h(a,"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest"),b=new xmldom.LSSerializer,d;for(d in O)O.hasOwnProperty(d)&&c.appendChild(E(d,O[d]));b.filter=new odf.OdfNodeFilter;return'\n'+b.writeToString(a,odf.Namespaces.namespaceMap)} -function ba(){var a=new xmldom.LSSerializer,c=Z("document-settings");a.filter=new odf.OdfNodeFilter;c+=a.writeToString(G.rootElement.settings,odf.Namespaces.namespaceMap);return c+""}function ga(){var a=odf.Namespaces.namespaceMap,c=new xmldom.LSSerializer,b,f,h,l=Z("document-styles");f=v(G.rootElement.automaticStyles,"document-styles");h=G.rootElement.masterStyles&&G.rootElement.masterStyles.cloneNode(!0);b=t(G.rootElement.fontFaceDecls,[h,G.rootElement.styles,f]);d.removePrefixFromStyleNames(f, -k,h);c.filter=new e(h,f);l+=c.writeToString(b,a);l+=c.writeToString(G.rootElement.styles,a);l+=c.writeToString(f,a);l+=c.writeToString(h,a);return l+""}function S(){var a=odf.Namespaces.namespaceMap,c=new xmldom.LSSerializer,b,d,f=Z("document-content");d=v(G.rootElement.automaticStyles,"document-content");b=t(G.rootElement.fontFaceDecls,[d]);c.filter=new p(G.rootElement.body,d);f+=c.writeToString(b,a);f+=c.writeToString(d,a);f+=c.writeToString(G.rootElement.body,a);return f+ -""}function Y(a,c){runtime.loadXML(a,function(a,b){if(a)c(a);else{var d=s(b);d&&"document"===d.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===d.namespaceURI?(A(d),D(n.DONE)):D(n.INVALID)}})}function V(){function a(c,b){var f;b||(b=c);f=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0",b);d[c]=f;d.appendChild(f)}var c=new core.Zip("",null),b=runtime.byteArrayFromString("application/vnd.oasis.opendocument.text","utf8"),d=G.rootElement, -f=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","text");c.save("mimetype",b,!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");d.body.appendChild(f);D(n.DONE);return c}function N(){var a,c=new Date;a=runtime.byteArrayFromString(ba(),"utf8");Q.save("settings.xml",a,!0,c);a=runtime.byteArrayFromString(ja(),"utf8");Q.save("meta.xml",a,!0,c); -a=runtime.byteArrayFromString(ga(),"utf8");Q.save("styles.xml",a,!0,c);a=runtime.byteArrayFromString(S(),"utf8");Q.save("content.xml",a,!0,c);a=runtime.byteArrayFromString(ka(),"utf8");Q.save("META-INF/manifest.xml",a,!0,c)}function L(a,c){N();Q.writeAs(a,function(a){c(a)})}var G=this,Q,O={},ca;this.onstatereadychange=m;this.rootElement=this.state=this.onchange=null;this.setRootElement=A;this.getContentElement=function(){var a;ca||(a=G.rootElement.body,ca=a.getElementsByTagNameNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0", -"text")[0]||a.getElementsByTagNameNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","presentation")[0]||a.getElementsByTagNameNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","spreadsheet")[0]);return ca};this.getDocumentType=function(){var a=G.getContentElement();return a&&a.localName};this.getPart=function(c){return new a(c,O[c],G,Q)};this.getPartData=function(a,c){Q.load(a,c)};this.createByteArray=function(a,c){N();Q.createByteArray(a,c)};this.saveAs=L;this.save=function(a){L(b,a)};this.getUrl= -function(){return b};this.setBlob=function(a,b,d){d=c.convertBase64ToByteArray(d);Q.save(a,d,!1,new Date);O.hasOwnProperty(a)&&runtime.log(a+" has been overwritten.");O[a]=b};this.removeBlob=function(a){var c=Q.remove(a);runtime.assert(c,"file is not found: "+a);delete O[a]};this.state=n.LOADING;this.rootElement=function(a){var c=document.createElementNS(a.namespaceURI,a.localName),b;a=new a;for(b in a)a.hasOwnProperty(b)&&(c[b]=a[b]);return c}(q);Q=b?new core.Zip(b,function(a,c){Q=c;a?Y(b,function(c){a&& -(Q.error=a+"\n"+c,D(n.INVALID))}):R([["styles.xml",C],["content.xml",I],["meta.xml",z],["settings.xml",M],["META-INF/manifest.xml",H]])}):V()};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 35 +runtime.loadClass("core.Base64");runtime.loadClass("core.Zip");runtime.loadClass("xmldom.LSSerializer");runtime.loadClass("odf.StyleInfo");runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfNodeFilter");runtime.loadClass("odf.MetadataManager"); +odf.OdfContainer=function(){function g(a,b,c){for(a=a?a.firstChild:null;a;){if(a.localName===c&&a.namespaceURI===b)return a;a=a.nextSibling}return null}function l(a){var b,c=k.length;for(b=0;bc)break;d=d.nextSibling}a.insertBefore(b,d)}}}function n(a){this.OdfContainer= +a}function b(a,b,c,e){var d=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!==e&&(this.mimetype=b,e.loadAsDataURL(a,b,function(a,b){a&&runtime.log(a);d.url=b;if(d.onchange)d.onchange(d);if(d.onstatereadychange)d.onstatereadychange(d)}))}}var p=new odf.StyleInfo,r,d=odf.Namespaces.stylens,k="meta settings scripts font-face-decls styles automatic-styles master-styles body".split(" "), +a=(new Date).getTime()+"_webodf_",e=new core.Base64;n.prototype=new function(){};n.prototype.constructor=n;n.namespaceURI="urn:oasis:names:tc:opendocument:xmlns:office:1.0";n.localName="document";b.prototype.load=function(){};b.prototype.getUrl=function(){return this.data?"data:;base64,"+e.toBase64(this.data):null};odf.OdfContainer=function q(k,l){function v(a){for(var b=a.firstChild,c;b;)c=b.nextSibling,b.nodeType===Node.ELEMENT_NODE?v(b):b.nodeType===Node.PROCESSING_INSTRUCTION_NODE&&a.removeChild(b), +b=c}function y(a,b){for(var c=a&&a.firstChild;c;)c.nodeType===Node.ELEMENT_NODE&&c.setAttributeNS("urn:webodf:names:scope","scope",b),c=c.nextSibling}function w(a,b){function c(a,b,e){var d=0,f;for(f=a=a.replace(/\d+$/,"");b.hasOwnProperty(f)||e.hasOwnProperty(f);)d+=1,f=a+d;return f}function e(a){var b={};for(a=a.firstChild;a;)a.nodeType===Node.ELEMENT_NODE&&a.namespaceURI===d&&"font-face"===a.localName&&(g=a.getAttributeNS(d,"name"),b[g]=a),a=a.nextSibling;return b}var f,k,g,l,m,s,p={};m=e(a);s= +e(b);for(f=b.firstChild;f;)k=f.nextSibling,f.nodeType===Node.ELEMENT_NODE&&f.namespaceURI===d&&"font-face"===f.localName&&(g=f.getAttributeNS(d,"name"),m.hasOwnProperty(g)?f.isEqualNode(m[g])||(l=c(g,m,s),f.setAttributeNS(d,"style:name",l),a.appendChild(f),m[l]=f,delete s[g],p[g]=l):(a.appendChild(f),m[g]=f,delete s[g])),f=k;return p}function t(a,b){var c=null,e,d,f;if(a)for(c=a.cloneNode(!0),e=c.firstChild;e;)d=e.nextSibling,e.nodeType===Node.ELEMENT_NODE&&(f=e.getAttributeNS("urn:webodf:names:scope", +"scope"))&&f!==b&&c.removeChild(e),e=d;return c}function s(a,b){var c=null,e,f,k,g={};if(a)for(b.forEach(function(a){p.collectUsedFontFaces(g,a)}),c=a.cloneNode(!0),e=c.firstChild;e;)f=e.nextSibling,e.nodeType===Node.ELEMENT_NODE&&(k=e.getAttributeNS(d,"name"),g[k]||c.removeChild(e)),e=f;return c}function D(a){var b=N.rootElement.ownerDocument,c;if(a){v(a.documentElement);try{c=b.importNode(a.documentElement,!0)}catch(e){}}return c}function A(a){N.state=a;if(N.onchange)N.onchange(N);if(N.onstatereadychange)N.onstatereadychange(N)} +function B(a){ka=null;N.rootElement=a;a.fontFaceDecls=g(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls");a.styles=g(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles");a.automaticStyles=g(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles");a.masterStyles=g(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles");a.body=g(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");a.meta=g(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", +"meta")}function M(b){b=D(b);var c=N.rootElement;b&&"document-styles"===b.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===b.namespaceURI?(c.fontFaceDecls=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls"),f(c,c.fontFaceDecls),c.styles=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles"),f(c,c.styles),c.automaticStyles=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles"),y(c.automaticStyles,"document-styles"),f(c,c.automaticStyles), +c.masterStyles=g(b,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles"),f(c,c.masterStyles),p.prefixStyleNames(c.automaticStyles,a,c.masterStyles)):A(q.INVALID)}function z(a){a=D(a);var b,c,e;if(a&&"document-content"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI){b=N.rootElement;c=g(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls");b.fontFaceDecls&&c?e=w(b.fontFaceDecls,c):c&&(b.fontFaceDecls=c,f(b,c));c=g(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", +"automatic-styles");y(c,"document-content");e&&p.changeFontFaceNames(c,e);if(b.automaticStyles&&c)for(e=c.firstChild;e;)b.automaticStyles.appendChild(e),e=c.firstChild;else c&&(b.automaticStyles=c,f(b,c));b.body=g(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");f(b,b.body)}else A(q.INVALID)}function K(a){a=D(a);var b;a&&"document-meta"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&(b=N.rootElement,b.meta=g(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", +"meta"),f(b,b.meta),r=new odf.MetadataManager(b.meta))}function F(a){a=D(a);var b;a&&"document-settings"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&(b=N.rootElement,b.settings=g(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","settings"),f(b,b.settings))}function Q(a){a=D(a);var b;if(a&&"manifest"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"===a.namespaceURI)for(b=N.rootElement,b.manifest=a,a=b.manifest.firstChild;a;)a.nodeType=== +Node.ELEMENT_NODE&&"file-entry"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"===a.namespaceURI&&(Z[a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","full-path")]=a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","media-type")),a=a.nextSibling}function $(a){var b=a.shift(),c,e;b?(c=b[0],e=b[1],O.loadAsDOM(c,function(b,c){e(c);b||N.state===q.INVALID||$(a)})):A(q.DONE)}function ia(a){var b="";odf.Namespaces.forEachPrefix(function(a,c){b+= +" xmlns:"+a+'="'+c+'"'});return''}function R(){var a=new xmldom.LSSerializer,b=ia("document-meta");a.filter=new odf.OdfNodeFilter;b+=a.writeToString(N.rootElement.meta,odf.Namespaces.namespaceMap);return b+""}function ma(a,b){var c=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest:file-entry");c.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0", +"manifest:full-path",a);c.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest:media-type",b);return c}function ba(){var a=runtime.parseXML(''),b=g(a,"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest"),c=new xmldom.LSSerializer,e;for(e in Z)Z.hasOwnProperty(e)&&b.appendChild(ma(e,Z[e]));c.filter=new odf.OdfNodeFilter;return'\n'+ +c.writeToString(a,odf.Namespaces.namespaceMap)}function ga(){var a=new xmldom.LSSerializer,b=ia("document-settings");a.filter=new odf.OdfNodeFilter;b+=a.writeToString(N.rootElement.settings,odf.Namespaces.namespaceMap);return b+""}function S(){var b=odf.Namespaces.namespaceMap,e=new xmldom.LSSerializer,d,f,k,g=ia("document-styles");f=t(N.rootElement.automaticStyles,"document-styles");k=N.rootElement.masterStyles&&N.rootElement.masterStyles.cloneNode(!0);d=s(N.rootElement.fontFaceDecls, +[k,N.rootElement.styles,f]);p.removePrefixFromStyleNames(f,a,k);e.filter=new c(k,f);g+=e.writeToString(d,b);g+=e.writeToString(N.rootElement.styles,b);g+=e.writeToString(f,b);g+=e.writeToString(k,b);return g+""}function Y(){var a=odf.Namespaces.namespaceMap,b=new xmldom.LSSerializer,c,e,d=ia("document-content");e=t(N.rootElement.automaticStyles,"document-content");c=s(N.rootElement.fontFaceDecls,[e]);b.filter=new m(N.rootElement.body,e);d+=b.writeToString(c,a);d+=b.writeToString(e, +a);d+=b.writeToString(N.rootElement.body,a);return d+""}function V(a,b){runtime.loadXML(a,function(a,c){if(a)b(a);else{var e=D(c);e&&"document"===e.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===e.namespaceURI?(B(e),A(q.DONE)):A(q.INVALID)}})}function G(){function a(b,c){var d;c||(c=b);d=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0",c);e[b]=d;e.appendChild(d)}var b=new core.Zip("",null),c=runtime.byteArrayFromString("application/vnd.oasis.opendocument.text", +"utf8"),e=N.rootElement,d=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","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(d);r=new odf.MetadataManager(e.meta);A(q.DONE);return b}function I(){var a,b=new Date,c=runtime.getWindow();a="WebODF/"+("undefined"!==String(typeof webodf_version)?webodf_version: +"FromSource");c&&(a=a+" "+c.navigator.userAgent);r.setMetadata({"meta:generator":a});a=runtime.byteArrayFromString(ga(),"utf8");O.save("settings.xml",a,!0,b);a=runtime.byteArrayFromString(R(),"utf8");O.save("meta.xml",a,!0,b);a=runtime.byteArrayFromString(S(),"utf8");O.save("styles.xml",a,!0,b);a=runtime.byteArrayFromString(Y(),"utf8");O.save("content.xml",a,!0,b);a=runtime.byteArrayFromString(ba(),"utf8");O.save("META-INF/manifest.xml",a,!0,b)}function ha(a,b){I();O.writeAs(a,function(a){b(a)})} +var N=this,O,Z={},ka;this.onstatereadychange=l;this.rootElement=this.state=this.onchange=null;this.setRootElement=B;this.getContentElement=function(){var a;ka||(a=N.rootElement.body,ka=a.getElementsByTagNameNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","text")[0]||a.getElementsByTagNameNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","presentation")[0]||a.getElementsByTagNameNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","spreadsheet")[0]);return ka};this.getDocumentType=function(){var a= +N.getContentElement();return a&&a.localName};this.getMetadataManager=function(){return r};this.getPart=function(a){return new b(a,Z[a],N,O)};this.getPartData=function(a,b){O.load(a,b)};this.createByteArray=function(a,b){I();O.createByteArray(a,b)};this.saveAs=ha;this.save=function(a){ha(k,a)};this.getUrl=function(){return k};this.setBlob=function(a,b,c){c=e.convertBase64ToByteArray(c);O.save(a,c,!1,new Date);Z.hasOwnProperty(a)&&runtime.log(a+" has been overwritten.");Z[a]=b};this.removeBlob=function(a){var b= +O.remove(a);runtime.assert(b,"file is not found: "+a);delete Z[a]};this.state=q.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}(n);O=k?new core.Zip(k,function(a,b){O=b;a?V(k,function(b){a&&(O.error=a+"\n"+b,A(q.INVALID))}):$([["styles.xml",M],["content.xml",z],["meta.xml",K],["settings.xml",F],["META-INF/manifest.xml",Q]])}):G()};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 36 /* Copyright (C) 2012-2013 KO GmbH @@ -845,10 +876,10 @@ function(){return b};this.setBlob=function(a,b,d){d=c.convertBase64ToByteArray(d @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.Base64");runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.OdfContainer"); -odf.FontLoader=function(){function h(m,l,q,a,d){var f,b=0,k;for(k in m)if(m.hasOwnProperty(k)){if(b===q){f=k;break}b+=1}f?l.getPartData(m[f].href,function(c,b){if(c)runtime.log(c);else{var k="@font-face { font-family: '"+(m[f].family||f)+"'; src: url(data:application/x-font-ttf;charset=binary;base64,"+e.convertUTF8ArrayToBase64(b)+') format("truetype"); }';try{a.insertRule(k,a.cssRules.length)}catch(r){runtime.log("Problem inserting rule in CSS: "+runtime.toJson(r)+"\nRule: "+k)}}h(m,l,q+1,a,d)}): -d&&d()}var m=new xmldom.XPath,e=new core.Base64;odf.FontLoader=function(){this.loadFonts=function(e,l){for(var q=e.rootElement.fontFaceDecls;l.cssRules.length;)l.deleteRule(l.cssRules.length-1);if(q){var a={},d,f,b,k;if(q)for(q=m.getODFElementsWithXPath(q,"style:font-face[svg:font-face-src]",odf.Namespaces.resolvePrefix),d=0;d @@ -887,10 +918,10 @@ odf.Namespaces.resolvePrefix),0 @@ -929,21 +960,20 @@ c.getAttributeNS(a,"href");c=c.substring(9,c.lastIndexOf("."));n[c]=!0}),c=new e @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.Utils");runtime.loadClass("odf.ObjectNameGenerator");runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfContainer");runtime.loadClass("odf.StyleInfo");runtime.loadClass("odf.OdfUtils");runtime.loadClass("odf.TextStyleApplicator"); -odf.Formatting=function(){function h(){for(var a=k.rootElement.fontFaceDecls,c={},b,d,a=a&&a.firstChild;a;)a.nodeType===Node.ELEMENT_NODE&&(b=a.getAttributeNS(n,"name"))&&((d=a.getAttributeNS(g,"font-family"))||a.getElementsByTagNameNS(g,"font-face-uri")[0])&&(c[b]=d),a=a.nextSibling;return c}function m(a){for(var c=k.rootElement.styles.firstChild;c;){if(c.nodeType===Node.ELEMENT_NODE&&c.namespaceURI===n&&"default-style"===c.localName&&c.getAttributeNS(n,"family")===a)return c;c=c.nextSibling}return null} -function e(a,c,b){var d,g;b=b||[k.rootElement.automaticStyles,k.rootElement.styles];for(d=b.shift();d;){for(d=d.firstChild;d;){if(d.nodeType===Node.ELEMENT_NODE&&(g=d.getAttributeNS(n,"name"),d.namespaceURI===n&&"style"===d.localName&&d.getAttributeNS(n,"family")===c&&g===a||"list-style"===c&&d.namespaceURI===r&&"list-style"===d.localName&&g===a||"data"===c&&d.namespaceURI===u&&g===a))return d;d=d.nextSibling}d=b.shift()}return null}function p(a){for(var c,b={},d=a.firstChild;d;){if(d.nodeType=== -Node.ELEMENT_NODE&&d.namespaceURI===n)for(b[d.nodeName]={},c=0;c @@ -982,40 +1012,67 @@ d&&(g=d.getAttributeNS(n,"print-orientation")||"portrait","portrait"===g?(g=21.0 @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils");runtime.loadClass("odf.OdfContainer");runtime.loadClass("odf.Formatting");runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.FontLoader");runtime.loadClass("odf.Style2CSS");runtime.loadClass("odf.OdfUtils");runtime.loadClass("gui.AnnotationViewManager"); -odf.OdfCanvas=function(){function h(){function a(d){b=!0;runtime.setTimeout(function(){try{d()}catch(g){runtime.log(g)}b=!1;0 text|list-item > *:first-child:before {";if(F=K.getAttributeNS(I, -"style-name"))K=w[F],G=ja.getFirstNonWhitespaceChild(K),K=void 0,G&&("list-level-style-number"===G.localName?(K=G.getAttributeNS(D,"num-format"),F=G.getAttributeNS(D,"num-suffix"),N="",N={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},L=void 0,L=G.getAttributeNS(D,"num-prefix")||"",L=N.hasOwnProperty(K)?L+(" counter(list, "+N[K]+")"):K?L+("'"+K+"';"):L+" ''",F&&(L+=" '"+F+"'"),K=N="content: "+L+";"):"list-level-style-image"===G.localName?K="content: none;":"list-level-style-bullet"=== -G.localName&&(K="content: '"+G.getAttributeNS(I,"bullet-char")+"';")),G=K;if(E){for(K=x[E];K;)E=K,K=x[E];B+="counter-increment:"+E+";";G?(G=G.replace("list",E),B+=G):B+="content:counter("+E+");"}else E="",G?(G=G.replace("list",z),B+=G):B+="content: counter("+z+");",B+="counter-increment:"+z+";",l.insertRule("text|list#"+z+" {counter-reset:"+z+"}",l.cssRules.length);B+="}";x[z]=E;B&&l.insertRule(B,l.cssRules.length)}T.insertBefore(fa,T.firstChild);A();V(h);if(!c&&(h=[O],ha.hasOwnProperty("statereadychange")))for(l= -ha.statereadychange,G=0;G text|list-item > *:first-child:before {";if(E=J.getAttributeNS(M, +"style-name"))J=x[E],G=ia.getFirstNonWhitespaceChild(J),J=void 0,G&&("list-level-style-number"===G.localName?(J=G.getAttributeNS(D,"num-format"),E=G.getAttributeNS(D,"num-suffix"),I="",I={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},L=void 0,L=G.getAttributeNS(D,"num-prefix")||"",L=I.hasOwnProperty(J)?L+(" counter(list, "+I[J]+")"):J?L+("'"+J+"';"):L+" ''",E&&(L+=" '"+E+"'"),J=I="content: "+L+";"):"list-level-style-image"===G.localName?J="content: none;":"list-level-style-bullet"=== +G.localName&&(J="content: '"+G.getAttributeNS(M,"bullet-char")+"';")),G=J;if(R){for(J=v[R];J;)R=J,J=v[R];C+="counter-increment:"+R+";";G?(G=G.replace("list",R),C+=G):C+="content:counter("+R+");"}else R="",G?(G=G.replace("list",z),C+=G):C+="content: counter("+z+");",C+="counter-increment:"+z+";",g.insertRule("text|list#"+z+" {counter-reset:"+z+"}",g.cssRules.length);C+="}";v[z]=R;C&&g.insertRule(C,g.cssRules.length)}T.insertBefore(fa,T.firstChild);A();V(f);if(!a&&(f=[O],ja.hasOwnProperty("statereadychange")))for(g= +ja.statereadychange,G=0;G + + @licstart + This file is part of WebODF. + + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +ops.Member=function(g,l){var c={};this.getMemberId=function(){return g};this.getProperties=function(){return c};this.setProperties=function(g){Object.keys(g).forEach(function(f){c[f]=g[f]})};this.removeProperties=function(g){delete g.fullName;delete g.color;delete g.imageUrl;Object.keys(g).forEach(function(f){c.hasOwnProperty(f)&&delete c[f]})};runtime.assert(Boolean(g),"No memberId was supplied!");l.fullName||(l.fullName=runtime.tr("Unknown Author"));l.color||(l.color="black");l.imageUrl||(l.imageUrl= +"avatar-joe.png");c=l}; +// Input 42 /* Copyright (C) 2013 KO GmbH @@ -1053,8 +1110,8 @@ odf.CommandLineTools=function(){this.roundTrip=function(h,m,e){return new odf.Od @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.Server=function(){};ops.Server.prototype.connect=function(h,m){};ops.Server.prototype.networkStatus=function(){};ops.Server.prototype.login=function(h,m,e,p){};ops.Server.prototype.joinSession=function(h,m,e,p){};ops.Server.prototype.leaveSession=function(h,m,e,p){};ops.Server.prototype.getGenesisUrl=function(h){}; -// Input 41 +ops.Server=function(){};ops.Server.prototype.connect=function(g,l){};ops.Server.prototype.networkStatus=function(){};ops.Server.prototype.login=function(g,l,c,m){};ops.Server.prototype.joinSession=function(g,l,c,m){};ops.Server.prototype.leaveSession=function(g,l,c,m){};ops.Server.prototype.getGenesisUrl=function(g){}; +// Input 43 /* Copyright (C) 2012-2013 KO GmbH @@ -1092,8 +1149,8 @@ ops.Server=function(){};ops.Server.prototype.connect=function(h,m){};ops.Server. @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.Operation=function(){};ops.Operation.prototype.init=function(h){};ops.Operation.prototype.execute=function(h){};ops.Operation.prototype.spec=function(){}; -// Input 42 +ops.Operation=function(){};ops.Operation.prototype.init=function(g){};ops.Operation.prototype.execute=function(g){};ops.Operation.prototype.spec=function(){}; +// Input 44 /* Copyright (C) 2012-2013 KO GmbH @@ -1131,8 +1188,8 @@ ops.Operation=function(){};ops.Operation.prototype.init=function(h){};ops.Operat @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpAddCursor=function(){var h,m;this.init=function(e){h=e.memberid;m=e.timestamp};this.execute=function(e){var m=e.getCursor(h);if(m)return!1;m=new ops.OdtCursor(h,e);e.addCursor(m);e.emit(ops.OdtDocument.signalCursorAdded,m);return!0};this.spec=function(){return{optype:"AddCursor",memberid:h,timestamp:m}}}; -// Input 43 +ops.OpAddCursor=function(){var g,l;this.init=function(c){g=c.memberid;l=c.timestamp};this.isEdit=!1;this.execute=function(c){var l=c.getCursor(g);if(l)return!1;l=new ops.OdtCursor(g,c);c.addCursor(l);c.emit(ops.OdtDocument.signalCursorAdded,l);return!0};this.spec=function(){return{optype:"AddCursor",memberid:g,timestamp:l}}}; +// Input 45 /* Copyright (C) 2012-2013 KO GmbH @@ -1171,11 +1228,11 @@ ops.OpAddCursor=function(){var h,m;this.init=function(e){h=e.memberid;m=e.timest @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils");runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfUtils"); -gui.StyleHelper=function(h){function m(a,d,f){var b=!0,e;for(e=0;e @@ -1214,9 +1271,9 @@ this.isBold=function(a){return m(a,"fo:font-weight","bold")};this.isItalic=funct @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("gui.StyleHelper");runtime.loadClass("odf.OdfUtils"); -ops.OpApplyDirectStyling=function(){function h(a){var f=0<=l?p+l:p,b=a.getIteratorAtPosition(0<=l?p:p+l),f=l?a.getIteratorAtPosition(f):b;a=a.getDOM().createRange();a.setStart(b.container(),b.unfilteredDomOffset());a.setEnd(f.container(),f.unfilteredDomOffset());return a}var m,e,p,l,q,a=new odf.OdfUtils;this.init=function(a){m=a.memberid;e=a.timestamp;p=parseInt(a.position,10);l=parseInt(a.length,10);q=a.setProperties};this.execute=function(d){var f=h(d),b=a.getImpactedParagraphs(f);(new gui.StyleHelper(d.getFormatting())).applyStyle(m, -f,q);f.detach();d.getOdfCanvas().refreshCSS();d.fixCursorPositions();b.forEach(function(a){d.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a,memberId:m,timeStamp:e})});d.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"ApplyDirectStyling",memberid:m,timestamp:e,position:p,length:l,setProperties:q}}}; -// Input 45 +ops.OpApplyDirectStyling=function(){function g(b){var c=0<=f?m+f:m,d=b.getIteratorAtPosition(0<=f?m:m+f),c=f?b.getIteratorAtPosition(c):d;b=b.getDOM().createRange();b.setStart(d.container(),d.unfilteredDomOffset());b.setEnd(c.container(),c.unfilteredDomOffset());return b}var l,c,m,f,n,b=new odf.OdfUtils;this.init=function(b){l=b.memberid;c=b.timestamp;m=parseInt(b.position,10);f=parseInt(b.length,10);n=b.setProperties};this.isEdit=!0;this.execute=function(f){var m=g(f),d=b.getImpactedParagraphs(m); +(new gui.StyleHelper(f.getFormatting())).applyStyle(l,m,n);m.detach();f.getOdfCanvas().refreshCSS();f.fixCursorPositions();d.forEach(function(b){f.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:b,memberId:l,timeStamp:c})});f.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"ApplyDirectStyling",memberid:l,timestamp:c,position:m,length:f,setProperties:n}}}; +// Input 47 /* Copyright (C) 2012-2013 KO GmbH @@ -1254,8 +1311,8 @@ f,q);f.detach();d.getOdfCanvas().refreshCSS();d.fixCursorPositions();b.forEach(f @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpRemoveCursor=function(){var h,m;this.init=function(e){h=e.memberid;m=e.timestamp};this.execute=function(e){return e.removeCursor(h)?!0:!1};this.spec=function(){return{optype:"RemoveCursor",memberid:h,timestamp:m}}}; -// Input 46 +ops.OpRemoveCursor=function(){var g,l;this.init=function(c){g=c.memberid;l=c.timestamp};this.isEdit=!1;this.execute=function(c){return c.removeCursor(g)?!0:!1};this.spec=function(){return{optype:"RemoveCursor",memberid:g,timestamp:l}}}; +// Input 48 /* Copyright (C) 2012-2013 KO GmbH @@ -1293,8 +1350,8 @@ ops.OpRemoveCursor=function(){var h,m;this.init=function(e){h=e.memberid;m=e.tim @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpMoveCursor=function(){var h,m,e,p,l;this.init=function(q){h=q.memberid;m=q.timestamp;e=q.position;p=q.length||0;l=q.selectionType||ops.OdtCursor.RangeSelection};this.execute=function(m){var a=m.getCursor(h),d;if(!a)return!1;d=m.convertCursorToDomRange(e,p);a.setSelectedRange(d,0<=p);a.setSelectionType(l);m.emit(ops.OdtDocument.signalCursorMoved,a);return!0};this.spec=function(){return{optype:"MoveCursor",memberid:h,timestamp:m,position:e,length:p,selectionType:l}}}; -// Input 47 +ops.OpMoveCursor=function(){var g,l,c,m,f;this.init=function(n){g=n.memberid;l=n.timestamp;c=n.position;m=n.length||0;f=n.selectionType||ops.OdtCursor.RangeSelection};this.isEdit=!1;this.execute=function(l){var b=l.getCursor(g),p;if(!b)return!1;p=l.convertCursorToDomRange(c,m);b.setSelectedRange(p,0<=m);b.setSelectionType(f);l.emit(ops.OdtDocument.signalCursorMoved,b);return!0};this.spec=function(){return{optype:"MoveCursor",memberid:g,timestamp:l,position:c,length:m,selectionType:f}}}; +// Input 49 /* Copyright (C) 2012-2013 KO GmbH @@ -1332,8 +1389,8 @@ ops.OpMoveCursor=function(){var h,m,e,p,l;this.init=function(q){h=q.memberid;m=q @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpSetBlob=function(){var h,m,e,p,l;this.init=function(q){h=q.memberid;m=q.timestamp;e=q.filename;p=q.mimetype;l=q.content};this.execute=function(h){h.getOdfCanvas().odfContainer().setBlob(e,p,l);return!0};this.spec=function(){return{optype:"SetBlob",memberid:h,timestamp:m,filename:e,mimetype:p,content:l}}}; -// Input 48 +ops.OpSetBlob=function(){var g,l,c,m,f;this.init=function(n){g=n.memberid;l=n.timestamp;c=n.filename;m=n.mimetype;f=n.content};this.isEdit=!0;this.execute=function(g){g.getOdfCanvas().odfContainer().setBlob(c,m,f);return!0};this.spec=function(){return{optype:"SetBlob",memberid:g,timestamp:l,filename:c,mimetype:m,content:f}}}; +// Input 50 /* Copyright (C) 2012-2013 KO GmbH @@ -1371,8 +1428,8 @@ ops.OpSetBlob=function(){var h,m,e,p,l;this.init=function(q){h=q.memberid;m=q.ti @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpRemoveBlob=function(){var h,m,e;this.init=function(p){h=p.memberid;m=p.timestamp;e=p.filename};this.execute=function(h){h.getOdfCanvas().odfContainer().removeBlob(e);return!0};this.spec=function(){return{optype:"RemoveBlob",memberid:h,timestamp:m,filename:e}}}; -// Input 49 +ops.OpRemoveBlob=function(){var g,l,c;this.init=function(m){g=m.memberid;l=m.timestamp;c=m.filename};this.isEdit=!0;this.execute=function(g){g.getOdfCanvas().odfContainer().removeBlob(c);return!0};this.spec=function(){return{optype:"RemoveBlob",memberid:g,timestamp:l,filename:c}}}; +// Input 51 /* Copyright (C) 2012-2013 KO GmbH @@ -1410,10 +1467,10 @@ ops.OpRemoveBlob=function(){var h,m,e;this.init=function(p){h=p.memberid;m=p.tim @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpInsertImage=function(){var h,m,e,p,l,q,a,d,f=odf.Namespaces.drawns,b=odf.Namespaces.svgns,k=odf.Namespaces.textns,c=odf.Namespaces.xlinkns;this.init=function(c){h=c.memberid;m=c.timestamp;e=c.position;p=c.filename;l=c.frameWidth;q=c.frameHeight;a=c.frameStyleName;d=c.frameName};this.execute=function(g){var n=g.getOdfCanvas(),r=g.getTextNodeAtStep(e,h),u,y;if(!r)return!1;u=r.textNode;y=g.getParagraphElement(u);var r=r.offset!==u.length?u.splitText(r.offset):u.nextSibling,x=g.getDOM(),w=x.createElementNS(f, -"draw:image"),x=x.createElementNS(f,"draw:frame");w.setAttributeNS(c,"xlink:href",p);w.setAttributeNS(c,"xlink:type","simple");w.setAttributeNS(c,"xlink:show","embed");w.setAttributeNS(c,"xlink:actuate","onLoad");x.setAttributeNS(f,"draw:style-name",a);x.setAttributeNS(f,"draw:name",d);x.setAttributeNS(k,"text:anchor-type","as-char");x.setAttributeNS(b,"svg:width",l);x.setAttributeNS(b,"svg:height",q);x.appendChild(w);u.parentNode.insertBefore(x,r);g.emit(ops.OdtDocument.signalStepsInserted,{position:e, -length:1});0===u.length&&u.parentNode.removeChild(u);n.addCssForFrameWithImage(x);n.refreshCSS();g.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:y,memberId:h,timeStamp:m});n.rerenderAnnotations();return!0};this.spec=function(){return{optype:"InsertImage",memberid:h,timestamp:m,filename:p,position:e,frameWidth:l,frameHeight:q,frameStyleName:a,frameName:d}}}; -// Input 50 +ops.OpInsertImage=function(){var g,l,c,m,f,n,b,p,r=odf.Namespaces.drawns,d=odf.Namespaces.svgns,k=odf.Namespaces.textns,a=odf.Namespaces.xlinkns;this.init=function(a){g=a.memberid;l=a.timestamp;c=a.position;m=a.filename;f=a.frameWidth;n=a.frameHeight;b=a.frameStyleName;p=a.frameName};this.isEdit=!0;this.execute=function(e){var h=e.getOdfCanvas(),q=e.getTextNodeAtStep(c,g),u,x;if(!q)return!1;u=q.textNode;x=e.getParagraphElement(u);var q=q.offset!==u.length?u.splitText(q.offset):u.nextSibling,v=e.getDOM(), +y=v.createElementNS(r,"draw:image"),v=v.createElementNS(r,"draw:frame");y.setAttributeNS(a,"xlink:href",m);y.setAttributeNS(a,"xlink:type","simple");y.setAttributeNS(a,"xlink:show","embed");y.setAttributeNS(a,"xlink:actuate","onLoad");v.setAttributeNS(r,"draw:style-name",b);v.setAttributeNS(r,"draw:name",p);v.setAttributeNS(k,"text:anchor-type","as-char");v.setAttributeNS(d,"svg:width",f);v.setAttributeNS(d,"svg:height",n);v.appendChild(y);u.parentNode.insertBefore(v,q);e.emit(ops.OdtDocument.signalStepsInserted, +{position:c,length:1});0===u.length&&u.parentNode.removeChild(u);h.addCssForFrameWithImage(v);h.refreshCSS();e.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:x,memberId:g,timeStamp:l});h.rerenderAnnotations();return!0};this.spec=function(){return{optype:"InsertImage",memberid:g,timestamp:l,filename:m,position:c,frameWidth:f,frameHeight:n,frameStyleName:b,frameName:p}}}; +// Input 52 /* Copyright (C) 2013 KO GmbH @@ -1451,12 +1508,12 @@ length:1});0===u.length&&u.parentNode.removeChild(u);n.addCssForFrameWithImage(x @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpInsertTable=function(){function h(a,c){var d;if(1===b.length)d=b[0];else if(3===b.length)switch(a){case 0:d=b[0];break;case p-1:d=b[2];break;default:d=b[1]}else d=b[a];if(1===d.length)return d[0];if(3===d.length)switch(c){case 0:return d[0];case l-1:return d[2];default:return d[1]}return d[c]}var m,e,p,l,q,a,d,f,b;this.init=function(k){m=k.memberid;e=k.timestamp;q=k.position;p=k.initialRows;l=k.initialColumns;a=k.tableName;d=k.tableStyleName;f=k.tableColumnStyleName;b=k.tableCellStyleMatrix}; -this.execute=function(b){var c=b.getTextNodeAtStep(q),g=b.getRootNode();if(c){var n=b.getDOM(),r=n.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table"),u=n.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table-column"),y,x,w,v;d&&r.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:style-name",d);a&&r.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:name",a);u.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0", -"table:number-columns-repeated",l);f&&u.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:style-name",f);r.appendChild(u);for(w=0;w @@ -1494,10 +1551,10 @@ tableColumnStyleName:f,tableCellStyleMatrix:b}}}; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpInsertText=function(){var h,m,e,p;this.init=function(l){h=l.memberid;m=l.timestamp;e=l.position;p=l.text};this.execute=function(l){var q,a,d,f=null,b=l.getDOM(),k,c=0,g,n;l.upgradeWhitespacesAtPosition(e);if(q=l.getTextNodeAtStep(e,h)){a=q.textNode;f=a.nextSibling;d=a.parentNode;k=l.getParagraphElement(a);for(n=0;n @@ -1536,12 +1593,12 @@ p.substring(c,n),d.insertBefore(b.createTextNode(c),f)),c=n+1,g=" "===p[n]?"text @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfUtils");runtime.loadClass("core.DomUtils"); -ops.OpRemoveText=function(){function h(f){function b(a){return d.hasOwnProperty(a.namespaceURI)||"br"===a.localName&&q.isLineBreak(a.parentNode)||a.nodeType===Node.TEXT_NODE&&d.hasOwnProperty(a.parentNode.namespaceURI)}function e(a){if(q.isCharacterElement(a))return!1;if(a.nodeType===Node.TEXT_NODE)return 0===a.textContent.length;for(a=a.firstChild;a;){if(d.hasOwnProperty(a.namespaceURI)||!e(a))return!1;a=a.nextSibling}return!0}function c(d){var h;d.nodeType===Node.TEXT_NODE?(h=d.parentNode,h.removeChild(d)): -h=a.removeUnwantedNodes(d,b);return!q.isParagraph(h)&&h!==f&&e(h)?c(h):h}this.isEmpty=e;this.mergeChildrenIntoParent=c}var m,e,p,l,q,a,d={};this.init=function(f){runtime.assert(0<=f.length,"OpRemoveText only supports positive lengths");m=f.memberid;e=f.timestamp;p=parseInt(f.position,10);l=parseInt(f.length,10);q=new odf.OdfUtils;a=new core.DomUtils;d[odf.Namespaces.dbns]=!0;d[odf.Namespaces.dcns]=!0;d[odf.Namespaces.dr3dns]=!0;d[odf.Namespaces.drawns]=!0;d[odf.Namespaces.chartns]=!0;d[odf.Namespaces.formns]= -!0;d[odf.Namespaces.numberns]=!0;d[odf.Namespaces.officens]=!0;d[odf.Namespaces.presentationns]=!0;d[odf.Namespaces.stylens]=!0;d[odf.Namespaces.svgns]=!0;d[odf.Namespaces.tablens]=!0;d[odf.Namespaces.textns]=!0};this.execute=function(d){var b,k,c,g,n=d.getCursor(m),r=new h(d.getRootNode());d.upgradeWhitespacesAtPosition(p);d.upgradeWhitespacesAtPosition(p+l);k=d.convertCursorToDomRange(p,l);a.splitBoundaries(k);b=d.getParagraphElement(k.startContainer);c=q.getTextElements(k,!1,!0);g=q.getParagraphElements(k); -k.detach();c.forEach(function(a){r.mergeChildrenIntoParent(a)});k=g.reduce(function(a,c){var b,d=!1,g=a,f=c,e,k=null;r.isEmpty(a)&&(d=!0,c.parentNode!==a.parentNode&&(e=c.parentNode,a.parentNode.insertBefore(c,a.nextSibling)),f=a,g=c,k=g.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo")[0]||g.firstChild);for(;f.hasChildNodes();)b=d?f.lastChild:f.firstChild,f.removeChild(b),"editinfo"!==b.localName&&g.insertBefore(b,k);e&&r.isEmpty(e)&&r.mergeChildrenIntoParent(e);r.mergeChildrenIntoParent(f); -return g});d.emit(ops.OdtDocument.signalStepsRemoved,{position:p,length:l});d.downgradeWhitespacesAtPosition(p);d.fixCursorPositions();d.getOdfCanvas().refreshSize();d.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:k||b,memberId:m,timeStamp:e});n&&(n.resetSelectionType(),d.emit(ops.OdtDocument.signalCursorMoved,n));d.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"RemoveText",memberid:m,timestamp:e,position:p,length:l}}}; -// Input 53 +ops.OpRemoveText=function(){function g(c){function d(a){return p.hasOwnProperty(a.namespaceURI)||"br"===a.localName&&n.isLineBreak(a.parentNode)||a.nodeType===Node.TEXT_NODE&&p.hasOwnProperty(a.parentNode.namespaceURI)}function f(a){if(n.isCharacterElement(a))return!1;if(a.nodeType===Node.TEXT_NODE)return 0===a.textContent.length;for(a=a.firstChild;a;){if(p.hasOwnProperty(a.namespaceURI)||!f(a))return!1;a=a.nextSibling}return!0}function a(e){var h;e.nodeType===Node.TEXT_NODE?(h=e.parentNode,h.removeChild(e)): +h=b.removeUnwantedNodes(e,d);return!n.isParagraph(h)&&h!==c&&f(h)?a(h):h}this.isEmpty=f;this.mergeChildrenIntoParent=a}var l,c,m,f,n,b,p={};this.init=function(g){runtime.assert(0<=g.length,"OpRemoveText only supports positive lengths");l=g.memberid;c=g.timestamp;m=parseInt(g.position,10);f=parseInt(g.length,10);n=new odf.OdfUtils;b=new core.DomUtils;p[odf.Namespaces.dbns]=!0;p[odf.Namespaces.dcns]=!0;p[odf.Namespaces.dr3dns]=!0;p[odf.Namespaces.drawns]=!0;p[odf.Namespaces.chartns]=!0;p[odf.Namespaces.formns]= +!0;p[odf.Namespaces.numberns]=!0;p[odf.Namespaces.officens]=!0;p[odf.Namespaces.presentationns]=!0;p[odf.Namespaces.stylens]=!0;p[odf.Namespaces.svgns]=!0;p[odf.Namespaces.tablens]=!0;p[odf.Namespaces.textns]=!0};this.isEdit=!0;this.execute=function(p){var d,k,a,e,h=p.getCursor(l),q=new g(p.getRootNode());p.upgradeWhitespacesAtPosition(m);p.upgradeWhitespacesAtPosition(m+f);k=p.convertCursorToDomRange(m,f);b.splitBoundaries(k);d=p.getParagraphElement(k.startContainer);a=n.getTextElements(k,!1,!0); +e=n.getParagraphElements(k);k.detach();a.forEach(function(a){q.mergeChildrenIntoParent(a)});k=e.reduce(function(a,b){var c,e=!1,d=a,h=b,f,k=null;q.isEmpty(a)&&(e=!0,b.parentNode!==a.parentNode&&(f=b.parentNode,a.parentNode.insertBefore(b,a.nextSibling)),h=a,d=b,k=d.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo")[0]||d.firstChild);for(;h.hasChildNodes();)c=e?h.lastChild:h.firstChild,h.removeChild(c),"editinfo"!==c.localName&&d.insertBefore(c,k);f&&q.isEmpty(f)&&q.mergeChildrenIntoParent(f); +q.mergeChildrenIntoParent(h);return d});p.emit(ops.OdtDocument.signalStepsRemoved,{position:m,length:f});p.downgradeWhitespacesAtPosition(m);p.fixCursorPositions();p.getOdfCanvas().refreshSize();p.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:k||d,memberId:l,timeStamp:c});h&&(h.resetSelectionType(),p.emit(ops.OdtDocument.signalCursorMoved,h));p.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"RemoveText",memberid:l,timestamp:c,position:m,length:f}}}; +// Input 55 /* Copyright (C) 2012-2013 KO GmbH @@ -1579,10 +1636,10 @@ return g});d.emit(ops.OdtDocument.signalStepsRemoved,{position:p,length:l});d.do @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpSplitParagraph=function(){var h,m,e,p;this.init=function(l){h=l.memberid;m=l.timestamp;e=l.position;p=new odf.OdfUtils};this.execute=function(l){var q,a,d,f,b,k,c;l.upgradeWhitespacesAtPosition(e);q=l.getTextNodeAtStep(e,h);if(!q)return!1;a=l.getParagraphElement(q.textNode);if(!a)return!1;d=p.isListItem(a.parentNode)?a.parentNode:a;0===q.offset?(c=q.textNode.previousSibling,k=null):(c=q.textNode,k=q.offset>=q.textNode.length?null:q.textNode.splitText(q.offset));for(f=q.textNode;f!==d;){f=f.parentNode; -b=f.cloneNode(!1);k&&b.appendChild(k);if(c)for(;c&&c.nextSibling;)b.appendChild(c.nextSibling);else for(;f.firstChild;)b.appendChild(f.firstChild);f.parentNode.insertBefore(b,f.nextSibling);c=f;k=b}p.isListItem(k)&&(k=k.childNodes[0]);0===q.textNode.length&&q.textNode.parentNode.removeChild(q.textNode);l.emit(ops.OdtDocument.signalStepsInserted,{position:e,length:1});l.fixCursorPositions();l.getOdfCanvas().refreshSize();l.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a,memberId:h, -timeStamp:m});l.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:k,memberId:h,timeStamp:m});l.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"SplitParagraph",memberid:h,timestamp:m,position:e}}}; -// Input 54 +ops.OpSplitParagraph=function(){var g,l,c,m;this.init=function(f){g=f.memberid;l=f.timestamp;c=f.position;m=new odf.OdfUtils};this.isEdit=!0;this.execute=function(f){var n,b,p,r,d,k,a;f.upgradeWhitespacesAtPosition(c);n=f.getTextNodeAtStep(c,g);if(!n)return!1;b=f.getParagraphElement(n.textNode);if(!b)return!1;p=m.isListItem(b.parentNode)?b.parentNode:b;0===n.offset?(a=n.textNode.previousSibling,k=null):(a=n.textNode,k=n.offset>=n.textNode.length?null:n.textNode.splitText(n.offset));for(r=n.textNode;r!== +p;){r=r.parentNode;d=r.cloneNode(!1);k&&d.appendChild(k);if(a)for(;a&&a.nextSibling;)d.appendChild(a.nextSibling);else for(;r.firstChild;)d.appendChild(r.firstChild);r.parentNode.insertBefore(d,r.nextSibling);a=r;k=d}m.isListItem(k)&&(k=k.childNodes[0]);0===n.textNode.length&&n.textNode.parentNode.removeChild(n.textNode);f.emit(ops.OdtDocument.signalStepsInserted,{position:c,length:1});f.fixCursorPositions();f.getOdfCanvas().refreshSize();f.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:b, +memberId:g,timeStamp:l});f.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:k,memberId:g,timeStamp:l});f.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"SplitParagraph",memberid:g,timestamp:l,position:c}}}; +// Input 56 /* Copyright (C) 2012-2013 KO GmbH @@ -1620,9 +1677,9 @@ timeStamp:m});l.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:k, @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpSetParagraphStyle=function(){var h,m,e,p;this.init=function(l){h=l.memberid;m=l.timestamp;e=l.position;p=l.styleName};this.execute=function(l){var q;q=l.getIteratorAtPosition(e);return(q=l.getParagraphElement(q.container()))?(""!==p?q.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","text:style-name",p):q.removeAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","style-name"),l.getOdfCanvas().refreshSize(),l.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:q, -timeStamp:m,memberId:h}),l.getOdfCanvas().rerenderAnnotations(),!0):!1};this.spec=function(){return{optype:"SetParagraphStyle",memberid:h,timestamp:m,position:e,styleName:p}}}; -// Input 55 +ops.OpSetParagraphStyle=function(){var g,l,c,m;this.init=function(f){g=f.memberid;l=f.timestamp;c=f.position;m=f.styleName};this.isEdit=!0;this.execute=function(f){var n;n=f.getIteratorAtPosition(c);return(n=f.getParagraphElement(n.container()))?(""!==m?n.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","text:style-name",m):n.removeAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","style-name"),f.getOdfCanvas().refreshSize(),f.emit(ops.OdtDocument.signalParagraphChanged, +{paragraphElement:n,timeStamp:l,memberId:g}),f.getOdfCanvas().rerenderAnnotations(),!0):!1};this.spec=function(){return{optype:"SetParagraphStyle",memberid:g,timestamp:l,position:c,styleName:m}}}; +// Input 57 /* Copyright (C) 2012-2013 KO GmbH @@ -1661,10 +1718,10 @@ timeStamp:m,memberId:h}),l.getOdfCanvas().rerenderAnnotations(),!0):!1};this.spe @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.Namespaces"); -ops.OpUpdateParagraphStyle=function(){function h(a,f){var b,e,c=f?f.split(","):[];for(b=0;b @@ -1703,9 +1760,9 @@ memberid:m,timestamp:e,styleName:p,setProperties:l,removedProperties:q}}}; @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.Namespaces"); -ops.OpAddStyle=function(){var h,m,e,p,l,q,a=odf.Namespaces.stylens;this.init=function(a){h=a.memberid;m=a.timestamp;e=a.styleName;p=a.styleFamily;l="true"===a.isAutomaticStyle||!0===a.isAutomaticStyle;q=a.setProperties};this.execute=function(d){var f=d.getOdfCanvas().odfContainer(),b=d.getFormatting(),h=d.getDOM().createElementNS(a,"style:style");if(!h)return!1;q&&b.updateStyle(h,q);h.setAttributeNS(a,"style:family",p);h.setAttributeNS(a,"style:name",e);l?f.rootElement.automaticStyles.appendChild(h):f.rootElement.styles.appendChild(h); -d.getOdfCanvas().refreshCSS();l||d.emit(ops.OdtDocument.signalCommonStyleCreated,{name:e,family:p});return!0};this.spec=function(){return{optype:"AddStyle",memberid:h,timestamp:m,styleName:e,styleFamily:p,isAutomaticStyle:l,setProperties:q}}}; -// Input 57 +ops.OpAddStyle=function(){var g,l,c,m,f,n,b=odf.Namespaces.stylens;this.init=function(b){g=b.memberid;l=b.timestamp;c=b.styleName;m=b.styleFamily;f="true"===b.isAutomaticStyle||!0===b.isAutomaticStyle;n=b.setProperties};this.isEdit=!0;this.execute=function(g){var l=g.getOdfCanvas().odfContainer(),d=g.getFormatting(),k=g.getDOM().createElementNS(b,"style:style");if(!k)return!1;n&&d.updateStyle(k,n);k.setAttributeNS(b,"style:family",m);k.setAttributeNS(b,"style:name",c);f?l.rootElement.automaticStyles.appendChild(k): +l.rootElement.styles.appendChild(k);g.getOdfCanvas().refreshCSS();f||g.emit(ops.OdtDocument.signalCommonStyleCreated,{name:c,family:m});return!0};this.spec=function(){return{optype:"AddStyle",memberid:g,timestamp:l,styleName:c,styleFamily:m,isAutomaticStyle:f,setProperties:n}}}; +// Input 59 /* Copyright (C) 2012-2013 KO GmbH @@ -1743,8 +1800,8 @@ d.getOdfCanvas().refreshCSS();l||d.emit(ops.OdtDocument.signalCommonStyleCreated @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpRemoveStyle=function(){var h,m,e,p;this.init=function(l){h=l.memberid;m=l.timestamp;e=l.styleName;p=l.styleFamily};this.execute=function(h){var m=h.getStyleElement(e,p);if(!m)return!1;m.parentNode.removeChild(m);h.getOdfCanvas().refreshCSS();h.emit(ops.OdtDocument.signalCommonStyleDeleted,{name:e,family:p});return!0};this.spec=function(){return{optype:"RemoveStyle",memberid:h,timestamp:m,styleName:e,styleFamily:p}}}; -// Input 58 +ops.OpRemoveStyle=function(){var g,l,c,m;this.init=function(f){g=f.memberid;l=f.timestamp;c=f.styleName;m=f.styleFamily};this.isEdit=!0;this.execute=function(f){var g=f.getStyleElement(c,m);if(!g)return!1;g.parentNode.removeChild(g);f.getOdfCanvas().refreshCSS();f.emit(ops.OdtDocument.signalCommonStyleDeleted,{name:c,family:m});return!0};this.spec=function(){return{optype:"RemoveStyle",memberid:g,timestamp:l,styleName:c,styleFamily:m}}}; +// Input 60 /* Copyright (C) 2012-2013 KO GmbH @@ -1782,11 +1839,11 @@ ops.OpRemoveStyle=function(){var h,m,e,p;this.init=function(l){h=l.memberid;m=l. @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OpAddAnnotation=function(){function h(a,d,f){var b=a.getTextNodeAtStep(f,m);b&&(a=b.textNode,f=a.parentNode,b.offset!==a.length&&a.splitText(b.offset),f.insertBefore(d,a.nextSibling),0===a.length&&f.removeChild(a))}var m,e,p,l,q;this.init=function(a){m=a.memberid;e=parseInt(a.timestamp,10);p=parseInt(a.position,10);l=parseInt(a.length,10)||0;q=a.name};this.execute=function(a){var d={},f=a.getPositionFilter(),b=a.getCursor(m),k=a.getCursorPosition(m),k=p-k-1,c=new Date(e),g,n,r,u,y;y=a.getDOM(); -g=y.createElementNS(odf.Namespaces.officens,"office:annotation");g.setAttributeNS(odf.Namespaces.officens,"office:name",q);n=y.createElementNS(odf.Namespaces.dcns,"dc:creator");n.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",m);r=y.createElementNS(odf.Namespaces.dcns,"dc:date");r.appendChild(y.createTextNode(c.toISOString()));c=y.createElementNS(odf.Namespaces.textns,"text:list");u=y.createElementNS(odf.Namespaces.textns,"text:list-item");y=y.createElementNS(odf.Namespaces.textns, -"text:p");u.appendChild(y);c.appendChild(u);g.appendChild(n);g.appendChild(r);g.appendChild(c);d.node=g;if(!d.node)return!1;if(l){g=a.getDOM().createElementNS(odf.Namespaces.officens,"office:annotation-end");g.setAttributeNS(odf.Namespaces.officens,"office:name",q);d.end=g;if(!d.end)return!1;h(a,d.end,p+l)}h(a,d.node,p);a.emit(ops.OdtDocument.signalStepsInserted,{position:p,length:l});b&&(f=b.getStepCounter().countSteps(k,f),b.move(f),b.resetSelectionType(),a.emit(ops.OdtDocument.signalCursorMoved, -b));a.getOdfCanvas().addAnnotation(d);a.fixCursorPositions();return!0};this.spec=function(){return{optype:"AddAnnotation",memberid:m,timestamp:e,position:p,length:l,name:q}}}; -// Input 59 +ops.OpAddAnnotation=function(){function g(b,c,f){var d=b.getTextNodeAtStep(f,l);d&&(b=d.textNode,f=b.parentNode,d.offset!==b.length&&b.splitText(d.offset),f.insertBefore(c,b.nextSibling),0===b.length&&f.removeChild(b))}var l,c,m,f,n;this.init=function(b){l=b.memberid;c=parseInt(b.timestamp,10);m=parseInt(b.position,10);f=parseInt(b.length,10)||0;n=b.name};this.isEdit=!0;this.execute=function(b){var p={},r=b.getPositionFilter(),d=b.getCursor(l),k=b.getCursorPosition(l),k=m-k-1,a=new Date(c),e,h,q, +u,x;x=b.getDOM();e=x.createElementNS(odf.Namespaces.officens,"office:annotation");e.setAttributeNS(odf.Namespaces.officens,"office:name",n);h=x.createElementNS(odf.Namespaces.dcns,"dc:creator");h.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",l);h.textContent=b.getMember(l).getProperties().fullName;q=x.createElementNS(odf.Namespaces.dcns,"dc:date");q.appendChild(x.createTextNode(a.toISOString()));a=x.createElementNS(odf.Namespaces.textns,"text:list");u=x.createElementNS(odf.Namespaces.textns, +"text:list-item");x=x.createElementNS(odf.Namespaces.textns,"text:p");u.appendChild(x);a.appendChild(u);e.appendChild(h);e.appendChild(q);e.appendChild(a);p.node=e;if(!p.node)return!1;if(f){e=b.getDOM().createElementNS(odf.Namespaces.officens,"office:annotation-end");e.setAttributeNS(odf.Namespaces.officens,"office:name",n);p.end=e;if(!p.end)return!1;g(b,p.end,m+f)}g(b,p.node,m);b.emit(ops.OdtDocument.signalStepsInserted,{position:m,length:f});d&&(r=d.getStepCounter().countSteps(k,r),d.move(r),d.resetSelectionType(), +b.emit(ops.OdtDocument.signalCursorMoved,d));b.getOdfCanvas().addAnnotation(p);b.fixCursorPositions();return!0};this.spec=function(){return{optype:"AddAnnotation",memberid:l,timestamp:c,position:m,length:f,name:n}}}; +// Input 61 /* Copyright (C) 2012-2013 KO GmbH @@ -1825,10 +1882,117 @@ b));a.getOdfCanvas().addAnnotation(d);a.fixCursorPositions();return!0};this.spec @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.Namespaces");runtime.loadClass("core.DomUtils"); -ops.OpRemoveAnnotation=function(){var h,m,e,p,l;this.init=function(q){h=q.memberid;m=q.timestamp;e=parseInt(q.position,10);p=parseInt(q.length,10);l=new core.DomUtils};this.execute=function(h){for(var a=h.getIteratorAtPosition(e).container(),d,f,b;a.namespaceURI!==odf.Namespaces.officens||"annotation"!==a.localName;)a=a.parentNode;if(null===a)return!1;(d=a.getAttributeNS(odf.Namespaces.officens,"name"))&&(f=l.getElementsByTagNameNS(h.getRootNode(),odf.Namespaces.officens,"annotation-end").filter(function(a){return d=== -a.getAttributeNS(odf.Namespaces.officens,"name")})[0]||null);h.getOdfCanvas().forgetAnnotations();for(b=l.getElementsByTagNameNS(a,"urn:webodf:names:cursor","cursor");b.length;)a.parentNode.insertBefore(b.pop(),a);a.parentNode.removeChild(a);f&&f.parentNode.removeChild(f);h.emit(ops.OdtDocument.signalStepsRemoved,{position:0 + + @licstart + This file is part of WebODF. + + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +runtime.loadClass("ops.Member");ops.OpAddMember=function(){var g,l,c;this.init=function(m){g=m.memberid;l=parseInt(m.timestamp,10);c=m.setProperties};this.isEdit=!1;this.execute=function(l){if(l.getMember(g))return!1;var f=new ops.Member(g,c);l.addMember(f);l.emit(ops.OdtDocument.signalMemberAdded,f);return!0};this.spec=function(){return{optype:"AddMember",memberid:g,timestamp:l,setProperties:c}}}; +// Input 63 +/* + + Copyright (C) 2013 KO GmbH + + @licstart + This file is part of WebODF. + + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +runtime.loadClass("ops.Member");runtime.loadClass("xmldom.XPath"); +ops.OpUpdateMember=function(){function g(){for(var b=new xmldom.XPath,c="//dc:creator[@editinfo:memberid='"+l+"']",b=b.getODFElementsWithXPath(n.getRootNode(),c,function(b){return"editinfo"===b?"urn:webodf:names:editinfo":odf.Namespaces.resolvePrefix(b)}),c=0;c + + @licstart + This file is part of WebODF. + + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +runtime.loadClass("ops.Member");ops.OpRemoveMember=function(){var g,l;this.init=function(c){g=c.memberid;l=parseInt(c.timestamp,10)};this.isEdit=!1;this.execute=function(c){if(!c.getMember(g))return!1;c.removeMember(g);c.emit(ops.OdtDocument.signalMemberRemoved,g);return!0};this.spec=function(){return{optype:"RemoveMember",memberid:g,timestamp:l}}}; +// Input 65 +/* + + Copyright (C) 2013 KO GmbH + + @licstart + This file is part of WebODF. + + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with WebODF. If not, see . + @licend + + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +ops.OpUpdateMetadata=function(){var g,l,c,m;this.init=function(f){g=f.memberid;l=parseInt(f.timestamp,10);c=f.setProperties;m=f.removedProperties};this.isEdit=!0;this.execute=function(f){f=f.getOdfCanvas().odfContainer().getMetadataManager();var g=[],b=["dc:date","dc:creator","meta:editing-cycles"];c&&b.forEach(function(b){if(c[b])return!1});m&&(b.forEach(function(b){if(-1!==g.indexOf(b))return!1}),g=m.attributes.split(","));f.setMetadata(c,g);return!0};this.spec=function(){return{optype:"UpdateMetadata", +memberid:g,timestamp:l,setProperties:c,removedProperties:m}}}; +// Input 66 /* Copyright (C) 2012-2013 KO GmbH @@ -1866,11 +2030,11 @@ length:p}}}; @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpApplyDirectStyling");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");runtime.loadClass("ops.OpSetBlob");runtime.loadClass("ops.OpRemoveBlob");runtime.loadClass("ops.OpInsertImage");runtime.loadClass("ops.OpInsertTable");runtime.loadClass("ops.OpInsertText");runtime.loadClass("ops.OpRemoveText");runtime.loadClass("ops.OpSplitParagraph");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("ops.OpUpdateParagraphStyle"); -runtime.loadClass("ops.OpAddStyle");runtime.loadClass("ops.OpRemoveStyle");runtime.loadClass("ops.OpAddAnnotation");runtime.loadClass("ops.OpRemoveAnnotation"); -ops.OperationFactory=function(){function h(e){return function(){return new e}}var m;this.register=function(e,h){m[e]=h};this.create=function(e){var h=null,l=m[e.optype];l&&(h=l(e),h.init(e));return h};m={AddCursor:h(ops.OpAddCursor),ApplyDirectStyling:h(ops.OpApplyDirectStyling),SetBlob:h(ops.OpSetBlob),RemoveBlob:h(ops.OpRemoveBlob),InsertImage:h(ops.OpInsertImage),InsertTable:h(ops.OpInsertTable),InsertText:h(ops.OpInsertText),RemoveText:h(ops.OpRemoveText),SplitParagraph:h(ops.OpSplitParagraph), -SetParagraphStyle:h(ops.OpSetParagraphStyle),UpdateParagraphStyle:h(ops.OpUpdateParagraphStyle),AddStyle:h(ops.OpAddStyle),RemoveStyle:h(ops.OpRemoveStyle),MoveCursor:h(ops.OpMoveCursor),RemoveCursor:h(ops.OpRemoveCursor),AddAnnotation:h(ops.OpAddAnnotation),RemoveAnnotation:h(ops.OpRemoveAnnotation)}}; -// Input 61 +runtime.loadClass("ops.OpAddMember");runtime.loadClass("ops.OpUpdateMember");runtime.loadClass("ops.OpRemoveMember");runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpApplyDirectStyling");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");runtime.loadClass("ops.OpSetBlob");runtime.loadClass("ops.OpRemoveBlob");runtime.loadClass("ops.OpInsertImage");runtime.loadClass("ops.OpInsertTable");runtime.loadClass("ops.OpInsertText");runtime.loadClass("ops.OpRemoveText"); +runtime.loadClass("ops.OpSplitParagraph");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("ops.OpUpdateParagraphStyle");runtime.loadClass("ops.OpAddStyle");runtime.loadClass("ops.OpRemoveStyle");runtime.loadClass("ops.OpAddAnnotation");runtime.loadClass("ops.OpRemoveAnnotation");runtime.loadClass("ops.OpUpdateMetadata"); +ops.OperationFactory=function(){function g(c){return function(){return new c}}var l;this.register=function(c,g){l[c]=g};this.create=function(c){var g=null,f=l[c.optype];f&&(g=f(c),g.init(c));return g};l={AddMember:g(ops.OpAddMember),UpdateMember:g(ops.OpUpdateMember),RemoveMember:g(ops.OpRemoveMember),AddCursor:g(ops.OpAddCursor),ApplyDirectStyling:g(ops.OpApplyDirectStyling),SetBlob:g(ops.OpSetBlob),RemoveBlob:g(ops.OpRemoveBlob),InsertImage:g(ops.OpInsertImage),InsertTable:g(ops.OpInsertTable), +InsertText:g(ops.OpInsertText),RemoveText:g(ops.OpRemoveText),SplitParagraph:g(ops.OpSplitParagraph),SetParagraphStyle:g(ops.OpSetParagraphStyle),UpdateParagraphStyle:g(ops.OpUpdateParagraphStyle),AddStyle:g(ops.OpAddStyle),RemoveStyle:g(ops.OpRemoveStyle),MoveCursor:g(ops.OpMoveCursor),RemoveCursor:g(ops.OpRemoveCursor),AddAnnotation:g(ops.OpAddAnnotation),RemoveAnnotation:g(ops.OpRemoveAnnotation),UpdateMetadata:g(ops.OpUpdateMetadata)}}; +// Input 67 /* Copyright (C) 2012-2013 KO GmbH @@ -1909,18 +2073,18 @@ SetParagraphStyle:h(ops.OpSetParagraphStyle),UpdateParagraphStyle:h(ops.OpUpdate @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.Cursor");runtime.loadClass("core.DomUtils");runtime.loadClass("core.PositionIterator");runtime.loadClass("core.PositionFilter");runtime.loadClass("core.LoopWatchDog");runtime.loadClass("odf.OdfUtils"); -gui.SelectionMover=function(h,m){function e(){x.setUnfilteredPosition(h.getNode(),0);return x}function p(a,c){var b,d=null;a&&(b=c?a[a.length-1]:a[0]);b&&(d={top:b.top,left:c?b.right:b.left,bottom:b.bottom});return d}function l(a,c,b,d){var g=a.nodeType;b.setStart(a,c);b.collapse(!d);d=p(b.getClientRects(),!0===d);!d&&0a?-1:1;for(a=Math.abs(a);0k?n.previousPosition():n.nextPosition());)if(G.check(),h.acceptPosition(n)===t&&(r+=1,p=n.container(),v=l(p,n.unfilteredDomOffset(),L),v.top!==Y)){if(v.top!==N&&N!==Y)break;N=v.top;v=Math.abs(V-v.left);if(null===q||va?(b=h.previousPosition,d=-1):(b=h.nextPosition,d=1);for(g=l(h.container(),h.unfilteredDomOffset(),p);b.call(h);)if(c.acceptPosition(h)===t){if(u.getParagraphElement(h.getCurrentNode())!==k)break;f=l(h.container(),h.unfilteredDomOffset(),p);if(f.bottom!==g.bottom&&(g=f.top>=g.top&&f.bottomg.bottom,!g))break;n+= -d;g=f}p.detach();return n}function r(a,c,b){runtime.assert(null!==a,"SelectionMover.countStepsToPosition called with element===null");var d=e(),g=d.container(),f=d.unfilteredDomOffset(),h=0,k=new core.LoopWatchDog(1E4);for(d.setUnfilteredPosition(a,c);b.acceptPosition(d)!==t&&d.previousPosition();)k.check();a=d.container();runtime.assert(Boolean(a),"SelectionMover.countStepsToPosition: positionIterator.container() returned null");c=d.unfilteredDomOffset();for(d.setUnfilteredPosition(g,f);b.acceptPosition(d)!== -t&&d.previousPosition();)k.check();g=y.comparePoints(a,c,d.container(),d.unfilteredDomOffset());if(0>g)for(;d.nextPosition()&&(k.check(),b.acceptPosition(d)===t&&(h+=1),d.container()!==a||d.unfilteredDomOffset()!==c););else if(0a?-1:1;for(a=Math.abs(a);0m?q.previousPosition():q.nextPosition());)if(ha.check(),g.acceptPosition(q)===t&&(p+=1,n=q.container(),v=f(n,q.unfilteredDomOffset(),I),v.top!==Y)){if(v.top!==G&&G!==Y)break;G=v.top;v=Math.abs(V-v.left);if(null===r||va?(e=g.previousPosition,d=-1):(e=g.nextPosition,d=1);for(h=f(g.container(),g.unfilteredDomOffset(),n);e.call(g);)if(b.acceptPosition(g)===t){if(u.getParagraphElement(g.getCurrentNode())!==m)break;k=f(g.container(),g.unfilteredDomOffset(),n);if(k.bottom!==h.bottom&&(h=k.top>=h.top&&k.bottomh.bottom,!h))break;q+= +d;h=k}n.detach();return q}function q(a,b,e){runtime.assert(null!==a,"SelectionMover.countStepsToPosition called with element===null");var d=c(),h=d.container(),f=d.unfilteredDomOffset(),k=0,g=new core.LoopWatchDog(1E4);for(d.setUnfilteredPosition(a,b);e.acceptPosition(d)!==t&&d.previousPosition();)g.check();a=d.container();runtime.assert(Boolean(a),"SelectionMover.countStepsToPosition: positionIterator.container() returned null");b=d.unfilteredDomOffset();for(d.setUnfilteredPosition(h,f);e.acceptPosition(d)!== +t&&d.previousPosition();)g.check();h=x.comparePoints(a,b,d.container(),d.unfilteredDomOffset());if(0>h)for(;d.nextPosition()&&(g.check(),e.acceptPosition(d)===t&&(k+=1),d.container()!==a||d.unfilteredDomOffset()!==b););else if(0 @@ -1959,15 +2123,15 @@ gui.SelectionMover.createPositionIterator=function(h){var m=new function(){this. @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils");runtime.loadClass("core.PositionFilter");runtime.loadClass("odf.OdfUtils"); -(function(){function h(e,h,l){function q(a,c){function b(a){for(var c=0;a&&a.previousSibling;)c+=1,a=a.previousSibling;return c}this.steps=a;this.node=c;this.setIteratorPosition=function(a){a.setUnfilteredPosition(c.parentNode,b(c));do if(h.acceptPosition(a)===u)break;while(a.nextPosition())}}function a(a){return a.nodeType===Node.ELEMENT_NODE&&a.getAttributeNS(b,"nodeId")}function d(a){var c=m;a.setAttributeNS(b,"nodeId",c.toString());m+=1;return c}function f(d,g){var f,h=null;for(d=d.childNodes[g]|| -d;!h&&d&&d!==e;)(f=a(d))&&(h=c[f])&&h.node!==d&&(runtime.log("Cloned node detected. Creating new bookmark"),h=null,d.removeAttributeNS(b,"nodeId")),d=d.parentNode;return h}var b="urn:webodf:names:steps",k={},c={},g=new odf.OdfUtils,n=new core.DomUtils,r,u=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.updateCache=function(b,f,e,h){var n;0===e&&g.isParagraph(f)?(n=!0,h||(b+=1)):f.hasChildNodes()&&f.childNodes[e]&&(f=f.childNodes[e],(n=g.isParagraph(f))&&(b+=1));n&&(e=a(f)||d(f),(h=c[e])?h.node=== -f?h.steps=b:(runtime.log("Cloned node detected. Creating new bookmark"),e=d(f),h=c[e]=new q(b,f)):h=c[e]=new q(b,f),e=h,b=Math.ceil(e.steps/l)*l,f=k[b],!f||e.steps>f.steps)&&(k[b]=e)};this.setToClosestStep=function(a,c){for(var b=Math.floor(a/l)*l,d;!d&&0!==b;)d=k[b],b-=l;d=d||r;d.setIteratorPosition(c);return d.steps};this.setToClosestDomPoint=function(a,c,b){var d;if(a===e&&0===c)d=r;else if(a===e&&c===e.childNodes.length)d=Object.keys(k).map(function(a){return k[a]}).reduce(function(a,c){return c.steps> -a.steps?c:a},r);else if(d=f(a,c),!d)for(b.setUnfilteredPosition(a,c);!d&&b.previousNode();)d=f(b.container(),b.unfilteredDomOffset());d=d||r;d.setIteratorPosition(b);return d.steps};this.updateCacheAtPoint=function(b,d){var g={};Object.keys(c).map(function(a){return c[a]}).filter(function(a){return a.steps>b}).forEach(function(b){var f=Math.ceil(b.steps/l)*l,h,m;if(n.containsNode(e,b.node)){if(d(b),h=Math.ceil(b.steps/l)*l,m=g[h],!m||b.steps>m.steps)g[h]=b}else delete c[a(b.node)];k[f]===b&&delete k[f]}); -Object.keys(g).forEach(function(a){k[a]=g[a]})};r=new function(a,c){this.steps=a;this.node=c;this.setIteratorPosition=function(a){a.setUnfilteredPosition(c,0);do if(h.acceptPosition(a)===u)break;while(a.nextPosition())}}(0,e)}var m=0;ops.StepsTranslator=function(e,m,l,q){function a(){var a=e();a!==d&&(runtime.log("Undo detected. Resetting steps cache"),d=a,f=new h(d,l,q),k=m(d))}var d=e(),f=new h(d,l,q),b=new core.DomUtils,k=m(e()),c=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.convertStepsToDomPoint= -function(b){var d,e;0>b&&(runtime.log("warn","Requested steps were negative ("+b+")"),b=0);a();for(d=f.setToClosestStep(b,k);db.comparePoints(d,0,g,e),g=d,e=m?0: -d.childNodes.length);k.setUnfilteredPosition(g,e);m=k.container();p=k.unfilteredDomOffset();h&&l.acceptPosition(k)!==c&&(q=1);g=f.setToClosestDomPoint(g,e,k);if(0>b.comparePoints(k.container(),k.unfilteredDomOffset(),m,p))return 0a.steps&&(a.steps=0)})}};return ops.StepsTranslator})(); -// Input 63 +(function(){function g(c,g,f){function n(a,b){function c(a){for(var b=0;a&&a.previousSibling;)b+=1,a=a.previousSibling;return b}this.steps=a;this.node=b;this.setIteratorPosition=function(a){a.setUnfilteredPosition(b.parentNode,c(b));do if(g.acceptPosition(a)===u)break;while(a.nextPosition())}}function b(a){return a.nodeType===Node.ELEMENT_NODE&&a.getAttributeNS(d,"nodeId")}function p(a){var b=l;a.setAttributeNS(d,"nodeId",b.toString());l+=1;return b}function r(e,h){var f,k=null;for(e=e.childNodes[h]|| +e;!k&&e&&e!==c;)(f=b(e))&&(k=a[f])&&k.node!==e&&(runtime.log("Cloned node detected. Creating new bookmark"),k=null,e.removeAttributeNS(d,"nodeId")),e=e.parentNode;return k}var d="urn:webodf:names:steps",k={},a={},e=new odf.OdfUtils,h=new core.DomUtils,q,u=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.updateCache=function(c,d,h,g){var l;0===h&&e.isParagraph(d)?(l=!0,g||(c+=1)):d.hasChildNodes()&&d.childNodes[h]&&(d=d.childNodes[h],(l=e.isParagraph(d))&&(c+=1));l&&(h=b(d)||p(d),(g=a[h])?g.node=== +d?g.steps=c:(runtime.log("Cloned node detected. Creating new bookmark"),h=p(d),g=a[h]=new n(c,d)):g=a[h]=new n(c,d),h=g,c=Math.ceil(h.steps/f)*f,d=k[c],!d||h.steps>d.steps)&&(k[c]=h)};this.setToClosestStep=function(a,b){for(var c=Math.floor(a/f)*f,e;!e&&0!==c;)e=k[c],c-=f;e=e||q;e.setIteratorPosition(b);return e.steps};this.setToClosestDomPoint=function(a,b,e){var d;if(a===c&&0===b)d=q;else if(a===c&&b===c.childNodes.length)d=Object.keys(k).map(function(a){return k[a]}).reduce(function(a,b){return b.steps> +a.steps?b:a},q);else if(d=r(a,b),!d)for(e.setUnfilteredPosition(a,b);!d&&e.previousNode();)d=r(e.container(),e.unfilteredDomOffset());d=d||q;d.setIteratorPosition(e);return d.steps};this.updateCacheAtPoint=function(e,d){var g={};Object.keys(a).map(function(b){return a[b]}).filter(function(a){return a.steps>e}).forEach(function(e){var l=Math.ceil(e.steps/f)*f,m,q;if(h.containsNode(c,e.node)){if(d(e),m=Math.ceil(e.steps/f)*f,q=g[m],!q||e.steps>q.steps)g[m]=e}else delete a[b(e.node)];k[l]===e&&delete k[l]}); +Object.keys(g).forEach(function(a){k[a]=g[a]})};q=new function(a,b){this.steps=a;this.node=b;this.setIteratorPosition=function(a){a.setUnfilteredPosition(b,0);do if(g.acceptPosition(a)===u)break;while(a.nextPosition())}}(0,c)}var l=0;ops.StepsTranslator=function(c,l,f,n){function b(){var a=c();a!==p&&(runtime.log("Undo detected. Resetting steps cache"),p=a,r=new g(p,f,n),k=l(p))}var p=c(),r=new g(p,f,n),d=new core.DomUtils,k=l(c()),a=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.convertStepsToDomPoint= +function(c){var d,g;0>c&&(runtime.log("warn","Requested steps were negative ("+c+")"),c=0);b();for(d=r.setToClosestStep(c,k);dd.comparePoints(p,0,c,h),c=p,h=l?0: +p.childNodes.length);k.setUnfilteredPosition(c,h);l=k.container();m=k.unfilteredDomOffset();g&&f.acceptPosition(k)!==a&&(n=1);c=r.setToClosestDomPoint(c,h,k);if(0>d.comparePoints(k.container(),k.unfilteredDomOffset(),l,m))return 0b.steps&&(b.steps=0)})}};return ops.StepsTranslator})(); +// Input 69 /* Copyright (C) 2012-2013 KO GmbH @@ -2006,10 +2170,10 @@ l.acceptPosition(k)===c)&&(b+=1),f.updateCache(b,k.container(),k.unfilteredDomOf @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.PositionFilter");runtime.loadClass("odf.OdfUtils"); -ops.TextPositionFilter=function(h){function m(h,a,d){var f,b;if(a&&(f=e.lookLeftForCharacter(a),1===f||2===f&&(e.scanRightForAnyCharacter(d)||e.scanRightForAnyCharacter(e.nextNode(h)))))return p;f=null===a&&e.isParagraph(h);b=e.lookRightForCharacter(d);if(f)return b?p:e.scanRightForAnyCharacter(d)?l:p;if(!b)return l;a=a||e.previousNode(h);return e.scanLeftForAnyCharacter(a)?l:p}var e=new odf.OdfUtils,p=core.PositionFilter.FilterResult.FILTER_ACCEPT,l=core.PositionFilter.FilterResult.FILTER_REJECT; -this.acceptPosition=function(q){var a=q.container(),d=a.nodeType,f,b,k;if(d!==Node.ELEMENT_NODE&&d!==Node.TEXT_NODE)return l;if(d===Node.TEXT_NODE){if(!e.isGroupingElement(a.parentNode)||e.isWithinTrackedChanges(a.parentNode,h()))return l;d=q.unfilteredDomOffset();f=a.data;runtime.assert(d!==f.length,"Unexpected offset.");if(0 @@ -2034,26 +2198,28 @@ e.scanLeftForNonWhitespace(k)&&(b=p);if(b===p)return e.isTrailingWhitespace(a,d) @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OperationTransformMatrix=function(){function h(a){a.position+=a.length;a.length*=-1}function m(a){var b=0>a.length;b&&h(a);return b}function e(a,b){var d=[];a&&["style:parent-style-name","style:next-style-name"].forEach(function(f){a[f]===b&&d.push(f)});return d}function p(a,b){a&&["style:parent-style-name","style:next-style-name"].forEach(function(d){a[d]===b&&delete a[d]})}function l(a){var b={};Object.keys(a).forEach(function(d){b[d]="object"===typeof a[d]?l(a[d]):a[d]});return b}function q(a, -b,d,f){var e,h,k=!1,l=!1,m,p,q=f&&f.attributes?f.attributes.split(","):[];a&&(d||0=b.position+b.length)){e=d?c:b;h=d?b:c;if(c.position!==b.position|| -c.length!==b.length)q=l(e),t=l(h);b=f(h,e,"style:text-properties");if(b.majorChanged||b.minorChanged)k=[],c=[],m=e.position+e.length,p=h.position+h.length,h.positionm?b.minorChanged&&(q=t,q.position=m,q.length=p-m,c.push(q),h.length=m-h.position): -m>p&&b.majorChanged&&(q.position=p,q.length=m-p,k.push(q),e.length=p-e.position),e.setProperties&&a(e.setProperties)&&k.push(e),h.setProperties&&a(h.setProperties)&&c.push(h),d?(m=k,k=c):m=c}return{opSpecsA:m,opSpecsB:k}},InsertText:function(a,b){b.position<=a.position?a.position+=b.text.length:b.position<=a.position+a.length&&(a.length+=b.text.length);return{opSpecsA:[a],opSpecsB:[b]}},MoveCursor:b,RemoveCursor:b,RemoveStyle:b,RemoveText:function(a,b){var d=a.position+a.length,f=b.position+b.length, -e=[a],h=[b];f<=a.position?a.position-=b.length:b.position -b.position)a.position+=b.text.length;else return d?b.position+=a.text.length:a.position+=b.text.length,null;return{opSpecsA:[a],opSpecsB:[b]}},MoveCursor:function(a,b){var d=m(b);a.positionb.position)a.position+=1;else return d?b.position+=a.text.length:a.position+=1,null;return{opSpecsA:[a],opSpecsB:[b]}},UpdateParagraphStyle:b},MoveCursor:{MoveCursor:b,RemoveCursor:function(a, -b){return{opSpecsA:a.memberid===b.memberid?[]:[a],opSpecsB:[b]}},RemoveStyle:b,RemoveText:function(a,b){var d=m(a),f=a.position+a.length,e=b.position+b.length;e<=a.position?a.position-=b.length:b.positionb.position)a.position+=1;else if(a.position===b.position)return d?b.position+=1:a.position+=1,null;return{opSpecsA:[a],opSpecsB:[b]}},UpdateParagraphStyle:b},UpdateParagraphStyle:{UpdateParagraphStyle:function(b,e,h){var k,l=[b],m=[e];b.styleName===e.styleName&&(k=h?b:e,b=h?e:b,f(b,k,"style:paragraph-properties"),f(b,k,"style:text-properties"),q(b.setProperties||null,b.removedProperties||null, -k.setProperties||null,k.removedProperties||null),k.setProperties&&a(k.setProperties)||k.removedProperties&&d(k.removedProperties)||(h?l=[]:m=[]),b.setProperties&&a(b.setProperties)||b.removedProperties&&d(b.removedProperties)||(h?m=[]:l=[]));return{opSpecsA:l,opSpecsB:m}}}};this.passUnchanged=b;this.extendTransformations=function(a){Object.keys(a).forEach(function(b){var d=a[b],f,e=k.hasOwnProperty(b);runtime.log((e?"Extending":"Adding")+" map for optypeA: "+b);e||(k[b]={});f=k[b];Object.keys(d).forEach(function(a){var c= -f.hasOwnProperty(a);runtime.assert(b<=a,"Wrong order:"+b+", "+a);runtime.log(" "+(c?"Overwriting":"Adding")+" entry for optypeB: "+a);f[a]=d[a]})})};this.transformOpspecVsOpspec=function(a,b){var d=a.optype<=b.optype,f;runtime.log("Crosstransforming:");runtime.log(runtime.toJson(a));runtime.log(runtime.toJson(b));d||(f=a,a=b,b=f);(f=(f=k[a.optype])&&f[b.optype])?(f=f(a,b,!d),d||null===f||(f={opSpecsA:f.opSpecsB,opSpecsB:f.opSpecsA})):f=null;runtime.log("result:");f?(runtime.log(runtime.toJson(f.opSpecsA)), -runtime.log(runtime.toJson(f.opSpecsB))):runtime.log("null");return f}}; -// Input 65 +ops.OperationTransformMatrix=function(){function g(a){a.position+=a.length;a.length*=-1}function l(a){var b=0>a.length;b&&g(a);return b}function c(a,b){var c=[];a&&["style:parent-style-name","style:next-style-name"].forEach(function(d){a[d]===b&&c.push(d)});return c}function m(a,b){a&&["style:parent-style-name","style:next-style-name"].forEach(function(c){a[c]===b&&delete a[c]})}function f(a){var b={};Object.keys(a).forEach(function(c){b[c]="object"===typeof a[c]?f(a[c]):a[c]});return b}function n(a, +b,c,d){var f,k,g=!1,l=!1,m,n,p=d&&d.attributes?d.attributes.split(","):[];a&&(c||0=c.position+c.length)){k=d?a:c;g=d?c:a;if(a.position!==c.position||a.length!==c.length)p=f(k),t=f(g);c=r(g,k,"style:text-properties");if(c.majorChanged||c.minorChanged)l=[],a=[],m=k.position+k.length,n=g.position+g.length,g.positionm?c.minorChanged&&(p=t,p.position=m,p.length=n-m,a.push(p),g.length=m-g.position):m>n&&c.majorChanged&&(p.position=n,p.length=m-n,l.push(p),k.length=n-k.position),k.setProperties&&b(k.setProperties)&&l.push(k),g.setProperties&&b(g.setProperties)&&a.push(g),d?(m=l,l=a):m=a}return{opSpecsA:m,opSpecsB:l}},InsertText:function(a, +b){b.position<=a.position?a.position+=b.text.length:b.position<=a.position+a.length&&(a.length+=b.text.length);return{opSpecsA:[a],opSpecsB:[b]}},MoveCursor:d,RemoveCursor:d,RemoveStyle:d,RemoveText:function(a,b){var c=a.position+a.length,d=b.position+b.length,f=[a],k=[b];d<=a.position?a.position-=b.length:b.positionb.position)a.position+=b.text.length;else return c?b.position+=a.text.length:a.position+=b.text.length,null;return{opSpecsA:[a],opSpecsB:[b]}},MoveCursor:function(a,b){var c=l(b);a.positionb.position)a.position+=1;else return c?b.position+=a.text.length:a.position+=1,null;return{opSpecsA:[a],opSpecsB:[b]}},UpdateMember:d,UpdateMetadata:d,UpdateParagraphStyle:d},MoveCursor:{MoveCursor:d,RemoveCursor:function(a,b){return{opSpecsA:a.memberid===b.memberid?[]:[a],opSpecsB:[b]}},RemoveMember:d,RemoveStyle:d,RemoveText:function(a,b){var c=l(a),d=a.position+a.length,f=b.position+b.length;f<= +a.position?a.position-=b.length:b.positionb.position)a.position+=1;else if(a.position===b.position)return c?b.position+=1:a.position+=1,null;return{opSpecsA:[a],opSpecsB:[b]}},UpdateMember:d,UpdateMetadata:d,UpdateParagraphStyle:d},UpdateMember:{UpdateMetadata:d,UpdateParagraphStyle:d},UpdateMetadata:{UpdateMetadata:function(a, +c,d){var f,k=[a],g=[c];f=d?a:c;a=d?c:a;n(a.setProperties||null,a.removedProperties||null,f.setProperties||null,f.removedProperties||null);f.setProperties&&b(f.setProperties)||f.removedProperties&&p(f.removedProperties)||(d?k=[]:g=[]);a.setProperties&&b(a.setProperties)||a.removedProperties&&p(a.removedProperties)||(d?g=[]:k=[]);return{opSpecsA:k,opSpecsB:g}},UpdateParagraphStyle:d},UpdateParagraphStyle:{UpdateParagraphStyle:function(a,c,d){var f,k=[a],g=[c];a.styleName===c.styleName&&(f=d?a:c,a=d? +c:a,r(a,f,"style:paragraph-properties"),r(a,f,"style:text-properties"),n(a.setProperties||null,a.removedProperties||null,f.setProperties||null,f.removedProperties||null),f.setProperties&&b(f.setProperties)||f.removedProperties&&p(f.removedProperties)||(d?k=[]:g=[]),a.setProperties&&b(a.setProperties)||a.removedProperties&&p(a.removedProperties)||(d?g=[]:k=[]));return{opSpecsA:k,opSpecsB:g}}}};this.passUnchanged=d;this.extendTransformations=function(a){Object.keys(a).forEach(function(b){var c=a[b], +d,f=k.hasOwnProperty(b);runtime.log((f?"Extending":"Adding")+" map for optypeA: "+b);f||(k[b]={});d=k[b];Object.keys(c).forEach(function(a){var f=d.hasOwnProperty(a);runtime.assert(b<=a,"Wrong order:"+b+", "+a);runtime.log(" "+(f?"Overwriting":"Adding")+" entry for optypeB: "+a);d[a]=c[a]})})};this.transformOpspecVsOpspec=function(a,b){var c=a.optype<=b.optype,d;runtime.log("Crosstransforming:");runtime.log(runtime.toJson(a));runtime.log(runtime.toJson(b));c||(d=a,a=b,b=d);(d=(d=k[a.optype])&&d[b.optype])? +(d=d(a,b,!c),c||null===d||(d={opSpecsA:d.opSpecsB,opSpecsB:d.opSpecsA})):d=null;runtime.log("result:");d?(runtime.log(runtime.toJson(d.opSpecsA)),runtime.log(runtime.toJson(d.opSpecsB))):runtime.log("null");return d}}; +// Input 71 /* Copyright (C) 2013 KO GmbH @@ -2079,14 +2245,14 @@ runtime.log(runtime.toJson(f.opSpecsB))):runtime.log("null");return f}}; @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("ops.OperationFactory");runtime.loadClass("ops.OperationTransformMatrix"); -ops.OperationTransformer=function(){function h(h){var m=[];h.forEach(function(a){m.push(e.create(a))});return m}function m(e,h){for(var a,d,f=[],b=[];0=a&&(b=-q.movePointBackward(-a,f));e.handleUpdate();return b};this.handleUpdate=function(){};this.getStepCounter=function(){return q.getStepCounter()};this.getMemberId=function(){return h};this.getNode=function(){return a.getNode()};this.getAnchorNode=function(){return a.getAnchorNode()};this.getSelectedRange=function(){return a.getSelectedRange()}; -this.setSelectedRange=function(d,f){a.setSelectedRange(d,f);e.handleUpdate()};this.hasForwardSelection=function(){return a.hasForwardSelection()};this.getOdtDocument=function(){return m};this.getSelectionType=function(){return l};this.setSelectionType=function(a){p.hasOwnProperty(a)?l=a:runtime.log("Invalid selection type: "+a)};this.resetSelectionType=function(){e.setSelectionType(ops.OdtCursor.RangeSelection)};a=new core.Cursor(m.getDOM(),h);q=new gui.SelectionMover(a,m.getRootNode());p[ops.OdtCursor.RangeSelection]= -!0;p[ops.OdtCursor.RegionSelection]=!0;e.resetSelectionType()};ops.OdtCursor.RangeSelection="Range";ops.OdtCursor.RegionSelection="Region";(function(){return ops.OdtCursor})(); -// Input 67 +ops.OdtCursor=function(g,l){var c=this,m={},f,n,b;this.removeFromOdtDocument=function(){b.remove()};this.move=function(b,f){var d=0;0=b&&(d=-n.movePointBackward(-b,f));c.handleUpdate();return d};this.handleUpdate=function(){};this.getStepCounter=function(){return n.getStepCounter()};this.getMemberId=function(){return g};this.getNode=function(){return b.getNode()};this.getAnchorNode=function(){return b.getAnchorNode()};this.getSelectedRange=function(){return b.getSelectedRange()}; +this.setSelectedRange=function(f,g){b.setSelectedRange(f,g);c.handleUpdate()};this.hasForwardSelection=function(){return b.hasForwardSelection()};this.getOdtDocument=function(){return l};this.getSelectionType=function(){return f};this.setSelectionType=function(b){m.hasOwnProperty(b)?f=b:runtime.log("Invalid selection type: "+b)};this.resetSelectionType=function(){c.setSelectionType(ops.OdtCursor.RangeSelection)};b=new core.Cursor(l.getDOM(),g);n=new gui.SelectionMover(b,l.getRootNode());m[ops.OdtCursor.RangeSelection]= +!0;m[ops.OdtCursor.RegionSelection]=!0;c.resetSelectionType()};ops.OdtCursor.RangeSelection="Range";ops.OdtCursor.RegionSelection="Region";(function(){return ops.OdtCursor})(); +// Input 73 /* Copyright (C) 2012 KO GmbH @@ -2124,23 +2290,23 @@ this.setSelectedRange=function(d,f){a.setSelectedRange(d,f);e.handleUpdate()};th @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.EditInfo=function(h,m){function e(){var e=[],a;for(a in l)l.hasOwnProperty(a)&&e.push({memberid:a,time:l[a].time});e.sort(function(a,f){return a.time-f.time});return e}var p,l={};this.getNode=function(){return p};this.getOdtDocument=function(){return m};this.getEdits=function(){return l};this.getSortedEdits=function(){return e()};this.addEdit=function(e,a){l[e]={time:a}};this.clearEdits=function(){l={}};this.destroy=function(e){h.parentNode&&h.removeChild(p);e()};p=m.getDOM().createElementNS("urn:webodf:names:editinfo", -"editinfo");h.insertBefore(p,h.firstChild)}; -// Input 68 -runtime.loadClass("gui.SelectionMover");gui.ShadowCursor=function(h){var m=h.getDOM().createRange(),e=!0;this.removeFromOdtDocument=function(){};this.getMemberId=function(){return gui.ShadowCursor.ShadowCursorMemberId};this.getSelectedRange=function(){return m};this.setSelectedRange=function(h,l){m=h;e=!1!==l};this.hasForwardSelection=function(){return e};this.getOdtDocument=function(){return h};this.getSelectionType=function(){return ops.OdtCursor.RangeSelection};m.setStart(h.getRootNode(),0)}; +ops.EditInfo=function(g,l){function c(){var c=[],b;for(b in f)f.hasOwnProperty(b)&&c.push({memberid:b,time:f[b].time});c.sort(function(b,c){return b.time-c.time});return c}var m,f={};this.getNode=function(){return m};this.getOdtDocument=function(){return l};this.getEdits=function(){return f};this.getSortedEdits=function(){return c()};this.addEdit=function(c,b){f[c]={time:b}};this.clearEdits=function(){f={}};this.destroy=function(c){g.parentNode&&g.removeChild(m);c()};m=l.getDOM().createElementNS("urn:webodf:names:editinfo", +"editinfo");g.insertBefore(m,g.firstChild)}; +// Input 74 +runtime.loadClass("gui.SelectionMover");gui.ShadowCursor=function(g){var l=g.getDOM().createRange(),c=!0;this.removeFromOdtDocument=function(){};this.getMemberId=function(){return gui.ShadowCursor.ShadowCursorMemberId};this.getSelectedRange=function(){return l};this.setSelectedRange=function(g,f){l=g;c=!1!==f};this.hasForwardSelection=function(){return c};this.getOdtDocument=function(){return g};this.getSelectionType=function(){return ops.OdtCursor.RangeSelection};l.setStart(g.getRootNode(),0)}; gui.ShadowCursor.ShadowCursorMemberId="";(function(){return gui.ShadowCursor})(); -// Input 69 -gui.Avatar=function(h,m){var e=this,p,l,q;this.setColor=function(a){l.style.borderColor=a};this.setImageUrl=function(a){e.isVisible()?l.src=a:q=a};this.isVisible=function(){return"block"===p.style.display};this.show=function(){q&&(l.src=q,q=void 0);p.style.display="block"};this.hide=function(){p.style.display="none"};this.markAsFocussed=function(a){p.className=a?"active":""};this.destroy=function(a){h.removeChild(p);a()};(function(){var a=h.ownerDocument,d=a.documentElement.namespaceURI;p=a.createElementNS(d, -"div");l=a.createElementNS(d,"img");l.width=64;l.height=64;p.appendChild(l);p.style.width="64px";p.style.height="70px";p.style.position="absolute";p.style.top="-80px";p.style.left="-34px";p.style.display=m?"block":"none";h.appendChild(p)})()}; -// Input 70 +// Input 75 +gui.Avatar=function(g,l){var c=this,m,f,n;this.setColor=function(b){f.style.borderColor=b};this.setImageUrl=function(b){c.isVisible()?f.src=b:n=b};this.isVisible=function(){return"block"===m.style.display};this.show=function(){n&&(f.src=n,n=void 0);m.style.display="block"};this.hide=function(){m.style.display="none"};this.markAsFocussed=function(b){m.className=b?"active":""};this.destroy=function(b){g.removeChild(m);b()};(function(){var b=g.ownerDocument,c=b.documentElement.namespaceURI;m=b.createElementNS(c, +"div");f=b.createElementNS(c,"img");f.width=64;f.height=64;m.appendChild(f);m.style.width="64px";m.style.height="70px";m.style.position="absolute";m.style.top="-80px";m.style.left="-34px";m.style.display=l?"block":"none";g.appendChild(m)})()}; +// Input 76 runtime.loadClass("core.DomUtils");runtime.loadClass("gui.Avatar");runtime.loadClass("ops.OdtCursor"); -gui.Caret=function(h,m,e){function p(b){k&&f.parentNode&&(!c||b)&&(b&&void 0!==g&&runtime.clearTimeout(g),c=!0,a.style.opacity=b||"0"===a.style.opacity?"1":"0",g=runtime.setTimeout(function(){c=!1;p(!1)},500))}function l(a,b){var c=a.getBoundingClientRect(),d=0,f=0;c&&b&&(d=Math.max(c.top,b.top),f=Math.min(c.bottom,b.bottom));return f-d}function q(){var c;c=h.getSelectedRange().cloneRange();var d=h.getNode(),f,e=null;d.previousSibling&&(f=d.previousSibling.nodeType===Node.TEXT_NODE?d.previousSibling.textContent.length: -d.previousSibling.childNodes.length,c.setStart(d.previousSibling,0l(d,e))&&(e=f));c=e;d=h.getOdtDocument().getOdfCanvas().getZoomLevel();b&&h.getSelectionType()===ops.OdtCursor.RangeSelection? -a.style.visibility="visible":a.style.visibility="hidden";c?(a.style.top="0",e=a.ownerDocument.createRange(),e.selectNode(a),f=e.getBoundingClientRect(),e.detach(),8>c.height&&(c={top:c.top-(8-c.height)/2,height:8}),a.style.height=n.adaptRangeDifferenceToZoomLevel(c.height,d)+"px",a.style.top=n.adaptRangeDifferenceToZoomLevel(c.top-f.top,d)+"px"):(a.style.height="1em",a.style.top="5%")}var a,d,f,b=!0,k=!1,c=!1,g,n=new core.DomUtils;this.handleUpdate=q;this.refreshCursorBlinking=function(){e||h.getSelectedRange().collapsed? -(k=!0,p(!0)):(k=!1,a.style.opacity="0")};this.setFocus=function(){k=!0;d.markAsFocussed(!0);p(!0)};this.removeFocus=function(){k=!1;d.markAsFocussed(!1);a.style.opacity="1"};this.show=function(){b=!0;q();d.markAsFocussed(!0)};this.hide=function(){b=!1;q();d.markAsFocussed(!1)};this.setAvatarImageUrl=function(a){d.setImageUrl(a)};this.setColor=function(b){a.style.borderColor=b;d.setColor(b)};this.getCursor=function(){return h};this.getFocusElement=function(){return a};this.toggleHandleVisibility=function(){d.isVisible()? -d.hide():d.show()};this.showHandle=function(){d.show()};this.hideHandle=function(){d.hide()};this.ensureVisible=function(){var b,c,d,f,e=h.getOdtDocument().getOdfCanvas().getElement().parentNode,g;d=e.offsetWidth-e.clientWidth+5;f=e.offsetHeight-e.clientHeight+5;g=a.getBoundingClientRect();b=g.left-d;c=g.top-f;d=g.right+d;f=g.bottom+f;g=e.getBoundingClientRect();cg.bottom&&(e.scrollTop+=f-g.bottom);bg.right&&(e.scrollLeft+=d-g.right); -q()};this.destroy=function(b){d.destroy(function(c){c?b(c):(f.removeChild(a),b())})};(function(){var b=h.getOdtDocument().getDOM();a=b.createElementNS(b.documentElement.namespaceURI,"span");a.style.top="5%";f=h.getNode();f.appendChild(a);d=new gui.Avatar(f,m);q()})()}; -// Input 71 +gui.Caret=function(g,l,c){function m(c){k&&r.parentNode&&(!a||c)&&(c&&void 0!==e&&runtime.clearTimeout(e),a=!0,b.style.opacity=c||"0"===b.style.opacity?"1":"0",e=runtime.setTimeout(function(){a=!1;m(!1)},500))}function f(a,b){var c=a.getBoundingClientRect(),d=0,e=0;c&&b&&(d=Math.max(c.top,b.top),e=Math.min(c.bottom,b.bottom));return e-d}function n(){var a;a=g.getSelectedRange().cloneRange();var c=g.getNode(),e,k=null;c.previousSibling&&(e=c.previousSibling.nodeType===Node.TEXT_NODE?c.previousSibling.textContent.length: +c.previousSibling.childNodes.length,a.setStart(c.previousSibling,0f(c,k))&&(k=e));a=k;c=g.getOdtDocument().getOdfCanvas().getZoomLevel();d&&g.getSelectionType()===ops.OdtCursor.RangeSelection? +b.style.visibility="visible":b.style.visibility="hidden";a?(b.style.top="0",k=h.getBoundingClientRect(b),8>a.height&&(a={top:a.top-(8-a.height)/2,height:8}),b.style.height=h.adaptRangeDifferenceToZoomLevel(a.height,c)+"px",b.style.top=h.adaptRangeDifferenceToZoomLevel(a.top-k.top,c)+"px"):(b.style.height="1em",b.style.top="5%")}var b,p,r,d=!0,k=!1,a=!1,e,h=new core.DomUtils;this.handleUpdate=n;this.refreshCursorBlinking=function(){c||g.getSelectedRange().collapsed?(k=!0,m(!0)):(k=!1,b.style.opacity= +"0")};this.setFocus=function(){k=!0;p.markAsFocussed(!0);m(!0)};this.removeFocus=function(){k=!1;p.markAsFocussed(!1);b.style.opacity="1"};this.show=function(){d=!0;n();p.markAsFocussed(!0)};this.hide=function(){d=!1;n();p.markAsFocussed(!1)};this.setAvatarImageUrl=function(a){p.setImageUrl(a)};this.setColor=function(a){b.style.borderColor=a;p.setColor(a)};this.getCursor=function(){return g};this.getFocusElement=function(){return b};this.toggleHandleVisibility=function(){p.isVisible()?p.hide():p.show()}; +this.showHandle=function(){p.show()};this.hideHandle=function(){p.hide()};this.ensureVisible=function(){var a,c,d,e,f=g.getOdtDocument().getOdfCanvas().getElement().parentNode,k;d=f.offsetWidth-f.clientWidth+5;e=f.offsetHeight-f.clientHeight+5;k=b.getBoundingClientRect();a=k.left-d;c=k.top-e;d=k.right+d;e=k.bottom+e;k=f.getBoundingClientRect();ck.bottom&&(f.scrollTop+=e-k.bottom);ak.right&&(f.scrollLeft+=d-k.right);n()};this.destroy=function(a){p.destroy(function(c){c? +a(c):(r.removeChild(b),a())})};(function(){var a=g.getOdtDocument().getDOM();b=a.createElementNS(a.documentElement.namespaceURI,"span");b.style.top="5%";r=g.getNode();r.appendChild(b);p=new gui.Avatar(r,l);n()})()}; +// Input 77 /* Copyright (C) 2013 KO GmbH @@ -2178,8 +2344,8 @@ q()};this.destroy=function(b){d.destroy(function(c){c?b(c):(f.removeChild(a),b() @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -gui.PlainTextPasteboard=function(h,m){function e(e,h){e.init(h);return e}this.createPasteOps=function(p){var l=h.getCursorPosition(m),q=l,a=[];p.replace(/\r/g,"").split("\n").forEach(function(d){a.push(e(new ops.OpSplitParagraph,{memberid:m,position:q}));q+=1;a.push(e(new ops.OpInsertText,{memberid:m,position:q,text:d}));q+=d.length});a.push(e(new ops.OpRemoveText,{memberid:m,position:l,length:1}));return a}}; -// Input 72 +gui.PlainTextPasteboard=function(g,l){function c(c,f){c.init(f);return c}this.createPasteOps=function(m){var f=g.getCursorPosition(l),n=f,b=[];m.replace(/\r/g,"").split("\n").forEach(function(f){b.push(c(new ops.OpSplitParagraph,{memberid:l,position:n}));n+=1;b.push(c(new ops.OpInsertText,{memberid:l,position:n,text:f}));n+=f.length});b.push(c(new ops.OpRemoveText,{memberid:l,position:f,length:1}));return b}}; +// Input 78 /* Copyright (C) 2013 KO GmbH @@ -2218,9 +2384,9 @@ gui.PlainTextPasteboard=function(h,m){function e(e,h){e.init(h);return e}this.cr @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.Namespaces");runtime.loadClass("xmldom.LSSerializer");runtime.loadClass("odf.OdfNodeFilter");runtime.loadClass("odf.TextSerializer"); -gui.Clipboard=function(){var h,m,e;this.setDataFromRange=function(e,l){var q=!0,a,d=e.clipboardData;a=runtime.getWindow();var f=l.startContainer.ownerDocument;!d&&a&&(d=a.clipboardData);d?(f=f.createElement("span"),f.appendChild(l.cloneContents()),a=d.setData("text/plain",m.writeToString(f)),q=q&&a,a=d.setData("text/html",h.writeToString(f,odf.Namespaces.namespaceMap)),q=q&&a,e.preventDefault()):q=!1;return q};h=new xmldom.LSSerializer;m=new odf.TextSerializer;e=new odf.OdfNodeFilter;h.filter=e;m.filter= -e}; -// Input 73 +gui.Clipboard=function(){var g,l,c;this.setDataFromRange=function(c,f){var n=!0,b,p=c.clipboardData;b=runtime.getWindow();var r=f.startContainer.ownerDocument;!p&&b&&(p=b.clipboardData);p?(r=r.createElement("span"),r.appendChild(f.cloneContents()),b=p.setData("text/plain",l.writeToString(r)),n=n&&b,b=p.setData("text/html",g.writeToString(r,odf.Namespaces.namespaceMap)),n=n&&b,c.preventDefault()):n=!1;return n};g=new xmldom.LSSerializer;l=new odf.TextSerializer;c=new odf.OdfNodeFilter;g.filter=c;l.filter= +c}; +// Input 79 /* Copyright (C) 2013 KO GmbH @@ -2259,15 +2425,15 @@ e}; @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.EventNotifier");runtime.loadClass("core.Utils");runtime.loadClass("ops.OpApplyDirectStyling");runtime.loadClass("gui.StyleHelper"); -gui.DirectTextStyler=function(h,m){function e(a,b){for(var c=0,d=b[c];d&&a;)a=a[d],c+=1,d=b[c];return b.length===c?a:void 0}function p(a,b){var c=e(a[0],b);return a.every(function(a){return c===e(a,b)})?c:void 0}function l(){var a=t.getCursor(m),a=(a=a&&a.getSelectedRange())&&s.getAppliedStyles(a)||[];a[0]&&A&&(a[0]=v.mergeObjects(a[0],A));return a}function q(){function a(b,d,f){b!==d&&(void 0===c&&(c={}),c[f]=d);return d}var b,c;C=l();I=a(I,C?s.isBold(C):!1,"isBold");z=a(z,C?s.isItalic(C):!1,"isItalic"); -M=a(M,C?s.hasUnderline(C):!1,"hasUnderline");H=a(H,C?s.hasStrikeThrough(C):!1,"hasStrikeThrough");b=C&&p(C,["style:text-properties","fo:font-size"]);R=a(R,b&&parseFloat(b),"fontSize");Z=a(Z,C&&p(C,["style:text-properties","style:font-name"]),"fontName");c&&D.emit(gui.DirectTextStyler.textStylingChanged,c)}function a(a){a.getMemberId()===m&&q()}function d(a){a===m&&q()}function f(a){a.getMemberId()===m&&q()}function b(){q()}function k(a){var b=t.getCursor(m);b&&t.getParagraphElement(b.getNode())=== -a.paragraphElement&&q()}function c(a,b){var c=t.getCursor(m);if(!c)return!1;c=s.getAppliedStyles(c.getSelectedRange());b(!a(c));return!0}function g(a){var b=t.getCursorSelection(m),c={"style:text-properties":a};0!==b.length?(a=new ops.OpApplyDirectStyling,a.init({memberid:m,position:b.position,length:b.length,setProperties:c}),h.enqueue([a])):(A=v.mergeObjects(A||{},c),q())}function n(a,b){var c={};c[a]=b;g(c)}function r(a){a=a.spec();A&&a.memberid===m&&"SplitParagraph"!==a.optype&&(A=null,q())}function u(a){n("fo:font-weight", -a?"bold":"normal")}function y(a){n("fo:font-style",a?"italic":"normal")}function x(a){n("style:text-underline-style",a?"solid":"none")}function w(a){n("style:text-line-through-style",a?"solid":"none")}var v=new core.Utils,t=h.getOdtDocument(),s=new gui.StyleHelper(t.getFormatting()),D=new core.EventNotifier([gui.DirectTextStyler.textStylingChanged]),A,C=[],I=!1,z=!1,M=!1,H=!1,R,Z;this.formatTextSelection=g;this.createCursorStyleOp=function(a,b){var c=null;A&&(c=new ops.OpApplyDirectStyling,c.init({memberid:m, -position:a,length:b,setProperties:A}),A=null,q());return c};this.setBold=u;this.setItalic=y;this.setHasUnderline=x;this.setHasStrikethrough=w;this.setFontSize=function(a){n("fo:font-size",a+"pt")};this.setFontName=function(a){n("style:font-name",a)};this.getAppliedStyles=function(){return C};this.toggleBold=c.bind(this,s.isBold,u);this.toggleItalic=c.bind(this,s.isItalic,y);this.toggleUnderline=c.bind(this,s.hasUnderline,x);this.toggleStrikethrough=c.bind(this,s.hasStrikeThrough,w);this.isBold=function(){return I}; -this.isItalic=function(){return z};this.hasUnderline=function(){return M};this.hasStrikeThrough=function(){return H};this.fontSize=function(){return R};this.fontName=function(){return Z};this.subscribe=function(a,b){D.subscribe(a,b)};this.unsubscribe=function(a,b){D.unsubscribe(a,b)};this.destroy=function(c){t.unsubscribe(ops.OdtDocument.signalCursorAdded,a);t.unsubscribe(ops.OdtDocument.signalCursorRemoved,d);t.unsubscribe(ops.OdtDocument.signalCursorMoved,f);t.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, -b);t.unsubscribe(ops.OdtDocument.signalParagraphChanged,k);t.unsubscribe(ops.OdtDocument.signalOperationExecuted,r);c()};t.subscribe(ops.OdtDocument.signalCursorAdded,a);t.subscribe(ops.OdtDocument.signalCursorRemoved,d);t.subscribe(ops.OdtDocument.signalCursorMoved,f);t.subscribe(ops.OdtDocument.signalParagraphStyleModified,b);t.subscribe(ops.OdtDocument.signalParagraphChanged,k);t.subscribe(ops.OdtDocument.signalOperationExecuted,r);q()};gui.DirectTextStyler.textStylingChanged="textStyling/changed"; +gui.DirectTextStyler=function(g,l){function c(a,b){for(var c=0,d=b[c];d&&a;)a=a[d],c+=1,d=b[c];return b.length===c?a:void 0}function m(a,b){var d=c(a[0],b);return a.every(function(a){return d===c(a,b)})?d:void 0}function f(){var a=t.getCursor(l),a=(a=a&&a.getSelectedRange())&&s.getAppliedStyles(a)||[];a[0]&&A&&(a[0]=w.mergeObjects(a[0],A));return a}function n(){function a(b,d,e){b!==d&&(void 0===c&&(c={}),c[e]=d);return d}var b,c;B=f();M=a(M,B?s.isBold(B):!1,"isBold");z=a(z,B?s.isItalic(B):!1,"isItalic"); +K=a(K,B?s.hasUnderline(B):!1,"hasUnderline");F=a(F,B?s.hasStrikeThrough(B):!1,"hasStrikeThrough");b=B&&m(B,["style:text-properties","fo:font-size"]);Q=a(Q,b&&parseFloat(b),"fontSize");$=a($,B&&m(B,["style:text-properties","style:font-name"]),"fontName");c&&D.emit(gui.DirectTextStyler.textStylingChanged,c)}function b(a){a.getMemberId()===l&&n()}function p(a){a===l&&n()}function r(a){a.getMemberId()===l&&n()}function d(){n()}function k(a){var b=t.getCursor(l);b&&t.getParagraphElement(b.getNode())=== +a.paragraphElement&&n()}function a(a,b){var c=t.getCursor(l);if(!c)return!1;c=s.getAppliedStyles(c.getSelectedRange());b(!a(c));return!0}function e(a){var b=t.getCursorSelection(l),c={"style:text-properties":a};0!==b.length?(a=new ops.OpApplyDirectStyling,a.init({memberid:l,position:b.position,length:b.length,setProperties:c}),g.enqueue([a])):(A=w.mergeObjects(A||{},c),n())}function h(a,b){var c={};c[a]=b;e(c)}function q(a){a=a.spec();A&&a.memberid===l&&"SplitParagraph"!==a.optype&&(A=null,n())}function u(a){h("fo:font-weight", +a?"bold":"normal")}function x(a){h("fo:font-style",a?"italic":"normal")}function v(a){h("style:text-underline-style",a?"solid":"none")}function y(a){h("style:text-line-through-style",a?"solid":"none")}var w=new core.Utils,t=g.getOdtDocument(),s=new gui.StyleHelper(t.getFormatting()),D=new core.EventNotifier([gui.DirectTextStyler.textStylingChanged]),A,B=[],M=!1,z=!1,K=!1,F=!1,Q,$;this.formatTextSelection=e;this.createCursorStyleOp=function(a,b){var c=null;A&&(c=new ops.OpApplyDirectStyling,c.init({memberid:l, +position:a,length:b,setProperties:A}),A=null,n());return c};this.setBold=u;this.setItalic=x;this.setHasUnderline=v;this.setHasStrikethrough=y;this.setFontSize=function(a){h("fo:font-size",a+"pt")};this.setFontName=function(a){h("style:font-name",a)};this.getAppliedStyles=function(){return B};this.toggleBold=a.bind(this,s.isBold,u);this.toggleItalic=a.bind(this,s.isItalic,x);this.toggleUnderline=a.bind(this,s.hasUnderline,v);this.toggleStrikethrough=a.bind(this,s.hasStrikeThrough,y);this.isBold=function(){return M}; +this.isItalic=function(){return z};this.hasUnderline=function(){return K};this.hasStrikeThrough=function(){return F};this.fontSize=function(){return Q};this.fontName=function(){return $};this.subscribe=function(a,b){D.subscribe(a,b)};this.unsubscribe=function(a,b){D.unsubscribe(a,b)};this.destroy=function(a){t.unsubscribe(ops.OdtDocument.signalCursorAdded,b);t.unsubscribe(ops.OdtDocument.signalCursorRemoved,p);t.unsubscribe(ops.OdtDocument.signalCursorMoved,r);t.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, +d);t.unsubscribe(ops.OdtDocument.signalParagraphChanged,k);t.unsubscribe(ops.OdtDocument.signalOperationExecuted,q);a()};t.subscribe(ops.OdtDocument.signalCursorAdded,b);t.subscribe(ops.OdtDocument.signalCursorRemoved,p);t.subscribe(ops.OdtDocument.signalCursorMoved,r);t.subscribe(ops.OdtDocument.signalParagraphStyleModified,d);t.subscribe(ops.OdtDocument.signalParagraphChanged,k);t.subscribe(ops.OdtDocument.signalOperationExecuted,q);n()};gui.DirectTextStyler.textStylingChanged="textStyling/changed"; (function(){return gui.DirectTextStyler})(); -// Input 74 +// Input 80 /* Copyright (C) 2013 KO GmbH @@ -2306,13 +2472,13 @@ b);t.unsubscribe(ops.OdtDocument.signalParagraphChanged,k);t.unsubscribe(ops.Odt @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.EventNotifier");runtime.loadClass("core.Utils");runtime.loadClass("odf.OdfUtils");runtime.loadClass("ops.OpAddStyle");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("gui.StyleHelper"); -gui.DirectParagraphStyler=function(h,m,e){function p(){function a(b,d,f){b!==d&&(void 0===c&&(c={}),c[f]=d);return d}var b=n.getCursor(m),b=b&&b.getSelectedRange(),c;w=a(w,b?y.isAlignedLeft(b):!1,"isAlignedLeft");v=a(v,b?y.isAlignedCenter(b):!1,"isAlignedCenter");t=a(t,b?y.isAlignedRight(b):!1,"isAlignedRight");s=a(s,b?y.isAlignedJustified(b):!1,"isAlignedJustified");c&&x.emit(gui.DirectParagraphStyler.paragraphStylingChanged,c)}function l(a){a.getMemberId()===m&&p()}function q(a){a===m&&p()}function a(a){a.getMemberId()=== -m&&p()}function d(){p()}function f(a){var b=n.getCursor(m);b&&n.getParagraphElement(b.getNode())===a.paragraphElement&&p()}function b(a){var b=n.getCursor(m).getSelectedRange(),c=n.getCursorPosition(m),b=u.getParagraphElements(b),d=n.getFormatting();b.forEach(function(b){var f=c+n.getDistanceFromCursor(m,b,0),g=b.getAttributeNS(odf.Namespaces.textns,"style-name");b=e.generateStyleName();var k,f=f+1;g&&(k=d.createDerivedStyleObject(g,"paragraph",{}));k=a(k||{});g=new ops.OpAddStyle;g.init({memberid:m, -styleName:b,styleFamily:"paragraph",isAutomaticStyle:!0,setProperties:k});k=new ops.OpSetParagraphStyle;k.init({memberid:m,styleName:b,position:f});h.enqueue([g,k])})}function k(a){b(function(b){return r.mergeObjects(b,a)})}function c(a){k({"style:paragraph-properties":{"fo:text-align":a}})}function g(a,b){var c=n.getFormatting().getDefaultTabStopDistance(),d=b["style:paragraph-properties"],d=(d=d&&d["fo:margin-left"])&&u.parseLength(d);return r.mergeObjects(b,{"style:paragraph-properties":{"fo:margin-left":d&& -d.unit===c.unit?d.value+a*c.value+d.unit:a*c.value+c.unit}})}var n=h.getOdtDocument(),r=new core.Utils,u=new odf.OdfUtils,y=new gui.StyleHelper(n.getFormatting()),x=new core.EventNotifier([gui.DirectParagraphStyler.paragraphStylingChanged]),w,v,t,s;this.isAlignedLeft=function(){return w};this.isAlignedCenter=function(){return v};this.isAlignedRight=function(){return t};this.isAlignedJustified=function(){return s};this.alignParagraphLeft=function(){c("left");return!0};this.alignParagraphCenter=function(){c("center"); -return!0};this.alignParagraphRight=function(){c("right");return!0};this.alignParagraphJustified=function(){c("justify");return!0};this.indent=function(){b(g.bind(null,1));return!0};this.outdent=function(){b(g.bind(null,-1));return!0};this.subscribe=function(a,b){x.subscribe(a,b)};this.unsubscribe=function(a,b){x.unsubscribe(a,b)};this.destroy=function(b){n.unsubscribe(ops.OdtDocument.signalCursorAdded,l);n.unsubscribe(ops.OdtDocument.signalCursorRemoved,q);n.unsubscribe(ops.OdtDocument.signalCursorMoved, -a);n.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,d);n.unsubscribe(ops.OdtDocument.signalParagraphChanged,f);b()};n.subscribe(ops.OdtDocument.signalCursorAdded,l);n.subscribe(ops.OdtDocument.signalCursorRemoved,q);n.subscribe(ops.OdtDocument.signalCursorMoved,a);n.subscribe(ops.OdtDocument.signalParagraphStyleModified,d);n.subscribe(ops.OdtDocument.signalParagraphChanged,f);p()};gui.DirectParagraphStyler.paragraphStylingChanged="paragraphStyling/changed";(function(){return gui.DirectParagraphStyler})(); -// Input 75 +gui.DirectParagraphStyler=function(g,l,c){function m(){function a(b,d,e){b!==d&&(void 0===c&&(c={}),c[e]=d);return d}var b=h.getCursor(l),b=b&&b.getSelectedRange(),c;y=a(y,b?x.isAlignedLeft(b):!1,"isAlignedLeft");w=a(w,b?x.isAlignedCenter(b):!1,"isAlignedCenter");t=a(t,b?x.isAlignedRight(b):!1,"isAlignedRight");s=a(s,b?x.isAlignedJustified(b):!1,"isAlignedJustified");c&&v.emit(gui.DirectParagraphStyler.paragraphStylingChanged,c)}function f(a){a.getMemberId()===l&&m()}function n(a){a===l&&m()}function b(a){a.getMemberId()=== +l&&m()}function p(){m()}function r(a){var b=h.getCursor(l);b&&h.getParagraphElement(b.getNode())===a.paragraphElement&&m()}function d(a){var b=h.getCursor(l).getSelectedRange(),d=h.getCursorPosition(l),b=u.getParagraphElements(b),e=h.getFormatting();b.forEach(function(b){var f=d+h.getDistanceFromCursor(l,b,0),k=b.getAttributeNS(odf.Namespaces.textns,"style-name");b=c.generateStyleName();var m,f=f+1;k&&(m=e.createDerivedStyleObject(k,"paragraph",{}));m=a(m||{});k=new ops.OpAddStyle;k.init({memberid:l, +styleName:b,styleFamily:"paragraph",isAutomaticStyle:!0,setProperties:m});m=new ops.OpSetParagraphStyle;m.init({memberid:l,styleName:b,position:f});g.enqueue([k,m])})}function k(a){d(function(b){return q.mergeObjects(b,a)})}function a(a){k({"style:paragraph-properties":{"fo:text-align":a}})}function e(a,b){var c=h.getFormatting().getDefaultTabStopDistance(),d=b["style:paragraph-properties"],d=(d=d&&d["fo:margin-left"])&&u.parseLength(d);return q.mergeObjects(b,{"style:paragraph-properties":{"fo:margin-left":d&& +d.unit===c.unit?d.value+a*c.value+d.unit:a*c.value+c.unit}})}var h=g.getOdtDocument(),q=new core.Utils,u=new odf.OdfUtils,x=new gui.StyleHelper(h.getFormatting()),v=new core.EventNotifier([gui.DirectParagraphStyler.paragraphStylingChanged]),y,w,t,s;this.isAlignedLeft=function(){return y};this.isAlignedCenter=function(){return w};this.isAlignedRight=function(){return t};this.isAlignedJustified=function(){return s};this.alignParagraphLeft=function(){a("left");return!0};this.alignParagraphCenter=function(){a("center"); +return!0};this.alignParagraphRight=function(){a("right");return!0};this.alignParagraphJustified=function(){a("justify");return!0};this.indent=function(){d(e.bind(null,1));return!0};this.outdent=function(){d(e.bind(null,-1));return!0};this.subscribe=function(a,b){v.subscribe(a,b)};this.unsubscribe=function(a,b){v.unsubscribe(a,b)};this.destroy=function(a){h.unsubscribe(ops.OdtDocument.signalCursorAdded,f);h.unsubscribe(ops.OdtDocument.signalCursorRemoved,n);h.unsubscribe(ops.OdtDocument.signalCursorMoved, +b);h.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,p);h.unsubscribe(ops.OdtDocument.signalParagraphChanged,r);a()};h.subscribe(ops.OdtDocument.signalCursorAdded,f);h.subscribe(ops.OdtDocument.signalCursorRemoved,n);h.subscribe(ops.OdtDocument.signalCursorMoved,b);h.subscribe(ops.OdtDocument.signalParagraphStyleModified,p);h.subscribe(ops.OdtDocument.signalParagraphChanged,r);m()};gui.DirectParagraphStyler.paragraphStylingChanged="paragraphStyling/changed";(function(){return gui.DirectParagraphStyler})(); +// Input 81 /* Copyright (C) 2012-2013 KO GmbH @@ -2350,20 +2516,20 @@ a);n.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,d);n.unsubscribe(o @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -gui.KeyboardHandler=function(){function h(e,h){h||(h=m.None);return e+":"+h}var m=gui.KeyboardHandler.Modifier,e=null,p={};this.setDefault=function(h){e=h};this.bind=function(e,m,a){e=h(e,m);runtime.assert(!1===p.hasOwnProperty(e),"tried to overwrite the callback handler of key combo: "+e);p[e]=a};this.unbind=function(e,m){var a=h(e,m);delete p[a]};this.reset=function(){e=null;p={}};this.handleEvent=function(l){var q=l.keyCode,a=m.None;l.metaKey&&(a|=m.Meta);l.ctrlKey&&(a|=m.Ctrl);l.altKey&&(a|=m.Alt); -l.shiftKey&&(a|=m.Shift);q=h(q,a);q=p[q];a=!1;q?a=q():null!==e&&(a=e(l));a&&(l.preventDefault?l.preventDefault():l.returnValue=!1)}};gui.KeyboardHandler.Modifier={None:0,Meta:1,Ctrl:2,Alt:4,CtrlAlt:6,Shift:8,MetaShift:9,CtrlShift:10,AltShift:12};gui.KeyboardHandler.KeyCode={Backspace:8,Tab:9,Clear:12,Enter:13,End:35,Home:36,Left:37,Up:38,Right:39,Down:40,Delete:46,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90};(function(){return gui.KeyboardHandler})(); -// Input 76 +gui.KeyboardHandler=function(){function g(c,g){g||(g=l.None);return c+":"+g}var l=gui.KeyboardHandler.Modifier,c=null,m={};this.setDefault=function(f){c=f};this.bind=function(c,l,b){c=g(c,l);runtime.assert(!1===m.hasOwnProperty(c),"tried to overwrite the callback handler of key combo: "+c);m[c]=b};this.unbind=function(c,l){var b=g(c,l);delete m[b]};this.reset=function(){c=null;m={}};this.handleEvent=function(f){var n=f.keyCode,b=l.None;f.metaKey&&(b|=l.Meta);f.ctrlKey&&(b|=l.Ctrl);f.altKey&&(b|=l.Alt); +f.shiftKey&&(b|=l.Shift);n=g(n,b);n=m[n];b=!1;n?b=n():null!==c&&(b=c(f));b&&(f.preventDefault?f.preventDefault():f.returnValue=!1)}};gui.KeyboardHandler.Modifier={None:0,Meta:1,Ctrl:2,Alt:4,CtrlAlt:6,Shift:8,MetaShift:9,CtrlShift:10,AltShift:12};gui.KeyboardHandler.KeyCode={Backspace:8,Tab:9,Clear:12,Enter:13,End:35,Home:36,Left:37,Up:38,Right:39,Down:40,Delete:46,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90};(function(){return gui.KeyboardHandler})(); +// Input 82 runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.ObjectNameGenerator"); -gui.ImageManager=function(h,m,e){var p={"image/gif":".gif","image/jpeg":".jpg","image/png":".png"},l=odf.Namespaces.textns,q=h.getOdtDocument(),a=q.getFormatting(),d={};this.insertImage=function(f,b,k,c){var g;runtime.assert(0g.width&&(n=g.width/k);c>g.height&&(r=g.height/c);n=Math.min(n,r);g=k*n;k=c*n;r=q.getOdfCanvas().odfContainer().rootElement.styles;c=f.toLowerCase();var n=p.hasOwnProperty(c)?p[c]:null,u;c=[];runtime.assert(null!==n,"Image type is not supported: "+f);n="Pictures/"+e.generateImageName()+n;u=new ops.OpSetBlob;u.init({memberid:m,filename:n,mimetype:f,content:b});c.push(u);a.getStyleElement("Graphics","graphic",[r])||(f=new ops.OpAddStyle,f.init({memberid:m,styleName:"Graphics",styleFamily:"graphic", -isAutomaticStyle:!1,setProperties:{"style:graphic-properties":{"text:anchor-type":"paragraph","svg:x":"0cm","svg:y":"0cm","style:wrap":"dynamic","style:number-wrapped-paragraphs":"no-limit","style:wrap-contour":"false","style:vertical-pos":"top","style:vertical-rel":"paragraph","style:horizontal-pos":"center","style:horizontal-rel":"paragraph"}}}),c.push(f));f=e.generateStyleName();b=new ops.OpAddStyle;b.init({memberid:m,styleName:f,styleFamily:"graphic",isAutomaticStyle:!0,setProperties:{"style:parent-style-name":"Graphics", +gui.ImageManager=function(g,l,c){var m={"image/gif":".gif","image/jpeg":".jpg","image/png":".png"},f=odf.Namespaces.textns,n=g.getOdtDocument(),b=n.getFormatting(),p={};this.insertImage=function(r,d,k,a){var e;runtime.assert(0e.width&&(h=e.width/k);a>e.height&&(q=e.height/a);h=Math.min(h,q);e=k*h;k=a*h;q=n.getOdfCanvas().odfContainer().rootElement.styles;a=r.toLowerCase();var h=m.hasOwnProperty(a)?m[a]:null,u;a=[];runtime.assert(null!==h,"Image type is not supported: "+r);h="Pictures/"+c.generateImageName()+h;u=new ops.OpSetBlob;u.init({memberid:l,filename:h,mimetype:r,content:d});a.push(u);b.getStyleElement("Graphics","graphic",[q])||(r=new ops.OpAddStyle,r.init({memberid:l,styleName:"Graphics",styleFamily:"graphic", +isAutomaticStyle:!1,setProperties:{"style:graphic-properties":{"text:anchor-type":"paragraph","svg:x":"0cm","svg:y":"0cm","style:wrap":"dynamic","style:number-wrapped-paragraphs":"no-limit","style:wrap-contour":"false","style:vertical-pos":"top","style:vertical-rel":"paragraph","style:horizontal-pos":"center","style:horizontal-rel":"paragraph"}}}),a.push(r));r=c.generateStyleName();d=new ops.OpAddStyle;d.init({memberid:l,styleName:r,styleFamily:"graphic",isAutomaticStyle:!0,setProperties:{"style:parent-style-name":"Graphics", "style:graphic-properties":{"style:vertical-pos":"top","style:vertical-rel":"baseline","style:horizontal-pos":"center","style:horizontal-rel":"paragraph","fo:background-color":"transparent","style:background-transparency":"100%","style:shadow":"none","style:mirror":"none","fo:clip":"rect(0cm, 0cm, 0cm, 0cm)","draw:luminance":"0%","draw:contrast":"0%","draw:red":"0%","draw:green":"0%","draw:blue":"0%","draw:gamma":"100%","draw:color-inversion":"false","draw:image-opacity":"100%","draw:color-mode":"standard"}}}); -c.push(b);u=new ops.OpInsertImage;u.init({memberid:m,position:q.getCursorPosition(m),filename:n,frameWidth:g+"cm",frameHeight:k+"cm",frameStyleName:f,frameName:e.generateFrameName()});c.push(u);h.enqueue(c)}}; -// Input 77 +a.push(d);u=new ops.OpInsertImage;u.init({memberid:l,position:n.getCursorPosition(l),filename:h,frameWidth:e+"cm",frameHeight:k+"cm",frameStyleName:r,frameName:c.generateFrameName()});a.push(u);g.enqueue(a)}}; +// Input 83 runtime.loadClass("odf.Namespaces"); -gui.ImageSelector=function(h){function m(){var a=h.getSizer(),d,f;d=l.createElement("div");d.id="imageSelector";d.style.borderWidth="1px";a.appendChild(d);p.forEach(function(a){f=l.createElement("div");f.className=a;d.appendChild(f)});return d}var e=odf.Namespaces.svgns,p="topLeft topRight bottomRight bottomLeft topMiddle rightMiddle bottomMiddle leftMiddle".split(" "),l=h.getElement().ownerDocument,q=!1;this.select=function(a){var d,f,b=l.getElementById("imageSelector");b||(b=m());q=!0;d=b.parentNode; -f=a.getBoundingClientRect();var k=d.getBoundingClientRect(),c=h.getZoomLevel();d=(f.left-k.left)/c-1;f=(f.top-k.top)/c-1;b.style.display="block";b.style.left=d+"px";b.style.top=f+"px";b.style.width=a.getAttributeNS(e,"width");b.style.height=a.getAttributeNS(e,"height")};this.clearSelection=function(){var a;q&&(a=l.getElementById("imageSelector"))&&(a.style.display="none");q=!1};this.isSelectorElement=function(a){var d=l.getElementById("imageSelector");return d?a===d||a.parentNode===d:!1}}; -// Input 78 +gui.ImageSelector=function(g){function l(){var b=g.getSizer(),c,l;c=f.createElement("div");c.id="imageSelector";c.style.borderWidth="1px";b.appendChild(c);m.forEach(function(b){l=f.createElement("div");l.className=b;c.appendChild(l)});return c}var c=odf.Namespaces.svgns,m="topLeft topRight bottomRight bottomLeft topMiddle rightMiddle bottomMiddle leftMiddle".split(" "),f=g.getElement().ownerDocument,n=!1;this.select=function(b){var m,r,d=f.getElementById("imageSelector");d||(d=l());n=!0;m=d.parentNode; +r=b.getBoundingClientRect();var k=m.getBoundingClientRect(),a=g.getZoomLevel();m=(r.left-k.left)/a-1;r=(r.top-k.top)/a-1;d.style.display="block";d.style.left=m+"px";d.style.top=r+"px";d.style.width=b.getAttributeNS(c,"width");d.style.height=b.getAttributeNS(c,"height")};this.clearSelection=function(){var b;n&&(b=f.getElementById("imageSelector"))&&(b.style.display="none");n=!1};this.isSelectorElement=function(b){var c=f.getElementById("imageSelector");return c?b===c||b.parentNode===c:!1}}; +// Input 84 /* Copyright (C) 2013 KO GmbH @@ -2402,165 +2568,75 @@ f=a.getBoundingClientRect();var k=d.getBoundingClientRect(),c=h.getZoomLevel();d @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.PositionFilter"); -gui.TextManipulator=function(h,m,e){function p(a){var b=new ops.OpRemoveText;b.init({memberid:m,position:a.position,length:a.length});return b}function l(a){0>a.length&&(a.position+=a.length,a.length=-a.length);return a}function q(f,b){var e=new core.PositionFilterChain,c=gui.SelectionMover.createPositionIterator(a.getRootElement(f)),g=b?c.nextPosition:c.previousPosition;e.addFilter("BaseFilter",a.getPositionFilter());e.addFilter("RootFilter",a.createRootFilter(m));for(c.setUnfilteredPosition(f,0);g();)if(e.acceptPosition(c)=== -d)return!0;return!1}var a=h.getOdtDocument(),d=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.enqueueParagraphSplittingOps=function(){var d=l(a.getCursorSelection(m)),b,e=[];0b.length&&(b.position+=b.length,b.length=-b.length);return b}function n(c,d){var f=new core.PositionFilterChain,a=gui.SelectionMover.createPositionIterator(b.getRootElement(c)),e=d?a.nextPosition:a.previousPosition;f.addFilter("BaseFilter",b.getPositionFilter());f.addFilter("RootFilter",b.createRootFilter(l));for(a.setUnfilteredPosition(c,0);e();)if(f.acceptPosition(a)=== +p)return!0;return!1}var b=g.getOdtDocument(),p=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.enqueueParagraphSplittingOps=function(){var c=f(b.getCursorSelection(l)),d,k=[];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. - - You should have received a copy of the GNU Affero General Public License - along with this code. If not, see . - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: https://github.com/kogmbh/WebODF/ -*/ -runtime.loadClass("core.EventNotifier");runtime.loadClass("core.PositionFilter");runtime.loadClass("ops.OpAddAnnotation");runtime.loadClass("ops.OpRemoveAnnotation");runtime.loadClass("gui.SelectionMover"); -gui.AnnotationManager=function(h,m){function e(){var e=a.getCursor(m),e=e&&e.getNode(),c;if(c=e){a:{for(c=a.getRootNode();e&&e!==c;){if(e.namespaceURI===b&&"annotation"===e.localName){e=!0;break a}e=e.parentNode}e=!1}c=!e}e=c;e!==d&&(d=e,f.emit(gui.AnnotationManager.annotatableChanged,d))}function p(a){a.getMemberId()===m&&e()}function l(a){a===m&&e()}function q(a){a.getMemberId()===m&&e()}var a=h.getOdtDocument(),d=!1,f=new core.EventNotifier([gui.AnnotationManager.annotatableChanged]),b=odf.Namespaces.officens; -this.isAnnotatable=function(){return d};this.addAnnotation=function(){var b=new ops.OpAddAnnotation,c=a.getCursorSelection(m),f=c.length,c=c.position;d&&(c=0<=f?c:c+f,f=Math.abs(f),b.init({memberid:m,position:c,length:f,name:m+Date.now()}),h.enqueue([b]))};this.removeAnnotation=function(b){var c,d;c=a.convertDomPointToCursorStep(b,0)+1;d=a.convertDomPointToCursorStep(b,b.childNodes.length);b=new ops.OpRemoveAnnotation;b.init({memberid:m,position:c,length:d-c});d=new ops.OpMoveCursor;d.init({memberid:m, -position:0 + WebODF is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License (GNU AGPL) + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. - @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. + WebODF is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License - along with this code. If not, see . - - 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. + along with WebODF. If not, see . @licend - @source: http://www.webodf.org/ - @source: https://github.com/kogmbh/WebODF/ -*/ -ops.MemberModel=function(){};ops.MemberModel.prototype.getMemberDetailsAndUpdates=function(h,m){};ops.MemberModel.prototype.unsubscribeMemberDetailsUpdates=function(h,m){};ops.MemberModel.prototype.close=function(h){}; -// Input 83 -/* - - 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. - - You should have received a copy of the GNU Affero General Public License - along with this code. If not, see . - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.TrivialMemberModel=function(){this.getMemberDetailsAndUpdates=function(h,m){m(h,{memberid:h,fullname:runtime.tr("Unknown Author"),color:"black",imageurl:"avatar-joe.png"})};this.unsubscribeMemberDetailsUpdates=function(h,m){};this.close=function(h){h()}}; -// Input 84 +runtime.loadClass("core.EventNotifier");runtime.loadClass("core.PositionFilter");runtime.loadClass("ops.OpAddAnnotation");runtime.loadClass("ops.OpRemoveAnnotation");runtime.loadClass("gui.SelectionMover"); +gui.AnnotationController=function(g,l){function c(){var c=b.getCursor(l),c=c&&c.getNode(),a;if(a=c){a:{for(a=b.getRootNode();c&&c!==a;){if(c.namespaceURI===d&&"annotation"===c.localName){c=!0;break a}c=c.parentNode}c=!1}a=!c}c=a;c!==p&&(p=c,r.emit(gui.AnnotationController.annotatableChanged,p))}function m(b){b.getMemberId()===l&&c()}function f(b){b===l&&c()}function n(b){b.getMemberId()===l&&c()}var b=g.getOdtDocument(),p=!1,r=new core.EventNotifier([gui.AnnotationController.annotatableChanged]), +d=odf.Namespaces.officens;this.isAnnotatable=function(){return p};this.addAnnotation=function(){var c=new ops.OpAddAnnotation,a=b.getCursorSelection(l),d=a.length,a=a.position;p&&(a=0<=d?a:a+d,d=Math.abs(d),c.init({memberid:l,position:a,length:d,name:l+Date.now()}),g.enqueue([c]))};this.removeAnnotation=function(c){var a,d;a=b.convertDomPointToCursorStep(c,0)+1;d=b.convertDomPointToCursorStep(c,c.childNodes.length);c=new ops.OpRemoveAnnotation;c.init({memberid:l,position:a,length:d-a});d=new ops.OpMoveCursor; +d.init({memberid:l,position:0 @@ -2598,8 +2674,8 @@ ops.TrivialMemberModel=function(){this.getMemberDetailsAndUpdates=function(h,m){ @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFactory=function(h){};ops.OperationRouter.prototype.setPlaybackFunction=function(h){};ops.OperationRouter.prototype.push=function(h){};ops.OperationRouter.prototype.close=function(h){}; -// Input 85 +ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFactory=function(g){};ops.OperationRouter.prototype.setPlaybackFunction=function(g){};ops.OperationRouter.prototype.push=function(g){};ops.OperationRouter.prototype.close=function(g){}; +// Input 89 /* Copyright (C) 2012 KO GmbH @@ -2637,11 +2713,11 @@ ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFacto @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -ops.TrivialOperationRouter=function(){var h,m;this.setOperationFactory=function(e){h=e};this.setPlaybackFunction=function(e){m=e};this.push=function(e){e.forEach(function(e){e=e.spec();e.timestamp=(new Date).getTime();e=h.create(e);m(e)})};this.close=function(e){e()}}; -// Input 86 -gui.EditInfoHandle=function(h){var m=[],e,p=h.ownerDocument,l=p.documentElement.namespaceURI;this.setEdits=function(h){m=h;var a,d,f,b;e.innerHTML="";for(h=0;h @@ -2680,10 +2756,10 @@ b=p.createElementNS(l,"span"),b.className="editInfoTime",b.setAttributeNS("urn:w @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("ops.EditInfo");runtime.loadClass("gui.EditInfoHandle"); -gui.EditInfoMarker=function(h,m){function e(b,d){return runtime.setTimeout(function(){a.style.opacity=b},d)}var p=this,l,q,a,d,f;this.addEdit=function(b,k){var c=Date.now()-k;h.addEdit(b,k);q.setEdits(h.getSortedEdits());a.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",b);d&&runtime.clearTimeout(d);f&&runtime.clearTimeout(f);1E4>c?(e(1,0),d=e(0.5,1E4-c),f=e(0.2,2E4-c)):1E4<=c&&2E4>c?(e(0.5,0),f=e(0.2,2E4-c)):e(0.2,0)};this.getEdits=function(){return h.getEdits()};this.clearEdits=function(){h.clearEdits(); -q.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(){p.hideHandle();a.style.display="none"};this.showHandle=function(){q.show()};this.hideHandle=function(){q.hide()};this.destroy=function(b){l.removeChild(a);q.destroy(function(a){a?b(a):h.destroy(b)})};(function(){var b=h.getOdtDocument().getDOM(); -a=b.createElementNS(b.documentElement.namespaceURI,"div");a.setAttribute("class","editInfoMarker");a.onmouseover=function(){p.showHandle()};a.onmouseout=function(){p.hideHandle()};l=h.getNode();l.appendChild(a);q=new gui.EditInfoHandle(l);m||p.hide()})()}; -// Input 88 +gui.EditInfoMarker=function(g,l){function c(c,f){return runtime.setTimeout(function(){b.style.opacity=c},f)}var m=this,f,n,b,p,r;this.addEdit=function(d,f){var a=Date.now()-f;g.addEdit(d,f);n.setEdits(g.getSortedEdits());b.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",d);p&&runtime.clearTimeout(p);r&&runtime.clearTimeout(r);1E4>a?(c(1,0),p=c(0.5,1E4-a),r=c(0.2,2E4-a)):1E4<=a&&2E4>a?(c(0.5,0),r=c(0.2,2E4-a)):c(0.2,0)};this.getEdits=function(){return g.getEdits()};this.clearEdits=function(){g.clearEdits(); +n.setEdits([]);b.hasAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")&&b.removeAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")};this.getEditInfo=function(){return g};this.show=function(){b.style.display="block"};this.hide=function(){m.hideHandle();b.style.display="none"};this.showHandle=function(){n.show()};this.hideHandle=function(){n.hide()};this.destroy=function(c){f.removeChild(b);n.destroy(function(b){b?c(b):g.destroy(c)})};(function(){var c=g.getOdtDocument().getDOM(); +b=c.createElementNS(c.documentElement.namespaceURI,"div");b.setAttribute("class","editInfoMarker");b.onmouseover=function(){m.showHandle()};b.onmouseout=function(){m.hideHandle()};f=g.getNode();f.appendChild(b);n=new gui.EditInfoHandle(f);l||m.hide()})()}; +// Input 92 /* Copyright (C) 2012-2013 KO GmbH @@ -2721,17 +2797,17 @@ a=b.createElementNS(b.documentElement.namespaceURI,"div");a.setAttribute("class" @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("gui.Caret");runtime.loadClass("ops.TrivialMemberModel");runtime.loadClass("ops.EditInfo");runtime.loadClass("gui.EditInfoMarker");gui.SessionViewOptions=function(){this.caretBlinksOnRangeSelect=this.caretAvatarsInitiallyVisible=this.editInfoMarkersInitiallyVisible=!0}; -gui.SessionView=function(){return function(h,m,e,p,l){function q(a,b,c){function d(b,c,e){c=b+'[editinfo|memberid="'+a+'"]'+e+c;a:{var f=u.firstChild;for(b=b+'[editinfo|memberid="'+a+'"]'+e+"{";f;){if(f.nodeType===Node.TEXT_NODE&&0===f.data.indexOf(b)){b=f;break a}f=f.nextSibling}b=null}b?b.data=c:u.appendChild(document.createTextNode(c))}d("div.editInfoMarker","{ background-color: "+c+"; }","");d("span.editInfoColor","{ background-color: "+c+"; }","");d("span.editInfoAuthor",'{ content: "'+b+'"; }', -":before");d("dc|creator",'{ content: "'+b+'"; display: none;}',":before");d("dc|creator","{ background-color: "+c+"; }","");d("div.selectionOverlay","{ background-color: "+c+";}","")}function a(a){var b,c;for(c in x)x.hasOwnProperty(c)&&(b=x[c],a?b.show():b.hide())}function d(a){p.getCarets().forEach(function(b){a?b.showHandle():b.hideHandle()})}function f(a,b){var c=p.getCaret(a);b?(c&&(c.setAvatarImageUrl(b.imageurl),c.setColor(b.color)),q(a,b.fullname,b.color),m===a&&q("",b.fullname,b.color)): -runtime.log('MemberModel sent undefined data for member "'+a+'".')}function b(a){var b=a.getMemberId(),c=e.getMemberModel();p.registerCursor(a,v,t);l.registerCursor(a,!0);f(b,null);c.getMemberDetailsAndUpdates(b,f);runtime.log("+++ View here +++ eagerly created an Caret for '"+b+"'! +++")}function k(a){a=a.getMemberId();var b=l.getSelectionView(m),c=l.getSelectionView(gui.ShadowCursor.ShadowCursorMemberId),d=p.getCaret(m);a===m?(c.hide(),b.show(),d&&d.show()):a===gui.ShadowCursor.ShadowCursorMemberId&& -(c.show(),b.hide(),d&&d.hide())}function c(a){var b=!1,c;for(c in x)if(x.hasOwnProperty(c)&&x[c].getEditInfo().getEdits().hasOwnProperty(a)){b=!0;break}l.removeSelectionView(a);b||e.getMemberModel().unsubscribeMemberDetailsUpdates(a,f)}function g(a){var b=a.paragraphElement,c=a.memberId;a=a.timeStamp;var d,f="",g=b.getElementsByTagNameNS(y,"editinfo")[0];g?(f=g.getAttributeNS(y,"id"),d=x[f]):(f=Math.random().toString(),d=new ops.EditInfo(b,e.getOdtDocument()),d=new gui.EditInfoMarker(d,w),g=b.getElementsByTagNameNS(y, -"editinfo")[0],g.setAttributeNS(y,"id",f),x[f]=d);d.addEdit(c,new Date(a))}function n(){D=!0}function r(){s=runtime.getWindow().setInterval(function(){D&&(l.rerenderSelectionViews(),D=!1)},200)}var u,y="urn:webodf:names:editinfo",x={},w=void 0!==h.editInfoMarkersInitiallyVisible?Boolean(h.editInfoMarkersInitiallyVisible):!0,v=void 0!==h.caretAvatarsInitiallyVisible?Boolean(h.caretAvatarsInitiallyVisible):!0,t=void 0!==h.caretBlinksOnRangeSelect?Boolean(h.caretBlinksOnRangeSelect):!0,s,D=!1;this.showEditInfoMarkers= -function(){w||(w=!0,a(w))};this.hideEditInfoMarkers=function(){w&&(w=!1,a(w))};this.showCaretAvatars=function(){v||(v=!0,d(v))};this.hideCaretAvatars=function(){v&&(v=!1,d(v))};this.getSession=function(){return e};this.getCaret=function(a){return p.getCaret(a)};this.destroy=function(a){var d=e.getOdtDocument(),h=e.getMemberModel(),l=Object.keys(x).map(function(a){return x[a]});d.unsubscribe(ops.OdtDocument.signalCursorAdded,b);d.unsubscribe(ops.OdtDocument.signalCursorRemoved,c);d.unsubscribe(ops.OdtDocument.signalParagraphChanged, -g);d.unsubscribe(ops.OdtDocument.signalCursorMoved,k);d.unsubscribe(ops.OdtDocument.signalParagraphChanged,n);d.unsubscribe(ops.OdtDocument.signalTableAdded,n);d.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,n);runtime.getWindow().clearInterval(s);p.getCarets().forEach(function(a){h.unsubscribeMemberDetailsUpdates(a.getCursor().getMemberId(),f)});u.parentNode.removeChild(u);(function H(b,c){c?a(c):b @@ -2770,11 +2846,11 @@ u.appendChild(document.createTextNode("@namespace editinfo url(urn:webodf:names: @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("gui.Caret"); -gui.CaretManager=function(h){function m(a){return g.hasOwnProperty(a)?g[a]:null}function e(){return Object.keys(g).map(function(a){return g[a]})}function p(a){a===h.getInputMemberId()&&h.getSession().getOdtDocument().getOdfCanvas().getElement().removeAttribute("tabindex");delete g[a]}function l(a){a=a.getMemberId();a===h.getInputMemberId()&&(a=m(a))&&a.refreshCursorBlinking()}function q(){var a=m(h.getInputMemberId());r=!1;a&&a.ensureVisible()}function a(){var a=m(h.getInputMemberId());a&&(a.handleUpdate(), -r||(r=!0,runtime.setTimeout(q,50)))}function d(b){b.memberId===h.getInputMemberId()&&a()}function f(){var a=m(h.getInputMemberId());a&&a.setFocus()}function b(){var a=m(h.getInputMemberId());a&&a.removeFocus()}function k(){var a=m(h.getInputMemberId());a&&a.show()}function c(){var a=m(h.getInputMemberId());a&&a.hide()}var g={},n=runtime.getWindow(),r=!1;this.registerCursor=function(b,c,d){var e=b.getMemberId();c=new gui.Caret(b,c,d);g[e]=c;e===h.getInputMemberId()?(runtime.log("Starting to track input on new cursor of "+ -e),b.handleUpdate=a,h.getSession().getOdtDocument().getOdfCanvas().getElement().setAttribute("tabindex",-1),h.getEventManager().focus()):b.handleUpdate=c.handleUpdate;return c};this.getCaret=m;this.getCarets=e;this.destroy=function(a){var m=h.getSession().getOdtDocument(),q=h.getEventManager(),r=e();m.unsubscribe(ops.OdtDocument.signalParagraphChanged,d);m.unsubscribe(ops.OdtDocument.signalCursorMoved,l);m.unsubscribe(ops.OdtDocument.signalCursorRemoved,p);q.unsubscribe("focus",f);q.unsubscribe("blur", -b);n.removeEventListener("focus",k,!1);n.removeEventListener("blur",c,!1);(function t(b,c){c?a(c):b @@ -2812,9 +2888,9 @@ b);n.removeEventListener("focus",k,!1);n.removeEventListener("blur",c,!1);(funct @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -gui.UndoManager=function(){};gui.UndoManager.prototype.subscribe=function(h,m){};gui.UndoManager.prototype.unsubscribe=function(h,m){};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 91 +gui.UndoManager=function(){};gui.UndoManager.prototype.subscribe=function(g,l){};gui.UndoManager.prototype.unsubscribe=function(g,l){};gui.UndoManager.prototype.setOdtDocument=function(g){};gui.UndoManager.prototype.saveInitialState=function(){};gui.UndoManager.prototype.resetInitialState=function(){};gui.UndoManager.prototype.setPlaybackFunction=function(g){};gui.UndoManager.prototype.hasUndoStates=function(){};gui.UndoManager.prototype.hasRedoStates=function(){}; +gui.UndoManager.prototype.moveForward=function(g){};gui.UndoManager.prototype.moveBackward=function(g){};gui.UndoManager.prototype.onOperationExecuted=function(g){};gui.UndoManager.signalUndoStackChanged="undoStackChanged";gui.UndoManager.signalUndoStateCreated="undoStateCreated";gui.UndoManager.signalUndoStateModified="undoStateModified";(function(){return gui.UndoManager})(); +// Input 95 /* Copyright (C) 2013 KO GmbH @@ -2852,9 +2928,9 @@ gui.UndoManager.prototype.moveForward=function(h){};gui.UndoManager.prototype.mo @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -gui.UndoStateRules=function(){function h(e){return e.spec().optype}function m(e){switch(h(e)){case "MoveCursor":case "AddCursor":case "RemoveCursor":return!1;default:return!0}}this.getOpType=h;this.isEditOperation=m;this.isPartOfOperationSet=function(e,p){if(m(e)){if(0===p.length)return!0;var l;if(l=m(p[p.length-1]))a:{l=p.filter(m);var q=h(e),a;b:switch(q){case "RemoveText":case "InsertText":a=!0;break b;default:a=!1}if(a&&q===h(l[0])){if(1===l.length){l=!0;break a}q=l[l.length-2].spec().position; -l=l[l.length-1].spec().position;a=e.spec().position;if(l===a-(l-q)){l=!0;break a}}l=!1}return l}return!0}}; -// Input 92 +gui.UndoStateRules=function(){function g(c){return c.spec().optype}function l(c){return c.isEdit}this.getOpType=g;this.isEditOperation=l;this.isPartOfOperationSet=function(c,m){if(c.isEdit){if(0===m.length)return!0;var f;if(f=m[m.length-1].isEdit)a:{f=m.filter(l);var n=g(c),b;b:switch(n){case "RemoveText":case "InsertText":b=!0;break b;default:b=!1}if(b&&n===g(f[0])){if(1===f.length){f=!0;break a}n=f[f.length-2].spec().position;f=f[f.length-1].spec().position;b=c.spec().position;if(f===b-(f-n)){f= +!0;break a}}f=!1}return f}return!0}}; +// Input 96 /* Copyright (C) 2013 KO GmbH @@ -2893,25 +2969,26 @@ l=l[l.length-1].spec().position;a=e.spec().position;if(l===a-(l-q)){l=!0;break a @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils");runtime.loadClass("gui.UndoManager");runtime.loadClass("gui.UndoStateRules"); -gui.TrivialUndoManager=function(h){function m(){u.emit(gui.UndoManager.signalUndoStackChanged,{undoAvailable:a.hasUndoStates(),redoAvailable:a.hasRedoStates()})}function e(){g!==b&&g!==n[n.length-1]&&n.push(g)}function p(a){var b=a.previousSibling||a.nextSibling;a.parentNode.removeChild(a);d.normalizeTextNodes(b)}function l(a){return Object.keys(a).map(function(b){return a[b]})}function q(a){function b(a){var c=a.spec();if(f[c.memberid])switch(c.optype){case "AddCursor":d[c.memberid]||(d[c.memberid]= -a,delete f[c.memberid],g-=1);break;case "MoveCursor":e[c.memberid]||(e[c.memberid]=a)}}var d={},e={},f={},g,h=a.pop();c.getCursors().forEach(function(a){f[a.getMemberId()]=!0});for(g=Object.keys(f).length;h&&0 @@ -2950,9 +3027,9 @@ r.appendChild(y);r.appendChild(x);r.appendChild(w);y.setAttributeNS("urn:webodf: @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("gui.SelectionView"); -gui.SelectionViewManager=function(){function h(){return Object.keys(m).map(function(e){return m[e]})}var m={};this.getSelectionView=function(e){return m.hasOwnProperty(e)?m[e]:null};this.getSelectionViews=h;this.removeSelectionView=function(e){m.hasOwnProperty(e)&&(m[e].destroy(function(){}),delete m[e])};this.hideSelectionView=function(e){m.hasOwnProperty(e)&&m[e].hide()};this.showSelectionView=function(e){m.hasOwnProperty(e)&&m[e].show()};this.rerenderSelectionViews=function(){Object.keys(m).forEach(function(e){m[e].visible()&& -m[e].rerender()})};this.registerCursor=function(e,h){var l=e.getMemberId(),q=new gui.SelectionView(e);h?q.show():q.hide();return m[l]=q};this.destroy=function(e){var m=h();(function q(a,d){d?e(d):a @@ -2990,23 +3067,24 @@ m[e].rerender()})};this.registerCursor=function(e,h){var l=e.getMemberId(),q=new @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.EventNotifier");runtime.loadClass("core.DomUtils");runtime.loadClass("odf.OdfUtils");runtime.loadClass("odf.Namespaces");runtime.loadClass("gui.SelectionMover");runtime.loadClass("core.PositionFilterChain");runtime.loadClass("ops.StepsTranslator");runtime.loadClass("ops.TextPositionFilter"); -ops.OdtDocument=function(h){function m(){var a=h.odfContainer().getContentElement(),b=a&&a.localName;runtime.assert("text"===b,"Unsupported content element type '"+b+"' for OdtDocument");return a}function e(){return m().ownerDocument}function p(a){for(;a&&!(a.namespaceURI===odf.Namespaces.officens&&"text"===a.localName||a.namespaceURI===odf.Namespaces.officens&&"annotation"===a.localName);)a=a.parentNode;return a}function l(a){this.acceptPosition=function(b){b=b.container();var d;d="string"===typeof a? -c[a].getNode():a;return p(b)===p(d)?n:r}}function q(a){var b=gui.SelectionMover.createPositionIterator(m());a=y.convertStepsToDomPoint(a);b.setUnfilteredPosition(a.node,a.offset);return b}function a(a,b){return h.getFormatting().getStyleElement(a,b)}function d(b){return a(b,"paragraph")}var f=this,b,k,c={},g=new core.EventNotifier([ops.OdtDocument.signalCursorAdded,ops.OdtDocument.signalCursorRemoved,ops.OdtDocument.signalCursorMoved,ops.OdtDocument.signalParagraphChanged,ops.OdtDocument.signalParagraphStyleModified, -ops.OdtDocument.signalCommonStyleCreated,ops.OdtDocument.signalCommonStyleDeleted,ops.OdtDocument.signalTableAdded,ops.OdtDocument.signalOperationExecuted,ops.OdtDocument.signalUndoStackChanged,ops.OdtDocument.signalStepsInserted,ops.OdtDocument.signalStepsRemoved]),n=core.PositionFilter.FilterResult.FILTER_ACCEPT,r=core.PositionFilter.FilterResult.FILTER_REJECT,u,y;this.getDOM=e;this.getRootElement=p;this.getIteratorAtPosition=q;this.convertDomPointToCursorStep=function(a,b){return y.convertDomPointToSteps(a, -b)};this.convertDomToCursorRange=function(a,b,c,d){var e;e=y.convertDomPointToSteps(a,b);a=a===c&&b===d?e:y.convertDomPointToSteps(c,d);return{position:e,length:a-e}};this.convertCursorToDomRange=function(a,b){var c=e().createRange(),d,f;d=y.convertStepsToDomPoint(a);b?(f=y.convertStepsToDomPoint(a+b),0=e;e+=1){c=a.container();d=a.unfilteredDomOffset();if(c.nodeType===Node.TEXT_NODE&&" "===c.data[d]&&b.isSignificantWhitespace(c,d)){runtime.assert(" "===c.data[d],"upgradeWhitespaceToElement: textNode.data[offset] should be a literal space");var f=c.ownerDocument.createElementNS(odf.Namespaces.textns,"text:s");f.appendChild(c.ownerDocument.createTextNode(" "));c.deleteData(d,1);0=e;e+=1){b=a.container();c=a.unfilteredDomOffset();if(b.nodeType===Node.TEXT_NODE&&" "===b.data[c]&&d.isSignificantWhitespace(b,c)){runtime.assert(" "===b.data[c],"upgradeWhitespaceToElement: textNode.data[offset] should be a literal space");var f=b.ownerDocument.createElementNS(odf.Namespaces.textns, +"text:s");f.appendChild(b.ownerDocument.createTextNode(" "));b.deleteData(c,1);0 @@ -3044,8 +3122,10 @@ ops.OdtDocument.signalStepsInserted="steps/inserted";ops.OdtDocument.signalSteps @source: http://www.webodf.org/ @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.TrivialMemberModel");runtime.loadClass("ops.TrivialOperationRouter");runtime.loadClass("ops.OperationFactory");runtime.loadClass("ops.OdtDocument"); -ops.Session=function(h){var m=new ops.OperationFactory,e=new ops.OdtDocument(h),p=new ops.TrivialMemberModel,l=null;this.setMemberModel=function(e){p=e};this.setOperationFactory=function(e){m=e;l&&l.setOperationFactory(m)};this.setOperationRouter=function(h){l=h;h.setPlaybackFunction(function(a){a.execute(e);e.emit(ops.OdtDocument.signalOperationExecuted,a)});h.setOperationFactory(m)};this.getMemberModel=function(){return p};this.getOperationFactory=function(){return m};this.getOdtDocument=function(){return e}; -this.enqueue=function(e){l.push(e)};this.close=function(h){l.close(function(a){a?h(a):p.close(function(a){a?h(a):e.close(h)})})};this.destroy=function(h){e.destroy(h)};this.setOperationRouter(new ops.TrivialOperationRouter)}; -// Input 97 +runtime.loadClass("ops.TrivialOperationRouter");runtime.loadClass("ops.OperationFactory");runtime.loadClass("ops.OdtDocument"); +ops.Session=function(g){var l=new ops.OperationFactory,c=new ops.OdtDocument(g),m=null;this.setOperationFactory=function(c){l=c;m&&m.setOperationFactory(l)};this.setOperationRouter=function(f){m=f;f.setPlaybackFunction(function(f){f.execute(c);c.emit(ops.OdtDocument.signalOperationExecuted,f)});f.setOperationFactory(l)};this.getOperationFactory=function(){return l};this.getOdtDocument=function(){return c};this.enqueue=function(c){m.push(c)};this.close=function(f){m.close(function(g){g?f(g):c.close(f)})}; +this.destroy=function(f){c.destroy(f)};this.setOperationRouter(new ops.TrivialOperationRouter)}; +// Input 101 var webodf_css="@namespace draw url(urn:oasis:names:tc:opendocument:xmlns:drawing:1.0);\n@namespace fo url(urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0);\n@namespace office url(urn:oasis:names:tc:opendocument:xmlns:office:1.0);\n@namespace presentation url(urn:oasis:names:tc:opendocument:xmlns:presentation:1.0);\n@namespace style url(urn:oasis:names:tc:opendocument:xmlns:style:1.0);\n@namespace svg url(urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0);\n@namespace table url(urn:oasis:names:tc:opendocument:xmlns:table:1.0);\n@namespace text url(urn:oasis:names:tc:opendocument:xmlns:text:1.0);\n@namespace webodfhelper url(urn:webodf:names:helper);\n@namespace cursor url(urn:webodf:names:cursor);\n@namespace editinfo url(urn:webodf:names:editinfo);\n@namespace annotation url(urn:webodf:names:annotation);\n@namespace dc url(http://purl.org/dc/elements/1.1/);\n\noffice|document > *, office|document-content > * {\n display: none;\n}\noffice|body, office|document {\n display: inline-block;\n position: relative;\n}\n\ntext|p, text|h {\n display: block;\n padding: 0;\n margin: 0;\n line-height: normal;\n position: relative;\n min-height: 1.3em; /* prevent empty paragraphs and headings from collapsing if they are empty */\n}\n*[webodfhelper|containsparagraphanchor] {\n position: relative;\n}\ntext|s {\n white-space: pre;\n}\ntext|tab {\n display: inline;\n white-space: pre;\n}\ntext|tracked-changes {\n /*Consumers that do not support change tracking, should ignore changes.*/\n display: none;\n}\noffice|binary-data {\n display: none;\n}\noffice|text {\n display: block;\n text-align: left;\n overflow: visible;\n word-wrap: break-word;\n}\n\noffice|text::selection {\n /** Let's not draw selection highlight that overflows into the office|text\n * node when selecting content across several paragraphs\n */\n background: transparent;\n}\n\n.virtualSelections office|document *::selection {\n background: transparent;\n}\n.virtualSelections office|document *::-moz-selection {\n background: transparent;\n}\n\noffice|text * draw|text-box {\n/** only for text documents */\n display: block;\n border: 1px solid #d3d3d3;\n}\noffice|spreadsheet {\n display: block;\n border-collapse: collapse;\n empty-cells: show;\n font-family: sans-serif;\n font-size: 10pt;\n text-align: left;\n page-break-inside: avoid;\n overflow: hidden;\n}\noffice|presentation {\n display: inline-block;\n text-align: left;\n}\n#shadowContent {\n display: inline-block;\n text-align: left;\n}\ndraw|page {\n display: block;\n position: relative;\n overflow: hidden;\n}\npresentation|notes, presentation|footer-decl, presentation|date-time-decl {\n display: none;\n}\n@media print {\n draw|page {\n border: 1pt solid black;\n page-break-inside: avoid;\n }\n presentation|notes {\n /*TODO*/\n }\n}\noffice|spreadsheet text|p {\n border: 0px;\n padding: 1px;\n margin: 0px;\n}\noffice|spreadsheet table|table {\n margin: 3px;\n}\noffice|spreadsheet table|table:after {\n /* show sheet name the end of the sheet */\n /*content: attr(table|name);*/ /* gives parsing error in opera */\n}\noffice|spreadsheet table|table-row {\n counter-increment: row;\n}\noffice|spreadsheet table|table-row:before {\n width: 3em;\n background: #cccccc;\n border: 1px solid black;\n text-align: center;\n content: counter(row);\n display: table-cell;\n}\noffice|spreadsheet table|table-cell {\n border: 1px solid #cccccc;\n}\ntable|table {\n display: table;\n}\ndraw|frame table|table {\n width: 100%;\n height: 100%;\n background: white;\n}\ntable|table-header-rows {\n display: table-header-group;\n}\ntable|table-row {\n display: table-row;\n}\ntable|table-column {\n display: table-column;\n}\ntable|table-cell {\n width: 0.889in;\n display: table-cell;\n word-break: break-all; /* prevent long words from extending out the table cell */\n}\ndraw|frame {\n display: block;\n}\ndraw|image {\n display: block;\n width: 100%;\n height: 100%;\n top: 0px;\n left: 0px;\n background-repeat: no-repeat;\n background-size: 100% 100%;\n -moz-background-size: 100% 100%;\n}\n/* only show the first image in frame */\ndraw|frame > draw|image:nth-of-type(n+2) {\n display: none;\n}\ntext|list:before {\n display: none;\n content:\"\";\n}\ntext|list {\n counter-reset: list;\n}\ntext|list-item {\n display: block;\n}\ntext|number {\n display:none;\n}\n\ntext|a {\n color: blue;\n text-decoration: underline;\n cursor: pointer;\n}\ntext|note-citation {\n vertical-align: super;\n font-size: smaller;\n}\ntext|note-body {\n display: none;\n}\ntext|note:hover text|note-citation {\n background: #dddddd;\n}\ntext|note:hover text|note-body {\n display: block;\n left:1em;\n max-width: 80%;\n position: absolute;\n background: #ffffaa;\n}\nsvg|title, svg|desc {\n display: none;\n}\nvideo {\n width: 100%;\n height: 100%\n}\n\n/* below set up the cursor */\ncursor|cursor {\n display: inline;\n width: 0px;\n height: 1em;\n /* making the position relative enables the avatar to use\n the cursor as reference for its absolute position */\n position: relative;\n z-index: 1;\n}\ncursor|cursor > span {\n /* IMPORTANT: when changing these values ensure DEFAULT_CARET_TOP and DEFAULT_CARET_HEIGHT\n in Caret.js remain in sync */\n display: inline;\n position: absolute;\n top: 5%; /* push down the caret; 0px can do the job, 5% looks better, 10% is a bit over */\n height: 1em;\n border-left: 2px solid black;\n outline: none;\n}\n\ncursor|cursor > div {\n padding: 3px;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n border: none !important;\n border-radius: 5px;\n opacity: 0.3;\n}\n\ncursor|cursor > div > img {\n border-radius: 5px;\n}\n\ncursor|cursor > div.active {\n opacity: 0.8;\n}\n\ncursor|cursor > div:after {\n content: ' ';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 43%;\n}\n\n\n.editInfoMarker {\n position: absolute;\n width: 10px;\n height: 100%;\n left: -20px;\n opacity: 0.8;\n top: 0;\n border-radius: 5px;\n background-color: transparent;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n}\n.editInfoMarker:hover {\n box-shadow: 0px 0px 8px rgba(0, 0, 0, 1);\n}\n\n.editInfoHandle {\n position: absolute;\n background-color: black;\n padding: 5px;\n border-radius: 5px;\n opacity: 0.8;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n bottom: 100%;\n margin-bottom: 10px;\n z-index: 3;\n left: -25px;\n}\n.editInfoHandle:after {\n content: ' ';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 5px;\n}\n.editInfo {\n font-family: sans-serif;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n color: white;\n width: 100%;\n height: 12pt;\n}\n.editInfoColor {\n float: left;\n width: 10pt;\n height: 10pt;\n border: 1px solid white;\n}\n.editInfoAuthor {\n float: left;\n margin-left: 5pt;\n font-size: 10pt;\n text-align: left;\n height: 12pt;\n line-height: 12pt;\n}\n.editInfoTime {\n float: right;\n margin-left: 30pt;\n font-size: 8pt;\n font-style: italic;\n color: yellow;\n height: 12pt;\n line-height: 12pt;\n}\n\n.annotationWrapper {\n display: inline;\n position: relative;\n}\n\n.annotationRemoveButton:before {\n content: '\u00d7';\n color: white;\n padding: 5px;\n line-height: 1em;\n}\n\n.annotationRemoveButton {\n width: 20px;\n height: 20px;\n border-radius: 10px;\n background-color: black;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n position: absolute;\n top: -10px;\n left: -10px;\n z-index: 3;\n text-align: center;\n font-family: sans-serif;\n font-style: normal;\n font-weight: normal;\n text-decoration: none;\n font-size: 15px;\n}\n.annotationRemoveButton:hover {\n cursor: pointer;\n box-shadow: 0px 0px 5px rgba(0, 0, 0, 1);\n}\n\n.annotationNote {\n width: 4cm;\n position: absolute;\n display: inline;\n z-index: 10;\n}\n.annotationNote > office|annotation {\n display: block;\n text-align: left;\n}\n\n.annotationConnector {\n position: absolute;\n display: inline;\n z-index: 2;\n border-top: 1px dashed brown;\n}\n.annotationConnector.angular {\n -moz-transform-origin: left top;\n -webkit-transform-origin: left top;\n -ms-transform-origin: left top;\n transform-origin: left top;\n}\n.annotationConnector.horizontal {\n left: 0;\n}\n.annotationConnector.horizontal:before {\n content: '';\n display: inline;\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: brown transparent transparent transparent;\n top: -1px;\n left: -5px;\n}\n\noffice|annotation {\n width: 100%;\n height: 100%;\n display: none;\n background: rgb(198, 238, 184);\n background: -moz-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -webkit-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -o-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: -ms-linear-gradient(90deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n background: linear-gradient(180deg, rgb(198, 238, 184) 30%, rgb(180, 196, 159) 100%);\n box-shadow: 0 3px 4px -3px #ccc;\n}\n\noffice|annotation > dc|creator {\n display: block;\n font-size: 10pt;\n font-weight: normal;\n font-style: normal;\n font-family: sans-serif;\n color: white;\n background-color: brown;\n padding: 4px;\n}\noffice|annotation > dc|date {\n display: block;\n font-size: 10pt;\n font-weight: normal;\n font-style: normal;\n font-family: sans-serif;\n border: 4px solid transparent;\n}\noffice|annotation > text|list {\n display: block;\n padding: 5px;\n}\n\n/* This is very temporary CSS. This must go once\n * we start bundling webodf-default ODF styles for annotations.\n */\noffice|annotation text|p {\n font-size: 10pt;\n color: black;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n font-family: sans-serif;\n}\n\ndc|*::selection {\n background: transparent;\n}\ndc|*::-moz-selection {\n background: transparent;\n}\n\n#annotationsPane {\n background-color: #EAEAEA;\n width: 4cm;\n height: 100%;\n display: none;\n position: absolute;\n outline: 1px solid #ccc;\n}\n\n.annotationHighlight {\n background-color: yellow;\n position: relative;\n}\n\n.selectionOverlay {\n position: absolute;\n z-index: 15;\n opacity: 0.2;\n pointer-events: none;\n top: 0;\n left: 0;\n width: 0;\n height: 0;\n}\n\n#imageSelector {\n display: none;\n position: absolute;\n border-style: solid;\n border-color: black;\n}\n\n#imageSelector > div {\n width: 5px;\n height: 5px;\n display: block;\n position: absolute;\n border: 1px solid black;\n background-color: #ffffff;\n}\n\n#imageSelector > .topLeft {\n top: -4px;\n left: -4px;\n}\n\n#imageSelector > .topRight {\n top: -4px;\n right: -4px;\n}\n\n#imageSelector > .bottomRight {\n right: -4px;\n bottom: -4px;\n}\n\n#imageSelector > .bottomLeft {\n bottom: -4px;\n left: -4px;\n}\n\n#imageSelector > .topMiddle {\n top: -4px;\n left: 50%;\n margin-left: -2.5px; /* half of the width defined in #imageSelector > div */\n}\n\n#imageSelector > .rightMiddle {\n top: 50%;\n right: -4px;\n margin-top: -2.5px; /* half of the height defined in #imageSelector > div */\n}\n\n#imageSelector > .bottomMiddle {\n bottom: -4px;\n left: 50%;\n margin-left: -2.5px; /* half of the width defined in #imageSelector > div */\n}\n\n#imageSelector > .leftMiddle {\n top: 50%;\n left: -4px;\n margin-top: -2.5px; /* half of the height defined in #imageSelector > div */\n}\n"; +// Input 102 +var webodf_version="0.4.2-1451-gc9cf878"; diff --git a/lib/db/op.php b/lib/db/op.php index 5446e382..280b43c6 100644 --- a/lib/db/op.php +++ b/lib/db/op.php @@ -84,11 +84,34 @@ class Db_Op extends Db { } public function removeCursor($esId, $memberId){ + $op = '{"optype":"RemoveCursor","memberid":"'. $memberId .'","reason":"server-idle","timestamp":'. time() .'}'; + $this->insertOp($esId, $op); + } + + public function addMember($esId, $memberId, $fullName, $color, $imageUrl){ + $op = '{"optype":"AddMember","memberid":"'. $memberId .'","timestamp":"'. time() .'", "setProperties":{"fullName":"'. $fullName .'","color":"'. $color .'","imageUrl":"'. $imageUrl .'"}}'; + $this->insertOp($esId, $op); + } + + public function removeMember($esId, $memberId){ + $op ='{"optype":"RemoveMember","memberid":"'. $memberId .'","timestamp":'. time() .'}'; + $this->insertOp($esId, $op); + } + + public function updateMember($esId, $memberId, $fullName, $color, $imageUrl){ + //TODO: Follow the spec https://github.com/kogmbh/WebODF/blob/master/webodf/lib/ops/OpUpdateMember.js#L95 + $op = '{"optype":"UpdateMember","memberid":"'. $memberId .'","fullName":"'. $fullName .'","color":"'. $color .'","imageUrl":"'. $imageUrl .'","timestamp":'. time() .'}' + ; + $this->insertOp($esId, $op); + } + + protected function insertOp($esId, $op){ $op = new Db_Op(array( $esId, 0, - '{"optype":"RemoveCursor","memberid":"'. $memberId .'","reason":"server-idle","timestamp":'. time() .'}' + $op )); $op->insert(); } + } diff --git a/lib/db/session.php b/lib/db/session.php index 6ac830f8..7133774e 100644 --- a/lib/db/session.php +++ b/lib/db/session.php @@ -64,14 +64,52 @@ class Db_Session extends \OCA\Documents\Db { ->getData() ; + $memberColor = Helper::getRandomColor(); + $member = new Db_Member(array( $session['es_id'], - $uid, - Helper::getRandomColor(), + $uid, + $memberColor, time() )); + if ($member->insert()){ + // Do we have OC_Avatar in out disposal? + if (!class_exists('\OC_Avatar') || \OC_Config::getValue('enable_avatars', true) !== true){ + //$x['avatar_url'] = \OCP\Util::linkToRoute('documents_user_avatar'); + $imageUrl = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw=='; + } else { + // https://github.com/owncloud/documents/issues/51 + // Temporary stub + $imageUrl = $uid; + + /* + $avatar = new \OC_Avatar($uid); + $image = $avatar->get(64); + // User has an avatar + if ($image instanceof \OC_Image) { + $imageUrl = \OC_Helper::linkToRoute( + 'core_avatar_get', + array( 'user' => $uid, 'size' => 64) + ) . '?requesttoken=' . \OC::$session->get('requesttoken'); + } else { + //shortcircuit if it's not an image + $imageUrl = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw=='; + } + + */ + } + + $session['member_id'] = (string) $member->getLastInsertId(); + $op = new Db_Op(); + $op->addMember( + $session['es_id'], + $session['member_id'], + \OCP\User::getDisplayName($uid), + $memberColor, + $imageUrl + ); } else { throw new \Exception('Failed to add member into database'); }