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]); + EditorSession.signalUndoStackChanged]), + shadowCursor = new gui.ShadowCursor(odtDocument); - - 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 = []; - - /* - * @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(); - // apply locally - opspec.timestamp = (new Date()).getTime(); - timedOp = operationFactory.create(opspec); + // 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); - playbackFunction(timedOp); + // apply locally + opspec.timestamp = (new Date()).getTime(); + timedOp = operationFactory.create(opspec); - // send to server - unsyncedClientOpspecQueue.push(opspec); + playbackFunction(timedOp); + + // 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 - } - }else { - while(container.lastChild) { - container = container.lastChild; - offset = container.nodeType === Node.TEXT_NODE ? container.textContent.length : container.childNodes.length - } +(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{container:container, offset:offset} + return rangeClientRectsBug } - 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 - } - 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 - } - } - n = n.parentNode - } - elements.reverse(); - n = treeWalker.nextNode(); - while(n) { - elements.push(n); - n = treeWalker.nextNode() - } - 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 + 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 { - if(nextNode.nodeType === Node.TEXT_NODE) { - node.appendData(nextNode.data); - nextNode.parentNode.removeChild(nextNode) + while(container.lastChild) { + container = container.lastChild; + offset = container.nodeType === Node.TEXT_NODE ? container.textContent.length : container.childNodes.length } - mergedNode = node } + return{container:container, offset:offset} } - return mergedNode - } - function normalizeTextNodes(node) { - if(node && node.nextSibling) { - node = mergeTextNodes(node, node.nextSibling) + 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 } - if(node && node.previousSibling) { - mergeTextNodes(node.previousSibling, node) + 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.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) + this.containsRange = containsRange; + function rangesIntersect(range1, range2) { + return range1.compareBoundaryPoints(range1.END_TO_START, range2) <= 0 && range1.compareBoundaryPoints(range1.START_TO_END, range2) >= 0 } - 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) - } - n = container.firstChild; - while(n !== node) { - offset += 1; - n = n.nextSibling - } - return offset - } - function comparePoints(c1, o1, c2, o2) { - if(c1 === c2) { - return o2 - o1 - } - var comparison = c1.compareDocumentPosition(c2); - if(comparison === 2) { - comparison = -1 - }else { - if(comparison === 4) { - comparison = 1 - }else { - if(comparison === 10) { - o1 = getPositionInContainingNode(c1, c2); - comparison = o1 < o2 ? 1 : -1 + 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 { - o2 = getPositionInContainingNode(c2, c1); - comparison = o2 < o1 ? -1 : 1 + if(filterResult === NodeFilter.FILTER_REJECT) { + break + } + } + n = n.parentNode + } + elements.reverse(); + n = treeWalker.nextNode(); + while(n) { + elements.push(n); + n = treeWalker.nextNode() + } + 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 } } + return mergedNode } - 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 + function normalizeTextNodes(node) { + if(node && node.nextSibling) { + node = mergeTextNodes(node, node.nextSibling) + } + if(node && node.previousSibling) { + mergeTextNodes(node.previousSibling, node) + } } - appVersion = window.navigator.appVersion.toLowerCase(); - webKitOrSafari = appVersion.indexOf("chrome") === -1 && (appVersion.indexOf("applewebkit") !== -1 || appVersion.indexOf("safari") !== -1); - if(webKitOrSafari) { - self.containsNode = containsNodeForBrokenWebKit + 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 } - } - init(this) -}; + 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 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 + } + this.removeUnwantedNodes = removeUnwantedNodes; + 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) + } + n = container.firstChild; + while(n !== node) { + offset += 1; + n = n.nextSibling + } + return offset + } + function comparePoints(c1, o1, c2, o2) { + if(c1 === c2) { + return o2 - o1 + } + var comparison = c1.compareDocumentPosition(c2); + if(comparison === 2) { + comparison = -1 + }else { + if(comparison === 4) { + comparison = 1 + }else { + if(comparison === 10) { + o1 = getPositionInContainingNode(c1, c2); + comparison = o1 < o2 ? 1 : -1 + }else { + o2 = getPositionInContainingNode(c2, c1); + comparison = o2 < o1 ? -1 : 1 + } + } + } + return comparison + } + this.comparePoints = comparePoints; + function containsNodeForBrokenWebKit(parent, descendant) { + return parent === descendant || Boolean(parent.compareDocumentPosition(descendant) & Node.DOCUMENT_POSITION_CONTAINED_BY) + } + this.areRangeRectanglesTransformed = function(document) { + return!rangeClientRectsUntransformedBug(document) + }; + function adaptRangeDifferenceToZoomLevel(inputNumber, zoomLevel) { + var window = runtime.getWindow(), document = window && window.document; + if(document && rangeClientRectsUntransformedBug(document)) { + return inputNumber + } + return inputNumber / zoomLevel + } + 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) + }; + 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,6 +9016,99 @@ odf.Formatting = function Formatting() { tabStopDistance = "1.25cm" } return odfUtils.parseNonNegativeLength(tabStopDistance) + }; + 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} } }; /* @@ -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) - } - pageNumberContainer.appendChild(document.createTextNode(pageNumber)) - } - setFramePosition(odfContainer, id, clonedPage, stylesheet); - clonedPage.setAttributeNS(drawns, "draw:master-page-name", masterPage.getAttributeNS(stylens, "name")) } + } + 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 + } + } + } + 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,17 +10590,210 @@ 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) 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.OpSetBlob = function OpSetBlob() { + var memberid, timestamp, filename, mimetype, content; + this.init = function(data) { + memberid = data.memberid; + timestamp = data.timestamp; + filename = data.filename; + mimetype = data.mimetype; + content = data.content + }; + this.execute = function(odtDocument) { + odtDocument.getOdfCanvas().odfContainer().setBlob(filename, mimetype, content); + return true + }; + this.spec = function() { + return{optype:"SetBlob", memberid:memberid, timestamp:timestamp, filename:filename, mimetype:mimetype, content:content} + } +}; +/* + + 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.OpRemoveBlob = function OpRemoveBlob() { + var memberid, timestamp, filename; + this.init = function(data) { + memberid = data.memberid; + timestamp = data.timestamp; + filename = data.filename + }; + this.execute = function(odtDocument) { + odtDocument.getOdfCanvas().odfContainer().removeBlob(filename); + return true + }; + 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} } }; /* @@ -10143,6 +10808,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,64 +10831,21 @@ 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"; + 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 = parseInt(data.position, 10); - initialRows = parseInt(data.initialRows, 10); - initialColumns = parseInt(data.initialColumns, 10); + position = data.position; + initialRows = data.initialRows; + initialColumns = data.initialColumns; 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 - }; function getCellStyleName(row, column) { var rowStyles; if(tableCellStyleMatrix.length === 1) { @@ -10291,7 +10916,7 @@ ops.OpInsertTable = function OpInsertTable() { if(domPosition) { tableNode = createTableNode(odtDocument.getDOM()); previousSibling = odtDocument.getParagraphElement(domPosition.textNode); - rootNode.insertBefore(tableNode, previousSibling ? previousSibling.nextSibling : undefined); + rootNode.insertBefore(tableNode, previousSibling.nextSibling); odtDocument.getOdfCanvas().refreshSize(); odtDocument.emit(ops.OdtDocument.signalTableAdded, {tableElement:tableNode, memberId:memberid, timeStamp:timestamp}); odtDocument.getOdfCanvas().rerenderAnnotations(); @@ -10300,7 +10925,7 @@ ops.OpInsertTable = function OpInsertTable() { return false }; 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:"InsertTable", memberid:memberid, timestamp:timestamp, position:position, initialRows:initialRows, initialColumns:initialColumns, tableName:tableName, tableStyleName:tableStyleName, tableColumnStyleName:tableColumnStyleName, tableCellStyleMatrix:tableCellStyleMatrix} } }; /* @@ -10315,6 +10940,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 +10963,26 @@ 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; + var space = " ", tab = "\t", memberid, timestamp, position, text; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; - position = parseInt(data.position, 10); + position = data.position; text = data.text }; - this.merge = function(otherOpspec) { - if(otherOpspec.optype === optype && otherOpspec.memberid === memberid && otherOpspec.position === position + text.length) { - text = text + otherOpspec.text; - timestamp = otherOpspec.timestamp; - return true - } - return false - }; - this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, result = [self]; - 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 - }; 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) + 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 + function countStepsPublic(steps, filter) { + var iterator = getIteratorAtCursor(); + return countSteps(iterator, steps, filter) + } + function countPositionsToClosestStep(container, offset, filter) { + var iterator = getIteratorAtCursor(), paragraphNode = odfUtils.getParagraphElement(iterator.getCurrentNode()), count = 0; + iterator.setUnfilteredPosition(container, offset); + if(filter.acceptPosition(iterator) !== FILTER_ACCEPT) { + count = countSteps(iterator, -1, filter); + if(count === 0 || paragraphNode && paragraphNode !== odfUtils.getParagraphElement(iterator.getCurrentNode())) { + iterator.setUnfilteredPosition(container, offset); + count = countSteps(iterator, 1, filter) } } return count } - function 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) - } - 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; - runtime.log("Crosstransforming:"); - runtime.log(runtime.toJson(opA.spec())); - runtime.log(runtime.toJson(opB.spec())); - oldOpB = operationFactory.create(opB.spec()); - opBTransformResult = opB.transform(opA, true); - opATransformResult = opA.transform(oldOpB, false); - if(!opATransformResult || !opBTransformResult) { - return null - } - return{opsA:opATransformResult, opsB:opBTransformResult} +ops.OperationTransformMatrix = function OperationTransformMatrix() { + function passUnchanged(opSpecA, opSpecB) { + return{opSpecsA:[opSpecA], opSpecsB:[opSpecB]} } - function transformOpListVsOp(opsA, opB) { - var b, transformResult, transformListResult, transformedOpsA = [], transformedOpsB = []; - while(opsA.length > 0 && opB) { - transformResult = transformOpVsOp(opsA.shift(), (opB)); + 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(opSpecA)); + runtime.log(runtime.toJson(opSpecB)); + if(!isOptypeAAlphaNumericSmaller) { + helper = opSpecA; + opSpecA = opSpecB; + opSpecB = helper + } + transformationFunctionMap = transformations[opSpecA.optype]; + transformationFunction = transformationFunctionMap && transformationFunctionMap[opSpecB.optype]; + if(transformationFunction) { + result = transformationFunction(opSpecA, opSpecB, !isOptypeAAlphaNumericSmaller); + if(!isOptypeAAlphaNumericSmaller && result !== null) { + result = {opSpecsA:result.opSpecsB, opSpecsB:result.opSpecsA} + } + }else { + result = null + } + runtime.log("result:"); + if(result) { + runtime.log(runtime.toJson(result.opSpecsA)); + runtime.log(runtime.toJson(result.opSpecsB)) + }else { + runtime.log("null") + } + return result + } +}; +/* + + Copyright (C) 2013 KO GmbH + + @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(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) { @@ -12849,7 +13650,7 @@ gui.DirectParagraphStyler.paragraphStylingChanged = "paragraphStyling/changed"; })(); /* - 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 @@ -12859,6 +13660,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 +13683,224 @@ 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.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, 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 +})(); +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 + + @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.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.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) - } - }) + this.getEventManager = function() { + return eventManager }; + this.getKeyboardHandlers = function() { + return{keydown:keyDownHandler, keypress:keyPressHandler} + }; + this.destroy = function(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 @@ -14269,11 +15622,11 @@ gui.SessionView = 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("gui.Caret"); gui.CaretManager = function CaretManager(sessionController) { - var carets = {}, window = runtime.getWindow(); + var carets = {}, window = runtime.getWindow(), scrollIntoViewScheduled = false; function getCaret(memberId) { return carets.hasOwnProperty(memberId) ? carets[memberId] : null } @@ -14300,15 +15653,28 @@ gui.CaretManager = function CaretManager(sessionController) { } } } - function ensureLocalCaretVisible(info) { - var caret; - if(info.memberId === sessionController.getInputMemberId()) { - caret = getCaret(info.memberId); - if(caret) { - caret.ensureVisible() + function executeEnsureCaretVisible() { + var caret = getCaret(sessionController.getInputMemberId()); + scrollIntoViewScheduled = false; + if(caret) { + caret.ensureVisible() + } + } + function scheduleCaretVisibilityCheck() { + var caret = getCaret(sessionController.getInputMemberId()); + if(caret) { + caret.handleUpdate(); + if(!scrollIntoViewScheduled) { + scrollIntoViewScheduled = true; + runtime.setTimeout(executeEnsureCaretVisible, 50) } } } + function ensureLocalCaretVisible(info) { + if(info.memberId === sessionController.getInputMemberId()) { + scheduleCaretVisibilityCheck() + } + } function focusLocalCaret() { var caret = getCaret(sessionController.getInputMemberId()); if(caret) { @@ -14334,25 +15700,27 @@ gui.CaretManager = function CaretManager(sessionController) { } } this.registerCursor = function(cursor, caretAvatarInitiallyVisible, blinkOnRangeSelect) { - var memberid = cursor.getMemberId(), canvasElement = getCanvasElement(), caret = new gui.Caret(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 = caret.ensureVisible; - canvasElement.setAttribute("tabindex", 0); - canvasElement.focus() + cursor.handleUpdate = scheduleCaretVisibilityCheck; + getCanvasElement().setAttribute("tabindex", -1); + sessionController.getEventManager().focus() + }else { + cursor.handleUpdate = caret.handleUpdate } return caret }; this.getCaret = getCaret; this.getCarets = getCarets; this.destroy = function(callback) { - var odtDocument = sessionController.getSession().getOdtDocument(), canvasElement = getCanvasElement(), caretArray = getCarets(); + 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); - canvasElement.removeEventListener("focus", focusLocalCaret, false); - canvasElement.removeEventListener("blur", blurLocalCaret, false); + eventManager.unsubscribe("focus", focusLocalCaret); + eventManager.unsubscribe("blur", blurLocalCaret); window.removeEventListener("focus", showLocalCaret, false); window.removeEventListener("blur", hideLocalCaret, false); (function destroyCaret(i, err) { @@ -14367,382 +15735,21 @@ gui.CaretManager = function CaretManager(sessionController) { callback() } } - })(0, undefined) + })(0, undefined); + carets = {} }; function init() { - var odtDocument = sessionController.getSession().getOdtDocument(), canvasElement = getCanvasElement(); + 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); - canvasElement.addEventListener("focus", focusLocalCaret, false); - canvasElement.addEventListener("blur", blurLocalCaret, false); + eventManager.subscribe("focus", focusLocalCaret); + eventManager.subscribe("blur", blurLocalCaret); 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 - } - } - } - function cancelEvent(event) { - if(event.preventDefault) { - event.preventDefault() - }else { - event.returnValue = false - } - } - function isCaretMoveCommand(charCode) { - if(charCode >= 16 && charCode <= 20) { - return true - } - if(charCode >= 33 && charCode <= 40) { - return true - } - return false - } - function syncSelectionWithWalker() { - var sel = element.ownerDocument.defaultView.getSelection(), r; - if(!sel || sel.rangeCount <= 0 || !walker) { - return - } - r = sel.getRangeAt(0); - walker.setPoint(r.startContainer, r.startOffset) - } - 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 - } - } - } - 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 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 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 + '"' - } - 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 - } - 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 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 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 setXML(xml) { - var node = xml.documentElement || xml; - node = element.ownerDocument.importNode(node, true); - documentElement = node; - addExplicitAttributes(node); - while(element.lastChild) { - element.removeChild(element.lastChild) - } - element.appendChild(node); - updateCSS(); - walker = new core.PositionIterator(node) - } - initElement(element); - this.updateCSS = updateCSS; - this.setXML = setXML; - this.getXML = getXML -}; /* Copyright (C) 2013 KO GmbH @@ -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,9 +16110,286 @@ 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) 2012-2013 KO GmbH + Copyright (C) 2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -15106,6 +16399,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 +16422,117 @@ 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("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 + + @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.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,41 +412,8 @@ a+'"]');e=d=void 0;for(d=0;d - - @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 @@ -450,13 +435,9 @@ 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}(); +odf.OdfNodeFilter=function(){this.acceptNode=function(e){return"http://www.w3.org/1999/xhtml"===e.namespaceURI?NodeFilter.FILTER_SKIP:e.namespaceURI&&e.namespaceURI.match(/^urn:webodf:/)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}; // Input 28 /* @@ -470,6 +451,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,36 +474,12 @@ 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. + 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,58 +516,38 @@ 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}}; +runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.Namespaces"); +odf.StyleInfo=function(){function e(a,b){for(var d=B[a.localName],c=d&&d[a.namespaceURI],f=c?c.length:0,g,d=0;d - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -runtime.loadClass("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 /* Copyright (C) 2012-2013 KO GmbH @@ -617,6 +560,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,13 +583,61 @@ 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))})}}; +runtime.loadClass("core.DomUtils");runtime.loadClass("odf.Namespaces"); +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 + + @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.OdfUtils"); +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 /* @@ -657,6 +651,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,32 +674,13 @@ 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"),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 @@ -736,30 +717,32 @@ 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}(); +runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfUtils");runtime.loadClass("xmldom.XPath");runtime.loadClass("core.CSSUnits"); +odf.Style2CSS=function(){function e(a){var b={},d,c;if(!a)return b;for(a=a.firstChild;a;){if(c=a.namespaceURI!==r||"style"!==a.localName&&"default-style"!==a.localName?a.namespaceURI===v&&"list-style"===a.localName?"list":a.namespaceURI!==r||"page-layout"!==a.localName&&"default-page-layout"!==a.localName?void 0:"page":a.getAttributeNS(r,"family"))(d=a.getAttributeNS&&a.getAttributeNS(r,"name"))||(d=""),c=b[c]=b[c]||{},c[d]=a;a=a.nextSibling}return b}function h(a,b){if(!b||!a)return null;if(a[b])return a[b]; +var d,c;for(d in a)if(a.hasOwnProperty(d)&&(c=h(a[d].derivedStyles,b)))return c;return null}function f(a,b,d){var c=b[a],e,g;c&&(e=c.getAttributeNS(r,"parent-style-name"),g=null,e&&(g=h(d,e),!g&&b[e]&&(f(e,b,d),g=b[e],b[e]=null)),g?(g.derivedStyles||(g.derivedStyles={}),g.derivedStyles[a]=c):d[a]=c)}function n(a,b){for(var d in a)a.hasOwnProperty(d)&&(f(d,a,b),a[d]=null)}function m(a,b){var d=u[a],c;if(null===d)return null;c=b?"["+d+'|style-name="'+b+'"]':"";"presentation"===d&&(d="draw",c=b?'[presentation|style-name="'+ +b+'"]':"");return d+"|"+s[a].join(c+","+d+"|")+c}function p(a,b,d){var c=[],e,f;c.push(m(a,b));for(e in d.derivedStyles)if(d.derivedStyles.hasOwnProperty(e))for(f in b=p(a,e,d.derivedStyles[e]),b)b.hasOwnProperty(f)&&c.push(b[f]);return c}function c(a,b,d){if(!a)return null;for(a=a.firstChild;a;){if(a.namespaceURI===b&&a.localName===d)return b=a;a=a.nextSibling}return null}function b(a,b){var d="",c,e;for(c in b)if(b.hasOwnProperty(c)&&(c=b[c],e=a.getAttributeNS(c[0],c[1]))){e=e.trim();if(T.hasOwnProperty(c[1])){var f= +e.indexOf(" "),g=void 0,k=void 0;-1!==f?(g=e.substring(0,f),k=e.substring(f)):(g=e,k="");(g=$.parseLength(g))&&"pt"===g.unit&&0.75>g.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. + 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,12 +779,32 @@ 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;kd)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 /* @@ -812,6 +818,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,9 +841,12 @@ 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 @@ -868,20 +883,12 @@ 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. + 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,77 +925,24 @@ 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 - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -ops.Server=function(){};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 /* Copyright (C) 2012-2013 KO GmbH @@ -998,6 +955,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,9 +978,81 @@ 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(){}; +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 e(){function a(c){d=!0;runtime.setTimeout(function(){try{c()}catch(e){runtime.log(e)}d=!1;0 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 + + @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.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 /* @@ -1034,6 +1066,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,9 +1089,9 @@ 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}}}; +ops.Operation=function(){};ops.Operation.prototype.init=function(e){};ops.Operation.prototype.execute=function(e){};ops.Operation.prototype.spec=function(){}; // Input 42 /* @@ -1070,6 +1105,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,13 +1128,9 @@ 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. + 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,11 +1167,13 @@ 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}}}; +runtime.loadClass("core.DomUtils");runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfUtils"); +gui.StyleHelper=function(e){function h(c,b,a){var d=!0,e;for(e=0;e. + 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,9 +1210,11 @@ 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}}}; +runtime.loadClass("gui.StyleHelper");runtime.loadClass("odf.OdfUtils"); +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 /* @@ -1184,6 +1228,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 +1251,13 @@ 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}}}; +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) 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 +1267,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,13 +1290,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. + 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,12 +1330,9 @@ 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. + 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,15 +1369,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 @@ -1363,16 +1408,15 @@ 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}}}; +ops.OpInsertImage=function(){var e,h,f,n,m,p,c,b,a=odf.Namespaces.drawns,d=odf.Namespaces.svgns,k=odf.Namespaces.textns,g=odf.Namespaces.xlinkns;this.init=function(a){e=a.memberid;h=a.timestamp;f=a.position;n=a.filename;m=a.frameWidth;p=a.frameHeight;c=a.frameStyleName;b=a.frameName};this.execute=function(q){var l=q.getOdfCanvas(),r=q.getPositionInTextNode(f,e),t,w;if(!r)return!1;t=r.textNode;w=q.getParagraphElement(t);var r=r.offset!==t.length?t.splitText(r.offset):t.nextSibling,v=q.getDOM(),y=v.createElementNS(a, +"draw:image"),v=v.createElementNS(a,"draw:frame");y.setAttributeNS(g,"xlink:href",n);y.setAttributeNS(g,"xlink:type","simple");y.setAttributeNS(g,"xlink:show","embed");y.setAttributeNS(g,"xlink:actuate","onLoad");v.setAttributeNS(a,"draw:style-name",c);v.setAttributeNS(a,"draw:name",b);v.setAttributeNS(k,"text:anchor-type","as-char");v.setAttributeNS(d,"svg:width",m);v.setAttributeNS(d,"svg:height",p);v.appendChild(y);t.parentNode.insertBefore(v,r);0===t.length&&t.parentNode.removeChild(t);l.addCssForFrameWithImage(v); +l.refreshCSS();q.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:w,memberId:e,timeStamp:h});l.rerenderAnnotations();return!0};this.spec=function(){return{optype:"InsertImage",memberid:e,timestamp:h,filename:n,position:f,frameWidth:m,frameHeight:p,frameStyleName:c,frameName:b}}}; // Input 50 /* - Copyright (C) 2012-2013 KO GmbH + Copyright (C) 2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1382,6 +1426,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,10 +1449,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}}}; +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. + 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,14 +1491,11 @@ 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. + 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,11 +1532,15 @@ 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}}}; +runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfUtils");runtime.loadClass("core.DomUtils"); +ops.OpRemoveText=function(){function e(a){function e(a){return d.hasOwnProperty(a.namespaceURI)||"br"===a.localName&&c.isLineBreak(a.parentNode)||a.nodeType===Node.TEXT_NODE&&d.hasOwnProperty(a.parentNode.namespaceURI)}function f(a){if(c.isCharacterElement(a))return!1;if(a.nodeType===Node.TEXT_NODE)return 0===a.textContent.length;for(a=a.firstChild;a;){if(d.hasOwnProperty(a.namespaceURI)||!f(a))return!1;a=a.nextSibling}return!0}function h(d){var m;d.nodeType===Node.TEXT_NODE?(m=d.parentNode,m.removeChild(d)): +m=b.removeUnwantedNodes(d,e);return!c.isParagraph(m)&&m!==a&&f(m)?h(m):m}this.isEmpty=f;this.mergeChildrenIntoParent=h}function h(d){var c=d.getPositionFilter(),e,f,h,n,w=p,v=d.getDOM().createRange();d=d.getIteratorAtPosition(m);e=d.container();for(f=d.unfilteredDomOffset();w&&d.nextPosition();)h=d.container(),n=d.unfilteredDomOffset(),c.acceptPosition(d)===a&&(w-=1);v.setStart(e,f);v.setEnd(h,n);b.splitBoundaries(v);return v}var f,n,m,p,c,b,a=core.PositionFilter.FilterResult.FILTER_ACCEPT,d={};this.init= +function(a){runtime.assert(0<=a.length,"OpRemoveText only supports positive lengths");f=a.memberid;n=a.timestamp;m=parseInt(a.position,10);p=parseInt(a.length,10);c=new odf.OdfUtils;b=new core.DomUtils;d[odf.Namespaces.dbns]=!0;d[odf.Namespaces.dcns]=!0;d[odf.Namespaces.dr3dns]=!0;d[odf.Namespaces.drawns]=!0;d[odf.Namespaces.chartns]=!0;d[odf.Namespaces.formns]=!0;d[odf.Namespaces.numberns]=!0;d[odf.Namespaces.officens]=!0;d[odf.Namespaces.presentationns]=!0;d[odf.Namespaces.stylens]=!0;d[odf.Namespaces.svgns]= +!0;d[odf.Namespaces.tablens]=!0;d[odf.Namespaces.textns]=!0};this.execute=function(a){var b,d,l,r,t=a.getCursor(f),w=new e(a.getRootNode());a.upgradeWhitespacesAtPosition(m);a.upgradeWhitespacesAtPosition(m+p);d=h(a);b=a.getParagraphElement(d.startContainer);l=c.getTextElements(d,!1,!0);r=c.getParagraphElements(d);d.detach();l.forEach(function(a){w.mergeChildrenIntoParent(a)});d=r.reduce(function(a,b){var d,c=!1,e=a,f=b,g,h=null;w.isEmpty(a)&&(c=!0,b.parentNode!==a.parentNode&&(g=b.parentNode,a.parentNode.insertBefore(b, +a.nextSibling)),f=a,e=b,h=e.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo")[0]||e.firstChild);for(;f.hasChildNodes();)d=c?f.lastChild:f.firstChild,f.removeChild(d),"editinfo"!==d.localName&&e.insertBefore(d,h);g&&w.isEmpty(g)&&w.mergeChildrenIntoParent(g);w.mergeChildrenIntoParent(f);return e});a.downgradeWhitespacesAtPosition(m);a.fixCursorPositions();a.getOdfCanvas().refreshSize();a.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:d||b,memberId:f,timeStamp:n});t&&(t.resetSelectionType(), +a.emit(ops.OdtDocument.signalCursorMoved,t));a.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"RemoveText",memberid:f,timestamp:n,position:m,length:p}}}; // Input 53 /* @@ -1498,6 +1554,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,11 +1577,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=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 /* @@ -1536,6 +1595,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,13 +1618,10 @@ 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}}}; +ops.OpSetParagraphStyle=function(){var e,h,f,n;this.init=function(m){e=m.memberid;h=m.timestamp;f=m.position;n=m.styleName};this.execute=function(m){var p;p=m.getIteratorAtPosition(f);return(p=m.getParagraphElement(p.container()))?(""!==n?p.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","text:style-name",n):p.removeAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","style-name"),m.getOdfCanvas().refreshSize(),m.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:p, +timeStamp:h,memberId:e}),m.getOdfCanvas().rerenderAnnotations(),!0):!1};this.spec=function(){return{optype:"SetParagraphStyle",memberid:e,timestamp:h,position:f,styleName:n}}}; // Input 55 /* @@ -1576,6 +1635,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,12 +1658,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}}}; +runtime.loadClass("odf.Namespaces"); +ops.OpUpdateParagraphStyle=function(){function e(b,a){var d,c,e=a?a.split(","):[];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 @@ -1635,29 +1700,15 @@ 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)}}; +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 -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})(); -// 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 +1718,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,16 +1741,257 @@ 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 + + @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.OpAddAnnotation=function(){function e(c,b,a){var d=c.getPositionInTextNode(a,h);d&&(c=d.textNode,a=c.parentNode,d.offset!==c.length&&c.splitText(d.offset),a.insertBefore(b,c.nextSibling),0===c.length&&a.removeChild(c))}var h,f,n,m,p;this.init=function(c){h=c.memberid;f=parseInt(c.timestamp,10);n=parseInt(c.position,10);m=parseInt(c.length,10)||0;p=c.name};this.execute=function(c){var b={},a=c.getPositionFilter(),d=c.getCursor(h),k=c.getCursorPosition(h),k=n-k-1,g=new Date(f),q,l,r,t,w;w=c.getDOM(); +q=w.createElementNS(odf.Namespaces.officens,"office:annotation");q.setAttributeNS(odf.Namespaces.officens,"office:name",p);l=w.createElementNS(odf.Namespaces.dcns,"dc:creator");l.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",h);r=w.createElementNS(odf.Namespaces.dcns,"dc:date");r.appendChild(w.createTextNode(g.toISOString()));g=w.createElementNS(odf.Namespaces.textns,"text:list");t=w.createElementNS(odf.Namespaces.textns,"text:list-item");w=w.createElementNS(odf.Namespaces.textns, +"text:p");t.appendChild(w);g.appendChild(t);q.appendChild(l);q.appendChild(r);q.appendChild(g);b.node=q;if(!b.node)return!1;if(m){q=c.getDOM().createElementNS(odf.Namespaces.officens,"office:annotation-end");q.setAttributeNS(odf.Namespaces.officens,"office:name",p);b.end=q;if(!b.end)return!1;e(c,b.end,n+m)}e(c,b.node,n);d&&(a=d.getStepCounter().countSteps(k,a),d.move(a),d.resetSelectionType(),c.emit(ops.OdtDocument.signalCursorMoved,d));c.getOdfCanvas().addAnnotation(b);c.fixCursorPositions();return!0}; +this.spec=function(){return{optype:"AddAnnotation",memberid:h,timestamp:f,position:n,length:m,name:p}}}; // Input 59 -runtime.loadClass("core.Cursor");runtime.loadClass("gui.SelectionMover"); -ops.OdtCursor=function(h,m){var f=this,a,c;this.removeFromOdtDocument=function(){c.remove()};this.move=function(c,b){var k=0;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-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("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 +/* + + 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");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/ +*/ +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 @@ -1709,51 +2004,8 @@ 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. - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -ops.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)}; -// 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 - - @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 @@ -1775,202 +2027,28 @@ 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/ */ -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})(); -// Input 64 -/* - - Copyright (C) 2013 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -runtime.loadClass("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= -f}; -// Input 65 -/* - - Copyright (C) 2013 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -runtime.loadClass("core.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})(); +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 -/* - - Copyright (C) 2013 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -runtime.loadClass("core.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})(); +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 -/* - - Copyright (C) 2013 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -gui.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;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) 2012-2013 KO GmbH + Copyright (C) 2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1980,6 +2058,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,13 +2081,15 @@ 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){}; +runtime.loadClass("odf.Namespaces");runtime.loadClass("xmldom.LSSerializer");runtime.loadClass("odf.OdfNodeFilter");runtime.loadClass("odf.TextSerializer"); +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 70 /* - Copyright (C) 2012-2013 KO GmbH + Copyright (C) 2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2016,6 +2099,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,9 +2122,17 @@ 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()}}; +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 /* @@ -2052,6 +2146,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,49 +2169,16 @@ 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){}; +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(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 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -ops.TrivialOperationRouter=function(){var h,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 +2191,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,16 +2214,25 @@ 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()})()}; +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) 2012-2013 KO GmbH + Copyright (C) 2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2166,6 +2242,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 +2265,90 @@ 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):bc.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 @@ -2209,62 +2361,8 @@ 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. - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -runtime.loadClass("gui.Caret"); -gui.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 -/* - - 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 @@ -2286,14 +2384,13 @@ 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})(); +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) 2013 KO GmbH + Copyright (C) 2012-2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2303,6 +2400,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,10 +2423,9 @@ 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}}; +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 /* @@ -2340,6 +2439,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,19 +2462,13 @@ 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 + Copyright (C) 2012 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -2382,6 +2478,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 +2501,13 @@ 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 @@ -2435,6 +2520,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 +2543,377 @@ 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.EditInfo");runtime.loadClass("gui.EditInfoHandle"); +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 + + @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.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(e,h,f,n,m){function p(a,b,c){function d(b,c,e){c=b+'[editinfo|memberid="'+a+'"]'+e+c;a:{var f=t.firstChild;for(b=b+'[editinfo|memberid="'+a+'"]'+e+"{";f;){if(f.nodeType===Node.TEXT_NODE&&0===f.data.indexOf(b)){b=f;break a}f=f.nextSibling}b=null}b?b.data=c:t.appendChild(document.createTextNode(c))}d("div.editInfoMarker","{ background-color: "+c+"; }","");d("span.editInfoColor","{ background-color: "+c+"; }","");d("span.editInfoAuthor",'{ content: "'+b+'"; }', +":before");d("dc|creator",'{ content: "'+b+'"; display: none;}',":before");d("dc|creator","{ background-color: "+c+"; }","");d("div.selectionOverlay","{ background-color: "+c+";}","")}function c(a){var b,c;for(c in v)v.hasOwnProperty(c)&&(b=v[c],a?b.show():b.hide())}function b(a){n.getCarets().forEach(function(b){a?b.showHandle():b.hideHandle()})}function a(a,b){var c=n.getCaret(a);b?(c&&(c.setAvatarImageUrl(b.imageurl),c.setColor(b.color)),p(a,b.fullname,b.color),h===a&&p("",b.fullname,b.color)): +runtime.log('MemberModel sent undefined data for member "'+a+'".')}function d(b){var c=b.getMemberId(),d=f.getMemberModel();n.registerCursor(b,x,u);m.registerCursor(b,!0);a(c,null);d.getMemberDetailsAndUpdates(c,a);runtime.log("+++ View here +++ eagerly created an Caret for '"+c+"'! +++")}function k(a){a=a.getMemberId();var b=m.getSelectionView(h),c=m.getSelectionView(gui.ShadowCursor.ShadowCursorMemberId),d=n.getCaret(h);a===h?(c.hide(),b.show(),d&&d.show()):a===gui.ShadowCursor.ShadowCursorMemberId&& +(c.show(),b.hide(),d&&d.hide())}function g(b){var c=!1,d;for(d in v)if(v.hasOwnProperty(d)&&v[d].getEditInfo().getEdits().hasOwnProperty(b)){c=!0;break}m.removeSelectionView(b);c||f.getMemberModel().unsubscribeMemberDetailsUpdates(b,a)}function q(a){var b=a.paragraphElement,c=a.memberId;a=a.timeStamp;var d,e="",g=b.getElementsByTagNameNS(w,"editinfo")[0];g?(e=g.getAttributeNS(w,"id"),d=v[e]):(e=Math.random().toString(),d=new ops.EditInfo(b,f.getOdtDocument()),d=new gui.EditInfoMarker(d,y),g=b.getElementsByTagNameNS(w, +"editinfo")[0],g.setAttributeNS(w,"id",e),v[e]=d);d.addEdit(c,new Date(a))}function l(){C=!0}function r(){s=runtime.getWindow().setInterval(function(){C&&(m.rerenderSelectionViews(),C=!1)},200)}var t,w="urn:webodf:names:editinfo",v={},y=void 0!==e.editInfoMarkersInitiallyVisible?Boolean(e.editInfoMarkersInitiallyVisible):!0,x=void 0!==e.caretAvatarsInitiallyVisible?Boolean(e.caretAvatarsInitiallyVisible):!0,u=void 0!==e.caretBlinksOnRangeSelect?Boolean(e.caretBlinksOnRangeSelect):!0,s,C=!1;this.showEditInfoMarkers= +function(){y||(y=!0,c(y))};this.hideEditInfoMarkers=function(){y&&(y=!1,c(y))};this.showCaretAvatars=function(){x||(x=!0,b(x))};this.hideCaretAvatars=function(){x&&(x=!1,b(x))};this.getSession=function(){return f};this.getCaret=function(a){return n.getCaret(a)};this.destroy=function(b){var c=f.getOdtDocument(),e=f.getMemberModel(),h=Object.keys(v).map(function(a){return v[a]});c.unsubscribe(ops.OdtDocument.signalCursorAdded,d);c.unsubscribe(ops.OdtDocument.signalCursorRemoved,g);c.unsubscribe(ops.OdtDocument.signalParagraphChanged, +q);c.unsubscribe(ops.OdtDocument.signalCursorMoved,k);c.unsubscribe(ops.OdtDocument.signalParagraphChanged,l);c.unsubscribe(ops.OdtDocument.signalTableAdded,l);c.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,l);runtime.getWindow().clearInterval(s);n.getCarets().forEach(function(b){e.unsubscribeMemberDetailsUpdates(b.getCursor().getMemberId(),a)});t.parentNode.removeChild(t);(function G(a,c){c?b(c):a + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + 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.Caret"); +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 + + @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.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 + + @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.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 + + @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.DomUtils");runtime.loadClass("gui.UndoManager");runtime.loadClass("gui.UndoStateRules"); +gui.TrivialUndoManager=function(e){function h(){t.emit(gui.UndoManager.signalUndoStackChanged,{undoAvailable:c.hasUndoStates(),redoAvailable:c.hasRedoStates()})}function f(){q!==d&&q!==l[l.length-1]&&l.push(q)}function n(a){var c=a.previousSibling||a.nextSibling;a.parentNode.removeChild(a);b.normalizeTextNodes(c)}function m(a){return Object.keys(a).map(function(b){return a[b]})}function p(a){function b(a){var g=a.spec();if(e[g.memberid])switch(g.optype){case "AddCursor":c[g.memberid]||(c[g.memberid]= +a,delete e[g.memberid],f-=1);break;case "MoveCursor":d[g.memberid]||(d[g.memberid]=a)}}var c={},d={},e={},f,h=a.pop();g.getCursors().forEach(function(a){e[a.getMemberId()]=!0});for(f=Object.keys(e).length;h&&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 + + @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.DomUtils");runtime.loadClass("odf.OdfUtils");runtime.loadClass("odf.Namespaces");runtime.loadClass("gui.SelectionMover");runtime.loadClass("core.PositionFilterChain"); +ops.OdtDocument=function(e){function h(){var a=e.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&&!(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;d="string"===typeof a?k[a].getNode():a;return b(c)===b(d)? +q:l}}function n(a){var b=gui.SelectionMover.createPositionIterator(h());for(a+=1;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 + + @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("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);