diff --git a/js/3rdparty/webodf/dojo-amalgamation.js b/js/3rdparty/webodf/dojo-amalgamation.js index 2ca85f21..4aa24949 100644 --- a/js/3rdparty/webodf/dojo-amalgamation.js +++ b/js/3rdparty/webodf/dojo-amalgamation.js @@ -661,7 +661,7 @@ a;this._set("title",a)},postCreate:function(){this.inherited(arguments);this.con "-"+c];j.replace(this.domNode,a,this._currentOrientClass||"");this._currentOrientClass=a},focus:function(){this._getFocusItems(this.containerNode);g.focus(this._firstFocusItem)},onOpen:function(a){this.orient(this.domNode,a.aroundCorner,a.corner);var b=a.aroundNodePos;if("M"==a.corner.charAt(0)&&"M"==a.aroundCorner.charAt(0))this.connectorNode.style.top=b.y+(b.h-this.connectorNode.offsetHeight>>1)-a.y+"px",this.connectorNode.style.left="";else if("M"==a.corner.charAt(1)&&"M"==a.aroundCorner.charAt(1))this.connectorNode.style.left= b.x+(b.w-this.connectorNode.offsetWidth>>1)-a.x+"px";this._onShow()},onClose:function(){this.onHide()},_onKey:function(a){var b=a.target;a.charOrCode===l.TAB&&this._getFocusItems(this.containerNode);var c=this._firstFocusItem==this._lastFocusItem;a.charOrCode==l.ESCAPE?(this.defer("onCancel"),i.stop(a)):b==this._firstFocusItem&&a.shiftKey&&a.charOrCode===l.TAB?(c||g.focus(this._lastFocusItem),i.stop(a)):b==this._lastFocusItem&&a.charOrCode===l.TAB&&!a.shiftKey?(c||g.focus(this._firstFocusItem),i.stop(a)): a.charOrCode===l.TAB&&a.stopPropagation()}})})},"url:dijit/templates/TooltipDialog.html":'
\n\t\n\t\n
\n',"*now":function(e){e(['dojo/i18n!*preload*dojo/nls/dojo*["ar","ca","cs","da","de","el","en-gb","en-us","es-es","fi-fi","fr-fr","he-il","hu","it-it","ja-jp","ko-kr","nl-nl","nb","pl","pt-br","pt-pt","ru","sk","sl","sv","th","tr","zh-tw","zh-cn","ROOT"]'])}}}); -// START OF nls/dojobundle.js +// START OF dojobundle.js /* START OF NLS BUNDLE ENTRY [dojo-deps/dist/dijit/_editor/nls/FontChoice.js] */ //>>built define("dijit/_editor/nls/FontChoice",{root:{fontSize:"Size",fontName:"Font",formatBlock:"Format",serif:"serif","sans-serif":"sans-serif",monospace:"monospace",cursive:"cursive",fantasy:"fantasy",noFormat:"None",p:"Paragraph",h1:"Heading",h2:"Subheading",h3:"Sub-subheading",pre:"Pre-formatted",1:"xx-small",2:"x-small",3:"small",4:"medium",5:"large",6:"x-large",7:"xx-large"},zh:!0,"zh-tw":!0,tr:!0,th:!0,sv:!0,sl:!0,sk:!0,ru:!0,ro:!0,pt:!0,"pt-pt":!0,pl:!0,nl:!0,nb:!0,ko:!0,kk:!0,ja:!0,it:!0,hu:!0, @@ -1706,6 +1706,6 @@ define("dojox/widget/nls/ru/FilePicker",{name:"\u0418\u043c\u044f",path:"\u041f\ define("dojox/widget/nls/ru/Wizard",{next:"\u0414\u0430\u043b\u0435\u0435",previous:"\u041d\u0430\u0437\u0430\u0434",done:"\u0413\u043e\u0442\u043e\u0432\u043e"}); /* END OF NLS BUNDLE ENTRY [dojo-deps/dist/dojox/widget/nls/ru/Wizard.js] */ -// END OF nls/dojobundle.js +// END OF dojobundle.js (function(){var e=this.require;e({cache:{}});!e.async&&e(["dojo"]);e.boot&&e.apply(null,e.boot)})(); \ No newline at end of file diff --git a/js/3rdparty/webodf/editor/Editor.js b/js/3rdparty/webodf/editor/Editor.js index 50881a26..b2fc8115 100644 --- a/js/3rdparty/webodf/editor/Editor.js +++ b/js/3rdparty/webodf/editor/Editor.js @@ -10,6 +10,9 @@ * 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 @@ -30,21 +33,19 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global runtime, define, document, odf, ops, window, gui, alert, saveAs, Blob */ define("webodf/editor/Editor", [ - "dojo/i18n!webodf/editor/nls/myResources", "webodf/editor/EditorSession", "webodf/editor/MemberListView", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "webodf/editor/Tools"], - function (myResources, - EditorSession, + function (EditorSession, MemberListView, BorderContainer, ContentPane, @@ -55,11 +56,11 @@ define("webodf/editor/Editor", [ /** * @constructor - * @param {{unstableFeaturesEnabled:boolean=, - * loadCallback:function()=, - * saveCallback:function()=, - * closeCallback:function()=, - * @param {!ops.Server=} server + * @param {{unstableFeaturesEnabled:boolean, + * loadCallback:function(), + * saveCallback:function(), + * closeCallback:function()}} + * param {!ops.Server=} server * @param {!ServerFactory=} serverFactory */ function Editor(args, server, serverFactory) { @@ -273,8 +274,6 @@ define("webodf/editor/Editor", [ if (err) { callback(err); } else { - document.translator = null; - document.translateContent = null; callback(); } }); @@ -285,9 +284,7 @@ define("webodf/editor/Editor", [ }; function setFocusToOdfCanvas() { - if (odfCanvas) { - odfCanvas.getElement().focus(); - } + editorSession.sessionController.getEventManager().focus(); } // init @@ -298,29 +295,15 @@ define("webodf/editor/Editor", [ memberListElement = document.getElementById('memberList'), collabEditing = Boolean(server), directStylingEnabled = (! collabEditing) || args.unstableFeaturesEnabled, + imageInsertingEnabled = (! collabEditing) || args.unstableFeaturesEnabled, // annotations not yet properly supported for OT annotationsEnabled = (! collabEditing) || args.unstableFeaturesEnabled, // undo manager is not yet integrated with collaboration undoRedoEnabled = (! collabEditing), closeCallback; - if (collabEditing) { - runtime.assert(memberListElement, 'missing "memberList" div in HTML'); - } - - runtime.assert(canvasElement, 'missing "canvas" div in HTML'); - - // setup translations - // TODO: move from document instance into webodf namespace - function translator(key, context) { - if (undefined === myResources[key]) { - return "translation missing: " + key; - } - return myResources[key]; - } - document.translator = translator; - - function translateContent(node) { + // Extend runtime with a convenient translation function + runtime.translateContent = function (node) { var i, element, tag, @@ -334,11 +317,16 @@ define("webodf/editor/Editor", [ if (tag === "label" || tag === "span" || /h\d/i.test(tag)) { - element.textContent = document.translator(placeholder); + element.textContent = runtime.tr(placeholder); } } + }; + + if (collabEditing) { + runtime.assert(memberListElement, 'missing "memberList" div in HTML'); } - document.translateContent = translateContent; + + runtime.assert(canvasElement, 'missing "canvas" div in HTML'); // App Widgets mainContainer = new BorderContainer({}, 'mainContainer'); @@ -351,7 +339,7 @@ define("webodf/editor/Editor", [ if (collabEditing) { memberListPane = new ContentPane({ region: 'right', - title: translator("members") + title: runtime.tr("Members") }, 'members'); mainContainer.addChild(memberListPane); memberListView = new MemberListView(memberListElement); @@ -362,7 +350,7 @@ define("webodf/editor/Editor", [ if (window.inviteButtonProxy) { inviteButton = document.getElementById('inviteButton'); runtime.assert(inviteButton, 'missing "inviteButton" div in HTML'); - inviteButton.innerText = translator("inviteMembers"); + inviteButton.innerText = runtime.tr("Invite Members"); inviteButton.style.display = "block"; inviteButton.onclick = window.inviteButtonProxy.clicked; } @@ -373,6 +361,7 @@ define("webodf/editor/Editor", [ saveOdtFile: saveOdtFile, close: close, directStylingEnabled: directStylingEnabled, + imageInsertingEnabled: imageInsertingEnabled, annotationsEnabled: annotationsEnabled, undoRedoEnabled: undoRedoEnabled }); @@ -391,7 +380,8 @@ define("webodf/editor/Editor", [ session = new ops.Session(odfCanvas); editorSession = new EditorSession(session, pendingMemberId, { viewOptions: viewOptions, - directStylingEnabled: directStylingEnabled + directStylingEnabled: directStylingEnabled, + imageInsertingEnabled: imageInsertingEnabled }); if (undoRedoEnabled) { editorSession.sessionController.setUndoManager(new gui.TrivialUndoManager()); diff --git a/js/3rdparty/webodf/editor/EditorSession.js b/js/3rdparty/webodf/editor/EditorSession.js index d890a8e0..746d8a7b 100644 --- a/js/3rdparty/webodf/editor/EditorSession.js +++ b/js/3rdparty/webodf/editor/EditorSession.js @@ -10,6 +10,9 @@ * 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 @@ -30,7 +33,7 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global define, runtime, core, gui, ops, document */ @@ -54,7 +57,9 @@ define("webodf/editor/EditorSession", [ runtime.loadClass("gui.SessionController"); runtime.loadClass("gui.SessionView"); runtime.loadClass("gui.TrivialUndoManager"); + runtime.loadClass("gui.SelectionViewManager"); runtime.loadClass("core.EventNotifier"); + runtime.loadClass("gui.ShadowCursor"); /** * Instantiate a new editor session attached to an existing operation session @@ -69,6 +74,7 @@ define("webodf/editor/EditorSession", [ currentCommonStyleName = null, currentStyleName = null, caretManager, + selectionViewManager, odtDocument = session.getOdtDocument(), textns = odf.Namespaces.textns, fontStyles = document.createElement('style'), @@ -82,16 +88,11 @@ define("webodf/editor/EditorSession", [ EditorSession.signalCommonStyleCreated, EditorSession.signalCommonStyleDeleted, EditorSession.signalParagraphStyleModified, - EditorSession.signalUndoStackChanged]); - - - this.sessionController = new gui.SessionController(session, localMemberId, {directStylingEnabled: config.directStylingEnabled}); - caretManager = new gui.CaretManager(self.sessionController); - this.sessionView = new gui.SessionView(config.viewOptions, session, caretManager); - this.availableFonts = []; + EditorSession.signalUndoStackChanged]), + shadowCursor = new gui.ShadowCursor(odtDocument); - /* - * @return {Array.{!string}} + /** + * @return {Array.} */ function getAvailableFonts() { var availableFonts, regex, matches; @@ -109,7 +110,6 @@ define("webodf/editor/EditorSession", [ return availableFonts; } - this.availableFonts = getAvailableFonts(); function checkParagraphStyleName() { var newStyleName, @@ -299,28 +299,6 @@ define("webodf/editor/EditorSession", [ return currentCommonStyleName; }; - /** - * Adds an annotation to the document based on the current selection - * @return {undefined} - */ - this.addAnnotation = function () { - var op = new ops.OpAddAnnotation(), - selection = self.getCursorSelection(), - length = selection.length, - position = selection.position; - - position = length >= 0 ? position : position + length; - length = Math.abs(length); - - op.init({ - memberid: localMemberId, - position: position, - length: length, - name: localMemberId + Date.now() - }); - session.enqueue(op); - }; - this.setCurrentParagraphStyle = function (value) { var op; if (currentCommonStyleName !== value) { @@ -330,7 +308,7 @@ define("webodf/editor/EditorSession", [ position: self.getCursorPosition(), styleName: value }); - session.enqueue(op); + session.enqueue([op]); } }; @@ -345,7 +323,7 @@ define("webodf/editor/EditorSession", [ tableColumnStyleName: tableColumnStyleName, tableCellStyleMatrix: tableCellStyleMatrix }); - session.enqueue(op); + session.enqueue([op]); }; /** @@ -409,7 +387,7 @@ define("webodf/editor/EditorSession", [ setProperties: setProperties, removedProperties: (!removedProperties) ? {} : removedProperties }); - session.enqueue(op); + session.enqueue([op]); }; /** @@ -447,7 +425,7 @@ define("webodf/editor/EditorSession", [ styleFamily: 'paragraph', setProperties: setProperties }); - session.enqueue(op); + session.enqueue([op]); return newStyleName; }; @@ -460,7 +438,7 @@ define("webodf/editor/EditorSession", [ styleName: styleName, styleFamily: 'paragraph' }); - session.enqueue(op); + session.enqueue([op]); }; /** @@ -469,7 +447,7 @@ define("webodf/editor/EditorSession", [ * first font name for any given family is kept. * The elements of the array are objects containing the font's name and * the family. - * @return {Array.{Object}} + * @return {Array.} */ this.getDeclaredFonts = function () { var fontMap = formatting.getFontMap(), @@ -523,6 +501,17 @@ define("webodf/editor/EditorSession", [ undoManager.moveForward(1); }; + /** + * + * @param {!string} mimetype + * @param {!string} content base64 encoded string + * @param {!number} width + * @param {!number} height + */ + this.insertImage = function (mimetype, content, width, height) { + self.sessionController.getTextManipulator().removeCurrentSelection(); + self.sessionController.getImageManager().insertImage(mimetype, content, width, height); + }; /** * @param {!function(!Object=)} callback, passing an error object in case of error * @return {undefined} @@ -573,12 +562,18 @@ define("webodf/editor/EditorSession", [ if (err) { callback(err); } else { - self.sessionController.destroy(function(err) { + selectionViewManager.destroy(function(err) { if (err) { callback(err); } else { - delete self.sessionController; - callback(); + self.sessionController.destroy(function(err) { + if (err) { + callback(err); + } else { + delete self.sessionController; + callback(); + } + }); } }); } @@ -596,6 +591,14 @@ define("webodf/editor/EditorSession", [ fontStyles.appendChild(document.createTextNode(fontsCSS)); head.appendChild(fontStyles); + self.sessionController = new gui.SessionController(session, localMemberId, shadowCursor, { + directStylingEnabled: config.directStylingEnabled + }); + caretManager = new gui.CaretManager(self.sessionController); + selectionViewManager = new gui.SelectionViewManager(); + self.sessionView = new gui.SessionView(config.viewOptions, localMemberId, session, caretManager, selectionViewManager); + self.availableFonts = getAvailableFonts(); + selectionViewManager.registerCursor(shadowCursor, true); // Custom signals, that make sense in the Editor context. We do not want to expose webodf's ops signals to random bits of the editor UI. odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); diff --git a/js/3rdparty/webodf/editor/MemberListView.js b/js/3rdparty/webodf/editor/MemberListView.js index f51aec3c..231db2d7 100644 --- a/js/3rdparty/webodf/editor/MemberListView.js +++ b/js/3rdparty/webodf/editor/MemberListView.js @@ -10,6 +10,9 @@ * 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 @@ -30,7 +33,7 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global define,runtime */ diff --git a/js/3rdparty/webodf/editor/Tools.js b/js/3rdparty/webodf/editor/Tools.js index 4810e133..f4a6ccb0 100644 --- a/js/3rdparty/webodf/editor/Tools.js +++ b/js/3rdparty/webodf/editor/Tools.js @@ -9,6 +9,9 @@ * 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 @@ -29,10 +32,10 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ -/*global define,document,require */ +/*global define,document,require,ops */ define("webodf/editor/Tools", [ "dojo/ready", @@ -45,29 +48,48 @@ define("webodf/editor/Tools", [ "webodf/editor/widgets/simpleStyles", "webodf/editor/widgets/undoRedoMenu", "webodf/editor/widgets/toolbarWidgets/currentStyle", + "webodf/editor/widgets/annotation", "webodf/editor/widgets/paragraphStylesDialog", - "webodf/editor/widgets/zoomSlider"], - function (ready, MenuItem, DropDownMenu, Button, DropDownButton, Toolbar, ParagraphAlignment, SimpleStyles, UndoRedoMenu, CurrentStyle, ParagraphStylesDialog, ZoomSlider) { + "webodf/editor/widgets/imageInserter", + "webodf/editor/widgets/zoomSlider", + "webodf/editor/EditorSession"], + function (ready, MenuItem, DropDownMenu, Button, DropDownButton, Toolbar, ParagraphAlignment, SimpleStyles, UndoRedoMenu, CurrentStyle, AnnotationControl, ParagraphStylesDialog, ImageInserter, ZoomSlider, EditorSession) { "use strict"; return function Tools(args) { - var translator = document.translator, + var tr = runtime.tr, onToolDone = args.onToolDone, loadOdtFile = args.loadOdtFile, saveOdtFile = args.saveOdtFile, close = args.close, toolbar, - loadButton, saveButton, annotateButton, closeButton, + loadButton, saveButton, closeButton, formatDropDownMenu, formatMenuButton, paragraphStylesMenuItem, paragraphStylesDialog, simpleStyles, currentStyle, zoomSlider, undoRedoMenu, editorSession, paragraphAlignment, + imageInserter, + annotationControl, sessionSubscribers = []; + function handleCursorMoved(cursor) { + var disabled = cursor.getSelectionType() === ops.OdtCursor.RegionSelection; + if (formatMenuButton) { + formatMenuButton.setAttribute('disabled', disabled); + } + } + function setEditorSession(session) { + if (editorSession) { + editorSession.unsubscribe(EditorSession.signalCursorMoved, handleCursorMoved); + } editorSession = session; + if (editorSession) { + editorSession.subscribe(EditorSession.signalCursorMoved, handleCursorMoved); + } + sessionSubscribers.forEach(function (subscriber) { subscriber.setEditorSession(editorSession); }); @@ -80,8 +102,18 @@ define("webodf/editor/Tools", [ * @return {undefined} */ this.destroy = function (callback) { - // TODO: investigate what else needs to be done - toolbar.destroyRecursive(true); + // TODO: + // 1. We don't want to use `document` + // 2. We would like to avoid deleting all widgets + // under document.body because this might interfere with + // other apps that use the editor not-in-an-iframe, + // but dojo always puts its dialogs below the body, + // so this works for now. Perhaps will be obsoleted + // once we move to a better widget toolkit + var widgets = dijit.findWidgets(document.body); + dojo.forEach(widgets, function(w) { + w.destroyRecursive(false); + }); callback(); }; @@ -100,18 +132,12 @@ define("webodf/editor/Tools", [ // Add annotation if (args.annotationsEnabled) { - annotateButton = new Button({ - label: translator('annotate'), - showLabel: false, - iconClass: 'dijitIconBookmark', - onClick: function () { - if (editorSession) { - editorSession.addAnnotation(); - onToolDone(); - } - } + annotationControl = new AnnotationControl(function (widget) { + widget.placeAt(toolbar); + widget.startup(); }); - annotateButton.placeAt(toolbar); + sessionSubscribers.push(annotationControl); + annotationControl.onToolDone = onToolDone; } // Simple Style Selector [B, I, U, S] @@ -154,7 +180,7 @@ define("webodf/editor/Tools", [ // Load if (loadOdtFile) { loadButton = new Button({ - label: translator('open'), + label: tr('Open'), showLabel: false, iconClass: 'dijitIcon dijitIconFolderOpen', style: { @@ -170,7 +196,7 @@ define("webodf/editor/Tools", [ // Save if (saveOdtFile) { saveButton = new Button({ - label: translator('save'), + label: tr('Save'), showLabel: false, iconClass: 'dijitEditorIcon dijitEditorIconSave', style: { @@ -187,7 +213,7 @@ define("webodf/editor/Tools", [ // Format menu formatDropDownMenu = new DropDownMenu({}); paragraphStylesMenuItem = new MenuItem({ - label: translator("paragraph_DDD") + label: tr("Paragraph...") }); formatDropDownMenu.addChild(paragraphStylesMenuItem); @@ -204,7 +230,7 @@ define("webodf/editor/Tools", [ formatMenuButton = new DropDownButton({ dropDown: formatDropDownMenu, - label: translator('format'), + label: tr('Format'), iconClass: "dijitIconEditTask", style: { float: 'left' @@ -212,9 +238,18 @@ define("webodf/editor/Tools", [ }); formatMenuButton.placeAt(toolbar); + if (args.imageInsertingEnabled) { + imageInserter = new ImageInserter(function (widget) { + widget.placeAt(toolbar); + widget.startup(); + }); + sessionSubscribers.push(imageInserter); + imageInserter.onToolDone = onToolDone; + } + if (close) { closeButton = new Button({ - label: translator('close'), + label: tr('Close'), showLabel: false, iconClass: 'dijitEditorIcon dijitEditorIconCancel', style: { diff --git a/js/3rdparty/webodf/editor/nls/de/myResources.js b/js/3rdparty/webodf/editor/nls/de/myResources.js index 109078be..a9e7ae3d 100644 --- a/js/3rdparty/webodf/editor/nls/de/myResources.js +++ b/js/3rdparty/webodf/editor/nls/de/myResources.js @@ -10,6 +10,9 @@ * 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 @@ -30,7 +33,7 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ define({ diff --git a/js/3rdparty/webodf/editor/nls/myResources.js b/js/3rdparty/webodf/editor/nls/myResources.js index fb5b0a10..e480d312 100644 --- a/js/3rdparty/webodf/editor/nls/myResources.js +++ b/js/3rdparty/webodf/editor/nls/myResources.js @@ -9,6 +9,9 @@ * 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 @@ -29,7 +32,7 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ define({ root: { @@ -91,7 +94,8 @@ define({ color: "Color", text: "Text", background: "Background", - defaultStyle: "Default Style" + defaultStyle: "Default Style", + insertImage: "Insert Image" }, de: true, diff --git a/js/3rdparty/webodf/editor/nls/ru/myResources.js b/js/3rdparty/webodf/editor/nls/ru/myResources.js index 879d0ac4..16057255 100644 --- a/js/3rdparty/webodf/editor/nls/ru/myResources.js +++ b/js/3rdparty/webodf/editor/nls/ru/myResources.js @@ -9,6 +9,9 @@ * 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 @@ -29,7 +32,7 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ define({ file: 'досье', diff --git a/js/3rdparty/webodf/editor/server/ServerFactory.js b/js/3rdparty/webodf/editor/server/ServerFactory.js index c4fafcac..e60c16d4 100644 --- a/js/3rdparty/webodf/editor/server/ServerFactory.js +++ b/js/3rdparty/webodf/editor/server/ServerFactory.js @@ -10,6 +10,9 @@ * 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 @@ -30,7 +33,7 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global ops, SessionList*/ @@ -38,7 +41,7 @@ /** * @interface */ -ServerFactory = function Server() {"use strict"; }; +function ServerFactory() {"use strict"; }; /** * @return {!ops.Server} diff --git a/js/3rdparty/webodf/editor/server/owncloud/ServerFactory.js b/js/3rdparty/webodf/editor/server/owncloud/ServerFactory.js index bf3a32cc..c8111cfa 100644 --- a/js/3rdparty/webodf/editor/server/owncloud/ServerFactory.js +++ b/js/3rdparty/webodf/editor/server/owncloud/ServerFactory.js @@ -3,34 +3,24 @@ * 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. * - * 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: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global define, require, OC*/ diff --git a/js/3rdparty/webodf/editor/server/pullbox/MemberModel.js b/js/3rdparty/webodf/editor/server/pullbox/MemberModel.js index 534b0eb7..9303a1cf 100644 --- a/js/3rdparty/webodf/editor/server/pullbox/MemberModel.js +++ b/js/3rdparty/webodf/editor/server/pullbox/MemberModel.js @@ -3,34 +3,24 @@ * 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. * - * 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: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global runtime, ops*/ diff --git a/js/3rdparty/webodf/editor/server/pullbox/OperationRouter.js b/js/3rdparty/webodf/editor/server/pullbox/OperationRouter.js index 48995e44..6e95148a 100644 --- a/js/3rdparty/webodf/editor/server/pullbox/OperationRouter.js +++ b/js/3rdparty/webodf/editor/server/pullbox/OperationRouter.js @@ -3,34 +3,24 @@ * 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. * - * 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: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global runtime, ops*/ @@ -81,8 +71,6 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () { unplayedServerOpspecQueue = [], /** @type {!Array.} sync request callbacks which should be called after the received ops have been applied server */ uncalledSyncRequestCallbacksQueue = [], - /** @type {!Array.} ops created since the last sync call to the server */ - hasLocalUnsyncedOpsStateSubscribers = [], /**@type{!boolean}*/ hasLocalUnsyncedOps = false, /**@type{!boolean} tells if any local ops have been modifying ops */ @@ -92,10 +80,11 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () { /**@const*/syncOpsDelay = 3000, /**@const*/idleDelay = 5000; - + /** + * @return {undefined} + */ function updateHasLocalUnsyncedOpsState() { - var i, - hasLocalUnsyncedOpsNow = (unsyncedClientOpspecQueue.length > 0); + var hasLocalUnsyncedOpsNow = (unsyncedClientOpspecQueue.length > 0); // no change? if (hasLocalUnsyncedOps === hasLocalUnsyncedOpsNow) { @@ -103,45 +92,6 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () { } hasLocalUnsyncedOps = hasLocalUnsyncedOpsNow; - for (i=0; i} opspecs - * @return {!Array.} - */ - function compressOpSpecs(opspecs) { - var i, j, op, - result = []; - - i = 0; - while (i < opspecs.length) { - // use factory to create an instance, and playback! - op = operationFactory.create(opspecs[i]); - // is known op and can do merge? - if (op !== null && op.merge) { - // go over the following and try to merge them - for (j = i+1; j < opspecs.length; j += 1) { - if (!op.merge(opspecs[j])) { - break; - } -runtime.log("Merged: "+opspecs[i].optype+" with "+opspecs[j].optype); - } - // add the resulting op to the results - result.push(op.spec()); - // and continue with the one which could not be merged, or behind end - i = j; - } else { - // just pass on - result.push(opspecs[i]); - i += 1; - } - } -runtime.log("Merged: from "+opspecs.length+" to "+result.length+" specs"); - - return result; } /** @@ -307,12 +257,12 @@ runtime.log("OperationRouter: sending sync_ops call"); if (response.ops.length > 0) { // no new locally in the meantime? if (unsyncedClientOpspecQueue.length === 0) { - receiveOpSpecsFromNetwork(compressOpSpecs(response.ops), syncRequestCallbacksArray); + receiveOpSpecsFromNetwork(response.ops, syncRequestCallbacksArray); } else { // transform server ops against new local ones and apply, // transform and send new local ops to server runtime.log("meh, have new ops locally meanwhile, have to do transformations."); - hasUnresolvableConflict = !handleOpsSyncConflict(compressOpSpecs(response.ops)); + hasUnresolvableConflict = !handleOpsSyncConflict(response.ops); syncRequestCallbacksQueue = syncRequestCallbacksArray.concat(syncRequestCallbacksQueue); } // and note server state @@ -333,7 +283,7 @@ runtime.log("OperationRouter: sending sync_ops call"); // transform server ops against new local ones and apply, // transform and request new send new local ops to server runtime.log("meh, server has new ops meanwhile, have to do transformations."); - hasUnresolvableConflict = !handleOpsSyncConflict(compressOpSpecs(response.ops)); + hasUnresolvableConflict = !handleOpsSyncConflict(response.ops); // and note server state lastServerSeq = response.head_seq; // try again instantly @@ -441,13 +391,10 @@ runtime.log("OperationRouter: instant opsSync requested"); /** * Brings the locally created operations into the game. * - * @param {!ops.Operation} op + * @param {!Array.} operations * @return {undefined} */ - this.push = function (op) { - var timedOp, - opspec = op.spec(); - + this.push = function (operations) { if (hasUnresolvableConflict) { return; } @@ -459,17 +406,22 @@ runtime.log("OperationRouter: instant opsSync requested"); return; } - // note if any local ops modified TODO: find less fragile way, perhaps have the operationFactory check it? - hasPushedModificationOps = hasPushedModificationOps || !/^(AddCursor|MoveCursor|RemoveCursor)$/.test(opspec.optype); + operations.forEach(function(op) { + var timedOp, + opspec = op.spec(); + + // note if any local ops modified TODO: find less fragile way, perhaps have the operationFactory check it? + hasPushedModificationOps = hasPushedModificationOps || !/^(AddCursor|MoveCursor|RemoveCursor)$/.test(opspec.optype); - // apply locally - opspec.timestamp = (new Date()).getTime(); - timedOp = operationFactory.create(opspec); + // apply locally + opspec.timestamp = (new Date()).getTime(); + timedOp = operationFactory.create(opspec); - playbackFunction(timedOp); + playbackFunction(timedOp); - // send to server - unsyncedClientOpspecQueue.push(opspec); + // send to server + unsyncedClientOpspecQueue.push(opspec); + }); triggerPushingOps(); @@ -502,40 +454,5 @@ runtime.log("OperationRouter: instant opsSync requested"); } }; - this.getHasLocalUnsyncedOpsAndUpdates = function (subscriber) { - var i; - - // detect double subscription - for (i=0; i * * @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. * - * 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: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global XMLHttpRequest, runtime, core, ops*/ diff --git a/js/3rdparty/webodf/editor/server/pullbox/ServerFactory.js b/js/3rdparty/webodf/editor/server/pullbox/ServerFactory.js index 5a67425a..dc07ba64 100644 --- a/js/3rdparty/webodf/editor/server/pullbox/ServerFactory.js +++ b/js/3rdparty/webodf/editor/server/pullbox/ServerFactory.js @@ -3,34 +3,24 @@ * 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. * - * 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: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global define, document, require, runtime, ops */ diff --git a/js/3rdparty/webodf/editor/server/pullbox/SessionList.js b/js/3rdparty/webodf/editor/server/pullbox/SessionList.js index e0d57acc..988da2eb 100644 --- a/js/3rdparty/webodf/editor/server/pullbox/SessionList.js +++ b/js/3rdparty/webodf/editor/server/pullbox/SessionList.js @@ -3,34 +3,24 @@ * 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. * - * 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: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global define, ops, runtime */ diff --git a/js/3rdparty/webodf/editor/widgets/annotation.js b/js/3rdparty/webodf/editor/widgets/annotation.js new file mode 100644 index 00000000..013d199b --- /dev/null +++ b/js/3rdparty/webodf/editor/widgets/annotation.js @@ -0,0 +1,103 @@ +/** + * @license + * Copyright (C) 2013 KO GmbH + * + * @licstart + * The JavaScript code in this page is free software: you can redistribute it + * and/or modify it under the terms of the GNU Affero General Public License + * (GNU AGPL) as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. The code is distributed + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + * + * 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/ + */ + +/*global define, require */ + +define("webodf/editor/widgets/annotation", [ + "dijit/form/Button"], + + function (Button) { + "use strict"; + + var AnnotationControl = function (callback) { + var self = this, + widget = {}, + addAnnotationButton, + annotationManager; + + + addAnnotationButton = new Button({ + label: runtime.tr('Annotate'), + disabled: true, + showLabel: false, + iconClass: 'dijitIconBookmark', + onClick: function () { + if (annotationManager) { + annotationManager.addAnnotation(); + self.onToolDone(); + } + } + }); + + widget.children = [addAnnotationButton]; + widget.startup = function () { + widget.children.forEach(function (element) { + element.startup(); + }); + }; + + widget.placeAt = function (container) { + widget.children.forEach(function (element) { + element.placeAt(container); + }); + return widget; + }; + + function onAnnotatableChanged(isAnnotatable) { + addAnnotationButton.setAttribute('disabled', !isAnnotatable); + } + + this.setEditorSession = function (session) { + if (annotationManager) { + annotationManager.unsubscribe(gui.AnnotationManager.annotatableChanged, onAnnotatableChanged); + } + annotationManager = session && session.sessionController.getAnnotationManager(); + if (annotationManager) { + annotationManager.subscribe(gui.AnnotationManager.annotatableChanged, onAnnotatableChanged); + } + onAnnotatableChanged(annotationManager && annotationManager.isAnnotatable()); + }; + + this.onToolDone = function () {}; + + callback(widget); + }; + + return AnnotationControl; + } +); diff --git a/js/3rdparty/webodf/editor/widgets/dialogWidgets/alignmentPane.html b/js/3rdparty/webodf/editor/widgets/dialogWidgets/alignmentPane.html index 8829fa59..56d9deae 100644 --- a/js/3rdparty/webodf/editor/widgets/dialogWidgets/alignmentPane.html +++ b/js/3rdparty/webodf/editor/widgets/dialogWidgets/alignmentPane.html @@ -4,22 +4,22 @@
-

Options

+

Options

-
+
-
+
-
+
-
+
-

Spacing (mm)

+

(mm)

- +

- +
- +

- + . + * * 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 @@ -30,10 +33,10 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ -/*global runtime,core,define,require,document,dijit */ +/*global runtime,core,define,require,dijit */ runtime.loadClass("core.CSSUnits"); @@ -103,13 +106,13 @@ define("webodf/editor/widgets/dialogWidgets/alignmentPane", [], function () { runtime.assert(editorBase, "webodf/editor path not defined in dojoConfig"); ready(function () { contentPane = new ContentPane({ - title: document.translator("alignment"), + title: runtime.tr("Alignment"), href: editorBase+"/widgets/dialogWidgets/alignmentPane.html", preload: true }); contentPane.onLoad = function () { form = dijit.byId('alignmentPaneForm'); - document.translateContent(form.domNode); + runtime.translateContent(form.domNode); }; return cb(); }); diff --git a/js/3rdparty/webodf/editor/widgets/dialogWidgets/fontEffectsPane.html b/js/3rdparty/webodf/editor/widgets/dialogWidgets/fontEffectsPane.html index 5a0c8997..4978583a 100644 --- a/js/3rdparty/webodf/editor/widgets/dialogWidgets/fontEffectsPane.html +++ b/js/3rdparty/webodf/editor/widgets/dialogWidgets/fontEffectsPane.html @@ -4,23 +4,23 @@
-

Style

+

-
+
-
+
-
+
-

Font

+


- +
- +

-

Color

+


- - Text - +
@@ -43,9 +41,7 @@
- - Background - +
diff --git a/js/3rdparty/webodf/editor/widgets/dialogWidgets/fontEffectsPane.js b/js/3rdparty/webodf/editor/widgets/dialogWidgets/fontEffectsPane.js index 9394f032..d766087f 100644 --- a/js/3rdparty/webodf/editor/widgets/dialogWidgets/fontEffectsPane.js +++ b/js/3rdparty/webodf/editor/widgets/dialogWidgets/fontEffectsPane.js @@ -10,6 +10,9 @@ * 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 @@ -30,7 +33,7 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global runtime,define,require,document,dijit */ @@ -123,13 +126,12 @@ define("webodf/editor/widgets/dialogWidgets/fontEffectsPane", [], function () { "dojox/widget/ColorPicker", "webodf/editor/widgets/fontPicker" ], function (dojo, ready, domConstruct, ContentPane, ColorPicker, FontPicker) { - var translator = document.translator, - editorBase = dojo.config && dojo.config.paths && + var editorBase = dojo.config && dojo.config.paths && dojo.config.paths['webodf/editor']; runtime.assert(editorBase, "webodf/editor path not defined in dojoConfig"); ready(function () { contentPane = new ContentPane({ - title: translator("fontEffects"), + title: runtime.tr("Font Effects"), href: editorBase+"/widgets/dialogWidgets/fontEffectsPane.html", preload: true }); @@ -139,7 +141,7 @@ define("webodf/editor/widgets/dialogWidgets/fontEffectsPane", [], function () { backgroundColorTB = dijit.byId('backgroundColorTB'); form = dijit.byId('fontEffectsPaneForm'); - document.translateContent(form.domNode); + runtime.translateContent(form.domNode); preview = document.getElementById('previewText'); textColorPicker = dijit.byId('textColorPicker'); diff --git a/js/3rdparty/webodf/editor/widgets/fontPicker.js b/js/3rdparty/webodf/editor/widgets/fontPicker.js index 513c2626..039c21b0 100644 --- a/js/3rdparty/webodf/editor/widgets/fontPicker.js +++ b/js/3rdparty/webodf/editor/widgets/fontPicker.js @@ -9,6 +9,9 @@ * 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 @@ -29,7 +32,7 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global define,require,document */ define("webodf/editor/widgets/fontPicker", [ diff --git a/js/3rdparty/webodf/editor/widgets/imageInserter.js b/js/3rdparty/webodf/editor/widgets/imageInserter.js new file mode 100644 index 00000000..607fb2ba --- /dev/null +++ b/js/3rdparty/webodf/editor/widgets/imageInserter.js @@ -0,0 +1,166 @@ +/** + * @license + * Copyright (C) 2012-2013 KO GmbH + * + * @licstart + * The JavaScript code in this page is free software: you can redistribute it + * and/or modify it under the terms of the GNU Affero General Public License + * (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/ + */ + +/*global define,require,document,Image,FileReader,window,runtime,ops */ + +define("webodf/editor/widgets/imageInserter", [ + "dijit/form/Button", + "webodf/editor/EditorSession"], + + function (Button, EditorSession) { + "use strict"; + + var ImageInserter = function (callback) { + var self = this, + widget = {}, + insertImageButton, + editorSession, + fileLoader; + + + /** + * @param {!string} content as datauri + * @param {!string} mimetype + * @return {undefined} + */ + function insertImageOnceLoaded(mimetype, content) { + var hiddenImage = new Image(); + + hiddenImage.style.position = "absolute"; + hiddenImage.style.left = "-99999px"; + document.body.appendChild(hiddenImage); + hiddenImage.onload = function () { + // remove the data:image/jpg;base64, bit + content = content.substring(content.indexOf(",") + 1); + if (editorSession) { + editorSession.insertImage(mimetype, content, hiddenImage.width, hiddenImage.height); + } + // clean up + document.body.removeChild(hiddenImage); + self.onToolDone(); + }; + hiddenImage.src = content; + } + + function fileSelectHandler(evt) { + var file, files, reader; + files = (evt.target && evt.target.files) || (evt.dataTransfer && evt.dataTransfer.files); + if (files && files.length === 1) { + file = files[0]; + reader = new FileReader(); + reader.onloadend = function () { + if (reader.readyState === 2) { + insertImageOnceLoaded(file.type, reader.result); + } else { + runtime.log("Image could not be loaded"); + self.onToolDone(); + } + }; + reader.readAsDataURL(file); + } + } + + function createFileLoader() { + var form = document.createElement("form"), + input = document.createElement("input"); + form.appendChild(input); + form.id = "imageForm"; + form.style.display = "none"; + input.id = "imageLoader"; + input.setAttribute("type", "file"); + input.setAttribute("accept", "image/*"); + input.addEventListener("change", fileSelectHandler, false); + document.body.appendChild(form); + return {input: input, form: form}; + } + + insertImageButton = new Button({ + label: runtime.tr("Insert Image"), + disabled: true, + showLabel: false, + iconClass: "dijitEditorIcon dijitEditorIconInsertImage", + onClick: function () { + if (!fileLoader) { + fileLoader = createFileLoader(); + } + fileLoader.form.reset(); + fileLoader.input.click(); + } + }); + + widget.children = [insertImageButton]; + widget.startup = function () { + widget.children.forEach(function (element) { + element.startup(); + }); + }; + + widget.placeAt = function (container) { + widget.children.forEach(function (element) { + element.placeAt(container); + }); + return widget; + }; + + function handleCursorMoved(cursor) { + var disabled = cursor.getSelectionType() === ops.OdtCursor.RegionSelection; + // LO/AOO pops up the picture/frame option dialog if image is selected when pressing the button + // Since we only support inline images, disable the button for now. + insertImageButton.setAttribute('disabled', disabled); + } + + this.setEditorSession = function (session) { + if (editorSession) { + editorSession.unsubscribe(EditorSession.signalCursorMoved, handleCursorMoved); + } + editorSession = session; + if (editorSession) { + editorSession.subscribe(EditorSession.signalCursorMoved, handleCursorMoved); + } + widget.children.forEach(function (element) { + element.setAttribute("disabled", !session); + }); + }; + + this.onToolDone = function () {}; + + callback(widget); + }; + + return ImageInserter; + }); diff --git a/js/3rdparty/webodf/editor/widgets/paragraphAlignment.js b/js/3rdparty/webodf/editor/widgets/paragraphAlignment.js index 97c6cf2a..ae833b04 100644 --- a/js/3rdparty/webodf/editor/widgets/paragraphAlignment.js +++ b/js/3rdparty/webodf/editor/widgets/paragraphAlignment.js @@ -10,6 +10,9 @@ * 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 @@ -30,20 +33,22 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ -/*global define,require,document */ +/*global define,require,ops,gui */ define("webodf/editor/widgets/paragraphAlignment", [ "dijit/form/ToggleButton", - "dijit/form/Button"], + "dijit/form/Button", + "webodf/editor/EditorSession"], - function (ToggleButton, Button) { + function (ToggleButton, Button, EditorSession) { "use strict"; var ParagraphAlignment = function (callback) { var self = this, + editorSession, widget = {}, directParagraphStyler, justifyLeft, @@ -54,7 +59,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ outdent; justifyLeft = new ToggleButton({ - label: document.translator('justifyLeft'), + label: runtime.tr('Align Left'), disabled: true, showLabel: false, checked: false, @@ -66,7 +71,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ }); justifyCenter = new ToggleButton({ - label: document.translator('justifyCenter'), + label: runtime.tr('Center'), disabled: true, showLabel: false, checked: false, @@ -78,7 +83,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ }); justifyRight = new ToggleButton({ - label: document.translator('justifyRight'), + label: runtime.tr('Align Right'), disabled: true, showLabel: false, checked: false, @@ -90,7 +95,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ }); justifyFull = new ToggleButton({ - label: document.translator('justifyFull'), + label: runtime.tr('Justify'), disabled: true, showLabel: false, checked: false, @@ -102,7 +107,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ }); outdent = new Button({ - label: document.translator('outdent'), + label: runtime.tr('Decrease Indent'), disabled: true, showLabel: false, iconClass: "dijitEditorIcon dijitEditorIconOutdent", @@ -113,7 +118,7 @@ define("webodf/editor/widgets/paragraphAlignment", [ }); indent = new Button({ - label: document.translator('indent'), + label: runtime.tr('Increase Indent'), disabled: true, showLabel: false, iconClass: "dijitEditorIcon dijitEditorIconIndent", @@ -161,7 +166,14 @@ define("webodf/editor/widgets/paragraphAlignment", [ }); } - this.setEditorSession = function(session) { + function handleCursorMoved(cursor) { + var disabled = cursor.getSelectionType() === ops.OdtCursor.RegionSelection; + widget.children.forEach(function (element) { + element.setAttribute('disabled', disabled); + }); + } + + this.setEditorSession = function (session) { if (directParagraphStyler) { directParagraphStyler.unsubscribe(gui.DirectParagraphStyler.paragraphStylingChanged, updateStyleButtons); } @@ -178,6 +190,14 @@ define("webodf/editor/widgets/paragraphAlignment", [ isAlignedRight: directParagraphStyler ? directParagraphStyler.isAlignedRight() : false, isAlignedJustified: directParagraphStyler ? directParagraphStyler.isAlignedJustified() : false }); + + if (editorSession) { + editorSession.unsubscribe(EditorSession.signalCursorMoved, handleCursorMoved); + } + editorSession = session; + if (editorSession) { + editorSession.subscribe(EditorSession.signalCursorMoved, handleCursorMoved); + } }; this.onToolDone = function () {}; diff --git a/js/3rdparty/webodf/editor/widgets/paragraphStyles.js b/js/3rdparty/webodf/editor/widgets/paragraphStyles.js index aec34eee..e7a93640 100644 --- a/js/3rdparty/webodf/editor/widgets/paragraphStyles.js +++ b/js/3rdparty/webodf/editor/widgets/paragraphStyles.js @@ -10,6 +10,9 @@ * 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 @@ -30,7 +33,7 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global define,require */ @@ -38,7 +41,7 @@ define("webodf/editor/widgets/paragraphStyles", ["webodf/editor/EditorSession"], - function (EditorSession) { + function (EditorSession) { "use strict"; /** * @constructor @@ -47,7 +50,6 @@ define("webodf/editor/widgets/paragraphStyles", var self = this, editorSession, select, - translator = document.translator, defaultStyleUIId = ":default"; this.widget = function () { @@ -90,7 +92,7 @@ define("webodf/editor/widgets/paragraphStyles", // Populate the Default Style always selectionList = [{ - label: translator("defaultStyle"), + label: runtime.tr("Default Style"), value: defaultStyleUIId }]; availableStyles = editorSession ? editorSession.getAvailableParagraphStyles() : []; @@ -166,15 +168,24 @@ define("webodf/editor/widgets/paragraphStyles", }); } + function handleCursorMoved(cursor) { + var disabled = cursor.getSelectionType() === ops.OdtCursor.RegionSelection; + if (select) { + select.setAttribute('disabled', disabled); + } + } + this.setEditorSession = function(session) { if (editorSession) { editorSession.unsubscribe(EditorSession.signalCommonStyleCreated, addStyle); editorSession.unsubscribe(EditorSession.signalCommonStyleDeleted, removeStyle); + editorSession.unsubscribe(EditorSession.signalCursorMoved, handleCursorMoved); } editorSession = session; if (editorSession) { editorSession.subscribe(EditorSession.signalCommonStyleCreated, addStyle); editorSession.subscribe(EditorSession.signalCommonStyleDeleted, removeStyle); + editorSession.subscribe(EditorSession.signalCursorMoved, handleCursorMoved); populateStyles(); } }; diff --git a/js/3rdparty/webodf/editor/widgets/paragraphStylesDialog.js b/js/3rdparty/webodf/editor/widgets/paragraphStylesDialog.js index 8eab4b27..708e9f53 100644 --- a/js/3rdparty/webodf/editor/widgets/paragraphStylesDialog.js +++ b/js/3rdparty/webodf/editor/widgets/paragraphStylesDialog.js @@ -10,6 +10,9 @@ * 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 @@ -30,10 +33,10 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ -/*global define,require,document,dojo,dijit */ +/*global define,require,dojo,dijit */ define("webodf/editor/widgets/paragraphStylesDialog", [], function () { "use strict"; @@ -54,7 +57,7 @@ define("webodf/editor/widgets/paragraphStylesDialog", [], function () { "dijit/form/DropDownButton", "dijit/form/RadioButton"], function (Dialog, TooltipDialog, popup, TabContainer, ContentPane, Button, DropDownButton, RadioButton) { var i, - translator = document.translator, + tr = runtime.tr, tabContainer, flowPane, numberingPane, @@ -179,17 +182,17 @@ define("webodf/editor/widgets/paragraphStylesDialog", [], function () { } // Dialog dialog = new Dialog({ - title: translator("paragraphStyles") + title: tr("Paragraph Styles") }); cloneTooltip = new TooltipDialog({ content: - '

'+translator("cloneThisStyle")+'


' + - '

', + '

'+tr("Clone this Style")+'


' + + '

', style: "width: 300px;" }); cloneButton = new Button({ - label: translator("create"), + label: tr("Create"), onClick: function () { cloneStyle(stylePicker.value(), cloneTooltip.get('value').name); cloneTooltip.reset(); @@ -198,7 +201,7 @@ define("webodf/editor/widgets/paragraphStylesDialog", [], function () { }); cloneTooltip.addChild(cloneButton); cloneDropDown = new DropDownButton({ - label: translator("clone"), + label: tr("Clone"), showLabel: false, iconClass: 'dijitEditorIcon dijitEditorIconCopy', dropDown: cloneTooltip, @@ -207,7 +210,7 @@ define("webodf/editor/widgets/paragraphStylesDialog", [], function () { dialog.addChild(cloneDropDown, 1); deleteButton = new Button({ - label: translator("delete"), + label: tr("Delete"), showLabel: false, iconClass: 'dijitEditorIcon dijitEditorIconDelete', style: "float: right; margin-bottom: 5px;", @@ -227,11 +230,11 @@ define("webodf/editor/widgets/paragraphStylesDialog", [], function () { "class": "dijitDialogPaneActionBar" }); okButton = new dijit.form.Button({ - label: translator("ok"), + label: tr("OK"), onClick: accept }).placeAt(actionBar); cancelButton = new dijit.form.Button({ - label: translator("cancel"), + label: tr("Cancel"), onClick: cancel }).placeAt(actionBar); dialog.domNode.appendChild(actionBar); diff --git a/js/3rdparty/webodf/editor/widgets/simpleStyles.js b/js/3rdparty/webodf/editor/widgets/simpleStyles.js index 9d9e16f5..10a6a107 100644 --- a/js/3rdparty/webodf/editor/widgets/simpleStyles.js +++ b/js/3rdparty/webodf/editor/widgets/simpleStyles.js @@ -10,6 +10,9 @@ * 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 @@ -30,21 +33,23 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ -/*global define,require,document */ +/*global define,require,gui,ops */ define("webodf/editor/widgets/simpleStyles", [ "webodf/editor/widgets/fontPicker", "dijit/form/ToggleButton", - "dijit/form/NumberSpinner"], + "dijit/form/NumberSpinner", + "webodf/editor/EditorSession"], - function (FontPicker, ToggleButton, NumberSpinner) { + function (FontPicker, ToggleButton, NumberSpinner, EditorSession) { "use strict"; var SimpleStyles = function(callback) { var self = this, + editorSession, widget = {}, directTextStyler, boldButton, @@ -56,7 +61,7 @@ define("webodf/editor/widgets/simpleStyles", [ fontPickerWidget; boldButton = new ToggleButton({ - label: document.translator('bold'), + label: runtime.tr('Bold'), disabled: true, showLabel: false, checked: false, @@ -68,7 +73,7 @@ define("webodf/editor/widgets/simpleStyles", [ }); italicButton = new ToggleButton({ - label: document.translator('italic'), + label: runtime.tr('Italic'), disabled: true, showLabel: false, checked: false, @@ -80,7 +85,7 @@ define("webodf/editor/widgets/simpleStyles", [ }); underlineButton = new ToggleButton({ - label: document.translator('underline'), + label: runtime.tr('Underline'), disabled: true, showLabel: false, checked: false, @@ -92,7 +97,7 @@ define("webodf/editor/widgets/simpleStyles", [ }); strikethroughButton = new ToggleButton({ - label: document.translator('strikethrough'), + label: runtime.tr('Strikethrough'), disabled: true, showLabel: false, checked: false, @@ -104,7 +109,7 @@ define("webodf/editor/widgets/simpleStyles", [ }); fontSizeSpinner = new NumberSpinner({ - label: document.translator('size'), + label: runtime.tr('Size'), disabled: true, showLabel: false, value: 12, @@ -170,6 +175,13 @@ define("webodf/editor/widgets/simpleStyles", [ }); } + function handleCursorMoved(cursor) { + var disabled = cursor.getSelectionType() === ops.OdtCursor.RegionSelection; + widget.children.forEach(function (element) { + element.setAttribute('disabled', disabled); + }); + } + this.setEditorSession = function(session) { if (directTextStyler) { directTextStyler.unsubscribe(gui.DirectTextStyler.textStylingChanged, updateStyleButtons); @@ -190,6 +202,14 @@ define("webodf/editor/widgets/simpleStyles", [ fontSize: directTextStyler ? directTextStyler.fontSize() : undefined, fontName: directTextStyler ? directTextStyler.fontName() : undefined }); + + if (editorSession) { + editorSession.unsubscribe(EditorSession.signalCursorMoved, handleCursorMoved); + } + editorSession = session; + if (editorSession) { + editorSession.subscribe(EditorSession.signalCursorMoved, handleCursorMoved); + } }; this.onToolDone = function () {}; diff --git a/js/3rdparty/webodf/editor/widgets/toolbarWidgets/currentStyle.js b/js/3rdparty/webodf/editor/widgets/toolbarWidgets/currentStyle.js index 47e7c718..7d864849 100644 --- a/js/3rdparty/webodf/editor/widgets/toolbarWidgets/currentStyle.js +++ b/js/3rdparty/webodf/editor/widgets/toolbarWidgets/currentStyle.js @@ -10,6 +10,9 @@ * 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 @@ -30,7 +33,7 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ /*global define, require */ diff --git a/js/3rdparty/webodf/editor/widgets/undoRedoMenu.js b/js/3rdparty/webodf/editor/widgets/undoRedoMenu.js index 7014074b..cf1a57cd 100644 --- a/js/3rdparty/webodf/editor/widgets/undoRedoMenu.js +++ b/js/3rdparty/webodf/editor/widgets/undoRedoMenu.js @@ -10,6 +10,9 @@ * 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 @@ -30,10 +33,10 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ -/*global define,require,document */ +/*global define,require*/ define("webodf/editor/widgets/undoRedoMenu", ["webodf/editor/EditorSession"], @@ -51,7 +54,7 @@ define("webodf/editor/widgets/undoRedoMenu", var widget = {}; undoButton = new Button({ - label: document.translator('undo'), + label: runtime.tr('Undo'), showLabel: false, disabled: true, // TODO: get current session state iconClass: "dijitEditorIcon dijitEditorIconUndo", @@ -63,7 +66,7 @@ define("webodf/editor/widgets/undoRedoMenu", }); redoButton = new Button({ - label: document.translator('redo'), + label: runtime.tr('Redo'), showLabel: false, disabled: true, // TODO: get current session state iconClass: "dijitEditorIcon dijitEditorIconRedo", diff --git a/js/3rdparty/webodf/editor/widgets/zoomSlider.js b/js/3rdparty/webodf/editor/widgets/zoomSlider.js index fccf8ffb..b445211e 100644 --- a/js/3rdparty/webodf/editor/widgets/zoomSlider.js +++ b/js/3rdparty/webodf/editor/widgets/zoomSlider.js @@ -10,6 +10,9 @@ * 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 @@ -30,10 +33,10 @@ * This license applies to this entire compilation. * @licend * @source: http://www.webodf.org/ - * @source: http://gitorious.org/webodf/webodf/ + * @source: https://github.com/kogmbh/WebODF/ */ -/*global define,require,document */ +/*global define,require*/ define("webodf/editor/widgets/zoomSlider", [], function () { "use strict"; diff --git a/js/3rdparty/webodf/webodf-debug.js b/js/3rdparty/webodf/webodf-debug.js index 9bb44d86..6c1479de 100644 --- a/js/3rdparty/webodf/webodf-debug.js +++ b/js/3rdparty/webodf/webodf-debug.js @@ -11,6 +11,9 @@ 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 @@ -31,7 +34,7 @@ This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ var core = {}; var gui = {}; @@ -948,7 +951,7 @@ var runtime = function() { } code = null; dir = dircontents[dir]; - if(dir && dir.indexOf && dir.indexOf(path) !== -1) { + if(dir && (dir.indexOf && dir.indexOf(path) !== -1)) { return dirs[i] + "/" + path } } @@ -987,6 +990,24 @@ var runtime = function() { cache[classpath] = true } })(); +(function() { + var translator = function() { + }; + function tr(original) { + var result = translator(original); + if(!result || String(typeof result) !== "string") { + return original + } + return result + } + runtime.getTranslator = function() { + return translator + }; + runtime.setTranslator = function(translatorFunction) { + translator = translatorFunction + }; + runtime.tr = tr +})(); (function(args) { if(args) { args = Array.prototype.slice.call((args)) @@ -1538,14 +1559,14 @@ core.RawDeflate = function() { } do { matchp = cur_match; - if(zip_window[matchp + best_len] !== scan_end || zip_window[matchp + best_len - 1] !== scan_end1 || zip_window[matchp] !== zip_window[scanp] || zip_window[++matchp] !== zip_window[scanp + 1]) { + if(zip_window[matchp + best_len] !== scan_end || (zip_window[matchp + best_len - 1] !== scan_end1 || (zip_window[matchp] !== zip_window[scanp] || zip_window[++matchp] !== zip_window[scanp + 1]))) { continue } scanp += 2; matchp++; do { ++scanp - }while(zip_window[scanp] === zip_window[++matchp] && zip_window[++scanp] === zip_window[++matchp] && zip_window[++scanp] === zip_window[++matchp] && zip_window[++scanp] === zip_window[++matchp] && zip_window[++scanp] === zip_window[++matchp] && zip_window[++scanp] === zip_window[++matchp] && zip_window[++scanp] === zip_window[++matchp] && zip_window[++scanp] === zip_window[++matchp] && scanp < strendp); + }while(zip_window[scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && (zip_window[++scanp] === zip_window[++matchp] && scanp < strendp)))))))); len = zip_MAX_MATCH - (strendp - scanp); scanp = strendp - zip_MAX_MATCH; if(len > best_len) { @@ -2044,7 +2065,7 @@ core.RawDeflate = function() { zip_prev_length = zip_match_length; zip_prev_match = zip_match_start; zip_match_length = zip_MIN_MATCH - 1; - if(zip_hash_head !== zip_NIL && zip_prev_length < zip_max_lazy_match && zip_strstart - zip_hash_head <= zip_MAX_DIST) { + if(zip_hash_head !== zip_NIL && (zip_prev_length < zip_max_lazy_match && zip_strstart - zip_hash_head <= zip_MAX_DIST)) { zip_match_length = zip_longest_match(zip_hash_head); if(zip_match_length > zip_lookahead) { zip_match_length = zip_lookahead @@ -2939,6 +2960,9 @@ core.RawInflate = function RawInflate() { 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 @@ -2959,7 +2983,7 @@ core.RawInflate = function RawInflate() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ core.LoopWatchDog = function LoopWatchDog(timeout, maxChecks) { var startTime = Date.now(), checks = 0; @@ -3023,6 +3047,9 @@ core.Utils = function Utils() { 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 @@ -3043,184 +3070,237 @@ core.Utils = function Utils() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -core.DomUtils = function DomUtils() { - function findStablePoint(container, offset) { - if(offset < container.childNodes.length) { - container = container.childNodes[offset]; - offset = 0; - while(container.firstChild) { - container = container.firstChild +(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 + } + core.DomUtils = function DomUtils() { + function findStablePoint(container, offset) { + if(offset < container.childNodes.length) { + container = container.childNodes[offset]; + offset = 0; + while(container.firstChild) { + container = container.firstChild + } + }else { + while(container.lastChild) { + container = container.lastChild; + offset = container.nodeType === Node.TEXT_NODE ? container.textContent.length : container.childNodes.length + } } - }else { - while(container.lastChild) { - container = container.lastChild; - offset = container.nodeType === Node.TEXT_NODE ? container.textContent.length : container.childNodes.length + return{container:container, offset:offset} + } + function splitBoundaries(range) { + var modifiedNodes = [], end, splitStart; + if(range.startContainer.nodeType === Node.TEXT_NODE || range.endContainer.nodeType === Node.TEXT_NODE) { + end = 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) + } + if(range.startOffset !== 0 && (range.startContainer.nodeType === Node.TEXT_NODE && range.startOffset !== range.startContainer.length)) { + splitStart = range.startContainer.splitText(range.startOffset); + modifiedNodes.push(range.startContainer); + modifiedNodes.push(splitStart); + range.setStart(splitStart, 0) + } } + return modifiedNodes } - return{container:container, offset:offset} - } - function splitBoundaries(range) { - var modifiedNodes = [], end, splitStart; - if(range.startContainer.nodeType === Node.TEXT_NODE || range.endContainer.nodeType === Node.TEXT_NODE) { - end = 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) + this.splitBoundaries = splitBoundaries; + function containsRange(container, insideRange) { + return container.compareBoundaryPoints(container.START_TO_START, insideRange) <= 0 && container.compareBoundaryPoints(container.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 + } + 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); + treeWalker.currentNode = range.startContainer; + n = range.startContainer; + while(n) { + filterResult = nodeFilter(n); + if(filterResult === NodeFilter.FILTER_ACCEPT) { + elements.push(n) + }else { + if(filterResult === NodeFilter.FILTER_REJECT) { + break + } + } + n = n.parentNode } - 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) + elements.reverse(); + n = treeWalker.nextNode(); + while(n) { + elements.push(n); + n = treeWalker.nextNode() } + return elements } - 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 - } - this.containsRange = containsRange; - function rangesIntersect(range1, range2) { - return range1.compareBoundaryPoints(range1.END_TO_START, range2) <= 0 && range1.compareBoundaryPoints(range1.START_TO_END, range2) >= 0 - } - this.rangesIntersect = rangesIntersect; - function getNodesInRange(range, nodeFilter) { - var document = range.startContainer.ownerDocument, elements = [], root = (range.commonAncestorContainer), n, treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ALL, nodeFilter, false); - treeWalker.currentNode = range.startContainer; - n = range.startContainer; - while(n) { - if(nodeFilter(n) === NodeFilter.FILTER_ACCEPT) { - elements.push(n) - }else { - if(nodeFilter(n) === NodeFilter.FILTER_REJECT) { - break + this.getNodesInRange = getNodesInRange; + function mergeTextNodes(node, nextNode) { + var mergedNode = null; + if(node.nodeType === Node.TEXT_NODE) { + if(node.length === 0) { + node.parentNode.removeChild(node); + if(nextNode.nodeType === Node.TEXT_NODE) { + mergedNode = nextNode + } + }else { + if(nextNode.nodeType === Node.TEXT_NODE) { + node.appendData(nextNode.data); + nextNode.parentNode.removeChild(nextNode) + } + mergedNode = node } } - n = n.parentNode + return mergedNode } - elements.reverse(); - n = treeWalker.nextNode(); - while(n) { - elements.push(n); - n = treeWalker.nextNode() + function normalizeTextNodes(node) { + if(node && node.nextSibling) { + node = mergeTextNodes(node, node.nextSibling) + } + if(node && node.previousSibling) { + mergeTextNodes(node.previousSibling, node) + } } - return elements - } - this.getNodesInRange = getNodesInRange; - function mergeTextNodes(node, nextNode) { - var mergedNode = null; - if(node.nodeType === Node.TEXT_NODE) { - if(node.length === 0) { - node.parentNode.removeChild(node); - if(nextNode.nodeType === Node.TEXT_NODE) { - mergedNode = nextNode - } - }else { - if(nextNode.nodeType === Node.TEXT_NODE) { - node.appendData(nextNode.data); - nextNode.parentNode.removeChild(nextNode) - } - mergedNode = node + this.normalizeTextNodes = normalizeTextNodes; + function rangeContainsNode(limits, node) { + var range = node.ownerDocument.createRange(), nodeLength = node.nodeType === Node.TEXT_NODE ? node.length : node.childNodes.length, result; + range.setStart(limits.startContainer, limits.startOffset); + range.setEnd(limits.endContainer, limits.endOffset); + result = range.comparePoint(node, 0) === 0 && range.comparePoint(node, nodeLength) === 0; + range.detach(); + return result + } + this.rangeContainsNode = rangeContainsNode; + function mergeIntoParent(targetNode) { + var parent = targetNode.parentNode; + while(targetNode.firstChild) { + parent.insertBefore(targetNode.firstChild, targetNode) } + parent.removeChild(targetNode); + return parent } - return mergedNode - } - function normalizeTextNodes(node) { - if(node && node.nextSibling) { - node = mergeTextNodes(node, node.nextSibling) + this.mergeIntoParent = mergeIntoParent; + function removeUnwantedNodes(targetNode, shouldRemove) { + var parent = targetNode.parentNode, node = targetNode.firstChild, next; + while(node) { + next = node.nextSibling; + removeUnwantedNodes(node, shouldRemove); + node = next + } + if(shouldRemove(targetNode)) { + parent = mergeIntoParent(targetNode) + } + return parent } - if(node && node.previousSibling) { - mergeTextNodes(node.previousSibling, node) + this.removeUnwantedNodes = removeUnwantedNodes; + function getElementsByTagNameNS(node, namespace, tagName) { + return Array.prototype.slice.call(node.getElementsByTagNameNS(namespace, tagName)) } - } - this.normalizeTextNodes = normalizeTextNodes; - function rangeContainsNode(limits, node) { - var range = node.ownerDocument.createRange(), nodeLength = node.nodeType === Node.TEXT_NODE ? node.length : node.childNodes.length, result; - range.setStart(limits.startContainer, limits.startOffset); - range.setEnd(limits.endContainer, limits.endOffset); - result = range.comparePoint(node, 0) === 0 && range.comparePoint(node, nodeLength) === 0; - range.detach(); - return result - } - this.rangeContainsNode = rangeContainsNode; - function mergeIntoParent(targetNode) { - var parent = targetNode.parentNode; - while(targetNode.firstChild) { - parent.insertBefore(targetNode.firstChild, targetNode) - } - parent.removeChild(targetNode); - return parent - } - this.mergeIntoParent = mergeIntoParent; - function getElementsByTagNameNS(node, namespace, tagName) { - return Array.prototype.slice.call(node.getElementsByTagNameNS(namespace, tagName)) - } - this.getElementsByTagNameNS = getElementsByTagNameNS; - 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 - } - this.rangeIntersectsNode = rangeIntersectsNode; - function containsNode(parent, descendant) { - return parent === descendant || parent.contains(descendant) - } - this.containsNode = containsNode; - function getPositionInContainingNode(node, container) { - var offset = 0, n; - while(node.parentNode !== container) { - runtime.assert(node.parentNode !== null, "parent is null"); - node = (node.parentNode) + 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 } - n = container.firstChild; - while(n !== node) { - offset += 1; - n = n.nextSibling + this.rangeIntersectsNode = rangeIntersectsNode; + function containsNode(parent, descendant) { + return parent === descendant || parent.contains(descendant) } - return offset - } - function comparePoints(c1, o1, c2, o2) { - if(c1 === c2) { - return o2 - o1 + this.containsNode = containsNode; + function getPositionInContainingNode(node, container) { + var offset = 0, n; + while(node.parentNode !== container) { + runtime.assert(node.parentNode !== null, "parent is null"); + node = (node.parentNode) + } + n = container.firstChild; + while(n !== node) { + offset += 1; + n = n.nextSibling + } + return offset } - var comparison = c1.compareDocumentPosition(c2); - if(comparison === 2) { - comparison = -1 - }else { - if(comparison === 4) { - comparison = 1 + function comparePoints(c1, o1, c2, o2) { + if(c1 === c2) { + return o2 - o1 + } + var comparison = c1.compareDocumentPosition(c2); + if(comparison === 2) { + comparison = -1 }else { - if(comparison === 10) { - o1 = getPositionInContainingNode(c1, c2); - comparison = o1 < o2 ? 1 : -1 + if(comparison === 4) { + comparison = 1 }else { - o2 = getPositionInContainingNode(c2, c1); - comparison = o2 < o1 ? -1 : 1 + if(comparison === 10) { + o1 = getPositionInContainingNode(c1, c2); + comparison = o1 < o2 ? 1 : -1 + }else { + o2 = getPositionInContainingNode(c2, c1); + comparison = o2 < o1 ? -1 : 1 + } } } + return comparison } - return comparison - } - this.comparePoints = comparePoints; - function containsNodeForBrokenWebKit(parent, descendant) { - return parent === descendant || Boolean(parent.compareDocumentPosition(descendant) & Node.DOCUMENT_POSITION_CONTAINED_BY) - } - function init(self) { - var window = runtime.getWindow(), appVersion, webKitOrSafari; - if(window === null) { - return + 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)) { + return inputNumber + } + return inputNumber / zoomLevel } - appVersion = window.navigator.appVersion.toLowerCase(); - webKitOrSafari = appVersion.indexOf("chrome") === -1 && (appVersion.indexOf("applewebkit") !== -1 || appVersion.indexOf("safari") !== -1); - if(webKitOrSafari) { - self.containsNode = containsNodeForBrokenWebKit + this.adaptRangeDifferenceToZoomLevel = adaptRangeDifferenceToZoomLevel; + function init(self) { + var window = runtime.getWindow(), appVersion, webKitOrSafari, ie; + if(window === null) { + return + } + appVersion = window.navigator.appVersion.toLowerCase(); + webKitOrSafari = appVersion.indexOf("chrome") === -1 && (appVersion.indexOf("applewebkit") !== -1 || appVersion.indexOf("safari") !== -1); + ie = appVersion.indexOf("msie"); + if(webKitOrSafari || ie) { + self.containsNode = containsNodeForBrokenWebKit + } } - } - init(this) -}; + init(this) + }; + return core.DomUtils +})(); 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; @@ -3312,6 +3392,9 @@ core.Cursor = function Cursor(document, memberId) { recentlyModifiedNodes.forEach(domUtils.normalizeTextNodes); recentlyModifiedNodes.length = 0 }; + this.hasForwardSelection = function() { + return forwardSelection + }; this.remove = function() { removeNode(cursorNode); recentlyModifiedNodes.forEach(domUtils.normalizeTextNodes); @@ -3335,6 +3418,9 @@ core.Cursor = function Cursor(document, memberId) { 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 @@ -3355,7 +3441,7 @@ core.Cursor = function Cursor(document, memberId) { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ core.EventNotifier = function EventNotifier(eventIds) { var eventListener = {}; @@ -3830,7 +3916,7 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa } filterResult = nodeFilter(container); node = container.parentNode; - while(node && node !== root && filterResult === NodeFilter.FILTER_ACCEPT) { + while(node && (node !== root && filterResult === NodeFilter.FILTER_ACCEPT)) { filterResult = nodeFilter(node); if(filterResult !== NodeFilter.FILTER_ACCEPT) { walker.currentNode = node @@ -3842,7 +3928,7 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa filterResult = nodeFilter(walker.currentNode); currentPos = 0 }else { - currentPos = offset === 0 ? 0 : 1 + currentPos = 1 } if(filterResult === NodeFilter.FILTER_REJECT) { currentPos = 1 @@ -3916,6 +4002,39 @@ core.PositionFilterChain = function PositionFilterChain() { delete filterChain[filterName] } }; +core.ScheduledTask = function ScheduledTask(fn, delay) { + var timeoutId, scheduled = false; + function execute() { + fn(); + scheduled = false + } + function cancel() { + if(scheduled) { + runtime.clearTimeout(timeoutId); + scheduled = false + } + } + this.trigger = function() { + if(!scheduled) { + timeoutId = runtime.setTimeout(execute, delay) + } + }; + this.triggerImmediate = function() { + cancel(); + execute() + }; + this.processRequests = function() { + if(scheduled) { + cancel(); + execute() + } + }; + this.cancel = cancel; + this.destroy = function(callback) { + cancel(); + callback() + } +}; core.Async = function Async() { this.forEach = function(items, f, callback) { var i, l = items.length, itemsDone = 0; @@ -3935,6 +4054,22 @@ core.Async = function Async() { for(i = 0;i < l;i += 1) { f(items[i], end) } + }; + this.destroyAll = function(items, callback) { + function destroy(itemIndex, err) { + if(err) { + callback(err) + }else { + if(itemIndex < items.length) { + items[itemIndex](function(err) { + destroy(itemIndex + 1, err) + }) + }else { + callback() + } + } + } + destroy(0, undefined) } }; /* @@ -4146,13 +4281,13 @@ core.Zip = function Zip(url, entriesReadCallback) { } var p = data, chunksize = 45E3, i = 0, dataurl; if(!mimetype) { - if(p[1] === 80 && p[2] === 78 && p[3] === 71) { + if(p[1] === 80 && (p[2] === 78 && p[3] === 71)) { mimetype = "image/png" }else { - if(p[0] === 255 && p[1] === 216 && p[2] === 255) { + if(p[0] === 255 && (p[1] === 216 && p[2] === 255)) { mimetype = "image/jpeg" }else { - if(p[0] === 71 && p[1] === 73 && p[2] === 70) { + if(p[0] === 71 && (p[1] === 73 && p[2] === 70)) { mimetype = "image/gif" }else { mimetype = "" @@ -4191,6 +4326,17 @@ core.Zip = function Zip(url, entriesReadCallback) { entry.set(filename, data, compressed, date); entries.push(entry) } + function remove(filename) { + var i, entry; + for(i = 0;i < entries.length;i += 1) { + entry = entries[i]; + if(entry.filename === filename) { + entries.splice(i, 1); + return true + } + } + return false + } function writeEntry(entry) { var data = new core.ByteArrayWriter("utf8"), length = 0; data.appendArray([80, 75, 3, 4, 20, 0, 0, 0, 0, 0]); @@ -4279,6 +4425,7 @@ core.Zip = function Zip(url, entriesReadCallback) { } this.load = load; this.save = save; + this.remove = remove; this.write = write; this.writeAs = writeAs; this.createByteArray = createByteArray; @@ -4300,7 +4447,7 @@ core.Zip = function Zip(url, entriesReadCallback) { entriesReadCallback("File '" + url + "' cannot be read.", zip) }else { runtime.read(url, filesize - 22, 22, function(err, data) { - if(err || entriesReadCallback === null || data === null) { + if(err || (entriesReadCallback === null || data === null)) { entriesReadCallback(err, zip) }else { handleCentralDirectoryEnd(data, entriesReadCallback) @@ -4526,7 +4673,7 @@ xmldom.RelaxNGParser = function RelaxNGParser() { if(att.localName === "name" && (name === "element" || name === "attribute")) { names.push(att.value) } - if(att.localName === "name" || att.localName === "combine" || att.localName === "type") { + if(att.localName === "name" || (att.localName === "combine" || att.localName === "type")) { att.value = trim(att.value) } a[att.localName] = att.value @@ -4548,7 +4695,7 @@ xmldom.RelaxNGParser = function RelaxNGParser() { names.push(nsmap[ce.a.ns] + ":" + ce.text); e.push(ce) }else { - if(ce.name === "choice" && ce.names && ce.names.length) { + if(ce.name === "choice" && (ce.names && ce.names.length)) { names = names.concat(ce.names); delete ce.names; e.push(ce) @@ -4570,7 +4717,7 @@ xmldom.RelaxNGParser = function RelaxNGParser() { var i, ce; for(i = 0;siblings && i < siblings.length;i += 1) { ce = siblings[i]; - if(ce.name === "define" && ce.a && ce.a.name === name) { + if(ce.name === "define" && (ce.a && ce.a.name === name)) { ce.e = [{name:combine, e:ce.e.concat(e)}]; return ce } @@ -4594,7 +4741,7 @@ xmldom.RelaxNGParser = function RelaxNGParser() { e = [{name:"name", text:i[1], a:{ns:i[0]}}].concat(e); delete a.name } - if(name === "name" || name === "nsName" || name === "value") { + if(name === "name" || (name === "nsName" || name === "value")) { if(a.ns === undefined) { a.ns = "" } @@ -4606,7 +4753,7 @@ xmldom.RelaxNGParser = function RelaxNGParser() { a.ns = i[0]; text = i[1] } - if(e.length > 1 && (name === "define" || name === "oneOrMore" || name === "zeroOrMore" || name === "optional" || name === "list" || name === "mixed")) { + if(e.length > 1 && (name === "define" || (name === "oneOrMore" || (name === "zeroOrMore" || (name === "optional" || (name === "list" || name === "mixed")))))) { e = [{name:"group", e:splitToDuos({name:"group", e:e}).e}] } if(e.length > 2 && name === "element") { @@ -4615,14 +4762,14 @@ xmldom.RelaxNGParser = function RelaxNGParser() { if(e.length === 1 && name === "attribute") { e.push({name:"text", text:text}) } - if(e.length === 1 && (name === "choice" || name === "group" || name === "interleave")) { + if(e.length === 1 && (name === "choice" || (name === "group" || name === "interleave"))) { name = e[0].name; names = e[0].names; a = e[0].a; text = e[0].text; e = e[0].e }else { - if(e.length > 2 && (name === "choice" || name === "group" || name === "interleave")) { + if(e.length > 2 && (name === "choice" || (name === "group" || name === "interleave"))) { e = splitToDuos({name:name, e:e}).e } } @@ -4687,8 +4834,8 @@ xmldom.RelaxNGParser = function RelaxNGParser() { } e = def.e; if(name === "choice") { - if(!e || !e[1] || e[1].name === "empty") { - if(!e || !e[0] || e[0].name === "empty") { + if(!e || (!e[1] || e[1].name === "empty")) { + if(!e || (!e[0] || e[0].name === "empty")) { delete def.e; def.name = "empty" }else { @@ -5363,7 +5510,7 @@ xmldom.RelaxNG2 = function RelaxNG2() { return nsmap[node.namespaceURI] + ":" + node.localName } function isWhitespace(node) { - return node && node.nodeType === Node.TEXT_NODE && /^\s+$/.test(node.nodeValue) + return node && (node.nodeType === Node.TEXT_NODE && /^\s+$/.test(node.nodeValue)) } function validatePattern(elementdef, walker, element, data) { if(elementdef.name === "empty") { @@ -5464,7 +5611,7 @@ xmldom.RelaxNG2 = function RelaxNG2() { n[i] = false } }else { - if(subnode === walker.currentNode || e.name === "oneOrMore" || e.name === "choice" && (e.e[0].name === "oneOrMore" || e.e[1].name === "oneOrMore")) { + if(subnode === walker.currentNode || (e.name === "oneOrMore" || e.name === "choice" && (e.e[0].name === "oneOrMore" || e.e[1].name === "oneOrMore"))) { donethisround += 1; n[i] = subnode }else { @@ -5574,7 +5721,7 @@ xmldom.XPathIterator = function XPathIterator() { xmldom.XPath = function() { var createXPathPathIterator, parsePredicates; function isSmallestPositive(a, b, c) { - return a !== -1 && (a < b || b === -1) && (a < c || c === -1) + return a !== -1 && ((a < b || b === -1) && (a < c || c === -1)) } function parseXPathStep(xpath, pos, end, steps) { var location = "", predicates = [], brapos = xpath.indexOf("[", pos), slapos = xpath.indexOf("/", pos), eqpos = xpath.indexOf("=", pos); @@ -5815,6 +5962,9 @@ xmldom.XPath = function() { 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 @@ -5835,7 +5985,7 @@ xmldom.XPath = function() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ gui.AnnotationViewManager = function AnnotationViewManager(odfCanvas, odfFragment, annotationsPane) { var annotations = [], doc = odfFragment.ownerDocument, odfUtils = new odf.OdfUtils, CONNECTOR_MARGIN = 30, NOTE_MARGIN = 20, window = runtime.getWindow(); @@ -5918,7 +6068,9 @@ gui.AnnotationViewManager = function AnnotationViewManager(odfCanvas, odfFragmen if(creatorNode) { creatorName = window.getComputedStyle((creatorNode), ":before").content; if(creatorName && creatorName !== "none") { - creatorName = creatorName.substring(1, creatorName.length - 1); + if(/^["'].*["']$/.test(creatorName)) { + creatorName = creatorName.substring(1, creatorName.length - 1) + } if(creatorNode.firstChild) { creatorNode.firstChild.nodeValue = creatorName }else { @@ -5994,6 +6146,9 @@ gui.AnnotationViewManager = function AnnotationViewManager(odfCanvas, odfFragmen 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 @@ -6014,7 +6169,7 @@ gui.AnnotationViewManager = function AnnotationViewManager(odfCanvas, odfFragmen This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ odf.OdfNodeFilter = function OdfNodeFilter() { this.acceptNode = function(node) { @@ -6043,6 +6198,9 @@ odf.OdfNodeFilter = function OdfNodeFilter() { 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 @@ -6063,12 +6221,12 @@ odf.OdfNodeFilter = function OdfNodeFilter() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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", webodfns = "urn:webodf", 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, "webodf":webodfns}, namespaces; + 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; function forEachPrefix(cb) { var prefix; for(prefix in namespaceMap) { @@ -6102,7 +6260,6 @@ odf.Namespaces = function() { namespaces.textns = textns; namespaces.xlinkns = xlinkns; namespaces.xmlns = xmlns; - namespaces.webodfns = webodfns; return namespaces }(); /* @@ -6117,6 +6274,9 @@ odf.Namespaces = function() { 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 @@ -6137,7 +6297,7 @@ odf.Namespaces = function() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("xmldom.XPath"); runtime.loadClass("odf.Namespaces"); @@ -6373,6 +6533,46 @@ odf.StyleInfo = function StyleInfo() { } }) } + function collectUsedFontFaces(usedFontFaceDeclMap, styleElementsRoot) { + var localNames = ["font-name", "font-name-asian", "font-name-complex"], currentNode; + function collectByAttribute(localName) { + var fontFaceName = currentNode.getAttributeNS(stylens, localName); + if(fontFaceName) { + usedFontFaceDeclMap[fontFaceName] = true + } + } + if(styleElementsRoot) { + currentNode = styleElementsRoot.firstChild; + while(currentNode) { + if(currentNode.nodeType === Node.ELEMENT_NODE) { + localNames.forEach(collectByAttribute); + collectUsedFontFaces(usedFontFaceDeclMap, (currentNode)) + } + currentNode = currentNode.nextSibling + } + } + } + this.collectUsedFontFaces = collectUsedFontFaces; + function changeFontFaceNames(styleElementsRoot, fontFaceNameChangeMap) { + var localNames = ["font-name", "font-name-asian", "font-name-complex"], currentNode; + function changeFontFaceNameByAttribute(localName) { + var fontFaceName = currentNode.getAttributeNS(stylens, localName); + if(fontFaceName && fontFaceNameChangeMap.hasOwnProperty(fontFaceName)) { + currentNode.setAttributeNS(stylens, "style:" + localName, fontFaceNameChangeMap[fontFaceName]) + } + } + if(styleElementsRoot) { + currentNode = styleElementsRoot.firstChild; + while(currentNode) { + if(currentNode.nodeType === Node.ELEMENT_NODE) { + localNames.forEach(changeFontFaceNameByAttribute); + changeFontFaceNames((currentNode), fontFaceNameChangeMap) + } + currentNode = currentNode.nextSibling + } + } + } + this.changeFontFaceNames = changeFontFaceNames; this.UsedStyleList = function(styleUsingElementsRoot, automaticStylesRoot) { var usedStyles = {}; this.uses = function(element) { @@ -6412,6 +6612,9 @@ odf.StyleInfo = function StyleInfo() { 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 @@ -6432,12 +6635,26 @@ odf.StyleInfo = function StyleInfo() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils"); runtime.loadClass("odf.Namespaces"); odf.OdfUtils = function OdfUtils() { var textns = odf.Namespaces.textns, drawns = odf.Namespaces.drawns, whitespaceOnly = /^\s*$/, domUtils = new core.DomUtils; + function isImage(e) { + var name = e && e.localName; + return name === "image" && e.namespaceURI === drawns + } + this.isImage = isImage; + function isCharacterFrame(e) { + var name = e && e.localName; + return name === "frame" && (e.namespaceURI === drawns && e.getAttributeNS(textns, "anchor-type") === "as-char") + } + this.isCharacterFrame = isCharacterFrame; + this.isTextSpan = function(e) { + var name = e && e.localName; + return name === "span" && e.namespaceURI === textns + }; function isParagraph(e) { var name = e && e.localName; return(name === "p" || name === "h") && e.namespaceURI === textns @@ -6463,6 +6680,10 @@ odf.OdfUtils = function OdfUtils() { var name = e && e.localName; return name === "list-item" && e.namespaceURI === textns }; + this.isLineBreak = function(e) { + var name = e && e.localName; + return name === "line-break" && e.namespaceURI === textns + }; function isODFWhitespace(text) { return/^[ \t\r\n]+$/.test(text) } @@ -6480,16 +6701,25 @@ odf.OdfUtils = function OdfUtils() { if(n) { ns = e.namespaceURI; if(ns === textns) { - r = n === "s" || n === "tab" || n === "line-break" + r = n === "s" || (n === "tab" || n === "line-break") }else { - if(ns === drawns) { - r = n === "frame" && e.getAttributeNS(textns, "anchor-type") === "as-char" - } + r = isCharacterFrame(e) } } return r } this.isCharacterElement = isCharacterElement; + function isWhitespaceElement(e) { + var n = e && e.localName, ns, r = false; + if(n) { + ns = e.namespaceURI; + if(ns === textns) { + r = n === "s" || n === "tab" + } + } + return r + } + this.isWhitespaceElement = isWhitespaceElement; function firstChild(node) { while(node.firstChild !== null && isGroupingElement(node)) { node = node.firstChild @@ -6529,7 +6759,7 @@ odf.OdfUtils = function OdfUtils() { } }else { if(isCharacterElement(node)) { - r = true; + r = isWhitespaceElement(node) === false; node = null }else { node = previousNode(node) @@ -6562,7 +6792,7 @@ odf.OdfUtils = function OdfUtils() { this.lookLeftForCharacter = lookLeftForCharacter; function lookRightForCharacter(node) { var r = false; - if(node && node.nodeType === Node.TEXT_NODE && node.length > 0) { + if(node && (node.nodeType === Node.TEXT_NODE && node.length > 0)) { r = !isODFWhitespace(node.data.substr(0, 1)) }else { if(isCharacterElement(node)) { @@ -6576,7 +6806,7 @@ odf.OdfUtils = function OdfUtils() { var r = false; node = node && lastChild(node); while(node) { - if(node.nodeType === Node.TEXT_NODE && node.length > 0 && !isODFWhitespace(node.data)) { + if(node.nodeType === Node.TEXT_NODE && (node.length > 0 && !isODFWhitespace(node.data))) { r = true; break } @@ -6593,7 +6823,7 @@ odf.OdfUtils = function OdfUtils() { var r = false; node = node && firstChild(node); while(node) { - if(node.nodeType === Node.TEXT_NODE && node.length > 0 && !isODFWhitespace(node.data)) { + if(node.nodeType === Node.TEXT_NODE && (node.length > 0 && !isODFWhitespace(node.data))) { r = true; break } @@ -6644,7 +6874,7 @@ odf.OdfUtils = function OdfUtils() { }; function getFirstNonWhitespaceChild(node) { var child = node && node.firstChild; - while(child && child.nodeType === Node.TEXT_NODE && whitespaceOnly.test(child.nodeValue)) { + while(child && (child.nodeType === Node.TEXT_NODE && whitespaceOnly.test(child.nodeValue))) { child = child.nextSibling } return child @@ -6742,12 +6972,15 @@ odf.OdfUtils = function OdfUtils() { function isSignificantTextContent(textNode) { return Boolean(getParagraphElement(textNode) && (!isODFWhitespace(textNode.textContent) || isSignificantWhitespace(textNode, 0))) } + function includeNode(range, nodeRange, includePartial) { + return includePartial && domUtils.rangesIntersect(range, nodeRange) || domUtils.containsRange(range, nodeRange) + } function getTextNodes(range, includePartial) { var document = range.startContainer.ownerDocument, nodeRange = document.createRange(), textNodes; function nodeFilter(node) { nodeRange.selectNodeContents(node); if(node.nodeType === Node.TEXT_NODE) { - if(includePartial && domUtils.rangesIntersect(range, nodeRange) || domUtils.containsRange(range, nodeRange)) { + if(includeNode(range, nodeRange, includePartial)) { return isSignificantTextContent(node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT } }else { @@ -6764,18 +6997,22 @@ odf.OdfUtils = function OdfUtils() { return textNodes } this.getTextNodes = getTextNodes; - this.getTextElements = function(range, includeInsignificantWhitespace) { + this.getTextElements = function(range, includePartial, includeInsignificantWhitespace) { var document = range.startContainer.ownerDocument, nodeRange = document.createRange(), elements; function nodeFilter(node) { - var nodeType = node.nodeType; nodeRange.selectNodeContents(node); - if(nodeType === Node.TEXT_NODE) { - if(domUtils.containsRange(range, nodeRange) && (includeInsignificantWhitespace || isSignificantTextContent(node))) { - return NodeFilter.FILTER_ACCEPT + if(isCharacterElement(node.parentNode)) { + return NodeFilter.FILTER_REJECT + } + if(node.nodeType === Node.TEXT_NODE) { + if(includeNode(range, nodeRange, includePartial)) { + if(includeInsignificantWhitespace || isSignificantTextContent(node)) { + return NodeFilter.FILTER_ACCEPT + } } }else { if(isCharacterElement(node)) { - if(domUtils.containsRange(range, nodeRange)) { + if(includeNode(range, nodeRange, includePartial)) { return NodeFilter.FILTER_ACCEPT } }else { @@ -6808,6 +7045,19 @@ odf.OdfUtils = function OdfUtils() { elements = domUtils.getNodesInRange(range, nodeFilter); nodeRange.detach(); return elements + }; + this.getImageElements = function(range) { + var document = range.startContainer.ownerDocument, nodeRange = document.createRange(), elements; + function nodeFilter(node) { + nodeRange.selectNodeContents(node); + if(isImage(node) && domUtils.containsRange(range, nodeRange)) { + return NodeFilter.FILTER_ACCEPT + } + return NodeFilter.FILTER_SKIP + } + elements = domUtils.getNodesInRange(range, nodeFilter); + nodeRange.detach(); + return elements } }; /* @@ -6822,6 +7072,9 @@ odf.OdfUtils = function OdfUtils() { 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 @@ -6842,7 +7095,7 @@ odf.OdfUtils = function OdfUtils() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.OdfUtils"); odf.TextSerializer = function TextSerializer() { @@ -6887,6 +7140,9 @@ odf.TextSerializer = function TextSerializer() { 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 @@ -6907,12 +7163,12 @@ odf.TextSerializer = function TextSerializer() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils"); runtime.loadClass("core.LoopWatchDog"); runtime.loadClass("odf.Namespaces"); -odf.TextStyleApplicator = function TextStyleApplicator(styleNameGenerator, formatting, automaticStyles) { +odf.TextStyleApplicator = function TextStyleApplicator(objectNameGenerator, formatting, automaticStyles) { var domUtils = new core.DomUtils, textns = odf.Namespaces.textns, stylens = odf.Namespaces.stylens, textProperties = "style:text-properties", webodfns = "urn:webodf:names:scope"; function StyleLookup(info) { function compare(expected, actual) { @@ -6935,7 +7191,7 @@ odf.TextStyleApplicator = function TextStyleApplicator(styleNameGenerator, forma derivedStyleInfo = existingStyleName ? formatting.createDerivedStyleObject(existingStyleName, "text", info) : info; derivedStyleNode = document.createElementNS(stylens, "style:style"); formatting.updateStyle(derivedStyleNode, derivedStyleInfo); - derivedStyleNode.setAttributeNS(stylens, "style:name", styleNameGenerator.generateName()); + derivedStyleNode.setAttributeNS(stylens, "style:name", objectNameGenerator.generateStyleName()); derivedStyleNode.setAttributeNS(stylens, "style:family", "text"); derivedStyleNode.setAttributeNS(webodfns, "scope", "document-content"); automaticStyles.appendChild(derivedStyleNode); @@ -7023,6 +7279,9 @@ odf.TextStyleApplicator = function TextStyleApplicator(styleNameGenerator, forma 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 @@ -7043,7 +7302,7 @@ odf.TextStyleApplicator = function TextStyleApplicator(styleNameGenerator, forma This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.Namespaces"); runtime.loadClass("odf.OdfUtils"); @@ -7204,7 +7463,7 @@ odf.Style2CSS = function Style2CSS() { theRestOfBorderAttributes = "" } width = utils.parseLength(width); - if(width && width.unit === "pt" && width.value < 0.75) { + if(width && (width.unit === "pt" && width.value < 0.75)) { value = "0.75pt" + theRestOfBorderAttributes } return value @@ -7633,6 +7892,9 @@ odf.Style2CSS = function Style2CSS() { 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 @@ -7653,7 +7915,7 @@ odf.Style2CSS = function Style2CSS() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.Base64"); runtime.loadClass("core.Zip"); @@ -7662,7 +7924,8 @@ runtime.loadClass("odf.StyleInfo"); runtime.loadClass("odf.Namespaces"); runtime.loadClass("odf.OdfNodeFilter"); 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", 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"; + 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 = + "document-content"; function getDirectChild(node, ns, name) { node = node ? node.firstChild : null; while(node) { @@ -7686,7 +7949,7 @@ odf.OdfContainer = function() { var usedStyleList = new styleInfo.UsedStyleList(styleUsingElementsRoot, automaticStyles), odfNodeFilter = new odf.OdfNodeFilter; this.acceptNode = function(node) { var result = odfNodeFilter.acceptNode(node); - if(result === NodeFilter.FILTER_ACCEPT && node.parentNode === automaticStyles && node.nodeType === Node.ELEMENT_NODE) { + if(result === NodeFilter.FILTER_ACCEPT && (node.parentNode === automaticStyles && node.nodeType === Node.ELEMENT_NODE)) { if(usedStyleList.uses((node))) { result = NodeFilter.FILTER_ACCEPT }else { @@ -7700,7 +7963,7 @@ odf.OdfContainer = function() { var odfStylesFilter = new OdfStylesFilter(styleUsingElementsRoot, automaticStyles); this.acceptNode = function(node) { var result = odfStylesFilter.acceptNode(node); - if(result === NodeFilter.FILTER_ACCEPT && node.parentNode && node.parentNode.namespaceURI === odf.Namespaces.textns && (node.parentNode.localName === "s" || node.parentNode.localName === "tab")) { + if(result === NodeFilter.FILTER_ACCEPT && (node.parentNode && (node.parentNode.namespaceURI === odf.Namespaces.textns && (node.parentNode.localName === "s" || node.parentNode.localName === "tab")))) { result = NodeFilter.FILTER_REJECT } return result @@ -7804,6 +8067,56 @@ odf.OdfContainer = function() { n = n.nextSibling } } + function mergeFontFaceDecls(targetFontFaceDeclsRootElement, sourceFontFaceDeclsRootElement) { + var n, s, fontFaceName, newFontFaceName, targetFontFaceDeclsMap, sourceFontFaceDeclsMap, fontFaceNameChangeMap = {}; + function unusedKey(key, map1, map2) { + var i = 0, postFixedKey; + key = key.replace(/\d+$/, ""); + postFixedKey = key; + while(map1.hasOwnProperty(postFixedKey) || map2.hasOwnProperty(postFixedKey)) { + i += 1; + postFixedKey = key + i + } + return postFixedKey + } + function mapByFontFaceName(fontFaceDecls) { + var fn, result = {}; + fn = fontFaceDecls.firstChild; + while(fn) { + if(fn.nodeType === Node.ELEMENT_NODE && (fn.namespaceURI === stylens && fn.localName === "font-face")) { + fontFaceName = fn.getAttributeNS(stylens, "name"); + result[fontFaceName] = fn + } + fn = fn.nextSibling + } + return result + } + targetFontFaceDeclsMap = mapByFontFaceName(targetFontFaceDeclsRootElement); + sourceFontFaceDeclsMap = mapByFontFaceName(sourceFontFaceDeclsRootElement); + n = sourceFontFaceDeclsRootElement.firstChild; + while(n) { + s = n.nextSibling; + if(n.nodeType === Node.ELEMENT_NODE && (n.namespaceURI === stylens && n.localName === "font-face")) { + fontFaceName = n.getAttributeNS(stylens, "name"); + if(targetFontFaceDeclsMap.hasOwnProperty(fontFaceName)) { + if(!n.isEqualNode(targetFontFaceDeclsMap[fontFaceName])) { + newFontFaceName = unusedKey(fontFaceName, targetFontFaceDeclsMap, sourceFontFaceDeclsMap); + n.setAttributeNS(stylens, "style:name", newFontFaceName); + targetFontFaceDeclsRootElement.appendChild(n); + targetFontFaceDeclsMap[newFontFaceName] = (n); + delete sourceFontFaceDeclsMap[fontFaceName]; + fontFaceNameChangeMap[fontFaceName] = newFontFaceName + } + }else { + targetFontFaceDeclsRootElement.appendChild(n); + targetFontFaceDeclsMap[fontFaceName] = (n); + delete sourceFontFaceDeclsMap[fontFaceName] + } + } + n = s + } + return fontFaceNameChangeMap + } function cloneStylesInScope(stylesRootElement, scope) { var copy = null, n, s, scopeAttrValue; if(stylesRootElement) { @@ -7822,6 +8135,27 @@ odf.OdfContainer = function() { } return copy } + function cloneFontFaceDeclsUsedInStyles(fontFaceDeclsRootElement, stylesRootElementList) { + var copy = null, n, nextSibling, fontFaceName, usedFontFaceDeclMap = {}; + if(fontFaceDeclsRootElement) { + stylesRootElementList.forEach(function(stylesRootElement) { + styleInfo.collectUsedFontFaces(usedFontFaceDeclMap, stylesRootElement) + }); + copy = fontFaceDeclsRootElement.cloneNode(true); + n = copy.firstChild; + while(n) { + nextSibling = n.nextSibling; + if(n.nodeType === Node.ELEMENT_NODE) { + fontFaceName = n.getAttributeNS(stylens, "name"); + if(!usedFontFaceDeclMap[fontFaceName]) { + copy.removeChild(n) + } + } + n = nextSibling + } + } + return copy + } function importRootNode(xmldoc) { var doc = self.rootElement.ownerDocument, node; if(xmldoc) { @@ -7854,7 +8188,7 @@ odf.OdfContainer = function() { } function handleFlatXml(xmldoc) { var root = importRootNode(xmldoc); - if(!root || root.localName !== "document" || root.namespaceURI !== officens) { + if(!root || (root.localName !== "document" || root.namespaceURI !== officens)) { setState(OdfContainer.INVALID); return } @@ -7863,7 +8197,7 @@ odf.OdfContainer = function() { } function handleStylesXml(xmldoc) { var node = importRootNode(xmldoc), root = self.rootElement; - if(!node || node.localName !== "document-styles" || node.namespaceURI !== officens) { + if(!node || (node.localName !== "document-styles" || node.namespaceURI !== officens)) { setState(OdfContainer.INVALID); return } @@ -7879,19 +8213,15 @@ odf.OdfContainer = function() { styleInfo.prefixStyleNames(root.automaticStyles, automaticStylePrefix, root.masterStyles) } function handleContentXml(xmldoc) { - var node = importRootNode(xmldoc), root, automaticStyles, fontFaceDecls, c; - if(!node || node.localName !== "document-content" || node.namespaceURI !== officens) { + var node = importRootNode(xmldoc), root, automaticStyles, fontFaceDecls, fontFaceNameChangeMap, c; + if(!node || (node.localName !== "document-content" || node.namespaceURI !== officens)) { setState(OdfContainer.INVALID); return } root = self.rootElement; fontFaceDecls = getDirectChild(node, officens, "font-face-decls"); if(root.fontFaceDecls && fontFaceDecls) { - c = fontFaceDecls.firstChild; - while(c) { - root.fontFaceDecls.appendChild(c); - c = fontFaceDecls.firstChild - } + fontFaceNameChangeMap = mergeFontFaceDecls(root.fontFaceDecls, fontFaceDecls) }else { if(fontFaceDecls) { root.fontFaceDecls = fontFaceDecls; @@ -7900,6 +8230,9 @@ odf.OdfContainer = function() { } automaticStyles = getDirectChild(node, officens, "automatic-styles"); setAutomaticStylesScope(automaticStyles, documentContentScope); + if(fontFaceNameChangeMap) { + styleInfo.changeFontFaceNames(automaticStyles, fontFaceNameChangeMap) + } if(root.automaticStyles && automaticStyles) { c = automaticStyles.firstChild; while(c) { @@ -7917,7 +8250,7 @@ odf.OdfContainer = function() { } function handleMetaXml(xmldoc) { var node = importRootNode(xmldoc), root; - if(!node || node.localName !== "document-meta" || node.namespaceURI !== officens) { + if(!node || (node.localName !== "document-meta" || node.namespaceURI !== officens)) { return } root = self.rootElement; @@ -7926,7 +8259,7 @@ odf.OdfContainer = function() { } function handleSettingsXml(xmldoc) { var node = importRootNode(xmldoc), root; - if(!node || node.localName !== "document-settings" || node.namespaceURI !== officens) { + if(!node || (node.localName !== "document-settings" || node.namespaceURI !== officens)) { return } root = self.rootElement; @@ -7935,14 +8268,14 @@ odf.OdfContainer = function() { } function handleManifestXml(xmldoc) { var node = importRootNode(xmldoc), root, n; - if(!node || node.localName !== "manifest" || node.namespaceURI !== manifestns) { + if(!node || (node.localName !== "manifest" || node.namespaceURI !== manifestns)) { return } root = self.rootElement; root.manifest = node; n = root.manifest.firstChild; while(n) { - if(n.nodeType === Node.ELEMENT_NODE && n.localName === "file-entry" && n.namespaceURI === manifestns) { + if(n.nodeType === Node.ELEMENT_NODE && (n.localName === "file-entry" && n.namespaceURI === manifestns)) { partMimetypes[n.getAttributeNS(manifestns, "full-path")] = n.getAttributeNS(manifestns, "media-type") } n = n.nextSibling @@ -7989,7 +8322,7 @@ odf.OdfContainer = function() { return element } function serializeManifestXml() { - var header = '\n', xml = '', manifest = (runtime.parseXML(xml)), manifestRoot = getDirectChild(manifest, manifestns, "manifest"), serializer = new xmldom.LSSerializer, fullPath; + var header = '\n', xml = '', manifest = (runtime.parseXML(xml)), manifestRoot = getDirectChild(manifest, manifestns, "manifest"), serializer = new xmldom.LSSerializer, fullPath; for(fullPath in partMimetypes) { if(partMimetypes.hasOwnProperty(fullPath)) { manifestRoot.appendChild(createManifestEntry(fullPath, partMimetypes[fullPath])) @@ -8006,10 +8339,13 @@ odf.OdfContainer = function() { return s } function serializeStylesXml() { - var nsmap = odf.Namespaces.namespaceMap, serializer = new xmldom.LSSerializer, automaticStyles = cloneStylesInScope(self.rootElement.automaticStyles, documentStylesScope), masterStyles = self.rootElement.masterStyles && self.rootElement.masterStyles.cloneNode(true), s = createDocumentElement("document-styles"); + var nsmap = odf.Namespaces.namespaceMap, serializer = new xmldom.LSSerializer, fontFaceDecls, automaticStyles, masterStyles, s = createDocumentElement("document-styles"); + automaticStyles = cloneStylesInScope(self.rootElement.automaticStyles, documentStylesScope); + masterStyles = self.rootElement.masterStyles && self.rootElement.masterStyles.cloneNode(true); + fontFaceDecls = cloneFontFaceDeclsUsedInStyles(self.rootElement.fontFaceDecls, [masterStyles, self.rootElement.styles, automaticStyles]); styleInfo.removePrefixFromStyleNames(automaticStyles, automaticStylePrefix, masterStyles); serializer.filter = new OdfStylesFilter(masterStyles, automaticStyles); - s += serializer.writeToString(self.rootElement.fontFaceDecls, nsmap); + s += serializer.writeToString(fontFaceDecls, nsmap); s += serializer.writeToString(self.rootElement.styles, nsmap); s += serializer.writeToString(automaticStyles, nsmap); s += serializer.writeToString(masterStyles, nsmap); @@ -8017,8 +8353,11 @@ odf.OdfContainer = function() { return s } function serializeContentXml() { - var nsmap = odf.Namespaces.namespaceMap, serializer = new xmldom.LSSerializer, automaticStyles = cloneStylesInScope(self.rootElement.automaticStyles, documentContentScope), s = createDocumentElement("document-content"); + var nsmap = odf.Namespaces.namespaceMap, serializer = new xmldom.LSSerializer, fontFaceDecls, automaticStyles, s = createDocumentElement("document-content"); + automaticStyles = cloneStylesInScope(self.rootElement.automaticStyles, documentContentScope); + fontFaceDecls = cloneFontFaceDeclsUsedInStyles(self.rootElement.fontFaceDecls, [automaticStyles]); serializer.filter = new OdfContentFilter(self.rootElement.body, automaticStyles); + s += serializer.writeToString(fontFaceDecls, nsmap); s += serializer.writeToString(automaticStyles, nsmap); s += serializer.writeToString(self.rootElement.body, nsmap); s += ""; @@ -8047,7 +8386,7 @@ odf.OdfContainer = function() { var body; if(!contentElement) { body = self.rootElement.body; - contentElement = body.getElementsByTagNameNS(officens, "text")[0] || body.getElementsByTagNameNS(officens, "presentation")[0] || body.getElementsByTagNameNS(officens, "spreadsheet")[0] + contentElement = body.getElementsByTagNameNS(officens, "text")[0] || (body.getElementsByTagNameNS(officens, "presentation")[0] || body.getElementsByTagNameNS(officens, "spreadsheet")[0]) } return contentElement }; @@ -8116,6 +8455,19 @@ odf.OdfContainer = function() { this.getUrl = function() { return url }; + this.setBlob = function(filename, mimetype, content) { + var data = base64.convertBase64ToByteArray(content), date = new Date; + zip.save(filename, data, false, date); + if(partMimetypes.hasOwnProperty(filename)) { + runtime.log(filename + " has been overwritten.") + } + partMimetypes[filename] = mimetype + }; + this.removeBlob = function(filename) { + var foundAndRemoved = zip.remove(filename); + runtime.assert(foundAndRemoved, "file is not found: " + filename); + delete partMimetypes[filename] + }; this.state = OdfContainer.LOADING; this.rootElement = createElement(ODFDocumentElement); if(url) { @@ -8159,6 +8511,9 @@ odf.OdfContainer = function() { 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 @@ -8179,7 +8534,7 @@ odf.OdfContainer = function() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.Base64"); runtime.loadClass("xmldom.XPath"); @@ -8267,6 +8622,9 @@ odf.FontLoader = function() { 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 @@ -8287,21 +8645,70 @@ odf.FontLoader = function() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -odf.StyleNameGenerator = function StyleNameGenerator(prefix, formatting) { - var reportedNames = {}; - this.generateName = function() { - var name, existingNames = {}, startIndex = 0; - formatting.getAllStyleNames().forEach(function(styleName) { - existingNames[styleName] = true +runtime.loadClass("core.DomUtils"); +runtime.loadClass("core.Utils"); +odf.ObjectNameGenerator = function ObjectNameGenerator(odfContainer, memberId) { + var stylens = odf.Namespaces.stylens, drawns = odf.Namespaces.drawns, xlinkns = odf.Namespaces.xlinkns, domUtils = new core.DomUtils, utils = new core.Utils, memberIdHash = utils.hashString(memberId), styleNameGenerator = null, frameNameGenerator = null, imageNameGenerator = null, existingFrameNames = {}, existingImageNames = {}; + function NameGenerator(prefix, findExistingNames) { + var reportedNames = {}; + this.generateName = function() { + var existingNames = findExistingNames(), startIndex = 0, name; + do { + name = prefix + startIndex; + startIndex += 1 + }while(reportedNames[name] || existingNames[name]); + reportedNames[name] = true; + return name + } + } + function getAllStyleNames() { + var styleElements = [odfContainer.rootElement.automaticStyles, odfContainer.rootElement.styles], node, styleNames = {}; + styleElements.forEach(function(styleListElement) { + node = styleListElement.firstChild; + while(node) { + if(node.nodeType === Node.ELEMENT_NODE && (node.namespaceURI === stylens && node.localName === "style")) { + styleNames[node.getAttributeNS(stylens, "name")] = true + } + node = node.nextSibling + } }); - do { - name = prefix + startIndex; - startIndex += 1 - }while(reportedNames[name] || existingNames[name]); - reportedNames[name] = true; - return name + return styleNames + } + this.generateStyleName = function() { + if(styleNameGenerator === null) { + styleNameGenerator = new NameGenerator("auto" + memberIdHash + "_", function() { + return getAllStyleNames() + }) + } + return styleNameGenerator.generateName() + }; + this.generateFrameName = function() { + if(frameNameGenerator === null) { + var nodes = domUtils.getElementsByTagNameNS(odfContainer.rootElement.body, drawns, "frame"); + nodes.forEach(function(frame) { + existingFrameNames[frame.getAttributeNS(drawns, "name")] = true + }); + frameNameGenerator = new NameGenerator("fr" + memberIdHash + "_", function() { + return existingFrameNames + }) + } + return frameNameGenerator.generateName() + }; + this.generateImageName = function() { + if(imageNameGenerator === null) { + var nodes = domUtils.getElementsByTagNameNS(odfContainer.rootElement.body, drawns, "image"); + nodes.forEach(function(image) { + var path = image.getAttributeNS(xlinkns, "href"); + path = path.substring("Pictures/".length, path.lastIndexOf(".")); + existingImageNames[path] = true + }); + imageNameGenerator = new NameGenerator("img" + memberIdHash + "_", function() { + return existingImageNames + }) + } + return imageNameGenerator.generateName() } }; /* @@ -8316,6 +8723,9 @@ odf.StyleNameGenerator = function StyleNameGenerator(prefix, formatting) { 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 @@ -8336,17 +8746,17 @@ odf.StyleNameGenerator = function StyleNameGenerator(prefix, formatting) { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.Utils"); -runtime.loadClass("odf.StyleNameGenerator"); +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 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, odfUtils = new odf.OdfUtils, utils = new core.Utils, builtInDefaultStyleAttributesByFamily = {"paragraph":{"style:paragraph-properties":{"fo:text-align":"left"}}}; + 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) { var result, builtInDefaultStyleAttributes = builtInDefaultStyleAttributesByFamily[styleFamily]; if(builtInDefaultStyleAttributes) { @@ -8380,7 +8790,7 @@ odf.Formatting = function Formatting() { this.getAvailableParagraphStyles = function() { var node = odfContainer.rootElement.styles && odfContainer.rootElement.styles.firstChild, p_family, p_name, p_displayName, paragraphStyles = [], style; while(node) { - if(node.nodeType === Node.ELEMENT_NODE && node.localName === "style" && node.namespaceURI === stylens) { + if(node.nodeType === Node.ELEMENT_NODE && (node.localName === "style" && node.namespaceURI === stylens)) { style = node; p_family = style.getAttributeNS(stylens, "family"); if(p_family === "paragraph") { @@ -8398,13 +8808,13 @@ odf.Formatting = function Formatting() { this.isStyleUsed = function(styleElement) { var hasDerivedStyles, isUsed; hasDerivedStyles = styleInfo.hasDerivedStyles(odfContainer.rootElement, odf.Namespaces.resolvePrefix, styleElement); - isUsed = (new styleInfo.UsedStyleList(odfContainer.rootElement.styles)).uses(styleElement) || (new styleInfo.UsedStyleList(odfContainer.rootElement.automaticStyles)).uses(styleElement) || (new styleInfo.UsedStyleList(odfContainer.rootElement.body)).uses(styleElement); + isUsed = (new styleInfo.UsedStyleList(odfContainer.rootElement.styles)).uses(styleElement) || ((new styleInfo.UsedStyleList(odfContainer.rootElement.automaticStyles)).uses(styleElement) || (new styleInfo.UsedStyleList(odfContainer.rootElement.body)).uses(styleElement)); return hasDerivedStyles || isUsed }; function getDefaultStyleElement(family) { var node = odfContainer.rootElement.styles.firstChild; while(node) { - if(node.nodeType === Node.ELEMENT_NODE && node.namespaceURI === stylens && node.localName === "default-style" && node.getAttributeNS(stylens, "family") === family) { + if(node.nodeType === Node.ELEMENT_NODE && (node.namespaceURI === stylens && (node.localName === "default-style" && node.getAttributeNS(stylens, "family") === family))) { return node } node = node.nextSibling @@ -8421,13 +8831,13 @@ odf.Formatting = function Formatting() { while(node) { if(node.nodeType === Node.ELEMENT_NODE) { nodeStyleName = node.getAttributeNS(stylens, "name"); - if(node.namespaceURI === stylens && node.localName === "style" && node.getAttributeNS(stylens, "family") === family && nodeStyleName === styleName) { + if(node.namespaceURI === stylens && (node.localName === "style" && (node.getAttributeNS(stylens, "family") === family && nodeStyleName === styleName))) { return node } - if(family === "list-style" && node.namespaceURI === textns && node.localName === "list-style" && nodeStyleName === styleName) { + if(family === "list-style" && (node.namespaceURI === textns && (node.localName === "list-style" && nodeStyleName === styleName))) { return node } - if(family === "data" && node.namespaceURI === numberns && nodeStyleName === styleName) { + if(family === "data" && (node.namespaceURI === numberns && nodeStyleName === styleName)) { return node } } @@ -8571,25 +8981,9 @@ odf.Formatting = function Formatting() { return styleChain ? calculateAppliedStyle(styleChain) : undefined }; this.applyStyle = function(memberId, textNodes, limits, info) { - var textStyles = new odf.TextStyleApplicator(new odf.StyleNameGenerator("auto" + utils.hashString(memberId) + "_", self), self, odfContainer.rootElement.automaticStyles); + var textStyles = new odf.TextStyleApplicator(new odf.ObjectNameGenerator((odfContainer), memberId), self, odfContainer.rootElement.automaticStyles); textStyles.applyStyle(textNodes, limits, info) }; - function getAllStyleNames() { - var styleElements = [odfContainer.rootElement.automaticStyles, odfContainer.rootElement.styles], node, styleNames = []; - styleElements.forEach(function(styleListElement) { - node = styleListElement.firstChild; - while(node) { - if(node.nodeType === Node.ELEMENT_NODE) { - if(node.namespaceURI === stylens && node.localName === "style" || node.namespaceURI === textns && node.localName === "list-style") { - styleNames.push(node.getAttributeNS(stylens, "name")) - } - } - node = node.nextSibling - } - }); - return styleNames - } - this.getAllStyleNames = getAllStyleNames; this.updateStyle = function(styleNode, properties) { var fontName, fontFaceNode; mapObjOntoNode(styleNode, properties); @@ -8622,12 +9016,105 @@ odf.Formatting = function Formatting() { tabStopDistance = "1.25cm" } return odfUtils.parseNonNegativeLength(tabStopDistance) - } -}; -/* - - Copyright (C) 2012-2013 KO GmbH - + }; + function getPageLayoutStyleElement(styleName, styleFamily) { + var styleElement = getStyleElement(styleName, styleFamily), masterPageName, layoutName, pageLayoutElements, node, i; + runtime.assert(styleFamily === "paragraph" || styleFamily === "table", "styleFamily has to be either paragraph or table"); + if(styleElement) { + masterPageName = styleElement.getAttributeNS(stylens, "master-page-name") || "Standard"; + node = odfContainer.rootElement.masterStyles.lastChild; + while(node && node.previousSibling) { + if(node.getAttributeNS(stylens, "name") === masterPageName) { + break + } + node = node.previousSibling + } + layoutName = node.getAttributeNS(stylens, "page-layout-name"); + pageLayoutElements = domUtils.getElementsByTagNameNS(odfContainer.rootElement.automaticStyles, stylens, "page-layout"); + for(i = 0;i < pageLayoutElements.length;i += 1) { + node = pageLayoutElements[i]; + if(node.getAttributeNS(stylens, "name") === layoutName) { + return(node) + } + } + } + return null + } + function lengthInCm(length, defaultValue) { + var result = odfUtils.parseLength(length), value = defaultValue; + if(result) { + switch(result.unit) { + case "cm": + value = result.value; + break; + case "mm": + value = result.value * 0.1; + break; + case "in": + value = result.value * 2.54; + break; + case "pt": + value = result.value * 0.035277778; + break; + case "pc": + ; + case "px": + ; + case "em": + break; + default: + runtime.log("Unit identifier: " + result.unit + " is not supported."); + break + } + } + return value + } + this.getContentSize = function(styleName, styleFamily) { + var pageLayoutElement, props, printOrientation, defaultOrientedPageWidth, defaultOrientedPageHeight, pageWidth, pageHeight, margin, marginLeft, marginRight, marginTop, marginBottom, padding, paddingLeft, paddingRight, paddingTop, paddingBottom; + pageLayoutElement = getPageLayoutStyleElement(styleName, styleFamily); + if(!pageLayoutElement) { + pageLayoutElement = odfContainer.rootElement.styles.getElementsByTagNameNS(stylens, "default-page-layout")[0] + } + if(pageLayoutElement) { + props = pageLayoutElement.getElementsByTagNameNS(stylens, "page-layout-properties")[0] + } + if(props) { + printOrientation = props.getAttributeNS(stylens, "print-orientation") || "portrait"; + if(printOrientation === "portrait") { + defaultOrientedPageWidth = defaultPageFormatSettings.width; + defaultOrientedPageHeight = defaultPageFormatSettings.height + }else { + defaultOrientedPageWidth = defaultPageFormatSettings.height; + defaultOrientedPageHeight = defaultPageFormatSettings.width + } + pageWidth = lengthInCm(props.getAttributeNS(fons, "page-width"), defaultOrientedPageWidth); + pageHeight = lengthInCm(props.getAttributeNS(fons, "page-height"), defaultOrientedPageHeight); + margin = lengthInCm(props.getAttributeNS(fons, "margin"), null); + if(margin === null) { + marginLeft = lengthInCm(props.getAttributeNS(fons, "margin-left"), defaultPageFormatSettings.margin); + marginRight = lengthInCm(props.getAttributeNS(fons, "margin-right"), defaultPageFormatSettings.margin); + marginTop = lengthInCm(props.getAttributeNS(fons, "margin-top"), defaultPageFormatSettings.margin); + marginBottom = lengthInCm(props.getAttributeNS(fons, "margin-bottom"), defaultPageFormatSettings.margin) + }else { + marginLeft = marginRight = marginTop = marginBottom = margin + } + padding = lengthInCm(props.getAttributeNS(fons, "padding"), null); + if(padding === null) { + paddingLeft = lengthInCm(props.getAttributeNS(fons, "padding-left"), defaultPageFormatSettings.padding); + paddingRight = lengthInCm(props.getAttributeNS(fons, "padding-right"), defaultPageFormatSettings.padding); + paddingTop = lengthInCm(props.getAttributeNS(fons, "padding-top"), defaultPageFormatSettings.padding); + paddingBottom = lengthInCm(props.getAttributeNS(fons, "padding-bottom"), defaultPageFormatSettings.padding) + }else { + paddingLeft = paddingRight = paddingTop = paddingBottom = padding + } + } + return{width:pageWidth - marginLeft - marginRight - paddingLeft - paddingRight, height:pageHeight - marginTop - marginBottom - paddingTop - paddingBottom} + } +}; +/* + + 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 @@ -8636,6 +9123,9 @@ odf.Formatting = function Formatting() { 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 @@ -8656,7 +9146,7 @@ odf.Formatting = function Formatting() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils"); runtime.loadClass("odf.OdfContainer"); @@ -8787,7 +9277,7 @@ odf.OdfCanvas = function() { if(rangeA === null || rangeB === null) { return true } - return rangeA.startContainer !== rangeB.startContainer || rangeA.startOffset !== rangeB.startOffset || rangeA.endContainer !== rangeB.endContainer || rangeA.endOffset !== rangeB.endOffset + return rangeA.startContainer !== rangeB.startContainer || (rangeA.startOffset !== rangeB.startOffset || (rangeA.endContainer !== rangeB.endContainer || rangeA.endOffset !== rangeB.endOffset)) } function emitNewSelection() { var i, l = listeners.length; @@ -8841,7 +9331,7 @@ odf.OdfCanvas = function() { listenEvent(element, "keyup", checkSelection); listenEvent(element, "keydown", checkSelection) } - var drawns = odf.Namespaces.drawns, fons = odf.Namespaces.fons, officens = odf.Namespaces.officens, stylens = odf.Namespaces.stylens, svgns = odf.Namespaces.svgns, tablens = odf.Namespaces.tablens, textns = odf.Namespaces.textns, xlinkns = odf.Namespaces.xlinkns, xmlns = odf.Namespaces.xmlns, presentationns = odf.Namespaces.presentationns, window = runtime.getWindow(), xpath = new xmldom.XPath, utils = new odf.OdfUtils, domUtils = new core.DomUtils, shadowContent; + var drawns = odf.Namespaces.drawns, fons = odf.Namespaces.fons, officens = odf.Namespaces.officens, stylens = odf.Namespaces.stylens, svgns = odf.Namespaces.svgns, tablens = odf.Namespaces.tablens, textns = odf.Namespaces.textns, xlinkns = odf.Namespaces.xlinkns, xmlns = odf.Namespaces.xmlns, presentationns = odf.Namespaces.presentationns, webodfhelperns = "urn:webodf:names:helper", window = runtime.getWindow(), xpath = new xmldom.XPath, odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils; function clear(element) { while(element.firstChild) { element.removeChild(element.firstChild) @@ -8855,56 +9345,61 @@ odf.OdfCanvas = function() { var fontLoader = new odf.FontLoader; fontLoader.loadFonts(odfContainer, fontcss.sheet) } - function getMasterPage(odfContainer, masterPageName) { + function getMasterPageElement(odfContainer, masterPageName) { if(!masterPageName) { return null } - var masterStyles = odfContainer.rootElement.masterStyles, masterPages = masterStyles.getElementsByTagNameNS(stylens, "master-page"), masterPage = null, i; - for(i = 0;i < masterPages.length;i += 1) { - if(masterPages[i].getAttributeNS(stylens, "name") === masterPageName) { - masterPage = masterPages[i]; + var masterStyles = odfContainer.rootElement.masterStyles, masterPageElements = masterStyles.getElementsByTagNameNS(stylens, "master-page"), masterPageElement = null, i; + for(i = 0;i < masterPageElements.length;i += 1) { + if(masterPageElements[i].getAttributeNS(stylens, "name") === masterPageName) { + masterPageElement = masterPageElements[i]; break } } - return masterPage + return masterPageElement } - function setFramePosition(odfContainer, id, frame, stylesheet) { - frame.setAttribute("styleid", id); - var rule, anchor = frame.getAttributeNS(textns, "anchor-type"), x = frame.getAttributeNS(svgns, "x"), y = frame.getAttributeNS(svgns, "y"), width = frame.getAttributeNS(svgns, "width"), height = frame.getAttributeNS(svgns, "height"), minheight = frame.getAttributeNS(fons, "min-height"), minwidth = frame.getAttributeNS(fons, "min-width"), masterPageName = frame.getAttributeNS(drawns, "master-page-name"), masterPage = null, j, clonedPage, clonedNode, pageNumber = 0, pageNumberContainer, node, document = - odfContainer.rootElement.ownerDocument; - masterPage = getMasterPage(odfContainer, masterPageName); - if(masterPage) { - clonedPage = document.createElementNS(drawns, "draw:page"); - node = masterPage.firstElementChild; - j = 0; - while(node) { - if(node.getAttributeNS(presentationns, "placeholder") !== "true") { - clonedNode = node.cloneNode(true); - clonedPage.appendChild(clonedNode); - setFramePosition(odfContainer, id + "_" + j, (clonedNode), stylesheet) - } - node = node.nextElementSibling; - j += 1 + function dropTemplateDrawFrames(clonedNode) { + var i, element, presentationClass, clonedDrawFrameElements = clonedNode.getElementsByTagNameNS(drawns, "frame"); + for(i = 0;i < clonedDrawFrameElements.length;i += 1) { + element = clonedDrawFrameElements[i]; + presentationClass = element.getAttributeNS(presentationns, "class"); + if(presentationClass && !/^(date-time|footer|header|page-number')$/.test(presentationClass)) { + element.parentNode.removeChild(element) } - shadowContent.appendChild(clonedPage); - pageNumber = shadowContent.getElementsByTagNameNS(drawns, "page").length; - pageNumberContainer = clonedPage.getElementsByTagNameNS(textns, "page-number")[0]; - if(pageNumberContainer) { - while(pageNumberContainer.firstChild) { - pageNumberContainer.removeChild(pageNumberContainer.firstChild) + } + } + function getHeaderFooter(odfContainer, frame, headerFooterId) { + var headerFooter = null, i, declElements = odfContainer.rootElement.body.getElementsByTagNameNS(presentationns, headerFooterId + "-decl"), headerFooterName = frame.getAttributeNS(presentationns, "use-" + headerFooterId + "-name"); + if(headerFooterName && declElements.length > 0) { + for(i = 0;i < declElements.length;i += 1) { + if(declElements[i].getAttributeNS(presentationns, "name") === headerFooterName) { + headerFooter = declElements[i].textContent; + break } - pageNumberContainer.appendChild(document.createTextNode(pageNumber)) } - setFramePosition(odfContainer, id, clonedPage, stylesheet); - clonedPage.setAttributeNS(drawns, "draw:master-page-name", masterPage.getAttributeNS(stylens, "name")) } + return headerFooter + } + function setContainerValue(rootElement, ns, localName, value) { + var i, containerList, document = rootElement.ownerDocument; + containerList = rootElement.getElementsByTagNameNS(ns, localName); + for(i = 0;i < containerList.length;i += 1) { + clear(containerList[i]); + if(value) { + containerList[i].appendChild(document.createTextNode(value)) + } + } + } + function setDrawElementPosition(styleid, frame, stylesheet) { + frame.setAttributeNS(webodfhelperns, "styleid", styleid); + var rule, anchor = frame.getAttributeNS(textns, "anchor-type"), x = frame.getAttributeNS(svgns, "x"), y = frame.getAttributeNS(svgns, "y"), width = frame.getAttributeNS(svgns, "width"), height = frame.getAttributeNS(svgns, "height"), minheight = frame.getAttributeNS(fons, "min-height"), minwidth = frame.getAttributeNS(fons, "min-width"); if(anchor === "as-char") { rule = "display: inline-block;" }else { - if(anchor || x || y) { + if(anchor || (x || y)) { rule = "position: absolute;" }else { - if(width || height || minheight || minwidth) { + if(width || (height || (minheight || minwidth))) { rule = "display: block;" } } @@ -8928,7 +9423,7 @@ odf.OdfCanvas = function() { rule += "min-width: " + minwidth + ";" } if(rule) { - rule = "draw|" + frame.localName + '[styleid="' + id + '"] {' + rule + "}"; + rule = "draw|" + frame.localName + '[webodfhelper|styleid="' + styleid + '"] {' + rule + "}"; stylesheet.insertRule(rule, stylesheet.cssRules.length) } } @@ -8943,13 +9438,13 @@ odf.OdfCanvas = function() { return"" } function setImage(id, container, image, stylesheet) { - image.setAttribute("styleid", id); + image.setAttributeNS(webodfhelperns, "styleid", id); var url = image.getAttributeNS(xlinkns, "href"), part; function callback(url) { var rule; if(url) { rule = "background-image: url(" + url + ");"; - rule = 'draw|image[styleid="' + id + '"] {' + rule + "}"; + rule = 'draw|image[webodfhelper|styleid="' + id + '"] {' + rule + "}"; stylesheet.insertRule(rule, stylesheet.cssRules.length) } } @@ -8969,11 +9464,11 @@ odf.OdfCanvas = function() { } } function formatParagraphAnchors(odfbody) { - var runtimens = "urn:webodf", n, i, nodes = xpath.getODFElementsWithXPath(odfbody, ".//*[*[@text:anchor-type='paragraph']]", odf.Namespaces.resolvePrefix); + var n, i, nodes = xpath.getODFElementsWithXPath(odfbody, ".//*[*[@text:anchor-type='paragraph']]", odf.Namespaces.resolvePrefix); for(i = 0;i < nodes.length;i += 1) { n = nodes[i]; if(n.setAttributeNS) { - n.setAttributeNS(runtimens, "containsparagraphanchor", true) + n.setAttributeNS(webodfhelperns, "containsparagraphanchor", true) } } } @@ -9026,6 +9521,14 @@ odf.OdfCanvas = function() { modifyLink(node) } } + function modifyLineBreakElements(odffragment) { + var document = odffragment.ownerDocument, lineBreakElements = domUtils.getElementsByTagNameNS(odffragment, textns, "line-break"); + lineBreakElements.forEach(function(lineBreak) { + if(!lineBreak.hasChildNodes()) { + lineBreak.appendChild(document.createElement("br")) + } + }) + } function expandSpaceElements(odffragment) { var spaces, doc = odffragment.ownerDocument; function expandSpaceElement(space) { @@ -9052,18 +9555,18 @@ odf.OdfCanvas = function() { tab.textContent = "\t" }) } - function modifyImages(container, odfbody, stylesheet) { - var node, frames, i; - frames = []; + function modifyDrawElements(odfbody, stylesheet) { + var node, drawElements, i; + drawElements = []; node = odfbody.firstChild; while(node && node !== odfbody) { if(node.namespaceURI === drawns) { - frames[frames.length] = node + drawElements[drawElements.length] = node } if(node.firstChild) { node = node.firstChild }else { - while(node && node !== odfbody && !node.nextSibling) { + while(node && (node !== odfbody && !node.nextSibling)) { node = node.parentNode } if(node && node.nextSibling) { @@ -9071,12 +9574,48 @@ odf.OdfCanvas = function() { } } } - for(i = 0;i < frames.length;i += 1) { - node = frames[i]; - setFramePosition(container, "frame" + String(i), node, stylesheet) + for(i = 0;i < drawElements.length;i += 1) { + node = drawElements[i]; + setDrawElementPosition("frame" + String(i), node, stylesheet) } formatParagraphAnchors(odfbody) } + function cloneMasterPages(odfContainer, shadowContent, odfbody, stylesheet) { + var masterPageName, masterPageElement, styleId, clonedPageElement, clonedElement, pageNumber = 0, i, element, elementToClone, document = odfContainer.rootElement.ownerDocument; + element = odfbody.firstElementChild; + if(!(element && (element.namespaceURI === officens && (element.localName === "presentation" || element.localName === "drawing")))) { + return + } + element = element.firstElementChild; + while(element) { + masterPageName = element.getAttributeNS(drawns, "master-page-name"); + masterPageElement = getMasterPageElement(odfContainer, masterPageName); + if(masterPageElement) { + styleId = element.getAttributeNS(webodfhelperns, "styleid"); + clonedPageElement = document.createElementNS(drawns, "draw:page"); + elementToClone = masterPageElement.firstElementChild; + i = 0; + while(elementToClone) { + if(elementToClone.getAttributeNS(presentationns, "placeholder") !== "true") { + clonedElement = elementToClone.cloneNode(true); + clonedPageElement.appendChild(clonedElement); + setDrawElementPosition(styleId + "_" + i, (clonedElement), stylesheet) + } + elementToClone = elementToClone.nextElementSibling; + i += 1 + } + dropTemplateDrawFrames(clonedPageElement); + shadowContent.appendChild(clonedPageElement); + pageNumber = String(shadowContent.getElementsByTagNameNS(drawns, "page").length); + setContainerValue(clonedPageElement, textns, "page-number", pageNumber); + setContainerValue(clonedPageElement, presentationns, "header", getHeaderFooter(odfContainer, (element), "header")); + setContainerValue(clonedPageElement, presentationns, "footer", getHeaderFooter(odfContainer, (element), "footer")); + setDrawElementPosition(styleId, clonedPageElement, stylesheet); + clonedPageElement.setAttributeNS(drawns, "draw:master-page-name", masterPageElement.getAttributeNS(stylens, "name")) + } + element = element.nextElementSibling + } + } function setVideo(container, plugin) { var video, source, url, doc = plugin.ownerDocument, part; url = plugin.getAttributeNS(xlinkns, "href"); @@ -9174,7 +9713,7 @@ odf.OdfCanvas = function() { styleName = node.getAttributeNS(textns, "style-name"); if(styleName) { node = listStyleMap[styleName]; - bulletRule = getBulletsRule((utils.getFirstNonWhitespaceChild(node))) + bulletRule = getBulletsRule((odfUtils.getFirstNonWhitespaceChild(node))) } if(continueList) { parentList = listMap[continueList]; @@ -9234,6 +9773,7 @@ odf.OdfCanvas = function() { odf.Namespaces.forEachPrefix(function(prefix, ns) { text += "@namespace " + prefix + " url(" + ns + ");\n" }); + text += "@namespace webodfhelper url(" + webodfhelperns + ");\n"; style.appendChild(document.createTextNode(text)); head.appendChild(style); return(style) @@ -9241,7 +9781,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, 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, annotationManager, 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) { @@ -9325,9 +9865,11 @@ odf.OdfCanvas = function() { shadowContent.style.top = 0; shadowContent.style.left = 0; container.getContentElement().appendChild(shadowContent); - modifyImages(container, odfnode.body, css); + modifyDrawElements(odfnode.body, css); + cloneMasterPages(container, shadowContent, odfnode.body, css); modifyTables(odfnode.body); modifyLinks(odfnode.body); + modifyLineBreakElements(odfnode.body); expandSpaceElements(odfnode.body); expandTabElements(odfnode.body); loadImages(container, odfnode.body, css); @@ -9414,7 +9956,7 @@ odf.OdfCanvas = function() { }; function load(url) { loadingQueue.clearQueue(); - element.innerHTML = "loading " + url; + element.innerHTML = runtime.tr("Loading") + " " + url + "..."; element.removeAttribute("style"); odfcontainer = new odf.OdfContainer(url, function(container) { odfcontainer = container; @@ -9528,6 +10070,11 @@ odf.OdfCanvas = function() { this.getElement = function() { return element }; + this.addCssForFrameWithImage = function(frame) { + var frameName = frame.getAttributeNS(drawns, "name"); + setDrawElementPosition(frameName, frame, positioncss.sheet); + setImage(frameName + "img", odfcontainer, (frame.firstChild), positioncss.sheet) + }; this.destroy = function(callback) { var head = doc.getElementsByTagName("head")[0]; if(annotationsPane && annotationsPane.parentNode) { @@ -9601,6 +10148,9 @@ odf.CommandLineTools = function CommandLineTools() { 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 @@ -9621,7 +10171,7 @@ odf.CommandLineTools = function CommandLineTools() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.Server = function Server() { }; @@ -9649,6 +10199,9 @@ ops.Server.prototype.getGenesisUrl = function(sessionId) { 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 @@ -9669,14 +10222,12 @@ ops.Server.prototype.getGenesisUrl = function(sessionId) { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.Operation = function Operation() { }; ops.Operation.prototype.init = function(data) { }; -ops.Operation.prototype.transform = function(otherOp, hasPriority) { -}; ops.Operation.prototype.execute = function(odtDocument) { }; ops.Operation.prototype.spec = function() { @@ -9693,6 +10244,9 @@ ops.Operation.prototype.spec = function() { 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 @@ -9713,17 +10267,14 @@ ops.Operation.prototype.spec = function() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.OpAddCursor = function OpAddCursor() { - var self = this, memberid, timestamp; + var memberid, timestamp; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp }; - this.transform = function(otherOp, hasPriority) { - return[self] - }; this.execute = function(odtDocument) { var cursor = odtDocument.getCursor(memberid); if(cursor) { @@ -9750,6 +10301,9 @@ ops.OpAddCursor = function OpAddCursor() { 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 @@ -9770,7 +10324,7 @@ ops.OpAddCursor = function OpAddCursor() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils"); runtime.loadClass("odf.Namespaces"); @@ -9797,11 +10351,10 @@ gui.StyleHelper = function StyleHelper(formatting) { formatting.applyStyle(memberId, textNodes, limits, info); nextTextNodes.forEach(domUtils.normalizeTextNodes) }; - function hasTextPropertyValue(range, propertyName, propertyValue) { - var hasOtherValue = true, styles, properties, i; - styles = getAppliedStyles(range); - for(i = 0;i < styles.length;i += 1) { - properties = styles[i]["style:text-properties"]; + function hasTextPropertyValue(appliedStyles, propertyName, propertyValue) { + var hasOtherValue = true, properties, i; + for(i = 0;i < appliedStyles.length;i += 1) { + properties = appliedStyles[i]["style:text-properties"]; hasOtherValue = !properties || properties[propertyName] !== propertyValue; if(hasOtherValue) { break @@ -9809,17 +10362,17 @@ gui.StyleHelper = function StyleHelper(formatting) { } return!hasOtherValue } - this.isBold = function(range) { - return hasTextPropertyValue(range, "fo:font-weight", "bold") + this.isBold = function(appliedStyles) { + return hasTextPropertyValue(appliedStyles, "fo:font-weight", "bold") }; - this.isItalic = function(range) { - return hasTextPropertyValue(range, "fo:font-style", "italic") + this.isItalic = function(appliedStyles) { + return hasTextPropertyValue(appliedStyles, "fo:font-style", "italic") }; - this.hasUnderline = function(range) { - return hasTextPropertyValue(range, "style:text-underline-style", "solid") + this.hasUnderline = function(appliedStyles) { + return hasTextPropertyValue(appliedStyles, "style:text-underline-style", "solid") }; - this.hasStrikeThrough = function(range) { - return hasTextPropertyValue(range, "style:text-line-through-style", "solid") + this.hasStrikeThrough = function(appliedStyles) { + return hasTextPropertyValue(appliedStyles, "style:text-line-through-style", "solid") }; function hasParagraphPropertyValue(range, propertyName, propertyValues) { var nodes = odfUtils.getParagraphElements(range), isStyleChecked = {}, isDefaultParagraphStyleChecked = false, paragraphStyleName, paragraphStyleElement, paragraphStyleAttributes, properties; @@ -9874,6 +10427,9 @@ gui.StyleHelper = function StyleHelper(formatting) { 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 @@ -9894,7 +10450,7 @@ gui.StyleHelper = function StyleHelper(formatting) { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("gui.StyleHelper"); runtime.loadClass("odf.OdfUtils"); @@ -9907,9 +10463,6 @@ ops.OpApplyDirectStyling = function OpApplyDirectStyling() { length = parseInt(data.length, 10); setProperties = data.setProperties }; - this.transform = function(otherOp, hasPriority) { - return null - }; function getRange(odtDocument) { var point1 = length >= 0 ? position : position + length, point2 = length >= 0 ? position + length : position, p1 = odtDocument.getIteratorAtPosition(point1), p2 = length ? odtDocument.getIteratorAtPosition(point2) : p1, range = odtDocument.getDOM().createRange(); range.setStart(p1.container(), p1.unfilteredDomOffset()); @@ -9921,6 +10474,7 @@ ops.OpApplyDirectStyling = function OpApplyDirectStyling() { styleHelper.applyStyle(memberid, range, setProperties); range.detach(); odtDocument.getOdfCanvas().refreshCSS(); + odtDocument.fixCursorPositions(); impactedParagraphs.forEach(function(n) { odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:n, memberId:memberid, timeStamp:timestamp}) }); @@ -9943,6 +10497,9 @@ ops.OpApplyDirectStyling = function OpApplyDirectStyling() { 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 @@ -9963,21 +10520,14 @@ ops.OpApplyDirectStyling = function OpApplyDirectStyling() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.OpRemoveCursor = function OpRemoveCursor() { - var self = this, optype = "RemoveCursor", memberid, timestamp; + var memberid, timestamp; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp }; - this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), result = [self]; - if(otherOpspec.optype === optype && otherOpspec.memberid === memberid) { - result = [] - } - return result - }; this.execute = function(odtDocument) { if(!odtDocument.removeCursor(memberid)) { return false @@ -9985,7 +10535,7 @@ ops.OpRemoveCursor = function OpRemoveCursor() { return true }; this.spec = function() { - return{optype:optype, memberid:memberid, timestamp:timestamp} + return{optype:"RemoveCursor", memberid:memberid, timestamp:timestamp} } }; /* @@ -10000,6 +10550,9 @@ ops.OpRemoveCursor = function OpRemoveCursor() { 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 @@ -10020,97 +10573,16 @@ ops.OpRemoveCursor = function OpRemoveCursor() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.OpMoveCursor = function OpMoveCursor() { - var self = this, memberid, timestamp, position, length; + var memberid, timestamp, position, length, selectionType; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; - position = parseInt(data.position, 10); - length = data.length !== undefined ? parseInt(data.length, 10) : 0 - }; - function countSteps(number, stepCounter, positionFilter) { - if(number > 0) { - return stepCounter.countForwardSteps(number, positionFilter) - } - if(number < 0) { - return-stepCounter.countBackwardSteps(-number, positionFilter) - } - return 0 - } - this.merge = function(otherOpspec) { - if(otherOpspec.optype === "MoveCursor" && otherOpspec.memberid === memberid) { - position = otherOpspec.position; - length = otherOpspec.length; - timestamp = otherOpspec.timestamp; - return true - } - return false - }; - this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, end = position + length, otherOpspecEnd, result = [self]; - switch(otherOptype) { - case "RemoveText": - otherOpspecEnd = otherOpspec.position + otherOpspec.length; - if(otherOpspecEnd <= position) { - position -= otherOpspec.length - }else { - if(otherOpspec.position < end) { - if(position < otherOpspec.position) { - if(otherOpspecEnd < end) { - length = length - otherOpspec.length - }else { - length = otherOpspec.position - position - } - }else { - position = otherOpspec.position; - if(otherOpspecEnd < end) { - length = end - otherOpspecEnd - }else { - length = 0 - } - } - } - } - break; - case "SplitParagraph": - if(otherOpspec.position < position) { - position += 1 - }else { - if(otherOpspec.position <= end) { - length += 1 - } - } - break; - case "AddAnnotation": - if(otherOpspec.position < position) { - position += 1 - }else { - if(otherOpspec.position < end) { - length += 1 - } - } - break; - case "InsertText": - if(otherOpspec.position < position) { - position += otherOpspec.text.length - }else { - if(otherOpspec.position <= end) { - length += otherOpspec.text.length - } - } - break; - case "RemoveCursor": - if(otherOpspec.memberid === memberid) { - result = [] - } - break; - case "InsertTable": - result = null; - break - } - return result + position = data.position; + length = data.length || 0; + selectionType = data.selectionType || ops.OdtCursor.RangeSelection }; this.execute = function(odtDocument) { var cursor = odtDocument.getCursor(memberid), oldPosition = odtDocument.getCursorPosition(memberid), positionFilter = odtDocument.getPositionFilter(), number = position - oldPosition, stepsToSelectionStart, stepsToSelectionEnd, stepCounter; @@ -10118,22 +10590,23 @@ ops.OpMoveCursor = function OpMoveCursor() { return false } stepCounter = cursor.getStepCounter(); - stepsToSelectionStart = countSteps(number, stepCounter, positionFilter); + stepsToSelectionStart = stepCounter.countSteps(number, positionFilter); cursor.move(stepsToSelectionStart); if(length) { - stepsToSelectionEnd = countSteps(length, stepCounter, positionFilter); + stepsToSelectionEnd = stepCounter.countSteps(length, positionFilter); cursor.move(stepsToSelectionEnd, true) } + cursor.setSelectionType(selectionType); odtDocument.emit(ops.OdtDocument.signalCursorMoved, cursor); return true }; this.spec = function() { - return{optype:"MoveCursor", memberid:memberid, timestamp:timestamp, position:position, length:length} + return{optype:"MoveCursor", memberid:memberid, timestamp:timestamp, position:position, length:length, selectionType:selectionType} } }; /* - Copyright (C) 2013 KO GmbH + Copyright (C) 2012-2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -10143,6 +10616,9 @@ ops.OpMoveCursor = function OpMoveCursor() { 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 @@ -10163,144 +10639,23 @@ ops.OpMoveCursor = function OpMoveCursor() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.OpInsertTable = function OpInsertTable() { - var self = this, optype = "InsertTable", memberid, timestamp, initialRows, initialColumns, position, tableName, tableStyleName, tableColumnStyleName, tableCellStyleMatrix, tablens = "urn:oasis:names:tc:opendocument:xmlns:table:1.0", textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; +ops.OpSetBlob = function OpSetBlob() { + var memberid, timestamp, filename, mimetype, content; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; - position = parseInt(data.position, 10); - initialRows = parseInt(data.initialRows, 10); - initialColumns = parseInt(data.initialColumns, 10); - tableName = data.tableName; - tableStyleName = data.tableStyleName; - tableColumnStyleName = data.tableColumnStyleName; - tableCellStyleMatrix = data.tableCellStyleMatrix - }; - this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, result = [self]; - switch(otherOptype) { - case optype: - result = null; - break; - case "AddAnnotation": - if(otherOpspec.position < position) { - position += 1 - } - break; - case "SplitParagraph": - if(otherOpspec.position < position) { - position += 1 - }else { - if(otherOpspec.position === position && !hasPriority) { - position += 1; - result = null - } - } - break; - case "InsertText": - if(otherOpspec.position < position) { - position += otherOpspec.text.length - }else { - if(otherOpspec.position === position && !hasPriority) { - position += otherOpspec.text.length; - result = null - } - } - break; - case "RemoveText": - if(otherOpspec.position + otherOpspec.length <= position) { - position -= otherOpspec.length - }else { - if(otherOpspec.position < position) { - position = otherOpspec.position - } - } - break - } - return result + filename = data.filename; + mimetype = data.mimetype; + content = data.content }; - function getCellStyleName(row, column) { - var rowStyles; - if(tableCellStyleMatrix.length === 1) { - rowStyles = tableCellStyleMatrix[0] - }else { - if(tableCellStyleMatrix.length === 3) { - switch(row) { - case 0: - rowStyles = tableCellStyleMatrix[0]; - break; - case initialRows - 1: - rowStyles = tableCellStyleMatrix[2]; - break; - default: - rowStyles = tableCellStyleMatrix[1]; - break - } - }else { - rowStyles = tableCellStyleMatrix[row] - } - } - if(rowStyles.length === 1) { - return rowStyles[0] - } - if(rowStyles.length === 3) { - switch(column) { - case 0: - return rowStyles[0]; - case initialColumns - 1: - return rowStyles[2]; - default: - return rowStyles[1] - } - } - return rowStyles[column] - } - function createTableNode(document) { - var tableNode = document.createElementNS(tablens, "table:table"), columns = document.createElementNS(tablens, "table:table-column"), row, cell, paragraph, rowCounter, columnCounter, cellStyleName; - if(tableStyleName) { - tableNode.setAttributeNS(tablens, "table:style-name", tableStyleName) - } - if(tableName) { - tableNode.setAttributeNS(tablens, "table:name", tableName) - } - columns.setAttributeNS(tablens, "table:number-columns-repeated", initialColumns); - if(tableColumnStyleName) { - columns.setAttributeNS(tablens, "table:style-name", tableColumnStyleName) - } - tableNode.appendChild(columns); - for(rowCounter = 0;rowCounter < initialRows;rowCounter += 1) { - row = document.createElementNS(tablens, "table:table-row"); - for(columnCounter = 0;columnCounter < initialColumns;columnCounter += 1) { - cell = document.createElementNS(tablens, "table:table-cell"); - cellStyleName = getCellStyleName(rowCounter, columnCounter); - if(cellStyleName) { - cell.setAttributeNS(tablens, "table:style-name", cellStyleName) - } - paragraph = document.createElementNS(textns, "text:p"); - cell.appendChild(paragraph); - row.appendChild(cell) - } - tableNode.appendChild(row) - } - return tableNode - } this.execute = function(odtDocument) { - var domPosition = odtDocument.getPositionInTextNode(position), rootNode = odtDocument.getRootNode(), previousSibling, tableNode; - if(domPosition) { - tableNode = createTableNode(odtDocument.getDOM()); - previousSibling = odtDocument.getParagraphElement(domPosition.textNode); - rootNode.insertBefore(tableNode, previousSibling ? previousSibling.nextSibling : undefined); - odtDocument.getOdfCanvas().refreshSize(); - odtDocument.emit(ops.OdtDocument.signalTableAdded, {tableElement:tableNode, memberId:memberid, timeStamp:timestamp}); - odtDocument.getOdfCanvas().rerenderAnnotations(); - return true - } - return false + odtDocument.getOdfCanvas().odfContainer().setBlob(filename, mimetype, content); + return true }; this.spec = function() { - return{optype:optype, memberid:memberid, timestamp:timestamp, position:position, initialRows:initialRows, initialColumns:initialColumns, tableName:tableName, tableStyleName:tableStyleName, tableColumnStyleName:tableColumnStyleName, tableCellStyleMatrix:tableCellStyleMatrix} + return{optype:"SetBlob", memberid:memberid, timestamp:timestamp, filename:filename, mimetype:mimetype, content:content} } }; /* @@ -10315,6 +10670,9 @@ ops.OpInsertTable = function OpInsertTable() { 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 @@ -10335,77 +10693,296 @@ ops.OpInsertTable = function OpInsertTable() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.OpInsertText = function OpInsertText() { - var self = this, space = " ", tab = "\t", optype = "InsertText", memberid, timestamp, position, text; +ops.OpRemoveBlob = function OpRemoveBlob() { + var memberid, timestamp, filename; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; - position = parseInt(data.position, 10); - text = data.text - }; - this.merge = function(otherOpspec) { - if(otherOpspec.optype === optype && otherOpspec.memberid === memberid && otherOpspec.position === position + text.length) { - text = text + otherOpspec.text; - timestamp = otherOpspec.timestamp; - return true - } - return false + filename = data.filename }; - this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, result = [self]; - switch(otherOptype) { - case optype: - if(otherOpspec.position < position) { - position += otherOpspec.text.length - }else { - if(otherOpspec.position === position && !hasPriority) { - position += otherOpspec.text.length; - result = null - } - } - break; - case "AddAnnotation": - if(otherOpspec.position < position) { - position += 1 - } - break; - case "SplitParagraph": - if(otherOpspec.position < position) { - position += 1 - }else { - if(otherOpspec.position === position && !hasPriority) { - position += 1; - result = null - } - } - break; - case "InsertTable": - result = null; - break; - case "RemoveText": - if(otherOpspec.position + otherOpspec.length <= position) { - position -= otherOpspec.length - }else { - if(otherOpspec.position < position) { - position = otherOpspec.position - } - } - break - } - return result + this.execute = function(odtDocument) { + odtDocument.getOdfCanvas().odfContainer().removeBlob(filename); + return true }; - function triggerLayoutInWebkit(textNode) { - var parent = textNode.parentNode, next = textNode.nextSibling; - parent.removeChild(textNode); - parent.insertBefore(textNode, next) - } - function requiresSpaceElement(text, index) { - return text[index] === space && (index === 0 || text[index - 1] === space) + this.spec = function() { + return{optype:"RemoveBlob", memberid:memberid, timestamp:timestamp, filename:filename} + } +}; +/* + + 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.OpInsertImage = function OpInsertImage() { + var memberid, timestamp, position, filename, frameWidth, frameHeight, frameStyleName, frameName, drawns = odf.Namespaces.drawns, svgns = odf.Namespaces.svgns, textns = odf.Namespaces.textns, xlinkns = odf.Namespaces.xlinkns; + this.init = function(data) { + memberid = data.memberid; + timestamp = data.timestamp; + position = data.position; + filename = data.filename; + frameWidth = data.frameWidth; + frameHeight = data.frameHeight; + frameStyleName = data.frameStyleName; + frameName = data.frameName + }; + function createFrameElement(document) { + var imageNode = document.createElementNS(drawns, "draw:image"), frameNode = document.createElementNS(drawns, "draw:frame"); + imageNode.setAttributeNS(xlinkns, "xlink:href", filename); + imageNode.setAttributeNS(xlinkns, "xlink:type", "simple"); + imageNode.setAttributeNS(xlinkns, "xlink:show", "embed"); + imageNode.setAttributeNS(xlinkns, "xlink:actuate", "onLoad"); + frameNode.setAttributeNS(drawns, "draw:style-name", frameStyleName); + frameNode.setAttributeNS(drawns, "draw:name", frameName); + frameNode.setAttributeNS(textns, "text:anchor-type", "as-char"); + frameNode.setAttributeNS(svgns, "svg:width", frameWidth); + frameNode.setAttributeNS(svgns, "svg:height", frameHeight); + frameNode.appendChild(imageNode); + return frameNode + } + this.execute = function(odtDocument) { + var odfCanvas = odtDocument.getOdfCanvas(), domPosition = odtDocument.getPositionInTextNode(position, memberid), textNode, refNode, paragraphElement, frameElement; + if(!domPosition) { + return false + } + textNode = domPosition.textNode; + paragraphElement = odtDocument.getParagraphElement(textNode); + refNode = domPosition.offset !== textNode.length ? textNode.splitText(domPosition.offset) : textNode.nextSibling; + frameElement = createFrameElement(odtDocument.getDOM()); + textNode.parentNode.insertBefore(frameElement, refNode); + if(textNode.length === 0) { + textNode.parentNode.removeChild(textNode) + } + odfCanvas.addCssForFrameWithImage(frameElement); + odfCanvas.refreshCSS(); + odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:paragraphElement, memberId:memberid, timeStamp:timestamp}); + odfCanvas.rerenderAnnotations(); + return true + }; + this.spec = function() { + return{optype:"InsertImage", memberid:memberid, timestamp:timestamp, filename:filename, position:position, frameWidth:frameWidth, frameHeight:frameHeight, frameStyleName:frameStyleName, frameName:frameName} + } +}; +/* + + 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 + 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.OpInsertTable = function OpInsertTable() { + var memberid, timestamp, initialRows, initialColumns, position, tableName, tableStyleName, tableColumnStyleName, tableCellStyleMatrix, tablens = "urn:oasis:names:tc:opendocument:xmlns:table:1.0", textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; + this.init = function(data) { + memberid = data.memberid; + timestamp = data.timestamp; + position = data.position; + initialRows = data.initialRows; + initialColumns = data.initialColumns; + tableName = data.tableName; + tableStyleName = data.tableStyleName; + tableColumnStyleName = data.tableColumnStyleName; + tableCellStyleMatrix = data.tableCellStyleMatrix + }; + function getCellStyleName(row, column) { + var rowStyles; + if(tableCellStyleMatrix.length === 1) { + rowStyles = tableCellStyleMatrix[0] + }else { + if(tableCellStyleMatrix.length === 3) { + switch(row) { + case 0: + rowStyles = tableCellStyleMatrix[0]; + break; + case initialRows - 1: + rowStyles = tableCellStyleMatrix[2]; + break; + default: + rowStyles = tableCellStyleMatrix[1]; + break + } + }else { + rowStyles = tableCellStyleMatrix[row] + } + } + if(rowStyles.length === 1) { + return rowStyles[0] + } + if(rowStyles.length === 3) { + switch(column) { + case 0: + return rowStyles[0]; + case initialColumns - 1: + return rowStyles[2]; + default: + return rowStyles[1] + } + } + return rowStyles[column] + } + function createTableNode(document) { + var tableNode = document.createElementNS(tablens, "table:table"), columns = document.createElementNS(tablens, "table:table-column"), row, cell, paragraph, rowCounter, columnCounter, cellStyleName; + if(tableStyleName) { + tableNode.setAttributeNS(tablens, "table:style-name", tableStyleName) + } + if(tableName) { + tableNode.setAttributeNS(tablens, "table:name", tableName) + } + columns.setAttributeNS(tablens, "table:number-columns-repeated", initialColumns); + if(tableColumnStyleName) { + columns.setAttributeNS(tablens, "table:style-name", tableColumnStyleName) + } + tableNode.appendChild(columns); + for(rowCounter = 0;rowCounter < initialRows;rowCounter += 1) { + row = document.createElementNS(tablens, "table:table-row"); + for(columnCounter = 0;columnCounter < initialColumns;columnCounter += 1) { + cell = document.createElementNS(tablens, "table:table-cell"); + cellStyleName = getCellStyleName(rowCounter, columnCounter); + if(cellStyleName) { + cell.setAttributeNS(tablens, "table:style-name", cellStyleName) + } + paragraph = document.createElementNS(textns, "text:p"); + cell.appendChild(paragraph); + row.appendChild(cell) + } + tableNode.appendChild(row) + } + return tableNode + } + this.execute = function(odtDocument) { + var domPosition = odtDocument.getPositionInTextNode(position), rootNode = odtDocument.getRootNode(), previousSibling, tableNode; + if(domPosition) { + tableNode = createTableNode(odtDocument.getDOM()); + previousSibling = odtDocument.getParagraphElement(domPosition.textNode); + rootNode.insertBefore(tableNode, previousSibling.nextSibling); + odtDocument.getOdfCanvas().refreshSize(); + odtDocument.emit(ops.OdtDocument.signalTableAdded, {tableElement:tableNode, memberId:memberid, timeStamp:timestamp}); + odtDocument.getOdfCanvas().rerenderAnnotations(); + return true + } + return false + }; + this.spec = function() { + return{optype:"InsertTable", memberid:memberid, timestamp:timestamp, position:position, initialRows:initialRows, initialColumns:initialColumns, tableName:tableName, tableStyleName:tableStyleName, tableColumnStyleName:tableColumnStyleName, tableCellStyleMatrix:tableCellStyleMatrix} + } +}; +/* + + 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.OpInsertText = function OpInsertText() { + var space = " ", tab = "\t", memberid, timestamp, position, text; + this.init = function(data) { + memberid = data.memberid; + timestamp = data.timestamp; + position = data.position; + text = data.text + }; + function triggerLayoutInWebkit(textNode) { + var parent = textNode.parentNode, next = textNode.nextSibling; + parent.removeChild(textNode); + parent.insertBefore(textNode, next) + } + function requiresSpaceElement(text, index) { + return text[index] === space && (index === 0 || (index === text.length - 1 || text[index - 1] === space)) } this.execute = function(odtDocument) { - var domPosition, previousNode, parentElement, nextNode, ownerDocument = odtDocument.getDOM(), paragraphElement, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", toInsertIndex = 0, spaceTag, spaceElement, i; + var domPosition, previousNode, parentElement, nextNode = null, ownerDocument = odtDocument.getDOM(), paragraphElement, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", toInsertIndex = 0, spaceTag, spaceElement, i; function insertTextNode(toInsertText) { parentElement.insertBefore(ownerDocument.createTextNode(toInsertText), nextNode) } @@ -10449,12 +11026,13 @@ ops.OpInsertText = function OpInsertText() { previousNode.parentNode.removeChild(previousNode) } if(position > 0) { - odtDocument.downgradeWhitespacesAtPosition(position - 1); if(position > 1) { odtDocument.downgradeWhitespacesAtPosition(position - 2) } + odtDocument.downgradeWhitespacesAtPosition(position - 1) } odtDocument.downgradeWhitespacesAtPosition(position); + odtDocument.downgradeWhitespacesAtPosition(position + text.length - 1); odtDocument.downgradeWhitespacesAtPosition(position + text.length); odtDocument.getOdfCanvas().refreshSize(); odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:paragraphElement, memberId:memberid, timeStamp:timestamp}); @@ -10464,7 +11042,7 @@ ops.OpInsertText = function OpInsertText() { return false }; this.spec = function() { - return{optype:optype, memberid:memberid, timestamp:timestamp, position:position, text:text} + return{optype:"InsertText", memberid:memberid, timestamp:timestamp, position:position, text:text} } }; /* @@ -10479,6 +11057,9 @@ ops.OpInsertText = function OpInsertText() { 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 @@ -10499,13 +11080,13 @@ ops.OpInsertText = function OpInsertText() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.Namespaces"); runtime.loadClass("odf.OdfUtils"); runtime.loadClass("core.DomUtils"); ops.OpRemoveText = function OpRemoveText() { - var self = this, optype = "RemoveText", memberid, timestamp, position, length, odfUtils, domUtils, editinfons = "urn:webodf:names:editinfo"; + var memberid, timestamp, position, length, odfUtils, domUtils, editinfons = "urn:webodf:names:editinfo", FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, odfNodeNamespaceMap = {}; this.init = function(data) { runtime.assert(data.length >= 0, "OpRemoveText only supports positive lengths"); memberid = data.memberid; @@ -10513,73 +11094,28 @@ ops.OpRemoveText = function OpRemoveText() { position = parseInt(data.position, 10); length = parseInt(data.length, 10); odfUtils = new odf.OdfUtils; - domUtils = new core.DomUtils - }; - this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, end = position + length, otherOpspecEnd, helperOp, result = [self]; - switch(otherOptype) { - case optype: - otherOpspecEnd = otherOpspec.position + otherOpspec.length; - if(otherOpspecEnd <= position) { - position -= otherOpspec.length - }else { - if(otherOpspec.position < end) { - if(position < otherOpspec.position) { - if(otherOpspecEnd < end) { - length = length - otherOpspec.length - }else { - length = otherOpspec.position - position - } - }else { - if(otherOpspecEnd < end) { - position = otherOpspec.position; - length = end - otherOpspecEnd - }else { - result = [] - } - } - } - } - break; - case "InsertText": - if(otherOpspec.position <= position) { - position += otherOpspec.text.length - }else { - if(otherOpspec.position < end) { - length = otherOpspec.position - position; - helperOp = new ops.OpRemoveText; - helperOp.init({memberid:memberid, timestamp:timestamp, position:otherOpspec.position + otherOpspec.text.length, length:end - otherOpspec.position}); - result = [helperOp, self] - } - } - break; - case "SplitParagraph": - if(otherOpspec.position <= position) { - position += 1 - }else { - if(otherOpspec.position < end) { - length = otherOpspec.position - position; - helperOp = new ops.OpRemoveText; - helperOp.init({memberid:memberid, timestamp:timestamp, position:otherOpspec.position + 1, length:end - otherOpspec.position}); - result = [helperOp, self] - } - } - break; - case "InsertTable": - result = null; - break; - case "AddAnnotation": - ; - case "RemoveAnnotation": - result = null; - break; - case "ApplyDirectStyling": - result = null; - break - } - return result + domUtils = new core.DomUtils; + odfNodeNamespaceMap[odf.Namespaces.dbns] = true; + odfNodeNamespaceMap[odf.Namespaces.dcns] = true; + odfNodeNamespaceMap[odf.Namespaces.dr3dns] = true; + odfNodeNamespaceMap[odf.Namespaces.drawns] = true; + odfNodeNamespaceMap[odf.Namespaces.chartns] = true; + odfNodeNamespaceMap[odf.Namespaces.formns] = true; + odfNodeNamespaceMap[odf.Namespaces.numberns] = true; + odfNodeNamespaceMap[odf.Namespaces.officens] = true; + odfNodeNamespaceMap[odf.Namespaces.presentationns] = true; + odfNodeNamespaceMap[odf.Namespaces.stylens] = true; + odfNodeNamespaceMap[odf.Namespaces.svgns] = true; + odfNodeNamespaceMap[odf.Namespaces.tablens] = true; + odfNodeNamespaceMap[odf.Namespaces.textns] = true }; function CollapsingRules(rootNode) { + function isOdfNode(node) { + return odfNodeNamespaceMap.hasOwnProperty(node.namespaceURI) + } + function shouldRemove(node) { + return isOdfNode(node) || (node.localName === "br" && odfUtils.isLineBreak(node.parentNode) || node.nodeType === Node.TEXT_NODE && isOdfNode((node.parentNode))) + } function isEmpty(node) { var childNode; if(odfUtils.isCharacterElement(node)) { @@ -10590,7 +11126,7 @@ ops.OpRemoveText = function OpRemoveText() { } childNode = node.firstChild; while(childNode) { - if(!isEmpty(childNode)) { + if(isOdfNode(childNode) || !isEmpty(childNode)) { return false } childNode = childNode.nextSibling @@ -10599,10 +11135,16 @@ ops.OpRemoveText = function OpRemoveText() { } this.isEmpty = isEmpty; function isCollapsibleContainer(node) { - return!odfUtils.isParagraph(node) && node !== rootNode && isEmpty(node) + return!odfUtils.isParagraph(node) && (node !== rootNode && isEmpty(node)) } - function mergeChildrenIntoParent(node) { - var parent = domUtils.mergeIntoParent(node); + function mergeChildrenIntoParent(targetNode) { + var parent; + if(targetNode.nodeType === Node.TEXT_NODE) { + parent = targetNode.parentNode; + parent.removeChild(targetNode) + }else { + parent = domUtils.removeUnwantedNodes(targetNode, shouldRemove) + } if(isCollapsibleContainer(parent)) { return mergeChildrenIntoParent(parent) } @@ -10611,7 +11153,7 @@ ops.OpRemoveText = function OpRemoveText() { this.mergeChildrenIntoParent = mergeChildrenIntoParent } function mergeParagraphs(first, second, collapseRules) { - var child, mergeForward, destination = first, source = second, secondParent, insertionPoint; + var child, mergeForward = false, destination = first, source = second, secondParent, insertionPoint = null; if(collapseRules.isEmpty(first)) { mergeForward = true; if(second.parentNode !== first.parentNode) { @@ -10643,7 +11185,7 @@ ops.OpRemoveText = function OpRemoveText() { while(remainingLength && iterator.nextPosition()) { endContainer = iterator.container(); endOffset = iterator.unfilteredDomOffset(); - if(filter.acceptPosition(iterator) === NodeFilter.FILTER_ACCEPT) { + if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { remainingLength -= 1 } } @@ -10653,13 +11195,13 @@ ops.OpRemoveText = function OpRemoveText() { return range } this.execute = function(odtDocument) { - var paragraphElement, destinationParagraph, range, textNodes, paragraphs, collapseRules = new CollapsingRules(odtDocument.getRootNode()); + var paragraphElement, destinationParagraph, range, textNodes, paragraphs, cursor = odtDocument.getCursor(memberid), collapseRules = new CollapsingRules(odtDocument.getRootNode()); odtDocument.upgradeWhitespacesAtPosition(position); odtDocument.upgradeWhitespacesAtPosition(position + length); range = stepsToRange(odtDocument); paragraphElement = odtDocument.getParagraphElement(range.startContainer); - textNodes = odtDocument.getTextElements(range, true); - paragraphs = odtDocument.getParagraphElements(range); + textNodes = odfUtils.getTextElements(range, false, true); + paragraphs = odfUtils.getParagraphElements(range); range.detach(); textNodes.forEach(function(element) { collapseRules.mergeChildrenIntoParent(element) @@ -10671,12 +11213,15 @@ ops.OpRemoveText = function OpRemoveText() { odtDocument.fixCursorPositions(); odtDocument.getOdfCanvas().refreshSize(); odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:destinationParagraph || paragraphElement, memberId:memberid, timeStamp:timestamp}); - odtDocument.emit(ops.OdtDocument.signalCursorMoved, odtDocument.getCursor(memberid)); + if(cursor) { + cursor.resetSelectionType(); + odtDocument.emit(ops.OdtDocument.signalCursorMoved, cursor) + } odtDocument.getOdfCanvas().rerenderAnnotations(); return true }; this.spec = function() { - return{optype:optype, memberid:memberid, timestamp:timestamp, position:position, length:length} + return{optype:"RemoveText", memberid:memberid, timestamp:timestamp, position:position, length:length} } }; /* @@ -10691,6 +11236,9 @@ ops.OpRemoveText = function OpRemoveText() { 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 @@ -10711,57 +11259,15 @@ ops.OpRemoveText = function OpRemoveText() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.OpSplitParagraph = function OpSplitParagraph() { - var self = this, optype = "SplitParagraph", memberid, timestamp, position, odfUtils = new odf.OdfUtils; + var memberid, timestamp, position, odfUtils; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; - position = parseInt(data.position, 10) - }; - this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, result = [self]; - switch(otherOptype) { - case optype: - if(otherOpspec.position < position) { - position += 1 - }else { - if(otherOpspec.position === position && !hasPriority) { - position += 1; - result = null - } - } - break; - case "AddAnnotation": - if(otherOpspec.position < position) { - position += 1 - } - break; - case "InsertText": - if(otherOpspec.position < position) { - position += otherOpspec.text.length - }else { - if(otherOpspec.position === position && !hasPriority) { - position += otherOpspec.text.length; - result = null - } - } - break; - case "InsertTable": - result = null; - break; - case "RemoveText": - if(otherOpspec.position + otherOpspec.length <= position) { - position -= otherOpspec.length - }else { - if(otherOpspec.position < position) { - position = otherOpspec.position - } - } - break - } - return result + position = data.position; + odfUtils = new odf.OdfUtils }; this.execute = function(odtDocument) { var domPosition, paragraphNode, targetNode, node, splitNode, splitChildNode, keptChildNode; @@ -10816,7 +11322,7 @@ ops.OpSplitParagraph = function OpSplitParagraph() { if(domPosition.textNode.length === 0) { domPosition.textNode.parentNode.removeChild(domPosition.textNode) } - odtDocument.fixCursorPositions(memberid); + odtDocument.fixCursorPositions(); odtDocument.getOdfCanvas().refreshSize(); odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:paragraphNode, memberId:memberid, timeStamp:timestamp}); odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:splitChildNode, memberId:memberid, timeStamp:timestamp}); @@ -10824,7 +11330,7 @@ ops.OpSplitParagraph = function OpSplitParagraph() { return true }; this.spec = function() { - return{optype:optype, memberid:memberid, timestamp:timestamp, position:position} + return{optype:"SplitParagraph", memberid:memberid, timestamp:timestamp, position:position} } }; /* @@ -10839,6 +11345,9 @@ ops.OpSplitParagraph = function OpSplitParagraph() { 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 @@ -10859,27 +11368,16 @@ ops.OpSplitParagraph = function OpSplitParagraph() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.OpSetParagraphStyle = function OpSetParagraphStyle() { - var self = this, optype = "SetParagraphStyle", memberid, timestamp, position, styleName, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; + var memberid, timestamp, position, styleName, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; position = data.position; styleName = data.styleName }; - this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), otherOpType = otherOpspec.optype, result = [self]; - switch(otherOpType) { - case "RemoveStyle": - if(otherOpspec.styleName === styleName && otherOpspec.styleFamily === "paragraph") { - styleName = "" - } - break - } - return result - }; this.execute = function(odtDocument) { var iterator, paragraphNode; iterator = odtDocument.getIteratorAtPosition(position); @@ -10898,7 +11396,7 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() { return false }; this.spec = function() { - return{optype:optype, memberid:memberid, timestamp:timestamp, position:position, styleName:styleName} + return{optype:"SetParagraphStyle", memberid:memberid, timestamp:timestamp, position:position, styleName:styleName} } }; /* @@ -10913,6 +11411,9 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() { 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 @@ -10933,11 +11434,11 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.Namespaces"); ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { - var self = this, optype = "UpdateParagraphStyle", memberid, timestamp, styleName, setProperties, removedProperties, paragraphPropertiesName = "style:paragraph-properties", textPropertiesName = "style:text-properties", stylens = odf.Namespaces.stylens; + var memberid, timestamp, styleName, setProperties, removedProperties, paragraphPropertiesName = "style:paragraph-properties", textPropertiesName = "style:text-properties", stylens = odf.Namespaces.stylens; function removedAttributesFromStyleNode(node, removedAttributeNames) { var i, attributeNameParts, attributeNameList = removedAttributeNames ? removedAttributeNames.split(",") : []; for(i = 0;i < attributeNameList.length;i += 1) { @@ -10945,73 +11446,6 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { node.removeAttributeNS(odf.Namespaces.resolvePrefix(attributeNameParts[0]), attributeNameParts[1]) } } - function dropShadowedAttributes(properties, removedProperties, shadowingProperties, shadowingRemovedProperties) { - var value, i, name, removedPropertyNames, shadowingRemovedPropertyNames = shadowingRemovedProperties && shadowingRemovedProperties.attributes ? shadowingRemovedProperties.attributes.split(",") : []; - if(properties && (shadowingProperties || shadowingRemovedPropertyNames.length > 0)) { - Object.keys(properties).forEach(function(key) { - value = properties[key]; - if(shadowingProperties && shadowingProperties[key] !== undefined || shadowingRemovedPropertyNames && shadowingRemovedPropertyNames.indexOf(key) !== -1) { - if(typeof value !== "object") { - delete properties[key] - } - } - }) - } - if(removedProperties && removedProperties.attributes && (shadowingProperties || shadowingRemovedPropertyNames.length > 0)) { - removedPropertyNames = removedProperties.attributes.split(","); - for(i = 0;i < removedPropertyNames.length;i += 1) { - name = removedPropertyNames[i]; - if(shadowingProperties && shadowingProperties[name] !== undefined || shadowingRemovedPropertyNames && shadowingRemovedPropertyNames.indexOf(name) !== -1) { - removedPropertyNames.splice(i, 1); - i -= 1 - } - } - if(removedPropertyNames.length > 0) { - removedProperties.attributes = removedPropertyNames.join(",") - }else { - delete removedProperties.attributes - } - } - } - function hasProperties(properties) { - var key; - for(key in properties) { - if(properties.hasOwnProperty(key)) { - return true - } - } - return false - } - function hasRemovedProperties(properties) { - var key; - for(key in properties) { - if(properties.hasOwnProperty(key)) { - if(key !== "attributes" || properties.attributes.length > 0) { - return true - } - } - } - return false - } - function dropShadowedProperties(otherOpspec, propertiesName) { - var sp = setProperties ? setProperties[propertiesName] : null, rp = removedProperties ? removedProperties[propertiesName] : null; - dropShadowedAttributes(sp, rp, otherOpspec.setProperties ? otherOpspec.setProperties[propertiesName] : null, otherOpspec.removedProperties ? otherOpspec.removedProperties[propertiesName] : null); - if(sp && !hasProperties(sp)) { - delete setProperties[propertiesName] - } - if(rp && !hasRemovedProperties(rp)) { - delete removedProperties[propertiesName] - } - } - function dropStyleReferencingAttributes(deletedStyleName) { - if(setProperties) { - ["style:parent-style-name", "style:next-style-name"].forEach(function(attributeName) { - if(setProperties[attributeName] === deletedStyleName) { - delete setProperties[attributeName] - } - }) - } - } this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; @@ -11019,33 +11453,6 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { setProperties = data.setProperties; removedProperties = data.removedProperties }; - this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), otherOpType = otherOpspec.optype, result = [self]; - switch(otherOpType) { - case optype: - if(otherOpspec.styleName === styleName) { - if(!hasPriority) { - dropShadowedProperties(otherOpspec, paragraphPropertiesName); - dropShadowedProperties(otherOpspec, textPropertiesName); - dropShadowedAttributes(setProperties || null, removedProperties || null, otherOpspec.setProperties || null, otherOpspec.removedProperties || null); - if(!(setProperties && hasProperties(setProperties)) && !(removedProperties && hasRemovedProperties(removedProperties))) { - result = [] - } - } - } - break; - case "RemoveStyle": - if(otherOpspec.styleFamily === "paragraph") { - if(otherOpspec.styleName === styleName) { - result = [] - }else { - dropStyleReferencingAttributes(otherOpspec.styleName) - } - } - break - } - return result - }; this.execute = function(odtDocument) { var formatting = odtDocument.getFormatting(), styleNode, paragraphPropertiesNode, textPropertiesNode; if(styleName !== "") { @@ -11082,7 +11489,7 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { return false }; this.spec = function() { - return{optype:optype, memberid:memberid, timestamp:timestamp, styleName:styleName, setProperties:setProperties, removedProperties:removedProperties} + return{optype:"UpdateParagraphStyle", memberid:memberid, timestamp:timestamp, styleName:styleName, setProperties:setProperties, removedProperties:removedProperties} } }; /* @@ -11097,6 +11504,9 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { 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 @@ -11117,11 +11527,11 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.Namespaces"); ops.OpAddStyle = function OpAddStyle() { - var self = this, memberid, timestamp, styleName, styleFamily, isAutomaticStyle, setProperties, stylens = odf.Namespaces.stylens; + var memberid, timestamp, styleName, styleFamily, isAutomaticStyle, setProperties, stylens = odf.Namespaces.stylens; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; @@ -11130,22 +11540,6 @@ ops.OpAddStyle = function OpAddStyle() { isAutomaticStyle = data.isAutomaticStyle === "true" || data.isAutomaticStyle === true; setProperties = data.setProperties }; - function dropStyleReferencingAttributes(deletedStyleName) { - if(setProperties) { - ["style:parent-style-name", "style:next-style-name"].forEach(function(attributeName) { - if(setProperties[attributeName] === deletedStyleName) { - delete setProperties[attributeName] - } - }) - } - } - this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(); - if(otherOpspec.optype === "RemoveStyle" && otherOpspec.styleFamily === styleFamily) { - dropStyleReferencingAttributes(otherOpspec.styleName) - } - return[self] - }; this.execute = function(odtDocument) { var odfContainer = odtDocument.getOdfCanvas().odfContainer(), formatting = odtDocument.getFormatting(), dom = odtDocument.getDOM(), styleNode = dom.createElementNS(stylens, "style:style"); if(!styleNode) { @@ -11183,6 +11577,9 @@ ops.OpAddStyle = function OpAddStyle() { 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 @@ -11203,66 +11600,16 @@ ops.OpAddStyle = function OpAddStyle() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.OpRemoveStyle = function OpRemoveStyle() { - var self = this, optype = "RemoveStyle", memberid, timestamp, styleName, styleFamily; + var memberid, timestamp, styleName, styleFamily; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; styleName = data.styleName; styleFamily = data.styleFamily }; - function getStyleReferencingAttributes(setProperties) { - var attributes = []; - if(setProperties) { - ["style:parent-style-name", "style:next-style-name"].forEach(function(attributeName) { - if(setProperties[attributeName] === styleName) { - attributes.push(attributeName) - } - }) - } - return attributes - } - this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), otherOpType = otherOpspec.optype, helperOp, setAttributes, result = [self]; - switch(otherOpType) { - case optype: - if(otherOpspec.styleName === styleName && otherOpspec.styleFamily === styleFamily) { - result = [] - } - break; - case "UpdateParagraphStyle": - if(styleFamily === "paragraph") { - setAttributes = getStyleReferencingAttributes(otherOpspec.setProperties); - if(setAttributes.length > 0) { - helperOp = new ops.OpUpdateParagraphStyle; - helperOp.init({memberid:memberid, timestamp:timestamp, styleName:otherOpspec.styleName, removedProperties:{attributes:setAttributes.join(",")}}); - result = [helperOp, self] - } - } - break; - case "AddStyle": - if(otherOpspec.styleFamily === styleFamily) { - setAttributes = getStyleReferencingAttributes(otherOpspec.setProperties); - if(setAttributes.length > 0) { - helperOp = new ops.OpUpdateParagraphStyle; - helperOp.init({memberid:memberid, timestamp:timestamp, styleName:otherOpspec.styleName, removedProperties:{attributes:setAttributes.join(",")}}); - result = [helperOp, self] - } - } - break; - case "SetParagraphStyle": - if(styleFamily === "paragraph" && otherOpspec.styleName === styleName) { - otherOpspec.styleName = ""; - helperOp = new ops.OpSetParagraphStyle; - helperOp.init(otherOpspec); - result = [helperOp, self] - } - break - } - return result - }; this.execute = function(odtDocument) { var styleNode = odtDocument.getStyleElement(styleName, styleFamily); if(!styleNode) { @@ -11274,7 +11621,7 @@ ops.OpRemoveStyle = function OpRemoveStyle() { return true }; this.spec = function() { - return{optype:optype, memberid:memberid, timestamp:timestamp, styleName:styleName, styleFamily:styleFamily} + return{optype:"RemoveStyle", memberid:memberid, timestamp:timestamp, styleName:styleName, styleFamily:styleFamily} } }; /* @@ -11289,6 +11636,9 @@ ops.OpRemoveStyle = function OpRemoveStyle() { 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 @@ -11309,10 +11659,10 @@ ops.OpRemoveStyle = function OpRemoveStyle() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.OpAddAnnotation = function OpAddAnnotation() { - var self = this, optype = "AddAnnotation", memberid, timestamp, position, length, name; + var memberid, timestamp, position, length, name; this.init = function(data) { memberid = data.memberid; timestamp = parseInt(data.timestamp, 10); @@ -11320,58 +11670,12 @@ ops.OpAddAnnotation = function OpAddAnnotation() { length = parseInt(data.length, 10) || 0; name = data.name }; - this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, end = position + length, result = [self]; - switch(otherOptype) { - case optype: - if(otherOpspec.position < position) { - position += 1 - }else { - if(otherOpspec.position === position && !hasPriority) { - position += 1; - result = null - } - } - break; - case "InsertText": - if(otherOpspec.position <= position) { - position += otherOpspec.text.length - }else { - if(otherOpspec.position <= end) { - length += otherOpspec.text.length - } - } - break; - case "SplitParagraph": - if(otherOpspec.position <= position) { - position += 1 - }else { - if(otherOpspec.position <= end) { - length += 1 - } - } - break; - case "InsertTable": - result = null; - break; - case "RemoveText": - if(otherOpspec.position + otherOpspec.length <= position) { - position -= otherOpspec.length - }else { - if(otherOpspec.position < position) { - position = otherOpspec.position - } - } - break - } - return result - }; 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(odf.Namespaces.webodfns + ":names:editinfo", "editinfo:memberid", memberid); + creatorNode.setAttributeNS("urn:webodf:names:editinfo", "editinfo:memberid", memberid); dateNode = doc.createElementNS(odf.Namespaces.dcns, "dc:date"); dateNode.appendChild(doc.createTextNode(date.toISOString())); listNode = doc.createElementNS(odf.Namespaces.textns, "text:list"); @@ -11404,15 +11708,6 @@ ops.OpAddAnnotation = function OpAddAnnotation() { } } } - function countSteps(number, stepCounter, positionFilter) { - if(number > 0) { - return stepCounter.countForwardSteps(number, positionFilter) - } - if(number < 0) { - return-stepCounter.countBackwardSteps(-number, positionFilter) - } - return 0 - } this.execute = function(odtDocument) { var annotation = {}, positionFilter = odtDocument.getPositionFilter(), cursor = odtDocument.getCursor(memberid), oldCursorPosition = odtDocument.getCursorPosition(memberid), lengthToMove = position - oldCursorPosition - 1, stepsToParagraph; annotation.node = createAnnotationNode(odtDocument, new Date(timestamp)); @@ -11428,15 +11723,17 @@ ops.OpAddAnnotation = function OpAddAnnotation() { } insertNodeAtPosition(odtDocument, annotation.node, position); if(cursor) { - stepsToParagraph = countSteps(lengthToMove, cursor.getStepCounter(), positionFilter); + stepsToParagraph = cursor.getStepCounter().countSteps(lengthToMove, positionFilter); cursor.move(stepsToParagraph); + cursor.resetSelectionType(); odtDocument.emit(ops.OdtDocument.signalCursorMoved, cursor) } odtDocument.getOdfCanvas().addAnnotation(annotation); + odtDocument.fixCursorPositions(); return true }; this.spec = function() { - return{optype:optype, memberid:memberid, timestamp:timestamp, position:position, length:length, name:name} + return{optype:"AddAnnotation", memberid:memberid, timestamp:timestamp, position:position, length:length, name:name} } }; /* @@ -11451,6 +11748,9 @@ ops.OpAddAnnotation = function OpAddAnnotation() { 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 @@ -11471,7 +11771,7 @@ ops.OpAddAnnotation = function OpAddAnnotation() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.Namespaces"); runtime.loadClass("core.DomUtils"); @@ -11484,9 +11784,6 @@ ops.OpRemoveAnnotation = function OpRemoveAnnotation() { length = parseInt(data.length, 10); domUtils = new core.DomUtils }; - this.transform = function(otherOp, hasPriority) { - return null - }; this.execute = function(odtDocument) { var iterator = odtDocument.getIteratorAtPosition(position), container = iterator.container(), annotationName, annotationNode = null, annotationEnd = null, cursors; while(!(container.namespaceURI === odf.Namespaces.officens && container.localName === "annotation")) { @@ -11503,7 +11800,7 @@ ops.OpRemoveAnnotation = function OpRemoveAnnotation() { })[0] || null } odtDocument.getOdfCanvas().forgetAnnotations(); - cursors = domUtils.getElementsByTagNameNS(annotationNode, odf.Namespaces.webodfns + ":names:cursor", "cursor"); + cursors = domUtils.getElementsByTagNameNS(annotationNode, "urn:webodf:names:cursor", "cursor"); while(cursors.length) { annotationNode.parentNode.insertBefore(cursors.pop(), annotationNode) } @@ -11531,6 +11828,9 @@ ops.OpRemoveAnnotation = function OpRemoveAnnotation() { 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 @@ -11551,12 +11851,15 @@ ops.OpRemoveAnnotation = function OpRemoveAnnotation() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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"); @@ -11586,11 +11889,48 @@ ops.OperationFactory = function OperationFactory() { } } function init() { - specs = {AddCursor:constructor(ops.OpAddCursor), ApplyDirectStyling:constructor(ops.OpApplyDirectStyling), 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 = {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)} } init() }; +/* + + 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/ +*/ runtime.loadClass("core.Cursor"); runtime.loadClass("core.DomUtils"); runtime.loadClass("core.PositionIterator"); @@ -11649,8 +11989,8 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { runtime.assert(Boolean(rectangle), "No visible rectangle found"); return(rectangle) } - function doMove(steps, extend, move) { - var left = steps, iterator = getIteratorAtCursor(), initialRect, range = (rootNode.ownerDocument.createRange()), selectionRange = cursor.getSelectedRange() ? cursor.getSelectedRange().cloneRange() : rootNode.ownerDocument.createRange(), newRect, horizontalMovement, o, c, isForwardSelection, window = runtime.getWindow(); + function doMove(positions, extend, move) { + var left = positions, iterator = getIteratorAtCursor(), initialRect, range = (rootNode.ownerDocument.createRange()), selectionRange = cursor.getSelectedRange() ? cursor.getSelectedRange().cloneRange() : rootNode.ownerDocument.createRange(), newRect, horizontalMovement, o, c, isForwardSelection; initialRect = getVisibleRect(iterator.container(), iterator.unfilteredDomOffset(), range); while(left > 0 && move()) { left -= 1 @@ -11675,92 +12015,90 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { if(horizontalMovement || cachedXOffset === undefined) { cachedXOffset = newRect.left } - window.clearTimeout(timeoutHandle); - timeoutHandle = window.setTimeout(function() { + runtime.clearTimeout(timeoutHandle); + timeoutHandle = runtime.setTimeout(function() { cachedXOffset = undefined }, 2E3); range.detach(); - return steps - left + return positions - left } - this.movePointForward = function(steps, extend) { - return doMove(steps, extend, positionIterator.nextPosition) + this.movePointForward = function(positions, extend) { + return doMove(positions, extend || false, positionIterator.nextPosition) }; - this.movePointBackward = function(steps, extend) { - return doMove(steps, extend, positionIterator.previousPosition) + this.movePointBackward = function(positions, extend) { + return doMove(positions, extend || false, positionIterator.previousPosition) }; function isPositionWalkable(filter) { var iterator = getIteratorAtCursor(); if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { - return true + iterator.setUnfilteredPosition(cursor.getAnchorNode(), 0); + if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { + return true + } } return false } - function countForwardSteps(steps, filter) { - var iterator = getIteratorAtCursor(), watch = new core.LoopWatchDog(1E3), stepCount = 0, count = 0; - while(steps > 0 && iterator.nextPosition()) { - stepCount += 1; + function countSteps(iterator, steps, filter) { + var watch = new core.LoopWatchDog(1E3), positions = 0, positionsCount = 0, increment = steps >= 0 ? 1 : -1, delegate = (steps >= 0 ? iterator.nextPosition : iterator.previousPosition); + while(steps !== 0 && delegate()) { watch.check(); + positionsCount += increment; if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { - count += stepCount; - stepCount = 0; - steps -= 1 + steps -= increment; + positions += positionsCount; + positionsCount = 0 } } - return count + return positions } - function convertForwardStepsBetweenFilters(steps, filter1, filter2) { - var iterator = getIteratorAtCursor(), watch = new core.LoopWatchDog(1E3), stepCount = 0, count = 0; - while(steps > 0 && iterator.nextPosition()) { + function convertForwardStepsBetweenFilters(stepsFilter1, filter1, filter2) { + var iterator = getIteratorAtCursor(), watch = new core.LoopWatchDog(1E3), pendingStepsFilter2 = 0, stepsFilter2 = 0; + while(stepsFilter1 > 0 && iterator.nextPosition()) { watch.check(); if(filter2.acceptPosition(iterator) === FILTER_ACCEPT) { - stepCount += 1; + pendingStepsFilter2 += 1; if(filter1.acceptPosition(iterator) === FILTER_ACCEPT) { - count += stepCount; - stepCount = 0; - steps -= 1 + stepsFilter2 += pendingStepsFilter2; + pendingStepsFilter2 = 0; + stepsFilter1 -= 1 } } } - return count + return stepsFilter2 } - function convertBackwardStepsBetweenFilters(steps, filter1, filter2) { - var iterator = getIteratorAtCursor(), watch = new core.LoopWatchDog(1E3), stepCount = 0, count = 0; - while(steps > 0 && iterator.previousPosition()) { + function convertBackwardStepsBetweenFilters(stepsFilter1, filter1, filter2) { + var iterator = getIteratorAtCursor(), watch = new core.LoopWatchDog(1E3), pendingStepsFilter2 = 0, stepsFilter2 = 0; + while(stepsFilter1 > 0 && iterator.previousPosition()) { watch.check(); if(filter2.acceptPosition(iterator) === FILTER_ACCEPT) { - stepCount += 1; + pendingStepsFilter2 += 1; if(filter1.acceptPosition(iterator) === FILTER_ACCEPT) { - count += stepCount; - stepCount = 0; - steps -= 1 + stepsFilter2 += pendingStepsFilter2; + pendingStepsFilter2 = 0; + stepsFilter1 -= 1 } } } - return count + return stepsFilter2 } - function countBackwardSteps(steps, filter) { - var iterator = getIteratorAtCursor(), watch = new core.LoopWatchDog(1E3), stepCount = 0, count = 0; - while(steps > 0 && iterator.previousPosition()) { - stepCount += 1; - watch.check(); - if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { - count += stepCount; - stepCount = 0; - steps -= 1 - } - } - return count + function countStepsPublic(steps, filter) { + var iterator = getIteratorAtCursor(); + return countSteps(iterator, steps, filter) } - function countStepsToValidPosition(filter) { - var iterator = getIteratorAtCursor(), paragraphNode = odfUtils.getParagraphElement(iterator.getCurrentNode()), count; - count = -countBackwardSteps(1, filter); - if(count === 0 || paragraphNode && paragraphNode !== odfUtils.getParagraphElement(iterator.getCurrentNode())) { - count = countForwardSteps(1, filter) + function countPositionsToClosestStep(container, offset, filter) { + var iterator = getIteratorAtCursor(), paragraphNode = odfUtils.getParagraphElement(iterator.getCurrentNode()), count = 0; + iterator.setUnfilteredPosition(container, offset); + if(filter.acceptPosition(iterator) !== FILTER_ACCEPT) { + count = countSteps(iterator, -1, filter); + if(count === 0 || paragraphNode && paragraphNode !== odfUtils.getParagraphElement(iterator.getCurrentNode())) { + iterator.setUnfilteredPosition(container, offset); + count = countSteps(iterator, 1, filter) + } } return count } function countLineSteps(filter, direction, iterator) { - var c = iterator.container(), count = 0, bestContainer = null, bestOffset, bestXDiff = 10, xDiff, bestCount = 0, top, left, lastTop, rect, range = (rootNode.ownerDocument.createRange()), watch = new core.LoopWatchDog(1E3); + var c = iterator.container(), steps = 0, bestContainer = null, bestOffset, bestXDiff = 10, xDiff, bestCount = 0, top, left, lastTop, rect, range = (rootNode.ownerDocument.createRange()), watch = new core.LoopWatchDog(1E3); rect = getVisibleRect(c, iterator.unfilteredDomOffset(), range); top = rect.top; if(cachedXOffset === undefined) { @@ -11772,7 +12110,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { while((direction < 0 ? iterator.previousPosition() : iterator.nextPosition()) === true) { watch.check(); if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { - count += 1; + steps += 1; c = iterator.container(); rect = getVisibleRect(c, iterator.unfilteredDomOffset(), range); if(rect.top !== top) { @@ -11785,35 +12123,35 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { bestContainer = c; bestOffset = iterator.unfilteredDomOffset(); bestXDiff = xDiff; - bestCount = count + bestCount = steps } } } } if(bestContainer !== null) { iterator.setUnfilteredPosition(bestContainer, (bestOffset)); - count = bestCount + steps = bestCount }else { - count = 0 + steps = 0 } range.detach(); - return count + return steps } function countLinesSteps(lines, filter) { - var iterator = getIteratorAtCursor(), stepCount = 0, count = 0, direction = lines < 0 ? -1 : 1; + var iterator = getIteratorAtCursor(), stepCount = 0, steps = 0, direction = lines < 0 ? -1 : 1; lines = Math.abs(lines); while(lines > 0) { stepCount += countLineSteps(filter, direction, iterator); if(stepCount === 0) { break } - count += stepCount; + steps += stepCount; lines -= 1 } - return count * direction + return steps * direction } function countStepsToLineBoundary(direction, filter) { - var fnNextPos, increment, lastRect, rect, onSameLine, iterator = getIteratorAtCursor(), paragraphNode = odfUtils.getParagraphElement(iterator.getCurrentNode()), count = 0, range = (rootNode.ownerDocument.createRange()); + var fnNextPos, increment, lastRect, rect, onSameLine, iterator = getIteratorAtCursor(), paragraphNode = odfUtils.getParagraphElement(iterator.getCurrentNode()), steps = 0, range = (rootNode.ownerDocument.createRange()); if(direction < 0) { fnNextPos = iterator.previousPosition; increment = -1 @@ -11834,21 +12172,27 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { break } } - count += increment; + steps += increment; lastRect = rect } } range.detach(); - return count + return steps } function countStepsToPosition(targetNode, targetOffset, filter) { runtime.assert(targetNode !== null, "SelectionMover.countStepsToPosition called with element===null"); var iterator = getIteratorAtCursor(), c = iterator.container(), o = iterator.unfilteredDomOffset(), steps = 0, watch = new core.LoopWatchDog(1E3), comparison; iterator.setUnfilteredPosition(targetNode, targetOffset); + while(filter.acceptPosition(iterator) !== FILTER_ACCEPT && iterator.previousPosition()) { + watch.check() + } targetNode = iterator.container(); runtime.assert(Boolean(targetNode), "SelectionMover.countStepsToPosition: positionIterator.container() returned null"); targetOffset = iterator.unfilteredDomOffset(); iterator.setUnfilteredPosition(c, o); + while(filter.acceptPosition(iterator) !== FILTER_ACCEPT && iterator.previousPosition()) { + watch.check() + } comparison = domUtils.comparePoints(targetNode, targetOffset, iterator.container(), iterator.unfilteredDomOffset()); if(comparison < 0) { while(iterator.nextPosition()) { @@ -11856,10 +12200,8 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { steps += 1 } - if(iterator.container() === targetNode) { - if(iterator.unfilteredDomOffset() === targetOffset) { - return steps - } + if(iterator.container() === targetNode && iterator.unfilteredDomOffset() === targetOffset) { + return steps } } }else { @@ -11868,7 +12210,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { watch.check(); if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { steps -= 1; - if(domUtils.comparePoints(targetNode, targetOffset, iterator.container(), iterator.unfilteredDomOffset()) <= 0) { + if(iterator.container() === targetNode && iterator.unfilteredDomOffset() === targetOffset) { break } } @@ -11878,7 +12220,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { return steps } this.getStepCounter = function() { - return{countForwardSteps:countForwardSteps, countBackwardSteps:countBackwardSteps, convertForwardStepsBetweenFilters:convertForwardStepsBetweenFilters, convertBackwardStepsBetweenFilters:convertBackwardStepsBetweenFilters, countLinesSteps:countLinesSteps, countStepsToLineBoundary:countStepsToLineBoundary, countStepsToPosition:countStepsToPosition, isPositionWalkable:isPositionWalkable, countStepsToValidPosition:countStepsToValidPosition} + return{countSteps:countStepsPublic, convertForwardStepsBetweenFilters:convertForwardStepsBetweenFilters, convertBackwardStepsBetweenFilters:convertBackwardStepsBetweenFilters, countLinesSteps:countLinesSteps, countStepsToLineBoundary:countStepsToLineBoundary, countStepsToPosition:countStepsToPosition, isPositionWalkable:isPositionWalkable, countPositionsToNearestStep:countPositionsToClosestStep} }; function init() { odfUtils = new odf.OdfUtils; @@ -11911,119 +12253,490 @@ gui.SelectionMover.createPositionIterator = function(rootNode) { 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. - 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: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.OpAddCursor"); -runtime.loadClass("ops.OpRemoveCursor"); -runtime.loadClass("ops.OpMoveCursor"); -runtime.loadClass("ops.OpInsertTable"); -runtime.loadClass("ops.OpInsertText"); -runtime.loadClass("ops.OpRemoveText"); -runtime.loadClass("ops.OpSplitParagraph"); -runtime.loadClass("ops.OpSetParagraphStyle"); -runtime.loadClass("ops.OpAddStyle"); -runtime.loadClass("ops.OpUpdateParagraphStyle"); -runtime.loadClass("ops.OpRemoveStyle"); -ops.OperationTransformer = function OperationTransformer() { - var operationFactory; - function transformOpVsOp(opA, opB) { - var oldOpB, opATransformResult, opBTransformResult; +ops.OperationTransformMatrix = function OperationTransformMatrix() { + function passUnchanged(opSpecA, opSpecB) { + return{opSpecsA:[opSpecA], opSpecsB:[opSpecB]} + } + function getStyleReferencingAttributes(setProperties, styleName) { + var attributes = []; + if(setProperties) { + ["style:parent-style-name", "style:next-style-name"].forEach(function(attributeName) { + if(setProperties[attributeName] === styleName) { + attributes.push(attributeName) + } + }) + } + return attributes + } + function dropStyleReferencingAttributes(setProperties, deletedStyleName) { + if(setProperties) { + ["style:parent-style-name", "style:next-style-name"].forEach(function(attributeName) { + if(setProperties[attributeName] === deletedStyleName) { + delete setProperties[attributeName] + } + }) + } + } + function transformAddStyleRemoveStyle(addStyleSpec, removeStyleSpec) { + var setAttributes, helperOpspec, addStyleSpecResult = [addStyleSpec], removeStyleSpecResult = [removeStyleSpec]; + if(addStyleSpec.styleFamily === removeStyleSpec.styleFamily) { + setAttributes = getStyleReferencingAttributes(addStyleSpec.setProperties, removeStyleSpec.styleName); + if(setAttributes.length > 0) { + helperOpspec = {optype:"UpdateParagraphStyle", memberid:removeStyleSpec.memberid, timestamp:removeStyleSpec.timestamp, styleName:addStyleSpec.styleName, removedProperties:{attributes:setAttributes.join(",")}}; + removeStyleSpecResult.unshift(helperOpspec) + } + dropStyleReferencingAttributes(addStyleSpec.setProperties, removeStyleSpec.styleName) + } + return{opSpecsA:addStyleSpecResult, opSpecsB:removeStyleSpecResult} + } + function transformInsertTextInsertText(insertTextSpecA, insertTextSpecB, hasAPriority) { + if(insertTextSpecA.position < insertTextSpecB.position) { + insertTextSpecB.position += insertTextSpecA.text.length + }else { + if(insertTextSpecA.position > insertTextSpecB.position) { + insertTextSpecA.position += insertTextSpecB.text.length + }else { + if(hasAPriority) { + insertTextSpecB.position += insertTextSpecA.text.length + }else { + insertTextSpecA.position += insertTextSpecB.text.length + } + return null + } + } + return{opSpecsA:[insertTextSpecA], opSpecsB:[insertTextSpecB]} + } + function transformInsertTextMoveCursor(insertTextSpec, moveCursorSpec) { + if(insertTextSpec.position < moveCursorSpec.position) { + moveCursorSpec.position += insertTextSpec.text.length + }else { + if(insertTextSpec.position <= moveCursorSpec.position + moveCursorSpec.length) { + moveCursorSpec.length += insertTextSpec.text.length + } + } + return{opSpecsA:[insertTextSpec], opSpecsB:[moveCursorSpec]} + } + function transformInsertTextRemoveText(insertTextSpec, removeTextSpec) { + var helperOpspec, removeTextSpecEnd = removeTextSpec.position + removeTextSpec.length, insertTextSpecResult = [insertTextSpec], removeTextSpecResult = [removeTextSpec]; + if(removeTextSpecEnd <= insertTextSpec.position) { + insertTextSpec.position -= removeTextSpec.length + }else { + if(insertTextSpec.position <= removeTextSpec.position) { + removeTextSpec.position += insertTextSpec.text.length + }else { + removeTextSpec.length = insertTextSpec.position - removeTextSpec.position; + helperOpspec = {optype:"RemoveText", memberid:removeTextSpec.memberid, timestamp:removeTextSpec.timestamp, position:insertTextSpec.position + insertTextSpec.text.length, length:removeTextSpecEnd - insertTextSpec.position}; + removeTextSpecResult.unshift(helperOpspec); + insertTextSpec.position = removeTextSpec.position + } + } + return{opSpecsA:insertTextSpecResult, opSpecsB:removeTextSpecResult} + } + function transformInsertTextSplitParagraph(insertTextSpec, splitParagraphSpec, hasAPriority) { + if(insertTextSpec.position < splitParagraphSpec.position) { + splitParagraphSpec.position += insertTextSpec.text.length + }else { + if(insertTextSpec.position > splitParagraphSpec.position) { + insertTextSpec.position += 1 + }else { + if(hasAPriority) { + splitParagraphSpec.position += insertTextSpec.text.length + }else { + insertTextSpec.position += 1 + } + return null + } + } + return{opSpecsA:[insertTextSpec], opSpecsB:[splitParagraphSpec]} + } + function dropShadowedAttributes(properties, removedProperties, shadowingProperties, shadowingRemovedProperties) { + var value, i, name, removedPropertyNames, shadowingRemovedPropertyNames = shadowingRemovedProperties && shadowingRemovedProperties.attributes ? shadowingRemovedProperties.attributes.split(",") : []; + if(properties && (shadowingProperties || shadowingRemovedPropertyNames.length > 0)) { + Object.keys(properties).forEach(function(key) { + value = properties[key]; + if(shadowingProperties && shadowingProperties[key] !== undefined || shadowingRemovedPropertyNames && shadowingRemovedPropertyNames.indexOf(key) !== -1) { + if(typeof value !== "object") { + delete properties[key] + } + } + }) + } + if(removedProperties && (removedProperties.attributes && (shadowingProperties || shadowingRemovedPropertyNames.length > 0))) { + removedPropertyNames = removedProperties.attributes.split(","); + for(i = 0;i < removedPropertyNames.length;i += 1) { + name = removedPropertyNames[i]; + if(shadowingProperties && shadowingProperties[name] !== undefined || shadowingRemovedPropertyNames && shadowingRemovedPropertyNames.indexOf(name) !== -1) { + removedPropertyNames.splice(i, 1); + i -= 1 + } + } + if(removedPropertyNames.length > 0) { + removedProperties.attributes = removedPropertyNames.join(",") + }else { + delete removedProperties.attributes + } + } + } + function hasProperties(properties) { + var key; + for(key in properties) { + if(properties.hasOwnProperty(key)) { + return true + } + } + return false + } + function hasRemovedProperties(properties) { + var key; + for(key in properties) { + if(properties.hasOwnProperty(key)) { + if(key !== "attributes" || properties.attributes.length > 0) { + return true + } + } + } + return false + } + function dropShadowedProperties(targetOpspec, shadowingOpspec, propertiesName) { + var sp = targetOpspec.setProperties ? targetOpspec.setProperties[propertiesName] : null, rp = targetOpspec.removedProperties ? targetOpspec.removedProperties[propertiesName] : null; + dropShadowedAttributes(sp, rp, shadowingOpspec.setProperties ? shadowingOpspec.setProperties[propertiesName] : null, shadowingOpspec.removedProperties ? shadowingOpspec.removedProperties[propertiesName] : null); + if(sp && !hasProperties(sp)) { + delete targetOpspec.setProperties[propertiesName] + } + if(rp && !hasRemovedProperties(rp)) { + delete targetOpspec.removedProperties[propertiesName] + } + } + function transformUpdateParagraphStyleUpdateParagraphStyle(updateParagraphStyleSpecA, updateParagraphStyleSpecB, hasAPriority) { + var majorSpec, minorSpec, updateParagraphStyleSpecAResult = [updateParagraphStyleSpecA], updateParagraphStyleSpecBResult = [updateParagraphStyleSpecB]; + if(updateParagraphStyleSpecA.styleName === updateParagraphStyleSpecB.styleName) { + majorSpec = hasAPriority ? updateParagraphStyleSpecA : updateParagraphStyleSpecB; + minorSpec = hasAPriority ? updateParagraphStyleSpecB : updateParagraphStyleSpecA; + 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); + if(!(minorSpec.setProperties && hasProperties(minorSpec.setProperties)) && !(minorSpec.removedProperties && hasRemovedProperties(minorSpec.removedProperties))) { + if(hasAPriority) { + updateParagraphStyleSpecBResult = [] + }else { + updateParagraphStyleSpecAResult = [] + } + } + } + return{opSpecsA:updateParagraphStyleSpecAResult, opSpecsB:updateParagraphStyleSpecBResult} + } + function transformSplitParagraphSplitParagraph(splitParagraphSpecA, splitParagraphSpecB, hasAPriority) { + if(splitParagraphSpecA.position < splitParagraphSpecB.position) { + splitParagraphSpecB.position += 1 + }else { + if(splitParagraphSpecA.position > splitParagraphSpecB.position) { + splitParagraphSpecA.position += 1 + }else { + if(splitParagraphSpecA.position === splitParagraphSpecB.position) { + if(hasAPriority) { + splitParagraphSpecB.position += 1 + }else { + splitParagraphSpecA.position += 1 + } + return null + } + } + } + return{opSpecsA:[splitParagraphSpecA], opSpecsB:[splitParagraphSpecB]} + } + function transformMoveCursorRemoveCursor(moveCursorSpec, removeCursorSpec) { + var isSameCursorRemoved = moveCursorSpec.memberid === removeCursorSpec.memberid; + return{opSpecsA:isSameCursorRemoved ? [] : [moveCursorSpec], opSpecsB:[removeCursorSpec]} + } + function transformMoveCursorRemoveText(moveCursorSpec, removeTextSpec) { + var moveCursorSpecEnd = moveCursorSpec.position + moveCursorSpec.length, removeTextSpecEnd = removeTextSpec.position + removeTextSpec.length; + if(removeTextSpecEnd <= moveCursorSpec.position) { + moveCursorSpec.position -= removeTextSpec.length + }else { + if(removeTextSpec.position < moveCursorSpecEnd) { + if(moveCursorSpec.position < removeTextSpec.position) { + if(removeTextSpecEnd < moveCursorSpecEnd) { + moveCursorSpec.length -= removeTextSpec.length + }else { + moveCursorSpec.length = removeTextSpec.position - moveCursorSpec.position + } + }else { + moveCursorSpec.position = removeTextSpec.position; + if(removeTextSpecEnd < moveCursorSpecEnd) { + moveCursorSpec.length = moveCursorSpecEnd - removeTextSpecEnd + }else { + moveCursorSpec.length = 0 + } + } + } + } + return{opSpecsA:[moveCursorSpec], opSpecsB:[removeTextSpec]} + } + function transformMoveCursorSplitParagraph(moveCursorSpec, splitParagraphSpec) { + if(splitParagraphSpec.position < moveCursorSpec.position) { + moveCursorSpec.position += 1 + }else { + if(splitParagraphSpec.position <= moveCursorSpec.position + moveCursorSpec.length) { + moveCursorSpec.length += 1 + } + } + return{opSpecsA:[moveCursorSpec], opSpecsB:[splitParagraphSpec]} + } + function transformRemoveCursorRemoveCursor(removeCursorSpecA, removeCursorSpecB) { + var isSameMemberid = removeCursorSpecA.memberid === removeCursorSpecB.memberid; + return{opSpecsA:isSameMemberid ? [] : [removeCursorSpecA], opSpecsB:isSameMemberid ? [] : [removeCursorSpecB]} + } + function transformRemoveStyleRemoveStyle(removeStyleSpecA, removeStyleSpecB) { + var isSameStyle = removeStyleSpecA.styleName === removeStyleSpecB.styleName && removeStyleSpecA.styleFamily === removeStyleSpecB.styleFamily; + return{opSpecsA:isSameStyle ? [] : [removeStyleSpecA], opSpecsB:isSameStyle ? [] : [removeStyleSpecB]} + } + function transformRemoveStyleSetParagraphStyle(removeStyleSpec, setParagraphStyleSpec) { + var helperOpspec, removeStyleSpecResult = [removeStyleSpec], setParagraphStyleSpecResult = [setParagraphStyleSpec]; + if(removeStyleSpec.styleFamily === "paragraph" && removeStyleSpec.styleName === setParagraphStyleSpec.styleName) { + helperOpspec = {optype:"SetParagraphStyle", memberid:removeStyleSpec.memberid, timestamp:removeStyleSpec.timestamp, position:setParagraphStyleSpec.position, styleName:""}; + removeStyleSpecResult.unshift(helperOpspec); + setParagraphStyleSpec.styleName = "" + } + return{opSpecsA:removeStyleSpecResult, opSpecsB:setParagraphStyleSpecResult} + } + function transformRemoveStyleUpdateParagraphStyle(removeStyleSpec, updateParagraphStyleSpec) { + var setAttributes, helperOpspec, removeStyleSpecResult = [removeStyleSpec], updateParagraphStyleSpecResult = [updateParagraphStyleSpec]; + if(removeStyleSpec.styleFamily === "paragraph") { + setAttributes = getStyleReferencingAttributes(updateParagraphStyleSpec.setProperties, removeStyleSpec.styleName); + if(setAttributes.length > 0) { + helperOpspec = {optype:"UpdateParagraphStyle", memberid:removeStyleSpec.memberid, timestamp:removeStyleSpec.timestamp, styleName:updateParagraphStyleSpec.styleName, removedProperties:{attributes:setAttributes.join(",")}}; + removeStyleSpecResult.unshift(helperOpspec) + } + if(removeStyleSpec.styleName === updateParagraphStyleSpec.styleName) { + updateParagraphStyleSpecResult = [] + }else { + dropStyleReferencingAttributes(updateParagraphStyleSpec.setProperties, removeStyleSpec.styleName) + } + } + return{opSpecsA:removeStyleSpecResult, opSpecsB:updateParagraphStyleSpecResult} + } + function transformRemoveTextRemoveText(removeTextSpecA, removeTextSpecB) { + var removeTextSpecAEnd = removeTextSpecA.position + removeTextSpecA.length, removeTextSpecBEnd = removeTextSpecB.position + removeTextSpecB.length, removeTextSpecAResult = [removeTextSpecA], removeTextSpecBResult = [removeTextSpecB]; + if(removeTextSpecBEnd <= removeTextSpecA.position) { + removeTextSpecA.position -= removeTextSpecB.length + }else { + if(removeTextSpecAEnd <= removeTextSpecB.position) { + removeTextSpecB.position -= removeTextSpecA.length + }else { + if(removeTextSpecB.position < removeTextSpecAEnd) { + if(removeTextSpecA.position < removeTextSpecB.position) { + if(removeTextSpecBEnd < removeTextSpecAEnd) { + removeTextSpecA.length = removeTextSpecA.length - removeTextSpecB.length + }else { + removeTextSpecA.length = removeTextSpecB.position - removeTextSpecA.position + } + if(removeTextSpecAEnd < removeTextSpecBEnd) { + removeTextSpecB.position = removeTextSpecA.position; + removeTextSpecB.length = removeTextSpecBEnd - removeTextSpecAEnd + }else { + removeTextSpecBResult = [] + } + }else { + if(removeTextSpecAEnd < removeTextSpecBEnd) { + removeTextSpecB.length = removeTextSpecB.length - removeTextSpecA.length + }else { + if(removeTextSpecB.position < removeTextSpecA.position) { + removeTextSpecB.length = removeTextSpecA.position - removeTextSpecB.position + }else { + removeTextSpecBResult = [] + } + } + if(removeTextSpecBEnd < removeTextSpecAEnd) { + removeTextSpecA.position = removeTextSpecB.position; + removeTextSpecA.length = removeTextSpecAEnd - removeTextSpecBEnd + }else { + removeTextSpecAResult = [] + } + } + } + } + } + return{opSpecsA:removeTextSpecAResult, opSpecsB:removeTextSpecBResult} + } + function transformRemoveTextSplitParagraph(removeTextSpec, splitParagraphSpec) { + var removeTextSpecEnd = removeTextSpec.position + removeTextSpec.length, helperOpspec, removeTextSpecResult = [removeTextSpec], splitParagraphSpecResult = [splitParagraphSpec]; + if(splitParagraphSpec.position <= removeTextSpec.position) { + removeTextSpec.position += 1 + }else { + if(splitParagraphSpec.position < removeTextSpecEnd) { + removeTextSpec.length = splitParagraphSpec.position - removeTextSpec.position; + helperOpspec = {optype:"RemoveText", memberid:removeTextSpec.memberid, timestamp:removeTextSpec.timestamp, position:splitParagraphSpec.position + 1, length:removeTextSpecEnd - splitParagraphSpec.position}; + removeTextSpecResult.unshift(helperOpspec) + } + } + if(removeTextSpec.position + removeTextSpec.length <= splitParagraphSpec.position) { + splitParagraphSpec.position -= removeTextSpec.length + }else { + if(removeTextSpec.position < splitParagraphSpec.position) { + splitParagraphSpec.position = removeTextSpec.position + } + } + return{opSpecsA:removeTextSpecResult, opSpecsB:splitParagraphSpecResult} + } + var transformations = {"AddCursor":{"AddCursor":passUnchanged, "AddStyle":passUnchanged, "InsertText":passUnchanged, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveStyle":passUnchanged, "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "UpdateParagraphStyle":passUnchanged}, "AddStyle":{"AddStyle":passUnchanged, "InsertText":passUnchanged, "MoveCursor":passUnchanged, "RemoveCursor":passUnchanged, "RemoveStyle":transformAddStyleRemoveStyle, + "RemoveText":passUnchanged, "SetParagraphStyle":passUnchanged, "SplitParagraph":passUnchanged, "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}}; + this.passUnchanged = passUnchanged; + this.extendTransformations = function(moreTransformations) { + Object.keys(moreTransformations).forEach(function(optypeA) { + var moreTransformationsOptypeAMap = moreTransformations[optypeA], optypeAMap, isExtendingOptypeAMap = transformations.hasOwnProperty(optypeA); + runtime.log((isExtendingOptypeAMap ? "Extending" : "Adding") + " map for optypeA: " + optypeA); + if(!isExtendingOptypeAMap) { + transformations[optypeA] = {} + } + optypeAMap = transformations[optypeA]; + Object.keys(moreTransformationsOptypeAMap).forEach(function(optypeB) { + var isOverwritingOptypeBEntry = optypeAMap.hasOwnProperty(optypeB); + runtime.assert(optypeA <= optypeB, "Wrong order:" + optypeA + ", " + optypeB); + runtime.log(" " + (isOverwritingOptypeBEntry ? "Overwriting" : "Adding") + " entry for optypeB: " + optypeB); + optypeAMap[optypeB] = moreTransformationsOptypeAMap[optypeB] + }) + }) + }; + this.transformOpspecVsOpspec = function(opSpecA, opSpecB) { + var isOptypeAAlphaNumericSmaller = opSpecA.optype <= opSpecB.optype, helper, transformationFunctionMap, transformationFunction, result; runtime.log("Crosstransforming:"); - runtime.log(runtime.toJson(opA.spec())); - runtime.log(runtime.toJson(opB.spec())); - oldOpB = operationFactory.create(opB.spec()); - opBTransformResult = opB.transform(opA, true); - opATransformResult = opA.transform(oldOpB, false); - if(!opATransformResult || !opBTransformResult) { - return null + runtime.log(runtime.toJson(opSpecA)); + runtime.log(runtime.toJson(opSpecB)); + if(!isOptypeAAlphaNumericSmaller) { + helper = opSpecA; + opSpecA = opSpecB; + opSpecB = helper + } + transformationFunctionMap = transformations[opSpecA.optype]; + transformationFunction = transformationFunctionMap && transformationFunctionMap[opSpecB.optype]; + if(transformationFunction) { + result = transformationFunction(opSpecA, opSpecB, !isOptypeAAlphaNumericSmaller); + if(!isOptypeAAlphaNumericSmaller && result !== null) { + result = {opSpecsA:result.opSpecsB, opSpecsB:result.opSpecsA} + } + }else { + result = null + } + runtime.log("result:"); + if(result) { + runtime.log(runtime.toJson(result.opSpecsA)); + runtime.log(runtime.toJson(result.opSpecsB)) + }else { + runtime.log("null") } - return{opsA:opATransformResult, opsB:opBTransformResult} + return result + } +}; +/* + + 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.OperationFactory"); +runtime.loadClass("ops.OperationTransformMatrix"); +ops.OperationTransformer = function OperationTransformer() { + var operationFactory, operationTransformMatrix = new ops.OperationTransformMatrix; + function operations(opspecs) { + var ops = []; + opspecs.forEach(function(opspec) { + ops.push(operationFactory.create(opspec)) + }); + return ops + } + function transformOpVsOp(opSpecA, opSpecB) { + return operationTransformMatrix.transformOpspecVsOpspec(opSpecA, opSpecB) } - function transformOpListVsOp(opsA, opB) { - var b, transformResult, transformListResult, transformedOpsA = [], transformedOpsB = []; - while(opsA.length > 0 && opB) { - transformResult = transformOpVsOp(opsA.shift(), (opB)); + function transformOpListVsOp(opSpecsA, opSpecB) { + var transformResult, transformListResult, transformedOpspecsA = [], transformedOpspecsB = []; + while(opSpecsA.length > 0 && opSpecB) { + transformResult = transformOpVsOp(opSpecsA.shift(), (opSpecB)); if(!transformResult) { return null } - transformedOpsA = transformedOpsA.concat(transformResult.opsA); - if(transformResult.opsB.length === 0) { - transformedOpsA = transformedOpsA.concat(opsA); - opB = null; + transformedOpspecsA = transformedOpspecsA.concat(transformResult.opSpecsA); + if(transformResult.opSpecsB.length === 0) { + transformedOpspecsA = transformedOpspecsA.concat(opSpecsA); + opSpecB = null; break } - if(transformResult.opsB.length > 1) { - for(b = 0;b < transformResult.opsB.length - 1;b += 1) { - transformListResult = transformOpListVsOp(opsA, transformResult.opsB[b]); - if(!transformListResult) { - return null - } - transformedOpsB = transformedOpsB.concat(transformListResult.opsB); - opsA = transformListResult.opsA + while(transformResult.opSpecsB.length > 1) { + transformListResult = transformOpListVsOp(opSpecsA, transformResult.opSpecsB.shift()); + if(!transformListResult) { + return null } + transformedOpspecsB = transformedOpspecsB.concat(transformListResult.opSpecsB); + opSpecsA = transformListResult.opSpecsA } - opB = transformResult.opsB.pop() + opSpecB = transformResult.opSpecsB.pop() } - if(opB) { - transformedOpsB.push(opB) + if(opSpecB) { + transformedOpspecsB.push(opSpecB) } - return{opsA:transformedOpsA, opsB:transformedOpsB} + return{opSpecsA:transformedOpspecsA, opSpecsB:transformedOpspecsB} } this.setOperationFactory = function(f) { operationFactory = f }; - this.transform = function(opspecsA, opspecsB) { - var c, s, opsA = [], clientOp, serverOp, transformResult, transformedOpsB = []; - for(c = 0;c < opspecsA.length;c += 1) { - clientOp = operationFactory.create(opspecsA[c]); - if(!clientOp) { - return null - } - opsA.push(clientOp) - } - for(s = 0;s < opspecsB.length;s += 1) { - serverOp = operationFactory.create(opspecsB[s]); - transformResult = transformOpListVsOp(opsA, serverOp); + this.getOperationTransformMatrix = function() { + return operationTransformMatrix + }; + this.transform = function(opSpecsA, opSpecsB) { + var transformResult, transformedOpspecsB = []; + while(opSpecsB.length > 0) { + transformResult = transformOpListVsOp(opSpecsA, opSpecsB.shift()); if(!transformResult) { return null } - opsA = transformResult.opsA; - transformedOpsB = transformedOpsB.concat(transformResult.opsB) + opSpecsA = transformResult.opSpecsA; + transformedOpspecsB = transformedOpspecsB.concat(transformResult.opSpecsB) } - return{opsA:opsA, opsB:transformedOpsB} + return{opsA:operations(opSpecsA), opsB:operations(transformedOpspecsB)} } }; runtime.loadClass("core.Cursor"); runtime.loadClass("gui.SelectionMover"); ops.OdtCursor = function OdtCursor(memberId, odtDocument) { - var self = this, selectionMover, cursor; + var self = this, validSelectionTypes = {}, selectionType, selectionMover, cursor; this.removeFromOdtDocument = function() { cursor.remove() }; @@ -12056,15 +12769,42 @@ ops.OdtCursor = function OdtCursor(memberId, odtDocument) { this.getSelectedRange = function() { return cursor.getSelectedRange() }; + this.setSelectedRange = function(range, isForwardSelection) { + cursor.setSelectedRange(range, isForwardSelection) + }; + this.hasForwardSelection = function() { + return cursor.hasForwardSelection() + }; this.getOdtDocument = function() { return odtDocument }; + this.getSelectionType = function() { + return selectionType + }; + this.setSelectionType = function(value) { + if(validSelectionTypes.hasOwnProperty(value)) { + selectionType = value + }else { + runtime.log("Invalid selection type: " + value) + } + }; + this.resetSelectionType = function() { + self.setSelectionType(ops.OdtCursor.RangeSelection) + }; function init() { cursor = new core.Cursor(odtDocument.getDOM(), memberId); - selectionMover = new gui.SelectionMover(cursor, odtDocument.getRootNode()) + selectionMover = new gui.SelectionMover(cursor, odtDocument.getRootNode()); + validSelectionTypes[ops.OdtCursor.RangeSelection] = true; + validSelectionTypes[ops.OdtCursor.RegionSelection] = true; + self.resetSelectionType() } init() }; +ops.OdtCursor.RangeSelection = "Range"; +ops.OdtCursor.RegionSelection = "Region"; +(function() { + return ops.OdtCursor +})(); /* Copyright (C) 2012 KO GmbH @@ -12077,6 +12817,9 @@ ops.OdtCursor = function OdtCursor(memberId, odtDocument) { 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 @@ -12097,7 +12840,7 @@ ops.OdtCursor = function OdtCursor(memberId, odtDocument) { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.EditInfo = function EditInfo(container, odtDocument) { var editInfoNode, editHistory = {}; @@ -12144,6 +12887,39 @@ ops.EditInfo = function EditInfo(container, odtDocument) { } init() }; +runtime.loadClass("gui.SelectionMover"); +gui.ShadowCursor = function ShadowCursor(odtDocument) { + var selectedRange = odtDocument.getDOM().createRange(), forwardSelection = true; + this.removeFromOdtDocument = function() { + }; + this.getMemberId = function() { + return gui.ShadowCursor.ShadowCursorMemberId + }; + this.getSelectedRange = function() { + return selectedRange + }; + this.setSelectedRange = function(range, isForwardSelection) { + selectedRange = range; + forwardSelection = isForwardSelection !== false + }; + this.hasForwardSelection = function() { + return forwardSelection + }; + this.getOdtDocument = function() { + return odtDocument + }; + this.getSelectionType = function() { + return ops.OdtCursor.RangeSelection + }; + function init() { + selectedRange.setStart(odtDocument.getRootNode(), 0) + } + init() +}; +gui.ShadowCursor.ShadowCursorMemberId = ""; +(function() { + return gui.ShadowCursor +})(); gui.Avatar = function Avatar(parentElement, avatarInitiallyVisible) { var self = this, handle, image, pendingImageUrl, displayShown = "block", displayHidden = "none"; this.setColor = function(color) { @@ -12193,10 +12969,11 @@ gui.Avatar = function Avatar(parentElement, avatarInitiallyVisible) { } init() }; +runtime.loadClass("core.DomUtils"); runtime.loadClass("gui.Avatar"); runtime.loadClass("ops.OdtCursor"); gui.Caret = function Caret(cursor, avatarInitiallyVisible, blinkOnRangeSelect) { - var span, avatar, cursorNode, shouldBlink = false, blinking = false, blinkTimeout; + var MIN_CARET_HEIGHT_PX = 8, DEFAULT_CARET_TOP = "5%", DEFAULT_CARET_HEIGHT = "1em", span, avatar, cursorNode, isShown = true, shouldBlink = false, blinking = false, blinkTimeout, domUtils = new core.DomUtils; function blink(reset) { if(!shouldBlink || !cursorNode.parentNode) { return @@ -12217,6 +12994,69 @@ gui.Caret = function Caret(cursor, avatarInitiallyVisible, blinkOnRangeSelect) { var caretRect = caretElement.getBoundingClientRect(); return{left:caretRect.left - margin.left, top:caretRect.top - margin.top, right:caretRect.right + margin.right, bottom:caretRect.bottom + margin.bottom} } + function length(node) { + return node.nodeType === Node.TEXT_NODE ? node.textContent.length : node.childNodes.length + } + function verticalOverlap(cursorNode, rangeRect) { + var cursorRect = cursorNode.getBoundingClientRect(), intersectTop = 0, intersectBottom = 0; + if(cursorRect && rangeRect) { + intersectTop = Math.max(cursorRect.top, rangeRect.top); + intersectBottom = Math.min(cursorRect.bottom, rangeRect.bottom) + } + return intersectBottom - intersectTop + } + function getSelectionRect() { + var range = cursor.getSelectedRange().cloneRange(), node = cursor.getNode(), nextRectangle, selectionRectangle = null, nodeLength; + if(node.previousSibling) { + nodeLength = length(node.previousSibling); + range.setStart(node.previousSibling, nodeLength > 0 ? nodeLength - 1 : 0); + range.setEnd(node.previousSibling, nodeLength); + nextRectangle = range.getBoundingClientRect(); + if(nextRectangle && nextRectangle.height) { + selectionRectangle = nextRectangle + } + } + if(node.nextSibling) { + range.setStart(node.nextSibling, 0); + range.setEnd(node.nextSibling, length(node.nextSibling) > 0 ? 1 : 0); + nextRectangle = range.getBoundingClientRect(); + if(nextRectangle && nextRectangle.height) { + if(!selectionRectangle || verticalOverlap(node, nextRectangle) > verticalOverlap(node, selectionRectangle)) { + selectionRectangle = nextRectangle + } + } + } + return selectionRectangle + } + function 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) { + span.style.visibility = "visible" + }else { + span.style.visibility = "hidden" + } + if(selectionRect) { + span.style.top = "0"; + caretRect = getSpanBoundingClientRect(); + if(selectionRect.height < MIN_CARET_HEIGHT_PX) { + selectionRect = {top:selectionRect.top - (MIN_CARET_HEIGHT_PX - selectionRect.height) / 2, height:MIN_CARET_HEIGHT_PX} + } + span.style.height = domUtils.adaptRangeDifferenceToZoomLevel(selectionRect.height, zoomLevel) + "px"; + span.style.top = domUtils.adaptRangeDifferenceToZoomLevel(selectionRect.top - caretRect.top, zoomLevel) + "px" + }else { + span.style.height = DEFAULT_CARET_HEIGHT; + span.style.top = DEFAULT_CARET_TOP + } + } + this.handleUpdate = handleUpdate; this.refreshCursorBlinking = function() { if(blinkOnRangeSelect || cursor.getSelectedRange().collapsed) { shouldBlink = true; @@ -12237,11 +13077,13 @@ gui.Caret = function Caret(cursor, avatarInitiallyVisible, blinkOnRangeSelect) { span.style.opacity = "1" }; this.show = function() { - span.style.visibility = "visible"; + isShown = true; + handleUpdate(); avatar.markAsFocussed(true) }; this.hide = function() { - span.style.visibility = "hidden"; + isShown = false; + handleUpdate(); avatar.markAsFocussed(false) }; this.setAvatarImageUrl = function(url) { @@ -12288,6 +13130,7 @@ gui.Caret = function Caret(cursor, avatarInitiallyVisible, blinkOnRangeSelect) { canvasContainerElement.scrollLeft += caretRect.right - canvasContainerRect.right } } + handleUpdate() }; this.destroy = function(callback) { avatar.destroy(function(err) { @@ -12302,109 +13145,14 @@ gui.Caret = function Caret(cursor, avatarInitiallyVisible, blinkOnRangeSelect) { function init() { var dom = cursor.getOdtDocument().getDOM(), htmlns = dom.documentElement.namespaceURI; span = dom.createElementNS(htmlns, "span"); + span.style.top = DEFAULT_CARET_TOP; cursorNode = cursor.getNode(); cursorNode.appendChild(span); - avatar = new gui.Avatar(cursorNode, avatarInitiallyVisible) + avatar = new gui.Avatar(cursorNode, avatarInitiallyVisible); + handleUpdate() } init() }; -/* - - Copyright (C) 2012-2013 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -gui.KeyboardHandler = function KeyboardHandler() { - var modifier = gui.KeyboardHandler.Modifier, defaultBinding = null, bindings = {}; - function getModifiers(e) { - var modifiers = modifier.None; - if(e.metaKey) { - modifiers |= modifier.Meta - } - if(e.ctrlKey) { - modifiers |= modifier.Ctrl - } - if(e.altKey) { - modifiers |= modifier.Alt - } - if(e.shiftKey) { - modifiers |= modifier.Shift - } - return modifiers - } - function getKeyCombo(keyCode, modifiers) { - if(!modifiers) { - modifiers = modifier.None - } - return keyCode + ":" + modifiers - } - this.setDefault = function(callback) { - defaultBinding = callback - }; - this.bind = function(keyCode, modifiers, callback) { - var keyCombo = getKeyCombo(keyCode, modifiers); - runtime.assert(bindings.hasOwnProperty(keyCombo) === false, "tried to overwrite the callback handler of key combo: " + keyCombo); - bindings[keyCombo] = callback - }; - this.unbind = function(keyCode, modifiers) { - var keyCombo = getKeyCombo(keyCode, modifiers); - delete bindings[keyCombo] - }; - this.reset = function() { - defaultBinding = null; - bindings = {} - }; - this.handleEvent = function(e) { - var keyCombo = getKeyCombo(e.keyCode, getModifiers(e)), callback = bindings[keyCombo], handled = false; - if(callback) { - handled = callback() - }else { - if(defaultBinding !== null) { - handled = defaultBinding(e) - } - } - if(handled) { - if(e.preventDefault) { - e.preventDefault() - }else { - e.returnValue = false - } - } - } -}; -gui.KeyboardHandler.Modifier = {None:0, Meta:1, Ctrl:2, Alt:4, Shift:8, MetaShift:9, CtrlShift:10, AltShift:12}; -gui.KeyboardHandler.KeyCode = {Backspace:8, Tab:9, Clear:12, Enter:13, End:35, Home:36, Left:37, Up:38, Right:39, Down:40, Delete:46, A:65, B:66, C:67, D:68, E:69, F:70, G:71, H:72, I:73, J:74, K:75, L:76, M:77, N:78, O:79, P:80, Q:81, R:82, S:83, T:84, U:85, V:86, W:87, X:88, Y:89, Z:90}; -(function() { - return gui.KeyboardHandler -})(); /* Copyright (C) 2013 KO GmbH @@ -12417,6 +13165,9 @@ gui.KeyboardHandler.KeyCode = {Backspace:8, Tab:9, Clear:12, Enter:13, End:35, H 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 @@ -12437,7 +13188,7 @@ gui.KeyboardHandler.KeyCode = {Backspace:8, Tab:9, Clear:12, Enter:13, End:35, H This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.Namespaces"); runtime.loadClass("xmldom.LSSerializer"); @@ -12484,6 +13235,9 @@ gui.Clipboard = function Clipboard() { 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 @@ -12504,13 +13258,14 @@ gui.Clipboard = function Clipboard() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.EventNotifier"); +runtime.loadClass("core.Utils"); runtime.loadClass("ops.OpApplyDirectStyling"); runtime.loadClass("gui.StyleHelper"); gui.DirectTextStyler = function DirectTextStyler(session, inputMemberId) { - var self = this, odtDocument = session.getOdtDocument(), styleHelper = new gui.StyleHelper(odtDocument.getFormatting()), eventNotifier = new core.EventNotifier([gui.DirectTextStyler.textStylingChanged]), isBoldValue = false, isItalicValue = false, hasUnderlineValue = false, hasStrikeThroughValue = false, fontSizeValue, fontNameValue; + var self = this, utils = new core.Utils, odtDocument = session.getOdtDocument(), styleHelper = new gui.StyleHelper(odtDocument.getFormatting()), eventNotifier = new core.EventNotifier([gui.DirectTextStyler.textStylingChanged]), directCursorStyleProperties, currentSelectionStyles = [], isBoldValue = false, isItalicValue = false, hasUnderlineValue = false, hasStrikeThroughValue = false, fontSizeValue, fontNameValue; function get(obj, keys) { var i = 0, key = keys[i]; while(key && obj) { @@ -12526,8 +13281,16 @@ gui.DirectTextStyler = function DirectTextStyler(session, inputMemberId) { return value === get(obj, keys) }) ? value : undefined } + function getAppliedStyles() { + var cursor = odtDocument.getCursor(inputMemberId), range = cursor && cursor.getSelectedRange(), selectionStyles = range && styleHelper.getAppliedStyles(range) || []; + if(selectionStyles[0] && directCursorStyleProperties) { + selectionStyles[0] = utils.mergeObjects(selectionStyles[0], (directCursorStyleProperties)) + } + return selectionStyles + } function updatedCachedValues() { - var cursor = odtDocument.getCursor(inputMemberId), range = cursor && cursor.getSelectedRange(), currentSelectionStyles = range && styleHelper.getAppliedStyles(range), fontSize, diffMap; + var fontSize, diffMap; + currentSelectionStyles = getAppliedStyles(); function noteChange(oldValue, newValue, id) { if(oldValue !== newValue) { if(diffMap === undefined) { @@ -12537,10 +13300,10 @@ gui.DirectTextStyler = function DirectTextStyler(session, inputMemberId) { } return newValue } - isBoldValue = noteChange(isBoldValue, range ? styleHelper.isBold(range) : false, "isBold"); - isItalicValue = noteChange(isItalicValue, range ? styleHelper.isItalic(range) : false, "isItalic"); - hasUnderlineValue = noteChange(hasUnderlineValue, range ? styleHelper.hasUnderline(range) : false, "hasUnderline"); - hasStrikeThroughValue = noteChange(hasStrikeThroughValue, range ? styleHelper.hasStrikeThrough(range) : false, "hasStrikeThrough"); + isBoldValue = noteChange(isBoldValue, currentSelectionStyles ? styleHelper.isBold(currentSelectionStyles) : false, "isBold"); + isItalicValue = noteChange(isItalicValue, currentSelectionStyles ? styleHelper.isItalic(currentSelectionStyles) : false, "isItalic"); + hasUnderlineValue = noteChange(hasUnderlineValue, currentSelectionStyles ? styleHelper.hasUnderline(currentSelectionStyles) : false, "hasUnderline"); + hasStrikeThroughValue = noteChange(hasStrikeThroughValue, currentSelectionStyles ? styleHelper.hasStrikeThrough(currentSelectionStyles) : false, "hasStrikeThrough"); fontSize = currentSelectionStyles && getCommonValue(currentSelectionStyles, ["style:text-properties", "fo:font-size"]); fontSizeValue = noteChange(fontSizeValue, fontSize && parseFloat(fontSize), "fontSize"); fontNameValue = noteChange(fontNameValue, currentSelectionStyles && getCommonValue(currentSelectionStyles, ["style:text-properties", "style:font-name"]), "fontName"); @@ -12573,47 +13336,81 @@ gui.DirectTextStyler = function DirectTextStyler(session, inputMemberId) { } } function toggle(predicate, toggleMethod) { - var cursor = odtDocument.getCursor(inputMemberId); + var cursor = odtDocument.getCursor(inputMemberId), appliedStyles; if(!cursor) { return false } - toggleMethod(!predicate(cursor.getSelectedRange())); + appliedStyles = styleHelper.getAppliedStyles(cursor.getSelectedRange()); + toggleMethod(!predicate(appliedStyles)); return true } - function formatTextSelection(propertyName, propertyValue) { - var selection = odtDocument.getCursorSelection(inputMemberId), op = new ops.OpApplyDirectStyling, properties = {}; - properties[propertyName] = propertyValue; - op.init({memberid:inputMemberId, position:selection.position, length:selection.length, setProperties:{"style:text-properties":properties}}); - session.enqueue(op) + function formatTextSelection(textProperties) { + var selection = odtDocument.getCursorSelection(inputMemberId), op, properties = {"style:text-properties":textProperties}; + if(selection.length !== 0) { + op = new ops.OpApplyDirectStyling; + op.init({memberid:inputMemberId, position:selection.position, length:selection.length, setProperties:properties}); + session.enqueue([op]) + }else { + directCursorStyleProperties = utils.mergeObjects(directCursorStyleProperties || {}, properties); + updatedCachedValues() + } + } + this.formatTextSelection = formatTextSelection; + function applyTextPropertyToSelection(propertyName, propertyValue) { + var textProperties = {}; + textProperties[propertyName] = propertyValue; + formatTextSelection(textProperties) + } + this.createCursorStyleOp = function(position, length) { + var styleOp = null; + if(directCursorStyleProperties) { + styleOp = new ops.OpApplyDirectStyling; + styleOp.init({memberid:inputMemberId, position:position, length:length, setProperties:directCursorStyleProperties}); + directCursorStyleProperties = null; + updatedCachedValues() + } + return styleOp + }; + function clearCursorStyle(op) { + var spec = op.spec(); + if(directCursorStyleProperties && spec.memberid === inputMemberId) { + if(spec.optype !== "SplitParagraph") { + directCursorStyleProperties = null; + updatedCachedValues() + } + } } function setBold(checked) { var value = checked ? "bold" : "normal"; - formatTextSelection("fo:font-weight", value) + applyTextPropertyToSelection("fo:font-weight", value) } this.setBold = setBold; function setItalic(checked) { var value = checked ? "italic" : "normal"; - formatTextSelection("fo:font-style", value) + applyTextPropertyToSelection("fo:font-style", value) } this.setItalic = setItalic; function setHasUnderline(checked) { var value = checked ? "solid" : "none"; - formatTextSelection("style:text-underline-style", value) + applyTextPropertyToSelection("style:text-underline-style", value) } this.setHasUnderline = setHasUnderline; function setHasStrikethrough(checked) { var value = checked ? "solid" : "none"; - formatTextSelection("style:text-line-through-style", value) + applyTextPropertyToSelection("style:text-line-through-style", value) } this.setHasStrikethrough = setHasStrikethrough; function setFontSize(value) { - formatTextSelection("fo:font-size", value + "pt") + applyTextPropertyToSelection("fo:font-size", value + "pt") } this.setFontSize = setFontSize; function setFontName(value) { - formatTextSelection("style:font-name", value) + applyTextPropertyToSelection("style:font-name", value) } this.setFontName = setFontName; + this.getAppliedStyles = function() { + return currentSelectionStyles + }; this.toggleBold = toggle.bind(self, styleHelper.isBold, setBold); this.toggleItalic = toggle.bind(self, styleHelper.isItalic, setItalic); this.toggleUnderline = toggle.bind(self, styleHelper.hasUnderline, setHasUnderline); @@ -12648,6 +13445,7 @@ gui.DirectTextStyler = function DirectTextStyler(session, inputMemberId) { odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); odtDocument.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified); odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); + odtDocument.unsubscribe(ops.OdtDocument.signalOperationExecuted, clearCursorStyle); callback() }; function init() { @@ -12656,6 +13454,7 @@ gui.DirectTextStyler = function DirectTextStyler(session, inputMemberId) { odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); odtDocument.subscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified); odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); + odtDocument.subscribe(ops.OdtDocument.signalOperationExecuted, clearCursorStyle); updatedCachedValues() } init() @@ -12676,6 +13475,9 @@ gui.DirectTextStyler.textStylingChanged = "textStyling/changed"; 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 @@ -12696,7 +13498,7 @@ gui.DirectTextStyler.textStylingChanged = "textStyling/changed"; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.EventNotifier"); runtime.loadClass("core.Utils"); @@ -12704,7 +13506,7 @@ runtime.loadClass("odf.OdfUtils"); runtime.loadClass("ops.OpAddStyle"); runtime.loadClass("ops.OpSetParagraphStyle"); runtime.loadClass("gui.StyleHelper"); -gui.DirectParagraphStyler = function DirectParagraphStyler(session, inputMemberId, styleNameGenerator) { +gui.DirectParagraphStyler = function DirectParagraphStyler(session, inputMemberId, objectNameGenerator) { var odtDocument = session.getOdtDocument(), utils = new core.Utils, odfUtils = new odf.OdfUtils, styleHelper = new gui.StyleHelper(odtDocument.getFormatting()), eventNotifier = new core.EventNotifier([gui.DirectParagraphStyler.paragraphStylingChanged]), isAlignedLeftValue, isAlignedCenterValue, isAlignedRightValue, isAlignedJustifiedValue; function updatedCachedValues() { var cursor = odtDocument.getCursor(inputMemberId), range = cursor && cursor.getSelectedRange(), diffMap; @@ -12764,7 +13566,7 @@ gui.DirectParagraphStyler = function DirectParagraphStyler(session, inputMemberI function applyParagraphDirectStyling(applyDirectStyling) { var range = odtDocument.getCursor(inputMemberId).getSelectedRange(), position = odtDocument.getCursorPosition(inputMemberId), paragraphs = odfUtils.getParagraphElements(range), formatting = odtDocument.getFormatting(); paragraphs.forEach(function(paragraph) { - var paragraphStartPoint = position + odtDocument.getDistanceFromCursor(inputMemberId, paragraph, 0), paragraphStyleName = paragraph.getAttributeNS(odf.Namespaces.textns, "style-name"), newParagraphStyleName = styleNameGenerator.generateName(), opAddStyle, opSetParagraphStyle, paragraphProperties; + var paragraphStartPoint = position + odtDocument.getDistanceFromCursor(inputMemberId, paragraph, 0), paragraphStyleName = paragraph.getAttributeNS(odf.Namespaces.textns, "style-name"), newParagraphStyleName = objectNameGenerator.generateStyleName(), opAddStyle, opSetParagraphStyle, paragraphProperties; paragraphStartPoint += 1; if(paragraphStyleName) { paragraphProperties = formatting.createDerivedStyleObject(paragraphStyleName, "paragraph", {}) @@ -12774,8 +13576,7 @@ gui.DirectParagraphStyler = function DirectParagraphStyler(session, inputMemberI opAddStyle.init({memberid:inputMemberId, styleName:newParagraphStyleName, styleFamily:"paragraph", isAutomaticStyle:true, setProperties:paragraphProperties}); opSetParagraphStyle = new ops.OpSetParagraphStyle; opSetParagraphStyle.init({memberid:inputMemberId, styleName:newParagraphStyleName, position:paragraphStartPoint}); - session.enqueue(opAddStyle); - session.enqueue(opSetParagraphStyle) + session.enqueue([opAddStyle, opSetParagraphStyle]) }) } function applySimpleParagraphDirectStyling(styleOverrides) { @@ -12833,20 +13634,235 @@ gui.DirectParagraphStyler = function DirectParagraphStyler(session, inputMemberI odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); callback() }; - function init() { - odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); - odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); - odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); - odtDocument.subscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified); - odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); - updatedCachedValues() + function init() { + odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); + odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); + odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); + odtDocument.subscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified); + odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); + updatedCachedValues() + } + init() +}; +gui.DirectParagraphStyler.paragraphStylingChanged = "paragraphStyling/changed"; +(function() { + return gui.DirectParagraphStyler +})(); +/* + + 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/ +*/ +gui.KeyboardHandler = function KeyboardHandler() { + var modifier = gui.KeyboardHandler.Modifier, defaultBinding = null, bindings = {}; + function getModifiers(e) { + var modifiers = modifier.None; + if(e.metaKey) { + modifiers |= modifier.Meta + } + if(e.ctrlKey) { + modifiers |= modifier.Ctrl + } + if(e.altKey) { + modifiers |= modifier.Alt + } + if(e.shiftKey) { + modifiers |= modifier.Shift + } + return modifiers + } + function getKeyCombo(keyCode, modifiers) { + if(!modifiers) { + modifiers = modifier.None + } + return keyCode + ":" + modifiers + } + this.setDefault = function(callback) { + defaultBinding = callback + }; + this.bind = function(keyCode, modifiers, callback) { + var keyCombo = getKeyCombo(keyCode, modifiers); + runtime.assert(bindings.hasOwnProperty(keyCombo) === false, "tried to overwrite the callback handler of key combo: " + keyCombo); + bindings[keyCombo] = callback + }; + this.unbind = function(keyCode, modifiers) { + var keyCombo = getKeyCombo(keyCode, modifiers); + delete bindings[keyCombo] + }; + this.reset = function() { + defaultBinding = null; + bindings = {} + }; + this.handleEvent = function(e) { + var keyCombo = getKeyCombo(e.keyCode, getModifiers(e)), callback = bindings[keyCombo], handled = false; + if(callback) { + handled = callback() + }else { + if(defaultBinding !== null) { + handled = defaultBinding(e) + } + } + if(handled) { + if(e.preventDefault) { + e.preventDefault() + }else { + e.returnValue = false + } + } } - init() }; -gui.DirectParagraphStyler.paragraphStylingChanged = "paragraphStyling/changed"; +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.DirectParagraphStyler + return gui.KeyboardHandler })(); +runtime.loadClass("odf.Namespaces"); +runtime.loadClass("odf.ObjectNameGenerator"); +gui.ImageManager = function ImageManager(session, inputMemberId, objectNameGenerator) { + var cmPerPixel = 0.0264583333333334, fileExtensionByMimetype = {"image/gif":".gif", "image/jpeg":".jpg", "image/png":".png"}, textns = odf.Namespaces.textns, odtDocument = session.getOdtDocument(), formatting = odtDocument.getFormatting(), paragraphStyleToPageContentSizeMap = {}; + function createAddGraphicsStyleOp(name) { + var op = new ops.OpAddStyle; + op.init({memberid:inputMemberId, styleName:name, styleFamily:"graphic", isAutomaticStyle:false, 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"}}}); + return op + } + function createAddFrameStyleOp(styleName, parentStyleName) { + var op = new ops.OpAddStyle; + op.init({memberid:inputMemberId, styleName:styleName, styleFamily:"graphic", isAutomaticStyle:true, setProperties:{"style:parent-style-name":parentStyleName, "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"}}}); + return op + } + function getFileExtension(mimetype) { + mimetype = mimetype.toLowerCase(); + return fileExtensionByMimetype.hasOwnProperty(mimetype) ? fileExtensionByMimetype[mimetype] : null + } + function insertImageInternal(mimetype, content, widthInCm, heightInCm) { + var graphicsStyleName = "Graphics", stylesElement = odtDocument.getOdfCanvas().odfContainer().rootElement.styles, fileExtension = getFileExtension(mimetype), fileName, graphicsStyleElement, frameStyleName, op, operations = []; + runtime.assert(fileExtension !== null, "Image type is not supported: " + mimetype); + fileName = "Pictures/" + objectNameGenerator.generateImageName() + fileExtension; + op = new ops.OpSetBlob; + op.init({memberid:inputMemberId, filename:fileName, mimetype:mimetype, content:content}); + operations.push(op); + graphicsStyleElement = formatting.getStyleElement(graphicsStyleName, "graphic", [stylesElement]); + if(!graphicsStyleElement) { + op = createAddGraphicsStyleOp(graphicsStyleName); + operations.push(op) + } + frameStyleName = objectNameGenerator.generateStyleName(); + op = createAddFrameStyleOp(frameStyleName, graphicsStyleName); + operations.push(op); + op = new ops.OpInsertImage; + op.init({memberid:inputMemberId, position:odtDocument.getCursorPosition(inputMemberId), filename:fileName, frameWidth:widthInCm + "cm", frameHeight:heightInCm + "cm", frameStyleName:frameStyleName, frameName:objectNameGenerator.generateFrameName()}); + operations.push(op); + session.enqueue(operations) + } + function trimmedSize(originalSize, pageContentSize) { + var widthRatio = 1, heightRatio = 1, ratio; + if(originalSize.width > pageContentSize.width) { + widthRatio = pageContentSize.width / originalSize.width + } + if(originalSize.height > pageContentSize.height) { + heightRatio = pageContentSize.height / originalSize.height + } + ratio = Math.min(widthRatio, heightRatio); + return{width:originalSize.width * ratio, height:originalSize.height * ratio} + } + this.insertImage = function(mimetype, content, widthInPx, heightInPx) { + var paragraphElement, styleName, pageContentSize, originalSize, newSize; + runtime.assert(widthInPx > 0 && heightInPx > 0, "Both width and height of the image should be greater than 0px."); + paragraphElement = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()); + styleName = paragraphElement.getAttributeNS(textns, "style-name"); + if(!paragraphStyleToPageContentSizeMap.hasOwnProperty(styleName)) { + paragraphStyleToPageContentSizeMap[styleName] = formatting.getContentSize(styleName, "paragraph") + } + pageContentSize = paragraphStyleToPageContentSizeMap[styleName]; + originalSize = {width:widthInPx * cmPerPixel, height:heightInPx * cmPerPixel}; + newSize = trimmedSize(originalSize, pageContentSize); + insertImageInternal(mimetype, content, newSize.width, newSize.height) + } +}; +runtime.loadClass("odf.Namespaces"); +gui.ImageSelector = function ImageSelector(odfCanvas) { + var svgns = odf.Namespaces.svgns, imageSelectorId = "imageSelector", selectorBorderWidth = 1, squareClassNames = ["topLeft", "topRight", "bottomRight", "bottomLeft", "topMiddle", "rightMiddle", "bottomMiddle", "leftMiddle"], document = odfCanvas.getElement().ownerDocument, hasSelection = false; + function createSelectorElement() { + var sizerElement = odfCanvas.getSizer(), selectorElement, squareElement; + selectorElement = document.createElement("div"); + selectorElement.id = "imageSelector"; + selectorElement.style.borderWidth = selectorBorderWidth + "px"; + sizerElement.appendChild(selectorElement); + squareClassNames.forEach(function(className) { + squareElement = document.createElement("div"); + squareElement.className = className; + selectorElement.appendChild(squareElement) + }); + return selectorElement + } + function getPosition(element, referenceElement) { + var rect = element.getBoundingClientRect(), refRect = referenceElement.getBoundingClientRect(), zoomLevel = odfCanvas.getZoomLevel(); + return{left:(rect.left - refRect.left) / zoomLevel - selectorBorderWidth, top:(rect.top - refRect.top) / zoomLevel - selectorBorderWidth} + } + this.select = function(frameElement) { + var selectorElement = document.getElementById(imageSelectorId), position; + if(!selectorElement) { + selectorElement = createSelectorElement() + } + hasSelection = true; + position = getPosition(frameElement, (selectorElement.parentNode)); + selectorElement.style.display = "block"; + selectorElement.style.left = position.left + "px"; + selectorElement.style.top = position.top + "px"; + selectorElement.style.width = frameElement.getAttributeNS(svgns, "width"); + selectorElement.style.height = frameElement.getAttributeNS(svgns, "height") + }; + this.clearSelection = function() { + var selectorElement; + if(hasSelection) { + selectorElement = document.getElementById(imageSelectorId); + if(selectorElement) { + selectorElement.style.display = "none" + } + } + hasSelection = false + }; + this.isSelectorElement = function(node) { + var selectorElement = document.getElementById(imageSelectorId); + if(!selectorElement) { + return false + } + return node === selectorElement || node.parentNode === selectorElement + } +}; /* Copyright (C) 2013 KO GmbH @@ -12859,6 +13875,9 @@ gui.DirectParagraphStyler.paragraphStylingChanged = "paragraphStyling/changed"; 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 @@ -12879,9 +13898,9 @@ gui.DirectParagraphStyler.paragraphStylingChanged = "paragraphStyling/changed"; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -gui.TextManipulator = function TextManipulator(session, inputMemberId) { +gui.TextManipulator = function TextManipulator(session, inputMemberId, directStyleOp) { var odtDocument = session.getOdtDocument(); function createOpRemoveSelection(selection) { var op = new ops.OpRemoveText; @@ -12896,14 +13915,15 @@ gui.TextManipulator = function TextManipulator(session, inputMemberId) { return selection } this.enqueueParagraphSplittingOps = function() { - var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op; + var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op, operations = []; if(selection.length > 0) { op = createOpRemoveSelection(selection); - session.enqueue(op) + operations.push(op) } op = new ops.OpSplitParagraph; op.init({memberid:inputMemberId, position:selection.position}); - session.enqueue(op); + operations.push(op); + session.enqueue(operations); return true }; this.removeTextByBackspaceKey = function() { @@ -12912,11 +13932,11 @@ gui.TextManipulator = function TextManipulator(session, inputMemberId) { if(selection.position > 0 && odtDocument.getPositionInTextNode(selection.position - 1)) { op = new ops.OpRemoveText; op.init({memberid:inputMemberId, position:selection.position - 1, length:1}); - session.enqueue(op) + session.enqueue([op]) } }else { op = createOpRemoveSelection(selection); - session.enqueue(op) + session.enqueue([op]) } return op !== null }; @@ -12926,11 +13946,11 @@ gui.TextManipulator = function TextManipulator(session, inputMemberId) { if(odtDocument.getPositionInTextNode(selection.position + 1)) { op = new ops.OpRemoveText; op.init({memberid:inputMemberId, position:selection.position, length:1}); - session.enqueue(op) + session.enqueue([op]) } }else { op = createOpRemoveSelection(selection); - session.enqueue(op) + session.enqueue([op]) } return op !== null }; @@ -12938,73 +13958,296 @@ gui.TextManipulator = function TextManipulator(session, inputMemberId) { var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op; if(selection.length !== 0) { op = createOpRemoveSelection(selection); - session.enqueue(op) + session.enqueue([op]) } return true }; function insertText(text) { - var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op = null; + var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op, stylingOp, operations = []; if(selection.length > 0) { op = createOpRemoveSelection(selection); - session.enqueue(op) + operations.push(op) } op = new ops.OpInsertText; op.init({memberid:inputMemberId, position:selection.position, text:text}); - session.enqueue(op) + operations.push(op); + if(directStyleOp) { + stylingOp = directStyleOp(selection.position, text.length); + if(stylingOp) { + operations.push(stylingOp) + } + } + session.enqueue(operations) } this.insertText = insertText }; (function() { return gui.TextManipulator })(); +/* + + 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 + 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 AnnotationManager(session, inputMemberId) { + var odtDocument = session.getOdtDocument(), baseFilter = odtDocument.getPositionFilter(), isAnnotatable = false, eventNotifier = new core.EventNotifier([gui.AnnotationManager.annotatableChanged]), officens = odf.Namespaces.officens, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT; + function isWithinAnnotation(node, container) { + while(node && node !== container) { + if(node.namespaceURI === officens && node.localName === "annotation") { + return true + } + node = node.parentNode + } + return false + } + function updatedCachedValues() { + var cursor = odtDocument.getCursor(inputMemberId), cursorNode = cursor && cursor.getNode(), newIsAnnotatable = cursorNode && !isWithinAnnotation(cursorNode, odtDocument.getRootNode()); + if(newIsAnnotatable !== isAnnotatable) { + isAnnotatable = newIsAnnotatable; + eventNotifier.emit(gui.AnnotationManager.annotatableChanged, isAnnotatable) + } + } + function onCursorAdded(cursor) { + if(cursor.getMemberId() === inputMemberId) { + updatedCachedValues() + } + } + function onCursorRemoved(memberId) { + if(memberId === inputMemberId) { + updatedCachedValues() + } + } + function onCursorMoved(cursor) { + if(cursor.getMemberId() === inputMemberId) { + updatedCachedValues() + } + } + function getWalkableNodeLength(node) { + var length = 0, iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), inside = false; + iterator.setUnfilteredPosition(node, 0); + do { + inside = Boolean(node.compareDocumentPosition(iterator.container()) & Node.DOCUMENT_POSITION_CONTAINED_BY); + if(!inside && node !== iterator.container()) { + break + } + if(baseFilter.acceptPosition(iterator) === FILTER_ACCEPT) { + length += 1 + } + }while(iterator.nextPosition()); + return length + } + function getFirstWalkablePositionInNode(node) { + var position = 0, iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), watch = new core.LoopWatchDog(1E3), inside = false; + while(iterator.nextPosition()) { + watch.check(); + inside = Boolean(node.compareDocumentPosition(iterator.container()) & Node.DOCUMENT_POSITION_CONTAINED_BY); + if(baseFilter.acceptPosition(iterator) === FILTER_ACCEPT) { + if(inside) { + break + } + position += 1 + } + } + return position + } + this.isAnnotatable = function() { + return isAnnotatable + }; + this.addAnnotation = function() { + var op = new ops.OpAddAnnotation, selection = odtDocument.getCursorSelection(inputMemberId), length = selection.length, position = selection.position; + if(!isAnnotatable) { + return + } + position = length >= 0 ? position : position + length; + length = Math.abs(length); + op.init({memberid:inputMemberId, position:position, length:length, name:inputMemberId + Date.now()}); + session.enqueue([op]) + }; + this.removeAnnotation = function(annotationNode) { + var position, length, op, moveCursor; + position = getFirstWalkablePositionInNode(annotationNode); + length = getWalkableNodeLength(annotationNode); + op = new ops.OpRemoveAnnotation; + op.init({memberid:inputMemberId, position:position, length:length}); + moveCursor = new ops.OpMoveCursor; + moveCursor.init({memberid:inputMemberId, position:position - 1, length:0}); + session.enqueue([op, moveCursor]) + }; + this.subscribe = function(eventid, cb) { + eventNotifier.subscribe(eventid, cb) + }; + this.unsubscribe = function(eventid, cb) { + eventNotifier.unsubscribe(eventid, cb) + }; + this.destroy = function(callback) { + odtDocument.unsubscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); + odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); + odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); + callback() + }; + function init() { + odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); + odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); + odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); + updatedCachedValues() + } + init() +}; +gui.AnnotationManager.annotatableChanged = "annotatable/changed"; +(function() { + return gui.AnnotationManager +})(); +gui.EventManager = function EventManager(odtDocument) { + var canvasElement = odtDocument.getOdfCanvas().getElement(), window = runtime.getWindow(), bindToDirectHandler = {"beforecut":true, "beforepaste":true}, bindToWindow = {"mousedown":true, "mouseup":true}; + function WindowScrollState(window) { + var x = window.scrollX, y = window.scrollY; + this.restore = function() { + if(window.scrollX !== x || window.scrollY !== y) { + window.scrollTo(x, y) + } + } + } + function ElementScrollState(element) { + var top = element.scrollTop, left = element.scrollLeft; + this.restore = function() { + if(element.scrollTop !== top || element.scrollLeft !== left) { + element.scrollTop = top; + element.scrollLeft = left + } + } + } + function listenEvent(eventTarget, eventType, eventHandler) { + var onVariant = "on" + eventType, bound = false; + if(eventTarget.attachEvent) { + bound = eventTarget.attachEvent(onVariant, eventHandler) + } + if(!bound && eventTarget.addEventListener) { + eventTarget.addEventListener(eventType, eventHandler, false); + bound = true + } + if((!bound || bindToDirectHandler[eventType]) && eventTarget.hasOwnProperty(onVariant)) { + eventTarget[onVariant] = eventHandler + } + } + function removeEvent(eventTarget, eventType, eventHandler) { + var onVariant = "on" + eventType; + if(eventTarget.detachEvent) { + eventTarget.detachEvent(onVariant, eventHandler) + } + if(eventTarget.removeEventListener) { + eventTarget.removeEventListener(eventType, eventHandler, false) + } + if(eventTarget[onVariant] === eventHandler) { + eventTarget[onVariant] = null + } + } + this.subscribe = function(eventName, handler) { + var element = canvasElement; + if(bindToWindow[eventName] && window) { + element = window + } + listenEvent(element, eventName, handler) + }; + this.unsubscribe = function(eventName, handler) { + var element = canvasElement; + if(bindToWindow[eventName] && window) { + element = window + } + removeEvent(element, eventName, handler) + }; + function hasFocus() { + var activeElement = odtDocument.getDOM().activeElement; + return activeElement === canvasElement + } + this.hasFocus = hasFocus; + function findScrollableParent(element) { + while(element && (!element.scrollTop && !element.scrollLeft)) { + element = (element.parentNode) + } + if(element) { + return new ElementScrollState(element) + } + if(window) { + return new WindowScrollState(window) + } + return null + } + this.focus = function() { + var scrollParent; + if(!hasFocus()) { + scrollParent = findScrollableParent(canvasElement); + canvasElement.focus(); + if(scrollParent) { + scrollParent.restore() + } + } + } +}; runtime.loadClass("core.DomUtils"); -runtime.loadClass("core.Utils"); +runtime.loadClass("core.Async"); +runtime.loadClass("core.ScheduledTask"); runtime.loadClass("odf.OdfUtils"); +runtime.loadClass("odf.ObjectNameGenerator"); +runtime.loadClass("ops.OdtCursor"); runtime.loadClass("ops.OpAddCursor"); runtime.loadClass("ops.OpRemoveCursor"); -runtime.loadClass("ops.OpMoveCursor"); -runtime.loadClass("ops.OpInsertText"); -runtime.loadClass("ops.OpRemoveText"); -runtime.loadClass("ops.OpSplitParagraph"); -runtime.loadClass("ops.OpSetParagraphStyle"); -runtime.loadClass("ops.OpRemoveAnnotation"); runtime.loadClass("gui.Clipboard"); -runtime.loadClass("gui.KeyboardHandler"); runtime.loadClass("gui.DirectTextStyler"); runtime.loadClass("gui.DirectParagraphStyler"); +runtime.loadClass("gui.KeyboardHandler"); +runtime.loadClass("gui.ImageManager"); +runtime.loadClass("gui.ImageSelector"); runtime.loadClass("gui.TextManipulator"); +runtime.loadClass("gui.AnnotationManager"); +runtime.loadClass("gui.EventManager"); gui.SessionController = function() { var FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT; - gui.SessionController = function SessionController(session, inputMemberId, args) { - var window = (runtime.getWindow()), odtDocument = session.getOdtDocument(), utils = new core.Utils, 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, styleNameGenerator = new odf.StyleNameGenerator("auto" + utils.hashString(inputMemberId) + - "_", odtDocument.getFormatting()), undoManager = null, textManipulator = new gui.TextManipulator(session, inputMemberId), directTextStyler = args && args.directStylingEnabled ? new gui.DirectTextStyler(session, inputMemberId) : null, directParagraphStyler = args && args.directStylingEnabled ? new gui.DirectParagraphStyler(session, inputMemberId, styleNameGenerator) : null; + 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 = args && args.directStylingEnabled ? new gui.DirectTextStyler(session, inputMemberId) : null, directParagraphStyler = args && args.directStylingEnabled ? new gui.DirectParagraphStyler(session, inputMemberId, objectNameGenerator) : null, createCursorStyleOp = (directTextStyler && + 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; runtime.assert(window !== null, "Expected to be run in an environment which has a global window, like a browser."); keyboardMovementsFilter.addFilter("BaseFilter", baseFilter); keyboardMovementsFilter.addFilter("RootFilter", odtDocument.createRootFilter(inputMemberId)); - function listenEvent(eventTarget, eventType, eventHandler, includeDirect) { - var onVariant = "on" + eventType, bound = false; - if(eventTarget.attachEvent) { - bound = eventTarget.attachEvent(onVariant, eventHandler) - } - if(!bound && eventTarget.addEventListener) { - eventTarget.addEventListener(eventType, eventHandler, false); - bound = true - } - if((!bound || includeDirect) && eventTarget.hasOwnProperty(onVariant)) { - eventTarget[onVariant] = eventHandler - } - } - function removeEvent(eventTarget, eventType, eventHandler) { - var onVariant = "on" + eventType; - if(eventTarget.detachEvent) { - eventTarget.detachEvent(onVariant, eventHandler) - } - if(eventTarget.removeEventListener) { - eventTarget.removeEventListener(eventType, eventHandler, false) - } - if(eventTarget[onVariant] === eventHandler) { - eventTarget[onVariant] = null - } + function getTarget(e) { + return e.target || e.srcElement } function cancelEvent(event) { if(event.preventDefault) { @@ -13016,33 +14259,11 @@ gui.SessionController = function() { function dummyHandler(e) { cancelEvent(e) } - function createOpMoveCursor(position, length) { + function createOpMoveCursor(position, length, selectionType) { var op = new ops.OpMoveCursor; - op.init({memberid:inputMemberId, position:position, length:length || 0}); + op.init({memberid:inputMemberId, position:position, length:length || 0, selectionType:selectionType}); return op } - function countStepsToNode(targetNode, targetOffset) { - var iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), canvasElement = odtDocument.getOdfCanvas().getElement(), node; - node = targetNode; - if(!node) { - return null - } - while(node !== canvasElement) { - if(node.namespaceURI === "urn:webodf:names:cursor" && node.localName === "cursor" || node.namespaceURI === "urn:webodf:names:editinfo" && node.localName === "editinfo") { - break - } - node = node.parentNode; - if(!node) { - return null - } - } - if(node !== canvasElement && targetNode !== node) { - targetNode = node.parentNode; - targetOffset = Array.prototype.indexOf.call(targetNode.childNodes, node) - } - iterator.setUnfilteredPosition(targetNode, targetOffset); - return odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()) - } function caretPositionFromPoint(x, y) { var doc = odtDocument.getDOM(), result; if(doc.caretRangeFromPoint) { @@ -13066,9 +14287,6 @@ gui.SessionController = function() { } return{node:newNode, offset:newOffset} } - function isTextSpan(node) { - return node.namespaceURI === odf.Namespaces.textns && node.localName === "span" - } function expandToWordBoundaries(selection) { var alphaNumeric = /[A-Za-z0-9]/, iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), isForwardSelection = domUtils.comparePoints(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset) > 0, startPoint, endPoint, currentNode, c; if(isForwardSelection) { @@ -13087,7 +14305,7 @@ gui.SessionController = function() { break } }else { - if(!isTextSpan(currentNode)) { + if(!odfUtils.isTextSpan(currentNode)) { break } } @@ -13103,7 +14321,7 @@ gui.SessionController = function() { break } }else { - if(!isTextSpan(currentNode)) { + if(!odfUtils.isTextSpan(currentNode)) { break } } @@ -13133,111 +14351,73 @@ gui.SessionController = function() { selection.focusOffset = focusParagraph.childNodes.length } } - function mutableSelection(selection) { - return{anchorNode:selection.anchorNode, anchorOffset:selection.anchorOffset, focusNode:selection.focusNode, focusOffset:selection.focusOffset} + function selectImage(frameNode) { + var stepsToAnchor = odtDocument.getDistanceFromCursor(inputMemberId, frameNode, 0), stepsToFocus = stepsToAnchor !== null ? stepsToAnchor + 1 : null, oldPosition, op; + if(stepsToFocus || stepsToAnchor) { + oldPosition = odtDocument.getCursorPosition(inputMemberId); + op = createOpMoveCursor(oldPosition + stepsToAnchor, stepsToFocus - stepsToAnchor, ops.OdtCursor.RegionSelection); + session.enqueue([op]) + } + eventManager.focus() } - function getSelection(e) { - var canvasElement = odtDocument.getOdfCanvas().getElement(), selection = mutableSelection(window.getSelection()), clickCount = e.detail, anchorNodeInsideCanvas, focusNodeInsideCanvas, caretPos, node; - if(selection.anchorNode === null && selection.focusNode === null) { - caretPos = caretPositionFromPoint(e.clientX, e.clientY); + function selectRange(selection, capturedDetails) { + var canvasElement = odtDocument.getOdfCanvas().getElement(), validSelection, clickCount = capturedDetails.detail, caretPos, anchorNodeInsideCanvas, focusNodeInsideCanvas, position, stepsToAnchor, stepsToFocus, oldPosition, op; + if(!selection) { + return + } + if(!selection.anchorNode && !selection.focusNode) { + caretPos = caretPositionFromPoint(capturedDetails.clientX, capturedDetails.clientY); if(!caretPos) { - return null + return } selection.anchorNode = (caretPos.container); selection.anchorOffset = caretPos.offset; selection.focusNode = selection.anchorNode; selection.focusOffset = selection.anchorOffset } - runtime.assert(selection.anchorNode !== null && selection.focusNode !== null, "anchorNode is null or focusNode is null"); - anchorNodeInsideCanvas = domUtils.containsNode(canvasElement, selection.anchorNode); - focusNodeInsideCanvas = domUtils.containsNode(canvasElement, selection.focusNode); + runtime.assert(selection.anchorNode !== null && selection.focusNode !== null, "anchorNode or focusNode is null"); + validSelection = (selection); + anchorNodeInsideCanvas = domUtils.containsNode(canvasElement, validSelection.anchorNode); + focusNodeInsideCanvas = domUtils.containsNode(canvasElement, validSelection.focusNode); if(!anchorNodeInsideCanvas && !focusNodeInsideCanvas) { - return null + return } if(!anchorNodeInsideCanvas) { - node = findClosestPosition(selection.anchorNode); - selection.anchorNode = node.node; - selection.anchorOffset = node.offset + position = findClosestPosition(validSelection.anchorNode); + validSelection.anchorNode = position.node; + validSelection.anchorOffset = position.offset } if(!focusNodeInsideCanvas) { - node = findClosestPosition(selection.focusNode); - selection.focusNode = node.node; - selection.focusOffset = node.offset + position = findClosestPosition(validSelection.focusNode); + validSelection.focusNode = position.node; + validSelection.focusOffset = position.offset } if(clickCount === 2) { - expandToWordBoundaries(selection) + expandToWordBoundaries(validSelection) }else { if(clickCount === 3) { - expandToParagraphBoundaries(selection) + expandToParagraphBoundaries(validSelection) } } - canvasElement.focus(); - return selection - } - function getFirstWalkablePositionInNode(node) { - var position = 0, iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), watch = new core.LoopWatchDog(1E3), inside = false; - while(iterator.nextPosition()) { - watch.check(); - inside = Boolean(node.compareDocumentPosition(iterator.container()) & Node.DOCUMENT_POSITION_CONTAINED_BY); - if(baseFilter.acceptPosition(iterator) === FILTER_ACCEPT) { - if(inside) { - break - } - position += 1 - } + stepsToAnchor = odtDocument.getDistanceFromCursor(inputMemberId, validSelection.anchorNode, validSelection.anchorOffset); + if(validSelection.focusNode === validSelection.anchorNode && validSelection.focusOffset === validSelection.anchorOffset) { + stepsToFocus = stepsToAnchor + }else { + stepsToFocus = odtDocument.getDistanceFromCursor(inputMemberId, validSelection.focusNode, validSelection.focusOffset) } - return position - } - function getWalkableNodeLength(node) { - var length = 0, iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), inside = false; - iterator.setUnfilteredPosition(node, 0); - do { - inside = Boolean(node.compareDocumentPosition(iterator.container()) & Node.DOCUMENT_POSITION_CONTAINED_BY); - if(!inside && node !== iterator.container()) { - break - } - if(baseFilter.acceptPosition(iterator) === FILTER_ACCEPT) { - length += 1 - } - }while(iterator.nextPosition()); - return length - } - function removeAnnotation(annotationNode) { - var position, length, op; - position = getFirstWalkablePositionInNode(annotationNode); - length = getWalkableNodeLength(annotationNode); - op = new ops.OpRemoveAnnotation; - op.init({memberid:inputMemberId, position:position, length:length}); - session.enqueue(op) - } - function selectRange(e) { - runtime.setTimeout(function() { - var selection = getSelection(e), oldPosition, stepsToAnchor, stepsToFocus, op; - if(selection === null) { - return - } - stepsToAnchor = countStepsToNode(selection.anchorNode, selection.anchorOffset); - if(selection.focusNode === selection.anchorNode && selection.focusOffset === selection.anchorOffset) { - stepsToFocus = stepsToAnchor - }else { - stepsToFocus = countStepsToNode(selection.focusNode, selection.focusOffset) - } - if(stepsToFocus !== null && stepsToFocus !== 0 || stepsToAnchor !== null && stepsToAnchor !== 0) { - oldPosition = odtDocument.getCursorPosition(inputMemberId); - op = createOpMoveCursor(oldPosition + stepsToAnchor, stepsToFocus - stepsToAnchor); - session.enqueue(op) - } - }, 0) - } - function handleContextMenu(e) { - selectRange(e) + if(stepsToFocus || stepsToAnchor) { + oldPosition = odtDocument.getCursorPosition(inputMemberId); + op = createOpMoveCursor(oldPosition + stepsToAnchor, stepsToFocus - stepsToAnchor, ops.OdtCursor.RangeSelection); + session.enqueue([op]) + } + eventManager.focus() } function extendCursorByAdjustment(lengthAdjust) { var selection = odtDocument.getCursorSelection(inputMemberId), stepCounter = odtDocument.getCursor(inputMemberId).getStepCounter(), newLength; if(lengthAdjust !== 0) { lengthAdjust = lengthAdjust > 0 ? stepCounter.convertForwardStepsBetweenFilters(lengthAdjust, keyboardMovementsFilter, baseFilter) : -stepCounter.convertBackwardStepsBetweenFilters(-lengthAdjust, keyboardMovementsFilter, baseFilter); newLength = selection.length + lengthAdjust; - session.enqueue(createOpMoveCursor(selection.position, newLength)) + session.enqueue([createOpMoveCursor(selection.position, newLength)]) } } function moveCursorByAdjustment(positionAdjust) { @@ -13245,7 +14425,7 @@ gui.SessionController = function() { if(positionAdjust !== 0) { positionAdjust = positionAdjust > 0 ? stepCounter.convertForwardStepsBetweenFilters(positionAdjust, keyboardMovementsFilter, baseFilter) : -stepCounter.convertBackwardStepsBetweenFilters(-positionAdjust, keyboardMovementsFilter, baseFilter); position = position + positionAdjust; - session.enqueue(createOpMoveCursor(position, 0)) + session.enqueue([createOpMoveCursor(position, 0)]) } } function moveCursorToLeft() { @@ -13378,18 +14558,43 @@ gui.SessionController = function() { steps = -odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()); iterator.moveToEnd(); steps += odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()); - session.enqueue(createOpMoveCursor(0, steps)); + session.enqueue([createOpMoveCursor(0, steps)]); return true } function maintainCursorSelection() { - var cursor = odtDocument.getCursor(inputMemberId), selection = window.getSelection(); + var cursor = odtDocument.getCursor(inputMemberId), selection = window.getSelection(), imageElement, range; if(cursor) { - selection.removeAllRanges(); - selection.addRange(cursor.getSelectedRange().cloneRange()) + imageSelector.clearSelection(); + if(cursor.getSelectionType() === ops.OdtCursor.RegionSelection) { + imageElement = odfUtils.getImageElements(cursor.getSelectedRange())[0]; + if(imageElement) { + imageSelector.select((imageElement.parentNode)) + } + } + if(eventManager.hasFocus()) { + range = cursor.getSelectedRange(); + if(selection.extend) { + if(cursor.hasForwardSelection()) { + selection.collapse(range.startContainer, range.startOffset); + selection.extend(range.endContainer, range.endOffset) + }else { + selection.collapse(range.endContainer, range.endOffset); + selection.extend(range.startContainer, range.startOffset) + } + }else { + selection.removeAllRanges(); + selection.addRange(range.cloneRange()) + } + } + }else { + imageSelector.clearSelection() } } + function delayedMaintainCursor() { + runtime.setTimeout(maintainCursorSelection, 0) + } function stringFromKeyPress(event) { - if(event.which === null) { + if(event.which === null || event.which === undefined) { return String.fromCharCode(event.keyCode) } if(event.which !== 0 && event.charCode !== 0) { @@ -13463,64 +14668,120 @@ gui.SessionController = function() { return false } function filterMouseClicks(e) { - clickStartedWithinContainer = e.target && domUtils.containsNode(odtDocument.getOdfCanvas().getElement(), e.target) + var target = getTarget(e); + clickStartedWithinContainer = target && domUtils.containsNode(odtDocument.getOdfCanvas().getElement(), target); + if(clickStartedWithinContainer) { + isMouseMoved = false; + mouseDownRootFilter = odtDocument.createRootFilter(target) + } + } + function cursorToSelection(cursor) { + var range = cursor.getSelectedRange(); + if(cursor.hasForwardSelection()) { + return{anchorNode:range.startContainer, anchorOffset:range.startOffset, focusNode:range.endContainer, focusOffset:range.endOffset} + } + return{anchorNode:range.endContainer, anchorOffset:range.endOffset, focusNode:range.startContainer, focusOffset:range.startOffset} + } + function mutableSelection(selection) { + if(selection) { + return{anchorNode:selection.anchorNode, anchorOffset:selection.anchorOffset, focusNode:selection.focusNode, focusOffset:selection.focusOffset} + } + return null + } + function handleMouseClickEvent(event) { + var target = getTarget(event), eventDetails = {detail:event.detail, clientX:event.clientX, clientY:event.clientY, target:target}; + drawShadowCursorTask.processRequests(); + if(odfUtils.isImage(target) && odfUtils.isCharacterFrame(target.parentNode)) { + selectImage(target.parentNode) + }else { + if(clickStartedWithinContainer && !imageSelector.isSelectorElement(target)) { + if(isMouseMoved) { + selectRange(cursorToSelection(shadowCursor), event) + }else { + runtime.setTimeout(function() { + selectRange(mutableSelection(window.getSelection()), eventDetails) + }, 0) + } + } + } + clickStartedWithinContainer = false; + isMouseMoved = false + } + function handleContextMenu(e) { + handleMouseClickEvent(e) } function handleMouseUp(event) { - var target = event.target, annotationNode = null; + var target = getTarget(event), annotationNode = null; if(target.className === "annotationRemoveButton") { annotationNode = domUtils.getElementsByTagNameNS(target.parentNode, odf.Namespaces.officens, "annotation")[0]; - removeAnnotation(annotationNode) + annotationManager.removeAnnotation(annotationNode) }else { - if(clickStartedWithinContainer) { - selectRange(event) + handleMouseClickEvent(event) + } + } + function updateShadowCursor() { + var selection = window.getSelection(), selectionRange, isForwardSelection; + if(clickStartedWithinContainer && selection.rangeCount > 0) { + isMouseMoved = true; + imageSelector.clearSelection(); + shadowCursorIterator.setUnfilteredPosition((selection.focusNode), selection.focusOffset); + if(mouseDownRootFilter.acceptPosition(shadowCursorIterator) === FILTER_ACCEPT) { + selectionRange = selection.getRangeAt(0).cloneRange(); + isForwardSelection = selection.anchorNode === selectionRange.startContainer && selection.anchorOffset === selectionRange.startOffset; + shadowCursor.setSelectedRange(selectionRange, isForwardSelection); + odtDocument.emit(ops.OdtDocument.signalCursorMoved, shadowCursor) } } } this.startEditing = function() { - var canvasElement, op; - canvasElement = odtDocument.getOdfCanvas().getElement(); - listenEvent(canvasElement, "keydown", keyDownHandler.handleEvent); - listenEvent(canvasElement, "keypress", keyPressHandler.handleEvent); - listenEvent(canvasElement, "keyup", dummyHandler); - listenEvent(canvasElement, "beforecut", handleBeforeCut, true); - listenEvent(canvasElement, "cut", handleCut); - listenEvent(canvasElement, "copy", handleCopy); - listenEvent(canvasElement, "beforepaste", handleBeforePaste, true); - listenEvent(canvasElement, "paste", handlePaste); - listenEvent(window, "mousedown", filterMouseClicks); - listenEvent(window, "mouseup", handleMouseUp); - listenEvent(canvasElement, "contextmenu", handleContextMenu); + var op; + odtDocument.getOdfCanvas().getElement().classList.add("virtualSelections"); + eventManager.subscribe("keydown", keyDownHandler.handleEvent); + eventManager.subscribe("keypress", keyPressHandler.handleEvent); + eventManager.subscribe("keyup", dummyHandler); + eventManager.subscribe("beforecut", handleBeforeCut); + eventManager.subscribe("cut", handleCut); + eventManager.subscribe("copy", handleCopy); + eventManager.subscribe("beforepaste", handleBeforePaste); + eventManager.subscribe("paste", handlePaste); + eventManager.subscribe("mousedown", filterMouseClicks); + eventManager.subscribe("mousemove", drawShadowCursorTask.trigger); + eventManager.subscribe("mouseup", handleMouseUp); + eventManager.subscribe("contextmenu", handleContextMenu); + eventManager.subscribe("focus", delayedMaintainCursor); odtDocument.subscribe(ops.OdtDocument.signalOperationExecuted, maintainCursorSelection); odtDocument.subscribe(ops.OdtDocument.signalOperationExecuted, updateUndoStack); op = new ops.OpAddCursor; op.init({memberid:inputMemberId}); - session.enqueue(op); + session.enqueue([op]); if(undoManager) { undoManager.saveInitialState() } }; this.endEditing = function() { - var canvasElement, op; - odtDocument.unsubscribe(ops.OdtDocument.signalOperationExecuted, updateUndoStack); - odtDocument.unsubscribe(ops.OdtDocument.signalOperationExecuted, maintainCursorSelection); - canvasElement = odtDocument.getOdfCanvas().getElement(); - removeEvent(canvasElement, "keydown", keyDownHandler.handleEvent); - removeEvent(canvasElement, "keypress", keyPressHandler.handleEvent); - removeEvent(canvasElement, "keyup", dummyHandler); - removeEvent(canvasElement, "cut", handleCut); - removeEvent(canvasElement, "beforecut", handleBeforeCut); - removeEvent(canvasElement, "copy", handleCopy); - removeEvent(canvasElement, "paste", handlePaste); - removeEvent(canvasElement, "beforepaste", handleBeforePaste); - removeEvent(window, "mousedown", filterMouseClicks); - removeEvent(window, "mouseup", handleMouseUp); - removeEvent(canvasElement, "contextmenu", handleContextMenu); + var op; op = new ops.OpRemoveCursor; op.init({memberid:inputMemberId}); - session.enqueue(op); + session.enqueue([op]); if(undoManager) { undoManager.resetInitialState() } + odtDocument.unsubscribe(ops.OdtDocument.signalOperationExecuted, updateUndoStack); + odtDocument.unsubscribe(ops.OdtDocument.signalOperationExecuted, maintainCursorSelection); + eventManager.unsubscribe("keydown", keyDownHandler.handleEvent); + eventManager.unsubscribe("keypress", keyPressHandler.handleEvent); + eventManager.unsubscribe("keyup", dummyHandler); + eventManager.unsubscribe("cut", handleCut); + eventManager.unsubscribe("beforecut", handleBeforeCut); + eventManager.unsubscribe("copy", handleCopy); + eventManager.unsubscribe("paste", handlePaste); + eventManager.unsubscribe("beforepaste", handleBeforePaste); + eventManager.unsubscribe("mousemove", drawShadowCursorTask.trigger); + eventManager.unsubscribe("mousedown", filterMouseClicks); + eventManager.unsubscribe("mouseup", handleMouseUp); + eventManager.unsubscribe("contextmenu", handleContextMenu); + eventManager.unsubscribe("focus", delayedMaintainCursor); + odtDocument.getOdfCanvas().getElement().classList.remove("virtualSelections") }; this.getInputMemberId = function() { return inputMemberId @@ -13544,106 +14805,136 @@ gui.SessionController = function() { this.getUndoManager = function() { return undoManager }; + this.getAnnotationManager = function() { + return annotationManager + }; this.getDirectTextStyler = function() { return directTextStyler }; this.getDirectParagraphStyler = function() { return directParagraphStyler }; + this.getImageManager = function() { + return imageManager + }; this.getTextManipulator = function() { return textManipulator }; + this.getEventManager = function() { + return eventManager + }; + this.getKeyboardHandlers = function() { + return{keydown:keyDownHandler, keypress:keyPressHandler} + }; this.destroy = function(callback) { - var destroyDirectTextStyler = directTextStyler ? directTextStyler.destroy : function(cb) { - cb() - }, destroyDirectParagraphStyler = directParagraphStyler ? directParagraphStyler.destroy : function(cb) { - cb() - }; - destroyDirectTextStyler(function(err) { - if(err) { - callback(err) - }else { - destroyDirectParagraphStyler(callback) - } - }) + var destroyCallbacks = [drawShadowCursorTask.destroy]; + if(directTextStyler) { + destroyCallbacks.push(directTextStyler.destroy) + } + if(directParagraphStyler) { + destroyCallbacks.push(directParagraphStyler.destroy) + } + async.destroyAll(destroyCallbacks, callback) }; + function returnTrue(fn) { + return function() { + fn(); + return true + } + } + function rangeSelectionOnly(fn) { + return function(e) { + var selectionType = odtDocument.getCursor(inputMemberId).getSelectionType(); + if(selectionType === ops.OdtCursor.RangeSelection) { + return fn(e) + } + return true + } + } function init() { var isMacOS = window.navigator.appVersion.toLowerCase().indexOf("mac") !== -1, modifier = gui.KeyboardHandler.Modifier, keyCode = gui.KeyboardHandler.KeyCode; - keyDownHandler.bind(keyCode.Tab, modifier.None, function() { + drawShadowCursorTask = new core.ScheduledTask(updateShadowCursor, 0); + keyDownHandler.bind(keyCode.Tab, modifier.None, rangeSelectionOnly(function() { textManipulator.insertText("\t"); return true - }); - keyDownHandler.bind(keyCode.Left, modifier.None, moveCursorToLeft); - keyDownHandler.bind(keyCode.Right, modifier.None, moveCursorToRight); - keyDownHandler.bind(keyCode.Up, modifier.None, moveCursorUp); - keyDownHandler.bind(keyCode.Down, modifier.None, moveCursorDown); - keyDownHandler.bind(keyCode.Backspace, modifier.None, textManipulator.removeTextByBackspaceKey); + })); + keyDownHandler.bind(keyCode.Left, modifier.None, rangeSelectionOnly(moveCursorToLeft)); + keyDownHandler.bind(keyCode.Right, modifier.None, rangeSelectionOnly(moveCursorToRight)); + keyDownHandler.bind(keyCode.Up, modifier.None, rangeSelectionOnly(moveCursorUp)); + keyDownHandler.bind(keyCode.Down, modifier.None, rangeSelectionOnly(moveCursorDown)); + keyDownHandler.bind(keyCode.Backspace, modifier.None, returnTrue(textManipulator.removeTextByBackspaceKey)); keyDownHandler.bind(keyCode.Delete, modifier.None, textManipulator.removeTextByDeleteKey); - keyDownHandler.bind(keyCode.Left, modifier.Shift, extendSelectionToLeft); - keyDownHandler.bind(keyCode.Right, modifier.Shift, extendSelectionToRight); - keyDownHandler.bind(keyCode.Up, modifier.Shift, extendSelectionUp); - keyDownHandler.bind(keyCode.Down, modifier.Shift, extendSelectionDown); - keyDownHandler.bind(keyCode.Home, modifier.None, moveCursorToLineStart); - keyDownHandler.bind(keyCode.End, modifier.None, moveCursorToLineEnd); - keyDownHandler.bind(keyCode.Home, modifier.Ctrl, moveCursorToDocumentStart); - keyDownHandler.bind(keyCode.End, modifier.Ctrl, moveCursorToDocumentEnd); - keyDownHandler.bind(keyCode.Home, modifier.Shift, extendSelectionToLineStart); - keyDownHandler.bind(keyCode.End, modifier.Shift, extendSelectionToLineEnd); - keyDownHandler.bind(keyCode.Up, modifier.CtrlShift, extendSelectionToParagraphStart); - keyDownHandler.bind(keyCode.Down, modifier.CtrlShift, extendSelectionToParagraphEnd); - keyDownHandler.bind(keyCode.Home, modifier.CtrlShift, extendSelectionToDocumentStart); - keyDownHandler.bind(keyCode.End, modifier.CtrlShift, extendSelectionToDocumentEnd); + keyDownHandler.bind(keyCode.Left, modifier.Shift, rangeSelectionOnly(extendSelectionToLeft)); + keyDownHandler.bind(keyCode.Right, modifier.Shift, rangeSelectionOnly(extendSelectionToRight)); + keyDownHandler.bind(keyCode.Up, modifier.Shift, rangeSelectionOnly(extendSelectionUp)); + keyDownHandler.bind(keyCode.Down, modifier.Shift, rangeSelectionOnly(extendSelectionDown)); + keyDownHandler.bind(keyCode.Home, modifier.None, rangeSelectionOnly(moveCursorToLineStart)); + keyDownHandler.bind(keyCode.End, modifier.None, rangeSelectionOnly(moveCursorToLineEnd)); + keyDownHandler.bind(keyCode.Home, modifier.Ctrl, rangeSelectionOnly(moveCursorToDocumentStart)); + keyDownHandler.bind(keyCode.End, modifier.Ctrl, rangeSelectionOnly(moveCursorToDocumentEnd)); + keyDownHandler.bind(keyCode.Home, modifier.Shift, rangeSelectionOnly(extendSelectionToLineStart)); + keyDownHandler.bind(keyCode.End, modifier.Shift, rangeSelectionOnly(extendSelectionToLineEnd)); + keyDownHandler.bind(keyCode.Up, modifier.CtrlShift, rangeSelectionOnly(extendSelectionToParagraphStart)); + keyDownHandler.bind(keyCode.Down, modifier.CtrlShift, rangeSelectionOnly(extendSelectionToParagraphEnd)); + keyDownHandler.bind(keyCode.Home, modifier.CtrlShift, rangeSelectionOnly(extendSelectionToDocumentStart)); + keyDownHandler.bind(keyCode.End, modifier.CtrlShift, rangeSelectionOnly(extendSelectionToDocumentEnd)); if(isMacOS) { keyDownHandler.bind(keyCode.Clear, modifier.None, textManipulator.removeCurrentSelection); - keyDownHandler.bind(keyCode.Left, modifier.Meta, moveCursorToLineStart); - keyDownHandler.bind(keyCode.Right, modifier.Meta, moveCursorToLineEnd); - keyDownHandler.bind(keyCode.Home, modifier.Meta, moveCursorToDocumentStart); - keyDownHandler.bind(keyCode.End, modifier.Meta, moveCursorToDocumentEnd); - keyDownHandler.bind(keyCode.Left, modifier.MetaShift, extendSelectionToLineStart); - keyDownHandler.bind(keyCode.Right, modifier.MetaShift, extendSelectionToLineEnd); - keyDownHandler.bind(keyCode.Up, modifier.AltShift, extendSelectionToParagraphStart); - keyDownHandler.bind(keyCode.Down, modifier.AltShift, extendSelectionToParagraphEnd); - keyDownHandler.bind(keyCode.Up, modifier.MetaShift, extendSelectionToDocumentStart); - keyDownHandler.bind(keyCode.Down, modifier.MetaShift, extendSelectionToDocumentEnd); - keyDownHandler.bind(keyCode.A, modifier.Meta, extendSelectionToEntireDocument); + keyDownHandler.bind(keyCode.Left, modifier.Meta, rangeSelectionOnly(moveCursorToLineStart)); + keyDownHandler.bind(keyCode.Right, modifier.Meta, rangeSelectionOnly(moveCursorToLineEnd)); + keyDownHandler.bind(keyCode.Home, modifier.Meta, rangeSelectionOnly(moveCursorToDocumentStart)); + keyDownHandler.bind(keyCode.End, modifier.Meta, rangeSelectionOnly(moveCursorToDocumentEnd)); + keyDownHandler.bind(keyCode.Left, modifier.MetaShift, rangeSelectionOnly(extendSelectionToLineStart)); + keyDownHandler.bind(keyCode.Right, modifier.MetaShift, rangeSelectionOnly(extendSelectionToLineEnd)); + keyDownHandler.bind(keyCode.Up, modifier.AltShift, rangeSelectionOnly(extendSelectionToParagraphStart)); + keyDownHandler.bind(keyCode.Down, modifier.AltShift, rangeSelectionOnly(extendSelectionToParagraphEnd)); + keyDownHandler.bind(keyCode.Up, modifier.MetaShift, rangeSelectionOnly(extendSelectionToDocumentStart)); + keyDownHandler.bind(keyCode.Down, modifier.MetaShift, rangeSelectionOnly(extendSelectionToDocumentEnd)); + keyDownHandler.bind(keyCode.A, modifier.Meta, rangeSelectionOnly(extendSelectionToEntireDocument)); if(directTextStyler) { - keyDownHandler.bind(keyCode.B, modifier.Meta, directTextStyler.toggleBold); - keyDownHandler.bind(keyCode.I, modifier.Meta, directTextStyler.toggleItalic); - keyDownHandler.bind(keyCode.U, modifier.Meta, directTextStyler.toggleUnderline) + keyDownHandler.bind(keyCode.B, modifier.Meta, rangeSelectionOnly(directTextStyler.toggleBold)); + keyDownHandler.bind(keyCode.I, modifier.Meta, rangeSelectionOnly(directTextStyler.toggleItalic)); + keyDownHandler.bind(keyCode.U, modifier.Meta, rangeSelectionOnly(directTextStyler.toggleUnderline)) } if(directParagraphStyler) { - keyDownHandler.bind(keyCode.L, modifier.MetaShift, directParagraphStyler.alignParagraphLeft); - keyDownHandler.bind(keyCode.E, modifier.MetaShift, directParagraphStyler.alignParagraphCenter); - keyDownHandler.bind(keyCode.R, modifier.MetaShift, directParagraphStyler.alignParagraphRight); - keyDownHandler.bind(keyCode.J, modifier.MetaShift, directParagraphStyler.alignParagraphJustified) + keyDownHandler.bind(keyCode.L, modifier.MetaShift, rangeSelectionOnly(directParagraphStyler.alignParagraphLeft)); + keyDownHandler.bind(keyCode.E, modifier.MetaShift, rangeSelectionOnly(directParagraphStyler.alignParagraphCenter)); + keyDownHandler.bind(keyCode.R, modifier.MetaShift, rangeSelectionOnly(directParagraphStyler.alignParagraphRight)); + keyDownHandler.bind(keyCode.J, modifier.MetaShift, rangeSelectionOnly(directParagraphStyler.alignParagraphJustified)) + } + if(annotationManager) { + keyDownHandler.bind(keyCode.C, modifier.MetaShift, annotationManager.addAnnotation) } keyDownHandler.bind(keyCode.Z, modifier.Meta, undo); keyDownHandler.bind(keyCode.Z, modifier.MetaShift, redo) }else { - keyDownHandler.bind(keyCode.A, modifier.Ctrl, extendSelectionToEntireDocument); + keyDownHandler.bind(keyCode.A, modifier.Ctrl, rangeSelectionOnly(extendSelectionToEntireDocument)); if(directTextStyler) { - keyDownHandler.bind(keyCode.B, modifier.Ctrl, directTextStyler.toggleBold); - keyDownHandler.bind(keyCode.I, modifier.Ctrl, directTextStyler.toggleItalic); - keyDownHandler.bind(keyCode.U, modifier.Ctrl, directTextStyler.toggleUnderline) + keyDownHandler.bind(keyCode.B, modifier.Ctrl, rangeSelectionOnly(directTextStyler.toggleBold)); + keyDownHandler.bind(keyCode.I, modifier.Ctrl, rangeSelectionOnly(directTextStyler.toggleItalic)); + keyDownHandler.bind(keyCode.U, modifier.Ctrl, rangeSelectionOnly(directTextStyler.toggleUnderline)) } if(directParagraphStyler) { - keyDownHandler.bind(keyCode.L, modifier.CtrlShift, directParagraphStyler.alignParagraphLeft); - keyDownHandler.bind(keyCode.E, modifier.CtrlShift, directParagraphStyler.alignParagraphCenter); - keyDownHandler.bind(keyCode.R, modifier.CtrlShift, directParagraphStyler.alignParagraphRight); - keyDownHandler.bind(keyCode.J, modifier.CtrlShift, directParagraphStyler.alignParagraphJustified) + keyDownHandler.bind(keyCode.L, modifier.CtrlShift, rangeSelectionOnly(directParagraphStyler.alignParagraphLeft)); + keyDownHandler.bind(keyCode.E, modifier.CtrlShift, rangeSelectionOnly(directParagraphStyler.alignParagraphCenter)); + keyDownHandler.bind(keyCode.R, modifier.CtrlShift, rangeSelectionOnly(directParagraphStyler.alignParagraphRight)); + keyDownHandler.bind(keyCode.J, modifier.CtrlShift, rangeSelectionOnly(directParagraphStyler.alignParagraphJustified)) + } + if(annotationManager) { + keyDownHandler.bind(keyCode.C, modifier.CtrlAlt, annotationManager.addAnnotation) } keyDownHandler.bind(keyCode.Z, modifier.Ctrl, undo); keyDownHandler.bind(keyCode.Z, modifier.CtrlShift, redo) } - keyPressHandler.setDefault(function(e) { + keyPressHandler.setDefault(rangeSelectionOnly(function(e) { var text = stringFromKeyPress(e); - if(text && !(e.altKey || e.ctrlKey || e.metaKey)) { + if(text && !(e.altKey || (e.ctrlKey || e.metaKey))) { textManipulator.insertText(text); return true } return false - }); - keyPressHandler.bind(keyCode.Enter, modifier.None, textManipulator.enqueueParagraphSplittingOps) + })); + keyPressHandler.bind(keyCode.Enter, modifier.None, rangeSelectionOnly(textManipulator.enqueueParagraphSplittingOps)) } init() }; @@ -13661,6 +14952,9 @@ gui.SessionController = function() { 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 @@ -13681,7 +14975,7 @@ gui.SessionController = function() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.MemberModel = function MemberModel() { }; @@ -13703,6 +14997,9 @@ ops.MemberModel.prototype.close = function(callback) { 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 @@ -13723,11 +15020,11 @@ ops.MemberModel.prototype.close = function(callback) { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.TrivialMemberModel = function TrivialMemberModel() { this.getMemberDetailsAndUpdates = function(memberId, subscriber) { - subscriber(memberId, {memberid:memberId, fullname:"Unknown", color:"black", imageurl:"avatar-joe.png"}) + subscriber(memberId, {memberid:memberId, fullname:runtime.tr("Unknown Author"), color:"black", imageurl:"avatar-joe.png"}) }; this.unsubscribeMemberDetailsUpdates = function(memberId, subscriber) { }; @@ -13747,6 +15044,9 @@ ops.TrivialMemberModel = function TrivialMemberModel() { 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 @@ -13767,7 +15067,7 @@ ops.TrivialMemberModel = function TrivialMemberModel() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.OperationRouter = function OperationRouter() { }; @@ -13775,14 +15075,10 @@ ops.OperationRouter.prototype.setOperationFactory = function(f) { }; ops.OperationRouter.prototype.setPlaybackFunction = function(playback_func) { }; -ops.OperationRouter.prototype.push = function(op) { +ops.OperationRouter.prototype.push = function(operations) { }; ops.OperationRouter.prototype.close = function(callback) { }; -ops.OperationRouter.prototype.getHasLocalUnsyncedOpsAndUpdates = function(subscriber) { -}; -ops.OperationRouter.prototype.unsubscribeHasLocalUnsyncedOpsUpdates = function(subscriber) { -}; /* Copyright (C) 2012 KO GmbH @@ -13795,6 +15091,9 @@ ops.OperationRouter.prototype.unsubscribeHasLocalUnsyncedOpsUpdates = function(s 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 @@ -13815,7 +15114,7 @@ ops.OperationRouter.prototype.unsubscribeHasLocalUnsyncedOpsUpdates = function(s This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ ops.TrivialOperationRouter = function TrivialOperationRouter() { var operationFactory, playbackFunction; @@ -13825,19 +15124,16 @@ ops.TrivialOperationRouter = function TrivialOperationRouter() { this.setPlaybackFunction = function(playback_func) { playbackFunction = playback_func }; - this.push = function(op) { - var timedOp, opspec = op.spec(); - opspec.timestamp = (new Date).getTime(); - timedOp = operationFactory.create(opspec); - playbackFunction(timedOp) + this.push = function(operations) { + operations.forEach(function(op) { + var timedOp, opspec = op.spec(); + opspec.timestamp = (new Date).getTime(); + timedOp = operationFactory.create(opspec); + playbackFunction(timedOp) + }) }; this.close = function(cb) { cb() - }; - this.getHasLocalUnsyncedOpsAndUpdates = function(subscriber) { - subscriber(true) - }; - this.unsubscribeHasLocalUnsyncedOpsUpdates = function(subscriber) { } }; gui.EditInfoHandle = function EditInfoHandle(parentElement) { @@ -13898,6 +15194,9 @@ gui.EditInfoHandle = function EditInfoHandle(parentElement) { 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 @@ -13918,19 +15217,19 @@ gui.EditInfoHandle = function EditInfoHandle(parentElement) { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("ops.EditInfo"); runtime.loadClass("gui.EditInfoHandle"); gui.EditInfoMarker = function EditInfoMarker(editInfo, initialVisibility) { var self = this, editInfoNode, handle, marker, editinfons = "urn:webodf:names:editinfo", decay1, decay2, decayTimeStep = 1E4; function applyDecay(opacity, delay) { - return runtime.getWindow().setTimeout(function() { + return runtime.setTimeout(function() { marker.style.opacity = opacity }, delay) } function deleteDecay(timer) { - runtime.getWindow().clearTimeout(timer) + runtime.clearTimeout(timer) } function setLastAuthor(memberid) { marker.setAttributeNS(editinfons, "editinfo:memberid", memberid) @@ -14026,6 +15325,9 @@ gui.EditInfoMarker = function EditInfoMarker(editInfo, initialVisibility) { 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 @@ -14046,7 +15348,7 @@ gui.EditInfoMarker = function EditInfoMarker(editInfo, initialVisibility) { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("gui.Caret"); runtime.loadClass("ops.TrivialMemberModel"); @@ -14061,13 +15363,13 @@ gui.SessionView = function() { function configOption(userValue, defaultValue) { return userValue !== undefined ? Boolean(userValue) : defaultValue } - function SessionView(viewOptions, session, caretManager) { - var avatarInfoStyles, editInfons = "urn:webodf:names:editinfo", editInfoMap = {}, showEditInfoMarkers = configOption(viewOptions.editInfoMarkersInitiallyVisible, true), showCaretAvatars = configOption(viewOptions.caretAvatarsInitiallyVisible, true), blinkOnRangeSelect = configOption(viewOptions.caretBlinksOnRangeSelect, true); + function SessionView(viewOptions, localMemberId, session, caretManager, selectionViewManager) { + var avatarInfoStyles, editInfons = "urn:webodf:names:editinfo", editInfoMap = {}, showEditInfoMarkers = configOption(viewOptions.editInfoMarkersInitiallyVisible, true), showCaretAvatars = configOption(viewOptions.caretAvatarsInitiallyVisible, true), blinkOnRangeSelect = configOption(viewOptions.caretBlinksOnRangeSelect, true), rerenderIntervalId, rerenderSelectionViews = false, RERENDER_INTERVAL = 200; function createAvatarInfoNodeMatch(nodeName, memberId, pseudoClass) { - return nodeName + '[editinfo|memberid^="' + memberId + '"]' + pseudoClass + return nodeName + '[editinfo|memberid="' + memberId + '"]' + pseudoClass } function getAvatarInfoStyle(nodeName, memberId, pseudoClass) { - var node = avatarInfoStyles.firstChild, nodeMatch = createAvatarInfoNodeMatch(nodeName, memberId, pseudoClass); + var node = avatarInfoStyles.firstChild, nodeMatch = createAvatarInfoNodeMatch(nodeName, memberId, pseudoClass) + "{"; while(node) { if(node.nodeType === Node.TEXT_NODE && node.data.indexOf(nodeMatch) === 0) { return node @@ -14089,7 +15391,8 @@ gui.SessionView = function() { 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("dc|creator", "{ background-color: " + color + "; }", ""); + setStyle("div.selectionOverlay", "{ background-color: " + color + ";}", "") } function highlightEdit(element, memberId, timestamp) { var editInfo, editInfoMarker, id = "", editInfoNode = element.getElementsByTagNameNS(editInfons, "editinfo")[0]; @@ -14172,15 +15475,37 @@ gui.SessionView = function() { caret.setAvatarImageUrl(memberData.imageurl); caret.setColor(memberData.color) } - setAvatarInfoStyle(memberId, memberData.fullname, memberData.color) + setAvatarInfoStyle(memberId, memberData.fullname, memberData.color); + if(localMemberId === memberId) { + setAvatarInfoStyle("", memberData.fullname, memberData.color) + } } function onCursorAdded(cursor) { var memberId = cursor.getMemberId(), memberModel = session.getMemberModel(); caretManager.registerCursor(cursor, showCaretAvatars, blinkOnRangeSelect); + selectionViewManager.registerCursor(cursor, true); renderMemberData(memberId, null); memberModel.getMemberDetailsAndUpdates(memberId, renderMemberData); runtime.log("+++ View here +++ eagerly created an Caret for '" + memberId + "'! +++") } + function onCursorMoved(cursor) { + var memberId = cursor.getMemberId(), localSelectionView = selectionViewManager.getSelectionView(localMemberId), shadowSelectionView = selectionViewManager.getSelectionView(gui.ShadowCursor.ShadowCursorMemberId), localCaret = caretManager.getCaret(localMemberId); + if(memberId === localMemberId) { + shadowSelectionView.hide(); + localSelectionView.show(); + if(localCaret) { + localCaret.show() + } + }else { + if(memberId === gui.ShadowCursor.ShadowCursorMemberId) { + shadowSelectionView.show(); + localSelectionView.hide(); + if(localCaret) { + localCaret.hide() + } + } + } + } function onCursorRemoved(memberid) { var hasMemberEditInfo = false, keyname; for(keyname in editInfoMap) { @@ -14189,6 +15514,7 @@ gui.SessionView = function() { break } } + selectionViewManager.removeSelectionView(memberid); if(!hasMemberEditInfo) { session.getMemberModel().unsubscribeMemberDetailsUpdates(memberid, renderMemberData) } @@ -14196,6 +15522,20 @@ gui.SessionView = function() { function onParagraphChanged(info) { highlightEdit(info.paragraphElement, info.memberId, info.timeStamp) } + function requestRerenderOfSelectionViews() { + rerenderSelectionViews = true + } + function startRerenderLoop() { + rerenderIntervalId = runtime.getWindow().setInterval(function() { + if(rerenderSelectionViews) { + selectionViewManager.rerenderSelectionViews(); + rerenderSelectionViews = false + } + }, RERENDER_INTERVAL) + } + function stopRerenderLoop() { + runtime.getWindow().clearInterval(rerenderIntervalId) + } this.destroy = function(callback) { var odtDocument = session.getOdtDocument(), memberModel = session.getMemberModel(), editInfoArray = Object.keys(editInfoMap).map(function(keyname) { return editInfoMap[keyname] @@ -14203,6 +15543,11 @@ gui.SessionView = function() { odtDocument.unsubscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); + odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); + odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, requestRerenderOfSelectionViews); + odtDocument.unsubscribe(ops.OdtDocument.signalTableAdded, requestRerenderOfSelectionViews); + odtDocument.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, requestRerenderOfSelectionViews); + stopRerenderLoop(); caretManager.getCarets().forEach(function(caret) { memberModel.unsubscribeMemberDetailsUpdates(caret.getCursor().getMemberId(), renderMemberData) }); @@ -14226,6 +15571,11 @@ gui.SessionView = function() { odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded); odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved); odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, onParagraphChanged); + odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved); + startRerenderLoop(); + odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, requestRerenderOfSelectionViews); + odtDocument.subscribe(ops.OdtDocument.signalTableAdded, requestRerenderOfSelectionViews); + odtDocument.subscribe(ops.OdtDocument.signalParagraphStyleModified, requestRerenderOfSelectionViews); avatarInfoStyles = document.createElementNS(head.namespaceURI, "style"); avatarInfoStyles.type = "text/css"; avatarInfoStyles.media = "screen, print, handheld, projection"; @@ -14249,6 +15599,9 @@ gui.SessionView = function() { 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 @@ -14264,484 +15617,138 @@ gui.SessionView = function() { and the LGPL for the libraries. If you modify this code, you may extend this exception to your version of the code, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -runtime.loadClass("gui.Caret"); -gui.CaretManager = function CaretManager(sessionController) { - var carets = {}, window = runtime.getWindow(); - function getCaret(memberId) { - return carets.hasOwnProperty(memberId) ? carets[memberId] : null - } - function getCarets() { - return Object.keys(carets).map(function(memberid) { - return carets[memberid] - }) - } - function getCanvasElement() { - return sessionController.getSession().getOdtDocument().getOdfCanvas().getElement() - } - function removeCaret(memberId) { - if(memberId === sessionController.getInputMemberId()) { - getCanvasElement().removeAttribute("tabindex") - } - delete carets[memberId] - } - function refreshLocalCaretBlinking(cursor) { - var caret, memberId = cursor.getMemberId(); - if(memberId === sessionController.getInputMemberId()) { - caret = getCaret(memberId); - if(caret) { - caret.refreshCursorBlinking() - } - } - } - function ensureLocalCaretVisible(info) { - var caret; - if(info.memberId === sessionController.getInputMemberId()) { - caret = getCaret(info.memberId); - if(caret) { - caret.ensureVisible() - } - } - } - function focusLocalCaret() { - var caret = getCaret(sessionController.getInputMemberId()); - if(caret) { - caret.setFocus() - } - } - function blurLocalCaret() { - var caret = getCaret(sessionController.getInputMemberId()); - if(caret) { - caret.removeFocus() - } - } - function showLocalCaret() { - var caret = getCaret(sessionController.getInputMemberId()); - if(caret) { - caret.show() - } - } - function hideLocalCaret() { - var caret = getCaret(sessionController.getInputMemberId()); - if(caret) { - caret.hide() - } - } - this.registerCursor = function(cursor, caretAvatarInitiallyVisible, blinkOnRangeSelect) { - var memberid = cursor.getMemberId(), canvasElement = getCanvasElement(), caret = new gui.Caret(cursor, caretAvatarInitiallyVisible, blinkOnRangeSelect); - carets[memberid] = caret; - if(memberid === sessionController.getInputMemberId()) { - runtime.log("Starting to track input on new cursor of " + memberid); - cursor.handleUpdate = caret.ensureVisible; - canvasElement.setAttribute("tabindex", 0); - canvasElement.focus() - } - return caret - }; - this.getCaret = getCaret; - this.getCarets = getCarets; - this.destroy = function(callback) { - var odtDocument = sessionController.getSession().getOdtDocument(), canvasElement = getCanvasElement(), caretArray = getCarets(); - odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, ensureLocalCaretVisible); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, refreshLocalCaretBlinking); - odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, removeCaret); - canvasElement.removeEventListener("focus", focusLocalCaret, false); - canvasElement.removeEventListener("blur", blurLocalCaret, false); - window.removeEventListener("focus", showLocalCaret, false); - window.removeEventListener("blur", hideLocalCaret, false); - (function destroyCaret(i, err) { - if(err) { - callback(err) - }else { - if(i < caretArray.length) { - caretArray[i].destroy(function(err) { - destroyCaret(i + 1, err) - }) - }else { - callback() - } - } - })(0, undefined) - }; - function init() { - var odtDocument = sessionController.getSession().getOdtDocument(), canvasElement = getCanvasElement(); - odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, ensureLocalCaretVisible); - odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, refreshLocalCaretBlinking); - odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, removeCaret); - canvasElement.addEventListener("focus", focusLocalCaret, false); - canvasElement.addEventListener("blur", blurLocalCaret, false); - window.addEventListener("focus", showLocalCaret, false); - window.addEventListener("blur", hideLocalCaret, false) - } - init() -}; -runtime.loadClass("xmldom.XPath"); -runtime.loadClass("odf.Namespaces"); -gui.PresenterUI = function() { - var xpath = new xmldom.XPath, window = runtime.getWindow(); - return function PresenterUI(odf_element) { - var self = this; - self.setInitialSlideMode = function() { - self.startSlideMode("single") - }; - self.keyDownHandler = function(ev) { - if(ev.target.isContentEditable) { - return - } - if(ev.target.nodeName === "input") { - return - } - switch(ev.keyCode) { - case 84: - self.toggleToolbar(); - break; - case 37: - ; - case 8: - self.prevSlide(); - break; - case 39: - ; - case 32: - self.nextSlide(); - break; - case 36: - self.firstSlide(); - break; - case 35: - self.lastSlide(); - break - } - }; - self.root = function() { - return self.odf_canvas.odfContainer().rootElement - }; - self.firstSlide = function() { - self.slideChange(function(old, pc) { - return 0 - }) - }; - self.lastSlide = function() { - self.slideChange(function(old, pc) { - return pc - 1 - }) - }; - self.nextSlide = function() { - self.slideChange(function(old, pc) { - return old + 1 < pc ? old + 1 : -1 - }) - }; - self.prevSlide = function() { - self.slideChange(function(old, pc) { - return old < 1 ? -1 : old - 1 - }) - }; - self.slideChange = function(indexChanger) { - var pages = self.getPages(self.odf_canvas.odfContainer().rootElement), last = -1, i = 0, newidx, pagelist; - pages.forEach(function(tuple) { - var node = tuple[1]; - if(node.hasAttribute("slide_current")) { - last = i; - node.removeAttribute("slide_current") - } - i += 1 - }); - newidx = indexChanger(last, pages.length); - if(newidx === -1) { - newidx = last - } - pages[newidx][1].setAttribute("slide_current", "1"); - pagelist = document.getElementById("pagelist"); - pagelist.selectedIndex = newidx; - if(self.slide_mode === "cont") { - window.scrollBy(0, pages[newidx][1].getBoundingClientRect().top - 30) - } - }; - self.selectSlide = function(idx) { - self.slideChange(function(old, pc) { - if(idx >= pc) { - return-1 - } - if(idx < 0) { - return-1 - } - return idx - }) - }; - self.scrollIntoContView = function(idx) { - var pages = self.getPages(self.odf_canvas.odfContainer().rootElement); - if(pages.length === 0) { - return - } - window.scrollBy(0, pages[idx][1].getBoundingClientRect().top - 30) - }; - self.getPages = function(root) { - var pagenodes = root.getElementsByTagNameNS(odf.Namespaces.drawns, "page"), pages = [], i; - for(i = 0;i < pagenodes.length;i += 1) { - pages.push([pagenodes[i].getAttribute("draw:name"), pagenodes[i]]) - } - return pages - }; - self.fillPageList = function(odfdom_root, html_select) { - var pages = self.getPages(odfdom_root), i, html_option, res, page_denom; - while(html_select.firstChild) { - html_select.removeChild(html_select.firstChild) - } - for(i = 0;i < pages.length;i += 1) { - html_option = document.createElement("option"); - res = xpath.getODFElementsWithXPath(pages[i][1], './draw:frame[@presentation:class="title"]//draw:text-box/text:p', xmldom.XPath); - page_denom = res.length > 0 ? res[0].textContent : pages[i][0]; - html_option.textContent = i + 1 + ": " + page_denom; - html_select.appendChild(html_option) - } - }; - self.startSlideMode = function(mode) { - var pagelist = document.getElementById("pagelist"), css = self.odf_canvas.slidevisibilitycss().sheet; - self.slide_mode = mode; - while(css.cssRules.length > 0) { - css.deleteRule(0) - } - self.selectSlide(0); - if(self.slide_mode === "single") { - css.insertRule("draw|page { position:fixed; left:0px;top:30px; z-index:1; }", 0); - css.insertRule("draw|page[slide_current] { z-index:2;}", 1); - css.insertRule("draw|page { -webkit-transform: scale(1);}", 2); - self.fitToWindow(); - window.addEventListener("resize", self.fitToWindow, false) - }else { - if(self.slide_mode === "cont") { - window.removeEventListener("resize", self.fitToWindow, false) - } - } - self.fillPageList(self.odf_canvas.odfContainer().rootElement, pagelist) - }; - self.toggleToolbar = function() { - var css, found, i; - css = self.odf_canvas.slidevisibilitycss().sheet; - found = -1; - for(i = 0;i < css.cssRules.length;i += 1) { - if(css.cssRules[i].cssText.substring(0, 8) === ".toolbar") { - found = i; - break - } - } - if(found > -1) { - css.deleteRule(found) - }else { - css.insertRule(".toolbar { position:fixed; left:0px;top:-200px; z-index:0; }", 0) - } - }; - self.fitToWindow = function() { - function ruleByFactor(f) { - return"draw|page { \n" + "-moz-transform: scale(" + f + "); \n" + "-moz-transform-origin: 0% 0%; " + "-webkit-transform-origin: 0% 0%; -webkit-transform: scale(" + f + "); " + "-o-transform-origin: 0% 0%; -o-transform: scale(" + f + "); " + "-ms-transform-origin: 0% 0%; -ms-transform: scale(" + f + "); " + "}" - } - var pages = self.getPages(self.root()), factorVert = (window.innerHeight - 40) / pages[0][1].clientHeight, factorHoriz = (window.innerWidth - 10) / pages[0][1].clientWidth, factor = factorVert < factorHoriz ? factorVert : factorHoriz, css = self.odf_canvas.slidevisibilitycss().sheet; - css.deleteRule(2); - css.insertRule(ruleByFactor(factor), 2) - }; - self.load = function(url) { - self.odf_canvas.load(url) - }; - self.odf_element = odf_element; - self.odf_canvas = new odf.OdfCanvas(self.odf_element); - self.odf_canvas.addListener("statereadychange", self.setInitialSlideMode); - self.slide_mode = "undefined"; - document.addEventListener("keydown", self.keyDownHandler, false) - } -}(); -runtime.loadClass("core.PositionIterator"); -runtime.loadClass("core.Cursor"); -gui.XMLEdit = function XMLEdit(element, stylesheet) { - var simplecss, cssprefix, documentElement, walker = null; - if(!element.id) { - element.id = "xml" + String(Math.random()).substring(2) - } - cssprefix = "#" + element.id + " "; - simplecss = cssprefix + "*," + cssprefix + ":visited, " + cssprefix + ":link {display:block; margin: 0px; margin-left: 10px; font-size: medium; color: black; background: white; font-variant: normal; font-weight: normal; font-style: normal; font-family: sans-serif; text-decoration: none; white-space: pre-wrap; height: auto; width: auto}\n" + cssprefix + ":before {color: blue; content: '<' attr(customns_name) attr(customns_atts) '>';}\n" + cssprefix + ":after {color: blue; content: '';}\n" + - cssprefix + "{overflow: auto;}\n"; - function listenEvent(eventTarget, eventType, eventHandler) { - if(eventTarget.addEventListener) { - eventTarget.addEventListener(eventType, eventHandler, false) - }else { - if(eventTarget.attachEvent) { - eventType = "on" + eventType; - eventTarget.attachEvent(eventType, eventHandler) - }else { - eventTarget["on" + eventType] = eventHandler - } - } + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: https://github.com/kogmbh/WebODF/ +*/ +runtime.loadClass("gui.Caret"); +gui.CaretManager = function CaretManager(sessionController) { + var carets = {}, window = runtime.getWindow(), scrollIntoViewScheduled = false; + function getCaret(memberId) { + return carets.hasOwnProperty(memberId) ? carets[memberId] : null } - function cancelEvent(event) { - if(event.preventDefault) { - event.preventDefault() - }else { - event.returnValue = false - } + function getCarets() { + return Object.keys(carets).map(function(memberid) { + return carets[memberid] + }) } - function isCaretMoveCommand(charCode) { - if(charCode >= 16 && charCode <= 20) { - return true - } - if(charCode >= 33 && charCode <= 40) { - return true - } - return false + function getCanvasElement() { + return sessionController.getSession().getOdtDocument().getOdfCanvas().getElement() } - function syncSelectionWithWalker() { - var sel = element.ownerDocument.defaultView.getSelection(), r; - if(!sel || sel.rangeCount <= 0 || !walker) { - return + function removeCaret(memberId) { + if(memberId === sessionController.getInputMemberId()) { + getCanvasElement().removeAttribute("tabindex") } - r = sel.getRangeAt(0); - walker.setPoint(r.startContainer, r.startOffset) + delete carets[memberId] } - function syncWalkerWithSelection() { - var sel = element.ownerDocument.defaultView.getSelection(), n, r; - sel.removeAllRanges(); - if(!walker || !walker.node()) { - return - } - n = walker.node(); - r = n.ownerDocument.createRange(); - r.setStart(n, walker.position()); - r.collapse(true); - sel.addRange(r) - } - function handleKeyDown(event) { - var charCode = event.charCode || event.keyCode; - walker = null; - if(walker && charCode === 39) { - syncSelectionWithWalker(); - walker.stepForward(); - syncWalkerWithSelection() - }else { - if(walker && charCode === 37) { - syncSelectionWithWalker(); - walker.stepBackward(); - syncWalkerWithSelection() - }else { - if(isCaretMoveCommand(charCode)) { - return - } + function refreshLocalCaretBlinking(cursor) { + var caret, memberId = cursor.getMemberId(); + if(memberId === sessionController.getInputMemberId()) { + caret = getCaret(memberId); + if(caret) { + caret.refreshCursorBlinking() } } - cancelEvent(event) } - function handleClick(event) { - cancelEvent(event) - } - function initElement(element) { - listenEvent(element, "click", handleClick); - listenEvent(element, "keydown", handleKeyDown); - listenEvent(element, "drop", cancelEvent); - listenEvent(element, "dragend", cancelEvent); - listenEvent(element, "beforepaste", cancelEvent); - listenEvent(element, "paste", cancelEvent) + function executeEnsureCaretVisible() { + var caret = getCaret(sessionController.getInputMemberId()); + scrollIntoViewScheduled = false; + if(caret) { + caret.ensureVisible() + } } - function cleanWhitespace(node) { - var n = node.firstChild, p, re = /^\s*$/; - while(n && n !== node) { - p = n; - n = n.nextSibling || n.parentNode; - if(p.nodeType === Node.TEXT_NODE && re.test(p.nodeValue)) { - p.parentNode.removeChild(p) + function scheduleCaretVisibilityCheck() { + var caret = getCaret(sessionController.getInputMemberId()); + if(caret) { + caret.handleUpdate(); + if(!scrollIntoViewScheduled) { + scrollIntoViewScheduled = true; + runtime.setTimeout(executeEnsureCaretVisible, 50) } } } - function setCssHelperAttributes(node) { - var atts, attsv, a, i; - atts = node.attributes; - attsv = ""; - for(i = atts.length - 1;i >= 0;i -= 1) { - a = atts.item(i); - attsv = attsv + " " + a.nodeName + '="' + a.nodeValue + '"' + function ensureLocalCaretVisible(info) { + if(info.memberId === sessionController.getInputMemberId()) { + scheduleCaretVisibilityCheck() } - node.setAttribute("customns_name", node.nodeName); - node.setAttribute("customns_atts", attsv) } - function addExplicitAttributes(node) { - var n = node.firstChild; - while(n && n !== node) { - if(n.nodeType === Node.ELEMENT_NODE) { - addExplicitAttributes(n) - } - n = n.nextSibling || n.parentNode + function focusLocalCaret() { + var caret = getCaret(sessionController.getInputMemberId()); + if(caret) { + caret.setFocus() } - setCssHelperAttributes(node); - cleanWhitespace(node) } - function getNamespacePrefixes(node, prefixes) { - var n = node.firstChild, atts, att, i; - while(n && n !== node) { - if(n.nodeType === Node.ELEMENT_NODE) { - getNamespacePrefixes(n, prefixes); - atts = n.attributes; - for(i = atts.length - 1;i >= 0;i -= 1) { - att = atts.item(i); - if(att.namespaceURI === "http://www.w3.org/2000/xmlns/") { - if(!prefixes[att.nodeValue]) { - prefixes[att.nodeValue] = att.localName - } - } - } - } - n = n.nextSibling || n.parentNode + function blurLocalCaret() { + var caret = getCaret(sessionController.getInputMemberId()); + if(caret) { + caret.removeFocus() } } - function generateUniquePrefixes(prefixes) { - var taken = {}, ns, p, n = 0; - for(ns in prefixes) { - if(prefixes.hasOwnProperty(ns) && ns) { - p = prefixes[ns]; - if(!p || taken.hasOwnProperty(p) || p === "xmlns") { - do { - p = "ns" + n; - n += 1 - }while(taken.hasOwnProperty(p)); - prefixes[ns] = p - } - taken[p] = true - } + function showLocalCaret() { + var caret = getCaret(sessionController.getInputMemberId()); + if(caret) { + caret.show() } } - function createCssFromXmlInstance(node) { - var prefixes = {}, css = "@namespace customns url(customns);\n"; - getNamespacePrefixes(node, prefixes); - generateUniquePrefixes(prefixes); - return css - } - function updateCSS() { - var css = element.ownerDocument.createElement("style"), text = createCssFromXmlInstance(element); - css.type = "text/css"; - text = text + simplecss; - css.appendChild(element.ownerDocument.createTextNode(text)); - stylesheet = stylesheet.parentNode.replaceChild(css, stylesheet) - } - function getXML() { - return documentElement + function hideLocalCaret() { + var caret = getCaret(sessionController.getInputMemberId()); + if(caret) { + caret.hide() + } } - function setXML(xml) { - var node = xml.documentElement || xml; - node = element.ownerDocument.importNode(node, true); - documentElement = node; - addExplicitAttributes(node); - while(element.lastChild) { - element.removeChild(element.lastChild) + this.registerCursor = function(cursor, caretAvatarInitiallyVisible, blinkOnRangeSelect) { + var memberid = cursor.getMemberId(), caret = new gui.Caret(cursor, caretAvatarInitiallyVisible, blinkOnRangeSelect); + carets[memberid] = caret; + if(memberid === sessionController.getInputMemberId()) { + runtime.log("Starting to track input on new cursor of " + memberid); + cursor.handleUpdate = scheduleCaretVisibilityCheck; + getCanvasElement().setAttribute("tabindex", -1); + sessionController.getEventManager().focus() + }else { + cursor.handleUpdate = caret.handleUpdate } - element.appendChild(node); - updateCSS(); - walker = new core.PositionIterator(node) + return caret + }; + this.getCaret = getCaret; + this.getCarets = getCarets; + this.destroy = function(callback) { + var odtDocument = sessionController.getSession().getOdtDocument(), eventManager = sessionController.getEventManager(), caretArray = getCarets(); + odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, ensureLocalCaretVisible); + odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, refreshLocalCaretBlinking); + odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, removeCaret); + eventManager.unsubscribe("focus", focusLocalCaret); + eventManager.unsubscribe("blur", blurLocalCaret); + window.removeEventListener("focus", showLocalCaret, false); + window.removeEventListener("blur", hideLocalCaret, false); + (function destroyCaret(i, err) { + if(err) { + callback(err) + }else { + if(i < caretArray.length) { + caretArray[i].destroy(function(err) { + destroyCaret(i + 1, err) + }) + }else { + callback() + } + } + })(0, undefined); + carets = {} + }; + function init() { + var odtDocument = sessionController.getSession().getOdtDocument(), eventManager = sessionController.getEventManager(); + odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, ensureLocalCaretVisible); + odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, refreshLocalCaretBlinking); + odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, removeCaret); + eventManager.subscribe("focus", focusLocalCaret); + eventManager.subscribe("blur", blurLocalCaret); + window.addEventListener("focus", showLocalCaret, false); + window.addEventListener("blur", hideLocalCaret, false) } - initElement(element); - this.updateCSS = updateCSS; - this.setXML = setXML; - this.getXML = getXML + init() }; /* @@ -14755,6 +15762,9 @@ gui.XMLEdit = function XMLEdit(element, stylesheet) { 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 @@ -14775,7 +15785,7 @@ gui.XMLEdit = function XMLEdit(element, stylesheet) { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ gui.UndoManager = function UndoManager() { }; @@ -14819,6 +15829,9 @@ gui.UndoManager.signalUndoStateModified = "undoStateModified"; 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 @@ -14839,7 +15852,7 @@ gui.UndoManager.signalUndoStateModified = "undoStateModified"; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ gui.UndoStateRules = function UndoStateRules() { function getOpType(op) { @@ -14911,6 +15924,9 @@ gui.UndoStateRules = function UndoStateRules() { 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 @@ -14931,7 +15947,7 @@ gui.UndoStateRules = function UndoStateRules() { This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils"); runtime.loadClass("gui.UndoManager"); @@ -15094,6 +16110,387 @@ gui.TrivialUndoManager.signalDocumentRootReplaced = "documentRootReplaced"; (function() { return gui.TrivialUndoManager })(); +runtime.loadClass("core.DomUtils"); +runtime.loadClass("odf.OdfUtils"); +runtime.loadClass("odf.OdfNodeFilter"); +runtime.loadClass("gui.SelectionMover"); +gui.SelectionView = function SelectionView(cursor) { + var odtDocument = cursor.getOdtDocument(), 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() + } + clientRectRange.selectNode(node); + return clientRectRange.getBoundingClientRect() + } + function setRect(div, rect) { + div.style.left = rect.left + "px"; + div.style.top = rect.top + "px"; + div.style.width = rect.width + "px"; + div.style.height = rect.height + "px" + } + function showOverlays(choice) { + var display; + isVisible = choice; + display = choice === true ? "block" : "none"; + overlayTop.style.display = overlayMiddle.style.display = overlayBottom.style.display = display + } + function translateRect(rect) { + var rootRect = getBoundingClientRect(root), zoomLevel = odtDocument.getOdfCanvas().getZoomLevel(), resultRect = {}; + resultRect.top = domUtils.adaptRangeDifferenceToZoomLevel(rect.top - rootRect.top, zoomLevel); + resultRect.left = domUtils.adaptRangeDifferenceToZoomLevel(rect.left - rootRect.left, zoomLevel); + resultRect.bottom = domUtils.adaptRangeDifferenceToZoomLevel(rect.bottom - rootRect.top, zoomLevel); + resultRect.right = domUtils.adaptRangeDifferenceToZoomLevel(rect.right - rootRect.left, zoomLevel); + resultRect.width = domUtils.adaptRangeDifferenceToZoomLevel(rect.width, zoomLevel); + resultRect.height = domUtils.adaptRangeDifferenceToZoomLevel(rect.height, zoomLevel); + return resultRect + } + function isRangeVisible(range) { + var bcr = range.getBoundingClientRect(); + return Boolean(bcr && bcr.height !== 0) + } + function lastVisibleRect(range, nodes) { + var nextNodeIndex = nodes.length - 1, node = nodes[nextNodeIndex], startOffset = range.endContainer === node ? range.endOffset : node.length || node.childNodes.length, endOffset = startOffset; + range.setStart(node, startOffset); + range.setEnd(node, endOffset); + while(!isRangeVisible(range)) { + if(node.nodeType === Node.ELEMENT_NODE && startOffset > 0) { + startOffset = 0 + }else { + if(node.nodeType === Node.TEXT_NODE && startOffset > 0) { + startOffset -= 1 + }else { + if(nodes[nextNodeIndex]) { + node = nodes[nextNodeIndex]; + nextNodeIndex -= 1; + startOffset = endOffset = node.length || node.childNodes.length + }else { + return false + } + } + } + range.setStart(node, startOffset); + range.setEnd(node, endOffset) + } + return true + } + function firstVisibleRect(range, nodes) { + var nextNodeIndex = 0, node = nodes[nextNodeIndex], startOffset = range.startContainer === node ? range.startOffset : 0, endOffset = startOffset; + range.setStart(node, startOffset); + range.setEnd(node, endOffset); + while(!isRangeVisible(range)) { + if(node.nodeType === Node.ELEMENT_NODE && endOffset < node.childNodes.length) { + endOffset = node.childNodes.length + }else { + if(node.nodeType === Node.TEXT_NODE && endOffset < node.length) { + endOffset += 1 + }else { + if(nodes[nextNodeIndex]) { + node = nodes[nextNodeIndex]; + nextNodeIndex += 1; + startOffset = endOffset = 0 + }else { + return false + } + } + } + range.setStart(node, startOffset); + range.setEnd(node, endOffset) + } + return true + } + function getExtremeRanges(range) { + var nodes = odfUtils.getTextElements(range, true, false), firstRange = (range.cloneRange()), lastRange = (range.cloneRange()), fillerRange = range.cloneRange(); + if(!nodes.length) { + return null + } + if(!firstVisibleRect(firstRange, nodes)) { + return null + } + if(!lastVisibleRect(lastRange, nodes)) { + return null + } + fillerRange.setStart(firstRange.startContainer, firstRange.startOffset); + fillerRange.setEnd(lastRange.endContainer, lastRange.endOffset); + return{firstRange:firstRange, lastRange:lastRange, fillerRange:fillerRange} + } + function getBoundingRect(rect1, rect2) { + var resultRect = {}; + resultRect.top = Math.min(rect1.top, rect2.top); + resultRect.left = Math.min(rect1.left, rect2.left); + resultRect.right = Math.max(rect1.right, rect2.right); + resultRect.bottom = Math.max(rect1.bottom, rect2.bottom); + resultRect.width = resultRect.right - resultRect.left; + resultRect.height = resultRect.bottom - resultRect.top; + return resultRect + } + function checkAndGrowOrCreateRect(originalRect, newRect) { + if(newRect && (newRect.width > 0 && newRect.height > 0)) { + if(!originalRect) { + originalRect = newRect + }else { + originalRect = getBoundingRect(originalRect, newRect) + } + } + return originalRect + } + function getFillerRect(fillerRange) { + var containerNode = fillerRange.commonAncestorContainer, firstNode = fillerRange.startContainer, lastNode = fillerRange.endContainer, firstOffset = fillerRange.startOffset, lastOffset = fillerRange.endOffset, currentNode, lastMeasuredNode, firstSibling, lastSibling, grownRect = null, currentRect, range = doc.createRange(), rootFilter, odfNodeFilter = new odf.OdfNodeFilter, treeWalker; + function acceptNode(node) { + positionIterator.setUnfilteredPosition(node, 0); + if(odfNodeFilter.acceptNode(node) === FILTER_ACCEPT && rootFilter.acceptPosition(positionIterator) === FILTER_ACCEPT) { + return FILTER_ACCEPT + } + return FILTER_REJECT + } + function getRectFromNodeAfterFiltering(node) { + var rect = null; + if(acceptNode(node) === FILTER_ACCEPT) { + rect = getBoundingClientRect(node) + } + return rect + } + if(firstNode === containerNode || lastNode === containerNode) { + range = fillerRange.cloneRange(); + grownRect = range.getBoundingClientRect(); + range.detach(); + return grownRect + } + firstSibling = firstNode; + while(firstSibling.parentNode !== containerNode) { + firstSibling = firstSibling.parentNode + } + lastSibling = lastNode; + while(lastSibling.parentNode !== containerNode) { + lastSibling = lastSibling.parentNode + } + rootFilter = odtDocument.createRootFilter(firstNode); + currentNode = firstSibling.nextSibling; + while(currentNode && currentNode !== lastSibling) { + currentRect = getRectFromNodeAfterFiltering(currentNode); + grownRect = checkAndGrowOrCreateRect(grownRect, currentRect); + currentNode = currentNode.nextSibling + } + if(odfUtils.isParagraph(firstSibling)) { + grownRect = checkAndGrowOrCreateRect(grownRect, getBoundingClientRect(firstSibling)) + }else { + treeWalker = doc.createTreeWalker(firstSibling, NodeFilter.SHOW_TEXT, acceptNode); + 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)) + }else { + treeWalker = doc.createTreeWalker(lastSibling, NodeFilter.SHOW_TEXT, acceptNode); + currentNode = treeWalker.currentNode = lastNode; + while(currentNode && currentNode !== lastMeasuredNode) { + range.setStart(currentNode, 0); + range.setEnd(currentNode, lastOffset); + currentRect = range.getBoundingClientRect(); + grownRect = checkAndGrowOrCreateRect(grownRect, currentRect); + currentNode = treeWalker.previousNode(); + if(currentNode) { + lastOffset = currentNode.length + } + } + } + return grownRect + } + function getCollapsedRectOfTextRange(range, useRightEdge) { + var clientRect = range.getBoundingClientRect(), collapsedRect = {}; + collapsedRect.width = 0; + collapsedRect.top = clientRect.top; + collapsedRect.bottom = clientRect.bottom; + collapsedRect.height = clientRect.height; + collapsedRect.left = collapsedRect.right = useRightEdge ? clientRect.right : clientRect.left; + return collapsedRect + } + function repositionOverlays(selectedRange) { + var extremes = getExtremeRanges(selectedRange), firstRange, lastRange, fillerRange, firstRect, fillerRect, lastRect; + if(selectedRange.collapsed || !extremes) { + showOverlays(false) + }else { + showOverlays(true); + firstRange = extremes.firstRange; + lastRange = extremes.lastRange; + fillerRange = extremes.fillerRange; + firstRect = translateRect(getCollapsedRectOfTextRange(firstRange, false)); + lastRect = translateRect(getCollapsedRectOfTextRange(lastRange, true)); + fillerRect = getFillerRect(fillerRange); + if(!fillerRect) { + fillerRect = getBoundingRect(firstRect, lastRect) + }else { + fillerRect = translateRect(fillerRect) + } + setRect(overlayTop, {left:firstRect.left, top:firstRect.top, width:Math.max(0, fillerRect.width - (firstRect.left - fillerRect.left)), height:firstRect.height}); + if(lastRect.top === firstRect.top || lastRect.bottom === firstRect.bottom) { + overlayMiddle.style.display = overlayBottom.style.display = "none" + }else { + setRect(overlayBottom, {left:fillerRect.left, top:lastRect.top, width:Math.max(0, lastRect.right - fillerRect.left), height:lastRect.height}); + setRect(overlayMiddle, {left:fillerRect.left, top:firstRect.top + firstRect.height, width:Math.max(0, parseFloat(overlayTop.style.left) + parseFloat(overlayTop.style.width) - parseFloat(overlayBottom.style.left)), height:Math.max(0, lastRect.top - firstRect.bottom)}) + } + firstRange.detach(); + lastRange.detach(); + fillerRange.detach() + } + } + function rerender() { + if(cursor.getSelectionType() === ops.OdtCursor.RangeSelection) { + showOverlays(true); + repositionOverlays(cursor.getSelectedRange()) + }else { + showOverlays(false) + } + } + this.rerender = rerender; + this.show = rerender; + this.hide = function() { + showOverlays(false) + }; + this.visible = function() { + return isVisible + }; + function handleCursorMove(movedCursor) { + if(movedCursor === cursor) { + rerender() + } + } + this.destroy = function(callback) { + root.removeChild(overlayTop); + root.removeChild(overlayMiddle); + root.removeChild(overlayBottom); + cursor.getOdtDocument().unsubscribe(ops.OdtDocument.signalCursorMoved, handleCursorMove); + callback() + }; + function init() { + var editinfons = "urn:webodf:names:editinfo", memberid = cursor.getMemberId(); + root.appendChild(overlayTop); + root.appendChild(overlayMiddle); + root.appendChild(overlayBottom); + overlayTop.setAttributeNS(editinfons, "editinfo:memberid", memberid); + overlayMiddle.setAttributeNS(editinfons, "editinfo:memberid", memberid); + overlayBottom.setAttributeNS(editinfons, "editinfo:memberid", memberid); + overlayTop.className = overlayMiddle.className = overlayBottom.className = "selectionOverlay"; + cursor.getOdtDocument().subscribe(ops.OdtDocument.signalCursorMoved, handleCursorMove) + } + 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 + 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("gui.SelectionView"); +gui.SelectionViewManager = function SelectionViewManager() { + var selectionViews = {}; + function getSelectionView(memberId) { + return selectionViews.hasOwnProperty(memberId) ? selectionViews[memberId] : null + } + this.getSelectionView = getSelectionView; + function getSelectionViews() { + return Object.keys(selectionViews).map(function(memberid) { + return selectionViews[memberid] + }) + } + this.getSelectionViews = getSelectionViews; + function removeSelectionView(memberId) { + if(selectionViews.hasOwnProperty(memberId)) { + selectionViews[memberId].destroy(function() { + }); + delete selectionViews[memberId] + } + } + this.removeSelectionView = removeSelectionView; + function hideSelectionView(memberId) { + if(selectionViews.hasOwnProperty(memberId)) { + selectionViews[memberId].hide() + } + } + this.hideSelectionView = hideSelectionView; + function showSelectionView(memberId) { + if(selectionViews.hasOwnProperty(memberId)) { + selectionViews[memberId].show() + } + } + this.showSelectionView = showSelectionView; + this.rerenderSelectionViews = function() { + Object.keys(selectionViews).forEach(function(memberId) { + if(selectionViews[memberId].visible()) { + selectionViews[memberId].rerender() + } + }) + }; + this.registerCursor = function(cursor, virtualSelectionsInitiallyVisible) { + var memberId = cursor.getMemberId(), selectionView = new gui.SelectionView(cursor); + if(virtualSelectionsInitiallyVisible) { + selectionView.show() + }else { + selectionView.hide() + } + selectionViews[memberId] = selectionView; + return selectionView + }; + this.destroy = function(callback) { + var selectionViewArray = getSelectionViews(); + (function destroySelectionView(i, err) { + if(err) { + callback(err) + }else { + if(i < selectionViewArray.length) { + selectionViewArray[i].destroy(function(err) { + destroySelectionView(i + 1, err) + }) + }else { + callback() + } + } + })(0, undefined) + } +}; /* Copyright (C) 2012-2013 KO GmbH @@ -15106,6 +16503,9 @@ gui.TrivialUndoManager.signalDocumentRootReplaced = "documentRootReplaced"; 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 @@ -15126,14 +16526,13 @@ gui.TrivialUndoManager.signalDocumentRootReplaced = "documentRootReplaced"; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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("gui.StyleHelper"); runtime.loadClass("core.PositionFilterChain"); 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]), FILTER_ACCEPT = @@ -15143,7 +16542,7 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { runtime.assert(localName === "text", "Unsupported content element type '" + localName + "'for OdtDocument"); return element } - function RootFilter(memberId) { + function RootFilter(anchor) { function isRoot(node) { if(node.namespaceURI === odf.Namespaces.officens && node.localName === "text" || node.namespaceURI === odf.Namespaces.officens && node.localName === "annotation") { return true @@ -15151,14 +16550,19 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { return false } function getRoot(node) { - while(!isRoot(node)) { + while(node && !isRoot(node)) { node = (node.parentNode) } return node } this.acceptPosition = function(iterator) { - var node = iterator.container(), cursorNode = cursors[memberId].getNode(); - if(getRoot(node) === getRoot(cursorNode)) { + var node = iterator.container(), anchorNode; + if(typeof anchor === "string") { + anchorNode = cursors[anchor].getNode() + }else { + anchorNode = anchor + } + if(getRoot(node) === getRoot(anchorNode)) { return FILTER_ACCEPT } return FILTER_REJECT @@ -15305,9 +16709,9 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { if(lastTextNode === null) { return null } - if(memberid && cursors[memberid] && self.getCursorPosition(memberid) === originalPosition) { + if(memberid && (cursors[memberid] && self.getCursorPosition(memberid) === originalPosition)) { cursorNode = cursors[memberid].getNode(); - while(nodeOffset === 0 && cursorNode.nextSibling && cursorNode.nextSibling.localName === "cursor") { + while(nodeOffset === 0 && (cursorNode.nextSibling && cursorNode.nextSibling.localName === "cursor")) { cursorNode.parentNode.insertBefore(cursorNode, cursorNode.nextSibling.nextSibling) } if(lastTextNode.length > 0) { @@ -15315,7 +16719,7 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { nodeOffset = 0; cursorNode.parentNode.insertBefore(lastTextNode, cursorNode.nextSibling) } - while(nodeOffset === 0 && lastTextNode.previousSibling && lastTextNode.previousSibling.localName === "cursor") { + while(nodeOffset === 0 && (lastTextNode.previousSibling && lastTextNode.previousSibling.localName === "cursor")) { node = lastTextNode.previousSibling; if(lastTextNode.length > 0) { lastTextNode = getRootNode().ownerDocument.createTextNode("") @@ -15369,7 +16773,7 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { for(i = -1;i <= 1;i += 1) { container = iterator.container(); offset = iterator.unfilteredDomOffset(); - if(container.nodeType === Node.TEXT_NODE && container.data[offset] === " " && odfUtils.isSignificantWhitespace(container, offset)) { + if(container.nodeType === Node.TEXT_NODE && (container.data[offset] === " " && odfUtils.isSignificantWhitespace(container, offset))) { container = upgradeWhitespaceToElement((container), offset); iterator.moveToEndOfNode(container) } @@ -15402,28 +16806,40 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { this.getParagraphElement = getParagraphElement; this.getParagraphStyleAttributes = getParagraphStyleAttributes; this.getPositionInTextNode = getPositionInTextNode; - this.fixCursorPositions = function(localMemberId) { - var memberId, cursor, stepCounter, steps, rootConstrainedFilter = new core.PositionFilterChain; - rootConstrainedFilter.addFilter("BaseFilter", self.getPositionFilter()); - for(memberId in cursors) { - if(cursors.hasOwnProperty(memberId)) { - rootConstrainedFilter.addFilter("RootFilter", self.createRootFilter(memberId)); - cursor = cursors[memberId]; - stepCounter = cursor.getStepCounter(); - if(!stepCounter.isPositionWalkable(rootConstrainedFilter)) { - steps = stepCounter.countStepsToValidPosition(rootConstrainedFilter); - cursor.move(steps); - if(memberId === localMemberId) { - self.emit(ops.OdtDocument.signalCursorMoved, cursor) + this.fixCursorPositions = function() { + var rootConstrainedFilter = new core.PositionFilterChain; + rootConstrainedFilter.addFilter("BaseFilter", filter); + Object.keys(cursors).forEach(function(memberId) { + var cursor = cursors[memberId], stepCounter = cursor.getStepCounter(), stepsSelectionLength, positionsToAdjustFocus, positionsToAdjustAnchor, positionsToAnchor, cursorMoved = false; + rootConstrainedFilter.addFilter("RootFilter", self.createRootFilter(memberId)); + stepsSelectionLength = stepCounter.countStepsToPosition(cursor.getAnchorNode(), 0, rootConstrainedFilter); + if(!stepCounter.isPositionWalkable(rootConstrainedFilter)) { + cursorMoved = true; + positionsToAdjustFocus = stepCounter.countPositionsToNearestStep(cursor.getNode(), 0, rootConstrainedFilter); + positionsToAdjustAnchor = stepCounter.countPositionsToNearestStep(cursor.getAnchorNode(), 0, rootConstrainedFilter); + cursor.move(positionsToAdjustFocus); + if(stepsSelectionLength !== 0) { + if(positionsToAdjustAnchor > 0) { + stepsSelectionLength += 1 } - }else { - if(self.getCursorSelection(memberId).length === 0) { - cursor.move(0) + if(positionsToAdjustFocus > 0) { + stepsSelectionLength -= 1 } + positionsToAnchor = stepCounter.countSteps(stepsSelectionLength, rootConstrainedFilter); + cursor.move(positionsToAnchor); + cursor.move(-positionsToAnchor, true) + } + }else { + if(stepsSelectionLength === 0) { + cursorMoved = true; + cursor.move(0) } - rootConstrainedFilter.removeFilter("RootFilter") } - } + if(cursorMoved) { + self.emit(ops.OdtDocument.signalCursorMoved, cursor) + } + rootConstrainedFilter.removeFilter("RootFilter") + }) }; this.getWalkableParagraphLength = function(paragraph) { var iterator = getIteratorAtPosition(0), length = 0; @@ -15483,8 +16899,8 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { }; this.addCursor = function(cursor) { runtime.assert(Boolean(cursor), "OdtDocument::addCursor without cursor"); - var distanceToFirstTextNode = cursor.getStepCounter().countForwardSteps(1, filter), memberid = cursor.getMemberId(); - runtime.assert(Boolean(memberid), "OdtDocument::addCursor has cursor without memberid"); + var distanceToFirstTextNode = cursor.getStepCounter().countSteps(1, filter), memberid = cursor.getMemberId(); + runtime.assert(typeof memberid === "string", "OdtDocument::addCursor has cursor without memberid"); runtime.assert(!cursors[memberid], "OdtDocument::addCursor is adding a duplicate cursor with memberid " + memberid); cursor.move(distanceToFirstTextNode); cursors[memberid] = cursor @@ -15517,12 +16933,6 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { this.getFormatting = function() { return odfCanvas.getFormatting() }; - this.getTextElements = function(range, includeInsignificantWhitespace) { - return odfUtils.getTextElements(range, includeInsignificantWhitespace) - }; - this.getParagraphElements = function(range) { - return odfUtils.getParagraphElements(range) - }; this.emit = function(eventid, args) { eventNotifier.emit(eventid, args) }; @@ -15573,6 +16983,9 @@ ops.OdtDocument.signalUndoStackChanged = "undo/changed"; 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 @@ -15593,7 +17006,7 @@ ops.OdtDocument.signalUndoStackChanged = "undo/changed"; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("ops.TrivialMemberModel"); runtime.loadClass("ops.TrivialOperationRouter"); @@ -15627,8 +17040,8 @@ ops.Session = function Session(odfCanvas) { this.getOdtDocument = function() { return odtDocument }; - this.enqueue = function(operation) { - operationRouter.push(operation) + this.enqueue = function(ops) { + operationRouter.push(ops) }; this.close = function(callback) { operationRouter.close(function(err) { @@ -15653,5 +17066,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 runtimens url(urn:webodf); /* namespace for runtime only */\n@namespace cursor url(urn:webodf:names:cursor);\n@namespace editinfo url(urn:webodf:names:editinfo);\n@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*[runtimens|containsparagraphanchor] {\n position: relative;\n}\ntext|s {\n white-space: pre;\n}\ntext|tab {\n display: inline;\n white-space: pre;\n}\ntext|line-break {\n content: \" \";\n display: block;\n}\ntext|tracked-changes {\n /*Consumers that do not support change tracking, should ignore changes.*/\n display: none;\n}\noffice|binary-data {\n display: none;\n}\noffice|text {\n display: block;\n text-align: left;\n overflow: visible;\n word-wrap: break-word;\n}\n\noffice|text::selection {\n /** Let's not draw selection highlight that overflows into the office|text\n * node when selecting content across several paragraphs\n */\n background: transparent;\n}\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 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"; +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"; diff --git a/js/3rdparty/webodf/webodf.js b/js/3rdparty/webodf/webodf.js index f82e23aa..14521100 100644 --- a/js/3rdparty/webodf/webodf.js +++ b/js/3rdparty/webodf/webodf.js @@ -12,6 +12,9 @@ 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 @@ -32,83 +35,83 @@ This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ 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,f,a){};Runtime.prototype.readFile=function(h,m,f){};Runtime.prototype.readFileSync=function(h,m){};Runtime.prototype.loadXML=function(h,m){};Runtime.prototype.writeFile=function(h,m,f){};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,f){};var IS_COMPILED_CODE=!0; -Runtime.byteArrayToString=function(h,m){function f(a){var b="",k,c=a.length;for(k=0;ke?b+=String.fromCharCode(e):(k+=1,s=a[k],194<=e&&224>e?b+=String.fromCharCode((e&31)<<6|s&63):(k+=1,n=a[k],224<=e&&240>e?b+=String.fromCharCode((e&15)<<12|(s&63)<<6|n&63):(k+=1,g=a[k],240<=e&&245>e&&(e=(e&7)<<18|(s&63)<<12|(n&63)<<6|g&63,e-=65536,b+=String.fromCharCode((e>>10)+55296,(e&1023)+56320))))); -return b}var c;"utf8"===m?c=a(h):("binary"!==m&&this.log("Unsupported encoding: "+m),c=f(h));return c};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(b,k){var a,e,c;void 0!==k?c=b:k=b;h?(e=h.ownerDocument,c&&(a=e.createElement("span"),a.className=c,a.appendChild(e.createTextNode(c)),h.appendChild(a),h.appendChild(e.createTextNode(" "))),a=e.createElement("span"),0n?(e[g]=n,g+=1):2048>n?(e[g]=192|n>>>6,e[g+1]=128|n&63,g+=2):(e[g]=224|n>>>12&15,e[g+1]=128|n>>>6&63,e[g+2]=128|n&63,g+=3)}else for("binary"!== -k&&a.log("unknown encoding: "+k),c=b.length,e=new a.ByteArray(c),d=0;de.status||0===e.status?d(null):d("Status "+String(e.status)+": "+e.responseText|| -e.statusText):d("File "+b+" is empty."))};k=k.buffer&&!e.sendAsBinary?k.buffer:a.byteArrayToString(k,"binary");try{e.sendAsBinary?e.sendAsBinary(k):e.send(k)}catch(f){a.log("HUH? "+f+" "+k),d(f.message)}};this.deleteFile=function(b,k){delete c[b];var a=new XMLHttpRequest;a.open("DELETE",b,!0);a.onreadystatechange=function(){4===a.readyState&&(200>a.status&&300<=a.status?k(a.responseText):k(null))};a.send(null)};this.loadXML=function(b,k){var a=new XMLHttpRequest;a.open("GET",b,!0);a.overrideMimeType&& -a.overrideMimeType("text/xml");a.onreadystatechange=function(){4===a.readyState&&(0!==a.status||a.responseText?200===a.status||0===a.status?k(null,a.responseXML):k(a.responseText):k("File "+b+" is empty."))};try{a.send(null)}catch(e){k(e.message)}};this.isFile=function(b,k){a.getFileSize(b,function(b){k(-1!==b)})};this.getFileSize=function(b,a){var c=new XMLHttpRequest;c.open("HEAD",b,!0);c.onreadystatechange=function(){if(4===c.readyState){var e=c.getResponseHeader("Content-Length");e?a(parseInt(e, -10)):f(b,"binary",function(e,b){e?a(-1):a(b.length)})}};c.send(null)};this.log=m;this.assert=function(b,a,c){if(!b)throw m("alert","ASSERTION FAILED:\n"+a),c&&c(),a;};this.setTimeout=function(b,a){return setTimeout(function(){b()},a)};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(b,d,e){b=a.resolve(c,b);"binary"!==d?f.readFile(b,d,e):f.readFile(b,null,e)}var m=this,f=require("fs"),a=require("path"),c="",d,b;this.ByteArray=function(a){return new Buffer(a)};this.byteArrayFromArray=function(a){var b=new Buffer(a.length),e,c=a.length;for(e=0;e").implementation} -function RhinoRuntime(){function h(b,a){var c;void 0!==a?c=b:a=b;"alert"===c&&print("\n!!!!! ALERT !!!!!");print(a);"alert"===c&&print("!!!!! ALERT !!!!!")}var m=this,f=Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance(),a,c,d="";f.setValidating(!1);f.setNamespaceAware(!0);f.setExpandEntityReferences(!1);f.setSchema(null);c=Packages.org.xml.sax.EntityResolver({resolveEntity:function(b,a){var c=new Packages.java.io.FileReader(a);return new Packages.org.xml.sax.InputSource(c)}});a=f.newDocumentBuilder(); -a.setEntityResolver(c);this.ByteArray=function(b){return[b]};this.byteArrayFromArray=function(b){return b};this.byteArrayFromString=function(b,a){var c=[],e,d=b.length;for(e=0;ed?c+=String.fromCharCode(d):(b+=1,k=f[b],194<=d&&224>d?c+=String.fromCharCode((d&31)<<6|k&63):(b+=1,g=f[b],224<=d&&240>d?c+=String.fromCharCode((d&15)<<12|(k&63)<<6|g&63):(b+=1,q=f[b],240<=d&&245>d&&(d=(d&7)<<18|(k&63)<<12|(g&63)<<6|q&63,d-=65536,c+=String.fromCharCode((d>>10)+55296,(d&1023)+56320))))); +return c}var m;"utf8"===h?m=n(e):("binary"!==h&&this.log("Unsupported encoding: "+h),m=f(e));return m};Runtime.getVariable=function(e){try{return eval(e)}catch(h){}};Runtime.toJson=function(e){return JSON.stringify(e)};Runtime.fromJson=function(e){return JSON.parse(e)};Runtime.getFunctionName=function(e){return void 0===e.name?(e=/function\s+(\w+)/.exec(e))&&e[1]:e.name}; +function BrowserRuntime(e){function h(c,b){var a,d,k;void 0!==b?k=c:b=c;e?(d=e.ownerDocument,k&&(a=d.createElement("span"),a.className=k,a.appendChild(d.createTextNode(k)),e.appendChild(a),e.appendChild(d.createTextNode(" "))),a=d.createElement("span"),0g?(d[q]=g,q+=1):2048>g?(d[q]=192|g>>>6,d[q+1]=128|g&63,q+=2):(d[q]=224|g>>>12&15,d[q+1]=128|g>>>6&63,d[q+2]=128|g&63,q+=3)}else for("binary"!== +b&&n.log("unknown encoding: "+b),a=c.length,d=new n.ByteArray(a),k=0;kd.status||0===d.status?a(null):a("Status "+String(d.status)+": "+d.responseText|| +d.statusText):a("File "+c+" is empty."))};b=b.buffer&&!d.sendAsBinary?b.buffer:n.byteArrayToString(b,"binary");try{d.sendAsBinary?d.sendAsBinary(b):d.send(b)}catch(k){n.log("HUH? "+k+" "+b),a(k.message)}};this.deleteFile=function(c,b){delete m[c];var a=new XMLHttpRequest;a.open("DELETE",c,!0);a.onreadystatechange=function(){4===a.readyState&&(200>a.status&&300<=a.status?b(a.responseText):b(null))};a.send(null)};this.loadXML=function(c,b){var a=new XMLHttpRequest;a.open("GET",c,!0);a.overrideMimeType&& +a.overrideMimeType("text/xml");a.onreadystatechange=function(){4===a.readyState&&(0!==a.status||a.responseText?200===a.status||0===a.status?b(null,a.responseXML):b(a.responseText):b("File "+c+" is empty."))};try{a.send(null)}catch(d){b(d.message)}};this.isFile=function(c,b){n.getFileSize(c,function(a){b(-1!==a)})};this.getFileSize=function(c,b){var a=new XMLHttpRequest;a.open("HEAD",c,!0);a.onreadystatechange=function(){if(4===a.readyState){var d=a.getResponseHeader("Content-Length");d?b(parseInt(d, +10)):f(c,"binary",function(a,d){a?b(-1):b(d.length)})}};a.send(null)};this.log=h;this.assert=function(c,b,a){if(!c)throw h("alert","ASSERTION FAILED:\n"+b),a&&a(),b;};this.setTimeout=function(c,b){return setTimeout(function(){c()},b)};this.clearTimeout=function(c){clearTimeout(c)};this.libraryPaths=function(){return["lib"]};this.setCurrentDirectory=function(){};this.type=function(){return"BrowserRuntime"};this.getDOMImplementation=function(){return window.document.implementation};this.parseXML=function(c){return(new DOMParser).parseFromString(c, +"text/xml")};this.exit=function(c){h("Calling exit with code "+String(c)+", but exit() is not implemented.")};this.getWindow=function(){return window}} +function NodeJSRuntime(){function e(b,a,d){b=n.resolve(m,b);"binary"!==a?f.readFile(b,a,d):f.readFile(b,null,d)}var h=this,f=require("fs"),n=require("path"),m="",p,c;this.ByteArray=function(b){return new Buffer(b)};this.byteArrayFromArray=function(b){var a=new Buffer(b.length),d,c=b.length;for(d=0;d").implementation} +function RhinoRuntime(){function e(c,b){var a;void 0!==b?a=c:b=c;"alert"===a&&print("\n!!!!! ALERT !!!!!");print(b);"alert"===a&&print("!!!!! ALERT !!!!!")}var h=this,f=Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance(),n,m,p="";f.setValidating(!1);f.setNamespaceAware(!0);f.setExpandEntityReferences(!1);f.setSchema(null);m=Packages.org.xml.sax.EntityResolver({resolveEntity:function(c,b){var a=new Packages.java.io.FileReader(b);return new Packages.org.xml.sax.InputSource(a)}});n=f.newDocumentBuilder(); +n.setEntityResolver(m);this.ByteArray=function(c){return[c]};this.byteArrayFromArray=function(c){return c};this.byteArrayFromString=function(c,b){var a=[],d,k=c.length;for(d=0;d>>18],b+=u[e>>>12&63],b+=u[e>>>6&63],b+=u[e&63];c===g+1?(e=a[c]<<4,b+=u[e>>>6],b+=u[e&63],b+="=="):c===g&&(e=a[c]<<10|a[c+1]<<2,b+=u[e>>>12],b+=u[e>>>6&63],b+=u[e&63],b+="=");return b}function f(a){a=a.replace(/[^A-Za-z0-9+\/]+/g,"");var b=[],e=a.length%4,c,g=a.length,n;for(c=0;c>16,n>>8&255,n&255);b.length-=[0,0,2,1][e];return b}function a(a){var b=[],e,c=a.length,g;for(e=0;eg?b.push(g):2048>g?b.push(192|g>>>6,128|g&63):b.push(224|g>>>12&15,128|g>>>6&63,128|g&63);return b}function c(a){var b=[],e,c=a.length,g,n,l;for(e=0;eg?b.push(g):(e+=1,n=a[e],224>g?b.push((g&31)<<6|n&63):(e+=1,l=a[e],b.push((g&15)<<12|(n&63)<<6|l&63)));return b}function d(a){return m(h(a))} -function b(a){return String.fromCharCode.apply(String,f(a))}function k(a){return c(h(a))}function p(a){a=c(a);for(var b="",e=0;eb?c+=String.fromCharCode(b):(l+=1,g=a.charCodeAt(l)&255,224>b?c+=String.fromCharCode((b&31)<<6|g&63):(l+=1,n=a.charCodeAt(l)&255,c+=String.fromCharCode((b&15)<<12|(g&63)<<6|n&63)));return c}function s(a,b){function c(){var d= -l+g;d>a.length&&(d=a.length);n+=e(a,l,d);l=d;d=l===a.length;b(n,d)&&!d&&runtime.setTimeout(c,0)}var g=1E5,n="",l=0;a.length>>18],b+=r[d>>>12&63],b+=r[d>>>6&63],b+=r[d&63];g===c+1?(d=a[g]<<4,b+=r[d>>>6],b+=r[d&63],b+="=="):g===c&&(d=a[g]<<10|a[g+1]<<2,b+=r[d>>>12],b+=r[d>>>6&63],b+=r[d&63],b+="=");return b}function f(a){a=a.replace(/[^A-Za-z0-9+\/]+/g,"");var d=[],b=a.length%4,g,c=a.length,k;for(g=0;g>16,k>>8&255,k&255);d.length-=[0,0,2,1][b];return d}function n(a){var d=[],b,g=a.length,c;for(b=0;bc?d.push(c):2048>c?d.push(192|c>>>6,128|c&63):d.push(224|c>>>12&15,128|c>>>6&63,128|c&63);return d}function m(a){var d=[],b,g=a.length,c,k,l;for(b=0;bc?d.push(c):(b+=1,k=a[b],224>c?d.push((c&31)<<6|k&63):(b+=1,l=a[b],d.push((c&15)<<12|(k&63)<<6|l&63)));return d}function p(a){return h(e(a))} +function c(a){return String.fromCharCode.apply(String,f(a))}function b(a){return m(e(a))}function a(a){a=m(a);for(var d="",b=0;bd?g+=String.fromCharCode(d):(l+=1,c=a.charCodeAt(l)&255,224>d?g+=String.fromCharCode((d&31)<<6|c&63):(l+=1,k=a.charCodeAt(l)&255,g+=String.fromCharCode((d&15)<<12|(c&63)<<6|k&63)));return g}function k(a,b){function g(){var q= +k+c;q>a.length&&(q=a.length);l+=d(a,k,q);k=q;q=k===a.length;b(l,q)&&!q&&runtime.setTimeout(g,0)}var c=1E5,l="",k=0;a.length>>8):(ta(a&255),ta(a>>>8))},ua=function(){w=(w<<5^l[B+3-1]&255)&8191;v=x[32768+w];x[B&32767]=v;x[32768+w]=B},la=function(a,b){y>16-b?(r|=a<>16-y,y+=b-16):(r|=a<a;a++)l[a]=l[a+32768];N-=32768;B-=32768;t-=32768;for(a=0;8192>a;a++)b=x[32768+a],x[32768+a]=32768<=b?b-32768:0;for(a=0;32768>a;a++)b=x[a],x[a]=32768<=b?b-32768:0;e+=32768}H||(a=Aa(l,B+L,e),0>=a?H=!0:L+=a)},Ba=function(a){var b=fa,e=B,c,g=K,n=32506=pa&&(b>>=2);do if(c=a,l[c+g]===v&&l[c+g-1]===k&&l[c]===l[e]&&l[++c]===l[e+1]){e+= -2;c++;do++e;while(l[e]===l[++c]&&l[++e]===l[++c]&&l[++e]===l[++c]&&l[++e]===l[++c]&&l[++e]===l[++c]&&l[++e]===l[++c]&&l[++e]===l[++c]&&l[++e]===l[++c]&&eg){N=a;g=c;if(258<=c)break;k=l[e+g-1];v=l[e+g]}a=x[a&32767]}while(a>n&&0!==--b);return g},ra=function(a,b){q[I++]=b;0===a?W[b].fc++:(a--,W[U[b]+256+1].fc++,aa[(256>a?V[a]:V[256+(a>>7)])&255].fc++,u[ia++]=a,na|=ja);ja<<=1;0===(I&7)&&(da[A++]=na,na=0,ja=1);if(2g;g++)e+=aa[g].fc* -(5+ba[g]);e>>=3;if(ia>=1,e<<=1;while(0<--b);return e>>1},Da=function(a,b){var e=[];e.length=16;var c=0,g;for(g=1;15>=g;g++)c=c+X[g-1]<<1,e[g]=c;for(c=0;c<=b;c++)g=a[c].dl,0!==g&&(a[c].fc=Ca(e[g]++,g))},ya=function(a){var b=a.dyn_tree,e=a.static_tree,c=a.elems,g,n=-1, -l=c;P=0;$=573;for(g=0;gP;)g=Q[++P]=2>n?++n:0,b[g].fc=1,ca[g]=0,ea--,null!==e&&(oa-=e[g].dl);a.max_code=n;for(g=P>>1;1<=g;g--)xa(b,g);do g=Q[1],Q[1]=Q[P--],xa(b,1),e=Q[1],Q[--$]=g,Q[--$]=e,b[l].fc=b[g].fc+b[e].fc,ca[l]=ca[g]>ca[e]+1?ca[g]:ca[e]+1,b[g].dl=b[e].dl=l,Q[1]=l++,xa(b,1);while(2<=P);Q[--$]=Q[1];l=a.dyn_tree;g=a.extra_bits;var c=a.extra_base,e=a.max_code,d=a.max_length,k=a.static_tree,v,f,q,h,m=0;for(f=0;15>=f;f++)X[f]=0;l[Q[$]].dl= -0;for(a=$+1;573>a;a++)v=Q[a],f=l[l[v].dl].dl+1,f>d&&(f=d,m++),l[v].dl=f,v>e||(X[f]++,q=0,v>=c&&(q=g[v-c]),h=l[v].fc,ea+=h*(f+q),null!==k&&(oa+=h*(k[v].dl+q)));if(0!==m){do{for(f=d-1;0===X[f];)f--;X[f]--;X[f+1]+=2;X[d]--;m-=2}while(0e||(l[g].dl!==f&&(ea+=(f-l[g].dl)*l[g].fc,l[g].fc=f),v--)}Da(b,n)},Ea=function(a,b){var e,c=-1,g,n=a[0].dl,l=0,d=7,k=4;0===n&&(d=138,k=3);a[b+1].dl=65535;for(e=0;e<=b;e++)g=n,n=a[e+1].dl,++l=l?F[17].fc++:F[18].fc++,l=0,c=g,0===n?(d=138,k=3):g===n?(d=6,k=3):(d=7,k=4))},Fa=function(){8b?V[b]:V[256+(b>>7)])&255,qa(d,e),k=ba[d],0!==k&&(b-=ga[d],la(b,k))),l>>=1;while(c=l?(qa(17,F),la(l-3,3)):(qa(18,F),la(l-11,7));l=0;c=g;0===n?(d=138,k=3):g===n?(d=6,k=3):(d=7,k=4)}},Ia=function(){var a;for(a=0;286>a;a++)W[a].fc=0;for(a=0;30>a;a++)aa[a].fc=0;for(a=0;19>a;a++)F[a].fc=0;W[256].fc=1;na=I=ia=A=ea=oa=0;ja=1},va=function(a){var b,e,c,g;g=B-t;da[A]=na;ya(G);ya(D);Ea(W,G.max_code);Ea(aa,D.max_code);ya(T);for(c=18;3<=c&&0===F[S[c]].dl;c--); -ea+=3*(c+1)+14;b=ea+3+7>>3;e=oa+3+7>>3;e<=b&&(b=e);if(g+4<=b&&0<=t)for(la(0+a,3),Fa(),Z(g),Z(~g),c=0;cb.len&&(k=b.len);for(v=0;vs-n&&(k=s-n);for(v=0;vf;f++)for(z[f]= -k,d=0;d<1<f;f++)for(ga[f]=k,d=0;d<1<>=7;30>f;f++)for(ga[f]=k<<7,d=0;d<1<=d;d++)X[d]=0;for(d=0;143>=d;)O[d++].dl=8,X[8]++;for(;255>=d;)O[d++].dl=9,X[9]++;for(;279>=d;)O[d++].dl=7,X[7]++;for(;287>=d;)O[d++].dl=8,X[8]++;Da(O,287);for(d=0;30>d;d++)R[d].dl=5,R[d].fc=Ca(d,5);Ia()}for(d=0;8192>d;d++)x[32768+d]=0;ma=sa[M].max_lazy;pa=sa[M].good_length;fa=sa[M].max_chain;t=B=0;L=Aa(l,0,65536);if(0>=L)H= -!0,L=0;else{for(H=!1;262>L&&!H;)wa();for(d=w=0;2>d;d++)w=(w<<5^l[d]&255)&8191}b=null;n=s=0;3>=M?(K=2,E=0):(E=2,J=0);g=!1}p=!0;if(0===L)return g=!0,0}d=Ja(a,e,c);if(d===c)return c;if(g)return d;if(3>=M)for(;0!==L&&null===b;){ua();0!==v&&32506>=B-v&&(E=Ba(v),E>L&&(E=L));if(3<=E)if(f=ra(B-N,E-3),L-=E,E<=ma){E--;do B++,ua();while(0!==--E);B++}else B+=E,E=0,w=l[B]&255,w=(w<<5^l[B+1]&255)&8191;else f=ra(0,l[B]&255),L--,B++;f&&(va(0),t=B);for(;262>L&&!H;)wa()}else for(;0!==L&&null===b;){ua();K=E;C=N;E=2; -0!==v&&(K=B-v)&&(E=Ba(v),E>L&&(E=L),3===E&&4096L&&!H;)wa()}0===L&&(0!==J&&ra(0,l[B-1]&255),va(1),g=!0);return d+Ja(a,d+e,c-d)};this.deflate=function(a,g){var n,v;Y=a;ka=0;"undefined"===String(typeof g)&&(g=6);(n=g)?1>n?n=1:9n;n++)W[n]=new h;aa=[];aa.length=61;for(n=0;61>n;n++)aa[n]=new h;O=[];O.length=288;for(n=0;288>n;n++)O[n]=new h;R=[];R.length=30;for(n=0;30>n;n++)R[n]=new h;F=[];F.length=39;for(n=0;39>n;n++)F[n]=new h;G=new m;D=new m;T=new m;X=[];X.length=16;Q=[];Q.length=573;ca=[];ca.length=573;U=[];U.length=256;V=[];V.length=512;z=[];z.length=29;ga=[];ga.length=30;da=[];da.length=1024}var f=Array(1024),t=[],r=[];for(n=Ka(f,0,f.length);0< -n;){r.length=n;for(v=0;v>>8):(xa(a&255),xa(a>>>8))},X=function(){u=(u<<5^l[z+3-1]&255)&8191;s=w[32768+u];w[z&32767]=s;w[32768+u]=z},ga=function(a,d){y>16-d?(v|=a<>16-y,y+=d-16):(v|=a<a;a++)l[a]=l[a+32768];N-=32768;z-=32768;x-=32768;for(a=0;8192>a;a++)d=w[32768+a],w[32768+a]=32768<=d?d-32768:0;for(a=0;32768>a;a++)d=w[a],w[a]=32768<=d?d-32768:0;b+=32768}G||(a=qa(l,z+R,b),0>=a?G=!0:R+=a)},va=function(a){var d=Z,b=z,g,c=I,k=32506=ra&&(d>>=2);do if(g=a,l[g+c]===e&&l[g+c-1]===f&&l[g]===l[b]&&l[++g]===l[b+1]){b+= +2;g++;do++b;while(l[b]===l[++g]&&l[++b]===l[++g]&&l[++b]===l[++g]&&l[++b]===l[++g]&&l[++b]===l[++g]&&l[++b]===l[++g]&&l[++b]===l[++g]&&l[++b]===l[++g]&&bc){N=a;c=g;if(258<=g)break;f=l[b+c-1];e=l[b+c]}a=w[a&32767]}while(a>k&&0!==--d);return c},wa=function(a,d){t[D++]=d;0===a?$[d].fc++:(a--,$[V[d]+256+1].fc++,ha[(256>a?Q[a]:Q[256+(a>>7)])&255].fc++,r[fa++]=a,ia|=Y);Y<<=1;0===(D&7)&&(oa[F++]=ia,ia=0,Y=1);if(2c;c++)b+=ha[c].fc* +(5+ma[c]);b>>=3;if(fa>=1,b<<=1;while(0<--d);return b>>1},Ea=function(a,d){var b=[];b.length=16;var g=0,c;for(c=1;15>=c;c++)g=g+S[c-1]<<1,b[c]=g;for(g=0;g<=d;g++)c=a[g].dl,0!==c&&(a[g].fc=Da(b[c]++,c))},Ca=function(a){var d=a.dyn_tree,b=a.static_tree,g=a.elems,c,l= +-1,k=g;aa=0;na=573;for(c=0;caa;)c=P[++aa]=2>l?++l:0,d[c].fc=1,da[c]=0,ba--,null!==b&&(la-=b[c].dl);a.max_code=l;for(c=aa>>1;1<=c;c--)ua(d,c);do c=P[1],P[1]=P[aa--],ua(d,1),b=P[1],P[--na]=c,P[--na]=b,d[k].fc=d[c].fc+d[b].fc,da[k]=da[c]>da[b]+1?da[c]:da[b]+1,d[c].dl=d[b].dl=k,P[1]=k++,ua(d,1);while(2<=aa);P[--na]=P[1];k=a.dyn_tree;c=a.extra_bits;var g=a.extra_base,b=a.max_code,q=a.max_length,f=a.static_tree,e,r,A,h,s=0;for(r=0;15>=r;r++)S[r]= +0;k[P[na]].dl=0;for(a=na+1;573>a;a++)e=P[a],r=k[k[e].dl].dl+1,r>q&&(r=q,s++),k[e].dl=r,e>b||(S[r]++,A=0,e>=g&&(A=c[e-g]),h=k[e].fc,ba+=h*(r+A),null!==f&&(la+=h*(f[e].dl+A)));if(0!==s){do{for(r=q-1;0===S[r];)r--;S[r]--;S[r+1]+=2;S[q]--;s-=2}while(0b||(k[c].dl!==r&&(ba+=(r-k[c].dl)*k[c].fc,k[c].fc=r),e--)}Ea(d,l)},Fa=function(a,d){var b,g=-1,c,k=a[0].dl,l=0,q=7,e=4;0===k&&(q=138,e=3);a[d+1].dl=65535;for(b=0;b<=d;b++)c=k,k=a[b+1].dl,++l=l?W[17].fc++:W[18].fc++,l=0,g=c,0===k?(q=138,e=3):c===k?(q=6,e=3):(q=7,e=4))},Ga=function(){8b?Q[b]:Q[256+(b>>7)])&255,K(q,d),e=ma[q],0!==e&&(b-=ea[q],ga(b,e))),l>>=1;while(g=l?(K(17,W),ga(l-3,3)):(K(18,W),ga(l-11,7));l=0;g=c;0===k?(q=138,e=3):c===k?(q=6,e=3):(q=7,e=4)}},Ja=function(){var a;for(a=0;286>a;a++)$[a].fc=0;for(a=0;30>a;a++)ha[a].fc=0;for(a=0;19>a;a++)W[a].fc=0;$[256].fc=1;ia=D=fa=F=ba=la=0;Y=1},Ba=function(a){var d,b,g,c;c=z-x;oa[F]=ia;Ca(E);Ca(H);Fa($,E.max_code);Fa(ha,H.max_code);Ca(M);for(g=18;3<=g&& +0===W[za[g]].dl;g--);ba+=3*(g+1)+14;d=ba+3+7>>3;b=la+3+7>>3;b<=d&&(d=b);if(c+4<=d&&0<=x)for(ga(0+a,3),Ga(),ca(c),ca(~c),g=0;gc.len&&(e=c.len);for(f=0;fk-g&&(e=k-g);for(f=0;fh;h++)for(J[h]=r,f=0;f<1<h;h++)for(ea[h]=r,f=0;f<1<>=7;30>h;h++)for(ea[h]=r<<7,f=0;f<1<=f;f++)S[f]=0;for(f=0;143>=f;)U[f++].dl=8,S[8]++;for(;255>=f;)U[f++].dl=9,S[9]++;for(;279>=f;)U[f++].dl=7,S[7]++;for(;287>=f;)U[f++].dl=8,S[8]++;Ea(U,287);for(f=0;30>f;f++)O[f].dl=5,O[f].fc=Da(f,5);Ja()}for(f=0;8192>f;f++)w[32768+f]=0;ka=ta[T].max_lazy;ra=ta[T].good_length;Z=ta[T].max_chain;x=z=0;R=qa(l, +0,65536);if(0>=R)G=!0,R=0;else{for(G=!1;262>R&&!G;)Aa();for(f=u=0;2>f;f++)u=(u<<5^l[f]&255)&8191}c=null;g=k=0;3>=T?(I=2,A=0):(A=2,B=0);q=!1}a=!0;if(0===R)return q=!0,0}f=Ka(d,b,e);if(f===e)return e;if(q)return f;if(3>=T)for(;0!==R&&null===c;){X();0!==s&&32506>=z-s&&(A=va(s),A>R&&(A=R));if(3<=A)if(h=wa(z-N,A-3),R-=A,A<=ka){A--;do z++,X();while(0!==--A);z++}else z+=A,A=0,u=l[z]&255,u=(u<<5^l[z+1]&255)&8191;else h=wa(0,l[z]&255),R--,z++;h&&(Ba(0),x=z);for(;262>R&&!G;)Aa()}else for(;0!==R&&null===c;){X(); +I=A;C=N;A=2;0!==s&&I=z-s&&(A=va(s),A>R&&(A=R),3===A&&4096R&&!G;)Aa()}0===R&&(0!==B&&wa(0,l[z-1]&255),Ba(1),q=!0);return f+Ka(d,f+b,e-f)};this.deflate=function(g,k){var q,f;L=g;sa=0;"undefined"===String(typeof k)&&(k=6);(q=k)?1>q?q=1:9q;q++)$[q]=new e;ha=[];ha.length=61;for(q=0;61>q;q++)ha[q]=new e;U=[];U.length=288;for(q=0;288>q;q++)U[q]=new e;O=[];O.length=30;for(q=0;30>q;q++)O[q]=new e;W=[];W.length=39;for(q=0;39>q;q++)W[q]=new e;E=new h;H=new h;M=new h;S=[];S.length=16;P=[];P.length=573;da=[];da.length=573;V=[];V.length=256;Q=[];Q.length=512;J=[];J.length=29;ea=[];ea.length=30;oa=[];oa.length=1024}var A=Array(1024),s=[],n=[];for(q=La(A,0, +A.length);0>8&255])};this.appendUInt32LE=function(a){m.appendArray([a&255,a>>8&255,a>>16&255,a>>24&255])};this.appendString=function(a){f=runtime.concatByteArrays(f, -runtime.byteArrayFromString(a,h))};this.getLength=function(){return f.length};this.getByteArray=function(){return f}}; +core.ByteArrayWriter=function(e){var h=this,f=new runtime.ByteArray(0);this.appendByteArrayWriter=function(e){f=runtime.concatByteArrays(f,e.getByteArray())};this.appendByteArray=function(e){f=runtime.concatByteArrays(f,e)};this.appendArray=function(e){f=runtime.concatByteArrays(f,runtime.byteArrayFromArray(e))};this.appendUInt16LE=function(f){h.appendArray([f&255,f>>8&255])};this.appendUInt32LE=function(f){h.appendArray([f&255,f>>8&255,f>>16&255,f>>24&255])};this.appendString=function(h){f=runtime.concatByteArrays(f, +runtime.byteArrayFromString(h,e))};this.getLength=function(){return f.length};this.getByteArray=function(){return f}}; // Input 6 -core.RawInflate=function(){var h,m,f=null,a,c,d,b,k,p,e,s,n,g,l,u,q,x,r=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],y=[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],t=[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],w=[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],v=[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],C=[16,17,18, -0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],J=function(){this.list=this.next=null},E=function(){this.n=this.b=this.e=0;this.t=null},K=function(a,b,e,c,g,n){this.BMAX=16;this.N_MAX=288;this.status=0;this.root=null;this.m=0;var d=Array(this.BMAX+1),l,k,v,f,h,q,m,t=Array(this.BMAX+1),x,p,u,r=new E,s=Array(this.BMAX);f=Array(this.N_MAX);var y,w=Array(this.BMAX+1),B,C,K;K=this.root=null;for(h=0;hh&&(n=h);for(B=1<(B-=d[q])){this.status=2;this.m=n;return}if(0>(B-=d[h]))this.status=2,this.m=n;else{d[h]+=B;w[1]=q=0;x=d;p=1;for(u=2;0<--h;)w[u++]=q+=x[p++];x=a;h=p=0;do 0!=(q=x[p++])&&(f[w[q]++]=h);while(++hy+t[1+f];){y+=t[1+f];f++;C=(C=v-y)>n?n:C;if((k=1<<(q=m-y))>a+1)for(k-=a+1,u=m;++ql&&y>y-t[f],s[f-1][q].e=r.e,s[f-1][q].b=r.b,s[f-1][q].n=r.n,s[f-1][q].t=r.t)}r.b=m-y;p>=b?r.e=99:x[p]x[p]?16:15,r.n=x[p++]): -(r.e=g[x[p]-e],r.n=c[x[p++]-e]);k=1<>y;q>=1)h^=q;for(h^=q;(h&(1<>=a;b-=a},L=function(a,b,c){var d,v,f;if(0==c)return 0;for(f=0;;){B(l);v=n.list[N(l)];for(d=v.e;16 -d;d++)p[C[d]]=0;l=7;d=new K(p,19,19,null,null,l);if(0!=d.status)return-1;n=d.root;l=d.m;f=q+m;for(c=k=0;cd)p[c++]=k=d;else if(16==d){B(2);d=3+N(2);H(2);if(c+d>f)return-1;for(;0f)return-1;for(;0D;D++)G[D]=8;for(;256>D;D++)G[D]=9;for(;280>D;D++)G[D]=7;for(;288>D;D++)G[D]=8;c=7;D=new K(G,288,257,y,t,c);if(0!=D.status){alert("HufBuild error: "+D.status);O=-1;break b}f=D.root;c=D.m;for(D=0;30>D;D++)G[D]=5;fa=5;D=new K(G,30,0,w,v,fa);if(1h&&(l=h);for(I=1<(I-=k[s])){this.status=2;this.m=l;return}if(0>(I-=k[h]))this.status=2,this.m=l;else{k[h]+=I;u[1]=s=0;p=k;n=1;for(N=2;0<--h;)u[N++]=s+=p[n++];p=a;h=n=0;do 0!=(s=p[n++])&&(r[u[s]++]=h);while(++hz+m[1+r];){z+=m[1+r];r++;v=(v=e-z)>l?l:v;if((f=1<<(s=t-z))>a+1)for(f-=a+1,N=t;++sq&&z>z-m[r],G[r-1][s].e=w.e,G[r-1][s].b=w.b,G[r-1][s].n=w.n,G[r-1][s].t=w.t)}w.b=t-z;n>=d?w.e=99:p[n]p[n]?16:15,w.n=p[n++]): +(w.e=c[p[n]-b],w.n=g[p[n++]-b]);f=1<>z;s>=1)h^=s;for(h^=s;(h&(1<>=a;c-=a},R=function(a,c,f){var s,A,t;if(0==f)return 0;for(t=0;;){z(l);A=g.list[N(l)];for(s=A.e;16 +k;k++)m[C[k]]=0;l=7;k=new I(m,19,19,null,null,l);if(0!=k.status)return-1;g=k.root;l=k.m;e=A+t;for(c=f=0;ck)m[c++]=f=k;else if(16==k){z(2);k=3+N(2);G(2);if(c+k>e)return-1;for(;0e)return-1;for(;0H;H++)E[H]=8;for(;256>H;H++)E[H]=9;for(;280>H;H++)E[H]=7;for(;288>H;H++)E[H]=8;m=7;H=new I(E,288,257,y,x,m);if(0!=H.status){alert("HufBuild error: "+H.status);U=-1;break b}f=H.root;m=H.m;for(H=0;30>H;H++)E[H]=5;Z=5;H=new I(E,30,0,u,s,Z);if(1. + 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 @@ -142,11 +148,11 @@ null;alert("HufBuild error: "+D.status);O=-1;break b}a=D.root;fa=D.m}n=f;g=a;l=c This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -core.LoopWatchDog=function(h,m){var f=Date.now(),a=0;this.check=function(){var c;if(h&&(c=Date.now(),c-f>h))throw runtime.log("alert","watchdog timeout"),"timeout!";if(0m))throw runtime.log("alert","watchdog loop overflow"),"loop overflow";}}; +core.LoopWatchDog=function(e,h){var f=Date.now(),n=0;this.check=function(){var m;if(e&&(m=Date.now(),m-f>e))throw runtime.log("alert","watchdog timeout"),"timeout!";if(0h))throw runtime.log("alert","watchdog loop overflow"),"loop overflow";}}; // Input 8 -core.Utils=function(){function h(m,f){f&&Array.isArray(f)?m=(m||[]).concat(f.map(function(a){return h({},a)})):f&&"object"===typeof f?(m=m||{},Object.keys(f).forEach(function(a){m[a]=h(m[a],f[a])})):m=f;return m}this.hashString=function(h){var f=0,a,c;a=0;for(c=h.length;a. + 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 @@ -180,21 +189,22 @@ core.Utils=function(){function h(m,f){f&&Array.isArray(f)?m=(m||[]).concat(f.map This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -core.DomUtils=function(){function h(a,c){var d=null;a.nodeType===Node.TEXT_NODE&&(0===a.length?(a.parentNode.removeChild(a),c.nodeType===Node.TEXT_NODE&&(d=c)):(c.nodeType===Node.TEXT_NODE&&(a.appendData(c.data),c.parentNode.removeChild(c)),d=a));return d}function m(a,c){for(var d=0,b;a.parentNode!==c;)runtime.assert(null!==a.parentNode,"parent is null"),a=a.parentNode;for(b=c.firstChild;b!==a;)d+=1,b=b.nextSibling;return d}function f(a,c){return a===c||Boolean(a.compareDocumentPosition(c)&Node.DOCUMENT_POSITION_CONTAINED_BY)} -this.splitBoundaries=function(a){var c=[],d;if(a.startContainer.nodeType===Node.TEXT_NODE||a.endContainer.nodeType===Node.TEXT_NODE){d=a.endContainer;var b=a.endOffset;if(b=a.compareBoundaryPoints(a.START_TO_START,c)&&0<=a.compareBoundaryPoints(a.END_TO_END,c)};this.rangesIntersect=function(a,c){return 0>=a.compareBoundaryPoints(a.END_TO_START,c)&&0<=a.compareBoundaryPoints(a.START_TO_END,c)}; -this.getNodesInRange=function(a,c){var d=[],b,k=a.startContainer.ownerDocument.createTreeWalker(a.commonAncestorContainer,NodeFilter.SHOW_ALL,c,!1);for(b=k.currentNode=a.startContainer;b;){if(c(b)===NodeFilter.FILTER_ACCEPT)d.push(b);else if(c(b)===NodeFilter.FILTER_REJECT)break;b=b.parentNode}d.reverse();for(b=k.nextNode();b;)d.push(b),b=k.nextNode();return d};this.normalizeTextNodes=function(a){a&&a.nextSibling&&(a=h(a,a.nextSibling));a&&a.previousSibling&&h(a.previousSibling,a)};this.rangeContainsNode= -function(a,c){var d=c.ownerDocument.createRange(),b=c.nodeType===Node.TEXT_NODE?c.length:c.childNodes.length;d.setStart(a.startContainer,a.startOffset);d.setEnd(a.endContainer,a.endOffset);b=0===d.comparePoint(c,0)&&0===d.comparePoint(c,b);d.detach();return b};this.mergeIntoParent=function(a){for(var c=a.parentNode;a.firstChild;)c.insertBefore(a.firstChild,a);c.removeChild(a);return c};this.getElementsByTagNameNS=function(a,c,d){return Array.prototype.slice.call(a.getElementsByTagNameNS(c,d))};this.rangeIntersectsNode= -function(a,c){var d=c.nodeType===Node.TEXT_NODE?c.length:c.childNodes.length;return 0>=a.comparePoint(c,0)&&0<=a.comparePoint(c,d)};this.containsNode=function(a,c){return a===c||a.contains(c)};this.comparePoints=function(a,c,d,b){if(a===d)return b-c;var k=a.compareDocumentPosition(d);2===k?k=-1:4===k?k=1:10===k?(c=m(a,d),k=c=b.compareBoundaryPoints(b.START_TO_START, +a)&&0<=b.compareBoundaryPoints(b.END_TO_END,a)};this.rangesIntersect=function(b,a){return 0>=b.compareBoundaryPoints(b.END_TO_START,a)&&0<=b.compareBoundaryPoints(b.START_TO_END,a)};this.getNodesInRange=function(b,a){var d=[],c,g,q=b.startContainer.ownerDocument.createTreeWalker(b.commonAncestorContainer,NodeFilter.SHOW_ALL,a,!1);for(c=q.currentNode=b.startContainer;c;){g=a(c);if(g===NodeFilter.FILTER_ACCEPT)d.push(c);else if(g===NodeFilter.FILTER_REJECT)break;c=c.parentNode}d.reverse();for(c=q.nextNode();c;)d.push(c), +c=q.nextNode();return d};this.normalizeTextNodes=function(b){b&&b.nextSibling&&(b=f(b,b.nextSibling));b&&b.previousSibling&&f(b.previousSibling,b)};this.rangeContainsNode=function(b,a){var d=a.ownerDocument.createRange(),c=a.nodeType===Node.TEXT_NODE?a.length:a.childNodes.length;d.setStart(b.startContainer,b.startOffset);d.setEnd(b.endContainer,b.endOffset);c=0===d.comparePoint(a,0)&&0===d.comparePoint(a,c);d.detach();return c};this.mergeIntoParent=h;this.removeUnwantedNodes=m;this.getElementsByTagNameNS= +function(b,a,d){return Array.prototype.slice.call(b.getElementsByTagNameNS(a,d))};this.rangeIntersectsNode=function(b,a){var d=a.nodeType===Node.TEXT_NODE?a.length:a.childNodes.length;return 0>=b.comparePoint(a,0)&&0<=b.comparePoint(a,d)};this.containsNode=function(b,a){return b===a||b.contains(a)};this.comparePoints=function(b,a,d,c){if(b===d)return c-a;var g=b.compareDocumentPosition(d);2===g?g=-1:4===g?g=1:10===g?(a=p(b,d),g=a. + 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 @@ -228,37 +241,39 @@ d.setAttributeNS("urn:webodf:names:cursor","memberId",m)}; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -core.EventNotifier=function(h){var m={};this.emit=function(f,a){var c,d;runtime.assert(m.hasOwnProperty(f),'unknown event fired "'+f+'"');d=m[f];for(c=0;c";return runtime.parseXML(f)}; -core.UnitTestRunner=function(){function h(a){b+=1;runtime.log("fail",a)}function m(a,b){var c;try{if(a.length!==b.length)return h("array of length "+a.length+" should be "+b.length+" long"),!1;for(c=0;c1/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 b=0,k;k=function(a,b){var d=Object.keys(a),n=Object.keys(b);d.sort();n.sort();return m(d,n)&&Object.keys(a).every(function(d){var n= -a[d],k=b[d];return c(n,k)?!0:(h(n+" should be "+k+" for key "+d),!1)})};this.areNodesEqual=a;this.shouldBeNull=function(a,b){d(a,b,"null")};this.shouldBeNonNull=function(a,b){var c,d;try{d=eval(b)}catch(g){c=g}c?h(b+" should be non-null. Threw exception "+c):null!==d?runtime.log("pass",b+" is non-null."):h(b+" should be non-null. Was "+d)};this.shouldBe=d;this.countFailedTests=function(){return b}}; -core.UnitTester=function(){function h(a,c){return""+a+""}var m=0,f={};this.runTests=function(a,c,d){function b(a){if(0===a.length)f[k]=s,m+=p.countFailedTests(),c();else{g=a[0];var d=Runtime.getFunctionName(g);runtime.log("Running "+d);u=p.countFailedTests();e.setUp();g(function(){e.tearDown();s[d]=u===p.countFailedTests();b(a.slice(1))})}}var k=Runtime.getFunctionName(a),p=new core.UnitTestRunner,e=new a(p),s={},n,g,l,u,q="BrowserRuntime"=== -runtime.type();if(f.hasOwnProperty(k))runtime.log("Test "+k+" has already run.");else{q?runtime.log("Running "+h(k,'runSuite("'+k+'");')+": "+e.description()+""):runtime.log("Running "+k+": "+e.description);l=e.tests();for(n=0;nRunning "+h(a,'runTest("'+k+'","'+a+'")')+""):runtime.log("Running "+a),u=p.countFailedTests(),e.setUp(),g(),e.tearDown(),s[a]=u===p.countFailedTests()); -b(e.asyncTests())}};this.countFailedTests=function(){return m};this.results=function(){return f}}; +core.UnitTest.provideTestAreaDiv=function(){var e=runtime.getWindow().document,h=e.getElementById("testarea");runtime.assert(!h,'Unclean test environment, found a div with id "testarea".');h=e.createElement("div");h.setAttribute("id","testarea");e.body.appendChild(h);return h}; +core.UnitTest.cleanupTestAreaDiv=function(){var e=runtime.getWindow().document,h=e.getElementById("testarea");runtime.assert(!!h&&h.parentNode===e.body,'Test environment broken, found no div with id "testarea" below body.');e.body.removeChild(h)};core.UnitTest.createOdtDocument=function(e,h){var f="",f=f+"";return runtime.parseXML(f)}; +core.UnitTestRunner=function(){function e(a){c+=1;runtime.log("fail",a)}function h(a,d){var b;try{if(a.length!==d.length)return e("array of length "+a.length+" should be "+d.length+" long"),!1;for(b=0;b1/q?"-0":String(q),e(d+" should be "+a+". Was "+b+".")):e(d+" should be "+a+" (of type "+typeof a+"). Was "+q+" (of type "+typeof q+").")}var c=0,b;b=function(a,d){var b=Object.keys(a),c=Object.keys(d);b.sort();c.sort();return h(b,c)&&Object.keys(a).every(function(b){var c= +a[b],g=d[b];return m(c,g)?!0:(e(c+" should be "+g+" for key "+b),!1)})};this.areNodesEqual=n;this.shouldBeNull=function(a,d){p(a,d,"null")};this.shouldBeNonNull=function(a,d){var b,c;try{c=eval(d)}catch(q){b=q}b?e(d+" should be non-null. Threw exception "+b):null!==c?runtime.log("pass",d+" is non-null."):e(d+" should be non-null. Was "+c)};this.shouldBe=p;this.countFailedTests=function(){return c}}; +core.UnitTester=function(){function e(f,e){return""+f+""}var h=0,f={};this.runTests=function(n,m,p){function c(g){if(0===g.length)f[b]=k,h+=a.countFailedTests(),m();else{q=g[0];var l=Runtime.getFunctionName(q);runtime.log("Running "+l);r=a.countFailedTests();d.setUp();q(function(){d.tearDown();k[l]=r===a.countFailedTests();c(g.slice(1))})}}var b=Runtime.getFunctionName(n),a=new core.UnitTestRunner,d=new n(a),k={},g,q,l,r,t="BrowserRuntime"=== +runtime.type();if(f.hasOwnProperty(b))runtime.log("Test "+b+" has already run.");else{t?runtime.log("Running "+e(b,'runSuite("'+b+'");')+": "+d.description()+""):runtime.log("Running "+b+": "+d.description);l=d.tests();for(g=0;gRunning "+e(n,'runTest("'+b+'","'+n+'")')+""):runtime.log("Running "+n),r=a.countFailedTests(),d.setUp(),q(),d.tearDown(),k[n]=r===a.countFailedTests()); +c(d.asyncTests())}};this.countFailedTests=function(){return h};this.results=function(){return f}}; // Input 13 -core.PositionIterator=function(h,m,f,a){function c(){this.acceptNode=function(a){return a.nodeType===Node.TEXT_NODE&&0===a.length?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}function d(a){this.acceptNode=function(b){return b.nodeType===Node.TEXT_NODE&&0===b.length?NodeFilter.FILTER_REJECT:a.acceptNode(b)}}function b(){var a=p.currentNode.nodeType;e=a===Node.TEXT_NODE?p.currentNode.length-1:a===Node.ELEMENT_NODE?1:0}var k=this,p,e,s;this.nextPosition=function(){if(p.currentNode===h)return!1; -if(0===e&&p.currentNode.nodeType===Node.ELEMENT_NODE)null===p.firstChild()&&(e=1);else if(p.currentNode.nodeType===Node.TEXT_NODE&&e+1 "+a.length),runtime.assert(0<=b,"Error in setPosition: "+b+" < 0"),b===a.length&&(e=void 0,p.nextSibling()?e=0:p.parentNode()&&(e=1),runtime.assert(void 0!==e,"Error in setPosition: position not valid.")),!0;c=s(a);for(d=a.parentNode;d&&d!==h&&c===NodeFilter.FILTER_ACCEPT;)c= -s(d),c!==NodeFilter.FILTER_ACCEPT&&(p.currentNode=d),d=d.parentNode;b "+c.length),runtime.assert(0<=f,"Error in setPosition: "+f+" < 0"),f===c.length&&(d=void 0,a.nextSibling()?d=0:a.parentNode()&&(d=1),runtime.assert(void 0!==d,"Error in setPosition: position not valid.")),!0;l=k(c);for(h=c.parentNode;h&&h!==e&&l===NodeFilter.FILTER_ACCEPT;)l= +k(h),l!==NodeFilter.FILTER_ACCEPT&&(a.currentNode=h),h=h.parentNode;f>>8^g;return c^-1}function a(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 c(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 d(b,c){var e,d,g,l,k,n,f,h=this;this.load=function(a){if(void 0!==h.data)a(null,h.data);else{var c=k+34+d+g+256;c+f>u&&(c=u-f);runtime.read(b,f,c,function(c,e){if(c||null===e)a(c,e);else a:{var d=e,g=new core.ByteArray(d),v=g.readUInt32LE(),f;if(67324752!==v)a("File entry signature is wrong."+v.toString()+" "+d.length.toString(),null);else{g.pos+=22;v=g.readUInt16LE();f=g.readUInt16LE();g.pos+=v+f; -if(l){d=d.slice(g.pos,g.pos+k);if(k!==d.length){a("The amount of compressed bytes read was "+d.length.toString()+" instead of "+k.toString()+" for "+h.filename+" in "+b+".",null);break a}d=x(d,n)}else d=d.slice(g.pos,g.pos+n);n!==d.length?a("The amount of bytes read was "+d.length.toString()+" instead of "+n.toString()+" for "+h.filename+" in "+b+".",null):(h.data=d,a(null,d))}}})}};this.set=function(a,b,c,e){h.filename=a;h.data=b;h.compressed=c;h.date=e};this.error=null;c&&(e=c.readUInt32LE(),33639248!== -e?this.error="Central directory entry has wrong signature at position "+(c.pos-4).toString()+' for file "'+b+'": '+c.data.length.toString():(c.pos+=6,l=c.readUInt16LE(),this.date=a(c.readUInt32LE()),c.readUInt32LE(),k=c.readUInt32LE(),n=c.readUInt32LE(),d=c.readUInt16LE(),g=c.readUInt16LE(),e=c.readUInt16LE(),c.pos+=8,f=c.readUInt32LE(),this.filename=runtime.byteArrayToString(c.data.slice(c.pos,c.pos+d),"utf8"),c.pos+=d+g+e))}function b(a,b){if(22!==a.length)b("Central directory length should be 22.", -r);else{var c=new core.ByteArray(a),e;e=c.readUInt32LE();101010256!==e?b("Central directory signature is wrong: "+e.toString(),r):(e=c.readUInt16LE(),0!==e?b("Zip files with non-zero disk numbers are not supported.",r):(e=c.readUInt16LE(),0!==e?b("Zip files with non-zero disk numbers are not supported.",r):(e=c.readUInt16LE(),q=c.readUInt16LE(),e!==q?b("Number of entries is inconsistent.",r):(e=c.readUInt32LE(),c=c.readUInt16LE(),c=u-22-e,runtime.read(h,c,u-c,function(a,c){if(a||null===c)b(a,r);else a:{var e= -new core.ByteArray(c),g,k;l=[];for(g=0;gu?m("File '"+h+"' cannot be read.",r):runtime.read(h,u-22,22,function(a,c){a||null===m||null===c?m(a,r):b(c,m)})})}; -// Input 18 -core.CSSUnits=function(){var h={"in":1,cm:2.54,mm:25.4,pt:72,pc:12};this.convert=function(m,f,a){return m*h[a]/h[f]};this.convertMeasure=function(h,f){var a,c;h&&f?(a=parseFloat(h),c=h.replace(a.toString(),""),a=this.convert(a,c,f)):a="";return a.toString()};this.getUnits=function(h){return h.substr(h.length-2,h.length)}}; +2932959818,3654703836,1088359270,936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117],b,c,g=a.length,l=0,l=0;b=-1;for(c=0;c>>8^l;return b^-1}function n(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 m(a){var d=a.getFullYear();return 1980>d?0:d-1980<< +25|a.getMonth()+1<<21|a.getDate()<<16|a.getHours()<<11|a.getMinutes()<<5|a.getSeconds()>>1}function p(a,d){var b,c,g,l,k,f,e,q=this;this.load=function(d){if(void 0!==q.data)d(null,q.data);else{var b=k+34+c+g+256;b+e>r&&(b=r-e);runtime.read(a,e,b,function(b,c){if(b||null===c)d(b,c);else a:{var g=c,e=new core.ByteArray(g),h=e.readUInt32LE(),r;if(67324752!==h)d("File entry signature is wrong."+h.toString()+" "+g.length.toString(),null);else{e.pos+=22;h=e.readUInt16LE();r=e.readUInt16LE();e.pos+=h+r; +if(l){g=g.slice(e.pos,e.pos+k);if(k!==g.length){d("The amount of compressed bytes read was "+g.length.toString()+" instead of "+k.toString()+" for "+q.filename+" in "+a+".",null);break a}g=w(g,f)}else g=g.slice(e.pos,e.pos+f);f!==g.length?d("The amount of bytes read was "+g.length.toString()+" instead of "+f.toString()+" for "+q.filename+" in "+a+".",null):(q.data=g,d(null,g))}}})}};this.set=function(a,d,b,c){q.filename=a;q.data=d;q.compressed=b;q.date=c};this.error=null;d&&(b=d.readUInt32LE(),33639248!== +b?this.error="Central directory entry has wrong signature at position "+(d.pos-4).toString()+' for file "'+a+'": '+d.data.length.toString():(d.pos+=6,l=d.readUInt16LE(),this.date=n(d.readUInt32LE()),d.readUInt32LE(),k=d.readUInt32LE(),f=d.readUInt32LE(),c=d.readUInt16LE(),g=d.readUInt16LE(),b=d.readUInt16LE(),d.pos+=8,e=d.readUInt32LE(),this.filename=runtime.byteArrayToString(d.data.slice(d.pos,d.pos+c),"utf8"),d.pos+=c+g+b))}function c(a,d){if(22!==a.length)d("Central directory length should be 22.", +v);else{var b=new core.ByteArray(a),c;c=b.readUInt32LE();101010256!==c?d("Central directory signature is wrong: "+c.toString(),v):(c=b.readUInt16LE(),0!==c?d("Zip files with non-zero disk numbers are not supported.",v):(c=b.readUInt16LE(),0!==c?d("Zip files with non-zero disk numbers are not supported.",v):(c=b.readUInt16LE(),t=b.readUInt16LE(),c!==t?d("Number of entries is inconsistent.",v):(c=b.readUInt32LE(),b=b.readUInt16LE(),b=r-22-c,runtime.read(e,b,r-b,function(a,b){if(a||null===b)d(a,v);else a:{var c= +new core.ByteArray(b),g,k;l=[];for(g=0;gr?h("File '"+e+"' cannot be read.",v):runtime.read(e,r-22,22,function(a,d){a||null===h||null===d?h(a,v):c(d,h)})})}; // Input 19 -xmldom.LSSerializerFilter=function(){}; +core.CSSUnits=function(){var e={"in":1,cm:2.54,mm:25.4,pt:72,pc:12};this.convert=function(h,f,n){return h*e[n]/e[f]};this.convertMeasure=function(e,f){var n,m;e&&f?(n=parseFloat(e),m=e.replace(n.toString(),""),n=this.convert(n,m,f)):n="";return n.toString()};this.getUnits=function(e){return e.substr(e.length-2,e.length)}}; // Input 20 -"function"!==typeof Object.create&&(Object.create=function(h){var m=function(){};m.prototype=h;return new m}); -xmldom.LSSerializer=function(){function h(a){var d=a||{},b=function(a){var b={},c;for(c in a)a.hasOwnProperty(c)&&(b[a[c]]=c);return b}(a),k=[d],f=[b],e=0;this.push=function(){e+=1;d=k[e]=Object.create(d);b=f[e]=Object.create(b)};this.pop=function(){k[e]=void 0;f[e]=void 0;e-=1;d=k[e];b=f[e]};this.getLocalNamespaceDefinitions=function(){return b};this.getQName=function(a){var c=a.namespaceURI,e=0,l;if(!c)return a.localName;if(l=b[c])return l+":"+a.localName;do{l||!a.prefix?(l="ns"+e,e+=1):l=a.prefix; -if(d[l]===c)break;if(!d[l]){d[l]=c;b[c]=l;break}l=null}while(null===l);return l+":"+a.localName}}function m(a){return a.replace(/&/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""")}function f(c,d){var b="",k=a.filter?a.filter.acceptNode(d):NodeFilter.FILTER_ACCEPT,h;if(k===NodeFilter.FILTER_ACCEPT&&d.nodeType===Node.ELEMENT_NODE){c.push();h=c.getQName(d);var e,s=d.attributes,n,g,l,u="",q;e="<"+h;n=s.length;for(g=0;g")}if(k===NodeFilter.FILTER_ACCEPT||k===NodeFilter.FILTER_SKIP){for(k=d.firstChild;k;)b+=f(c,k),k=k.nextSibling;d.nodeValue&&(b+=m(d.nodeValue))}h&&(b+="",c.pop());return b}var a=this;this.filter=null;this.writeToString=function(a,d){if(!a)return"";var b=new h(d);return f(b,a)}}; +xmldom.LSSerializerFilter=function(){}; // Input 21 -xmldom.RelaxNGParser=function(){function h(a,b){this.message=function(){b&&(a+=1===b.nodeType?" Element ":" Node ",a+=b.nodeName,b.nodeValue&&(a+=" with value '"+b.nodeValue+"'"),a+=".");return a}}function m(a){if(2>=a.e.length)return a;var b={name:a.name,e:a.e.slice(0,2)};return m({name:a.name,e:[b].concat(a.e.slice(2))})}function f(a){a=a.split(":",2);var b="",c;1===a.length?a=["",a[0]]:b=a[0];for(c in k)k[c]===b&&(a[0]=c);return a}function a(b,c){for(var d=0,g,l,k=b.name;b.e&&d/g,">").replace(/'/g,"'").replace(/"/g,""")}function f(e,p){var c="",b=n.filter?n.filter.acceptNode(p):NodeFilter.FILTER_ACCEPT,a;if(b===NodeFilter.FILTER_ACCEPT&&p.nodeType===Node.ELEMENT_NODE){e.push();a=e.getQName(p);var d,k=p.attributes,g,q,l,r="",t;d="<"+a;g=k.length;for(q=0;q")}if(b===NodeFilter.FILTER_ACCEPT||b===NodeFilter.FILTER_SKIP){for(b=p.firstChild;b;)c+=f(e,b),b=b.nextSibling;p.nodeValue&&(c+=h(p.nodeValue))}a&&(c+="",e.pop());return c}var n=this;this.filter=null;this.writeToString=function(h,p){if(!h)return"";var c=new e(p);return f(c,h)}}; // Input 22 -runtime.loadClass("xmldom.RelaxNGParser"); -xmldom.RelaxNG=function(){function h(a){return function(){var b;return function(){void 0===b&&(b=a());return b}}()}function m(a,b){return function(){var c={},d=0;return function(e){var g=e.hash||e.toString(),l;l=c[g];if(void 0!==l)return l;c[g]=l=b(e);l.hash=a+d.toString();d+=1;return l}}()}function f(a){return function(){var b={};return function(c){var d,e;e=b[c.localName];if(void 0===e)b[c.localName]=e={};else if(d=e[c.namespaceURI],void 0!==d)return d;return e[c.namespaceURI]=d=a(c)}}()}function a(a, -b,c){return function(){var d={},e=0;return function(g,l){var k=b&&b(g,l),n,f;if(void 0!==k)return k;k=g.hash||g.toString();n=l.hash||l.toString();f=d[k];if(void 0===f)d[k]=f={};else if(k=f[n],void 0!==k)return k;f[n]=k=c(g,l);k.hash=a+e.toString();e+=1;return k}}()}function c(a,b){"choice"===b.p1.type?c(a,b.p1):a[b.p1.hash]=b.p1;"choice"===b.p2.type?c(a,b.p2):a[b.p2.hash]=b.p2}function d(a,b){return{type:"element",nc:a,nullable:!1,textDeriv:function(){return w},startTagOpenDeriv:function(c){return a.contains(c)? -l(b,v):w},attDeriv:function(){return w},startTagCloseDeriv:function(){return this}}}function b(){return{type:"list",nullable:!1,hash:"list",textDeriv:function(){return v}}}function k(a,b,c,d){if(b===w)return w;if(d>=c.length)return b;0===d&&(d=0);for(var g=c.item(d);g.namespaceURI===e;){d+=1;if(d>=c.length)return b;g=c.item(d)}return g=k(a,b.attDeriv(a,c.item(d)),c,d+1)}function p(a,b,c){c.e[0].a?(a.push(c.e[0].text),b.push(c.e[0].a.ns)):p(a,b,c.e[0]);c.e[1].a?(a.push(c.e[1].text),b.push(c.e[1].a.ns)): -p(a,b,c.e[1])}var e="http://www.w3.org/2000/xmlns/",s,n,g,l,u,q,x,r,y,t,w={type:"notAllowed",nullable:!1,hash:"notAllowed",textDeriv:function(){return w},startTagOpenDeriv:function(){return w},attDeriv:function(){return w},startTagCloseDeriv:function(){return w},endTagDeriv:function(){return w}},v={type:"empty",nullable:!0,hash:"empty",textDeriv:function(){return w},startTagOpenDeriv:function(){return w},attDeriv:function(){return w},startTagCloseDeriv:function(){return v},endTagDeriv:function(){return w}}, -C={type:"text",nullable:!0,hash:"text",textDeriv:function(){return C},startTagOpenDeriv:function(){return w},attDeriv:function(){return w},startTagCloseDeriv:function(){return C},endTagDeriv:function(){return w}},J,E,K;s=a("choice",function(a,b){if(a===w)return b;if(b===w||a===b)return a},function(a,b){var d={},e;c(d,{p1:a,p2:b});b=a=void 0;for(e in d)d.hasOwnProperty(e)&&(void 0===a?a=d[e]:b=void 0===b?d[e]:s(b,d[e]));return function(a,b){return{type:"choice",p1:a,p2:b,nullable:a.nullable||b.nullable, -textDeriv:function(c,d){return s(a.textDeriv(c,d),b.textDeriv(c,d))},startTagOpenDeriv:f(function(c){return s(a.startTagOpenDeriv(c),b.startTagOpenDeriv(c))}),attDeriv:function(c,d){return s(a.attDeriv(c,d),b.attDeriv(c,d))},startTagCloseDeriv:h(function(){return s(a.startTagCloseDeriv(),b.startTagCloseDeriv())}),endTagDeriv:h(function(){return s(a.endTagDeriv(),b.endTagDeriv())})}}(a,b)});n=function(a,b,c){return function(){var d={},e=0;return function(g,l){var k=b&&b(g,l),n,f;if(void 0!==k)return k; -k=g.hash||g.toString();n=l.hash||l.toString();k=a.e.length)return a;var b={name:a.name,e:a.e.slice(0,2)};return h({name:a.name,e:[b].concat(a.e.slice(2))})}function f(a){a=a.split(":",2);var c="",g;1===a.length?a=["",a[0]]:c=a[0];for(g in b)b[g]===c&&(a[0]=g);return a}function n(a,b){for(var c=0,e,l,h=a.name;a.e&&cNode.ELEMENT_NODE;){if(e!==Node.COMMENT_NODE&&(e!==Node.TEXT_NODE||!/^\s+$/.test(c.currentNode.nodeValue)))return[new h("Not allowed node of type "+ -e+".")];e=(f=c.nextSibling())?f.nodeType:0}if(!f)return[new h("Missing element "+a.names)];if(a.names&&-1===a.names.indexOf(d[f.namespaceURI]+":"+f.localName))return[new h("Found "+f.nodeName+" instead of "+a.names+".",f)];if(c.firstChild()){for(s=m(a.e[1],c,f);c.nextSibling();)if(e=c.currentNode.nodeType,!(c.currentNode&&c.currentNode.nodeType===Node.TEXT_NODE&&/^\s+$/.test(c.currentNode.nodeValue)||e===Node.COMMENT_NODE))return[new h("Spurious content.",c.currentNode)];if(c.parentNode()!==f)return[new h("Implementation error.")]}else s= -m(a.e[1],c,f);c.nextSibling();return s}var a,c,d;c=function(a,d,p,e){var s=a.name,n=null;if("text"===s)a:{for(var g=(a=d.currentNode)?a.nodeType:0;a!==p&&3!==g;){if(1===g){n=[new h("Element not allowed here.",a)];break a}g=(a=d.nextSibling())?a.nodeType:0}d.nextSibling();n=null}else if("data"===s)n=null;else if("value"===s)e!==a.text&&(n=[new h("Wrong value, should be '"+a.text+"', not '"+e+"'",p)]);else if("list"===s)n=null;else if("attribute"===s)a:{if(2!==a.e.length)throw"Attribute with wrong # of elements: "+ -a.e.length;s=a.localnames.length;for(n=0;n=g.length)return c;0===e&&(e=0);for(var l=g.item(e);l.namespaceURI===d;){e+=1;if(e>=g.length)return c;l=g.item(e)}return l=b(a,c.attDeriv(a,g.item(e)),g,e+1)}function a(b,d,c){c.e[0].a?(b.push(c.e[0].text),d.push(c.e[0].a.ns)):a(b,d,c.e[0]);c.e[1].a?(b.push(c.e[1].text),d.push(c.e[1].a.ns)): +a(b,d,c.e[1])}var d="http://www.w3.org/2000/xmlns/",k,g,q,l,r,t,w,v,y,x,u={type:"notAllowed",nullable:!1,hash:"notAllowed",textDeriv:function(){return u},startTagOpenDeriv:function(){return u},attDeriv:function(){return u},startTagCloseDeriv:function(){return u},endTagDeriv:function(){return u}},s={type:"empty",nullable:!0,hash:"empty",textDeriv:function(){return u},startTagOpenDeriv:function(){return u},attDeriv:function(){return u},startTagCloseDeriv:function(){return s},endTagDeriv:function(){return u}}, +C={type:"text",nullable:!0,hash:"text",textDeriv:function(){return C},startTagOpenDeriv:function(){return u},attDeriv:function(){return u},startTagCloseDeriv:function(){return C},endTagDeriv:function(){return u}},B,A,I;k=n("choice",function(a,b){if(a===u)return b;if(b===u||a===b)return a},function(a,b){var d={},c;m(d,{p1:a,p2:b});b=a=void 0;for(c in d)d.hasOwnProperty(c)&&(void 0===a?a=d[c]:b=void 0===b?d[c]:k(b,d[c]));return function(a,b){return{type:"choice",p1:a,p2:b,nullable:a.nullable||b.nullable, +textDeriv:function(d,c){return k(a.textDeriv(d,c),b.textDeriv(d,c))},startTagOpenDeriv:f(function(d){return k(a.startTagOpenDeriv(d),b.startTagOpenDeriv(d))}),attDeriv:function(d,c){return k(a.attDeriv(d,c),b.attDeriv(d,c))},startTagCloseDeriv:e(function(){return k(a.startTagCloseDeriv(),b.startTagCloseDeriv())}),endTagDeriv:e(function(){return k(a.endTagDeriv(),b.endTagDeriv())})}}(a,b)});g=function(a,b,d){return function(){var c={},g=0;return function(e,l){var f=b&&b(e,l),k,h;if(void 0!==f)return f; +f=e.hash||e.toString();k=l.hash||l.toString();f=k&&c.push(m(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(){};e=function(d,e,l){var f,h,m,r;for(f=0;fNode.ELEMENT_NODE;){if(d!==Node.COMMENT_NODE&&(d!==Node.TEXT_NODE||!/^\s+$/.test(b.currentNode.nodeValue)))return[new e("Not allowed node of type "+ +d+".")];d=(a=b.nextSibling())?a.nodeType:0}if(!a)return[new e("Missing element "+c.names)];if(c.names&&-1===c.names.indexOf(p[a.namespaceURI]+":"+a.localName))return[new e("Found "+a.nodeName+" instead of "+c.names+".",a)];if(b.firstChild()){for(f=h(c.e[1],b,a);b.nextSibling();)if(d=b.currentNode.nodeType,!(b.currentNode&&b.currentNode.nodeType===Node.TEXT_NODE&&/^\s+$/.test(b.currentNode.nodeValue)||d===Node.COMMENT_NODE))return[new e("Spurious content.",b.currentNode)];if(b.parentNode()!==a)return[new e("Implementation error.")]}else f= +h(c.e[1],b,a);b.nextSibling();return f}var n,m,p;m=function(c,b,a,d){var k=c.name,g=null;if("text"===k)a:{for(var q=(c=b.currentNode)?c.nodeType:0;c!==a&&3!==q;){if(1===q){g=[new e("Element not allowed here.",c)];break a}q=(c=b.nextSibling())?c.nodeType:0}b.nextSibling();g=null}else if("data"===k)g=null;else if("value"===k)d!==c.text&&(g=[new e("Wrong value, should be '"+c.text+"', not '"+d+"'",a)]);else if("list"===k)g=null;else if("attribute"===k)a:{if(2!==c.e.length)throw"Attribute with wrong # of elements: "+ +c.e.length;k=c.localnames.length;for(g=0;g=f&&d.push(h(a.substring(b,c)))):"["===a[c]&&(0>=f&&(b=c+1),f+=1),c+=1;return c};xmldom.XPathIterator.prototype.next=function(){};xmldom.XPathIterator.prototype.reset=function(){};d=function(a,d,e){var f,k,h,p;for(f=0;f @@ -352,6 +367,9 @@ function(){this.getODFElementsWithXPath=p};return xmldom.XPath}(); 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 @@ -372,16 +390,16 @@ function(){this.getODFElementsWithXPath=p};return xmldom.XPath}(); This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -gui.AnnotationViewManager=function(h,m,f){function a(a){var b=a.node,c=a.end;a=p.createRange();c&&(a.setStart(b,b.childNodes.length),a.setEnd(c,0),c=e.getTextNodes(a,!1),c.forEach(function(a){var c=p.createElement("span");c.className="annotationHighlight";c.setAttribute("annotation",b.getAttributeNS(odf.Namespaces.officens,"name"));a.parentNode.insertBefore(c,a);c.appendChild(a)}));a.detach()}function c(a){var b=h.getSizer();a?(f.style.display="inline-block",b.style.paddingRight=s.getComputedStyle(f).width): -(f.style.display="none",b.style.paddingRight=0);h.refreshSize()}function d(){k.sort(function(a,b){return a.node.compareDocumentPosition(b.node)===Node.DOCUMENT_POSITION_FOLLOWING?-1:1})}function b(){var a;for(a=0;a=(m.getBoundingClientRect().top-t.bottom)/r?c.style.top=Math.abs(m.getBoundingClientRect().top-t.bottom)/r+20+"px":c.style.top="0px");e.style.left=d.getBoundingClientRect().width/r+"px";var d=e.style,m=e.getBoundingClientRect().left/r,y=e.getBoundingClientRect().top/r,t=c.getBoundingClientRect().left/r,w=c.getBoundingClientRect().top/r,v=0,C= -0,v=t-m,v=v*v,C=w-y,C=C*C,m=Math.sqrt(v+C);d.width=m+"px";r=Math.asin((c.getBoundingClientRect().top-e.getBoundingClientRect().top)/(r*parseFloat(e.style.width)));e.style.transform="rotate("+r+"rad)";e.style.MozTransform="rotate("+r+"rad)";e.style.WebkitTransform="rotate("+r+"rad)";e.style.msTransform="rotate("+r+"rad)";b&&(r=s.getComputedStyle(b,":before").content)&&"none"!==r&&(r=r.substring(1,r.length-1),b.firstChild?b.firstChild.nodeValue=r:b.appendChild(p.createTextNode(r)))}}var k=[],p=m.ownerDocument, -e=new odf.OdfUtils,s=runtime.getWindow();runtime.assert(Boolean(s),"Expected to be run in an environment which has a global window, like a browser.");this.rerenderAnnotations=b;this.addAnnotation=function(e){c(!0);k.push({node:e.node,end:e.end});d();var g=p.createElement("div"),l=p.createElement("div"),f=p.createElement("div"),h=p.createElement("div"),m=p.createElement("div"),r=e.node;g.className="annotationWrapper";r.parentNode.insertBefore(g,r);l.className="annotationNote";l.appendChild(r);m.className= -"annotationRemoveButton";l.appendChild(m);f.className="annotationConnector horizontal";h.className="annotationConnector angular";g.appendChild(l);g.appendChild(f);g.appendChild(h);e.end&&a(e);b()};this.forgetAnnotations=function(){for(;k.length;){var a=k[0],b=k.indexOf(a),d=a.node,e=d.parentNode.parentNode;"div"===e.localName&&(e.parentNode.insertBefore(d,e),e.parentNode.removeChild(e));a=a.node.getAttributeNS(odf.Namespaces.officens,"name");a=p.querySelectorAll('span.annotationHighlight[annotation="'+ -a+'"]');e=d=void 0;for(d=0;d=(p.getBoundingClientRect().top-x.bottom)/n?l.style.top=Math.abs(p.getBoundingClientRect().top-x.bottom)/n+20+"px":l.style.top="0px");m.style.left=h.getBoundingClientRect().width/n+"px";var h=m.style,p=m.getBoundingClientRect().left/n,y=m.getBoundingClientRect().top/n,x=l.getBoundingClientRect().left/n,u=l.getBoundingClientRect().top/n,s=0,C= +0,s=x-p,s=s*s,C=u-y,C=C*C,p=Math.sqrt(s+C);h.width=p+"px";n=Math.asin((l.getBoundingClientRect().top-m.getBoundingClientRect().top)/(n*parseFloat(m.style.width)));m.style.transform="rotate("+n+"rad)";m.style.MozTransform="rotate("+n+"rad)";m.style.WebkitTransform="rotate("+n+"rad)";m.style.msTransform="rotate("+n+"rad)";c&&(n=k.getComputedStyle(c,":before").content)&&"none"!==n&&(/^["'].*["']$/.test(n)&&(n=n.substring(1,n.length-1)),c.firstChild?c.firstChild.nodeValue=n:c.appendChild(a.createTextNode(n)))}} +var b=[],a=h.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=c;this.addAnnotation=function(d){m(!0);b.push({node:d.node,end:d.end});p();var e=a.createElement("div"),f=a.createElement("div"),k=a.createElement("div"),h=a.createElement("div"),w=a.createElement("div"),v=d.node;e.className="annotationWrapper";v.parentNode.insertBefore(e,v);f.className="annotationNote"; +f.appendChild(v);w.className="annotationRemoveButton";f.appendChild(w);k.className="annotationConnector horizontal";h.className="annotationConnector angular";e.appendChild(f);e.appendChild(k);e.appendChild(h);d.end&&n(d);c()};this.forgetAnnotations=function(){for(;b.length;){var d=b[0],c=b.indexOf(d),e=d.node,f=e.parentNode.parentNode;"div"===f.localName&&(f.parentNode.insertBefore(e,f),f.parentNode.removeChild(f));d=d.node.getAttributeNS(odf.Namespaces.officens,"name");d=a.querySelectorAll('span.annotationHighlight[annotation="'+ +d+'"]');f=e=void 0;for(e=0;e @@ -394,6 +412,9 @@ a+'"]');e=d=void 0;for(d=0;d. + 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 @@ -414,10 +435,10 @@ a+'"]');e=d=void 0;for(d=0;d @@ -430,6 +451,9 @@ odf.OdfNodeFilter=function(){this.acceptNode=function(h){return"http://www.w3.or 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 @@ -450,14 +474,13 @@ odf.OdfNodeFilter=function(){this.acceptNode=function(h){return"http://www.w3.or This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -odf.Namespaces=function(){function h(a){return m[a]||null}var m={db:"urn:oasis:names:tc:opendocument:xmlns:database:1.0",dc:"http://purl.org/dc/elements/1.1/",dr3d:"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0",draw:"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",chart:"urn:oasis:names:tc:opendocument:xmlns:chart:1.0",fo:"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",form:"urn:oasis:names:tc:opendocument:xmlns:form:1.0",numberns:"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0", -office:"urn:oasis:names:tc:opendocument:xmlns:office:1.0",presentation:"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0",style:"urn:oasis:names:tc:opendocument:xmlns:style:1.0",svg:"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",table:"urn:oasis:names:tc:opendocument:xmlns:table:1.0",text:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",webodf:"urn:webodf"},f;h.lookupNamespaceURI=h;f=function(){};f.forEachPrefix= -function(a){for(var c in m)m.hasOwnProperty(c)&&a(c,m[c])};f.resolvePrefix=h;f.namespaceMap=m;f.dbns="urn:oasis:names:tc:opendocument:xmlns:database:1.0";f.dcns="http://purl.org/dc/elements/1.1/";f.dr3dns="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0";f.drawns="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0";f.chartns="urn:oasis:names:tc:opendocument:xmlns:chart:1.0";f.fons="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0";f.formns="urn:oasis:names:tc:opendocument:xmlns:form:1.0"; -f.numberns="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0";f.officens="urn:oasis:names:tc:opendocument:xmlns:office:1.0";f.presentationns="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0";f.stylens="urn:oasis:names:tc:opendocument:xmlns:style:1.0";f.svgns="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0";f.tablens="urn:oasis:names:tc:opendocument:xmlns:table:1.0";f.textns="urn:oasis:names:tc:opendocument:xmlns:text:1.0";f.xlinkns="http://www.w3.org/1999/xlink";f.xmlns="http://www.w3.org/XML/1998/namespace"; -f.webodfns="urn:webodf";return f}(); -// Input 28 +odf.Namespaces=function(){function e(e){return h[e]||null}var h={db:"urn:oasis:names:tc:opendocument:xmlns:database:1.0",dc:"http://purl.org/dc/elements/1.1/",dr3d:"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0",draw:"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",chart:"urn:oasis:names:tc:opendocument:xmlns:chart:1.0",fo:"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",form:"urn:oasis:names:tc:opendocument:xmlns:form:1.0",numberns:"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0", +office:"urn:oasis:names:tc:opendocument:xmlns:office:1.0",presentation:"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0",style:"urn:oasis:names:tc:opendocument:xmlns:style:1.0",svg:"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",table:"urn:oasis:names:tc:opendocument:xmlns:table:1.0",text:"urn:oasis:names:tc:opendocument:xmlns:text:1.0",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace"},f;e.lookupNamespaceURI=e;f=function(){};f.forEachPrefix=function(e){for(var f in h)h.hasOwnProperty(f)&& +e(f,h[f])};f.resolvePrefix=e;f.namespaceMap=h;f.dbns="urn:oasis:names:tc:opendocument:xmlns:database:1.0";f.dcns="http://purl.org/dc/elements/1.1/";f.dr3dns="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0";f.drawns="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0";f.chartns="urn:oasis:names:tc:opendocument:xmlns:chart:1.0";f.fons="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0";f.formns="urn:oasis:names:tc:opendocument:xmlns:form:1.0";f.numberns="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"; +f.officens="urn:oasis:names:tc:opendocument:xmlns:office:1.0";f.presentationns="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0";f.stylens="urn:oasis:names:tc:opendocument:xmlns:style:1.0";f.svgns="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0";f.tablens="urn:oasis:names:tc:opendocument:xmlns:table:1.0";f.textns="urn:oasis:names:tc:opendocument:xmlns:text:1.0";f.xlinkns="http://www.w3.org/1999/xlink";f.xmlns="http://www.w3.org/XML/1998/namespace";return f}(); +// Input 29 /* Copyright (C) 2012-2013 KO GmbH @@ -470,6 +493,9 @@ f.webodfns="urn:webodf";return f}(); 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 @@ -490,37 +516,38 @@ f.webodfns="urn:webodf";return f}(); This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.Namespaces"); -odf.StyleInfo=function(){function h(a,b){for(var c=v[a.localName],d=c&&c[a.namespaceURI],e=d?d.length:0,g,c=0;c @@ -533,6 +560,9 @@ k=d,l=e.getAttributeNS(g,"name"),f=void 0;l?f=g:(l=e.getAttributeNS(r,"name"))&& 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 @@ -553,21 +583,22 @@ k=d,l=e.getAttributeNS(g,"name"),f=void 0;l?f=g:(l=e.getAttributeNS(r,"name"))&& This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils");runtime.loadClass("odf.Namespaces"); -odf.OdfUtils=function(){function h(a){var c=a&&a.localName;return("p"===c||"h"===c)&&a.namespaceURI===r}function m(a){for(;a&&!h(a);)a=a.parentNode;return a}function f(a){return/^[ \t\r\n]+$/.test(a)}function a(a){var c=a&&a.localName;return/^(span|p|h|a|meta)$/.test(c)&&a.namespaceURI===r||"span"===c&&"annotationHighlight"===a.className?!0:!1}function c(a){var c=a&&a.localName,b,d=!1;c&&(b=a.namespaceURI,b===r?d="s"===c||"tab"===c||"line-break"===c:b===y&&(d="frame"===c&&"as-char"===a.getAttributeNS(r, -"anchor-type")));return d}function d(c){for(;null!==c.firstChild&&a(c);)c=c.firstChild;return c}function b(c){for(;null!==c.lastChild&&a(c);)c=c.lastChild;return c}function k(a){for(;!h(a)&&null===a.previousSibling;)a=a.parentNode;return h(a)?null:b(a.previousSibling)}function p(a){for(;!h(a)&&null===a.nextSibling;)a=a.parentNode;return h(a)?null:d(a.nextSibling)}function e(a){for(var b=!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 c(a)? -(b=!0,a=null):a=k(a);return b}function s(a){var b=!1;for(a=a&&d(a);a;){if(a.nodeType===Node.TEXT_NODE&&0a.value||"%"===a.unit)?null:a}function q(a){return(a=l(a))&&"%"!==a.unit?null:a}function x(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 r=odf.Namespaces.textns,y=odf.Namespaces.drawns,t=/^\s*$/,w=new core.DomUtils;this.isParagraph=h;this.getParagraphElement=m;this.isWithinTrackedChanges=function(a,c){for(;a&&a!==c;){if(a.namespaceURI===r&&"tracked-changes"===a.localName)return!0;a=a.parentNode}return!1};this.isListItem=function(a){return"list-item"===(a&&a.localName)&&a.namespaceURI===r};this.isODFWhitespace=f;this.isGroupingElement=a;this.isCharacterElement=c;this.firstChild=d;this.lastChild=b;this.previousNode=k;this.nextNode= -p;this.scanLeftForNonWhitespace=e;this.lookLeftForCharacter=function(a){var b;b=0;a.nodeType===Node.TEXT_NODE&&0=c.value|| -"%"===c.unit)?null:c;return c||q(a)};this.parseFoLineHeight=function(a){return u(a)||q(a)};this.getImpactedParagraphs=function(a){var c=a.commonAncestorContainer,b=[];for(c.nodeType===Node.ELEMENT_NODE&&(b=w.getElementsByTagNameNS(c,r,"p").concat(w.getElementsByTagNameNS(c,r,"h")));c&&!h(c);)c=c.parentNode;c&&b.push(c);return b.filter(function(c){return w.rangeIntersectsNode(a,c)})};this.getTextNodes=function(a,c){var b=a.startContainer.ownerDocument.createRange(),d;d=w.getNodesInRange(a,function(d){b.selectNodeContents(d); -if(d.nodeType===Node.TEXT_NODE){if(c&&w.rangesIntersect(a,b)||w.containsRange(a,b))return Boolean(m(d)&&(!f(d.textContent)||g(d,0)))?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}else if(w.rangesIntersect(a,b)&&x(d))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});b.detach();return d};this.getTextElements=function(b,d){var e=b.startContainer.ownerDocument.createRange(),k;k=w.getNodesInRange(b,function(k){var l=k.nodeType;e.selectNodeContents(k);if(l===Node.TEXT_NODE){if(w.containsRange(b, -e)&&(d||Boolean(m(k)&&(!f(k.textContent)||g(k,0)))))return NodeFilter.FILTER_ACCEPT}else if(c(k)){if(w.containsRange(b,e))return NodeFilter.FILTER_ACCEPT}else if(x(k)||a(k))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});e.detach();return k};this.getParagraphElements=function(c){var b=c.startContainer.ownerDocument.createRange(),d;d=w.getNodesInRange(c,function(d){b.selectNodeContents(d);if(h(d)){if(w.rangesIntersect(c,b))return NodeFilter.FILTER_ACCEPT}else if(x(d)||a(d))return NodeFilter.FILTER_SKIP; -return NodeFilter.FILTER_REJECT});b.detach();return d}}; -// Input 30 +odf.OdfUtils=function(){function e(a){return"image"===(a&&a.localName)&&a.namespaceURI===s}function h(a){return"frame"===(a&&a.localName)&&a.namespaceURI===s&&"as-char"===a.getAttributeNS(u,"anchor-type")}function f(a){var b=a&&a.localName;return("p"===b||"h"===b)&&a.namespaceURI===u}function n(a){for(;a&&!f(a);)a=a.parentNode;return a}function m(a){return/^[ \t\r\n]+$/.test(a)}function p(a){var b=a&&a.localName;return/^(span|p|h|a|meta)$/.test(b)&&a.namespaceURI===u||"span"===b&&"annotationHighlight"=== +a.className?!0:!1}function c(a){var b=a&&a.localName,d;d=!1;b&&(d=a.namespaceURI,d=d===u?"s"===b||"tab"===b||"line-break"===b:h(a));return d}function b(a){var b=a&&a.localName,d=!1;b&&(a=a.namespaceURI,a===u&&(d="s"===b||"tab"===b));return d}function a(a){for(;null!==a.firstChild&&p(a);)a=a.firstChild;return a}function d(a){for(;null!==a.lastChild&&p(a);)a=a.lastChild;return a}function k(a){for(;!f(a)&&null===a.previousSibling;)a=a.parentNode;return f(a)?null:d(a.previousSibling)}function g(b){for(;!f(b)&& +null===b.nextSibling;)b=b.parentNode;return f(b)?null:a(b.nextSibling)}function q(a){for(var d=!1;a;)if(a.nodeType===Node.TEXT_NODE)if(0===a.length)a=k(a);else return!m(a.data.substr(a.length-1,1));else c(a)?(d=!1===b(a),a=null):a=k(a);return d}function l(b){var d=!1;for(b=b&&a(b);b;){if(b.nodeType===Node.TEXT_NODE&&0a.value||"%"===a.unit)?null:a}function y(a){return(a=w(a))&&"%"!==a.unit?null:a}function x(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 u=odf.Namespaces.textns,s=odf.Namespaces.drawns,C=/^\s*$/,B=new core.DomUtils;this.isImage=e;this.isCharacterFrame=h;this.isTextSpan=function(a){return"span"===(a&&a.localName)&&a.namespaceURI===u};this.isParagraph=f;this.getParagraphElement=n;this.isWithinTrackedChanges=function(a,b){for(;a&&a!==b;){if(a.namespaceURI=== +u&&"tracked-changes"===a.localName)return!0;a=a.parentNode}return!1};this.isListItem=function(a){return"list-item"===(a&&a.localName)&&a.namespaceURI===u};this.isLineBreak=function(a){return"line-break"===(a&&a.localName)&&a.namespaceURI===u};this.isODFWhitespace=m;this.isGroupingElement=p;this.isCharacterElement=c;this.isWhitespaceElement=b;this.firstChild=a;this.lastChild=d;this.previousNode=k;this.nextNode=g;this.scanLeftForNonWhitespace=q;this.lookLeftForCharacter=function(a){var b;b=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,d=[];for(b.nodeType===Node.ELEMENT_NODE&&(d=B.getElementsByTagNameNS(b,u,"p").concat(B.getElementsByTagNameNS(b,u,"h")));b&&!f(b);)b=b.parentNode;b&&d.push(b);return d.filter(function(b){return B.rangeIntersectsNode(a,b)})};this.getTextNodes=function(a,b){var d=a.startContainer.ownerDocument.createRange(),c;c=B.getNodesInRange(a,function(c){d.selectNodeContents(c);if(c.nodeType===Node.TEXT_NODE){if(b&&B.rangesIntersect(a,d)||B.containsRange(a,d))return Boolean(n(c)&& +(!m(c.textContent)||t(c,0)))?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}else if(B.rangesIntersect(a,d)&&x(c))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});d.detach();return c};this.getTextElements=function(a,b,d){var e=a.startContainer.ownerDocument.createRange(),f;f=B.getNodesInRange(a,function(f){e.selectNodeContents(f);if(c(f.parentNode))return NodeFilter.FILTER_REJECT;if(f.nodeType===Node.TEXT_NODE){if(b&&B.rangesIntersect(a,e)||B.containsRange(a,e))if(d||Boolean(n(f)&& +(!m(f.textContent)||t(f,0))))return NodeFilter.FILTER_ACCEPT}else if(c(f)){if(b&&B.rangesIntersect(a,e)||B.containsRange(a,e))return NodeFilter.FILTER_ACCEPT}else if(x(f)||p(f))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});e.detach();return f};this.getParagraphElements=function(a){var b=a.startContainer.ownerDocument.createRange(),d;d=B.getNodesInRange(a,function(d){b.selectNodeContents(d);if(f(d)){if(B.rangesIntersect(a,b))return NodeFilter.FILTER_ACCEPT}else if(x(d)||p(d))return NodeFilter.FILTER_SKIP; +return NodeFilter.FILTER_REJECT});b.detach();return d};this.getImageElements=function(a){var b=a.startContainer.ownerDocument.createRange(),d;d=B.getNodesInRange(a,function(d){b.selectNodeContents(d);return e(d)&&B.containsRange(a,b)?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP});b.detach();return d}}; +// Input 31 /* Copyright (C) 2013 KO GmbH @@ -580,6 +611,9 @@ return NodeFilter.FILTER_REJECT});b.detach();return d}}; 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 @@ -600,11 +634,11 @@ return NodeFilter.FILTER_REJECT});b.detach();return d}}; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("odf.OdfUtils"); -odf.TextSerializer=function(){function h(a){var c="",d=m.filter?m.filter.acceptNode(a):NodeFilter.FILTER_ACCEPT,b=a.nodeType,k;if(d===NodeFilter.FILTER_ACCEPT||d===NodeFilter.FILTER_SKIP)for(k=a.firstChild;k;)c+=h(k),k=k.nextSibling;d===NodeFilter.FILTER_ACCEPT&&(b===Node.ELEMENT_NODE&&f.isParagraph(a)?c+="\n":b===Node.TEXT_NODE&&a.textContent&&(c+=a.textContent));return c}var m=this,f=new odf.OdfUtils;this.filter=null;this.writeToString=function(a){return a?h(a):""}}; -// Input 31 +odf.TextSerializer=function(){function e(n){var m="",p=h.filter?h.filter.acceptNode(n):NodeFilter.FILTER_ACCEPT,c=n.nodeType,b;if(p===NodeFilter.FILTER_ACCEPT||p===NodeFilter.FILTER_SKIP)for(b=n.firstChild;b;)m+=e(b),b=b.nextSibling;p===NodeFilter.FILTER_ACCEPT&&(c===Node.ELEMENT_NODE&&f.isParagraph(n)?m+="\n":c===Node.TEXT_NODE&&n.textContent&&(m+=n.textContent));return m}var h=this,f=new odf.OdfUtils;this.filter=null;this.writeToString=function(f){return f?e(f):""}}; +// Input 32 /* Copyright (C) 2012-2013 KO GmbH @@ -617,6 +651,9 @@ odf.TextSerializer=function(){function h(a){var c="",d=m.filter?m.filter.acceptN 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 @@ -637,14 +674,14 @@ odf.TextSerializer=function(){function h(a){var c="",d=m.filter?m.filter.acceptN This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils");runtime.loadClass("core.LoopWatchDog");runtime.loadClass("odf.Namespaces"); -odf.TextStyleApplicator=function(h,m,f){function a(a){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(b){b=m.getAppliedStylesForElement(b);return c(a,b)}}function c(a){var c={};this.applyStyleToContainer=function(b){var d;d=b.getAttributeNS(k,"style-name");var l=b.ownerDocument;d=d||"";if(!c.hasOwnProperty(d)){var u=d,q;q=d?m.createDerivedStyleObject(d,"text",a):a;l=l.createElementNS(p,"style:style"); -m.updateStyle(l,q);l.setAttributeNS(p,"style:name",h.generateName());l.setAttributeNS(p,"style:family","text");l.setAttributeNS("urn:webodf:names:scope","scope","document-content");f.appendChild(l);c[u]=l}d=c[d].getAttributeNS(p,"name");b.setAttributeNS(k,"text:style-name",d)}}function d(a,c){var d=a.ownerDocument,g=a.parentNode,l,f,h=new core.LoopWatchDog(1E3);f=[];"span"!==g.localName||g.namespaceURI!==k?(l=d.createElementNS(k,"text:span"),g.insertBefore(l,a),g=!1):(a.previousSibling&&!b.rangeContainsNode(c, -g.firstChild)?(l=g.cloneNode(!1),g.parentNode.insertBefore(l,g.nextSibling)):l=g,g=!0);f.push(a);for(d=a.nextSibling;d&&b.rangeContainsNode(c,d);)h.check(),f.push(d),d=d.nextSibling;f.forEach(function(a){a.parentNode!==l&&l.appendChild(a)});if(d&&g)for(f=l.cloneNode(!1),l.parentNode.insertBefore(f,l.nextSibling);d;)h.check(),g=d.nextSibling,f.appendChild(d),d=g;return l}var b=new core.DomUtils,k=odf.Namespaces.textns,p=odf.Namespaces.stylens;this.applyStyle=function(b,k,f){var g={},l,h,m,p;runtime.assert(f&& -f["style:text-properties"],"applyStyle without any text properties");g["style:text-properties"]=f["style:text-properties"];m=new c(g);p=new a(g);b.forEach(function(a){l=p.isStyleApplied(a);!1===l&&(h=d(a,k),m.applyStyleToContainer(h))})}}; -// Input 32 +odf.TextStyleApplicator=function(e,h,f){function n(a){function b(a,d){return"object"===typeof a&&"object"===typeof d?Object.keys(a).every(function(c){return b(a[c],d[c])}):a===d}this.isStyleApplied=function(c){c=h.getAppliedStylesForElement(c);return b(a,c)}}function m(d){var c={};this.applyStyleToContainer=function(g){var q;q=g.getAttributeNS(b,"style-name");var l=g.ownerDocument;q=q||"";if(!c.hasOwnProperty(q)){var m=q,p;p=q?h.createDerivedStyleObject(q,"text",d):d;l=l.createElementNS(a,"style:style"); +h.updateStyle(l,p);l.setAttributeNS(a,"style:name",e.generateStyleName());l.setAttributeNS(a,"style:family","text");l.setAttributeNS("urn:webodf:names:scope","scope","document-content");f.appendChild(l);c[m]=l}q=c[q].getAttributeNS(a,"name");g.setAttributeNS(b,"text:style-name",q)}}function p(a,e){var f=a.ownerDocument,h=a.parentNode,l,m,p=new core.LoopWatchDog(1E3);m=[];"span"!==h.localName||h.namespaceURI!==b?(l=f.createElementNS(b,"text:span"),h.insertBefore(l,a),h=!1):(a.previousSibling&&!c.rangeContainsNode(e, +h.firstChild)?(l=h.cloneNode(!1),h.parentNode.insertBefore(l,h.nextSibling)):l=h,h=!0);m.push(a);for(f=a.nextSibling;f&&c.rangeContainsNode(e,f);)p.check(),m.push(f),f=f.nextSibling;m.forEach(function(a){a.parentNode!==l&&l.appendChild(a)});if(f&&h)for(m=l.cloneNode(!1),l.parentNode.insertBefore(m,l.nextSibling);f;)p.check(),h=f.nextSibling,m.appendChild(f),f=h;return l}var c=new core.DomUtils,b=odf.Namespaces.textns,a=odf.Namespaces.stylens;this.applyStyle=function(a,b,c){var e={},f,h,t,w;runtime.assert(c&& +c["style:text-properties"],"applyStyle without any text properties");e["style:text-properties"]=c["style:text-properties"];t=new m(e);w=new n(e);a.forEach(function(a){f=w.isStyleApplied(a);!1===f&&(h=p(a,b),t.applyStyleToContainer(h))})}}; +// Input 33 /* Copyright (C) 2012-2013 KO GmbH @@ -657,6 +694,9 @@ f["style:text-properties"],"applyStyle without any text properties");g["style:te 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 @@ -677,33 +717,33 @@ f["style:text-properties"],"applyStyle without any text properties");g["style:te This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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,d;if(!a)return c;for(a=a.firstChild;a;){if(d=a.namespaceURI!==u||"style"!==a.localName&&"default-style"!==a.localName?a.namespaceURI===r&&"list-style"===a.localName?"list":a.namespaceURI!==u||"page-layout"!==a.localName&&"default-page-layout"!==a.localName?void 0:"page":a.getAttributeNS(u,"family"))(b=a.getAttributeNS&&a.getAttributeNS(u,"name"))||(b=""),d=c[d]=c[d]||{},d[b]=a;a=a.nextSibling}return c}function m(a,c){if(!c||!a)return null;if(a[c])return a[c]; -var b,d;for(b in a)if(a.hasOwnProperty(b)&&(d=m(a[b].derivedStyles,c)))return d;return null}function f(a,c,b){var d=c[a],e,g;d&&(e=d.getAttributeNS(u,"parent-style-name"),g=null,e&&(g=m(b,e),!g&&c[e]&&(f(e,c,b),g=c[e],c[e]=null)),g?(g.derivedStyles||(g.derivedStyles={}),g.derivedStyles[a]=d):b[a]=d)}function a(a,c){for(var b in a)a.hasOwnProperty(b)&&(f(b,a,c),a[b]=null)}function c(a,c){var b=w[a],d;if(null===b)return null;d=c?"["+b+'|style-name="'+c+'"]':"";"presentation"===b&&(b="draw",d=c?'[presentation|style-name="'+ -c+'"]':"");return b+"|"+v[a].join(d+","+b+"|")+d}function d(a,b,e){var g=[],k,l;g.push(c(a,b));for(k in e.derivedStyles)if(e.derivedStyles.hasOwnProperty(k))for(l in b=d(a,k,e.derivedStyles[k]),b)b.hasOwnProperty(l)&&g.push(b[l]);return g}function b(a,b,c){if(!a)return null;for(a=a.firstChild;a;){if(a.namespaceURI===b&&a.localName===c)return b=a;a=a.nextSibling}return null}function k(a,b){var c="",d,e;for(d in b)if(b.hasOwnProperty(d)&&(d=b[d],e=a.getAttributeNS(d[0],d[1]))){e=e.trim();if(M.hasOwnProperty(d[1])){var g= -e.indexOf(" "),k=void 0,l=void 0;-1!==g?(k=e.substring(0,g),l=e.substring(g)):(k=e,l="");(k=W.parseLength(k))&&("pt"===k.unit&&0.75>k.value)&&(e="0.75pt"+l)}d[2]&&(c+=d[2]+":"+e+";")}return c}function p(a){return(a=b(a,u,"text-properties"))?W.parseFoFontSize(a.getAttributeNS(l,"font-size")):null}function e(a){a=a.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,function(a,b,c,d){return b+b+c+c+d+d});return(a=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(a))?{r:parseInt(a[1],16),g:parseInt(a[2],16),b:parseInt(a[3], -16)}:null}function s(a,b,c,d){b='text|list[text|style-name="'+b+'"]';var e=c.getAttributeNS(r,"level"),g;c=W.getFirstNonWhitespaceChild(c);c=W.getFirstNonWhitespaceChild(c);var k;c&&(g=c.attributes,k=g["fo:text-indent"]?g["fo:text-indent"].value:void 0,g=g["fo:margin-left"]?g["fo:margin-left"].value:void 0);k||(k="-0.6cm");c="-"===k.charAt(0)?k.substring(1):"-"+k;for(e=e&&parseInt(e,10);1 text|list-item > text|list",e-=1;e=b+" > text|list-item > *:not(text|list):first-child";void 0!==g&& -(g=e+"{margin-left:"+g+";}",a.insertRule(g,a.cssRules.length));d=b+" > text|list-item > *:not(text|list):first-child:before{"+d+";";d+="counter-increment:list;";d+="margin-left:"+k+";";d+="width:"+c+";";d+="display:inline-block}";try{a.insertRule(d,a.cssRules.length)}catch(l){throw l;}}function n(a,c,f,h){if("list"===c)for(var m=h.firstChild,q,v;m;){if(m.namespaceURI===r)if(q=m,"list-level-style-number"===m.localName){var w=q;v=w.getAttributeNS(u,"num-format");var M=w.getAttributeNS(u,"num-suffix"), -z={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},w=w.getAttributeNS(u,"num-prefix")||"",w=z.hasOwnProperty(v)?w+(" counter(list, "+z[v]+")"):v?w+("'"+v+"';"):w+" ''";M&&(w+=" '"+M+"'");v="content: "+w+";";s(a,f,q,v)}else"list-level-style-image"===m.localName?(v="content: none;",s(a,f,q,v)):"list-level-style-bullet"===m.localName&&(v="content: '"+q.getAttributeNS(r,"bullet-char")+"';",s(a,f,q,v));m=m.nextSibling}else if("page"===c)if(M=q=f="",m=h.getElementsByTagNameNS(u, -"page-layout-properties")[0],q=m.parentNode.parentNode.parentNode.masterStyles,M="",f+=k(m,fa),v=m.getElementsByTagNameNS(u,"background-image"),0g.value&&(e="0.75pt"+k)}c[2]&&(d+=c[2]+":"+e+";")}return d}function a(a){return(a=c(a,r,"text-properties"))?$.parseFoFontSize(a.getAttributeNS(l,"font-size")):null}function d(a){a=a.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,function(a,b,d,c){return b+b+d+d+c+c});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,d,c){b='text|list[text|style-name="'+b+'"]';var e=d.getAttributeNS(v,"level"),f;d=$.getFirstNonWhitespaceChild(d);d=$.getFirstNonWhitespaceChild(d);var g;d&&(f=d.attributes,g=f["fo:text-indent"]?f["fo:text-indent"].value:void 0,f=f["fo:margin-left"]?f["fo:margin-left"].value:void 0);g||(g="-0.6cm");d="-"===g.charAt(0)?g.substring(1):"-"+g;for(e=e&&parseInt(e,10);1 text|list-item > text|list",e-=1;e=b+" > text|list-item > *:not(text|list):first-child";void 0!==f&& +(f=e+"{margin-left:"+f+";}",a.insertRule(f,a.cssRules.length));c=b+" > text|list-item > *:not(text|list):first-child:before{"+c+";";c+="counter-increment:list;";c+="margin-left:"+g+";";c+="width:"+d+";";c+="display:inline-block}";try{a.insertRule(c,a.cssRules.length)}catch(k){throw k;}}function g(e,f,h,m){if("list"===f)for(var s=m.firstChild,n,t;s;){if(s.namespaceURI===v)if(n=s,"list-level-style-number"===s.localName){var u=n;t=u.getAttributeNS(r,"num-format");var Q=u.getAttributeNS(r,"num-suffix"), +J={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},u=u.getAttributeNS(r,"num-prefix")||"",u=J.hasOwnProperty(t)?u+(" counter(list, "+J[t]+")"):t?u+("'"+t+"';"):u+" ''";Q&&(u+=" '"+Q+"'");t="content: "+u+";";k(e,h,n,t)}else"list-level-style-image"===s.localName?(t="content: none;",k(e,h,n,t)):"list-level-style-bullet"===s.localName&&(t="content: '"+n.getAttributeNS(v,"bullet-char")+"';",k(e,h,n,t));s=s.nextSibling}else if("page"===f)if(Q=n=h="",s=m.getElementsByTagNameNS(r, +"page-layout-properties")[0],n=s.parentNode.parentNode.parentNode.masterStyles,Q="",h+=b(s,Z),t=s.getElementsByTagNameNS(r,"background-image"),0 @@ -716,6 +756,9 @@ if(q=b(h,u,"drawing-page-properties"))v=""+k(q,K),"true"===q.getAttributeNS(t,"b 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 @@ -736,31 +779,33 @@ if(q=b(h,u,"drawing-page-properties"))v=""+k(q,K),"true"===q.getAttributeNS(t,"b This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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,b=p.length;for(c=0;cb)break;e=e.nextSibling}a.insertBefore(c,e)}}}function d(a){this.OdfContainer= -a}function b(a,c,b,d){var e=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);e.url=c;if(e.onchange)e.onchange(e);if(e.onstatereadychange)e.onstatereadychange(e)}))}}var k=new odf.StyleInfo,p="meta settings scripts font-face-decls styles automatic-styles master-styles body".split(" "), -e=(new Date).getTime()+"_webodf_",s=new core.Base64;d.prototype=new function(){};d.prototype.constructor=d;d.namespaceURI="urn:oasis:names:tc:opendocument:xmlns:office:1.0";d.localName="document";b.prototype.load=function(){};b.prototype.getUrl=function(){return this.data?"data:;base64,"+s.toBase64(this.data):null};odf.OdfContainer=function g(l,m){function q(a){for(var c=a.firstChild,b;c;)b=c.nextSibling,c.nodeType===Node.ELEMENT_NODE?q(c):c.nodeType===Node.PROCESSING_INSTRUCTION_NODE&&a.removeChild(c), -c=b}function p(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 r(a,c){var b=null,d,e,g;if(a)for(b=a.cloneNode(!0),d=b.firstChild;d;)e=d.nextSibling,d.nodeType===Node.ELEMENT_NODE&&(g=d.getAttributeNS("urn:webodf:names:scope","scope"))&&g!==c&&b.removeChild(d),d=e;return b}function y(a){var c=F.rootElement.ownerDocument,b;if(a){q(a.documentElement);try{b=c.importNode(a.documentElement,!0)}catch(d){}}return b} -function t(a){F.state=a;if(F.onchange)F.onchange(F);if(F.onstatereadychange)F.onstatereadychange(F)}function s(a){T=null;F.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 v(a){a=y(a);var b=F.rootElement;a&&"document-styles"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI?(b.fontFaceDecls=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls"),c(b,b.fontFaceDecls),b.styles=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles"),c(b,b.styles),b.automaticStyles=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles"), -p(b.automaticStyles,"document-styles"),c(b,b.automaticStyles),b.masterStyles=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles"),c(b,b.masterStyles),k.prefixStyleNames(b.automaticStyles,e,b.masterStyles)):t(g.INVALID)}function C(a){a=y(a);var b,d,e;if(a&&"document-content"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI){b=F.rootElement;d=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls");if(b.fontFaceDecls&&d)for(e=d.firstChild;e;)b.fontFaceDecls.appendChild(e), -e=d.firstChild;else d&&(b.fontFaceDecls=d,c(b,d));d=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles");p(d,"document-content");if(b.automaticStyles&&d)for(e=d.firstChild;e;)b.automaticStyles.appendChild(e),e=d.firstChild;else d&&(b.automaticStyles=d,c(b,d));b.body=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");c(b,b.body)}else t(g.INVALID)}function J(a){a=y(a);var b;a&&("document-meta"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI)&& -(b=F.rootElement,b.meta=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","meta"),c(b,b.meta))}function E(a){a=y(a);var b;a&&("document-settings"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI)&&(b=F.rootElement,b.settings=h(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","settings"),c(b,b.settings))}function K(a){a=y(a);var b;if(a&&"manifest"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"===a.namespaceURI)for(b=F.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)&&(D[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 B(a){var b=a.shift(),c,d;b?(c=b[0],d=b[1],G.loadAsDOM(c,function(b,c){d(c);b||F.state===g.INVALID||B(a)})):t(g.DONE)}function N(a){var b="";odf.Namespaces.forEachPrefix(function(a, -c){b+=" xmlns:"+a+'="'+c+'"'});return''}function H(){var a=new xmldom.LSSerializer,b=N("document-meta");a.filter=new odf.OdfNodeFilter;b+=a.writeToString(F.rootElement.meta,odf.Namespaces.namespaceMap);return b+""}function L(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 fa(){var a=runtime.parseXML(''),b=h(a,"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest"),c=new xmldom.LSSerializer,d;for(d in D)D.hasOwnProperty(d)&&b.appendChild(L(d,D[d]));c.filter=new odf.OdfNodeFilter;return'\n'+ -c.writeToString(a,odf.Namespaces.namespaceMap)}function ma(){var a=new xmldom.LSSerializer,b=N("document-settings");a.filter=new odf.OdfNodeFilter;b+=a.writeToString(F.rootElement.settings,odf.Namespaces.namespaceMap);return b+""}function M(){var a=odf.Namespaces.namespaceMap,b=new xmldom.LSSerializer,c=r(F.rootElement.automaticStyles,"document-styles"),d=F.rootElement.masterStyles&&F.rootElement.masterStyles.cloneNode(!0),g=N("document-styles");k.removePrefixFromStyleNames(c, -e,d);b.filter=new f(d,c);g+=b.writeToString(F.rootElement.fontFaceDecls,a);g+=b.writeToString(F.rootElement.styles,a);g+=b.writeToString(c,a);g+=b.writeToString(d,a);return g+""}function pa(){var b=odf.Namespaces.namespaceMap,c=new xmldom.LSSerializer,d=r(F.rootElement.automaticStyles,"document-content"),e=N("document-content");c.filter=new a(F.rootElement.body,d);e+=c.writeToString(d,b);e+=c.writeToString(F.rootElement.body,b);return e+""}function W(a, -b){runtime.loadXML(a,function(a,c){if(a)b(a);else{var d=y(c);d&&"document"===d.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===d.namespaceURI?(s(d),t(g.DONE)):t(g.INVALID)}})}function aa(){function a(b,c){var e;c||(c=b);e=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0",c);d[b]=e;d.appendChild(e)}var b=new core.Zip("",null),c=runtime.byteArrayFromString("application/vnd.oasis.opendocument.text","utf8"),d=F.rootElement,e=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");d.body.appendChild(e);t(g.DONE);return b}function O(){var a,b=new Date;a=runtime.byteArrayFromString(ma(),"utf8");G.save("settings.xml",a,!0,b);a=runtime.byteArrayFromString(H(),"utf8");G.save("meta.xml",a,!0,b);a=runtime.byteArrayFromString(M(),"utf8");G.save("styles.xml",a,!0,b);a=runtime.byteArrayFromString(pa(), -"utf8");G.save("content.xml",a,!0,b);a=runtime.byteArrayFromString(fa(),"utf8");G.save("META-INF/manifest.xml",a,!0,b)}function R(a,b){O();G.writeAs(a,function(a){b(a)})}var F=this,G,D={},T;this.onstatereadychange=m;this.rootElement=this.state=this.onchange=null;this.setRootElement=s;this.getContentElement=function(){var a;T||(a=F.rootElement.body,T=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 T};this.getDocumentType=function(){var a=F.getContentElement();return a&&a.localName};this.getPart=function(a){return new b(a,D[a],F,G)};this.getPartData=function(a,b){G.load(a,b)};this.createByteArray=function(a,b){O();G.createByteArray(a,b)};this.saveAs=R;this.save=function(a){R(l,a)};this.getUrl=function(){return l};this.state=g.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}(d);G=l?new core.Zip(l,function(a,b){G=b;a?W(l,function(b){a&&(G.error=a+"\n"+b,t(g.INVALID))}):B([["styles.xml",v],["content.xml",C],["meta.xml",J],["settings.xml",E],["META-INF/manifest.xml",K]])}):aa()};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 34 +odf.OdfContainer=function(){function e(a,b,d){for(a=a?a.firstChild:null;a;){if(a.localName===d&&a.namespaceURI===b)return a;a=a.nextSibling}return null}function h(a){var b,c=d.length;for(b=0;bd)break;e=e.nextSibling}a.insertBefore(b,e)}}}function p(a){this.OdfContainer= +a}function c(a,b,d,c){var e=this;this.size=0;this.type=null;this.name=a;this.container=d;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!==c&&(this.mimetype=b,c.loadAsDataURL(a,b,function(a,b){a&&runtime.log(a);e.url=b;if(e.onchange)e.onchange(e);if(e.onstatereadychange)e.onstatereadychange(e)}))}}var b=new odf.StyleInfo,a=odf.Namespaces.stylens,d="meta settings scripts font-face-decls styles automatic-styles master-styles body".split(" "), +k=(new Date).getTime()+"_webodf_",g=new core.Base64;p.prototype=new function(){};p.prototype.constructor=p;p.namespaceURI="urn:oasis:names:tc:opendocument:xmlns:office:1.0";p.localName="document";c.prototype.load=function(){};c.prototype.getUrl=function(){return this.data?"data:;base64,"+g.toBase64(this.data):null};odf.OdfContainer=function l(d,h){function w(a){for(var b=a.firstChild,d;b;)d=b.nextSibling,b.nodeType===Node.ELEMENT_NODE?w(b):b.nodeType===Node.PROCESSING_INSTRUCTION_NODE&&a.removeChild(b), +b=d}function v(a,b){for(var d=a&&a.firstChild;d;)d.nodeType===Node.ELEMENT_NODE&&d.setAttributeNS("urn:webodf:names:scope","scope",b),d=d.nextSibling}function y(b,d){function c(a,b,d){var e=0,f;for(f=a=a.replace(/\d+$/,"");b.hasOwnProperty(f)||d.hasOwnProperty(f);)e+=1,f=a+e;return f}function e(b){var d={};for(b=b.firstChild;b;)b.nodeType===Node.ELEMENT_NODE&&b.namespaceURI===a&&"font-face"===b.localName&&(k=b.getAttributeNS(a,"name"),d[k]=b),b=b.nextSibling;return d}var f,g,k,h,l,m,n={};l=e(b);m= +e(d);for(f=d.firstChild;f;)g=f.nextSibling,f.nodeType===Node.ELEMENT_NODE&&f.namespaceURI===a&&"font-face"===f.localName&&(k=f.getAttributeNS(a,"name"),l.hasOwnProperty(k)?f.isEqualNode(l[k])||(h=c(k,l,m),f.setAttributeNS(a,"style:name",h),b.appendChild(f),l[h]=f,delete m[k],n[k]=h):(b.appendChild(f),l[k]=f,delete m[k])),f=g;return n}function x(a,b){var d=null,c,e,f;if(a)for(d=a.cloneNode(!0),c=d.firstChild;c;)e=c.nextSibling,c.nodeType===Node.ELEMENT_NODE&&(f=c.getAttributeNS("urn:webodf:names:scope", +"scope"))&&f!==b&&d.removeChild(c),c=e;return d}function u(d,c){var e=null,f,g,k,h={};if(d)for(c.forEach(function(a){b.collectUsedFontFaces(h,a)}),e=d.cloneNode(!0),f=e.firstChild;f;)g=f.nextSibling,f.nodeType===Node.ELEMENT_NODE&&(k=f.getAttributeNS(a,"name"),h[k]||e.removeChild(f)),f=g;return e}function s(a){var b=M.rootElement.ownerDocument,d;if(a){w(a.documentElement);try{d=b.importNode(a.documentElement,!0)}catch(c){}}return d}function C(a){M.state=a;if(M.onchange)M.onchange(M);if(M.onstatereadychange)M.onstatereadychange(M)} +function B(a){aa=null;M.rootElement=a;a.fontFaceDecls=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls");a.styles=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles");a.automaticStyles=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles");a.masterStyles=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles");a.body=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");a.meta=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", +"meta")}function A(a){a=s(a);var d=M.rootElement;a&&"document-styles"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI?(d.fontFaceDecls=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls"),m(d,d.fontFaceDecls),d.styles=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles"),m(d,d.styles),d.automaticStyles=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles"),v(d.automaticStyles,"document-styles"),m(d,d.automaticStyles), +d.masterStyles=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles"),m(d,d.masterStyles),b.prefixStyleNames(d.automaticStyles,k,d.masterStyles)):C(l.INVALID)}function I(a){a=s(a);var d,c,f;if(a&&"document-content"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI){d=M.rootElement;c=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls");d.fontFaceDecls&&c?f=y(d.fontFaceDecls,c):c&&(d.fontFaceDecls=c,m(d,c));c=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", +"automatic-styles");v(c,"document-content");f&&b.changeFontFaceNames(c,f);if(d.automaticStyles&&c)for(f=c.firstChild;f;)d.automaticStyles.appendChild(f),f=c.firstChild;else c&&(d.automaticStyles=c,m(d,c));d.body=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");m(d,d.body)}else C(l.INVALID)}function z(a){a=s(a);var b;a&&"document-meta"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&(b=M.rootElement,b.meta=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", +"meta"),m(b,b.meta))}function N(a){a=s(a);var b;a&&"document-settings"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&(b=M.rootElement,b.settings=e(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","settings"),m(b,b.settings))}function G(a){a=s(a);var b;if(a&&"manifest"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"===a.namespaceURI)for(b=M.rootElement,b.manifest=a,a=b.manifest.firstChild;a;)a.nodeType===Node.ELEMENT_NODE&&"file-entry"=== +a.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"===a.namespaceURI&&(P[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 b=a.shift(),d,c;b?(d=b[0],c=b[1],S.loadAsDOM(d,function(b,d){c(d);b||M.state===l.INVALID||R(a)})):C(l.DONE)}function Z(a){var b="";odf.Namespaces.forEachPrefix(function(a,d){b+=" xmlns:"+a+'="'+d+'"'});return''}function ka(){var a=new xmldom.LSSerializer,b=Z("document-meta");a.filter=new odf.OdfNodeFilter;b+=a.writeToString(M.rootElement.meta,odf.Namespaces.namespaceMap);return b+""}function T(a,b){var d=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest:file-entry");d.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest:full-path",a);d.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0", +"manifest:media-type",b);return d}function ra(){var a=runtime.parseXML(''),b=e(a,"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest"),d=new xmldom.LSSerializer,c;for(c in P)P.hasOwnProperty(c)&&b.appendChild(T(c,P[c]));d.filter=new odf.OdfNodeFilter;return'\n'+d.writeToString(a,odf.Namespaces.namespaceMap)} +function $(){var a=new xmldom.LSSerializer,b=Z("document-settings");a.filter=new odf.OdfNodeFilter;b+=a.writeToString(M.rootElement.settings,odf.Namespaces.namespaceMap);return b+""}function ha(){var a=odf.Namespaces.namespaceMap,d=new xmldom.LSSerializer,c,e,g,h=Z("document-styles");e=x(M.rootElement.automaticStyles,"document-styles");g=M.rootElement.masterStyles&&M.rootElement.masterStyles.cloneNode(!0);c=u(M.rootElement.fontFaceDecls,[g,M.rootElement.styles,e]);b.removePrefixFromStyleNames(e, +k,g);d.filter=new f(g,e);h+=d.writeToString(c,a);h+=d.writeToString(M.rootElement.styles,a);h+=d.writeToString(e,a);h+=d.writeToString(g,a);return h+""}function U(){var a=odf.Namespaces.namespaceMap,b=new xmldom.LSSerializer,d,c,e=Z("document-content");c=x(M.rootElement.automaticStyles,"document-content");d=u(M.rootElement.fontFaceDecls,[c]);b.filter=new n(M.rootElement.body,c);e+=b.writeToString(d,a);e+=b.writeToString(c,a);e+=b.writeToString(M.rootElement.body,a);return e+ +""}function O(a,b){runtime.loadXML(a,function(a,d){if(a)b(a);else{var c=s(d);c&&"document"===c.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===c.namespaceURI?(B(c),C(l.DONE)):C(l.INVALID)}})}function W(){function a(b,d){var e;d||(d=b);e=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0",d);c[b]=e;c.appendChild(e)}var b=new core.Zip("",null),d=runtime.byteArrayFromString("application/vnd.oasis.opendocument.text","utf8"),c=M.rootElement, +e=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","text");b.save("mimetype",d,!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");c.body.appendChild(e);C(l.DONE);return b}function E(){var a,b=new Date;a=runtime.byteArrayFromString($(),"utf8");S.save("settings.xml",a,!0,b);a=runtime.byteArrayFromString(ka(),"utf8");S.save("meta.xml",a,!0,b); +a=runtime.byteArrayFromString(ha(),"utf8");S.save("styles.xml",a,!0,b);a=runtime.byteArrayFromString(U(),"utf8");S.save("content.xml",a,!0,b);a=runtime.byteArrayFromString(ra(),"utf8");S.save("META-INF/manifest.xml",a,!0,b)}function H(a,b){E();S.writeAs(a,function(a){b(a)})}var M=this,S,P={},aa;this.onstatereadychange=h;this.rootElement=this.state=this.onchange=null;this.setRootElement=B;this.getContentElement=function(){var a;aa||(a=M.rootElement.body,aa=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 aa};this.getDocumentType=function(){var a=M.getContentElement();return a&&a.localName};this.getPart=function(a){return new c(a,P[a],M,S)};this.getPartData=function(a,b){S.load(a,b)};this.createByteArray=function(a,b){E();S.createByteArray(a,b)};this.saveAs=H;this.save=function(a){H(d,a)};this.getUrl= +function(){return d};this.setBlob=function(a,b,d){d=g.convertBase64ToByteArray(d);S.save(a,d,!1,new Date);P.hasOwnProperty(a)&&runtime.log(a+" has been overwritten.");P[a]=b};this.removeBlob=function(a){var b=S.remove(a);runtime.assert(b,"file is not found: "+a);delete P[a]};this.state=l.LOADING;this.rootElement=function(a){var b=document.createElementNS(a.namespaceURI,a.localName),d;a=new a;for(d in a)a.hasOwnProperty(d)&&(b[d]=a[d]);return b}(p);S=d?new core.Zip(d,function(a,b){S=b;a?O(d,function(b){a&& +(S.error=a+"\n"+b,C(l.INVALID))}):R([["styles.xml",A],["content.xml",I],["meta.xml",z],["settings.xml",N],["META-INF/manifest.xml",G]])}):W()};odf.OdfContainer.EMPTY=0;odf.OdfContainer.LOADING=1;odf.OdfContainer.DONE=2;odf.OdfContainer.INVALID=3;odf.OdfContainer.SAVING=4;odf.OdfContainer.MODIFIED=5;odf.OdfContainer.getContainer=function(a){return new odf.OdfContainer(a,null)};return odf.OdfContainer}(); +// Input 35 /* Copyright (C) 2012-2013 KO GmbH @@ -773,6 +818,9 @@ null)};return odf.OdfContainer}(); 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 @@ -793,13 +841,13 @@ null)};return odf.OdfContainer}(); This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.Base64");runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.OdfContainer"); -odf.FontLoader=function(){function h(a,c,d,b,k){var m,e=0,s;for(s in a)if(a.hasOwnProperty(s)){if(e===d){m=s;break}e+=1}m?c.getPartData(a[m].href,function(e,g){if(e)runtime.log(e);else{var l="@font-face { font-family: '"+(a[m].family||m)+"'; src: url(data:application/x-font-ttf;charset=binary;base64,"+f.convertUTF8ArrayToBase64(g)+') format("truetype"); }';try{b.insertRule(l,b.cssRules.length)}catch(s){runtime.log("Problem inserting rule in CSS: "+runtime.toJson(s)+"\nRule: "+l)}}h(a,c,d+1,b,k)}): -k&&k()}var m=new xmldom.XPath,f=new core.Base64;odf.FontLoader=function(){this.loadFonts=function(a,c){for(var d=a.rootElement.fontFaceDecls;c.cssRules.length;)c.deleteRule(c.cssRules.length-1);if(d){var b={},k,f,e,s;if(d)for(d=m.getODFElementsWithXPath(d,"style:font-face[svg:font-face-src]",odf.Namespaces.resolvePrefix),k=0;k @@ -812,6 +860,9 @@ odf.Namespaces.resolvePrefix),0. + 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 @@ -832,10 +883,13 @@ odf.Namespaces.resolvePrefix),0 @@ -848,6 +902,9 @@ odf.StyleNameGenerator=function(h,m){var f={};this.generateName=function(){var a 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 @@ -868,21 +925,24 @@ odf.StyleNameGenerator=function(h,m){var f={};this.generateName=function(){var a This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.Utils");runtime.loadClass("odf.StyleNameGenerator");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=e.rootElement.fontFaceDecls,b={},c,d,a=a&&a.firstChild;a;)a.nodeType===Node.ELEMENT_NODE&&(c=a.getAttributeNS(g,"name"))&&((d=a.getAttributeNS(n,"font-family"))||a.getElementsByTagNameNS(n,"font-face-uri")[0])&&(b[c]=d),a=a.nextSibling;return b}function m(a){for(var b=e.rootElement.styles.firstChild;b;){if(b.nodeType===Node.ELEMENT_NODE&&b.namespaceURI===g&&"default-style"===b.localName&&b.getAttributeNS(g,"family")===a)return b;b=b.nextSibling}return null} -function f(a,b,c){var d,k;c=c||[e.rootElement.automaticStyles,e.rootElement.styles];for(d=c.shift();d;){for(d=d.firstChild;d;){if(d.nodeType===Node.ELEMENT_NODE&&(k=d.getAttributeNS(g,"name"),d.namespaceURI===g&&"style"===d.localName&&d.getAttributeNS(g,"family")===b&&k===a||"list-style"===b&&d.namespaceURI===l&&"list-style"===d.localName&&k===a||"data"===b&&d.namespaceURI===u&&k===a))return d;d=d.nextSibling}d=c.shift()}return null}function a(a){for(var b,c={},d=a.firstChild;d;){if(d.nodeType=== -Node.ELEMENT_NODE&&d.namespaceURI===g)for(c[d.nodeName]={},b=0;b @@ -895,6 +955,9 @@ b+"' of family '"+c+"'");b=k.parentNode===e.rootElement.automaticStyles?a(k):{"s 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 @@ -915,41 +978,43 @@ b+"' of family '"+c+"'");b=k.parentNode===e.rootElement.automaticStyles?a(k):{"s This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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){c=!0;runtime.setTimeout(function(){try{d()}catch(e){runtime.log(e)}c=!1;0 text|list-item > *:first-child:before {";if(H=S.getAttributeNS(v,"style-name")){S= -r[H];A=N.getFirstNonWhitespaceChild(S);S=void 0;if(A)if("list-level-style-number"===A.localName){S=A.getAttributeNS(y,"num-format");H=A.getAttributeNS(y,"num-suffix");var F="",F={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},I=void 0,I=A.getAttributeNS(y,"num-prefix")||"",I=F.hasOwnProperty(S)?I+(" counter(list, "+F[S]+")"):S?I+("'"+S+"';"):I+" ''";H&&(I+=" '"+H+"'");S=F="content: "+I+";"}else"list-level-style-image"===A.localName?S="content: none;":"list-level-style-bullet"=== -A.localName&&(S="content: '"+A.getAttributeNS(v,"bullet-char")+"';");A=S}if(C){for(S=m[C];S;)C=S,S=m[C];Z+="counter-increment:"+C+";";A?(A=A.replace("list",C),Z+=A):Z+="content:counter("+C+");"}else C="",A?(A=A.replace("list",u),Z+=A):Z+="content: counter("+u+");",Z+="counter-increment:"+u+";",l.insertRule("text|list#"+u+" {counter-reset:"+u+"}",l.cssRules.length);Z+="}";m[u]=C;Z&&l.insertRule(Z,l.cssRules.length)}P.insertBefore(L,P.firstChild);t();E(f);if(!c&&(f=[D],ia.hasOwnProperty("statereadychange")))for(l= -ia.statereadychange,A=0;A text|list-item > *:first-child:before {";if(H=K.getAttributeNS(I, +"style-name"))K=v[H],O=ka.getFirstNonWhitespaceChild(K),K=void 0,O&&("list-level-style-number"===O.localName?(K=O.getAttributeNS(C,"num-format"),H=O.getAttributeNS(C,"num-suffix"),J="",J={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},M=void 0,M=O.getAttributeNS(C,"num-prefix")||"",M=J.hasOwnProperty(K)?M+(" counter(list, "+J[K]+")"):K?M+("'"+K+"';"):M+" ''",H&&(M+=" '"+H+"'"),K=J="content: "+M+";"):"list-level-style-image"===O.localName?K="content: none;":"list-level-style-bullet"=== +O.localName&&(K="content: '"+O.getAttributeNS(I,"bullet-char")+"';")),O=K;if(T){for(K=w[T];K;)T=K,K=w[T];E+="counter-increment:"+T+";";O?(O=O.replace("list",T),E+=O):E+="content:counter("+T+");"}else T="",O?(O=O.replace("list",z),E+=O):E+="content: counter("+z+");",E+="counter-increment:"+z+";",h.insertRule("text|list#"+z+" {counter-reset:"+z+"}",h.cssRules.length);E+="}";w[z]=T;E&&h.insertRule(E,h.cssRules.length)}V.insertBefore(ia,V.firstChild);B();W(g);if(!e&&(g=[P],ba.hasOwnProperty("statereadychange")))for(h= +ba.statereadychange,O=0;O @@ -962,6 +1027,9 @@ odf.CommandLineTools=function(){this.roundTrip=function(h,m,f){return new odf.Od 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 @@ -982,10 +1050,10 @@ odf.CommandLineTools=function(){this.roundTrip=function(h,m,f){return new odf.Od This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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,f,a){};ops.Server.prototype.joinSession=function(h,m,f,a){};ops.Server.prototype.leaveSession=function(h,m,f,a){};ops.Server.prototype.getGenesisUrl=function(h){}; -// Input 40 +ops.Server=function(){};ops.Server.prototype.connect=function(e,h){};ops.Server.prototype.networkStatus=function(){};ops.Server.prototype.login=function(e,h,f,n){};ops.Server.prototype.joinSession=function(e,h,f,n){};ops.Server.prototype.leaveSession=function(e,h,f,n){};ops.Server.prototype.getGenesisUrl=function(e){}; +// Input 41 /* Copyright (C) 2012-2013 KO GmbH @@ -998,6 +1066,9 @@ ops.Server=function(){};ops.Server.prototype.connect=function(h,m){};ops.Server. 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 @@ -1018,10 +1089,10 @@ ops.Server=function(){};ops.Server.prototype.connect=function(h,m){};ops.Server. This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.Operation=function(){};ops.Operation.prototype.init=function(h){};ops.Operation.prototype.transform=function(h,m){};ops.Operation.prototype.execute=function(h){};ops.Operation.prototype.spec=function(){}; -// Input 41 +ops.Operation=function(){};ops.Operation.prototype.init=function(e){};ops.Operation.prototype.execute=function(e){};ops.Operation.prototype.spec=function(){}; +// Input 42 /* Copyright (C) 2012-2013 KO GmbH @@ -1034,6 +1105,9 @@ ops.Operation=function(){};ops.Operation.prototype.init=function(h){};ops.Operat 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 @@ -1054,10 +1128,10 @@ ops.Operation=function(){};ops.Operation.prototype.init=function(h){};ops.Operat This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.OpAddCursor=function(){var h=this,m,f;this.init=function(a){m=a.memberid;f=a.timestamp};this.transform=function(a,c){return[h]};this.execute=function(a){var c=a.getCursor(m);if(c)return!1;c=new ops.OdtCursor(m,a);a.addCursor(c);a.emit(ops.OdtDocument.signalCursorAdded,c);return!0};this.spec=function(){return{optype:"AddCursor",memberid:m,timestamp:f}}}; -// Input 42 +ops.OpAddCursor=function(){var e,h;this.init=function(f){e=f.memberid;h=f.timestamp};this.execute=function(f){var h=f.getCursor(e);if(h)return!1;h=new ops.OdtCursor(e,f);f.addCursor(h);f.emit(ops.OdtDocument.signalCursorAdded,h);return!0};this.spec=function(){return{optype:"AddCursor",memberid:e,timestamp:h}}}; +// Input 43 /* Copyright (C) 2012-2013 KO GmbH @@ -1070,6 +1144,9 @@ ops.OpAddCursor=function(){var h=this,m,f;this.init=function(a){m=a.memberid;f=a 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 @@ -1090,14 +1167,14 @@ ops.OpAddCursor=function(){var h=this,m,f;this.init=function(a){m=a.memberid;f=a This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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){var b;a.collapsed?(b=a.startContainer,b.hasChildNodes()&&a.startOffset @@ -1110,6 +1187,9 @@ this.isBold=function(a){return f(a,"fo:font-weight","bold")};this.isItalic=funct 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 @@ -1130,12 +1210,12 @@ this.isBold=function(a){return f(a,"fo:font-weight","bold")};this.isItalic=funct This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("gui.StyleHelper");runtime.loadClass("odf.OdfUtils"); -ops.OpApplyDirectStyling=function(){function h(b){var d=0<=c?a+c:a,e=b.getIteratorAtPosition(0<=c?a:a+c),d=c?b.getIteratorAtPosition(d):e;b=b.getDOM().createRange();b.setStart(e.container(),e.unfilteredDomOffset());b.setEnd(d.container(),d.unfilteredDomOffset());return b}var m,f,a,c,d,b=new odf.OdfUtils;this.init=function(b){m=b.memberid;f=b.timestamp;a=parseInt(b.position,10);c=parseInt(b.length,10);d=b.setProperties};this.transform=function(a,b){return null};this.execute=function(a){var c=h(a), -e=b.getImpactedParagraphs(c);(new gui.StyleHelper(a.getFormatting())).applyStyle(m,c,d);c.detach();a.getOdfCanvas().refreshCSS();e.forEach(function(b){a.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:b,memberId:m,timeStamp:f})});a.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"ApplyDirectStyling",memberid:m,timestamp:f,position:a,length:c,setProperties:d}}}; -// Input 44 +ops.OpApplyDirectStyling=function(){function e(b){var a=0<=m?n+m:n,d=b.getIteratorAtPosition(0<=m?n:n+m),a=m?b.getIteratorAtPosition(a):d;b=b.getDOM().createRange();b.setStart(d.container(),d.unfilteredDomOffset());b.setEnd(a.container(),a.unfilteredDomOffset());return b}var h,f,n,m,p,c=new odf.OdfUtils;this.init=function(b){h=b.memberid;f=b.timestamp;n=parseInt(b.position,10);m=parseInt(b.length,10);p=b.setProperties};this.execute=function(b){var a=e(b),d=c.getImpactedParagraphs(a);(new gui.StyleHelper(b.getFormatting())).applyStyle(h, +a,p);a.detach();b.getOdfCanvas().refreshCSS();b.fixCursorPositions();d.forEach(function(a){b.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a,memberId:h,timeStamp:f})});b.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"ApplyDirectStyling",memberid:h,timestamp:f,position:n,length:m,setProperties:p}}}; +// Input 45 /* Copyright (C) 2012-2013 KO GmbH @@ -1148,6 +1228,9 @@ e=b.getImpactedParagraphs(c);(new gui.StyleHelper(a.getFormatting())).applyStyle 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 @@ -1168,10 +1251,10 @@ e=b.getImpactedParagraphs(c);(new gui.StyleHelper(a.getFormatting())).applyStyle This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.OpRemoveCursor=function(){var h=this,m,f;this.init=function(a){m=a.memberid;f=a.timestamp};this.transform=function(a,c){var d=a.spec(),b=[h];"RemoveCursor"===d.optype&&d.memberid===m&&(b=[]);return b};this.execute=function(a){return a.removeCursor(m)?!0:!1};this.spec=function(){return{optype:"RemoveCursor",memberid:m,timestamp:f}}}; -// Input 45 +ops.OpRemoveCursor=function(){var e,h;this.init=function(f){e=f.memberid;h=f.timestamp};this.execute=function(f){return f.removeCursor(e)?!0:!1};this.spec=function(){return{optype:"RemoveCursor",memberid:e,timestamp:h}}}; +// Input 46 /* Copyright (C) 2012-2013 KO GmbH @@ -1184,6 +1267,9 @@ ops.OpRemoveCursor=function(){var h=this,m,f;this.init=function(a){m=a.memberid; 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 @@ -1204,15 +1290,14 @@ ops.OpRemoveCursor=function(){var h=this,m,f;this.init=function(a){m=a.memberid; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.OpMoveCursor=function(){var h=this,m,f,a,c;this.init=function(d){m=d.memberid;f=d.timestamp;a=parseInt(d.position,10);c=void 0!==d.length?parseInt(d.length,10):0};this.merge=function(d){return"MoveCursor"===d.optype&&d.memberid===m?(a=d.position,c=d.length,f=d.timestamp,!0):!1};this.transform=function(d,b){var k=d.spec(),f=a+c,e,s=[h];switch(k.optype){case "RemoveText":e=k.position+k.length;e<=a?a-=k.length:k.positione?-k.countBackwardSteps(-e, -f):0;b.move(e);c&&(f=0c?-k.countBackwardSteps(-c,f):0,b.move(f,!0));d.emit(ops.OdtDocument.signalCursorMoved,b);return!0};this.spec=function(){return{optype:"MoveCursor",memberid:m,timestamp:f,position:a,length:c}}}; -// Input 46 +ops.OpMoveCursor=function(){var e,h,f,n,m;this.init=function(p){e=p.memberid;h=p.timestamp;f=p.position;n=p.length||0;m=p.selectionType||ops.OdtCursor.RangeSelection};this.execute=function(h){var c=h.getCursor(e),b=h.getCursorPosition(e),a=h.getPositionFilter(),d=f-b;if(!c)return!1;b=c.getStepCounter();d=b.countSteps(d,a);c.move(d);n&&(a=b.countSteps(n,a),c.move(a,!0));c.setSelectionType(m);h.emit(ops.OdtDocument.signalCursorMoved,c);return!0};this.spec=function(){return{optype:"MoveCursor",memberid:e, +timestamp:h,position:f,length:n,selectionType:m}}}; +// Input 47 /* - Copyright (C) 2013 KO GmbH + Copyright (C) 2012-2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1222,6 +1307,9 @@ f):0;b.move(e);c&&(f=0c?-k.countBackwardSteps(-c,f 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 @@ -1242,14 +1330,10 @@ f):0;b.move(e);c&&(f=0c?-k.countBackwardSteps(-c,f This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.OpInsertTable=function(){function h(a,b){var e;if(1===s.length)e=s[0];else if(3===s.length)switch(a){case 0:e=s[0];break;case c-1:e=s[2];break;default:e=s[1]}else e=s[a];if(1===e.length)return e[0];if(3===e.length)switch(b){case 0:return e[0];case d-1:return e[2];default:return e[1]}return e[b]}var m=this,f,a,c,d,b,k,p,e,s;this.init=function(h){f=h.memberid;a=h.timestamp;b=parseInt(h.position,10);c=parseInt(h.initialRows,10);d=parseInt(h.initialColumns,10);k=h.tableName;p=h.tableStyleName;e=h.tableColumnStyleName; -s=h.tableCellStyleMatrix};this.transform=function(a,c){var d=a.spec(),e=[m];switch(d.optype){case "InsertTable":e=null;break;case "AddAnnotation":d.position @@ -1262,6 +1346,9 @@ r.appendChild(y),x.appendChild(r);q.appendChild(x)}g=m.getParagraphElement(g.tex 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 @@ -1282,13 +1369,10 @@ r.appendChild(y),x.appendChild(r);q.appendChild(x)}g=m.getParagraphElement(g.tex This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.OpInsertText=function(){var h=this,m,f,a,c;this.init=function(d){m=d.memberid;f=d.timestamp;a=parseInt(d.position,10);c=d.text};this.merge=function(d){return"InsertText"===d.optype&&d.memberid===m&&d.position===a+c.length?(c+=d.text,f=d.timestamp,!0):!1};this.transform=function(c,b){var f=c.spec(),m=[h];switch(f.optype){case "InsertText":f.position @@ -1301,6 +1385,9 @@ k.appendData(c.substring(0,u))):g. + 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 @@ -1321,19 +1408,15 @@ k.appendData(c.substring(0,u))):g + Copyright (C) 2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1343,6 +1426,9 @@ m=[l,f]);break;case "InsertTable":m=null;break;case "AddAnnotation":case "Remove 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 @@ -1363,13 +1449,13 @@ m=[l,f]);break;case "InsertTable":m=null;break;case "AddAnnotation":case "Remove This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.OpSplitParagraph=function(){var h=this,m,f,a,c=new odf.OdfUtils;this.init=function(c){m=c.memberid;f=c.timestamp;a=parseInt(c.position,10)};this.transform=function(c,b){var f=c.spec(),m=[h];switch(f.optype){case "SplitParagraph":f.position=b.textNode.length?null:b.textNode.splitText(b.offset));for(e=b.textNode;e!==h;)if(e=e.parentNode,s=e.cloneNode(!1),g){for(n&&s.appendChild(n);g.nextSibling;)s.appendChild(g.nextSibling); -e.parentNode.insertBefore(s,e.nextSibling);g=e;n=s}else e.parentNode.insertBefore(s,e),g=s,n=e;c.isListItem(n)&&(n=n.childNodes[0]);0===b.textNode.length&&b.textNode.parentNode.removeChild(b.textNode);d.fixCursorPositions(m);d.getOdfCanvas().refreshSize();d.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:k,memberId:m,timeStamp:f});d.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:n,memberId:m,timeStamp:f});d.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"SplitParagraph", -memberid:m,timestamp:f,position:a}}}; -// Input 50 +ops.OpInsertTable=function(){function e(a,b){var c;if(1===d.length)c=d[0];else if(3===d.length)switch(a){case 0:c=d[0];break;case n-1:c=d[2];break;default:c=d[1]}else c=d[a];if(1===c.length)return c[0];if(3===c.length)switch(b){case 0:return c[0];case m-1:return c[2];default:return c[1]}return c[b]}var h,f,n,m,p,c,b,a,d;this.init=function(e){h=e.memberid;f=e.timestamp;p=e.position;n=e.initialRows;m=e.initialColumns;c=e.tableName;b=e.tableStyleName;a=e.tableColumnStyleName;d=e.tableCellStyleMatrix}; +this.execute=function(d){var g=d.getPositionInTextNode(p),q=d.getRootNode();if(g){var l=d.getDOM(),r=l.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table"),t=l.createElementNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:table-column"),w,v,y,x;b&&r.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:style-name",b);c&&r.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:name",c);t.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0", +"table:number-columns-repeated",m);a&&t.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:table:1.0","table:style-name",a);r.appendChild(t);for(y=0;y @@ -1382,6 +1468,9 @@ memberid:m,timestamp:f,position:a}}}; 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 @@ -1402,11 +1491,12 @@ memberid:m,timestamp:f,position:a}}}; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.OpSetParagraphStyle=function(){var h=this,m,f,a,c;this.init=function(d){m=d.memberid;f=d.timestamp;a=d.position;c=d.styleName};this.transform=function(a,b){var f=a.spec(),m=[h];switch(f.optype){case "RemoveStyle":f.styleName===c&&"paragraph"===f.styleFamily&&(c="")}return m};this.execute=function(d){var b;b=d.getIteratorAtPosition(a);return(b=d.getParagraphElement(b.container()))?(""!==c?b.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","text:style-name",c):b.removeAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0", -"style-name"),d.getOdfCanvas().refreshSize(),d.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:b,timeStamp:f,memberId:m}),d.getOdfCanvas().rerenderAnnotations(),!0):!1};this.spec=function(){return{optype:"SetParagraphStyle",memberid:m,timestamp:f,position:a,styleName:c}}}; -// Input 51 +ops.OpInsertText=function(){var e,h,f,n;this.init=function(m){e=m.memberid;h=m.timestamp;f=m.position;n=m.text};this.execute=function(m){var p,c,b,a=null,d=m.getDOM(),k,g=0,q,l;m.upgradeWhitespacesAtPosition(f);if(p=m.getPositionInTextNode(f,e)){c=p.textNode;a=c.nextSibling;b=c.parentNode;k=m.getParagraphElement(c);for(l=0;l @@ -1419,6 +1509,9 @@ ops.OpSetParagraphStyle=function(){var h=this,m,f,a,c;this.init=function(d){m=d. 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 @@ -1439,15 +1532,16 @@ ops.OpSetParagraphStyle=function(){var h=this,m,f,a,c;this.init=function(d){m=d. This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces"); -ops.OpUpdateParagraphStyle=function(){function h(a,b){var c,d,e=b?b.split(","):[];for(c=0;c @@ -1460,6 +1554,9 @@ h.styleFamily&&(h.styleName===e?x=[]:d(h.styleName))}return x};this.execute=func 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 @@ -1480,12 +1577,12 @@ h.styleFamily&&(h.styleName===e?x=[]:d(h.styleName))}return x};this.execute=func This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces"); -ops.OpAddStyle=function(){function h(a){k&&["style:parent-style-name","style:next-style-name"].forEach(function(b){k[b]===a&&delete k[b]})}var m=this,f,a,c,d,b,k,p=odf.Namespaces.stylens;this.init=function(e){f=e.memberid;a=e.timestamp;c=e.styleName;d=e.styleFamily;b="true"===e.isAutomaticStyle||!0===e.isAutomaticStyle;k=e.setProperties};this.transform=function(a,b){var c=a.spec();"RemoveStyle"===c.optype&&c.styleFamily===d&&h(c.styleName);return[m]};this.execute=function(a){var f=a.getOdfCanvas().odfContainer(), -h=a.getFormatting(),g=a.getDOM().createElementNS(p,"style:style");if(!g)return!1;k&&h.updateStyle(g,k);g.setAttributeNS(p,"style:family",d);g.setAttributeNS(p,"style:name",c);b?f.rootElement.automaticStyles.appendChild(g):f.rootElement.styles.appendChild(g);a.getOdfCanvas().refreshCSS();b||a.emit(ops.OdtDocument.signalCommonStyleCreated,{name:c,family:d});return!0};this.spec=function(){return{optype:"AddStyle",memberid:f,timestamp:a,styleName:c,styleFamily:d,isAutomaticStyle:b,setProperties:k}}}; -// Input 53 +ops.OpSplitParagraph=function(){var e,h,f,n;this.init=function(m){e=m.memberid;h=m.timestamp;f=m.position;n=new odf.OdfUtils};this.execute=function(m){var p,c,b,a,d,k,g;m.upgradeWhitespacesAtPosition(f);p=m.getPositionInTextNode(f,e);if(!p)return!1;c=m.getParagraphElement(p.textNode);if(!c)return!1;b=n.isListItem(c.parentNode)?c.parentNode:c;0===p.offset?(g=p.textNode.previousSibling,k=null):(g=p.textNode,k=p.offset>=p.textNode.length?null:p.textNode.splitText(p.offset));for(a=p.textNode;a!==b;)if(a= +a.parentNode,d=a.cloneNode(!1),g){for(k&&d.appendChild(k);g.nextSibling;)d.appendChild(g.nextSibling);a.parentNode.insertBefore(d,a.nextSibling);g=a;k=d}else a.parentNode.insertBefore(d,a),g=d,k=a;n.isListItem(k)&&(k=k.childNodes[0]);0===p.textNode.length&&p.textNode.parentNode.removeChild(p.textNode);m.fixCursorPositions();m.getOdfCanvas().refreshSize();m.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:c,memberId:e,timeStamp:h});m.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:k, +memberId:e,timeStamp:h});m.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"SplitParagraph",memberid:e,timestamp:h,position:f}}}; +// Input 54 /* Copyright (C) 2012-2013 KO GmbH @@ -1498,6 +1595,9 @@ h=a.getFormatting(),g=a.getDOM().createElementNS(p,"style:style");if(!g)return!1 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 @@ -1518,12 +1618,11 @@ h=a.getFormatting(),g=a.getDOM().createElementNS(p,"style:style");if(!g)return!1 This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.OpRemoveStyle=function(){function h(a){var d=[];a&&["style:parent-style-name","style:next-style-name"].forEach(function(f){a[f]===c&&d.push(f)});return d}var m=this,f,a,c,d;this.init=function(b){f=b.memberid;a=b.timestamp;c=b.styleName;d=b.styleFamily};this.transform=function(b,k){var p=b.spec(),e,s;e=[m];switch(p.optype){case "RemoveStyle":p.styleName===c&&p.styleFamily===d&&(e=[]);break;case "UpdateParagraphStyle":"paragraph"===d&&(s=h(p.setProperties),0 @@ -1536,6 +1635,9 @@ d);if(!f)return!1;f.parentNode.removeChild(f);a.getOdfCanvas().refreshCSS();a.em 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 @@ -1556,14 +1658,13 @@ d);if(!f)return!1;f.parentNode.removeChild(f);a.getOdfCanvas().refreshCSS();a.em This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.OpAddAnnotation=function(){function h(a,b,c){var d=a.getPositionInTextNode(c,f);d&&(a=d.textNode,c=a.parentNode,d.offset!==a.length&&a.splitText(d.offset),c.insertBefore(b,a.nextSibling),0===a.length&&c.removeChild(a))}var m=this,f,a,c,d,b;this.init=function(k){f=k.memberid;a=parseInt(k.timestamp,10);c=parseInt(k.position,10);d=parseInt(k.length,10)||0;b=k.name};this.transform=function(a,b){var e=a.spec(),f=c+d,h=[m];switch(e.optype){case "AddAnnotation":e.positionn?-l.countBackwardSteps(-n,e):0,s.move(e),k.emit(ops.OdtDocument.signalCursorMoved,s));k.getOdfCanvas().addAnnotation(m);return!0};this.spec=function(){return{optype:"AddAnnotation", -memberid:f,timestamp:a,position:c,length:d,name:b}}}; -// Input 55 +runtime.loadClass("odf.Namespaces"); +ops.OpUpdateParagraphStyle=function(){function e(b,a){var d,c,e=a?a.split(","):[];for(d=0;d @@ -1576,6 +1677,9 @@ memberid:f,timestamp:a,position:c,length:d,name:b}}}; 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 @@ -1596,13 +1700,12 @@ memberid:f,timestamp:a,position:c,length:d,name:b}}}; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("odf.Namespaces");runtime.loadClass("core.DomUtils"); -ops.OpRemoveAnnotation=function(){var h,m,f,a,c;this.init=function(d){h=d.memberid;m=d.timestamp;f=parseInt(d.position,10);a=parseInt(d.length,10);c=new core.DomUtils};this.transform=function(a,b){return null};this.execute=function(a){for(var b=a.getIteratorAtPosition(f).container(),k,h=null,e=null;b.namespaceURI!==odf.Namespaces.officens||"annotation"!==b.localName;)b=b.parentNode;if(null===b)return!1;h=b;(k=h.getAttributeNS(odf.Namespaces.officens,"name"))&&(e=c.getElementsByTagNameNS(a.getRootNode(), -odf.Namespaces.officens,"annotation-end").filter(function(a){return k===a.getAttributeNS(odf.Namespaces.officens,"name")})[0]||null);a.getOdfCanvas().forgetAnnotations();for(b=c.getElementsByTagNameNS(h,odf.Namespaces.webodfns+":names:cursor","cursor");b.length;)h.parentNode.insertBefore(b.pop(),h);h.parentNode.removeChild(h);e&&e.parentNode.removeChild(e);a.fixCursorPositions();a.getOdfCanvas().refreshAnnotations();return!0};this.spec=function(){return{optype:"RemoveAnnotation",memberid:h,timestamp:m, -position:f,length:a}}}; -// Input 56 +runtime.loadClass("odf.Namespaces"); +ops.OpAddStyle=function(){var e,h,f,n,m,p,c=odf.Namespaces.stylens;this.init=function(b){e=b.memberid;h=b.timestamp;f=b.styleName;n=b.styleFamily;m="true"===b.isAutomaticStyle||!0===b.isAutomaticStyle;p=b.setProperties};this.execute=function(b){var a=b.getOdfCanvas().odfContainer(),d=b.getFormatting(),e=b.getDOM().createElementNS(c,"style:style");if(!e)return!1;p&&d.updateStyle(e,p);e.setAttributeNS(c,"style:family",n);e.setAttributeNS(c,"style:name",f);m?a.rootElement.automaticStyles.appendChild(e):a.rootElement.styles.appendChild(e); +b.getOdfCanvas().refreshCSS();m||b.emit(ops.OdtDocument.signalCommonStyleCreated,{name:f,family:n});return!0};this.spec=function(){return{optype:"AddStyle",memberid:e,timestamp:h,styleName:f,styleFamily:n,isAutomaticStyle:m,setProperties:p}}}; +// Input 57 /* Copyright (C) 2012-2013 KO GmbH @@ -1615,6 +1718,9 @@ position:f,length:a}}}; 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 @@ -1635,29 +1741,13 @@ position:f,length:a}}}; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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.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(f){return function(){return new f}}var m;this.register=function(f,a){m[f]=a};this.create=function(f){var a=null,c=m[f.optype];c&&(a=c(f),a.init(f));return a};m={AddCursor:h(ops.OpAddCursor),ApplyDirectStyling:h(ops.OpApplyDirectStyling),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 57 -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 f(){r.setUnfilteredPosition(h.getNode(),0);return r}function a(a,b){var c,d=null;a&&(c=b?a[a.length-1]:a[0]);c&&(d={top:c.top,left:b?c.right:c.left,bottom:c.bottom});return d}function c(b,d,e,f){var g=b.nodeType;e.setStart(b,d);e.collapse(!f);f=a(e.getClientRects(),!0===f);!f&&0a?-1:1;for(a=Math.abs(a);0l?q.previousPosition():q.nextPosition());)if(T.check(),h.acceptPosition(q)===w&&(n+=1,r=q.container(),t=c(r,q.unfilteredDomOffset(),D),t.top!==R)){if(t.top!==G&&G!==R)break;G=t.top;t=Math.abs(F-t.left);if(null===x||ta?(d=h.previousPosition,e=-1):(d=h.nextPosition,e=1);for(g=c(h.container(),h.unfilteredDomOffset(),n);d.call(h);)if(b.acceptPosition(h)===w){if(q.getParagraphElement(h.getCurrentNode())!==l)break;k=c(h.container(),h.unfilteredDomOffset(),n);if(k.bottom!==g.bottom&&(g=k.top>=g.top&&k.bottomg.bottom,!g))break;r+=e;g=k}n.detach();return r}function u(a,b,c){runtime.assert(null!==a,"SelectionMover.countStepsToPosition called with element===null"); -var d=f(),e=d.container(),g=d.unfilteredDomOffset(),k=0,h=new core.LoopWatchDog(1E3);d.setUnfilteredPosition(a,b);a=d.container();runtime.assert(Boolean(a),"SelectionMover.countStepsToPosition: positionIterator.container() returned null");b=d.unfilteredDomOffset();d.setUnfilteredPosition(e,g);e=x.comparePoints(a,b,d.container(),d.unfilteredDomOffset());if(0>e)for(;d.nextPosition()&&(h.check(),c.acceptPosition(d)===w&&(k+=1),d.container()!==a||d.unfilteredDomOffset()!==b););else if(0=x.comparePoints(a,b,d.container(),d.unfilteredDomOffset()))););return k}var q,x,r,y,t,w=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.movePointForward=function(a,b){return d(a,b,r.nextPosition)};this.movePointBackward=function(a,b){return d(a,b,r.previousPosition)};this.getStepCounter=function(){return{countForwardSteps:k,countBackwardSteps:s,convertForwardStepsBetweenFilters:p,convertBackwardStepsBetweenFilters:e,countLinesSteps:g,countStepsToLineBoundary:l, -countStepsToPosition:u,isPositionWalkable:b,countStepsToValidPosition:n}};(function(){q=new odf.OdfUtils;x=new core.DomUtils;r=gui.SelectionMover.createPositionIterator(m);var a=m.ownerDocument.createRange();a.setStart(r.container(),r.unfilteredDomOffset());a.collapse(!0);h.setSelectedRange(a)})()}; -gui.SelectionMover.createPositionIterator=function(h){var m=new function(){this.acceptNode=function(f){return"urn:webodf:names:cursor"===f.namespaceURI||"urn:webodf:names:editinfo"===f.namespaceURI?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}};return new core.PositionIterator(h,5,m,!1)};(function(){return gui.SelectionMover})(); +ops.OpRemoveStyle=function(){var e,h,f,n;this.init=function(m){e=m.memberid;h=m.timestamp;f=m.styleName;n=m.styleFamily};this.execute=function(e){var h=e.getStyleElement(f,n);if(!h)return!1;h.parentNode.removeChild(h);e.getOdfCanvas().refreshCSS();e.emit(ops.OdtDocument.signalCommonStyleDeleted,{name:f,family:n});return!0};this.spec=function(){return{optype:"RemoveStyle",memberid:e,timestamp:h,styleName:f,styleFamily:n}}}; // Input 58 /* - Copyright (C) 2013 KO GmbH + Copyright (C) 2012-2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1667,6 +1757,9 @@ gui.SelectionMover.createPositionIterator=function(h){var m=new function(){this. 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 @@ -1687,19 +1780,57 @@ gui.SelectionMover.createPositionIterator=function(h){var m=new function(){this. This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");runtime.loadClass("ops.OpInsertTable");runtime.loadClass("ops.OpInsertText");runtime.loadClass("ops.OpRemoveText");runtime.loadClass("ops.OpSplitParagraph");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("ops.OpAddStyle");runtime.loadClass("ops.OpUpdateParagraphStyle");runtime.loadClass("ops.OpRemoveStyle"); -ops.OperationTransformer=function(){function h(f,a){for(var c,d,b,k=[],p=[];0=c&&(k=-a.movePointBackward(-c,b));f.handleUpdate();return k};this.handleUpdate=function(){};this.getStepCounter=function(){return a.getStepCounter()};this.getMemberId=function(){return h};this.getNode=function(){return c.getNode()};this.getAnchorNode=function(){return c.getAnchorNode()};this.getSelectedRange=function(){return c.getSelectedRange()}; -this.getOdtDocument=function(){return m};c=new core.Cursor(m.getDOM(),h);a=new gui.SelectionMover(c,m.getRootNode())}; +/* + + Copyright (C) 2012-2013 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + 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("odf.Namespaces");runtime.loadClass("core.DomUtils"); +ops.OpRemoveAnnotation=function(){var e,h,f,n,m;this.init=function(p){e=p.memberid;h=p.timestamp;f=parseInt(p.position,10);n=parseInt(p.length,10);m=new core.DomUtils};this.execute=function(e){for(var c=e.getIteratorAtPosition(f).container(),b,a=null,d=null;c.namespaceURI!==odf.Namespaces.officens||"annotation"!==c.localName;)c=c.parentNode;if(null===c)return!1;a=c;(b=a.getAttributeNS(odf.Namespaces.officens,"name"))&&(d=m.getElementsByTagNameNS(e.getRootNode(),odf.Namespaces.officens,"annotation-end").filter(function(a){return b=== +a.getAttributeNS(odf.Namespaces.officens,"name")})[0]||null);e.getOdfCanvas().forgetAnnotations();for(c=m.getElementsByTagNameNS(a,"urn:webodf:names:cursor","cursor");c.length;)a.parentNode.insertBefore(c.pop(),a);a.parentNode.removeChild(a);d&&d.parentNode.removeChild(d);e.fixCursorPositions();e.getOdfCanvas().refreshAnnotations();return!0};this.spec=function(){return{optype:"RemoveAnnotation",memberid:e,timestamp:h,position:f,length:n}}}; // Input 60 /* - Copyright (C) 2012 KO GmbH + Copyright (C) 2012-2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1709,6 +1840,9 @@ this.getOdtDocument=function(){return m};c=new core.Cursor(m.getDOM(),h);a=new g 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 @@ -1729,20 +1863,13 @@ this.getOdtDocument=function(){return m};c=new core.Cursor(m.getDOM(),h);a=new g This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.EditInfo=function(h,m){function f(){var a=[],b;for(b in c)c.hasOwnProperty(b)&&a.push({memberid:b,time:c[b].time});a.sort(function(a,b){return a.time-b.time});return a}var a,c={};this.getNode=function(){return a};this.getOdtDocument=function(){return m};this.getEdits=function(){return c};this.getSortedEdits=function(){return f()};this.addEdit=function(a,b){c[a]={time:b}};this.clearEdits=function(){c={}};this.destroy=function(c){h.parentNode&&h.removeChild(a);c()};a=m.getDOM().createElementNS("urn:webodf:names:editinfo", -"editinfo");h.insertBefore(a,h.firstChild)}; +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 e(e){return function(){return new e}}var h;this.register=function(e,n){h[e]=n};this.create=function(e){var n=null,m=h[e.optype];m&&(n=m(e),n.init(e));return n};h={AddCursor:e(ops.OpAddCursor),ApplyDirectStyling:e(ops.OpApplyDirectStyling),SetBlob:e(ops.OpSetBlob),RemoveBlob:e(ops.OpRemoveBlob),InsertImage:e(ops.OpInsertImage),InsertTable:e(ops.OpInsertTable),InsertText:e(ops.OpInsertText),RemoveText:e(ops.OpRemoveText),SplitParagraph:e(ops.OpSplitParagraph), +SetParagraphStyle:e(ops.OpSetParagraphStyle),UpdateParagraphStyle:e(ops.OpUpdateParagraphStyle),AddStyle:e(ops.OpAddStyle),RemoveStyle:e(ops.OpRemoveStyle),MoveCursor:e(ops.OpMoveCursor),RemoveCursor:e(ops.OpRemoveCursor),AddAnnotation:e(ops.OpAddAnnotation),RemoveAnnotation:e(ops.OpRemoveAnnotation)}}; // Input 61 -gui.Avatar=function(h,m){var f=this,a,c,d;this.setColor=function(a){c.style.borderColor=a};this.setImageUrl=function(a){f.isVisible()?c.src=a:d=a};this.isVisible=function(){return"block"===a.style.display};this.show=function(){d&&(c.src=d,d=void 0);a.style.display="block"};this.hide=function(){a.style.display="none"};this.markAsFocussed=function(b){a.className=b?"active":""};this.destroy=function(b){h.removeChild(a);b()};(function(){var b=h.ownerDocument,d=b.documentElement.namespaceURI;a=b.createElementNS(d, -"div");c=b.createElementNS(d,"img");c.width=64;c.height=64;a.appendChild(c);a.style.width="64px";a.style.height="70px";a.style.position="absolute";a.style.top="-80px";a.style.left="-34px";a.style.display=m?"block":"none";h.appendChild(a)})()}; -// Input 62 -runtime.loadClass("gui.Avatar");runtime.loadClass("ops.OdtCursor"); -gui.Caret=function(h,m,f){function a(d){k&&b.parentNode&&(!p||d)&&(d&&void 0!==e&&runtime.clearTimeout(e),p=!0,c.style.opacity=d||"0"===c.style.opacity?"1":"0",e=runtime.setTimeout(function(){p=!1;a(!1)},500))}var c,d,b,k=!1,p=!1,e;this.refreshCursorBlinking=function(){f||h.getSelectedRange().collapsed?(k=!0,a(!0)):(k=!1,c.style.opacity="0")};this.setFocus=function(){k=!0;d.markAsFocussed(!0);a(!0)};this.removeFocus=function(){k=!1;d.markAsFocussed(!1);c.style.opacity="1"};this.show=function(){c.style.visibility= -"visible";d.markAsFocussed(!0)};this.hide=function(){c.style.visibility="hidden";d.markAsFocussed(!1)};this.setAvatarImageUrl=function(a){d.setImageUrl(a)};this.setColor=function(a){c.style.borderColor=a;d.setColor(a)};this.getCursor=function(){return h};this.getFocusElement=function(){return c};this.toggleHandleVisibility=function(){d.isVisible()?d.hide():d.show()};this.showHandle=function(){d.show()};this.hideHandle=function(){d.hide()};this.ensureVisible=function(){var a,b,d,e,f=h.getOdtDocument().getOdfCanvas().getElement().parentNode, -k;d=f.offsetWidth-f.clientWidth+5;e=f.offsetHeight-f.clientHeight+5;k=c.getBoundingClientRect();a=k.left-d;b=k.top-e;d=k.right+d;e=k.bottom+e;k=f.getBoundingClientRect();bk.bottom&&(f.scrollTop+=e-k.bottom);ak.right&&(f.scrollLeft+=d-k.right)};this.destroy=function(a){d.destroy(function(d){d?a(d):(b.removeChild(c),a())})};(function(){var a=h.getOdtDocument().getDOM();c=a.createElementNS(a.documentElement.namespaceURI,"span");b=h.getNode(); -b.appendChild(c);d=new gui.Avatar(b,m)})()}; -// Input 63 /* Copyright (C) 2012-2013 KO GmbH @@ -1755,6 +1882,9 @@ b.appendChild(c);d=new gui.Avatar(b,m)})()}; 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 @@ -1775,11 +1905,147 @@ b.appendChild(c);d=new gui.Avatar(b,m)})()}; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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(e,h){function f(){v.setUnfilteredPosition(e.getNode(),0);return v}function n(a,b){var d,c=null;a&&(d=b?a[a.length-1]:a[0]);d&&(c={top:d.top,left:b?d.right:d.left,bottom:d.bottom});return c}function m(a,b,d,c){var e=a.nodeType;d.setStart(a,b);d.collapse(!c);c=n(d.getClientRects(),!0===c);!c&&0a?-1:1;for(a=Math.abs(a);0l?n.previousPosition():n.nextPosition());)if(M.check(),k.acceptPosition(n)===u&&(t+=1,p=n.container(),v=m(p,n.unfilteredDomOffset(),H),v.top!==O)){if(v.top!==E&&E!==O)break;E=v.top;v=Math.abs(W-v.left);if(null===q||va?(d=k.previousPosition,c=-1):(d=k.nextPosition,c=1);for(e=m(k.container(),k.unfilteredDomOffset(),p);d.call(k);)if(b.acceptPosition(k)===u){if(t.getParagraphElement(k.getCurrentNode())!==l)break;g=m(k.container(),k.unfilteredDomOffset(),p);if(g.bottom!==e.bottom&&(e=g.top>=e.top&&g.bottome.bottom,!e))break;n+= +c;e=g}p.detach();return n}function r(a,b,d){runtime.assert(null!==a,"SelectionMover.countStepsToPosition called with element===null");var c=f(),e=c.container(),g=c.unfilteredDomOffset(),h=0,k=new core.LoopWatchDog(1E3);for(c.setUnfilteredPosition(a,b);d.acceptPosition(c)!==u&&c.previousPosition();)k.check();a=c.container();runtime.assert(Boolean(a),"SelectionMover.countStepsToPosition: positionIterator.container() returned null");b=c.unfilteredDomOffset();for(c.setUnfilteredPosition(e,g);d.acceptPosition(c)!== +u&&c.previousPosition();)k.check();e=w.comparePoints(a,b,c.container(),c.unfilteredDomOffset());if(0>e)for(;c.nextPosition()&&(k.check(),d.acceptPosition(c)===u&&(h+=1),c.container()!==a||c.unfilteredDomOffset()!==b););else if(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/ +*/ +ops.OperationTransformMatrix=function(){function e(a,b){return{opSpecsA:[a],opSpecsB:[b]}}function h(a,b){var c=[];a&&["style:parent-style-name","style:next-style-name"].forEach(function(e){a[e]===b&&c.push(e)});return c}function f(a,b){a&&["style:parent-style-name","style:next-style-name"].forEach(function(c){a[c]===b&&delete a[c]})}function n(a,b,c,e){var f,h,m,n=e&&e.attributes?e.attributes.split(","):[];a&&(c||0b.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){a.positionb.position)a.position+=1;else return c?b.position+=a.text.length:a.position+=1,null;return{opSpecsA:[a],opSpecsB:[b]}},UpdateParagraphStyle:e},MoveCursor:{MoveCursor:e,RemoveCursor:function(a,b){return{opSpecsA:a.memberid===b.memberid?[]:[a],opSpecsB:[b]}}, +RemoveStyle:e,RemoveText:function(a,b){var c=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 c?b.position+=1:a.position+=1,null;return{opSpecsA:[a],opSpecsB:[b]}},UpdateParagraphStyle:e},UpdateParagraphStyle:{UpdateParagraphStyle:function(a,b,e){var f,h=[a],l=[b];a.styleName===b.styleName&&(f=e?a:b,a=e?b:a,c(a,f,"style:paragraph-properties"),c(a,f,"style:text-properties"),n(a.setProperties||null,a.removedProperties||null,f.setProperties||null,f.removedProperties||null),a.setProperties&&m(a.setProperties)||a.removedProperties&&p(a.removedProperties)|| +(e?l=[]:h=[]));return{opSpecsA:h,opSpecsB:l}}}};this.passUnchanged=e;this.extendTransformations=function(a){Object.keys(a).forEach(function(c){var e=a[c],f,h=b.hasOwnProperty(c);runtime.log((h?"Extending":"Adding")+" map for optypeA: "+c);h||(b[c]={});f=b[c];Object.keys(e).forEach(function(a){var b=f.hasOwnProperty(a);runtime.assert(c<=a,"Wrong order:"+c+", "+a);runtime.log(" "+(b?"Overwriting":"Adding")+" entry for optypeB: "+a);f[a]=e[a]})})};this.transformOpspecVsOpspec=function(a,c){var e=a.optype<= +c.optype,f;runtime.log("Crosstransforming:");runtime.log(runtime.toJson(a));runtime.log(runtime.toJson(c));e||(f=a,a=c,c=f);(f=(f=b[a.optype])&&f[c.optype])?(f=f(a,c,!e),e||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 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/ */ -gui.KeyboardHandler=function(){function h(a,d){d||(d=m.None);return a+":"+d}var m=gui.KeyboardHandler.Modifier,f=null,a={};this.setDefault=function(a){f=a};this.bind=function(c,d,b){c=h(c,d);runtime.assert(!1===a.hasOwnProperty(c),"tried to overwrite the callback handler of key combo: "+c);a[c]=b};this.unbind=function(c,d){var b=h(c,d);delete a[b]};this.reset=function(){f=null;a={}};this.handleEvent=function(c){var d=c.keyCode,b=m.None;c.metaKey&&(b|=m.Meta);c.ctrlKey&&(b|=m.Ctrl);c.altKey&&(b|=m.Alt); -c.shiftKey&&(b|=m.Shift);d=h(d,b);d=a[d];b=!1;d?b=d():null!==f&&(b=f(c));b&&(c.preventDefault?c.preventDefault():c.returnValue=!1)}};gui.KeyboardHandler.Modifier={None:0,Meta:1,Ctrl:2,Alt:4,Shift:8,MetaShift:9,CtrlShift:10,AltShift:12};gui.KeyboardHandler.KeyCode={Backspace:8,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})(); +runtime.loadClass("ops.OperationFactory");runtime.loadClass("ops.OperationTransformMatrix"); +ops.OperationTransformer=function(){function e(e){var h=[];e.forEach(function(c){h.push(f.create(c))});return h}function h(e,f){for(var c,b,a=[],d=[];0=b&&(c=-p.movePointBackward(-b,a));f.handleUpdate();return c};this.handleUpdate=function(){};this.getStepCounter=function(){return p.getStepCounter()};this.getMemberId=function(){return e};this.getNode=function(){return c.getNode()};this.getAnchorNode=function(){return c.getAnchorNode()};this.getSelectedRange=function(){return c.getSelectedRange()}; +this.setSelectedRange=function(b,a){c.setSelectedRange(b,a)};this.hasForwardSelection=function(){return c.hasForwardSelection()};this.getOdtDocument=function(){return h};this.getSelectionType=function(){return m};this.setSelectionType=function(b){n.hasOwnProperty(b)?m=b:runtime.log("Invalid selection type: "+b)};this.resetSelectionType=function(){f.setSelectionType(ops.OdtCursor.RangeSelection)};c=new core.Cursor(h.getDOM(),e);p=new gui.SelectionMover(c,h.getRootNode());n[ops.OdtCursor.RangeSelection]= +!0;n[ops.OdtCursor.RegionSelection]=!0;f.resetSelectionType()};ops.OdtCursor.RangeSelection="Range";ops.OdtCursor.RegionSelection="Region";(function(){return ops.OdtCursor})(); +// Input 65 +/* + + Copyright (C) 2012 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + 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.EditInfo=function(e,h){function f(){var e=[],c;for(c in m)m.hasOwnProperty(c)&&e.push({memberid:c,time:m[c].time});e.sort(function(b,a){return b.time-a.time});return e}var n,m={};this.getNode=function(){return n};this.getOdtDocument=function(){return h};this.getEdits=function(){return m};this.getSortedEdits=function(){return f()};this.addEdit=function(e,c){m[e]={time:c}};this.clearEdits=function(){m={}};this.destroy=function(f){e.parentNode&&e.removeChild(n);f()};n=h.getDOM().createElementNS("urn:webodf:names:editinfo", +"editinfo");e.insertBefore(n,e.firstChild)}; +// Input 66 +runtime.loadClass("gui.SelectionMover");gui.ShadowCursor=function(e){var h=e.getDOM().createRange(),f=!0;this.removeFromOdtDocument=function(){};this.getMemberId=function(){return gui.ShadowCursor.ShadowCursorMemberId};this.getSelectedRange=function(){return h};this.setSelectedRange=function(e,m){h=e;f=!1!==m};this.hasForwardSelection=function(){return f};this.getOdtDocument=function(){return e};this.getSelectionType=function(){return ops.OdtCursor.RangeSelection};h.setStart(e.getRootNode(),0)}; +gui.ShadowCursor.ShadowCursorMemberId="";(function(){return gui.ShadowCursor})(); +// Input 67 +gui.Avatar=function(e,h){var f=this,n,m,p;this.setColor=function(c){m.style.borderColor=c};this.setImageUrl=function(c){f.isVisible()?m.src=c:p=c};this.isVisible=function(){return"block"===n.style.display};this.show=function(){p&&(m.src=p,p=void 0);n.style.display="block"};this.hide=function(){n.style.display="none"};this.markAsFocussed=function(c){n.className=c?"active":""};this.destroy=function(c){e.removeChild(n);c()};(function(){var c=e.ownerDocument,b=c.documentElement.namespaceURI;n=c.createElementNS(b, +"div");m=c.createElementNS(b,"img");m.width=64;m.height=64;n.appendChild(m);n.style.width="64px";n.style.height="70px";n.style.position="absolute";n.style.top="-80px";n.style.left="-34px";n.style.display=h?"block":"none";e.appendChild(n)})()}; +// Input 68 +runtime.loadClass("core.DomUtils");runtime.loadClass("gui.Avatar");runtime.loadClass("ops.OdtCursor"); +gui.Caret=function(e,h,f){function n(b){k&&a.parentNode&&(!g||b)&&(b&&void 0!==q&&runtime.clearTimeout(q),g=!0,c.style.opacity=b||"0"===c.style.opacity?"1":"0",q=runtime.setTimeout(function(){g=!1;n(!1)},500))}function m(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 p(){var a;a=e.getSelectedRange().cloneRange();var b=e.getNode(),f,g=null;b.previousSibling&&(f=b.previousSibling.nodeType===Node.TEXT_NODE?b.previousSibling.textContent.length: +b.previousSibling.childNodes.length,a.setStart(b.previousSibling,0m(b,g))&&(g=f));a=g;b=e.getOdtDocument().getOdfCanvas().getZoomLevel();d&&e.getSelectionType()===ops.OdtCursor.RangeSelection? +c.style.visibility="visible":c.style.visibility="hidden";a?(c.style.top="0",g=c.ownerDocument.createRange(),g.selectNode(c),f=g.getBoundingClientRect(),g.detach(),8>a.height&&(a={top:a.top-(8-a.height)/2,height:8}),c.style.height=l.adaptRangeDifferenceToZoomLevel(a.height,b)+"px",c.style.top=l.adaptRangeDifferenceToZoomLevel(a.top-f.top,b)+"px"):(c.style.height="1em",c.style.top="5%")}var c,b,a,d=!0,k=!1,g=!1,q,l=new core.DomUtils;this.handleUpdate=p;this.refreshCursorBlinking=function(){f||e.getSelectedRange().collapsed? +(k=!0,n(!0)):(k=!1,c.style.opacity="0")};this.setFocus=function(){k=!0;b.markAsFocussed(!0);n(!0)};this.removeFocus=function(){k=!1;b.markAsFocussed(!1);c.style.opacity="1"};this.show=function(){d=!0;p();b.markAsFocussed(!0)};this.hide=function(){d=!1;p();b.markAsFocussed(!1)};this.setAvatarImageUrl=function(a){b.setImageUrl(a)};this.setColor=function(a){c.style.borderColor=a;b.setColor(a)};this.getCursor=function(){return e};this.getFocusElement=function(){return c};this.toggleHandleVisibility=function(){b.isVisible()? +b.hide():b.show()};this.showHandle=function(){b.show()};this.hideHandle=function(){b.hide()};this.ensureVisible=function(){var a,b,d,f,g=e.getOdtDocument().getOdfCanvas().getElement().parentNode,h;d=g.offsetWidth-g.clientWidth+5;f=g.offsetHeight-g.clientHeight+5;h=c.getBoundingClientRect();a=h.left-d;b=h.top-f;d=h.right+d;f=h.bottom+f;h=g.getBoundingClientRect();bh.bottom&&(g.scrollTop+=f-h.bottom);ah.right&&(g.scrollLeft+=d-h.right); +p()};this.destroy=function(d){b.destroy(function(b){b?d(b):(a.removeChild(c),d())})};(function(){var d=e.getOdtDocument().getDOM();c=d.createElementNS(d.documentElement.namespaceURI,"span");c.style.top="5%";a=e.getNode();a.appendChild(c);b=new gui.Avatar(a,h);p()})()}; +// Input 69 /* Copyright (C) 2013 KO GmbH @@ -1792,6 +2058,9 @@ c.shiftKey&&(b|=m.Shift);d=h(d,b);d=a[d];b=!1;d?b=d():null!==f&&(b=f(c));b&&(c.p 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 @@ -1812,12 +2081,12 @@ c.shiftKey&&(b|=m.Shift);d=h(d,b);d=a[d];b=!1;d?b=d():null!==f&&(b=f(c));b&&(c.p This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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,f;this.setDataFromRange=function(a,c){var d=!0,b,f=a.clipboardData;b=runtime.getWindow();var p=c.startContainer.ownerDocument;!f&&b&&(f=b.clipboardData);f?(p=p.createElement("span"),p.appendChild(c.cloneContents()),b=f.setData("text/plain",m.writeToString(p)),d=d&&b,b=f.setData("text/html",h.writeToString(p,odf.Namespaces.namespaceMap)),d=d&&b,a.preventDefault()):d=!1;return d};h=new xmldom.LSSerializer;m=new odf.TextSerializer;f=new odf.OdfNodeFilter;h.filter=f;m.filter= +gui.Clipboard=function(){var e,h,f;this.setDataFromRange=function(f,m){var p=!0,c,b=f.clipboardData;c=runtime.getWindow();var a=m.startContainer.ownerDocument;!b&&c&&(b=c.clipboardData);b?(a=a.createElement("span"),a.appendChild(m.cloneContents()),c=b.setData("text/plain",h.writeToString(a)),p=p&&c,c=b.setData("text/html",e.writeToString(a,odf.Namespaces.namespaceMap)),p=p&&c,f.preventDefault()):p=!1;return p};e=new xmldom.LSSerializer;h=new odf.TextSerializer;f=new odf.OdfNodeFilter;e.filter=f;h.filter= f}; -// Input 65 +// Input 70 /* Copyright (C) 2013 KO GmbH @@ -1830,6 +2099,9 @@ f}; 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 @@ -1850,16 +2122,18 @@ f}; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -runtime.loadClass("core.EventNotifier");runtime.loadClass("ops.OpApplyDirectStyling");runtime.loadClass("gui.StyleHelper"); -gui.DirectTextStyler=function(h,m){function f(a,b){for(var c=0,d=b[c];d&&a;)a=a[d],c+=1,d=b[c];return b.length===c?a:void 0}function a(a,b){var c=f(a[0],b);return a.every(function(a){return c===f(a,b)})?c:void 0}function c(){function b(a,c,d){a!==c&&(void 0===e&&(e={}),e[d]=c);return c}var c=x.getCursor(m),d=c&&c.getSelectedRange(),c=d&&r.getAppliedStyles(d),e;t=b(t,d?r.isBold(d):!1,"isBold");w=b(w,d?r.isItalic(d):!1,"isItalic");v=b(v,d?r.hasUnderline(d):!1,"hasUnderline");C=b(C,d?r.hasStrikeThrough(d): -!1,"hasStrikeThrough");d=c&&a(c,["style:text-properties","fo:font-size"]);J=b(J,d&&parseFloat(d),"fontSize");E=b(E,c&&a(c,["style:text-properties","style:font-name"]),"fontName");e&&y.emit(gui.DirectTextStyler.textStylingChanged,e)}function d(a){a.getMemberId()===m&&c()}function b(a){a===m&&c()}function k(a){a.getMemberId()===m&&c()}function p(){c()}function e(a){var b=x.getCursor(m);b&&x.getParagraphElement(b.getNode())===a.paragraphElement&&c()}function s(a,b){var c=x.getCursor(m);if(!c)return!1; -b(!a(c.getSelectedRange()));return!0}function n(a,b){var c=x.getCursorSelection(m),d=new ops.OpApplyDirectStyling,e={};e[a]=b;d.init({memberid:m,position:c.position,length:c.length,setProperties:{"style:text-properties":e}});h.enqueue(d)}function g(a){n("fo:font-weight",a?"bold":"normal")}function l(a){n("fo:font-style",a?"italic":"normal")}function u(a){n("style:text-underline-style",a?"solid":"none")}function q(a){n("style:text-line-through-style",a?"solid":"none")}var x=h.getOdtDocument(),r=new gui.StyleHelper(x.getFormatting()), -y=new core.EventNotifier([gui.DirectTextStyler.textStylingChanged]),t=!1,w=!1,v=!1,C=!1,J,E;this.setBold=g;this.setItalic=l;this.setHasUnderline=u;this.setHasStrikethrough=q;this.setFontSize=function(a){n("fo:font-size",a+"pt")};this.setFontName=function(a){n("style:font-name",a)};this.toggleBold=s.bind(this,r.isBold,g);this.toggleItalic=s.bind(this,r.isItalic,l);this.toggleUnderline=s.bind(this,r.hasUnderline,u);this.toggleStrikethrough=s.bind(this,r.hasStrikeThrough,q);this.isBold=function(){return t}; -this.isItalic=function(){return w};this.hasUnderline=function(){return v};this.hasStrikeThrough=function(){return C};this.fontSize=function(){return J};this.fontName=function(){return E};this.subscribe=function(a,b){y.subscribe(a,b)};this.unsubscribe=function(a,b){y.unsubscribe(a,b)};this.destroy=function(a){x.unsubscribe(ops.OdtDocument.signalCursorAdded,d);x.unsubscribe(ops.OdtDocument.signalCursorRemoved,b);x.unsubscribe(ops.OdtDocument.signalCursorMoved,k);x.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, -p);x.unsubscribe(ops.OdtDocument.signalParagraphChanged,e);a()};x.subscribe(ops.OdtDocument.signalCursorAdded,d);x.subscribe(ops.OdtDocument.signalCursorRemoved,b);x.subscribe(ops.OdtDocument.signalCursorMoved,k);x.subscribe(ops.OdtDocument.signalParagraphStyleModified,p);x.subscribe(ops.OdtDocument.signalParagraphChanged,e);c()};gui.DirectTextStyler.textStylingChanged="textStyling/changed";(function(){return gui.DirectTextStyler})(); -// Input 66 +runtime.loadClass("core.EventNotifier");runtime.loadClass("core.Utils");runtime.loadClass("ops.OpApplyDirectStyling");runtime.loadClass("gui.StyleHelper"); +gui.DirectTextStyler=function(e,h){function f(a,b){for(var c=0,d=b[c];d&&a;)a=a[d],c+=1,d=b[c];return b.length===c?a:void 0}function n(a,b){var c=f(a[0],b);return a.every(function(a){return c===f(a,b)})?c:void 0}function m(){var a=u.getCursor(h),a=(a=a&&a.getSelectedRange())&&s.getAppliedStyles(a)||[];a[0]&&B&&(a[0]=x.mergeObjects(a[0],B));return a}function p(){function a(b,d,e){b!==d&&(void 0===c&&(c={}),c[e]=d);return d}var b,c;A=m();I=a(I,A?s.isBold(A):!1,"isBold");z=a(z,A?s.isItalic(A):!1,"isItalic"); +N=a(N,A?s.hasUnderline(A):!1,"hasUnderline");G=a(G,A?s.hasStrikeThrough(A):!1,"hasStrikeThrough");b=A&&n(A,["style:text-properties","fo:font-size"]);R=a(R,b&&parseFloat(b),"fontSize");Z=a(Z,A&&n(A,["style:text-properties","style:font-name"]),"fontName");c&&C.emit(gui.DirectTextStyler.textStylingChanged,c)}function c(a){a.getMemberId()===h&&p()}function b(a){a===h&&p()}function a(a){a.getMemberId()===h&&p()}function d(){p()}function k(a){var b=u.getCursor(h);b&&u.getParagraphElement(b.getNode())=== +a.paragraphElement&&p()}function g(a,b){var c=u.getCursor(h);if(!c)return!1;c=s.getAppliedStyles(c.getSelectedRange());b(!a(c));return!0}function q(a){var b=u.getCursorSelection(h),c={"style:text-properties":a};0!==b.length?(a=new ops.OpApplyDirectStyling,a.init({memberid:h,position:b.position,length:b.length,setProperties:c}),e.enqueue([a])):(B=x.mergeObjects(B||{},c),p())}function l(a,b){var c={};c[a]=b;q(c)}function r(a){a=a.spec();B&&a.memberid===h&&"SplitParagraph"!==a.optype&&(B=null,p())}function t(a){l("fo:font-weight", +a?"bold":"normal")}function w(a){l("fo:font-style",a?"italic":"normal")}function v(a){l("style:text-underline-style",a?"solid":"none")}function y(a){l("style:text-line-through-style",a?"solid":"none")}var x=new core.Utils,u=e.getOdtDocument(),s=new gui.StyleHelper(u.getFormatting()),C=new core.EventNotifier([gui.DirectTextStyler.textStylingChanged]),B,A=[],I=!1,z=!1,N=!1,G=!1,R,Z;this.formatTextSelection=q;this.createCursorStyleOp=function(a,b){var c=null;B&&(c=new ops.OpApplyDirectStyling,c.init({memberid:h, +position:a,length:b,setProperties:B}),B=null,p());return c};this.setBold=t;this.setItalic=w;this.setHasUnderline=v;this.setHasStrikethrough=y;this.setFontSize=function(a){l("fo:font-size",a+"pt")};this.setFontName=function(a){l("style:font-name",a)};this.getAppliedStyles=function(){return A};this.toggleBold=g.bind(this,s.isBold,t);this.toggleItalic=g.bind(this,s.isItalic,w);this.toggleUnderline=g.bind(this,s.hasUnderline,v);this.toggleStrikethrough=g.bind(this,s.hasStrikeThrough,y);this.isBold=function(){return I}; +this.isItalic=function(){return z};this.hasUnderline=function(){return N};this.hasStrikeThrough=function(){return G};this.fontSize=function(){return R};this.fontName=function(){return Z};this.subscribe=function(a,b){C.subscribe(a,b)};this.unsubscribe=function(a,b){C.unsubscribe(a,b)};this.destroy=function(e){u.unsubscribe(ops.OdtDocument.signalCursorAdded,c);u.unsubscribe(ops.OdtDocument.signalCursorRemoved,b);u.unsubscribe(ops.OdtDocument.signalCursorMoved,a);u.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, +d);u.unsubscribe(ops.OdtDocument.signalParagraphChanged,k);u.unsubscribe(ops.OdtDocument.signalOperationExecuted,r);e()};u.subscribe(ops.OdtDocument.signalCursorAdded,c);u.subscribe(ops.OdtDocument.signalCursorRemoved,b);u.subscribe(ops.OdtDocument.signalCursorMoved,a);u.subscribe(ops.OdtDocument.signalParagraphStyleModified,d);u.subscribe(ops.OdtDocument.signalParagraphChanged,k);u.subscribe(ops.OdtDocument.signalOperationExecuted,r);p()};gui.DirectTextStyler.textStylingChanged="textStyling/changed"; +(function(){return gui.DirectTextStyler})(); +// Input 71 /* Copyright (C) 2013 KO GmbH @@ -1872,6 +2146,9 @@ p);x.unsubscribe(ops.OdtDocument.signalParagraphChanged,e);a()};x.subscribe(ops. 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 @@ -1892,16 +2169,67 @@ p);x.unsubscribe(ops.OdtDocument.signalParagraphChanged,e);a()};x.subscribe(ops. This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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,f){function a(){function a(b,d,e){b!==d&&(void 0===c&&(c={}),c[e]=d);return d}var b=l.getCursor(m),b=b&&b.getSelectedRange(),c;y=a(y,b?x.isAlignedLeft(b):!1,"isAlignedLeft");t=a(t,b?x.isAlignedCenter(b):!1,"isAlignedCenter");w=a(w,b?x.isAlignedRight(b):!1,"isAlignedRight");v=a(v,b?x.isAlignedJustified(b):!1,"isAlignedJustified");c&&r.emit(gui.DirectParagraphStyler.paragraphStylingChanged,c)}function c(b){b.getMemberId()===m&&a()}function d(b){b===m&&a()}function b(b){b.getMemberId()=== -m&&a()}function k(){a()}function p(b){var c=l.getCursor(m);c&&l.getParagraphElement(c.getNode())===b.paragraphElement&&a()}function e(a){var b=l.getCursor(m).getSelectedRange(),c=l.getCursorPosition(m),b=q.getParagraphElements(b),d=l.getFormatting();b.forEach(function(b){var e=c+l.getDistanceFromCursor(m,b,0),g=b.getAttributeNS(odf.Namespaces.textns,"style-name");b=f.generateName();var k,e=e+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:e});h.enqueue(g);h.enqueue(k)})}function s(a){e(function(b){return u.mergeObjects(b,a)})}function n(a){s({"style:paragraph-properties":{"fo:text-align":a}})}function g(a,b){var c=l.getFormatting().getDefaultTabStopDistance(),d=b["style:paragraph-properties"],d=(d=d&&d["fo:margin-left"])&&q.parseLength(d);return u.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 l=h.getOdtDocument(),u=new core.Utils,q=new odf.OdfUtils,x=new gui.StyleHelper(l.getFormatting()),r=new core.EventNotifier([gui.DirectParagraphStyler.paragraphStylingChanged]),y,t,w,v;this.isAlignedLeft=function(){return y};this.isAlignedCenter=function(){return t};this.isAlignedRight=function(){return w};this.isAlignedJustified=function(){return v};this.alignParagraphLeft=function(){n("left");return!0};this.alignParagraphCenter=function(){n("center"); -return!0};this.alignParagraphRight=function(){n("right");return!0};this.alignParagraphJustified=function(){n("justify");return!0};this.indent=function(){e(g.bind(null,1));return!0};this.outdent=function(){e(g.bind(null,-1));return!0};this.subscribe=function(a,b){r.subscribe(a,b)};this.unsubscribe=function(a,b){r.unsubscribe(a,b)};this.destroy=function(a){l.unsubscribe(ops.OdtDocument.signalCursorAdded,c);l.unsubscribe(ops.OdtDocument.signalCursorRemoved,d);l.unsubscribe(ops.OdtDocument.signalCursorMoved, -b);l.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,k);l.unsubscribe(ops.OdtDocument.signalParagraphChanged,p);a()};l.subscribe(ops.OdtDocument.signalCursorAdded,c);l.subscribe(ops.OdtDocument.signalCursorRemoved,d);l.subscribe(ops.OdtDocument.signalCursorMoved,b);l.subscribe(ops.OdtDocument.signalParagraphStyleModified,k);l.subscribe(ops.OdtDocument.signalParagraphChanged,p);a()};gui.DirectParagraphStyler.paragraphStylingChanged="paragraphStyling/changed";(function(){return gui.DirectParagraphStyler})(); -// Input 67 +gui.DirectParagraphStyler=function(e,h,f){function n(){function a(b,d,e){b!==d&&(void 0===c&&(c={}),c[e]=d);return d}var b=l.getCursor(h),b=b&&b.getSelectedRange(),c;y=a(y,b?w.isAlignedLeft(b):!1,"isAlignedLeft");x=a(x,b?w.isAlignedCenter(b):!1,"isAlignedCenter");u=a(u,b?w.isAlignedRight(b):!1,"isAlignedRight");s=a(s,b?w.isAlignedJustified(b):!1,"isAlignedJustified");c&&v.emit(gui.DirectParagraphStyler.paragraphStylingChanged,c)}function m(a){a.getMemberId()===h&&n()}function p(a){a===h&&n()}function c(a){a.getMemberId()=== +h&&n()}function b(){n()}function a(a){var b=l.getCursor(h);b&&l.getParagraphElement(b.getNode())===a.paragraphElement&&n()}function d(a){var b=l.getCursor(h).getSelectedRange(),c=l.getCursorPosition(h),b=t.getParagraphElements(b),d=l.getFormatting();b.forEach(function(b){var g=c+l.getDistanceFromCursor(h,b,0),k=b.getAttributeNS(odf.Namespaces.textns,"style-name");b=f.generateStyleName();var m,g=g+1;k&&(m=d.createDerivedStyleObject(k,"paragraph",{}));m=a(m||{});k=new ops.OpAddStyle;k.init({memberid:h, +styleName:b,styleFamily:"paragraph",isAutomaticStyle:!0,setProperties:m});m=new ops.OpSetParagraphStyle;m.init({memberid:h,styleName:b,position:g});e.enqueue([k,m])})}function k(a){d(function(b){return r.mergeObjects(b,a)})}function g(a){k({"style:paragraph-properties":{"fo:text-align":a}})}function q(a,b){var c=l.getFormatting().getDefaultTabStopDistance(),d=b["style:paragraph-properties"],d=(d=d&&d["fo:margin-left"])&&t.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 l=e.getOdtDocument(),r=new core.Utils,t=new odf.OdfUtils,w=new gui.StyleHelper(l.getFormatting()),v=new core.EventNotifier([gui.DirectParagraphStyler.paragraphStylingChanged]),y,x,u,s;this.isAlignedLeft=function(){return y};this.isAlignedCenter=function(){return x};this.isAlignedRight=function(){return u};this.isAlignedJustified=function(){return s};this.alignParagraphLeft=function(){g("left");return!0};this.alignParagraphCenter=function(){g("center"); +return!0};this.alignParagraphRight=function(){g("right");return!0};this.alignParagraphJustified=function(){g("justify");return!0};this.indent=function(){d(q.bind(null,1));return!0};this.outdent=function(){d(q.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(d){l.unsubscribe(ops.OdtDocument.signalCursorAdded,m);l.unsubscribe(ops.OdtDocument.signalCursorRemoved,p);l.unsubscribe(ops.OdtDocument.signalCursorMoved, +c);l.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,b);l.unsubscribe(ops.OdtDocument.signalParagraphChanged,a);d()};l.subscribe(ops.OdtDocument.signalCursorAdded,m);l.subscribe(ops.OdtDocument.signalCursorRemoved,p);l.subscribe(ops.OdtDocument.signalCursorMoved,c);l.subscribe(ops.OdtDocument.signalParagraphStyleModified,b);l.subscribe(ops.OdtDocument.signalParagraphChanged,a);n()};gui.DirectParagraphStyler.paragraphStylingChanged="paragraphStyling/changed";(function(){return gui.DirectParagraphStyler})(); +// Input 72 +/* + + 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/ +*/ +gui.KeyboardHandler=function(){function e(e,f){f||(f=h.None);return e+":"+f}var h=gui.KeyboardHandler.Modifier,f=null,n={};this.setDefault=function(e){f=e};this.bind=function(f,h,c){f=e(f,h);runtime.assert(!1===n.hasOwnProperty(f),"tried to overwrite the callback handler of key combo: "+f);n[f]=c};this.unbind=function(f,h){var c=e(f,h);delete n[c]};this.reset=function(){f=null;n={}};this.handleEvent=function(m){var p=m.keyCode,c=h.None;m.metaKey&&(c|=h.Meta);m.ctrlKey&&(c|=h.Ctrl);m.altKey&&(c|=h.Alt); +m.shiftKey&&(c|=h.Shift);p=e(p,c);p=n[p];c=!1;p?c=p():null!==f&&(c=f(m));c&&(m.preventDefault?m.preventDefault():m.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 73 +runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.ObjectNameGenerator"); +gui.ImageManager=function(e,h,f){var n={"image/gif":".gif","image/jpeg":".jpg","image/png":".png"},m=odf.Namespaces.textns,p=e.getOdtDocument(),c=p.getFormatting(),b={};this.insertImage=function(a,d,k,g){var q;runtime.assert(0q.width&&(l=q.width/k);g>q.height&&(r=q.height/g);l=Math.min(l,r);q=k*l;k=g*l;r=p.getOdfCanvas().odfContainer().rootElement.styles;g=a.toLowerCase();var l=n.hasOwnProperty(g)?n[g]:null,t;g=[];runtime.assert(null!==l,"Image type is not supported: "+a);l="Pictures/"+f.generateImageName()+l;t=new ops.OpSetBlob;t.init({memberid:h,filename:l,mimetype:a,content:d});g.push(t);c.getStyleElement("Graphics","graphic",[r])||(a=new ops.OpAddStyle,a.init({memberid:h,styleName:"Graphics",styleFamily:"graphic", +isAutomaticStyle:!1,setProperties:{"style:graphic-properties":{"text:anchor-type":"paragraph","svg:x":"0cm","svg:y":"0cm","style:wrap":"dynamic","style:number-wrapped-paragraphs":"no-limit","style:wrap-contour":"false","style:vertical-pos":"top","style:vertical-rel":"paragraph","style:horizontal-pos":"center","style:horizontal-rel":"paragraph"}}}),g.push(a));a=f.generateStyleName();d=new ops.OpAddStyle;d.init({memberid:h,styleName:a,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"}}}); +g.push(d);t=new ops.OpInsertImage;t.init({memberid:h,position:p.getCursorPosition(h),filename:l,frameWidth:q+"cm",frameHeight:k+"cm",frameStyleName:a,frameName:f.generateFrameName()});g.push(t);e.enqueue(g)}}; +// Input 74 +runtime.loadClass("odf.Namespaces"); +gui.ImageSelector=function(e){function h(){var c=e.getSizer(),b,a;b=m.createElement("div");b.id="imageSelector";b.style.borderWidth="1px";c.appendChild(b);n.forEach(function(c){a=m.createElement("div");a.className=c;b.appendChild(a)});return b}var f=odf.Namespaces.svgns,n="topLeft topRight bottomRight bottomLeft topMiddle rightMiddle bottomMiddle leftMiddle".split(" "),m=e.getElement().ownerDocument,p=!1;this.select=function(c){var b,a,d=m.getElementById("imageSelector");d||(d=h());p=!0;b=d.parentNode; +a=c.getBoundingClientRect();var k=b.getBoundingClientRect(),g=e.getZoomLevel();b=(a.left-k.left)/g-1;a=(a.top-k.top)/g-1;d.style.display="block";d.style.left=b+"px";d.style.top=a+"px";d.style.width=c.getAttributeNS(f,"width");d.style.height=c.getAttributeNS(f,"height")};this.clearSelection=function(){var c;p&&(c=m.getElementById("imageSelector"))&&(c.style.display="none");p=!1};this.isSelectorElement=function(c){var b=m.getElementById("imageSelector");return b?c===b||c.parentNode===b:!1}}; +// Input 75 /* Copyright (C) 2013 KO GmbH @@ -1914,6 +2242,9 @@ b);l.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,k);l.unsubscribe(o 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 @@ -1934,40 +2265,90 @@ b);l.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,k);l.unsubscribe(o This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -gui.TextManipulator=function(h,m){function f(a){var b=new ops.OpRemoveText;b.init({memberid:m,position:a.position,length:a.length});return b}function a(a){0>a.length&&(a.position+=a.length,a.length=-a.length);return a}var c=h.getOdtDocument();this.enqueueParagraphSplittingOps=function(){var d=a(c.getCursorSelection(m)),b;0c.length&&(c.position+=c.length,c.length=-c.length);return c}var p=e.getOdtDocument();this.enqueueParagraphSplittingOps=function(){var c=m(p.getCursorSelection(h)),b,a=[];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(e,h){function f(){var b=c.getCursor(h),b=b&&b.getNode(),e;if(e=b){a:{for(e=c.getRootNode();b&&b!==e;){if(b.namespaceURI===k&&"annotation"===b.localName){b=!0;break a}b=b.parentNode}b=!1}e=!b}b=e;b!==a&&(a=b,d.emit(gui.AnnotationManager.annotatableChanged,a))}function n(a){a.getMemberId()===h&&f()}function m(a){a===h&&f()}function p(a){a.getMemberId()===h&&f()}var c=e.getOdtDocument(),b=c.getPositionFilter(),a=!1,d=new core.EventNotifier([gui.AnnotationManager.annotatableChanged]), +k=odf.Namespaces.officens,g=core.PositionFilter.FilterResult.FILTER_ACCEPT;this.isAnnotatable=function(){return a};this.addAnnotation=function(){var b=new ops.OpAddAnnotation,d=c.getCursorSelection(h),f=d.length,d=d.position;a&&(d=0<=f?d:d+f,f=Math.abs(f),b.init({memberid:h,position:d,length:f,name:h+Date.now()}),e.enqueue([b]))};this.removeAnnotation=function(a){var d,f;d=0;f=gui.SelectionMover.createPositionIterator(c.getRootNode());for(var k=new core.LoopWatchDog(1E3),m=!1;f.nextPosition();)if(k.check(), +m=Boolean(a.compareDocumentPosition(f.container())&Node.DOCUMENT_POSITION_CONTAINED_BY),b.acceptPosition(f)===g){if(m)break;d+=1}f=0;k=gui.SelectionMover.createPositionIterator(c.getRootNode());m=!1;k.setUnfilteredPosition(a,0);do{m=Boolean(a.compareDocumentPosition(k.container())&Node.DOCUMENT_POSITION_CONTAINED_BY);if(!m&&a!==k.container())break;b.acceptPosition(k)===g&&(f+=1)}while(k.nextPosition());a=new ops.OpRemoveAnnotation;a.init({memberid:h,position:d,length:f});f=new ops.OpMoveCursor;f.init({memberid:h, +position:d-1,length:0});e.enqueue([a,f])};this.subscribe=function(a,b){d.subscribe(a,b)};this.unsubscribe=function(a,b){d.unsubscribe(a,b)};this.destroy=function(a){c.unsubscribe(ops.OdtDocument.signalCursorAdded,n);c.unsubscribe(ops.OdtDocument.signalCursorRemoved,m);c.unsubscribe(ops.OdtDocument.signalCursorMoved,p);a()};c.subscribe(ops.OdtDocument.signalCursorAdded,n);c.subscribe(ops.OdtDocument.signalCursorRemoved,m);c.subscribe(ops.OdtDocument.signalCursorMoved,p);f()}; +gui.AnnotationManager.annotatableChanged="annotatable/changed";(function(){return gui.AnnotationManager})(); +// Input 77 +gui.EventManager=function(e){function h(a){var b=a.scrollX,c=a.scrollY;this.restore=function(){a.scrollX===b&&a.scrollY===c||a.scrollTo(b,c)}}function f(a){var b=a.scrollTop,c=a.scrollLeft;this.restore=function(){if(a.scrollTop!==b||a.scrollLeft!==c)a.scrollTop=b,a.scrollLeft=c}}function n(){return e.getDOM().activeElement===m}var m=e.getOdfCanvas().getElement(),p=runtime.getWindow(),c={beforecut:!0,beforepaste:!0},b={mousedown:!0,mouseup:!0};this.subscribe=function(a,d){var e=m;b[a]&&p&&(e=p);var f= +"on"+a,h=!1;e.attachEvent&&(h=e.attachEvent(f,d));!h&&e.addEventListener&&(e.addEventListener(a,d,!1),h=!0);h&&!c[a]||!e.hasOwnProperty(f)||(e[f]=d)};this.unsubscribe=function(a,c){var e=m;b[a]&&p&&(e=p);var f="on"+a;e.detachEvent&&e.detachEvent(f,c);e.removeEventListener&&e.removeEventListener(a,c,!1);e[f]===c&&(e[f]=null)};this.hasFocus=n;this.focus=function(){var a;if(!n()){for(a=m;a&&!a.scrollTop&&!a.scrollLeft;)a=a.parentNode;a=a?new f(a):p?new h(p):null;m.focus();a&&a.restore()}}}; +// Input 78 +runtime.loadClass("core.DomUtils");runtime.loadClass("core.Async");runtime.loadClass("core.ScheduledTask");runtime.loadClass("odf.OdfUtils");runtime.loadClass("odf.ObjectNameGenerator");runtime.loadClass("ops.OdtCursor");runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("gui.Clipboard");runtime.loadClass("gui.DirectTextStyler");runtime.loadClass("gui.DirectParagraphStyler");runtime.loadClass("gui.KeyboardHandler");runtime.loadClass("gui.ImageManager"); +runtime.loadClass("gui.ImageSelector");runtime.loadClass("gui.TextManipulator");runtime.loadClass("gui.AnnotationManager");runtime.loadClass("gui.EventManager"); +gui.SessionController=function(){var e=core.PositionFilter.FilterResult.FILTER_ACCEPT;gui.SessionController=function(h,f,n,m){function p(a){a.preventDefault?a.preventDefault():a.returnValue=!1}function c(a,b,c){var d=new ops.OpMoveCursor;d.init({memberid:f,position:a,length:b||0,selectionType:c});return d}function b(a){var b=F.getOdfCanvas().getElement(),c=F.getRootNode(),d=0;b.compareDocumentPosition(a)&Node.DOCUMENT_POSITION_PRECEDING||(a=gui.SelectionMover.createPositionIterator(c),a.moveToEnd(), +c=a.container(),d=a.unfilteredDomOffset());return{node:c,offset:d}}function a(a){a=F.getDistanceFromCursor(f,a,0);var b=null!==a?a+1:null,d;if(b||a)d=F.getCursorPosition(f),a=c(d+a,b-a,ops.OdtCursor.RegionSelection),h.enqueue([a]);X.focus()}function d(a,d){var e,g,k,l;g=F.getOdfCanvas().getElement();e=d.detail;if(a){if(!a.anchorNode&&!a.focusNode){k=d.clientX;l=d.clientY;var m=F.getDOM();m.caretRangeFromPoint?(k=m.caretRangeFromPoint(k,l),k={container:k.startContainer,offset:k.startOffset}):m.caretPositionFromPoint? +(k=m.caretPositionFromPoint(k,l),k={container:k.offsetNode,offset:k.offset}):k=null;if(!k)return;a.anchorNode=k.container;a.anchorOffset=k.offset;a.focusNode=a.anchorNode;a.focusOffset=a.anchorOffset}runtime.assert(null!==a.anchorNode&&null!==a.focusNode,"anchorNode or focusNode is null");k=Y.containsNode(g,a.anchorNode);g=Y.containsNode(g,a.focusNode);if(k||g){k||(k=b(a.anchorNode),a.anchorNode=k.node,a.anchorOffset=k.offset);g||(k=b(a.focusNode),a.focusNode=k.node,a.focusOffset=k.offset);if(2=== +e){var m=/[A-Za-z0-9]/,n=gui.SelectionMover.createPositionIterator(F.getRootNode()),p=0 @@ -1980,6 +2361,9 @@ A.bind(c.Z,b.Meta,P),A.bind(c.Z,b.MetaShift,$)):(A.bind(c.A,b.Ctrl,aa),ha&&(A.bi 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 @@ -2000,10 +2384,10 @@ A.bind(c.Z,b.Meta,P),A.bind(c.Z,b.MetaShift,$)):(A.bind(c.A,b.Ctrl,aa),ha&&(A.bi This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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 70 +ops.MemberModel=function(){};ops.MemberModel.prototype.getMemberDetailsAndUpdates=function(e,h){};ops.MemberModel.prototype.unsubscribeMemberDetailsUpdates=function(e,h){};ops.MemberModel.prototype.close=function(e){}; +// Input 80 /* Copyright (C) 2012-2013 KO GmbH @@ -2016,6 +2400,9 @@ ops.MemberModel=function(){};ops.MemberModel.prototype.getMemberDetailsAndUpdate 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 @@ -2036,10 +2423,10 @@ ops.MemberModel=function(){};ops.MemberModel.prototype.getMemberDetailsAndUpdate This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.TrivialMemberModel=function(){this.getMemberDetailsAndUpdates=function(h,m){m(h,{memberid:h,fullname:"Unknown",color:"black",imageurl:"avatar-joe.png"})};this.unsubscribeMemberDetailsUpdates=function(h,m){};this.close=function(h){h()}}; -// Input 71 +ops.TrivialMemberModel=function(){this.getMemberDetailsAndUpdates=function(e,h){h(e,{memberid:e,fullname:runtime.tr("Unknown Author"),color:"black",imageurl:"avatar-joe.png"})};this.unsubscribeMemberDetailsUpdates=function(e,h){};this.close=function(e){e()}}; +// Input 81 /* Copyright (C) 2013 KO GmbH @@ -2052,6 +2439,9 @@ ops.TrivialMemberModel=function(){this.getMemberDetailsAndUpdates=function(h,m){ 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 @@ -2072,10 +2462,10 @@ ops.TrivialMemberModel=function(){this.getMemberDetailsAndUpdates=function(h,m){ This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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){};ops.OperationRouter.prototype.getHasLocalUnsyncedOpsAndUpdates=function(h){};ops.OperationRouter.prototype.unsubscribeHasLocalUnsyncedOpsUpdates=function(h){}; -// Input 72 +ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFactory=function(e){};ops.OperationRouter.prototype.setPlaybackFunction=function(e){};ops.OperationRouter.prototype.push=function(e){};ops.OperationRouter.prototype.close=function(e){}; +// Input 82 /* Copyright (C) 2012 KO GmbH @@ -2088,6 +2478,9 @@ ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFacto 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 @@ -2108,13 +2501,13 @@ ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFacto This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -ops.TrivialOperationRouter=function(){var h,m;this.setOperationFactory=function(f){h=f};this.setPlaybackFunction=function(f){m=f};this.push=function(f){f=f.spec();f.timestamp=(new Date).getTime();f=h.create(f);m(f)};this.close=function(f){f()};this.getHasLocalUnsyncedOpsAndUpdates=function(f){f(!0)};this.unsubscribeHasLocalUnsyncedOpsUpdates=function(f){}}; -// Input 73 -gui.EditInfoHandle=function(h){var m=[],f,a=h.ownerDocument,c=a.documentElement.namespaceURI;this.setEdits=function(d){m=d;var b,k,h,e;f.innerHTML="";for(d=0;d @@ -2127,6 +2520,9 @@ e=a.createElementNS(c,"span"),e.className="editInfoTime",e.setAttributeNS("urn:w 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 @@ -2147,13 +2543,13 @@ e=a.createElementNS(c,"span"),e.className="editInfoTime",e.setAttributeNS("urn:w This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("ops.EditInfo");runtime.loadClass("gui.EditInfoHandle"); -gui.EditInfoMarker=function(h,m){function f(a,c){return runtime.getWindow().setTimeout(function(){b.style.opacity=a},c)}var a=this,c,d,b,k,p;this.addEdit=function(a,c){var m=Date.now()-c;h.addEdit(a,c);d.setEdits(h.getSortedEdits());b.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",a);if(k){var g=k;runtime.getWindow().clearTimeout(g)}p&&(g=p,runtime.getWindow().clearTimeout(g));1E4>m?(f(1,0),k=f(0.5,1E4-m),p=f(0.2,2E4-m)):1E4<=m&&2E4>m?(f(0.5,0),p=f(0.2,2E4-m)):f(0.2,0)};this.getEdits= -function(){return h.getEdits()};this.clearEdits=function(){h.clearEdits();d.setEdits([]);b.hasAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")&&b.removeAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")};this.getEditInfo=function(){return h};this.show=function(){b.style.display="block"};this.hide=function(){a.hideHandle();b.style.display="none"};this.showHandle=function(){d.show()};this.hideHandle=function(){d.hide()};this.destroy=function(a){c.removeChild(b);d.destroy(function(b){b? -a(b):h.destroy(a)})};(function(){var e=h.getOdtDocument().getDOM();b=e.createElementNS(e.documentElement.namespaceURI,"div");b.setAttribute("class","editInfoMarker");b.onmouseover=function(){a.showHandle()};b.onmouseout=function(){a.hideHandle()};c=h.getNode();c.appendChild(b);d=new gui.EditInfoHandle(c);m||a.hide()})()}; -// Input 75 +gui.EditInfoMarker=function(e,h){function f(a,b){return runtime.setTimeout(function(){c.style.opacity=a},b)}var n=this,m,p,c,b,a;this.addEdit=function(d,h){var g=Date.now()-h;e.addEdit(d,h);p.setEdits(e.getSortedEdits());c.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",d);b&&runtime.clearTimeout(b);a&&runtime.clearTimeout(a);1E4>g?(f(1,0),b=f(0.5,1E4-g),a=f(0.2,2E4-g)):1E4<=g&&2E4>g?(f(0.5,0),a=f(0.2,2E4-g)):f(0.2,0)};this.getEdits=function(){return e.getEdits()};this.clearEdits=function(){e.clearEdits(); +p.setEdits([]);c.hasAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")&&c.removeAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")};this.getEditInfo=function(){return e};this.show=function(){c.style.display="block"};this.hide=function(){n.hideHandle();c.style.display="none"};this.showHandle=function(){p.show()};this.hideHandle=function(){p.hide()};this.destroy=function(a){m.removeChild(c);p.destroy(function(b){b?a(b):e.destroy(a)})};(function(){var a=e.getOdtDocument().getDOM(); +c=a.createElementNS(a.documentElement.namespaceURI,"div");c.setAttribute("class","editInfoMarker");c.onmouseover=function(){n.showHandle()};c.onmouseout=function(){n.hideHandle()};m=e.getNode();m.appendChild(c);p=new gui.EditInfoHandle(m);h||n.hide()})()}; +// Input 85 /* Copyright (C) 2012-2013 KO GmbH @@ -2166,6 +2562,9 @@ a(b):h.destroy(a)})};(function(){var e=h.getOdtDocument().getDOM();b=e.createEle 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 @@ -2186,17 +2585,19 @@ a(b):h.destroy(a)})};(function(){var e=h.getOdtDocument().getDOM();b=e.createEle This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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,f){function a(a,b,c){function d(b,c,e){c=b+'[editinfo|memberid^="'+a+'"]'+e+c;a:{var g=s.firstChild;for(b=b+'[editinfo|memberid^="'+a+'"]'+e;g;){if(g.nodeType===Node.TEXT_NODE&&0===g.data.indexOf(b)){b=g;break a}g=g.nextSibling}b=null}b?b.data=c:s.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+"; }","")}function c(a){var b,c;for(c in g)g.hasOwnProperty(c)&&(b=g[c],a?b.show():b.hide())}function d(a){f.getCarets().forEach(function(b){a?b.showHandle():b.hideHandle()})}function b(b,c){var d=f.getCaret(b);c?(d&&(d.setAvatarImageUrl(c.imageurl),d.setColor(c.color)),a(b,c.fullname,c.color)):runtime.log('MemberModel sent undefined data for member "'+b+'".')}function k(a){var c=a.getMemberId(), -d=m.getMemberModel();f.registerCursor(a,u,q);b(c,null);d.getMemberDetailsAndUpdates(c,b);runtime.log("+++ View here +++ eagerly created an Caret for '"+c+"'! +++")}function p(a){var c=!1,d;for(d in g)if(g.hasOwnProperty(d)&&g[d].getEditInfo().getEdits().hasOwnProperty(a)){c=!0;break}c||m.getMemberModel().unsubscribeMemberDetailsUpdates(a,b)}function e(a){var b=a.paragraphElement,c=a.memberId;a=a.timeStamp;var d,e="",f=b.getElementsByTagNameNS(n,"editinfo")[0];f?(e=f.getAttributeNS(n,"id"),d=g[e]): -(e=Math.random().toString(),d=new ops.EditInfo(b,m.getOdtDocument()),d=new gui.EditInfoMarker(d,l),f=b.getElementsByTagNameNS(n,"editinfo")[0],f.setAttributeNS(n,"id",e),g[e]=d);d.addEdit(c,new Date(a))}var s,n="urn:webodf:names:editinfo",g={},l=void 0!==h.editInfoMarkersInitiallyVisible?Boolean(h.editInfoMarkersInitiallyVisible):!0,u=void 0!==h.caretAvatarsInitiallyVisible?Boolean(h.caretAvatarsInitiallyVisible):!0,q=void 0!==h.caretBlinksOnRangeSelect?Boolean(h.caretBlinksOnRangeSelect):!0;this.showEditInfoMarkers= -function(){l||(l=!0,c(l))};this.hideEditInfoMarkers=function(){l&&(l=!1,c(l))};this.showCaretAvatars=function(){u||(u=!0,d(u))};this.hideCaretAvatars=function(){u&&(u=!1,d(u))};this.getSession=function(){return m};this.getCaret=function(a){return f.getCaret(a)};this.destroy=function(a){var c=m.getOdtDocument(),d=m.getMemberModel(),h=Object.keys(g).map(function(a){return g[a]});c.unsubscribe(ops.OdtDocument.signalCursorAdded,k);c.unsubscribe(ops.OdtDocument.signalCursorRemoved,p);c.unsubscribe(ops.OdtDocument.signalParagraphChanged, -e);f.getCarets().forEach(function(a){d.unsubscribeMemberDetailsUpdates(a.getCursor().getMemberId(),b)});s.parentNode.removeChild(s);(function v(b,c){c?a(c):b @@ -2209,6 +2610,9 @@ s.type="text/css";s.media="screen, print, handheld, projection";s.appendChild(do 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 @@ -2229,31 +2633,14 @@ s.type="text/css";s.media="screen, print, handheld, projection";s.appendChild(do This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("gui.Caret"); -gui.CaretManager=function(h){function m(a){return n.hasOwnProperty(a)?n[a]:null}function f(){return Object.keys(n).map(function(a){return n[a]})}function a(){return h.getSession().getOdtDocument().getOdfCanvas().getElement()}function c(b){b===h.getInputMemberId()&&a().removeAttribute("tabindex");delete n[b]}function d(a){a=a.getMemberId();a===h.getInputMemberId()&&(a=m(a))&&a.refreshCursorBlinking()}function b(a){a.memberId===h.getInputMemberId()&&(a=m(a.memberId))&&a.ensureVisible()}function k(){var a= -m(h.getInputMemberId());a&&a.setFocus()}function p(){var a=m(h.getInputMemberId());a&&a.removeFocus()}function e(){var a=m(h.getInputMemberId());a&&a.show()}function s(){var a=m(h.getInputMemberId());a&&a.hide()}var n={},g=runtime.getWindow();this.registerCursor=function(b,c,d){var e=b.getMemberId(),g=a();c=new gui.Caret(b,c,d);n[e]=c;e===h.getInputMemberId()&&(runtime.log("Starting to track input on new cursor of "+e),b.handleUpdate=c.ensureVisible,g.setAttribute("tabindex",0),g.focus());return c}; -this.getCaret=m;this.getCarets=f;this.destroy=function(l){var m=h.getSession().getOdtDocument(),q=a(),n=f();m.unsubscribe(ops.OdtDocument.signalParagraphChanged,b);m.unsubscribe(ops.OdtDocument.signalCursorMoved,d);m.unsubscribe(ops.OdtDocument.signalCursorRemoved,c);q.removeEventListener("focus",k,!1);q.removeEventListener("blur",p,!1);g.removeEventListener("focus",e,!1);g.removeEventListener("blur",s,!1);(function y(a,b){b?l(b):aa?-1:a-1})};a.slideChange=function(c){var d=a.getPages(a.odf_canvas.odfContainer().rootElement),b=-1,f=0;d.forEach(function(a){a=a[1];a.hasAttribute("slide_current")&&(b=f,a.removeAttribute("slide_current"));f+=1});c=c(b,d.length);-1===c&&(c=b);d[c][1].setAttribute("slide_current", -"1");document.getElementById("pagelist").selectedIndex=c;"cont"===a.slide_mode&&m.scrollBy(0,d[c][1].getBoundingClientRect().top-30)};a.selectSlide=function(c){a.slideChange(function(a,b){return c>=b||0>c?-1:c})};a.scrollIntoContView=function(c){var d=a.getPages(a.odf_canvas.odfContainer().rootElement);0!==d.length&&m.scrollBy(0,d[c][1].getBoundingClientRect().top-30)};a.getPages=function(a){a=a.getElementsByTagNameNS(odf.Namespaces.drawns,"page");var d=[],b;for(b=0;b=a.rangeCount||!u)||(a=a.getRangeAt(0),u.setPoint(a.startContainer,a.startOffset))}function d(){var a=h.ownerDocument.defaultView.getSelection(),b,c;a.removeAllRanges();u&&u.node()&&(b=u.node(),c=b.ownerDocument.createRange(), -c.setStart(b,u.position()),c.collapse(!0),a.addRange(c))}function b(b){var e=b.charCode||b.keyCode;if(u=null,u&&37===e)c(),u.stepBackward(),d();else if(16<=e&&20>=e||33<=e&&40>=e)return;a(b)}function k(b){a(b)}function p(a){for(var b=a.firstChild;b&&b!==a;)b.nodeType===Node.ELEMENT_NODE&&p(b),b=b.nextSibling||b.parentNode;var c,d,e,b=a.attributes;c="";for(e=b.length-1;0<=e;e-=1)d=b.item(e),c=c+" "+d.nodeName+'="'+d.nodeValue+'"';a.setAttribute("customns_name",a.nodeName);a.setAttribute("customns_atts", -c);b=a.firstChild;for(d=/^\s*$/;b&&b!==a;)c=b,b=b.nextSibling||b.parentNode,c.nodeType===Node.TEXT_NODE&&d.test(c.nodeValue)&&c.parentNode.removeChild(c)}function e(a,b){for(var c=a.firstChild,d,f,g;c&&c!==a;){if(c.nodeType===Node.ELEMENT_NODE)for(e(c,b),d=c.attributes,g=d.length-1;0<=g;g-=1)f=d.item(g),"http://www.w3.org/2000/xmlns/"!==f.namespaceURI||b[f.nodeValue]||(b[f.nodeValue]=f.localName);c=c.nextSibling||c.parentNode}}function s(){var a=h.ownerDocument.createElement("style"),b;b={};e(h,b); -var c={},d,f,g=0;for(d in b)if(b.hasOwnProperty(d)&&d){f=b[d];if(!f||c.hasOwnProperty(f)||"xmlns"===f){do f="ns"+g,g+=1;while(c.hasOwnProperty(f));b[d]=f}c[f]=!0}a.type="text/css";b="@namespace customns url(customns);\n"+n;a.appendChild(h.ownerDocument.createTextNode(b));m=m.parentNode.replaceChild(a,m)}var n,g,l,u=null;h.id||(h.id="xml"+String(Math.random()).substring(2));g="#"+h.id+" ";n=g+"*,"+g+":visited, "+g+":link {display:block; margin: 0px; margin-left: 10px; font-size: medium; color: black; background: white; font-variant: normal; font-weight: normal; font-style: normal; font-family: sans-serif; text-decoration: none; white-space: pre-wrap; height: auto; width: auto}\n"+ -g+":before {color: blue; content: '<' attr(customns_name) attr(customns_atts) '>';}\n"+g+":after {color: blue; content: '';}\n"+g+"{overflow: auto;}\n";(function(c){f(c,"click",k);f(c,"keydown",b);f(c,"drop",a);f(c,"dragend",a);f(c,"beforepaste",a);f(c,"paste",a)})(h);this.updateCSS=s;this.setXML=function(a){a=a.documentElement||a;l=a=h.ownerDocument.importNode(a,!0);for(p(a);h.lastChild;)h.removeChild(h.lastChild);h.appendChild(a);s();u=new core.PositionIterator(a)};this.getXML= -function(){return l}}; -// Input 79 +gui.CaretManager=function(e){function h(a){return q.hasOwnProperty(a)?q[a]:null}function f(){return Object.keys(q).map(function(a){return q[a]})}function n(a){a===e.getInputMemberId()&&e.getSession().getOdtDocument().getOdfCanvas().getElement().removeAttribute("tabindex");delete q[a]}function m(a){a=a.getMemberId();a===e.getInputMemberId()&&(a=h(a))&&a.refreshCursorBlinking()}function p(){var a=h(e.getInputMemberId());r=!1;a&&a.ensureVisible()}function c(){var a=h(e.getInputMemberId());a&&(a.handleUpdate(), +r||(r=!0,runtime.setTimeout(p,50)))}function b(a){a.memberId===e.getInputMemberId()&&c()}function a(){var a=h(e.getInputMemberId());a&&a.setFocus()}function d(){var a=h(e.getInputMemberId());a&&a.removeFocus()}function k(){var a=h(e.getInputMemberId());a&&a.show()}function g(){var a=h(e.getInputMemberId());a&&a.hide()}var q={},l=runtime.getWindow(),r=!1;this.registerCursor=function(a,b,d){var f=a.getMemberId();b=new gui.Caret(a,b,d);q[f]=b;f===e.getInputMemberId()?(runtime.log("Starting to track input on new cursor of "+ +f),a.handleUpdate=c,e.getSession().getOdtDocument().getOdfCanvas().getElement().setAttribute("tabindex",-1),e.getEventManager().focus()):a.handleUpdate=b.handleUpdate;return b};this.getCaret=h;this.getCarets=f;this.destroy=function(c){var h=e.getSession().getOdtDocument(),p=e.getEventManager(),r=f();h.unsubscribe(ops.OdtDocument.signalParagraphChanged,b);h.unsubscribe(ops.OdtDocument.signalCursorMoved,m);h.unsubscribe(ops.OdtDocument.signalCursorRemoved,n);p.unsubscribe("focus",a);p.unsubscribe("blur", +d);l.removeEventListener("focus",k,!1);l.removeEventListener("blur",g,!1);(function u(a,b){b?c(b):a @@ -2266,6 +2653,9 @@ function(){return l}}; 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 @@ -2286,11 +2676,11 @@ function(){return l}}; This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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 80 +gui.UndoManager=function(){};gui.UndoManager.prototype.subscribe=function(e,h){};gui.UndoManager.prototype.unsubscribe=function(e,h){};gui.UndoManager.prototype.setOdtDocument=function(e){};gui.UndoManager.prototype.saveInitialState=function(){};gui.UndoManager.prototype.resetInitialState=function(){};gui.UndoManager.prototype.setPlaybackFunction=function(e){};gui.UndoManager.prototype.hasUndoStates=function(){};gui.UndoManager.prototype.hasRedoStates=function(){}; +gui.UndoManager.prototype.moveForward=function(e){};gui.UndoManager.prototype.moveBackward=function(e){};gui.UndoManager.prototype.onOperationExecuted=function(e){};gui.UndoManager.signalUndoStackChanged="undoStackChanged";gui.UndoManager.signalUndoStateCreated="undoStateCreated";gui.UndoManager.signalUndoStateModified="undoStateModified";(function(){return gui.UndoManager})(); +// Input 88 /* Copyright (C) 2013 KO GmbH @@ -2303,6 +2693,9 @@ gui.UndoManager.prototype.moveForward=function(h){};gui.UndoManager.prototype.mo 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 @@ -2323,11 +2716,11 @@ gui.UndoManager.prototype.moveForward=function(h){};gui.UndoManager.prototype.mo This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ -gui.UndoStateRules=function(){function h(f){return f.spec().optype}function m(f){switch(h(f)){case "MoveCursor":case "AddCursor":case "RemoveCursor":return!1;default:return!0}}this.getOpType=h;this.isEditOperation=m;this.isPartOfOperationSet=function(f,a){if(m(f)){if(0===a.length)return!0;var c;if(c=m(a[a.length-1]))a:{c=a.filter(m);var d=h(f),b;b:switch(d){case "RemoveText":case "InsertText":b=!0;break b;default:b=!1}if(b&&d===h(c[0])){if(1===c.length){c=!0;break a}d=c[c.length-2].spec().position; -c=c[c.length-1].spec().position;b=f.spec().position;if(c===b-(c-d)){c=!0;break a}}c=!1}return c}return!0}}; -// Input 81 +gui.UndoStateRules=function(){function e(e){return e.spec().optype}function h(f){switch(e(f)){case "MoveCursor":case "AddCursor":case "RemoveCursor":return!1;default:return!0}}this.getOpType=e;this.isEditOperation=h;this.isPartOfOperationSet=function(f,n){if(h(f)){if(0===n.length)return!0;var m;if(m=h(n[n.length-1]))a:{m=n.filter(h);var p=e(f),c;b:switch(p){case "RemoveText":case "InsertText":c=!0;break b;default:c=!1}if(c&&p===e(m[0])){if(1===m.length){m=!0;break a}p=m[m.length-2].spec().position; +m=m[m.length-1].spec().position;c=f.spec().position;if(m===c-(m-p)){m=!0;break a}}m=!1}return m}return!0}}; +// Input 89 /* Copyright (C) 2013 KO GmbH @@ -2340,6 +2733,9 @@ c=c[c.length-1].spec().position;b=f.spec().position;if(c===b-(c-d)){c=!0;break a 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 @@ -2360,16 +2756,69 @@ c=c[c.length-1].spec().position;b=f.spec().position;if(c===b-(c-d)){c=!0;break a This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @source: https://github.com/kogmbh/WebODF/ */ runtime.loadClass("core.DomUtils");runtime.loadClass("gui.UndoManager");runtime.loadClass("gui.UndoStateRules"); -gui.TrivialUndoManager=function(h){function m(){q.emit(gui.UndoManager.signalUndoStackChanged,{undoAvailable:b.hasUndoStates(),redoAvailable:b.hasRedoStates()})}function f(){g!==e&&g!==l[l.length-1]&&l.push(g)}function a(a){var b=a.previousSibling||a.nextSibling;a.parentNode.removeChild(a);k.normalizeTextNodes(b)}function c(a){return Object.keys(a).map(function(b){return a[b]})}function d(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,k=a.pop();n.getCursors().forEach(function(a){f[a.getMemberId()]=!0});for(g=Object.keys(f).length;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("gui.SelectionView"); +gui.SelectionViewManager=function(){function e(){return Object.keys(h).map(function(e){return h[e]})}var h={};this.getSelectionView=function(e){return h.hasOwnProperty(e)?h[e]:null};this.getSelectionViews=e;this.removeSelectionView=function(e){h.hasOwnProperty(e)&&(h[e].destroy(function(){}),delete h[e])};this.hideSelectionView=function(e){h.hasOwnProperty(e)&&h[e].hide()};this.showSelectionView=function(e){h.hasOwnProperty(e)&&h[e].show()};this.rerenderSelectionViews=function(){Object.keys(h).forEach(function(e){h[e].visible()&& +h[e].rerender()})};this.registerCursor=function(e,n){var m=e.getMemberId(),p=new gui.SelectionView(e);n?p.show():p.hide();return h[m]=p};this.destroy=function(f){var h=e();(function p(c,b){b?f(b):c @@ -2382,6 +2831,9 @@ b.refreshCSS(),g=l[l.length-1]||e,m());return d}};gui.TrivialUndoManager.signalD 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 @@ -2402,27 +2854,27 @@ b.refreshCSS(),g=l[l.length-1]||e,m());return d}};gui.TrivialUndoManager.signalD This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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("gui.StyleHelper");runtime.loadClass("core.PositionFilterChain"); -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 f(a){function b(a){for(;!(a.namespaceURI===odf.Namespaces.officens&&"text"===a.localName||a.namespaceURI===odf.Namespaces.officens&&"annotation"===a.localName);)a=a.parentNode;return a}this.acceptPosition=function(c){c=c.container();var d=s[a].getNode();return b(c)===b(d)?g:l}}function a(a){var b= -gui.SelectionMover.createPositionIterator(m());for(a+=1;0=e;e+=1){c=b.container();d=b.unfilteredDomOffset();if(c.nodeType===Node.TEXT_NODE&& -" "===c.data[d]&&p.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= 0");u.acceptPosition(c)===g?(e=c.container(),e.nodeType===Node.TEXT_NODE&&(d=e,f=0)):a+=1;for(;0=e;e+=1){c=b.container();d=b.unfilteredDomOffset(); +if(c.nodeType===Node.TEXT_NODE&&" "===c.data[d]&&a.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= 0");r.acceptPosition(d)===q?(f=d.container(),f.nodeType===Node.TEXT_NODE&&(e=f,g=0)):a+=1;for(;0 @@ -2435,6 +2887,9 @@ ops.OdtDocument.signalCursorRemoved="cursor/removed";ops.OdtDocument.signalCurso 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 @@ -2455,10 +2910,10 @@ ops.OdtDocument.signalCursorRemoved="cursor/removed";ops.OdtDocument.signalCurso This license applies to this entire compilation. @licend @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ + @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,f=new ops.OdtDocument(h),a=new ops.TrivialMemberModel,c=null;this.setMemberModel=function(c){a=c};this.setOperationFactory=function(a){m=a;c&&c.setOperationFactory(m)};this.setOperationRouter=function(a){c=a;a.setPlaybackFunction(function(a){a.execute(f);f.emit(ops.OdtDocument.signalOperationExecuted,a)});a.setOperationFactory(m)};this.getMemberModel=function(){return a};this.getOperationFactory=function(){return m};this.getOdtDocument=function(){return f}; -this.enqueue=function(a){c.push(a)};this.close=function(d){c.close(function(b){b?d(b):a.close(function(a){a?d(a):f.close(d)})})};this.destroy=function(a){f.destroy(a)};this.setOperationRouter(new ops.TrivialOperationRouter)}; -// Input 84 -var webodf_css="@namespace draw url(urn:oasis:names:tc:opendocument:xmlns:drawing:1.0);\n@namespace fo url(urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0);\n@namespace office url(urn:oasis:names:tc:opendocument:xmlns:office:1.0);\n@namespace presentation url(urn:oasis:names:tc:opendocument:xmlns:presentation:1.0);\n@namespace style url(urn:oasis:names:tc:opendocument:xmlns:style:1.0);\n@namespace svg url(urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0);\n@namespace table url(urn:oasis:names:tc:opendocument:xmlns:table:1.0);\n@namespace text url(urn:oasis:names:tc:opendocument:xmlns:text:1.0);\n@namespace runtimens url(urn:webodf); /* namespace for runtime only */\n@namespace cursor url(urn:webodf:names:cursor);\n@namespace editinfo url(urn:webodf:names:editinfo);\n@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*[runtimens|containsparagraphanchor] {\n position: relative;\n}\ntext|s {\n white-space: pre;\n}\ntext|tab {\n display: inline;\n white-space: pre;\n}\ntext|line-break {\n content: \" \";\n display: block;\n}\ntext|tracked-changes {\n /*Consumers that do not support change tracking, should ignore changes.*/\n display: none;\n}\noffice|binary-data {\n display: none;\n}\noffice|text {\n display: block;\n text-align: left;\n overflow: visible;\n word-wrap: break-word;\n}\n\noffice|text::selection {\n /** Let's not draw selection highlight that overflows into the office|text\n * node when selecting content across several paragraphs\n */\n background: transparent;\n}\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 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"; +ops.Session=function(e){var h=new ops.OperationFactory,f=new ops.OdtDocument(e),n=new ops.TrivialMemberModel,m=null;this.setMemberModel=function(e){n=e};this.setOperationFactory=function(e){h=e;m&&m.setOperationFactory(h)};this.setOperationRouter=function(e){m=e;e.setPlaybackFunction(function(c){c.execute(f);f.emit(ops.OdtDocument.signalOperationExecuted,c)});e.setOperationFactory(h)};this.getMemberModel=function(){return n};this.getOperationFactory=function(){return h};this.getOdtDocument=function(){return f}; +this.enqueue=function(e){m.push(e)};this.close=function(e){m.close(function(c){c?e(c):n.close(function(b){b?e(b):f.close(e)})})};this.destroy=function(e){f.destroy(e)};this.setOperationRouter(new ops.TrivialOperationRouter)}; +// Input 94 +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"; diff --git a/js/documents.js b/js/documents.js index 1ecb9a5d..30c9d581 100644 --- a/js/documents.js +++ b/js/documents.js @@ -167,7 +167,9 @@ var documentsMain = { var serverFactory = new ServerFactory(); documentsMain.esId = response.es_id; documentsMain.memberId = response.member_id; - + + // TODO: set webodf translation system, by passing a proper function translate(!string):!string in "runtime.setTranslator(translate);" + documentsMain.webodfServerInstance = serverFactory.createServer(); documentsMain.webodfServerInstance.setToken(oc_requesttoken); documentsMain.webodfEditorInstance = new Editor({unstableFeaturesEnabled: documentsMain.useUnstable}, documentsMain.webodfServerInstance, serverFactory);