diff --git a/js/editor/Editor.js b/js/editor/Editor.js index 49eb3690..583d11aa 100644 --- a/js/editor/Editor.js +++ b/js/editor/Editor.js @@ -59,8 +59,9 @@ define("webodf/editor/Editor", [ * cursorRemovedCallback:function(!string)=, * registerCallbackForShutdown:function(!function())= }} args * @param {!ops.Server=} server + * @param {!ServerFactory=} serverFactory */ - function Editor(args, server) { + function Editor(args, server, serverFactory) { var self = this, // Private @@ -102,7 +103,8 @@ define("webodf/editor/Editor", [ inviteButton, viewOptions = { editInfoMarkersInitiallyVisible: networked, - caretAvatarsInitiallyVisible: networked + caretAvatarsInitiallyVisible: networked, + caretBlinksOnRangeSelect: true }, peopleListDiv = document.getElementById('peopleList'); @@ -153,6 +155,8 @@ define("webodf/editor/Editor", [ editorSession.startEditing(); return; } + // Allow annotations + odfCanvas.enableAnnotations(true); if (!memberid) { // legacy - memberid should be passed in the constructor @@ -266,10 +270,10 @@ define("webodf/editor/Editor", [ self.loadSession = function (sessionId, editorReadyCallback) { initGuiAndDoc(server.getGenesisUrl(sessionId), function () { // get router and user model - opRouter = opRouter || server.createOperationRouter(sessionId, memberid); + opRouter = opRouter || serverFactory.createOperationRouter(sessionId, memberid, server); session.setOperationRouter(opRouter); - userModel = userModel || server.createUserModel(); + userModel = userModel || serverFactory.createUserModel(server); session.setUserModel(userModel); opRouter.requestReplay(function done() { diff --git a/js/editor/EditorSession.js b/js/editor/EditorSession.js index 6a10aea7..cab8eaea 100644 --- a/js/editor/EditorSession.js +++ b/js/editor/EditorSession.js @@ -45,11 +45,12 @@ define("webodf/editor/EditorSession", [ runtime.loadClass("ops.OdtDocument"); runtime.loadClass("ops.Session"); runtime.loadClass("odf.OdfCanvas"); - runtime.loadClass("gui.CaretFactory"); + runtime.loadClass("gui.CaretManager"); runtime.loadClass("gui.Caret"); runtime.loadClass("gui.SessionController"); runtime.loadClass("gui.SessionView"); runtime.loadClass("gui.TrivialUndoManager"); + runtime.loadClass("gui.StyleHelper"); runtime.loadClass("core.EventNotifier"); /** @@ -67,6 +68,7 @@ define("webodf/editor/EditorSession", [ odtDocument = session.getOdtDocument(), textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", formatting = odtDocument.getFormatting(), + styleHelper = new gui.StyleHelper(formatting), eventNotifier = new core.EventNotifier([ EditorSession.signalUserAdded, EditorSession.signalUserRemoved, @@ -79,7 +81,7 @@ define("webodf/editor/EditorSession", [ this.sessionController = new gui.SessionController(session, memberid); - this.sessionView = new gui.SessionView(config.viewOptions, session, new gui.CaretFactory(self.sessionController)); + this.sessionView = new gui.SessionView(config.viewOptions, session, new gui.CaretManager(self.sessionController)); this.availableFonts = []; /* @@ -188,6 +190,7 @@ define("webodf/editor/EditorSession", [ if (info.paragraphElement !== currentParagraphNode) { return; } + self.emit(EditorSession.signalParagraphChanged, info); checkParagraphStyleName(); } @@ -276,18 +279,40 @@ define("webodf/editor/EditorSession", [ return formatting.getAvailableParagraphStyles(); }; - this.getCurrentSelectionStyle = function () { - var cursor = odtDocument.getCursor(memberid), - selectedRange; + this.isBold = function () { + var cursor = odtDocument.getCursor(memberid); // no own cursor yet/currently added? if (!cursor) { - return []; + return false; } - selectedRange = cursor.getSelectedRange(); - if (selectedRange.collapsed) { - return [formatting.getAppliedStylesForElement(cursor.getNode())]; + return styleHelper.isBold(cursor.getSelectedRange()); + }; + + this.isItalic = function () { + var cursor = odtDocument.getCursor(memberid); + // no own cursor yet/currently added? + if (!cursor) { + return false; } - return formatting.getAppliedStyles(selectedRange); + return styleHelper.isItalic(cursor.getSelectedRange()); + }; + + this.hasUnderline = function () { + var cursor = odtDocument.getCursor(memberid); + // no own cursor yet/currently added? + if (!cursor) { + return false; + } + return styleHelper.hasUnderline(cursor.getSelectedRange()); + }; + + this.hasStrikeThrough = function () { + var cursor = odtDocument.getCursor(memberid); + // no own cursor yet/currently added? + if (!cursor) { + return false; + } + return styleHelper.hasStrikeThrough(cursor.getSelectedRange()); }; this.getCurrentParagraphStyle = function () { @@ -295,13 +320,35 @@ define("webodf/editor/EditorSession", [ }; this.formatSelection = function (value) { - var op = new ops.OpApplyStyle(), + var op = new ops.OpApplyDirectStyling(), selection = self.getCursorSelection(); op.init({ memberid: memberid, position: selection.position, length: selection.length, - info: value + setProperties: value + }); + session.enqueue(op); + }; + + /** + * 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: memberid, + position: position, + length: length, + name: memberid + Date.now() }); session.enqueue(op); }; @@ -379,14 +426,30 @@ define("webodf/editor/EditorSession", [ */ this.cloneParagraphStyle = function (styleName, newStyleDisplayName) { var newStyleName = uniqueParagraphStyleNCName(newStyleDisplayName), - op; + styleNode = odtDocument.getParagraphStyleElement(styleName), + formatting = odtDocument.getFormatting(), + op, setProperties, attributes, i; - op = new ops.OpCloneParagraphStyle(); + setProperties = formatting.getStyleAttributes(styleNode); + // copy any attributes directly on the style + attributes = styleNode.attributes; + for (i = 0; i < attributes.length; i += 1) { + // skip... + // * style:display-name -> not copied, set to new string below + // * style:name -> not copied, set from op by styleName property + // * style:family -> "paragraph" always, set by op + if (!/^(style:display-name|style:name|style:family)/.test(attributes[i].name)) { + setProperties[attributes[i].name] = attributes[i].value; + } + } + + setProperties['style:display-name'] = newStyleDisplayName; + + op = new ops.OpAddParagraphStyle(); op.init({ memberid: memberid, - styleName: styleName, - newStyleName: newStyleName, - newStyleDisplayName: newStyleDisplayName + styleName: newStyleName, + setProperties: setProperties }); session.enqueue(op); diff --git a/js/editor/SessionListView.js b/js/editor/SessionListView.js index 66f11dd7..84ca10b1 100644 --- a/js/editor/SessionListView.js +++ b/js/editor/SessionListView.js @@ -54,7 +54,11 @@ function SessionListView(sessionList, sessionListDiv, cb) { sessionDiv.appendChild(fullnameTextNode); sessionDiv.sessionId = sessionDetails.id; // TODO: namespace? + sessionDiv.style.cursor = "pointer"; // TODO: do not set on each element, use CSS sessionDiv.onclick = function () { + // HACK: stop pulling, so that does not mess up the logs + // Remove before merging to master + if (sessionList.stopPulling) { sessionList.stopPulling(); } cb(sessionDetails.id); }; diff --git a/js/editor/boot_editor.js b/js/editor/boot_editor.js index 394e2602..cddfc85c 100644 --- a/js/editor/boot_editor.js +++ b/js/editor/boot_editor.js @@ -47,7 +47,7 @@ * */ -/*global runtime, require, document, alert, net, window, NowjsSessionList, PullBoxSessionList, SessionListView, ops */ +/*global runtime, require, document, alert, net, window, SessionListView, ops */ // define the namespace/object we want to provide // this is the first line of API, the user gets. @@ -62,6 +62,7 @@ var webodfEditor = (function () { }; var editorInstance = null, + serverFactory = null, server = null, booting = false, loadedFilename; @@ -78,22 +79,31 @@ var webodfEditor = (function () { * @return {undefined} */ function connectNetwork(backend, callback) { - if (backend === "pullbox") { - runtime.loadClass("ops.PullBoxServer"); - server = new ops.PullBoxServer(); - } else if (backend === "nowjs") { - runtime.loadClass("ops.NowjsServer"); - server = new ops.NowjsServer(); - } else if (backend === "owncloud") { - runtime.loadClass("ops.PullBoxServer"); - server = new ops.PullBoxServer({url: "./office/ajax/otpoll.php"}); - server.getGenesisUrl = function(sid) { - return "/owncloud/index.php/apps/files/download/welcome.odt"; - }; - } else { - callback("unavailable"); + function createServer(ServerFactory) { + serverFactory = new ServerFactory(); + server = serverFactory.createServer(); + server.connect(8000, callback); + } + + switch (backend) { + case "pullbox": + require({ }, ["webodf/editor/server/pullbox/serverFactory"], createServer); + break; + case "nowjs": + require({ }, ["webodf/editor/server/nowjs/serverFactory"], createServer); + break; + case "owncloud": + require({ }, ["webodf/editor/server/pullbox/serverFactory"], function (ServerFactory) { + serverFactory = new ServerFactory(); + server = serverFactory.createServer({url: "./office/ajax/otpoll.php"}); + server.getGenesisUrl = function(sid) { + return "/owncloud/index.php/apps/files/download/welcome.odt"; + }; + server.connect(8000, callback); + }); + default: + callback("unavailable"); } - server.connect(8000, callback); } /** @@ -261,7 +271,7 @@ var webodfEditor = (function () { function (Editor) { // TODO: the networkSecurityToken needs to be retrieved via now.login // (but this is to be implemented later) - editorInstance = new Editor(editorOptions, server); + editorInstance = new Editor(editorOptions, server, serverFactory); // load the document and get called back when it's live editorInstance.loadSession(sessionId, function (editorSession) { @@ -299,8 +309,7 @@ var webodfEditor = (function () { function showSessions() { var sessionListDiv = document.getElementById("sessionList"), -// sessionList = new NowjsSessionList(server), - sessionList = new PullBoxSessionList(server), + sessionList = new serverFactory.createSessionList(server), sessionListView = new SessionListView(sessionList, sessionListDiv, enterSession); // hide login view diff --git a/js/editor/widgets.js b/js/editor/widgets.js index c827affa..f039431c 100644 --- a/js/editor/widgets.js +++ b/js/editor/widgets.js @@ -55,7 +55,7 @@ define("webodf/editor/widgets", [ ], function (ready, MenuItem, DropDownMenu, Button, DropDownButton, Toolbar) { ready(function () { var loadButton, saveButton, dropDownMenu, menuButton, paragraphStylesMenuItem, dialog, toolbar, simpleStyles, currentStyle, zoomSlider, - undoRedoMenu; + undoRedoMenu, annotateButton; dropDownMenu = new DropDownMenu({}); paragraphStylesMenuItem = new MenuItem({ @@ -136,6 +136,16 @@ define("webodf/editor/widgets", [ } }); menuButton.placeAt(toolbar); + + annotateButton = new Button({ + label: translator('annotate'), + showLabel: false, + iconClass: 'dijitIconBookmark', + onClick: function () { + editorSession.addAnnotation(); + } + }); + annotateButton.placeAt(toolbar); }); }); }; diff --git a/js/editor/widgets/paragraphStylesDialog.js b/js/editor/widgets/paragraphStylesDialog.js index eccdd169..9e19552f 100644 --- a/js/editor/widgets/paragraphStylesDialog.js +++ b/js/editor/widgets/paragraphStylesDialog.js @@ -65,12 +65,90 @@ define("webodf/editor/widgets/paragraphStylesDialog", [], function () { deleteButton, cloneTooltip, cloneDropDown, - newStyleName = null; + newStyleName = null, + /** + * Mapping of the properties from edit pane properties to the attributes of style:text-properties + * @const@type{Array.} + */ + textPropertyMapping = [ + { + propertyName: 'fontSize', + attributeName: 'fo:font-size', + unit: 'pt' + }, { + propertyName: 'fontName', + attributeName: 'style:font-name' + }, { + propertyName: 'color', + attributeName: 'fo:color' + }, { + propertyName: 'backgroundColor', + attributeName: 'fo:background-color' + }, { + propertyName: 'fontWeight', + attributeName: 'fo:font-weight' + }, { + propertyName: 'fontStyle', + attributeName: 'fo:font-style' + }, { + propertyName: 'underline', + attributeName: 'style:text-underline-style' + }, { + propertyName: 'strikethrough', + attributeName: 'style:text-line-through-style' + }], + /** + * Mapping of the properties from edit pane properties to the attributes of style:paragraph-properties + * @const@type{Array.} + */ + paragraphPropertyMapping = [ + { + propertyName: 'topMargin', + attributeName: 'fo:margin-top', + unit: 'mm' + }, { + propertyName: 'bottomMargin', + attributeName: 'fo:margin-bottom', + unit: 'mm' + }, { + propertyName: 'leftMargin', + attributeName: 'fo:margin-left', + unit: 'mm' + }, { + propertyName: 'rightMargin', + attributeName: 'fo:margin-right', + unit: 'mm' + }, { + propertyName: 'textAlign', + attributeName: 'fo:text-align' + }]; + + /** + * Sets attributes of a node by the properties of the object properties, + * based on the mapping defined in propertyMapping. + * @param {!Object} properties + * @param {!Array.} propertyMapping + * @return {undefined} + */ + function mappedProperties(properties, propertyMapping) { + var i, m, value, + result = {}; + for (i = 0; i < propertyMapping.length; i += 1) { + m = propertyMapping[i]; + value = properties[m.propertyName]; + // Set a value as the attribute of a node, if that value is defined. + // If there is a unit specified, it is suffixed to the value. + if (value !== undefined) { + result[m.attributeName] = (m.unit !== undefined) ? value + m.unit : value; + } + } + return result; + } function accept() { editorSession.updateParagraphStyle(stylePicker.value(), { - paragraphProperties: alignmentPane.value(), - textProperties: fontEffectsPane.value() + "style:paragraph-properties": mappedProperties(alignmentPane.value(), paragraphPropertyMapping), + "style:text-properties": mappedProperties(fontEffectsPane.value(), textPropertyMapping) }); dialog.hide(); diff --git a/js/editor/widgets/simpleStyles.js b/js/editor/widgets/simpleStyles.js index d1755c6e..da8bfedf 100644 --- a/js/editor/widgets/simpleStyles.js +++ b/js/editor/widgets/simpleStyles.js @@ -106,30 +106,12 @@ define("webodf/editor/widgets/simpleStyles", }); function checkStyleButtons() { - var fontWeight, fontStyle, underline, strikethrough, appliedStyles; - appliedStyles = editorSession.getCurrentSelectionStyle(); - - fontWeight = false; - fontStyle = false; - underline = false; - strikethrough = false; - - appliedStyles.forEach(function(appliedStyle) { - var textProperties = appliedStyle['style:text-properties']; - if (textProperties) { - fontWeight = fontWeight || textProperties['fo:font-weight'] === 'bold'; - fontStyle = fontStyle || textProperties['fo:font-style'] === 'italic'; - underline = underline || textProperties['style:text-underline-style'] === 'solid'; - strikethrough = strikethrough || textProperties['style:text-line-through-style'] === 'solid'; - } - }); - // The 3rd parameter is false to avoid firing onChange when setting the value // programmatically. - boldButton.set('checked', fontWeight, false); - italicButton.set('checked', fontStyle, false); - underlineButton.set('checked', underline, false); - strikethroughButton.set('checked', strikethrough, false); + boldButton.set('checked', editorSession.isBold(), false); + italicButton.set('checked', editorSession.isItalic(), false); + underlineButton.set('checked', editorSession.hasUnderline(), false); + strikethroughButton.set('checked', editorSession.hasStrikeThrough(), false); } editorSession.subscribe(EditorSession.signalCursorMoved, checkStyleButtons); diff --git a/js/webodf-debug.js b/js/webodf-debug.js index ae5a8329..3620cb06 100644 --- a/js/webodf-debug.js +++ b/js/webodf-debug.js @@ -79,6 +79,8 @@ Runtime.prototype.log = function(msgOrCategory, msg) { }; Runtime.prototype.setTimeout = function(callback, milliseconds) { }; +Runtime.prototype.clearTimeout = function(timeoutID) { +}; Runtime.prototype.libraryPaths = function() { }; Runtime.prototype.type = function() { @@ -399,7 +401,7 @@ function BrowserRuntime(logoutput) { if(xhr.status === 200 || xhr.status === 0) { result = xhr.responseText } - }catch(e) { + }catch(ignore) { } return result } @@ -494,26 +496,17 @@ function BrowserRuntime(logoutput) { if(cl) { callback(parseInt(cl, 10)) }else { - callback(-1) + readFile(path, "binary", function(err, data) { + if(!err) { + callback(data.length) + }else { + callback(-1) + } + }) } }; xhr.send(null) } - function wrap(nativeFunction, nargs) { - if(!nativeFunction) { - return null - } - return function() { - cache = {}; - var callback = arguments[nargs], args = Array.prototype.slice.call(arguments, 0, nargs), callbackname = "callback" + String(Math.random()).substring(2); - window[callbackname] = function() { - delete window[callbackname]; - callback.apply(this, arguments) - }; - args.push(callbackname); - nativeFunction.apply(this, args) - } - } this.readFile = readFile; this.read = read; this.readFileSync = readFileSync; @@ -525,14 +518,17 @@ function BrowserRuntime(logoutput) { this.log = log; this.assert = assert; this.setTimeout = function(f, msec) { - setTimeout(function() { + return setTimeout(function() { f() }, msec) }; + this.clearTimeout = function(timeoutID) { + clearTimeout(timeoutID) + }; this.libraryPaths = function() { return["lib"] }; - this.setCurrentDirectory = function(dir) { + this.setCurrentDirectory = function() { }; this.type = function() { return"BrowserRuntime" @@ -620,7 +616,7 @@ function NodeJSRuntime() { return } var buffer = new Buffer(length); - fs.read(fd, buffer, 0, length, offset, function(err, bytesRead) { + fs.read(fd, buffer, 0, length, offset, function(err) { fs.close(fd); callback(err, buffer) }) @@ -672,10 +668,13 @@ function NodeJSRuntime() { } this.assert = assert; this.setTimeout = function(f, msec) { - setTimeout(function() { + return setTimeout(function() { f() }, msec) }; + this.clearTimeout = function(timeoutID) { + clearTimeout(timeoutID) + }; this.libraryPaths = function() { return[__dirname] }; @@ -768,7 +767,7 @@ function RhinoRuntime() { } } function runtimeReadFileSync(path, encoding) { - var file = new Packages.java.io.File(path), data, i; + var file = new Packages.java.io.File(path); if(!file.isFile()) { return null } @@ -858,8 +857,11 @@ function RhinoRuntime() { } } this.assert = assert; - this.setTimeout = function(f, msec) { - f() + this.setTimeout = function(f) { + f(); + return 0 + }; + this.clearTimeout = function() { }; this.libraryPaths = function() { return["lib"] @@ -997,13 +999,13 @@ var runtime = function() { } var script = argv[0]; runtime.readFile(script, "utf8", function(err, code) { - var path = "", paths = runtime.libraryPaths(), codestring = (code); + var path = "", codestring = (code); if(script.indexOf("/") !== -1) { path = script.substring(0, script.indexOf("/")) } runtime.setCurrentDirectory(path); - function run() { - var script, path, paths, args, argv, result; + function inner_run() { + var script, path, args, argv, result; result = eval(codestring); if(result) { runtime.exit(result) @@ -1014,7 +1016,7 @@ var runtime = function() { runtime.log(err); runtime.exit(1) }else { - run.apply(null, argv) + inner_run.apply(null, argv) } }) } @@ -1029,21 +1031,7 @@ var runtime = function() { } })(String(typeof arguments) !== "undefined" && arguments); core.Base64 = function() { - var b64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", b64charcodes = function() { - var a = [], i, codeA = "A".charCodeAt(0), codea = "a".charCodeAt(0), code0 = "0".charCodeAt(0); - for(i = 0;i < 26;i += 1) { - a.push(codeA + i) - } - for(i = 0;i < 26;i += 1) { - a.push(codea + i) - } - for(i = 0;i < 10;i += 1) { - a.push(code0 + i) - } - a.push("+".charCodeAt(0)); - a.push("/".charCodeAt(0)); - return a - }(), b64tab = function(bin) { + var b64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", b64tab = function(bin) { var t = {}, i, l; for(i = 0, l = bin.length;i < l;i += 1) { t[bin.charAt(i)] = i @@ -1166,7 +1154,7 @@ core.Base64 = function() { return str } function convertUTF8StringToUTF16String(bin, callback) { - var partsize = 1E5, numparts = bin.length / partsize, str = "", pos = 0; + var partsize = 1E5, str = "", pos = 0; if(bin.length < partsize) { callback(convertUTF8StringToUTF16String_internal(bin, 0, bin.length), true); return @@ -1385,30 +1373,6 @@ core.RawDeflate = function() { zip_flag_buf = []; zip_flag_buf.length = parseInt(zip_LIT_BUFSIZE / 8, 10) } - var zip_deflate_end = function() { - zip_free_queue = zip_qhead = zip_qtail = null; - zip_outbuf = null; - zip_window = null; - zip_d_buf = null; - zip_l_buf = null; - zip_prev = null; - zip_dyn_ltree = null; - zip_dyn_dtree = null; - zip_static_ltree = null; - zip_static_dtree = null; - zip_bl_tree = null; - zip_l_desc = null; - zip_d_desc = null; - zip_bl_desc = null; - zip_bl_count = null; - zip_heap = null; - zip_depth = null; - zip_length_code = null; - zip_dist_code = null; - zip_base_length = null; - zip_base_dist = null; - zip_flag_buf = null - }; var zip_reuse_queue = function(p) { p.next = zip_free_queue; zip_free_queue = p @@ -1599,7 +1563,8 @@ core.RawDeflate = function() { scan_end1 = zip_window[scanp + best_len - 1]; scan_end = zip_window[scanp + best_len] } - }while((cur_match = zip_prev[cur_match & zip_WMASK]) > limit && --chain_length !== 0); + cur_match = zip_prev[cur_match & zip_WMASK] + }while(cur_match > limit && --chain_length !== 0); return best_len }; var zip_ct_tally = function(dist, lc) { @@ -1735,8 +1700,9 @@ core.RawDeflate = function() { code = code + zip_bl_count[bits - 1] << 1; next_code[bits] = code } + var len; for(n = 0;n <= max_code;n++) { - var len = tree[n].dl; + len = tree[n].dl; if(len === 0) { continue } @@ -1760,8 +1726,9 @@ core.RawDeflate = function() { tree[n].dl = 0 } } + var xnew; while(zip_heap_len < 2) { - var xnew = zip_heap[++zip_heap_len] = max_code < 2 ? ++max_code : 0; + xnew = zip_heap[++zip_heap_len] = max_code < 2 ? ++max_code : 0; tree[xnew].fc = 1; zip_depth[xnew] = 0; zip_opt_len--; @@ -1812,21 +1779,20 @@ core.RawDeflate = function() { nextlen = tree[n + 1].dl; if(++count < max_count && curlen === nextlen) { continue + } + if(count < min_count) { + zip_bl_tree[curlen].fc += count }else { - if(count < min_count) { - zip_bl_tree[curlen].fc += count + if(curlen !== 0) { + if(curlen !== prevlen) { + zip_bl_tree[curlen].fc++ + } + zip_bl_tree[zip_REP_3_6].fc++ }else { - if(curlen !== 0) { - if(curlen !== prevlen) { - zip_bl_tree[curlen].fc++ - } - zip_bl_tree[zip_REP_3_6].fc++ + if(count <= 10) { + zip_bl_tree[zip_REPZ_3_10].fc++ }else { - if(count <= 10) { - zip_bl_tree[zip_REPZ_3_10].fc++ - }else { - zip_bl_tree[zip_REPZ_11_138].fc++ - } + zip_bl_tree[zip_REPZ_11_138].fc++ } } } @@ -1926,27 +1892,26 @@ core.RawDeflate = function() { nextlen = tree[n + 1].dl; if(++count < max_count && curlen === nextlen) { continue + } + if(count < min_count) { + do { + zip_SEND_CODE(curlen, zip_bl_tree) + }while(--count !== 0) }else { - if(count < min_count) { - do { - zip_SEND_CODE(curlen, zip_bl_tree) - }while(--count !== 0) + if(curlen !== 0) { + if(curlen !== prevlen) { + zip_SEND_CODE(curlen, zip_bl_tree); + count-- + } + zip_SEND_CODE(zip_REP_3_6, zip_bl_tree); + zip_send_bits(count - 3, 2) }else { - if(curlen !== 0) { - if(curlen !== prevlen) { - zip_SEND_CODE(curlen, zip_bl_tree); - count-- - } - zip_SEND_CODE(zip_REP_3_6, zip_bl_tree); - zip_send_bits(count - 3, 2) + if(count <= 10) { + zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree); + zip_send_bits(count - 3, 3) }else { - if(count <= 10) { - zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree); - zip_send_bits(count - 3, 3) - }else { - zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree); - zip_send_bits(count - 11, 7) - } + zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree); + zip_send_bits(count - 11, 7) } } } @@ -2033,8 +1998,8 @@ core.RawDeflate = function() { } }; var zip_deflate_fast = function() { + var flush; while(zip_lookahead !== 0 && zip_qhead === null) { - var flush; zip_INSERT_STRING(); if(zip_hash_head !== zip_NIL && zip_strstart - zip_hash_head <= zip_MAX_DIST) { zip_match_length = zip_longest_match(zip_hash_head); @@ -2073,6 +2038,7 @@ core.RawDeflate = function() { } }; var zip_deflate_better = function() { + var flush; while(zip_lookahead !== 0 && zip_qhead === null) { zip_INSERT_STRING(); zip_prev_length = zip_match_length; @@ -2088,7 +2054,6 @@ core.RawDeflate = function() { } } if(zip_prev_length >= zip_MIN_MATCH && zip_match_length <= zip_prev_length) { - var flush; flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match, zip_prev_length - zip_MIN_MATCH); zip_lookahead -= zip_prev_length - 1; zip_prev_length -= 2; @@ -2223,7 +2188,7 @@ core.RawDeflate = function() { zip_complete = false }; var zip_qcopy = function(buff, off, buff_size) { - var n, i, j; + var n, i, j, p; n = 0; while(zip_qhead !== null && n < buff_size) { i = buff_size - n; @@ -2237,7 +2202,6 @@ core.RawDeflate = function() { zip_qhead.len -= i; n += i; if(zip_qhead.len === 0) { - var p; p = zip_qhead; zip_qhead = zip_qhead.next; zip_reuse_queue(p) @@ -2272,7 +2236,8 @@ core.RawDeflate = function() { return 0 } } - if((n = zip_qcopy(buff, off, buff_size)) === buff_size) { + n = zip_qcopy(buff, off, buff_size); + if(n === buff_size) { return buff_size } if(zip_complete) { @@ -2301,14 +2266,15 @@ core.RawDeflate = function() { } zip_deflate_start(level); var buff = new Array(1024); - var aout = []; - while((i = zip_deflate_internal(buff, 0, buff.length)) > 0) { - var cbuf = []; + var aout = [], cbuf = []; + i = zip_deflate_internal(buff, 0, buff.length); + while(i > 0) { cbuf.length = i; for(j = 0;j < i;j++) { cbuf[j] = String.fromCharCode(buff[j]) } - aout[aout.length] = cbuf.join("") + aout[aout.length] = cbuf.join(""); + i = zip_deflate_internal(buff, 0, buff.length) } zip_deflate_data = null; return aout.join("") @@ -2319,12 +2285,14 @@ core.ByteArray = function ByteArray(data) { this.pos = 0; this.data = data; this.readUInt32LE = function() { - var data = this.data, pos = this.pos += 4; - return data[--pos] << 24 | data[--pos] << 16 | data[--pos] << 8 | data[--pos] + this.pos += 4; + var d = this.data, pos = this.pos; + return d[--pos] << 24 | d[--pos] << 16 | d[--pos] << 8 | d[--pos] }; this.readUInt16LE = function() { - var data = this.data, pos = this.pos += 2; - return data[--pos] << 8 | data[--pos] + this.pos += 2; + var d = this.data, pos = this.pos; + return d[--pos] << 8 | d[--pos] } }; core.ByteArrayWriter = function ByteArrayWriter(encoding) { @@ -3014,22 +2982,83 @@ core.LoopWatchDog = function LoopWatchDog(timeout, maxChecks) { } this.check = check }; -core.DomUtils = function DomUtils() { - function splitBoundaries(range) { - var modifiedNodes = [], splitStart; - if(range.endOffset !== 0 && range.endContainer.nodeType === Node.TEXT_NODE && range.endOffset !== range.endContainer.length) { - modifiedNodes.push(range.endContainer.splitText(range.endOffset)); - modifiedNodes.push(range.endContainer) +core.Utils = function Utils() { + function hashString(value) { + var hash = 0, i, l; + for(i = 0, l = value.length;i < l;i += 1) { + hash = (hash << 5) - hash + value.charCodeAt(i); + hash |= 0 } - 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 hash + } + this.hashString = hashString +}; +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 + } + } + return{container:container, offset:offset} + } + function splitBoundaries(range) { + var modifiedNodes = [], end, splitStart; + if(range.startContainer.nodeType === Node.TEXT_NODE || range.endContainer.nodeType === Node.TEXT_NODE) { + end = findStablePoint(range.endContainer, range.endOffset); + range.setEnd(end.container, end.offset); + if(range.endOffset !== 0 && range.endContainer.nodeType === Node.TEXT_NODE && range.endOffset !== range.endContainer.length) { + modifiedNodes.push(range.endContainer.splitText(range.endOffset)); + modifiedNodes.push(range.endContainer) + } + if(range.startOffset !== 0 && range.startContainer.nodeType === Node.TEXT_NODE && range.startOffset !== range.startContainer.length) { + splitStart = range.startContainer.splitText(range.startOffset); + modifiedNodes.push(range.startContainer); + modifiedNodes.push(splitStart); + range.setStart(splitStart, 0) + } } return modifiedNodes } 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(node1, node2) { if(node1.nodeType === Node.TEXT_NODE) { if(node1.length === 0) { @@ -3074,11 +3103,16 @@ core.DomUtils = function DomUtils() { function getElementsByTagNameNS(node, namespace, tagName) { return Array.prototype.slice.call(node.getElementsByTagNameNS(namespace, tagName)) } - this.getElementsByTagNameNS = getElementsByTagNameNS + 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 }; runtime.loadClass("core.DomUtils"); core.Cursor = function Cursor(document, memberId) { - var self = this, cursorns = "urn:webodf:names:cursor", cursorNode = document.createElementNS(cursorns, "cursor"), anchorNode = document.createElementNS(cursorns, "anchor"), forwardSelection, recentlyModifiedNodes = [], selectedRange, isCollapsed, domUtils = new core.DomUtils; + var cursorns = "urn:webodf:names:cursor", cursorNode = document.createElementNS(cursorns, "cursor"), anchorNode = document.createElementNS(cursorns, "anchor"), forwardSelection, recentlyModifiedNodes = [], selectedRange, isCollapsed, domUtils = new core.DomUtils; function putIntoTextNode(node, container, offset) { runtime.assert(Boolean(container), "putCursorIntoTextNode: invalid container"); var parent = container.parentNode; @@ -3213,7 +3247,7 @@ core.Cursor = function Cursor(document, memberId) { @source: http://gitorious.org/webodf/webodf/ */ core.EventNotifier = function EventNotifier(eventIds) { - var self = this, eventListener = {}; + var eventListener = {}; this.emit = function(eventId, args) { var i, subscribers; runtime.assert(eventListener.hasOwnProperty(eventId), 'unknown event fired "' + eventId + '"'); @@ -3485,13 +3519,13 @@ core.UnitTester = function UnitTester() { return } t = todo[0]; - var tname = Runtime.getFunctionName(t); - runtime.log("Running " + tname); + var fname = Runtime.getFunctionName(t); + runtime.log("Running " + fname); lastFailCount = runner.countFailedTests(); test.setUp(); t(function() { test.tearDown(); - testResults[tname] = lastFailCount === runner.countFailedTests(); + testResults[fname] = lastFailCount === runner.countFailedTests(); runAsyncTests(todo.slice(1)) }) } @@ -3658,17 +3692,6 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa } return c }; - this.textOffset = function() { - if(walker.currentNode.nodeType !== Node.TEXT_NODE) { - return 0 - } - var offset = currentPos, n = walker.currentNode; - while(walker.previousSibling() && walker.currentNode.nodeType === Node.TEXT_NODE) { - offset += walker.currentNode.length - } - walker.currentNode = n; - return offset - }; this.getPreviousSibling = function() { var currentNode = walker.currentNode, sibling = walker.previousSibling(); walker.currentNode = currentNode; @@ -3679,33 +3702,6 @@ core.PositionIterator = function PositionIterator(root, whatToShow, filter, expa walker.currentNode = currentNode; return sibling }; - this.text = function() { - var i, data = "", neighborhood = self.textNeighborhood(); - for(i = 0;i < neighborhood.length;i += 1) { - data += neighborhood[i].data - } - return data - }; - this.textNeighborhood = function() { - var n = walker.currentNode, t, neighborhood = []; - if(n.nodeType !== Node.TEXT_NODE) { - return neighborhood - } - while(walker.previousSibling()) { - if(walker.currentNode.nodeType !== Node.TEXT_NODE) { - walker.nextSibling(); - break - } - } - do { - neighborhood.push(walker.currentNode) - }while(walker.nextSibling() && walker.currentNode.nodeType === Node.TEXT_NODE); - walker.currentNode = n; - return neighborhood - }; - this.substr = function(start, length) { - return self.text().substr(start, length) - }; this.setUnfilteredPosition = function(container, offset) { var filterResult; runtime.assert(container !== null && container !== undefined, "PositionIterator.setUnfilteredPosition called without container"); @@ -3786,6 +3782,27 @@ core.PositionFilter.prototype.acceptPosition = function(point) { (function() { return core.PositionFilter })(); +runtime.loadClass("core.PositionFilter"); +core.PositionFilterChain = function PositionFilterChain() { + var filterChain = {}, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT; + this.acceptPosition = function(iterator) { + var filterName; + for(filterName in filterChain) { + if(filterChain.hasOwnProperty(filterName)) { + if(filterChain[filterName].acceptPosition(iterator) === FILTER_REJECT) { + return FILTER_REJECT + } + } + } + return FILTER_ACCEPT + }; + this.addFilter = function(filterName, filterInstance) { + filterChain[filterName] = filterInstance + }; + this.removeFilter = function(filterName) { + delete filterChain[filterName] + } +}; core.Async = function Async() { this.forEach = function(items, f, callback) { var i, l = items.length, itemsDone = 0; @@ -3807,6 +3824,14 @@ core.Async = function Async() { } } }; +/* + + WebODF + Copyright (c) 2010 Jos van den Oever + Licensed under the ... License: + + Project home: http://www.webodf.org/ +*/ runtime.loadClass("core.RawInflate"); runtime.loadClass("core.ByteArray"); runtime.loadClass("core.ByteArrayWriter"); @@ -3838,26 +3863,26 @@ core.Zip = function Zip(url, entriesReadCallback) { return y < 1980 ? 0 : y - 1980 << 25 | date.getMonth() + 1 << 21 | date.getDate() << 16 | date.getHours() << 11 | date.getMinutes() << 5 | date.getSeconds() >> 1 } function ZipEntry(url, stream) { - var sig, namelen, extralen, commentlen, compressionMethod, compressedSize, uncompressedSize, offset, crc, entry = this; + var sig, namelen, extralen, commentlen, compressionMethod, compressedSize, uncompressedSize, offset, entry = this; function handleEntryData(data, callback) { - var stream = new core.ByteArray(data), sig = stream.readUInt32LE(), filenamelen, extralen; - if(sig !== 67324752) { - callback("File entry signature is wrong." + sig.toString() + " " + data.length.toString(), null); + var estream = new core.ByteArray(data), esig = estream.readUInt32LE(), filenamelen, eextralen; + if(esig !== 67324752) { + callback("File entry signature is wrong." + esig.toString() + " " + data.length.toString(), null); return } - stream.pos += 22; - filenamelen = stream.readUInt16LE(); - extralen = stream.readUInt16LE(); - stream.pos += filenamelen + extralen; + estream.pos += 22; + filenamelen = estream.readUInt16LE(); + eextralen = estream.readUInt16LE(); + estream.pos += filenamelen + eextralen; if(compressionMethod) { - data = data.slice(stream.pos, stream.pos + compressedSize); + data = data.slice(estream.pos, estream.pos + compressedSize); if(compressedSize !== data.length) { callback("The amount of compressed bytes read was " + data.length.toString() + " instead of " + compressedSize.toString() + " for " + entry.filename + " in " + url + ".", null); return } data = inflate(data, uncompressedSize) }else { - data = data.slice(stream.pos, stream.pos + uncompressedSize) + data = data.slice(estream.pos, estream.pos + uncompressedSize) } if(uncompressedSize !== data.length) { callback("The amount of bytes read was " + data.length.toString() + " instead of " + uncompressedSize.toString() + " for " + entry.filename + " in " + url + ".", null); @@ -3903,7 +3928,7 @@ core.Zip = function Zip(url, entriesReadCallback) { stream.pos += 6; compressionMethod = stream.readUInt16LE(); this.date = dosTime2Date(stream.readUInt32LE()); - crc = stream.readUInt32LE(); + stream.readUInt32LE(); compressedSize = stream.readUInt32LE(); uncompressedSize = stream.readUInt32LE(); namelen = stream.readUInt16LE(); @@ -3966,7 +3991,7 @@ core.Zip = function Zip(url, entriesReadCallback) { }) } function load(filename, callback) { - var entry = null, end = filesize, e, i; + var entry = null, e, i; for(i = 0;i < entries.length;i += 1) { e = entries[i]; if(e.filename === filename) { @@ -4006,7 +4031,7 @@ core.Zip = function Zip(url, entriesReadCallback) { if(err) { return callback(err, null) } - var p = data, chunksize = 45E3, i = 0, url; + var p = data, chunksize = 45E3, i = 0, dataurl; if(!mimetype) { if(p[1] === 80 && p[2] === 78 && p[3] === 71) { mimetype = "image/png" @@ -4022,12 +4047,12 @@ core.Zip = function Zip(url, entriesReadCallback) { } } } - url = "data:" + mimetype + ";base64,"; + dataurl = "data:" + mimetype + ";base64,"; while(i < data.length) { - url += base64.convertUTF8ArrayToBase64(p.slice(i, Math.min(i + chunksize, p.length))); + dataurl += base64.convertUTF8ArrayToBase64(p.slice(i, Math.min(i + chunksize, p.length))); i += chunksize } - callback(null, url) + callback(null, dataurl) }) } function loadAsDOM(filename, callback) { @@ -4213,7 +4238,7 @@ xmldom.LSSerializer = function LSSerializer() { } return m } - var self = this, current = nsmap || {}, currentrev = invertMap(nsmap), levels = [current], levelsrev = [currentrev], level = 0; + var current = nsmap || {}, currentrev = invertMap(nsmap), levels = [current], levelsrev = [currentrev], level = 0; this.push = function() { level += 1; current = levels[level] = Object.create(current); @@ -4230,7 +4255,7 @@ xmldom.LSSerializer = function LSSerializer() { return currentrev }; this.getQName = function(node) { - var ns = node.namespaceURI, n, i = 0, p; + var ns = node.namespaceURI, i = 0, p; if(!ns) { return node.localName } @@ -4363,12 +4388,14 @@ xmldom.RelaxNGParser = function RelaxNGParser() { return r } function splitQNames(def) { - var i, l = def.names ? def.names.length : 0, name, localnames = def.localnames = [l], namespaces = def.namespaces = [l]; + var i, l = def.names ? def.names.length : 0, name, localnames = [], namespaces = []; for(i = 0;i < l;i += 1) { name = splitQName(def.names[i]); namespaces[i] = name[0]; localnames[i] = name[1] } + def.localnames = localnames; + def.namespaces = namespaces } function trim(str) { str = str.replace(/^\s\s*/, ""); @@ -4597,7 +4624,7 @@ xmldom.RelaxNGParser = function RelaxNGParser() { } } function resolveElements(def, elements) { - var i = 0, e, name; + var i = 0, e; while(def.e && i < def.e.length) { e = def.e[i]; if(e.name === "elementref") { @@ -4665,7 +4692,7 @@ xmldom.RelaxNG = function RelaxNG() { return notAllowed }, startTagOpenDeriv:function() { return notAllowed - }, attDeriv:function(context, attribute) { + }, attDeriv:function() { return notAllowed }, startTagCloseDeriv:function() { return empty @@ -4944,7 +4971,7 @@ xmldom.RelaxNG = function RelaxNG() { return createAfter(p, empty) } return notAllowed - }, attDeriv:function(context, attribute) { + }, attDeriv:function() { return notAllowed }, startTagCloseDeriv:function() { return this @@ -4964,7 +4991,7 @@ xmldom.RelaxNG = function RelaxNG() { }} }); function createList() { - return{type:"list", nullable:false, hash:"list", textDeriv:function(context, text) { + return{type:"list", nullable:false, hash:"list", textDeriv:function() { return empty }} } @@ -4986,9 +5013,6 @@ xmldom.RelaxNG = function RelaxNG() { return this }} }); - function createDataExcept() { - return{type:"dataExcept", nullable:false, hash:"dataExcept"} - } applyAfter = function applyAfter(f, p) { var result; if(p.type === "after") { @@ -5024,14 +5048,13 @@ xmldom.RelaxNG = function RelaxNG() { return a } function childrenDeriv(context, pattern, walker) { - var element = walker.currentNode, childNode = walker.firstChild(), numberOfTextNodes = 0, childNodes = [], i, p; + var element = walker.currentNode, childNode = walker.firstChild(), childNodes = [], i, p; while(childNode) { if(childNode.nodeType === Node.ELEMENT_NODE) { childNodes.push(childNode) }else { if(childNode.nodeType === Node.TEXT_NODE && !/^\s*$/.test(childNode.nodeValue)) { - childNodes.push(childNode.nodeValue); - numberOfTextNodes += 1 + childNodes.push(childNode.nodeValue) } } childNode = walker.nextSibling() @@ -5097,9 +5120,9 @@ xmldom.RelaxNG = function RelaxNG() { hash += "{" + ns[i] + "}" + name[i] + "," } result = {hash:hash, contains:function(node) { - var i; - for(i = 0;i < name.length;i += 1) { - if(name[i] === node.localName && ns[i] === node.namespaceURI) { + var j; + for(j = 0;j < name.length;j += 1) { + if(name[j] === node.localName && ns[j] === node.namespaceURI) { return true } } @@ -5196,7 +5219,7 @@ xmldom.RelaxNG = function RelaxNG() { }; runtime.loadClass("xmldom.RelaxNGParser"); xmldom.RelaxNG2 = function RelaxNG2() { - var start, validateNonEmptyPattern, nsmap, depth = 0, p = " "; + var start, validateNonEmptyPattern, nsmap; function RelaxNGParseError(error, context) { this.message = function() { if(context) { @@ -5258,26 +5281,22 @@ xmldom.RelaxNG2 = function RelaxNG2() { function validateTop(elementdef, walker, element) { return validatePattern(elementdef, walker, element) } - function validateElement(elementdef, walker, element) { + function validateElement(elementdef, walker) { if(elementdef.e.length !== 2) { throw"Element with wrong # of elements: " + elementdef.e.length; } - depth += 1; var node = walker.currentNode, type = node ? node.nodeType : 0, error = null; while(type > Node.ELEMENT_NODE) { if(type !== Node.COMMENT_NODE && (type !== Node.TEXT_NODE || !/^\s+$/.test(walker.currentNode.nodeValue))) { - depth -= 1; return[new RelaxNGParseError("Not allowed node of type " + type + ".")] } node = walker.nextSibling(); type = node ? node.nodeType : 0 } if(!node) { - depth -= 1; return[new RelaxNGParseError("Missing element " + elementdef.names)] } if(elementdef.names && elementdef.names.indexOf(qName(node)) === -1) { - depth -= 1; return[new RelaxNGParseError("Found " + node.nodeName + " instead of " + elementdef.names + ".", node)] } if(walker.firstChild()) { @@ -5285,18 +5304,15 @@ xmldom.RelaxNG2 = function RelaxNG2() { while(walker.nextSibling()) { type = walker.currentNode.nodeType; if(!isWhitespace(walker.currentNode) && type !== Node.COMMENT_NODE) { - depth -= 1; return[new RelaxNGParseError("Spurious content.", walker.currentNode)] } } if(walker.parentNode() !== node) { - depth -= 1; return[new RelaxNGParseError("Implementation error.")] } }else { error = validateTop(elementdef.e[1], walker, node) } - depth -= 1; node = walker.nextSibling(); return error } @@ -5372,7 +5388,7 @@ xmldom.RelaxNG2 = function RelaxNG2() { return validateNonEmptyPattern(elementdef.e[0], walker, element) || validateNonEmptyPattern(elementdef.e[1], walker, element) } function validateText(elementdef, walker, element) { - var node = walker.currentNode, type = node ? node.nodeType : 0, error = null; + var node = walker.currentNode, type = node ? node.nodeType : 0; while(node !== element && type !== 3) { if(type === 1) { return[new RelaxNGParseError("Element not allowed here.", node)] @@ -5403,7 +5419,7 @@ xmldom.RelaxNG2 = function RelaxNG2() { err = validateAttribute(elementdef, walker, element) }else { if(name === "element") { - err = validateElement(elementdef, walker, element) + err = validateElement(elementdef, walker) }else { if(name === "oneOrMore") { err = validateOneOrMore(elementdef, walker, element) @@ -5440,60 +5456,6 @@ xmldom.RelaxNG2 = function RelaxNG2() { nsmap = nsmap1 } }; -xmldom.OperationalTransformInterface = function() { -}; -xmldom.OperationalTransformInterface.prototype.retain = function(amount) { -}; -xmldom.OperationalTransformInterface.prototype.insertCharacters = function(chars) { -}; -xmldom.OperationalTransformInterface.prototype.insertElementStart = function(tagname, attributes) { -}; -xmldom.OperationalTransformInterface.prototype.insertElementEnd = function() { -}; -xmldom.OperationalTransformInterface.prototype.deleteCharacters = function(amount) { -}; -xmldom.OperationalTransformInterface.prototype.deleteElementStart = function() { -}; -xmldom.OperationalTransformInterface.prototype.deleteElementEnd = function() { -}; -xmldom.OperationalTransformInterface.prototype.replaceAttributes = function(atts) { -}; -xmldom.OperationalTransformInterface.prototype.updateAttributes = function(atts) { -}; -xmldom.OperationalTransformDOM = function OperationalTransformDOM(root, serializer) { - var pos, length; - function retain(amount) { - } - function insertCharacters(chars) { - } - function insertElementStart(tagname, attributes) { - } - function insertElementEnd() { - } - function deleteCharacters(amount) { - } - function deleteElementStart() { - } - function deleteElementEnd() { - } - function replaceAttributes(atts) { - } - function updateAttributes(atts) { - } - function atEnd() { - return pos === length - } - this.retain = retain; - this.insertCharacters = insertCharacters; - this.insertElementStart = insertElementStart; - this.insertElementEnd = insertElementEnd; - this.deleteCharacters = deleteCharacters; - this.deleteElementStart = deleteElementStart; - this.deleteElementEnd = deleteElementEnd; - this.replaceAttributes = replaceAttributes; - this.updateAttributes = updateAttributes; - this.atEnd = atEnd -}; xmldom.XPathIterator = function XPathIterator() { }; xmldom.XPath = function() { @@ -5502,7 +5464,7 @@ xmldom.XPath = function() { return a !== -1 && (a < b || b === -1) && (a < c || c === -1) } function parseXPathStep(xpath, pos, end, steps) { - var location = "", predicates = [], value, brapos = xpath.indexOf("[", pos), slapos = xpath.indexOf("/", pos), eqpos = xpath.indexOf("=", pos), depth = 0, start = 0; + var location = "", predicates = [], brapos = xpath.indexOf("[", pos), slapos = xpath.indexOf("/", pos), eqpos = xpath.indexOf("=", pos); if(isSmallestPositive(slapos, brapos, eqpos)) { location = xpath.substring(pos, slapos); pos = slapos + 1 @@ -5534,7 +5496,7 @@ xmldom.XPath = function() { }else { try { value = parseInt(value, 10) - }catch(e) { + }catch(ignore) { } } p = end @@ -5543,7 +5505,7 @@ xmldom.XPath = function() { return{steps:steps, value:value} } parsePredicates = function parsePredicates(xpath, start, predicates) { - var pos = start, l = xpath.length, selector, depth = 0; + var pos = start, l = xpath.length, depth = 0; while(pos < l) { if(xpath[pos] === "]") { depth -= 1; @@ -5585,7 +5547,7 @@ xmldom.XPath = function() { it.reset() }; this.next = function next() { - var node = it.next(), attr; + var node = it.next(); while(node) { node = node.getAttributeNodeNS(namespace, localName); if(node) { @@ -5668,7 +5630,7 @@ xmldom.XPath = function() { }) } createXPathPathIterator = function createXPathPathIterator(it, xpath, namespaceResolver) { - var i, j, step, location, namespace, localName, prefix, p; + var i, j, step, location, p; for(i = 0;i < xpath.steps.length;i += 1) { step = xpath.steps[i]; location = step.location; @@ -5695,7 +5657,7 @@ xmldom.XPath = function() { return it }; function fallback(node, xpath, namespaceResolver) { - var it = new XPathNodeIterator, i, nodelist, parsedXPath, pos; + var it = new XPathNodeIterator, i, nodelist, parsedXPath; it.setNode(node); parsedXPath = parseXPath(xpath); it = createXPathPathIterator(it, parsedXPath, namespaceResolver); @@ -5762,9 +5724,219 @@ xmldom.XPath = function() { @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ +gui.AnnotationViewManager = function AnnotationViewManager(odfFragment, annotationsPane) { + var annotations = [], doc = odfFragment.ownerDocument, odfUtils = new odf.OdfUtils, CONNECTOR_MARGIN = 30, NOTE_MARGIN = 20, window = runtime.getWindow(); + runtime.assert(Boolean(window), "Expected to be run in an environment which has a global window, like a browser."); + function wrapAnnotation(annotation) { + var annotationWrapper = doc.createElement("div"), annotationNote = doc.createElement("div"), connectorHorizontal = doc.createElement("div"), connectorAngular = doc.createElement("div"), annotationNode = annotation.node; + annotationWrapper.className = "annotationWrapper"; + annotationNode.parentNode.insertBefore(annotationWrapper, annotationNode); + annotationNote.className = "annotationNote"; + annotationNote.appendChild(annotationNode); + connectorHorizontal.className = "annotationConnector horizontal"; + connectorAngular.className = "annotationConnector angular"; + annotationWrapper.appendChild(annotationNote); + annotationWrapper.appendChild(connectorHorizontal); + annotationWrapper.appendChild(connectorAngular) + } + function unwrapAnnotation(annotation) { + var annotationNode = annotation.node, annotationWrapper = annotationNode.parentNode.parentNode; + if(annotationWrapper.localName === "div") { + annotationWrapper.parentNode.insertBefore(annotationNode, annotationWrapper); + annotationWrapper.parentNode.removeChild(annotationWrapper) + } + } + function highlightAnnotation(annotation) { + var annotationNode = annotation.node, annotationEnd = annotation.end, range = doc.createRange(), textNodes; + if(annotationEnd) { + range.setStart(annotationNode, annotationNode.childNodes.length); + range.setEnd(annotationEnd, 0); + textNodes = odfUtils.getTextNodes(range, false); + textNodes.forEach(function(n) { + var container = doc.createElement("span"); + container.className = "annotationHighlight"; + container.setAttribute("annotation", annotationNode.getAttributeNS(odf.Namespaces.officens, "name")); + n.parentNode.insertBefore(container, n); + container.appendChild(n) + }) + } + range.detach() + } + function unhighlightAnnotation(annotation) { + var annotationName = annotation.node.getAttributeNS(odf.Namespaces.officens, "name"), highlightSpans = doc.querySelectorAll('span.annotationHighlight[annotation="' + annotationName + '"]'), i, j, container, children; + for(i = 0;i < highlightSpans.length;i += 1) { + container = highlightSpans[i]; + children = container.childNodes; + for(j = 0;j < children.length;j += 1) { + container.parentNode.insertBefore(children[j], container) + } + container.parentNode.removeChild(container) + } + } + function lineDistance(point1, point2) { + var xs = 0, ys = 0; + xs = point2.x - point1.x; + xs = xs * xs; + ys = point2.y - point1.y; + ys = ys * ys; + return Math.sqrt(xs + ys) + } + function renderAnnotation(annotation) { + var annotationNote = annotation.node.parentNode, connectorHorizontal = annotationNote.nextSibling, connectorAngular = connectorHorizontal.nextSibling, annotationWrapper = annotationNote.parentNode, connectorAngle = 0, previousAnnotation = annotations[annotations.indexOf(annotation) - 1], previousRect, creatorNode = annotation.node.getElementsByTagNameNS(odf.Namespaces.dcns, "creator")[0], creatorName; + annotationNote.style.left = annotationsPane.getBoundingClientRect().left - annotationWrapper.getBoundingClientRect().left + "px"; + annotationNote.style.width = annotationsPane.getBoundingClientRect().width + "px"; + connectorHorizontal.style.width = parseFloat(annotationNote.style.left) - CONNECTOR_MARGIN + "px"; + if(previousAnnotation) { + previousRect = previousAnnotation.node.parentNode.getBoundingClientRect(); + if(annotationWrapper.getBoundingClientRect().top - previousRect.bottom <= NOTE_MARGIN) { + annotationNote.style.top = Math.abs(annotationWrapper.getBoundingClientRect().top - previousRect.bottom) + NOTE_MARGIN + "px" + }else { + annotationNote.style.top = "0px" + } + } + connectorAngular.style.left = connectorHorizontal.getBoundingClientRect().width + "px"; + connectorAngular.style.width = lineDistance({x:connectorAngular.getBoundingClientRect().left, y:connectorAngular.getBoundingClientRect().top}, {x:annotationNote.getBoundingClientRect().left, y:annotationNote.getBoundingClientRect().top}) + "px"; + connectorAngle = Math.asin((annotationNote.getBoundingClientRect().top - connectorAngular.getBoundingClientRect().top) / parseFloat(connectorAngular.style.width)); + connectorAngular.style.transform = "rotate(" + connectorAngle + "rad)"; + connectorAngular.style.MozTransform = "rotate(" + connectorAngle + "rad)"; + connectorAngular.style.WebkitTransform = "rotate(" + connectorAngle + "rad)"; + connectorAngular.style.msTransform = "rotate(" + connectorAngle + "rad)"; + if(creatorNode) { + creatorName = window.getComputedStyle((creatorNode), ":before").content; + if(creatorName && creatorName !== "none") { + creatorName = creatorName.substring(1, creatorName.length - 1); + if(creatorNode.firstChild) { + creatorNode.firstChild.nodeValue = creatorName + }else { + creatorNode.appendChild(doc.createTextNode(creatorName)) + } + } + } + } + function sortAnnotations() { + annotations.sort(function(a, b) { + if(a.node.compareDocumentPosition(b.node) === Node.DOCUMENT_POSITION_FOLLOWING) { + return-1 + } + return 1 + }) + } + function rerenderAnnotations() { + var i; + for(i = 0;i < annotations.length;i += 1) { + renderAnnotation(annotations[i]) + } + } + this.rerenderAnnotations = rerenderAnnotations; + function addAnnotation(annotation) { + annotations.push({node:annotation.node, end:annotation.end}); + sortAnnotations(); + wrapAnnotation(annotation); + if(annotation.end) { + highlightAnnotation(annotation) + } + rerenderAnnotations() + } + this.addAnnotation = addAnnotation; + function forgetAnnotation(annotation) { + unwrapAnnotation(annotation); + unhighlightAnnotation(annotation); + annotations.splice(annotations.indexOf(annotation), 1) + } + function forgetAnnotations() { + while(annotations.length) { + forgetAnnotation(annotations[0]) + } + } + this.forgetAnnotations = forgetAnnotations +}; +/* + + 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/ +*/ +odf.OdfNodeFilter = function OdfNodeFilter() { + this.acceptNode = function(node) { + var result; + if(node.namespaceURI === "http://www.w3.org/1999/xhtml") { + result = NodeFilter.FILTER_SKIP + }else { + if(node.namespaceURI && node.namespaceURI.match(/^urn:webodf:/)) { + result = NodeFilter.FILTER_REJECT + }else { + result = NodeFilter.FILTER_ACCEPT + } + } + return result + } +}; +/* + + Copyright (C) 2012-2013 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ odf.Namespaces = function() { var drawns = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0", fons = "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0", officens = "urn:oasis:names:tc:opendocument:xmlns:office:1.0", presentationns = "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0", stylens = "urn:oasis:names:tc:opendocument:xmlns:style:1.0", svgns = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0", tablens = "urn:oasis:names:tc:opendocument:xmlns:table:1.0", textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", - xlinkns = "http://www.w3.org/1999/xlink", xmlns = "http://www.w3.org/XML/1998/namespace", namespaceMap = {"draw":drawns, "fo":fons, "office":officens, "presentation":presentationns, "style":stylens, "svg":svgns, "table":tablens, "text":textns, "xlink":xlinkns, "xml":xmlns}, namespaces; + dr3dns = "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0", numberns = "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0", xlinkns = "http://www.w3.org/1999/xlink", xmlns = "http://www.w3.org/XML/1998/namespace", dcns = "http://purl.org/dc/elements/1.1/", webodfns = "urn:webodf", namespaceMap = {"draw":drawns, "fo":fons, "office":officens, "presentation":presentationns, "style":stylens, "svg":svgns, "table":tablens, "text":textns, "dr3d":dr3dns, "numberns":numberns, "xlink":xlinkns, "xml":xmlns, + "dc":dcns, "webodf":webodfns}, namespaces; function forEachPrefix(cb) { var prefix; for(prefix in namespaceMap) { @@ -5790,46 +5962,47 @@ odf.Namespaces = function() { namespaces.svgns = svgns; namespaces.tablens = tablens; namespaces.textns = textns; + namespaces.dr3dns = dr3dns; + namespaces.numberns = numberns; namespaces.xlinkns = xlinkns; namespaces.xmlns = xmlns; + namespaces.dcns = dcns; + namespaces.webodfns = webodfns; return namespaces }(); runtime.loadClass("xmldom.XPath"); odf.StyleInfo = function StyleInfo() { - var chartns = "urn:oasis:names:tc:opendocument:xmlns:chart:1.0", dbns = "urn:oasis:names:tc:opendocument:xmlns:database:1.0", dr3dns = "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0", drawns = "urn:oasis:names:tc:opendocument:xmlns:drawing: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", xmlns = "http://www.w3.org/XML/1998/namespace", nsprefixes = {"urn:oasis:names:tc:opendocument:xmlns:chart:1.0":"chart:", "urn:oasis:names:tc:opendocument:xmlns:database:1.0":"db:", - "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0":"dr3d:", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0":"draw:", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0":"fo:", "urn:oasis:names:tc:opendocument:xmlns:form:1.0":"form:", "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0":"number:", "urn:oasis:names:tc:opendocument:xmlns:office:1.0":"office:", "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0":"presentation:", "urn:oasis:names:tc:opendocument:xmlns:style:1.0":"style:", - "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0":"svg:", "urn:oasis:names:tc:opendocument:xmlns:table:1.0":"table:", "urn:oasis:names:tc:opendocument:xmlns:text:1.0":"chart:", "http://www.w3.org/XML/1998/namespace":"xml:"}, elementstyles = {"text":[{ens:stylens, en:"tab-stop", ans:stylens, a:"leader-text-style"}, {ens:stylens, en:"drop-cap", ans:stylens, a:"style-name"}, {ens:textns, en:"notes-configuration", ans:textns, a:"citation-body-style-name"}, {ens:textns, en:"notes-configuration", - ans:textns, a:"citation-style-name"}, {ens:textns, en:"a", ans:textns, a:"style-name"}, {ens:textns, en:"alphabetical-index", ans:textns, a:"style-name"}, {ens:textns, en:"linenumbering-configuration", ans:textns, a:"style-name"}, {ens:textns, en:"list-level-style-number", ans:textns, a:"style-name"}, {ens:textns, en:"ruby-text", ans:textns, a:"style-name"}, {ens:textns, en:"span", ans:textns, a:"style-name"}, {ens:textns, en:"a", ans:textns, a:"visited-style-name"}, {ens:stylens, en:"text-properties", - ans:stylens, a:"text-line-through-text-style"}, {ens:textns, en:"alphabetical-index-source", ans:textns, a:"main-entry-style-name"}, {ens:textns, en:"index-entry-bibliography", ans:textns, a:"style-name"}, {ens:textns, en:"index-entry-chapter", ans:textns, a:"style-name"}, {ens:textns, en:"index-entry-link-end", ans:textns, a:"style-name"}, {ens:textns, en:"index-entry-link-start", ans:textns, a:"style-name"}, {ens:textns, en:"index-entry-page-number", ans:textns, a:"style-name"}, {ens:textns, - en:"index-entry-span", ans:textns, a:"style-name"}, {ens:textns, en:"index-entry-tab-stop", ans:textns, a:"style-name"}, {ens:textns, en:"index-entry-text", ans:textns, a:"style-name"}, {ens:textns, en:"index-title-template", ans:textns, a:"style-name"}, {ens:textns, en:"list-level-style-bullet", ans:textns, a:"style-name"}, {ens:textns, en:"outline-level-style", ans:textns, a:"style-name"}], "paragraph":[{ens:drawns, en:"caption", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"circle", ans:drawns, - a:"text-style-name"}, {ens:drawns, en:"connector", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"control", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"custom-shape", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"ellipse", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"frame", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"line", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"measure", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"path", ans:drawns, a:"text-style-name"}, - {ens:drawns, en:"polygon", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"polyline", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"rect", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"regular-polygon", ans:drawns, a:"text-style-name"}, {ens:officens, en:"annotation", ans:drawns, a:"text-style-name"}, {ens:formns, en:"column", ans:formns, a:"text-style-name"}, {ens:stylens, en:"style", ans:stylens, a:"next-style-name"}, {ens:tablens, en:"body", ans:tablens, a:"paragraph-style-name"}, - {ens:tablens, en:"even-columns", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"even-rows", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"first-column", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"first-row", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"last-column", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"last-row", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"odd-columns", ans:tablens, a:"paragraph-style-name"}, - {ens:tablens, en:"odd-rows", ans:tablens, a:"paragraph-style-name"}, {ens:textns, en:"notes-configuration", ans:textns, a:"default-style-name"}, {ens:textns, en:"alphabetical-index-entry-template", ans:textns, a:"style-name"}, {ens:textns, en:"bibliography-entry-template", ans:textns, a:"style-name"}, {ens:textns, en:"h", ans:textns, a:"style-name"}, {ens:textns, en:"illustration-index-entry-template", ans:textns, a:"style-name"}, {ens:textns, en:"index-source-style", ans:textns, a:"style-name"}, - {ens:textns, en:"object-index-entry-template", ans:textns, a:"style-name"}, {ens:textns, en:"p", ans:textns, a:"style-name"}, {ens:textns, en:"table-index-entry-template", ans:textns, a:"style-name"}, {ens:textns, en:"table-of-content-entry-template", ans:textns, a:"style-name"}, {ens:textns, en:"table-index-entry-template", ans:textns, a:"style-name"}, {ens:textns, en:"user-index-entry-template", ans:textns, a:"style-name"}, {ens:stylens, en:"page-layout-properties", ans:stylens, a:"register-truth-ref-style-name"}], - "chart":[{ens:chartns, en:"axis", ans:chartns, a:"style-name"}, {ens:chartns, en:"chart", ans:chartns, a:"style-name"}, {ens:chartns, en:"data-label", ans:chartns, a:"style-name"}, {ens:chartns, en:"data-point", ans:chartns, a:"style-name"}, {ens:chartns, en:"equation", ans:chartns, a:"style-name"}, {ens:chartns, en:"error-indicator", ans:chartns, a:"style-name"}, {ens:chartns, en:"floor", ans:chartns, a:"style-name"}, {ens:chartns, en:"footer", ans:chartns, a:"style-name"}, {ens:chartns, en:"grid", - ans:chartns, a:"style-name"}, {ens:chartns, en:"legend", ans:chartns, a:"style-name"}, {ens:chartns, en:"mean-value", ans:chartns, a:"style-name"}, {ens:chartns, en:"plot-area", ans:chartns, a:"style-name"}, {ens:chartns, en:"regression-curve", ans:chartns, a:"style-name"}, {ens:chartns, en:"series", ans:chartns, a:"style-name"}, {ens:chartns, en:"stock-gain-marker", ans:chartns, a:"style-name"}, {ens:chartns, en:"stock-loss-marker", ans:chartns, a:"style-name"}, {ens:chartns, en:"stock-range-line", - ans:chartns, a:"style-name"}, {ens:chartns, en:"subtitle", ans:chartns, a:"style-name"}, {ens:chartns, en:"title", ans:chartns, a:"style-name"}, {ens:chartns, en:"wall", ans:chartns, a:"style-name"}], "section":[{ens:textns, en:"alphabetical-index", ans:textns, a:"style-name"}, {ens:textns, en:"bibliography", ans:textns, a:"style-name"}, {ens:textns, en:"illustration-index", ans:textns, a:"style-name"}, {ens:textns, en:"index-title", ans:textns, a:"style-name"}, {ens:textns, en:"object-index", - ans:textns, a:"style-name"}, {ens:textns, en:"section", ans:textns, a:"style-name"}, {ens:textns, en:"table-of-content", ans:textns, a:"style-name"}, {ens:textns, en:"table-index", ans:textns, a:"style-name"}, {ens:textns, en:"user-index", ans:textns, a:"style-name"}], "ruby":[{ens:textns, en:"ruby", ans:textns, a:"style-name"}], "table":[{ens:dbns, en:"query", ans:dbns, a:"style-name"}, {ens:dbns, en:"table-representation", ans:dbns, a:"style-name"}, {ens:tablens, en:"background", ans:tablens, - a:"style-name"}, {ens:tablens, en:"table", ans:tablens, a:"style-name"}], "table-column":[{ens:dbns, en:"column", ans:dbns, a:"style-name"}, {ens:tablens, en:"table-column", ans:tablens, a:"style-name"}], "table-row":[{ens:dbns, en:"query", ans:dbns, a:"default-row-style-name"}, {ens:dbns, en:"table-representation", ans:dbns, a:"default-row-style-name"}, {ens:tablens, en:"table-row", ans:tablens, a:"style-name"}], "table-cell":[{ens:dbns, en:"column", ans:dbns, a:"default-cell-style-name"}, {ens:tablens, - en:"table-column", ans:tablens, a:"default-cell-style-name"}, {ens:tablens, en:"table-row", ans:tablens, a:"default-cell-style-name"}, {ens:tablens, en:"body", ans:tablens, a:"style-name"}, {ens:tablens, en:"covered-table-cell", ans:tablens, a:"style-name"}, {ens:tablens, en:"even-columns", ans:tablens, a:"style-name"}, {ens:tablens, en:"covered-table-cell", ans:tablens, a:"style-name"}, {ens:tablens, en:"even-columns", ans:tablens, a:"style-name"}, {ens:tablens, en:"even-rows", ans:tablens, a:"style-name"}, - {ens:tablens, en:"first-column", ans:tablens, a:"style-name"}, {ens:tablens, en:"first-row", ans:tablens, a:"style-name"}, {ens:tablens, en:"last-column", ans:tablens, a:"style-name"}, {ens:tablens, en:"last-row", ans:tablens, a:"style-name"}, {ens:tablens, en:"odd-columns", ans:tablens, a:"style-name"}, {ens:tablens, en:"odd-rows", ans:tablens, a:"style-name"}, {ens:tablens, en:"table-cell", ans:tablens, a:"style-name"}], "graphic":[{ens:dr3dns, en:"cube", ans:drawns, a:"style-name"}, {ens:dr3dns, - en:"extrude", ans:drawns, a:"style-name"}, {ens:dr3dns, en:"rotate", ans:drawns, a:"style-name"}, {ens:dr3dns, en:"scene", ans:drawns, a:"style-name"}, {ens:dr3dns, en:"sphere", ans:drawns, a:"style-name"}, {ens:drawns, en:"caption", ans:drawns, a:"style-name"}, {ens:drawns, en:"circle", ans:drawns, a:"style-name"}, {ens:drawns, en:"connector", ans:drawns, a:"style-name"}, {ens:drawns, en:"control", ans:drawns, a:"style-name"}, {ens:drawns, en:"custom-shape", ans:drawns, a:"style-name"}, {ens:drawns, - en:"ellipse", ans:drawns, a:"style-name"}, {ens:drawns, en:"frame", ans:drawns, a:"style-name"}, {ens:drawns, en:"g", ans:drawns, a:"style-name"}, {ens:drawns, en:"line", ans:drawns, a:"style-name"}, {ens:drawns, en:"measure", ans:drawns, a:"style-name"}, {ens:drawns, en:"page-thumbnail", ans:drawns, a:"style-name"}, {ens:drawns, en:"path", ans:drawns, a:"style-name"}, {ens:drawns, en:"polygon", ans:drawns, a:"style-name"}, {ens:drawns, en:"polyline", ans:drawns, a:"style-name"}, {ens:drawns, en:"rect", - ans:drawns, a:"style-name"}, {ens:drawns, en:"regular-polygon", ans:drawns, a:"style-name"}, {ens:officens, en:"annotation", ans:drawns, a:"style-name"}], "presentation":[{ens:dr3dns, en:"cube", ans:presentationns, a:"style-name"}, {ens:dr3dns, en:"extrude", ans:presentationns, a:"style-name"}, {ens:dr3dns, en:"rotate", ans:presentationns, a:"style-name"}, {ens:dr3dns, en:"scene", ans:presentationns, a:"style-name"}, {ens:dr3dns, en:"sphere", ans:presentationns, a:"style-name"}, {ens:drawns, en:"caption", - ans:presentationns, a:"style-name"}, {ens:drawns, en:"circle", ans:presentationns, a:"style-name"}, {ens:drawns, en:"connector", ans:presentationns, a:"style-name"}, {ens:drawns, en:"control", ans:presentationns, a:"style-name"}, {ens:drawns, en:"custom-shape", ans:presentationns, a:"style-name"}, {ens:drawns, en:"ellipse", ans:presentationns, a:"style-name"}, {ens:drawns, en:"frame", ans:presentationns, a:"style-name"}, {ens:drawns, en:"g", ans:presentationns, a:"style-name"}, {ens:drawns, en:"line", - ans:presentationns, a:"style-name"}, {ens:drawns, en:"measure", ans:presentationns, a:"style-name"}, {ens:drawns, en:"page-thumbnail", ans:presentationns, a:"style-name"}, {ens:drawns, en:"path", ans:presentationns, a:"style-name"}, {ens:drawns, en:"polygon", ans:presentationns, a:"style-name"}, {ens:drawns, en:"polyline", ans:presentationns, a:"style-name"}, {ens:drawns, en:"rect", ans:presentationns, a:"style-name"}, {ens:drawns, en:"regular-polygon", ans:presentationns, a:"style-name"}, {ens:officens, - en:"annotation", ans:presentationns, a:"style-name"}], "drawing-page":[{ens:drawns, en:"page", ans:drawns, a:"style-name"}, {ens:presentationns, en:"notes", ans:drawns, a:"style-name"}, {ens:stylens, en:"handout-master", ans:drawns, a:"style-name"}, {ens:stylens, en:"master-page", ans:drawns, a:"style-name"}], "list-style":[{ens:textns, en:"list", ans:textns, a:"style-name"}, {ens:textns, en:"numbered-paragraph", ans:textns, a:"style-name"}, {ens:textns, en:"list-item", ans:textns, a:"style-override"}, - {ens:stylens, en:"style", ans:stylens, a:"list-style-name"}, {ens:stylens, en:"style", ans:stylens, a:"data-style-name"}, {ens:stylens, en:"style", ans:stylens, a:"percentage-data-style-name"}, {ens:presentationns, en:"date-time-decl", ans:stylens, a:"data-style-name"}, {ens:textns, en:"creation-date", ans:stylens, a:"data-style-name"}, {ens:textns, en:"creation-time", ans:stylens, a:"data-style-name"}, {ens:textns, en:"database-display", ans:stylens, a:"data-style-name"}, {ens:textns, en:"date", - ans:stylens, a:"data-style-name"}, {ens:textns, en:"editing-duration", ans:stylens, a:"data-style-name"}, {ens:textns, en:"expression", ans:stylens, a:"data-style-name"}, {ens:textns, en:"meta-field", ans:stylens, a:"data-style-name"}, {ens:textns, en:"modification-date", ans:stylens, a:"data-style-name"}, {ens:textns, en:"modification-time", ans:stylens, a:"data-style-name"}, {ens:textns, en:"print-date", ans:stylens, a:"data-style-name"}, {ens:textns, en:"print-time", ans:stylens, a:"data-style-name"}, - {ens:textns, en:"table-formula", ans:stylens, a:"data-style-name"}, {ens:textns, en:"time", ans:stylens, a:"data-style-name"}, {ens:textns, en:"user-defined", ans:stylens, a:"data-style-name"}, {ens:textns, en:"user-field-get", ans:stylens, a:"data-style-name"}, {ens:textns, en:"user-field-input", ans:stylens, a:"data-style-name"}, {ens:textns, en:"variable-get", ans:stylens, a:"data-style-name"}, {ens:textns, en:"variable-input", ans:stylens, a:"data-style-name"}, {ens:textns, en:"variable-set", - ans:stylens, a:"data-style-name"}], "data":[{ens:stylens, en:"style", ans:stylens, a:"data-style-name"}, {ens:stylens, en:"style", ans:stylens, a:"percentage-data-style-name"}, {ens:presentationns, en:"date-time-decl", ans:stylens, a:"data-style-name"}, {ens:textns, en:"creation-date", ans:stylens, a:"data-style-name"}, {ens:textns, en:"creation-time", ans:stylens, a:"data-style-name"}, {ens:textns, en:"database-display", ans:stylens, a:"data-style-name"}, {ens:textns, en:"date", ans:stylens, a:"data-style-name"}, - {ens:textns, en:"editing-duration", ans:stylens, a:"data-style-name"}, {ens:textns, en:"expression", ans:stylens, a:"data-style-name"}, {ens:textns, en:"meta-field", ans:stylens, a:"data-style-name"}, {ens:textns, en:"modification-date", ans:stylens, a:"data-style-name"}, {ens:textns, en:"modification-time", ans:stylens, a:"data-style-name"}, {ens:textns, en:"print-date", ans:stylens, a:"data-style-name"}, {ens:textns, en:"print-time", ans:stylens, a:"data-style-name"}, {ens:textns, en:"table-formula", - ans:stylens, a:"data-style-name"}, {ens:textns, en:"time", ans:stylens, a:"data-style-name"}, {ens:textns, en:"user-defined", ans:stylens, a:"data-style-name"}, {ens:textns, en:"user-field-get", ans:stylens, a:"data-style-name"}, {ens:textns, en:"user-field-input", ans:stylens, a:"data-style-name"}, {ens:textns, en:"variable-get", ans:stylens, a:"data-style-name"}, {ens:textns, en:"variable-input", ans:stylens, a:"data-style-name"}, {ens:textns, en:"variable-set", ans:stylens, a:"data-style-name"}], - "page-layout":[{ens:presentationns, en:"notes", ans:stylens, a:"page-layout-name"}, {ens:stylens, en:"handout-master", ans:stylens, a:"page-layout-name"}, {ens:stylens, en:"master-page", ans:stylens, a:"page-layout-name"}]}, elements, xpath = new xmldom.XPath; + var chartns = "urn:oasis:names:tc:opendocument:xmlns:chart:1.0", dbns = "urn:oasis:names:tc:opendocument:xmlns:database:1.0", dr3dns = "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0", drawns = "urn:oasis:names:tc:opendocument:xmlns:drawing: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", tablens = "urn:oasis:names:tc:opendocument:xmlns:table:1.0", textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", nsprefixes = {"urn:oasis:names:tc:opendocument:xmlns:chart:1.0":"chart:", "urn:oasis:names:tc:opendocument:xmlns:database:1.0":"db:", "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0":"dr3d:", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0":"draw:", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0":"fo:", + "urn:oasis:names:tc:opendocument:xmlns:form:1.0":"form:", "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0":"number:", "urn:oasis:names:tc:opendocument:xmlns:office:1.0":"office:", "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0":"presentation:", "urn:oasis:names:tc:opendocument:xmlns:style:1.0":"style:", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0":"svg:", "urn:oasis:names:tc:opendocument:xmlns:table:1.0":"table:", "urn:oasis:names:tc:opendocument:xmlns:text:1.0":"chart:", + "http://www.w3.org/XML/1998/namespace":"xml:"}, elementstyles = {"text":[{ens:stylens, en:"tab-stop", ans:stylens, a:"leader-text-style"}, {ens:stylens, en:"drop-cap", ans:stylens, a:"style-name"}, {ens:textns, en:"notes-configuration", ans:textns, a:"citation-body-style-name"}, {ens:textns, en:"notes-configuration", ans:textns, a:"citation-style-name"}, {ens:textns, en:"a", ans:textns, a:"style-name"}, {ens:textns, en:"alphabetical-index", ans:textns, a:"style-name"}, {ens:textns, en:"linenumbering-configuration", + ans:textns, a:"style-name"}, {ens:textns, en:"list-level-style-number", ans:textns, a:"style-name"}, {ens:textns, en:"ruby-text", ans:textns, a:"style-name"}, {ens:textns, en:"span", ans:textns, a:"style-name"}, {ens:textns, en:"a", ans:textns, a:"visited-style-name"}, {ens:stylens, en:"text-properties", ans:stylens, a:"text-line-through-text-style"}, {ens:textns, en:"alphabetical-index-source", ans:textns, a:"main-entry-style-name"}, {ens:textns, en:"index-entry-bibliography", ans:textns, a:"style-name"}, + {ens:textns, en:"index-entry-chapter", ans:textns, a:"style-name"}, {ens:textns, en:"index-entry-link-end", ans:textns, a:"style-name"}, {ens:textns, en:"index-entry-link-start", ans:textns, a:"style-name"}, {ens:textns, en:"index-entry-page-number", ans:textns, a:"style-name"}, {ens:textns, en:"index-entry-span", ans:textns, a:"style-name"}, {ens:textns, en:"index-entry-tab-stop", ans:textns, a:"style-name"}, {ens:textns, en:"index-entry-text", ans:textns, a:"style-name"}, {ens:textns, en:"index-title-template", + ans:textns, a:"style-name"}, {ens:textns, en:"list-level-style-bullet", ans:textns, a:"style-name"}, {ens:textns, en:"outline-level-style", ans:textns, a:"style-name"}], "paragraph":[{ens:drawns, en:"caption", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"circle", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"connector", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"control", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"custom-shape", ans:drawns, a:"text-style-name"}, {ens:drawns, + en:"ellipse", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"frame", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"line", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"measure", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"path", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"polygon", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"polyline", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"rect", ans:drawns, a:"text-style-name"}, {ens:drawns, en:"regular-polygon", + ans:drawns, a:"text-style-name"}, {ens:officens, en:"annotation", ans:drawns, a:"text-style-name"}, {ens:formns, en:"column", ans:formns, a:"text-style-name"}, {ens:stylens, en:"style", ans:stylens, a:"next-style-name"}, {ens:tablens, en:"body", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"even-columns", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"even-rows", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"first-column", ans:tablens, a:"paragraph-style-name"}, + {ens:tablens, en:"first-row", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"last-column", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"last-row", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"odd-columns", ans:tablens, a:"paragraph-style-name"}, {ens:tablens, en:"odd-rows", ans:tablens, a:"paragraph-style-name"}, {ens:textns, en:"notes-configuration", ans:textns, a:"default-style-name"}, {ens:textns, en:"alphabetical-index-entry-template", ans:textns, a:"style-name"}, + {ens:textns, en:"bibliography-entry-template", ans:textns, a:"style-name"}, {ens:textns, en:"h", ans:textns, a:"style-name"}, {ens:textns, en:"illustration-index-entry-template", ans:textns, a:"style-name"}, {ens:textns, en:"index-source-style", ans:textns, a:"style-name"}, {ens:textns, en:"object-index-entry-template", ans:textns, a:"style-name"}, {ens:textns, en:"p", ans:textns, a:"style-name"}, {ens:textns, en:"table-index-entry-template", ans:textns, a:"style-name"}, {ens:textns, en:"table-of-content-entry-template", + ans:textns, a:"style-name"}, {ens:textns, en:"table-index-entry-template", ans:textns, a:"style-name"}, {ens:textns, en:"user-index-entry-template", ans:textns, a:"style-name"}, {ens:stylens, en:"page-layout-properties", ans:stylens, a:"register-truth-ref-style-name"}], "chart":[{ens:chartns, en:"axis", ans:chartns, a:"style-name"}, {ens:chartns, en:"chart", ans:chartns, a:"style-name"}, {ens:chartns, en:"data-label", ans:chartns, a:"style-name"}, {ens:chartns, en:"data-point", ans:chartns, a:"style-name"}, + {ens:chartns, en:"equation", ans:chartns, a:"style-name"}, {ens:chartns, en:"error-indicator", ans:chartns, a:"style-name"}, {ens:chartns, en:"floor", ans:chartns, a:"style-name"}, {ens:chartns, en:"footer", ans:chartns, a:"style-name"}, {ens:chartns, en:"grid", ans:chartns, a:"style-name"}, {ens:chartns, en:"legend", ans:chartns, a:"style-name"}, {ens:chartns, en:"mean-value", ans:chartns, a:"style-name"}, {ens:chartns, en:"plot-area", ans:chartns, a:"style-name"}, {ens:chartns, en:"regression-curve", + ans:chartns, a:"style-name"}, {ens:chartns, en:"series", ans:chartns, a:"style-name"}, {ens:chartns, en:"stock-gain-marker", ans:chartns, a:"style-name"}, {ens:chartns, en:"stock-loss-marker", ans:chartns, a:"style-name"}, {ens:chartns, en:"stock-range-line", ans:chartns, a:"style-name"}, {ens:chartns, en:"subtitle", ans:chartns, a:"style-name"}, {ens:chartns, en:"title", ans:chartns, a:"style-name"}, {ens:chartns, en:"wall", ans:chartns, a:"style-name"}], "section":[{ens:textns, en:"alphabetical-index", + ans:textns, a:"style-name"}, {ens:textns, en:"bibliography", ans:textns, a:"style-name"}, {ens:textns, en:"illustration-index", ans:textns, a:"style-name"}, {ens:textns, en:"index-title", ans:textns, a:"style-name"}, {ens:textns, en:"object-index", ans:textns, a:"style-name"}, {ens:textns, en:"section", ans:textns, a:"style-name"}, {ens:textns, en:"table-of-content", ans:textns, a:"style-name"}, {ens:textns, en:"table-index", ans:textns, a:"style-name"}, {ens:textns, en:"user-index", ans:textns, + a:"style-name"}], "ruby":[{ens:textns, en:"ruby", ans:textns, a:"style-name"}], "table":[{ens:dbns, en:"query", ans:dbns, a:"style-name"}, {ens:dbns, en:"table-representation", ans:dbns, a:"style-name"}, {ens:tablens, en:"background", ans:tablens, a:"style-name"}, {ens:tablens, en:"table", ans:tablens, a:"style-name"}], "table-column":[{ens:dbns, en:"column", ans:dbns, a:"style-name"}, {ens:tablens, en:"table-column", ans:tablens, a:"style-name"}], "table-row":[{ens:dbns, en:"query", ans:dbns, + a:"default-row-style-name"}, {ens:dbns, en:"table-representation", ans:dbns, a:"default-row-style-name"}, {ens:tablens, en:"table-row", ans:tablens, a:"style-name"}], "table-cell":[{ens:dbns, en:"column", ans:dbns, a:"default-cell-style-name"}, {ens:tablens, en:"table-column", ans:tablens, a:"default-cell-style-name"}, {ens:tablens, en:"table-row", ans:tablens, a:"default-cell-style-name"}, {ens:tablens, en:"body", ans:tablens, a:"style-name"}, {ens:tablens, en:"covered-table-cell", ans:tablens, + a:"style-name"}, {ens:tablens, en:"even-columns", ans:tablens, a:"style-name"}, {ens:tablens, en:"covered-table-cell", ans:tablens, a:"style-name"}, {ens:tablens, en:"even-columns", ans:tablens, a:"style-name"}, {ens:tablens, en:"even-rows", ans:tablens, a:"style-name"}, {ens:tablens, en:"first-column", ans:tablens, a:"style-name"}, {ens:tablens, en:"first-row", ans:tablens, a:"style-name"}, {ens:tablens, en:"last-column", ans:tablens, a:"style-name"}, {ens:tablens, en:"last-row", ans:tablens, + a:"style-name"}, {ens:tablens, en:"odd-columns", ans:tablens, a:"style-name"}, {ens:tablens, en:"odd-rows", ans:tablens, a:"style-name"}, {ens:tablens, en:"table-cell", ans:tablens, a:"style-name"}], "graphic":[{ens:dr3dns, en:"cube", ans:drawns, a:"style-name"}, {ens:dr3dns, en:"extrude", ans:drawns, a:"style-name"}, {ens:dr3dns, en:"rotate", ans:drawns, a:"style-name"}, {ens:dr3dns, en:"scene", ans:drawns, a:"style-name"}, {ens:dr3dns, en:"sphere", ans:drawns, a:"style-name"}, {ens:drawns, en:"caption", + ans:drawns, a:"style-name"}, {ens:drawns, en:"circle", ans:drawns, a:"style-name"}, {ens:drawns, en:"connector", ans:drawns, a:"style-name"}, {ens:drawns, en:"control", ans:drawns, a:"style-name"}, {ens:drawns, en:"custom-shape", ans:drawns, a:"style-name"}, {ens:drawns, en:"ellipse", ans:drawns, a:"style-name"}, {ens:drawns, en:"frame", ans:drawns, a:"style-name"}, {ens:drawns, en:"g", ans:drawns, a:"style-name"}, {ens:drawns, en:"line", ans:drawns, a:"style-name"}, {ens:drawns, en:"measure", + ans:drawns, a:"style-name"}, {ens:drawns, en:"page-thumbnail", ans:drawns, a:"style-name"}, {ens:drawns, en:"path", ans:drawns, a:"style-name"}, {ens:drawns, en:"polygon", ans:drawns, a:"style-name"}, {ens:drawns, en:"polyline", ans:drawns, a:"style-name"}, {ens:drawns, en:"rect", ans:drawns, a:"style-name"}, {ens:drawns, en:"regular-polygon", ans:drawns, a:"style-name"}, {ens:officens, en:"annotation", ans:drawns, a:"style-name"}], "presentation":[{ens:dr3dns, en:"cube", ans:presentationns, a:"style-name"}, + {ens:dr3dns, en:"extrude", ans:presentationns, a:"style-name"}, {ens:dr3dns, en:"rotate", ans:presentationns, a:"style-name"}, {ens:dr3dns, en:"scene", ans:presentationns, a:"style-name"}, {ens:dr3dns, en:"sphere", ans:presentationns, a:"style-name"}, {ens:drawns, en:"caption", ans:presentationns, a:"style-name"}, {ens:drawns, en:"circle", ans:presentationns, a:"style-name"}, {ens:drawns, en:"connector", ans:presentationns, a:"style-name"}, {ens:drawns, en:"control", ans:presentationns, a:"style-name"}, + {ens:drawns, en:"custom-shape", ans:presentationns, a:"style-name"}, {ens:drawns, en:"ellipse", ans:presentationns, a:"style-name"}, {ens:drawns, en:"frame", ans:presentationns, a:"style-name"}, {ens:drawns, en:"g", ans:presentationns, a:"style-name"}, {ens:drawns, en:"line", ans:presentationns, a:"style-name"}, {ens:drawns, en:"measure", ans:presentationns, a:"style-name"}, {ens:drawns, en:"page-thumbnail", ans:presentationns, a:"style-name"}, {ens:drawns, en:"path", ans:presentationns, a:"style-name"}, + {ens:drawns, en:"polygon", ans:presentationns, a:"style-name"}, {ens:drawns, en:"polyline", ans:presentationns, a:"style-name"}, {ens:drawns, en:"rect", ans:presentationns, a:"style-name"}, {ens:drawns, en:"regular-polygon", ans:presentationns, a:"style-name"}, {ens:officens, en:"annotation", ans:presentationns, a:"style-name"}], "drawing-page":[{ens:drawns, en:"page", ans:drawns, a:"style-name"}, {ens:presentationns, en:"notes", ans:drawns, a:"style-name"}, {ens:stylens, en:"handout-master", ans:drawns, + a:"style-name"}, {ens:stylens, en:"master-page", ans:drawns, a:"style-name"}], "list-style":[{ens:textns, en:"list", ans:textns, a:"style-name"}, {ens:textns, en:"numbered-paragraph", ans:textns, a:"style-name"}, {ens:textns, en:"list-item", ans:textns, a:"style-override"}, {ens:stylens, en:"style", ans:stylens, a:"list-style-name"}], "data":[{ens:stylens, en:"style", ans:stylens, a:"data-style-name"}, {ens:stylens, en:"style", ans:stylens, a:"percentage-data-style-name"}, {ens:presentationns, + en:"date-time-decl", ans:stylens, a:"data-style-name"}, {ens:textns, en:"creation-date", ans:stylens, a:"data-style-name"}, {ens:textns, en:"creation-time", ans:stylens, a:"data-style-name"}, {ens:textns, en:"database-display", ans:stylens, a:"data-style-name"}, {ens:textns, en:"date", ans:stylens, a:"data-style-name"}, {ens:textns, en:"editing-duration", ans:stylens, a:"data-style-name"}, {ens:textns, en:"expression", ans:stylens, a:"data-style-name"}, {ens:textns, en:"meta-field", ans:stylens, + a:"data-style-name"}, {ens:textns, en:"modification-date", ans:stylens, a:"data-style-name"}, {ens:textns, en:"modification-time", ans:stylens, a:"data-style-name"}, {ens:textns, en:"print-date", ans:stylens, a:"data-style-name"}, {ens:textns, en:"print-time", ans:stylens, a:"data-style-name"}, {ens:textns, en:"table-formula", ans:stylens, a:"data-style-name"}, {ens:textns, en:"time", ans:stylens, a:"data-style-name"}, {ens:textns, en:"user-defined", ans:stylens, a:"data-style-name"}, {ens:textns, + en:"user-field-get", ans:stylens, a:"data-style-name"}, {ens:textns, en:"user-field-input", ans:stylens, a:"data-style-name"}, {ens:textns, en:"variable-get", ans:stylens, a:"data-style-name"}, {ens:textns, en:"variable-input", ans:stylens, a:"data-style-name"}, {ens:textns, en:"variable-set", ans:stylens, a:"data-style-name"}], "page-layout":[{ens:presentationns, en:"notes", ans:stylens, a:"page-layout-name"}, {ens:stylens, en:"handout-master", ans:stylens, a:"page-layout-name"}, {ens:stylens, + en:"master-page", ans:stylens, a:"page-layout-name"}]}, elements, xpath = new xmldom.XPath; function hasDerivedStyles(odfbody, nsResolver, styleElement) { - var nodes, xp, stylens = nsResolver("style"), styleName = styleElement.getAttributeNS(stylens, "name"), styleFamily = styleElement.getAttributeNS(stylens, "family"); + var nodes, xp, resolver = nsResolver("style"), styleName = styleElement.getAttributeNS(resolver, "name"), styleFamily = styleElement.getAttributeNS(resolver, "family"); xp = "//style:*[@style:parent-style-name='" + styleName + "'][@style:family='" + styleFamily + "']"; nodes = xpath.getODFElementsWithXPath(odfbody, xp, nsResolver); if(nodes.length) { @@ -5837,10 +6010,6 @@ odf.StyleInfo = function StyleInfo() { } return false } - function canElementHaveStyle(family, element) { - var elname = elements[element.localName], elns = elname && elname[element.namespaceURI], length = elns ? elns.length : 0; - return length > 0 - } function prefixUsedStyleNames(styleUsingElementsRoot, prefix) { var elname = elements[styleUsingElementsRoot.localName], elns = elname && elname[styleUsingElementsRoot.namespaceURI], length = elns ? elns.length : 0, i, stylename, e; for(i = 0;i < length;i += 1) { @@ -6001,20 +6170,20 @@ odf.StyleInfo = function StyleInfo() { return knownStyles } function inverse(elementstyles) { - var keyname, i, l, list, item, elements = {}, map, array; + var keyname, i, l, list, item, e = {}, map, array; for(keyname in elementstyles) { if(elementstyles.hasOwnProperty(keyname)) { list = elementstyles[keyname]; l = list.length; for(i = 0;i < l;i += 1) { item = list[i]; - map = elements[item.en] = elements[item.en] || {}; + map = e[item.en] = e[item.en] || {}; array = map[item.ens] = map[item.ens] || []; array.push({ns:item.ans, localname:item.a, keyname:keyname}) } } } - return elements + return e } function mergeRequiredStyles(styleDependency, usedStyles) { var family = usedStyles[styleDependency.family]; @@ -6056,7 +6225,6 @@ odf.StyleInfo = function StyleInfo() { mergeUsedAutomaticStyles(automaticStylesRoot, usedStyles) } }; - this.canElementHaveStyle = canElementHaveStyle; this.hasDerivedStyles = hasDerivedStyles; this.prefixStyleNames = prefixStyleNames; this.removePrefixFromStyleNames = removePrefixFromStyleNames; @@ -6097,18 +6265,29 @@ odf.StyleInfo = function StyleInfo() { @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ +runtime.loadClass("core.DomUtils"); odf.OdfUtils = function OdfUtils() { - var self = this, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", drawns = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0", whitespaceOnly = /^\s*$/; + var textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", drawns = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0", whitespaceOnly = /^\s*$/, domUtils = new core.DomUtils; function isParagraph(e) { var name = e && e.localName; return(name === "p" || name === "h") && e.namespaceURI === textns } this.isParagraph = isParagraph; - this.getParagraphElement = function(node) { + function getParagraphElement(node) { while(node && !isParagraph(node)) { node = node.parentNode } return node + } + this.getParagraphElement = getParagraphElement; + this.isWithinTrackedChanges = function(node, container) { + while(node && node !== container) { + if(node.namespaceURI === textns && node.localName === "tracked-changes") { + return true + } + node = node.parentNode + } + return false }; this.isListItem = function(e) { var name = e && e.localName; @@ -6119,8 +6298,11 @@ odf.OdfUtils = function OdfUtils() { } this.isODFWhitespace = isODFWhitespace; function isGroupingElement(e) { - var name = e && e.localName; - return(name === "span" || name === "p" || name === "h") && e.namespaceURI === textns + var localName = e && e.localName; + if(/^(span|p|h|a|meta)$/.test(localName) && e.namespaceURI === textns || localName === "span" && e.className === "annotationHighlight") { + return true + } + return false } this.isGroupingElement = isGroupingElement; function isCharacterElement(e) { @@ -6178,7 +6360,7 @@ odf.OdfUtils = function OdfUtils() { }else { if(isCharacterElement(node)) { r = true; - break + node = null }else { node = previousNode(node) } @@ -6227,11 +6409,10 @@ odf.OdfUtils = function OdfUtils() { if(node.nodeType === Node.TEXT_NODE && node.length > 0 && !isODFWhitespace(node.data)) { r = true; break - }else { - if(isCharacterElement(node)) { - r = true; - break - } + } + if(isCharacterElement(node)) { + r = true; + break } node = previousNode(node) } @@ -6245,11 +6426,10 @@ odf.OdfUtils = function OdfUtils() { if(node.nodeType === Node.TEXT_NODE && node.length > 0 && !isODFWhitespace(node.data)) { r = true; break - }else { - if(isCharacterElement(node)) { - r = true; - break - } + } + if(isCharacterElement(node)) { + r = true; + break } node = nextNode(node) } @@ -6264,35 +6444,24 @@ odf.OdfUtils = function OdfUtils() { } this.isTrailingWhitespace = isTrailingWhitespace; function isSignificantWhitespace(textNode, offset) { - var text = textNode.data, leftChar, leftNode, rightChar, rightNode, result; + var text = textNode.data, result; if(!isODFWhitespace(text[offset])) { return false } + if(isCharacterElement(textNode.parentNode)) { + return false + } if(offset > 0) { if(!isODFWhitespace(text[offset - 1])) { - return true + result = true } - if(offset > 1) { - if(!isODFWhitespace(text[offset - 2])) { - result = true - }else { - if(!isODFWhitespace(text.substr(0, offset))) { - return false - } - } - }else { - if(scanLeftForNonWhitespace(previousNode(textNode))) { - result = true - } + }else { + if(scanLeftForNonWhitespace(previousNode(textNode))) { + result = true } - if(result === true) { - return isTrailingWhitespace(textNode, offset) ? false : true - } - rightChar = text[offset + 1]; - if(isODFWhitespace(rightChar)) { - return false - } - return scanLeftForAnyCharacter(previousNode(textNode)) ? false : true + } + if(result === true) { + return isTrailingWhitespace(textNode, offset) ? false : true } return false } @@ -6342,31 +6511,192 @@ odf.OdfUtils = function OdfUtils() { return parseNonNegativeLength(lineHeight) || parsePercentage(lineHeight) } this.parseFoLineHeight = parseFoLineHeight; + function getImpactedParagraphs(range) { + var outerContainer = (range.commonAncestorContainer), impactedParagraphs = []; + if(outerContainer.nodeType === Node.ELEMENT_NODE) { + impactedParagraphs = domUtils.getElementsByTagNameNS(outerContainer, textns, "p").concat(domUtils.getElementsByTagNameNS(outerContainer, textns, "h")) + } + while(outerContainer && !isParagraph(outerContainer)) { + outerContainer = outerContainer.parentNode + } + if(outerContainer) { + impactedParagraphs.push(outerContainer) + } + return impactedParagraphs.filter(function(n) { + return domUtils.rangeIntersectsNode(range, n) + }) + } + this.getImpactedParagraphs = getImpactedParagraphs; + function isAcceptedNode(node) { + switch(node.namespaceURI) { + case odf.Namespaces.drawns: + ; + case odf.Namespaces.svgns: + ; + case odf.Namespaces.dr3dns: + return false; + case odf.Namespaces.textns: + switch(node.localName) { + case "note-body": + ; + case "ruby-text": + return false + } + break; + case odf.Namespaces.officens: + switch(node.localName) { + case "annotation": + ; + case "binary-data": + ; + case "event-listeners": + return false + } + break; + default: + switch(node.localName) { + case "editinfo": + return false + } + break + } + return true + } + function isSignificantTextContent(textNode) { + return Boolean(getParagraphElement(textNode) && (!isODFWhitespace(textNode.textContent) || isSignificantWhitespace(textNode, 0))) + } function getTextNodes(range, includePartial) { - var document = range.startContainer.ownerDocument, nodeRange = document.createRange(), textNodes = [], n, root = (range.commonAncestorContainer.nodeType === Node.TEXT_NODE ? range.commonAncestorContainer.parentNode : range.commonAncestorContainer), treeWalker; - treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ALL, function(node) { + var document = range.startContainer.ownerDocument, nodeRange = document.createRange(), textNodes; + function nodeFilter(node) { nodeRange.selectNodeContents(node); - if(includePartial === false && node.nodeType === Node.TEXT_NODE) { - if(range.compareBoundaryPoints(range.START_TO_START, nodeRange) <= 0 && range.compareBoundaryPoints(range.END_TO_END, nodeRange) >= 0) { - return NodeFilter.FILTER_ACCEPT + if(node.nodeType === Node.TEXT_NODE) { + if(includePartial && domUtils.rangesIntersect(range, nodeRange) || domUtils.containsRange(range, nodeRange)) { + return isSignificantTextContent(node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT } }else { - if(range.compareBoundaryPoints(range.END_TO_START, nodeRange) === -1 && range.compareBoundaryPoints(range.START_TO_END, nodeRange) === 1) { - return node.nodeType === Node.TEXT_NODE ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP + if(domUtils.rangesIntersect(range, nodeRange)) { + if(isAcceptedNode(node)) { + return NodeFilter.FILTER_SKIP + } } } return NodeFilter.FILTER_REJECT - }, false); - treeWalker.currentNode = range.startContainer.previousSibling || range.startContainer.parentNode; - n = treeWalker.nextNode(); - while(n) { - textNodes.push(n); - n = treeWalker.nextNode() } + textNodes = domUtils.getNodesInRange(range, nodeFilter); nodeRange.detach(); return textNodes } - this.getTextNodes = getTextNodes + this.getTextNodes = getTextNodes; + this.getTextElements = function(range, 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 + } + }else { + if(isCharacterElement(node)) { + if(domUtils.containsRange(range, nodeRange)) { + return NodeFilter.FILTER_ACCEPT + } + }else { + if(isAcceptedNode(node) || isGroupingElement(node)) { + return NodeFilter.FILTER_SKIP + } + } + } + return NodeFilter.FILTER_REJECT + } + elements = domUtils.getNodesInRange(range, nodeFilter); + nodeRange.detach(); + return elements + }; + this.getParagraphElements = function(range) { + var document = range.startContainer.ownerDocument, nodeRange = document.createRange(), elements; + function nodeFilter(node) { + nodeRange.selectNodeContents(node); + if(isParagraph(node)) { + if(domUtils.rangesIntersect(range, nodeRange)) { + return NodeFilter.FILTER_ACCEPT + } + }else { + if(isAcceptedNode(node) || isGroupingElement(node)) { + return NodeFilter.FILTER_SKIP + } + } + return NodeFilter.FILTER_REJECT + } + elements = domUtils.getNodesInRange(range, nodeFilter); + nodeRange.detach(); + return elements + } +}; +/* + + 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.OdfUtils"); +odf.TextSerializer = function TextSerializer() { + var self = this, odfUtils = new odf.OdfUtils; + function serializeNode(node) { + var s = "", accept = self.filter ? self.filter.acceptNode(node) : NodeFilter.FILTER_ACCEPT, nodeType = node.nodeType, child; + if(accept === NodeFilter.FILTER_ACCEPT || accept === NodeFilter.FILTER_SKIP) { + child = node.firstChild; + while(child) { + s += serializeNode(child); + child = child.nextSibling + } + } + if(accept === NodeFilter.FILTER_ACCEPT) { + if(nodeType === Node.ELEMENT_NODE && odfUtils.isParagraph(node)) { + s += "\n" + }else { + if(nodeType === Node.TEXT_NODE && node.textContent) { + s += node.textContent + } + } + } + return s + } + this.filter = null; + this.writeToString = function(node) { + if(!node) { + return"" + } + return serializeNode(node) + } }; /* @@ -6405,9 +6735,8 @@ odf.OdfUtils = function OdfUtils() { runtime.loadClass("core.DomUtils"); runtime.loadClass("core.LoopWatchDog"); runtime.loadClass("odf.Namespaces"); -runtime.loadClass("odf.OdfUtils"); odf.TextStyleApplicator = function TextStyleApplicator(newStylePrefix, formatting, automaticStyles) { - var nextTextNodes, odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils, textns = odf.Namespaces.textns, stylens = odf.Namespaces.stylens, textProperties = "style:text-properties", webodfns = "urn:webodf:names:scope"; + var domUtils = new core.DomUtils, textns = odf.Namespaces.textns, stylens = odf.Namespaces.stylens, textProperties = "style:text-properties", webodfns = "urn:webodf:names:scope"; function StyleLookup(info) { function compare(expected, actual) { if(typeof expected === "object" && typeof actual === "object") { @@ -6457,9 +6786,12 @@ odf.TextStyleApplicator = function TextStyleApplicator(newStylePrefix, formattin container.setAttributeNS(textns, "text:style-name", name) } } + function isTextSpan(node) { + return node.localName === "span" && node.namespaceURI === textns + } function moveToNewSpan(startNode, limits) { - var document = startNode.ownerDocument, originalContainer = startNode.parentNode, styledContainer, trailingContainer, moveTrailing, node = startNode, nextNode, loopGuard = new core.LoopWatchDog(1E3); - if(odfUtils.isParagraph(originalContainer)) { + var document = startNode.ownerDocument, originalContainer = (startNode.parentNode), styledContainer, trailingContainer, moveTrailing, node = startNode, nextNode, loopGuard = new core.LoopWatchDog(1E3); + if(!isTextSpan(originalContainer)) { styledContainer = document.createElementNS(textns, "text:span"); originalContainer.insertBefore(styledContainer, startNode); moveTrailing = false @@ -6493,24 +6825,19 @@ odf.TextStyleApplicator = function TextStyleApplicator(newStylePrefix, formattin } return(styledContainer) } - this.applyStyle = function(range, info) { - var textNodes, isStyled, container, styleCache, styleLookup, textPropsOnly = {}, limits; + this.applyStyle = function(textNodes, limits, info) { + var textPropsOnly = {}, isStyled, container, styleCache, styleLookup; runtime.assert(info && info[textProperties], "applyStyle without any text properties"); textPropsOnly[textProperties] = info[textProperties]; styleCache = new StyleManager(textPropsOnly); styleLookup = new StyleLookup(textPropsOnly); - nextTextNodes = domUtils.splitBoundaries(range); - textNodes = odfUtils.getTextNodes(range, false); - limits = {startContainer:range.startContainer, startOffset:range.startOffset, endContainer:range.endContainer, endOffset:range.endOffset}; textNodes.forEach(function(n) { isStyled = styleLookup.isStyleApplied(n); if(isStyled === false) { container = moveToNewSpan((n), limits); styleCache.applyStyleToContainer(container) } - }); - nextTextNodes.forEach(domUtils.normalizeTextNodes); - nextTextNodes = null + }) } }; /* @@ -6761,9 +7088,8 @@ odf.Style2CSS = function Style2CSS() { if(fontSize.unit !== "%") { fontSizeRule = "font-size: " + fontSize.value * sizeMultiplier + fontSize.unit + ";"; break - }else { - sizeMultiplier *= fontSize.value / 100 } + sizeMultiplier *= fontSize.value / 100 } parentStyle = getParentStyleNode(parentStyle) } @@ -6789,7 +7115,7 @@ odf.Style2CSS = function Style2CSS() { if(lineHeight && lineHeight !== "normal") { lineHeight = utils.parseFoLineHeight(lineHeight); if(lineHeight.unit !== "%") { - rule += "line-height: " + lineHeight.value + ";" + rule += "line-height: " + lineHeight.value + lineHeight.unit + ";" }else { rule += "line-height: " + lineHeight.value / 100 + ";" } @@ -6917,7 +7243,7 @@ odf.Style2CSS = function Style2CSS() { } return"content: " + content + ";" } - function getImageRule(node) { + function getImageRule() { var rule = "content: none;"; return rule } @@ -6965,7 +7291,7 @@ odf.Style2CSS = function Style2CSS() { } } function addPageStyleRules(sheet, node) { - var rule = "", imageProps, url, element, contentLayoutRule = "", pageSizeRule = "", height, width, props = node.getElementsByTagNameNS(stylens, "page-layout-properties")[0], masterStyles = props.parentNode.parentNode.parentNode.masterStyles, masterPages, masterStyleName = "", i; + var rule = "", imageProps, url, element, contentLayoutRule = "", pageSizeRule = "", props = node.getElementsByTagNameNS(stylens, "page-layout-properties")[0], masterStyles = props.parentNode.parentNode.parentNode.masterStyles, masterPages, masterStyleName = "", i; rule += applySimpleMapping(props, pageContentPropertySimpleMapping); imageProps = props.getElementsByTagNameNS(stylens, "background-image"); if(imageProps.length > 0) { @@ -7007,11 +7333,6 @@ odf.Style2CSS = function Style2CSS() { } } } - function getPageSizeProperties(props) { - var rule = ""; - rule += applySimpleMapping(props, pageSizePropertySimpleMapping); - return rule - } function addListStyleRules(sheet, name, node) { var n = node.firstChild, e, itemrule; while(n) { @@ -7022,7 +7343,7 @@ odf.Style2CSS = function Style2CSS() { addListStyleRule(sheet, name, e, itemrule) }else { if(n.localName === "list-level-style-image") { - itemrule = getImageRule(e); + itemrule = getImageRule(); addListStyleRule(sheet, name, e, itemrule) }else { if(n.localName === "list-level-style-bullet") { @@ -7056,7 +7377,7 @@ odf.Style2CSS = function Style2CSS() { } } this.style2css = function(doctype, stylesheet, fontFaceMap, styles, autostyles) { - var doc, prefix, styletree, tree, name, rule, family, stylenodes, styleautonodes; + var doc, styletree, tree, name, rule, family, stylenodes, styleautonodes; while(stylesheet.cssRules.length) { stylesheet.deleteRule(stylesheet.cssRules.length - 1) } @@ -7076,12 +7397,12 @@ odf.Style2CSS = function Style2CSS() { rule = "@namespace " + prefix + " url(" + ns + ");"; try { stylesheet.insertRule(rule, stylesheet.cssRules.length) - }catch(e) { + }catch(ignore) { } }); fontFaceDeclsMap = fontFaceMap; documentType = doctype; - defaultFontSize = window.getComputedStyle(document.body, null).getPropertyValue("font-size") || "12pt"; + defaultFontSize = runtime.getWindow().getComputedStyle(document.body, null).getPropertyValue("font-size") || "12pt"; stylenodes = getStyleMap(styles); styleautonodes = getStyleMap(autostyles); styletree = {}; @@ -7104,6 +7425,7 @@ runtime.loadClass("core.Zip"); runtime.loadClass("xmldom.LSSerializer"); 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"; function getDirectChild(node, ns, name) { @@ -7125,33 +7447,30 @@ odf.OdfContainer = function() { } return-1 } - function OdfNodeFilter(styleUsingElementsRoot, automaticStyles) { - var usedStyleList; - if(styleUsingElementsRoot) { - usedStyleList = new styleInfo.UsedStyleList(styleUsingElementsRoot, automaticStyles) - } + function OdfStylesFilter(styleUsingElementsRoot, automaticStyles) { + var usedStyleList = new styleInfo.UsedStyleList(styleUsingElementsRoot, automaticStyles), odfNodeFilter = new odf.OdfNodeFilter; this.acceptNode = function(node) { - var result; - if(node.namespaceURI === "http://www.w3.org/1999/xhtml") { - result = 3 - }else { - if(node.namespaceURI && node.namespaceURI.match(/^urn:webodf:/)) { - result = 2 + var result = odfNodeFilter.acceptNode(node); + if(result === NodeFilter.FILTER_ACCEPT && node.parentNode === automaticStyles && node.nodeType === Node.ELEMENT_NODE) { + if(usedStyleList.uses((node))) { + result = NodeFilter.FILTER_ACCEPT }else { - if(usedStyleList && node.parentNode === automaticStyles && node.nodeType === Node.ELEMENT_NODE) { - if(usedStyleList.uses(node)) { - result = NodeFilter.FILTER_ACCEPT - }else { - result = NodeFilter.FILTER_REJECT - } - }else { - result = NodeFilter.FILTER_ACCEPT - } + result = NodeFilter.FILTER_REJECT } } return result } } + function OdfContentFilter(styleUsingElementsRoot, automaticStyles) { + 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")) { + result = NodeFilter.FILTER_REJECT + } + return result + } + } function setChild(node, child) { if(!child) { return @@ -7210,8 +7529,6 @@ odf.OdfContainer = function() { self.onstatereadychange(self) } }) - }; - this.abort = function() { } } OdfPart.prototype.load = function() { @@ -7222,19 +7539,12 @@ odf.OdfContainer = function() { } return null }; - function OdfPartList(odfcontainer) { - var self = this; - this.length = 0; - this.item = function(index) { - } - } odf.OdfContainer = function OdfContainer(url, onstatereadychange) { var self = this, zip, partMimetypes = {}, contentElement; this.onstatereadychange = onstatereadychange; this.onchange = null; this.state = null; this.rootElement = null; - this.parts = null; function removeProcessingInstructions(element) { var n = element.firstChild, next, e; while(n) { @@ -7283,7 +7593,7 @@ odf.OdfContainer = function() { removeProcessingInstructions(xmldoc.documentElement); try { node = doc.importNode(xmldoc.documentElement, true) - }catch(e) { + }catch(ignore) { } } return node @@ -7410,7 +7720,7 @@ odf.OdfContainer = function() { callback = (component[1]); zip.loadAsDOM(filepath, function(err, xmldoc) { callback(xmldoc); - if(self.state === OdfContainer.INVALID) { + if(err || self.state === OdfContainer.INVALID) { return } loadNextComponent(remainingComponents) @@ -7424,7 +7734,7 @@ odf.OdfContainer = function() { loadNextComponent(componentOrder) } function createDocumentElement(name) { - var s = "", i; + var s = ""; odf.Namespaces.forEachPrefix(function(prefix, ns) { s += " xmlns:" + prefix + '="' + ns + '"' }); @@ -7432,7 +7742,7 @@ odf.OdfContainer = function() { } function serializeMetaXml() { var serializer = new xmldom.LSSerializer, s = createDocumentElement("document-meta"); - serializer.filter = new OdfNodeFilter; + serializer.filter = new odf.OdfNodeFilter; s += serializer.writeToString(self.rootElement.meta, odf.Namespaces.namespaceMap); s += ""; return s @@ -7450,12 +7760,12 @@ odf.OdfContainer = function() { manifestRoot.appendChild(createManifestEntry(fullPath, partMimetypes[fullPath])) } } - serializer.filter = new OdfNodeFilter; + serializer.filter = new odf.OdfNodeFilter; return header + serializer.writeToString(manifest, odf.Namespaces.namespaceMap) } function serializeSettingsXml() { var serializer = new xmldom.LSSerializer, s = createDocumentElement("document-settings"); - serializer.filter = new OdfNodeFilter; + serializer.filter = new odf.OdfNodeFilter; s += serializer.writeToString(self.rootElement.settings, odf.Namespaces.namespaceMap); s += ""; return s @@ -7463,7 +7773,7 @@ odf.OdfContainer = function() { 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"); styleInfo.removePrefixFromStyleNames(automaticStyles, automaticStylePrefix, masterStyles); - serializer.filter = new OdfNodeFilter(masterStyles, automaticStyles); + serializer.filter = new OdfStylesFilter(masterStyles, automaticStyles); s += serializer.writeToString(self.rootElement.fontFaceDecls, nsmap); s += serializer.writeToString(self.rootElement.styles, nsmap); s += serializer.writeToString(automaticStyles, nsmap); @@ -7473,7 +7783,7 @@ odf.OdfContainer = function() { } function serializeContentXml() { var nsmap = odf.Namespaces.namespaceMap, serializer = new xmldom.LSSerializer, automaticStyles = cloneStylesInScope(self.rootElement.automaticStyles, documentContentScope), s = createDocumentElement("document-content"); - serializer.filter = new OdfNodeFilter(self.rootElement.body, automaticStyles); + serializer.filter = new OdfContentFilter(self.rootElement.body, automaticStyles); s += serializer.writeToString(automaticStyles, nsmap); s += serializer.writeToString(self.rootElement.body, nsmap); s += ""; @@ -7507,8 +7817,8 @@ odf.OdfContainer = function() { return contentElement }; this.getDocumentType = function() { - var contentElement = self.getContentElement(); - return contentElement && contentElement.localName + var content = self.getContentElement(); + return content && content.localName }; this.getPart = function(partname) { return new OdfPart(partname, partMimetypes[partname], self, zip) @@ -7517,8 +7827,8 @@ odf.OdfContainer = function() { zip.load(url, callback) }; function createEmptyTextDocument() { - var zip = new core.Zip("", null), data = runtime.byteArrayFromString("application/vnd.oasis.opendocument.text", "utf8"), root = self.rootElement, text = document.createElementNS(officens, "text"); - zip.save("mimetype", data, false, new Date); + var emptyzip = new core.Zip("", null), data = runtime.byteArrayFromString("application/vnd.oasis.opendocument.text", "utf8"), root = self.rootElement, text = document.createElementNS(officens, "text"); + emptyzip.save("mimetype", data, false, new Date); function addToplevelElement(memberName, realLocalName) { var element; if(!realLocalName) { @@ -7538,7 +7848,7 @@ odf.OdfContainer = function() { addToplevelElement("body"); root.body.appendChild(text); setState(OdfContainer.DONE); - return zip + return emptyzip } function fillZip() { var data, date = new Date; @@ -7573,7 +7883,6 @@ odf.OdfContainer = function() { }; this.state = OdfContainer.LOADING; this.rootElement = createElement(ODFDocumentElement); - this.parts = new OdfPartList(this); if(url) { zip = new core.Zip(url, function(err, zipobject) { zip = zipobject; @@ -7680,7 +7989,10 @@ odf.FontLoader = function() { } } if(!name) { - return callback() + if(callback) { + callback() + } + return } odfContainer.getPartData(embeddedFontDeclarations[name].href, function(err, fontdata) { if(err) { @@ -7692,11 +8004,9 @@ odf.FontLoader = function() { }) } function loadFontsIntoCSS(embeddedFontDeclarations, odfContainer, stylesheet) { - loadFontIntoCSS(embeddedFontDeclarations, odfContainer, 0, stylesheet, function() { - }) + loadFontIntoCSS(embeddedFontDeclarations, odfContainer, 0, stylesheet) } odf.FontLoader = function FontLoader() { - var self = this; this.loadFonts = function(odfContainer, stylesheet) { var embeddedFontDeclarations, fontFaceDecls = odfContainer.rootElement.fontFaceDecls; while(stylesheet.cssRules.length) { @@ -7744,21 +8054,14 @@ odf.FontLoader = function() { @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ +runtime.loadClass("core.Utils"); 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, odfUtils = new odf.OdfUtils; - function hashString(value) { - var hash = 0, i, l; - for(i = 0, l = value.length;i < l;i += 1) { - hash = (hash << 5) - hash + value.charCodeAt(i); - hash |= 0 - } - return hash - } + 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; function mergeRecursive(destination, source) { Object.keys(source).forEach(function(p) { try { @@ -7828,17 +8131,21 @@ odf.Formatting = function Formatting() { return null } function getStyleElement(styleName, family, styleElements) { - var node, styleListElement; + var node, nodeStyleName, styleListElement; styleElements = styleElements || [odfContainer.rootElement.automaticStyles, odfContainer.rootElement.styles]; styleListElement = styleElements.shift(); while(styleListElement) { node = styleListElement.firstChild; while(node) { if(node.nodeType === Node.ELEMENT_NODE) { - if(node.namespaceURI === stylens && node.localName === "style" && node.getAttributeNS(stylens, "family") === family && node.getAttributeNS(stylens, "name") === styleName) { + nodeStyleName = node.getAttributeNS(stylens, "name"); + 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" && node.getAttributeNS(stylens, "name") === styleName) { + if(family === "list-style" && node.namespaceURI === textns && node.localName === "list-style" && nodeStyleName === styleName) { + return node + } + if(family === "data" && node.namespaceURI === numberns && nodeStyleName === styleName) { return node } } @@ -7863,9 +8170,9 @@ odf.Formatting = function Formatting() { return propertiesMap } this.getStyleAttributes = getStyleAttributes; - function mapObjOntoNode(node, info) { - Object.keys(info).forEach(function(key) { - var parts = key.split(":"), prefix = parts[0], localName = parts[1], ns = odf.Namespaces.resolvePrefix(prefix), value = info[key], element; + function mapObjOntoNode(node, properties) { + Object.keys(properties).forEach(function(key) { + var parts = key.split(":"), prefix = parts[0], localName = parts[1], ns = odf.Namespaces.resolvePrefix(prefix), value = properties[key], element; if(typeof value === "object" && Object.keys(value).length) { element = node.getElementsByTagNameNS(ns, localName)[0] || node.ownerDocument.createElementNS(ns, key); node.appendChild(element); @@ -7897,8 +8204,10 @@ odf.Formatting = function Formatting() { this.getInheritedStyleAttributes = getInheritedStyleAttributes; this.getFirstNamedParentStyleNameOrSelf = function(styleName) { var automaticStyleElementList = odfContainer.rootElement.automaticStyles, styleElementList = odfContainer.rootElement.styles, styleElement; - while((styleElement = getStyleElement(styleName, "paragraph", [automaticStyleElementList])) !== null) { - styleName = styleElement.getAttributeNS(stylens, "parent-style-name") + styleElement = getStyleElement(styleName, "paragraph", [automaticStyleElementList]); + while(styleElement) { + styleName = styleElement.getAttributeNS(stylens, "parent-style-name"); + styleElement = getStyleElement(styleName, "paragraph", [automaticStyleElementList]) } styleElement = getStyleElement(styleName, "paragraph", [styleElementList]); if(!styleElement) { @@ -7939,17 +8248,22 @@ odf.Formatting = function Formatting() { var mergedChildStyle = {orderedStyles:[]}; styleChain.forEach(function(elementStyleSet) { Object.keys((elementStyleSet)).forEach(function(styleFamily) { - var styleName = Object.keys(elementStyleSet[styleFamily])[0], styleElement, parentStyle; + var styleName = Object.keys(elementStyleSet[styleFamily])[0], styleElement, parentStyle, displayName; styleElement = getStyleElement(styleName, styleFamily); - parentStyle = getInheritedStyleAttributes((styleElement)); - mergedChildStyle = mergeRecursive(parentStyle, mergedChildStyle); - mergedChildStyle.orderedStyles.push({name:styleName, family:styleFamily, displayName:styleElement.getAttributeNS(stylens, "display-name")}) + if(styleElement) { + parentStyle = getInheritedStyleAttributes((styleElement)); + mergedChildStyle = mergeRecursive(parentStyle, mergedChildStyle); + displayName = styleElement.getAttributeNS(stylens, "display-name") + }else { + runtime.log("No style element found for '" + styleName + "' of family '" + styleFamily + "'") + } + mergedChildStyle.orderedStyles.push({name:styleName, family:styleFamily, displayName:displayName}) }) }); return mergedChildStyle } - this.getAppliedStyles = function(range) { - var textNodes = odfUtils.getTextNodes(range), styleChains = {}, styles = []; + this.getAppliedStyles = function(textNodes) { + var styleChains = {}, styles = []; textNodes.forEach(function(n) { buildStyleChain(n, styleChains) }); @@ -7963,9 +8277,9 @@ odf.Formatting = function Formatting() { styleChain = buildStyleChain(node); return styleChain ? calculateAppliedStyle(styleChain) : undefined }; - this.applyStyle = function(memberId, range, info) { - var textStyles = new odf.TextStyleApplicator("auto" + hashString(memberId) + "_", self, odfContainer.rootElement.automaticStyles); - textStyles.applyStyle(range, info) + this.applyStyle = function(memberId, textNodes, limits, info) { + var textStyles = new odf.TextStyleApplicator("auto" + utils.hashString(memberId) + "_", self, odfContainer.rootElement.automaticStyles); + textStyles.applyStyle(textNodes, limits, info) }; function getAllStyleNames() { var styleElements = [odfContainer.rootElement.automaticStyles, odfContainer.rootElement.styles], node, styleNames = []; @@ -7982,11 +8296,11 @@ odf.Formatting = function Formatting() { }); return styleNames } - this.updateStyle = function(styleNode, info, newStylePrefix) { + this.updateStyle = function(styleNode, properties, newStylePrefix) { var name, existingNames, startIndex; - mapObjOntoNode(styleNode, info); - name = styleNode.getAttributeNS(stylens, "name"); + mapObjOntoNode(styleNode, properties); if(newStylePrefix) { + name = styleNode.getAttributeNS(stylens, "name"); existingNames = getAllStyleNames(); startIndex = 0; do { @@ -8038,6 +8352,7 @@ runtime.loadClass("xmldom.XPath"); runtime.loadClass("odf.FontLoader"); runtime.loadClass("odf.Style2CSS"); runtime.loadClass("odf.OdfUtils"); +runtime.loadClass("gui.AnnotationViewManager"); odf.OdfCanvas = function() { function LoadingQueue() { var queue = [], taskRunning = false; @@ -8111,7 +8426,7 @@ odf.OdfCanvas = function() { } } function SelectionWatcher(element) { - var selection = [], count = 0, listeners = []; + var selection = [], listeners = []; function isAncestorOf(ancestor, descendant) { while(descendant) { if(descendant === ancestor) { @@ -8125,9 +8440,9 @@ odf.OdfCanvas = function() { return isAncestorOf(element, range.startContainer) && isAncestorOf(element, range.endContainer) } function getCurrentSelection() { - var s = [], selection = runtime.getWindow().getSelection(), i, r; - for(i = 0;i < selection.rangeCount;i += 1) { - r = selection.getRangeAt(i); + var s = [], current = runtime.getWindow().getSelection(), i, r; + for(i = 0;i < current.rangeCount;i += 1) { + r = current.getRangeAt(i); if(r !== null && fallsWithin(element, r)) { s.push(r) } @@ -8189,7 +8504,8 @@ 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, window = runtime.getWindow(), xpath = new xmldom.XPath, utils = new odf.OdfUtils, domUtils = new core.DomUtils, shadowContent, annotationsPane, allowAnnotations = + false, annotationManager; function clear(element) { while(element.firstChild) { element.removeChild(element.firstChild) @@ -8218,8 +8534,8 @@ odf.OdfCanvas = function() { } 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, i, j, clonedPage, clonedNode, pageNumber = 0, pageNumberContainer, node, - document = odfContainer.rootElement.ownerDocument; + 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"); @@ -8292,7 +8608,7 @@ odf.OdfCanvas = function() { } function setImage(id, container, image, stylesheet) { image.setAttribute("styleid", id); - var url = image.getAttributeNS(xlinkns, "href"), part, node; + var url = image.getAttributeNS(xlinkns, "href"), part; function callback(url) { var rule; if(url) { @@ -8302,14 +8618,18 @@ odf.OdfCanvas = function() { } } if(url) { - try { - part = container.getPart(url); - part.onchange = function(part) { - callback(part.url) - }; - part.load() - }catch(e) { - runtime.log("slight problem: " + e) + if(/^(?:http|https|ftp):\/\//.test(url)) { + callback(url) + }else { + try { + part = container.getPart(url); + part.onchange = function(part) { + callback(part.url) + }; + part.load() + }catch(e) { + runtime.log("slight problem: " + e) + } } }else { url = getUrlFromBinaryDataElement(image); @@ -8325,9 +8645,9 @@ odf.OdfCanvas = function() { } } } - function modifyTables(container, odffragment, stylesheet) { + function modifyTables(odffragment) { var i, tableCells, node; - function modifyTableCell(container, node, stylesheet) { + function modifyTableCell(node) { if(node.hasAttributeNS(tablens, "number-columns-spanned")) { node.setAttribute("colspan", node.getAttributeNS(tablens, "number-columns-spanned")) } @@ -8338,12 +8658,23 @@ odf.OdfCanvas = function() { tableCells = odffragment.getElementsByTagNameNS(tablens, "table-cell"); for(i = 0;i < tableCells.length;i += 1) { node = (tableCells.item(i)); - modifyTableCell(container, node, stylesheet) + modifyTableCell(node) } } - function modifyLinks(container, odffragment, stylesheet) { + function modifyAnnotations(odffragment) { + var annotationNodes = domUtils.getElementsByTagNameNS(odffragment, officens, "annotation"), annotationEnds = domUtils.getElementsByTagNameNS(odffragment, officens, "annotation-end"), currentAnnotationName, i; + function matchAnnotationEnd(element) { + return currentAnnotationName === element.getAttributeNS(officens, "name") + } + for(i = 0;i < annotationNodes.length;i += 1) { + currentAnnotationName = annotationNodes[i].getAttributeNS(officens, "name"); + annotationManager.addAnnotation({node:annotationNodes[i], end:annotationEnds.filter(matchAnnotationEnd)[0] || null}) + } + annotationManager.rerenderAnnotations() + } + function modifyLinks(odffragment) { var i, links, node; - function modifyLink(container, node, stylesheet) { + function modifyLink(node) { var url, clickHandler; if(!node.hasAttributeNS(xlinkns, "href")) { return @@ -8371,7 +8702,7 @@ odf.OdfCanvas = function() { links = odffragment.getElementsByTagNameNS(textns, "a"); for(i = 0;i < links.length;i += 1) { node = (links.item(i)); - modifyLink(container, node, stylesheet) + modifyLink(node) } } function expandSpaceElements(odffragment) { @@ -8401,7 +8732,7 @@ odf.OdfCanvas = function() { }) } function modifyImages(container, odfbody, stylesheet) { - var node, frames, i, images; + var node, frames, i; frames = []; node = odfbody.firstChild; while(node && node !== odfbody) { @@ -8425,8 +8756,8 @@ odf.OdfCanvas = function() { } formatParagraphAnchors(odfbody) } - function setVideo(id, container, plugin, stylesheet) { - var video, source, url, videoType, doc = plugin.ownerDocument, part, node; + function setVideo(container, plugin) { + var video, source, url, doc = plugin.ownerDocument, part; url = plugin.getAttributeNS(xlinkns, "href"); function callback(url, mimetype) { var ns = doc.documentElement.namespaceURI; @@ -8476,12 +8807,12 @@ odf.OdfCanvas = function() { rule = "content: " + content + ";"; return rule } - function getImageRule(node) { + function getImageRule() { var rule = "content: none;"; return rule } function getBulletRule(node) { - var rule = "", bulletChar = node.getAttributeNS(textns, "bullet-char"); + var bulletChar = node.getAttributeNS(textns, "bullet-char"); return"content: '" + bulletChar + "';" } function getBulletsRule(node) { @@ -8490,7 +8821,7 @@ odf.OdfCanvas = function() { itemrule = getNumberRule(node) }else { if(node.localName === "list-level-style-image") { - itemrule = getImageRule(node) + itemrule = getImageRule() }else { if(node.localName === "list-level-style-bullet") { itemrule = getBulletRule(node) @@ -8499,8 +8830,8 @@ odf.OdfCanvas = function() { } return itemrule } - function loadLists(container, odffragment, stylesheet) { - var i, lists, node, id, continueList, styleName, rule, listMap = {}, parentList, listStyles, listStyle, listStyleMap = {}, bulletRule; + function loadLists(odffragment, stylesheet) { + var i, lists, node, id, continueList, styleName, rule, listMap = {}, parentList, listStyles, listStyleMap = {}, bulletRule; listStyles = window.document.getElementsByTagNameNS(textns, "list-style"); for(i = 0;i < listStyles.length;i += 1) { node = (listStyles.item(i)); @@ -8574,7 +8905,7 @@ odf.OdfCanvas = function() { return style } function addStyleSheet(document) { - var head = document.getElementsByTagName("head")[0], style = document.createElementNS(head.namespaceURI, "style"), text = "", prefix; + var head = document.getElementsByTagName("head")[0], style = document.createElementNS(head.namespaceURI, "style"), text = ""; style.setAttribute("type", "text/css"); style.setAttribute("media", "screen, print, handheld, projection"); odf.Namespaces.forEachPrefix(function(prefix, ns) { @@ -8586,7 +8917,7 @@ odf.OdfCanvas = function() { } odf.OdfCanvas = function OdfCanvas(element) { runtime.assert(element !== null && element !== undefined, "odf.OdfCanvas constructor needs DOM element"); - var self = this, doc = element.ownerDocument, odfcontainer, formatting = new odf.Formatting, selectionWatcher = new SelectionWatcher(element), slidecssindex = 0, pageSwitcher, fontcss, stylesxmlcss, positioncss, editable = false, zoomLevel = 1, eventHandlers = {}, editparagraph, loadingQueue = new LoadingQueue; + var doc = element.ownerDocument, odfcontainer, formatting = new odf.Formatting, selectionWatcher = new SelectionWatcher(element), pageSwitcher, fontcss, stylesxmlcss, positioncss, editable = false, zoomLevel = 1, eventHandlers = {}, editparagraph, loadingQueue = new LoadingQueue; addWebODFStyleSheet(doc); pageSwitcher = new PageSwitcher(addStyleSheet(doc)); fontcss = addStyleSheet(doc); @@ -8605,17 +8936,17 @@ odf.OdfCanvas = function() { loadImage("image" + String(i), container, node, stylesheet) } } - function loadVideos(container, odffragment, stylesheet) { + function loadVideos(container, odffragment) { var i, plugins, node; - function loadVideo(name, container, node, stylesheet) { + function loadVideo(container, node) { loadingQueue.addToQueue(function() { - setVideo(name, container, node, stylesheet) + setVideo(container, node) }) } plugins = odffragment.getElementsByTagNameNS(drawns, "plugin"); for(i = 0;i < plugins.length;i += 1) { node = (plugins.item(i)); - loadVideo("video" + String(i), container, node, stylesheet) + loadVideo(container, node) } } function addEventListener(eventType, eventHandler) { @@ -8665,8 +8996,11 @@ odf.OdfCanvas = function() { sizer = doc.createElementNS(element.namespaceURI, "div"); sizer.style.display = "inline-block"; sizer.style.background = "white"; + sizer.id = "sizer"; sizer.appendChild(odfnode); element.appendChild(sizer); + annotationsPane = doc.createElementNS(element.namespaceURI, "div"); + annotationsPane.id = "annotationsPane"; shadowContent = doc.createElementNS(element.namespaceURI, "div"); shadowContent.id = "shadowContent"; shadowContent.style.position = "absolute"; @@ -8674,16 +9008,38 @@ odf.OdfCanvas = function() { shadowContent.style.left = 0; container.getContentElement().appendChild(shadowContent); modifyImages(container, odfnode.body, css); - modifyTables(container, odfnode.body, css); - modifyLinks(container, odfnode.body, css); + modifyTables(odfnode.body); + modifyLinks(odfnode.body); expandSpaceElements(odfnode.body); expandTabElements(odfnode.body); loadImages(container, odfnode.body, css); - loadVideos(container, odfnode.body, css); - loadLists(container, odfnode.body, css); + loadVideos(container, odfnode.body); + loadLists(odfnode.body, css); sizer.insertBefore(shadowContent, sizer.firstChild); fixContainerSize() } + function handleAnnotations(odfnode) { + var sizer = doc.getElementById("sizer"); + if(allowAnnotations) { + if(!annotationsPane.parentNode) { + sizer.appendChild(annotationsPane); + sizer.style.paddingRight = window.getComputedStyle(annotationsPane).width; + fixContainerSize() + } + if(annotationManager) { + annotationManager.forgetAnnotations() + } + annotationManager = new gui.AnnotationViewManager(odfnode.body, annotationsPane); + modifyAnnotations(odfnode.body) + }else { + if(annotationsPane.parentNode) { + sizer.removeChild(annotationsPane); + sizer.style.paddingRight = 0; + annotationManager.forgetAnnotations(); + fixContainerSize() + } + } + } function refreshOdf(suppressEvent) { function callback() { clear(element); @@ -8694,6 +9050,7 @@ odf.OdfCanvas = function() { handleFonts(odfcontainer, fontcss); handleStyles(odfcontainer, formatting, stylesxmlcss); handleContent(odfcontainer, odfnode); + handleAnnotations(odfnode); if(!suppressEvent) { fireEvent("statereadychange", [odfcontainer]) } @@ -8729,7 +9086,7 @@ odf.OdfCanvas = function() { odfcontainer = container; refreshOdf(suppressEvent === true) }; - this["load"] = this.load = function(url) { + function load(url) { loadingQueue.clearQueue(); element.innerHTML = "loading " + url; element.removeAttribute("style"); @@ -8737,7 +9094,9 @@ odf.OdfCanvas = function() { odfcontainer = container; refreshOdf(false) }) - }; + } + this["load"] = load; + this.load = load; function stopEditing() { if(!editparagraph) { return @@ -8752,13 +9111,6 @@ odf.OdfCanvas = function() { stopEditing(); odfcontainer.save(callback) }; - function cancelPropagation(event) { - if(event.stopPropagation) { - event.stopPropagation() - }else { - event.cancelBubble = true - } - } function cancelEvent(event) { if(event.preventDefault) { event.preventDefault(); @@ -8770,7 +9122,7 @@ odf.OdfCanvas = function() { } function processClick(evt) { evt = evt || window.event; - var e = evt.target, selection = window.getSelection(), range = selection.rangeCount > 0 ? selection.getRangeAt(0) : null, startContainer = range && range.startContainer, startOffset = range && range.startOffset, endContainer = range && range.endContainer, endOffset = range && range.endOffset, doc, ns; + var e = evt.target, selection = window.getSelection(), range = selection.rangeCount > 0 ? selection.getRangeAt(0) : null, startContainer = range && range.startContainer, startOffset = range && range.startOffset, endContainer = range && range.endContainer, endOffset = range && range.endOffset, clickdoc, ns; while(e && !((e.localName === "p" || e.localName === "h") && e.namespaceURI === textns)) { e = e.parentNode } @@ -8780,10 +9132,10 @@ odf.OdfCanvas = function() { if(!e || e.parentNode === editparagraph) { return } - doc = e.ownerDocument; - ns = doc.documentElement.namespaceURI; + clickdoc = e.ownerDocument; + ns = clickdoc.documentElement.namespaceURI; if(!editparagraph) { - editparagraph = doc.createElementNS(ns, "p"); + editparagraph = clickdoc.createElementNS(ns, "p"); editparagraph.style.margin = "0px"; editparagraph.style.padding = "0px"; editparagraph.style.border = "0px"; @@ -8828,6 +9180,28 @@ odf.OdfCanvas = function() { this.getFormatting = function() { return formatting }; + this.getAnnotationManager = function() { + return annotationManager + }; + this.refreshAnnotations = function() { + handleAnnotations(odfcontainer.rootElement) + }; + this.rerenderAnnotations = function() { + if(annotationManager) { + annotationManager.rerenderAnnotations() + } + }; + this.enableAnnotations = function(allow) { + if(allow !== allowAnnotations) { + allowAnnotations = allow; + handleAnnotations(odfcontainer.rootElement) + } + }; + this.addAnnotation = function(annotation) { + if(annotationManager) { + annotationManager.addAnnotation(annotation) + } + }; this.setZoomLevel = function(zoom) { zoomLevel = zoom; fixContainerSize() @@ -8879,8 +9253,6 @@ odf.OdfCanvas = function() { pageSwitcher.showPage(n); fixContainerSize() }; - this.showAllPages = function() { - }; this.getElement = function() { return element } @@ -8902,7 +9274,8 @@ odf.CommandLineTools = function CommandLineTools() { callback("Document was not completely loaded.") } } - var odfcontainer = new odf.OdfContainer(inputfilepath, onready) + var odfcontainer = new odf.OdfContainer(inputfilepath, onready); + return odfcontainer }; this.render = function(inputfilepath, document, callback) { var body = document.getElementsByTagName("body")[0], odfcanvas; @@ -8958,6 +9331,8 @@ ops.Server.prototype.networkStatus = function() { }; ops.Server.prototype.login = function(login, password, successCb, failCb) { }; +ops.Server.prototype.getGenesisUrl = function(sessionId) { +}; /* Copyright (C) 2013 KO GmbH @@ -9003,9 +9378,9 @@ ops.NowjsServer = function NowjsServer() { function createUserModel() { return new ops.NowjsUserModel(self) } - function getGenesisUrl(sessionId) { + this.getGenesisUrl = function(sessionId) { return"/session/" + sessionId + "/genesis" - } + }; this.connect = function(timeout, callback) { var accumulatedWaitingTime = 0; if(nowObject) { @@ -9089,17 +9464,14 @@ ops.PullBoxServer = function PullBoxServer(args) { var self = this, token, base64 = new core.Base64; args = args || {}; args.url = args.url || "/WSER"; - function createOperationRouter(sid, mid) { - return new ops.PullBoxOperationRouter(sid, mid, self) - } - function createUserModel() { - return new ops.PullBoxUserModel(self) - } - function getGenesisUrl(sessionId) { + this.getGenesisUrl = function(sessionId) { return"/session/" + sessionId + "/genesis" - } + }; function call(message, cb) { var xhr = new XMLHttpRequest, byteArrayWriter = new core.ByteArrayWriter("utf8"), data; + if(typeof message === "object") { + message = JSON.stringify(message) + } function handleResult() { if(xhr.readyState === 4) { if((xhr.status < 200 || xhr.status >= 300) && xhr.status === 0) { @@ -9136,11 +9508,10 @@ ops.PullBoxServer = function PullBoxServer(args) { this.getToken = function() { return token }; - this.setToken = function (a_token) { - token = a_token; + this.setToken = function(a_token) { + token = a_token }; this.connect = function(timeout, callback) { - var accumulatedWaitingTime = 0; callback("ready") }; this.networkStatus = function() { @@ -9158,9 +9529,7 @@ ops.PullBoxServer = function PullBoxServer(args) { failCb(responseData) } }) - }; - this.createOperationRouter = createOperationRouter; - this.createUserModel = createUserModel + } }; /* @@ -9297,15 +9666,98 @@ ops.OpAddCursor = function OpAddCursor() { @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ +runtime.loadClass("core.DomUtils"); runtime.loadClass("odf.OdfUtils"); -ops.OpApplyStyle = function OpApplyStyle() { - var self = this, memberid, timestamp, position, length, info, odfUtils = new odf.OdfUtils, domUtils = new core.DomUtils, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; +gui.StyleHelper = function StyleHelper(formatting) { + var domUtils = new core.DomUtils, odfUtils = new odf.OdfUtils; + this.getAppliedStyles = function(range) { + var textNodes = odfUtils.getTextNodes(range, true); + return formatting.getAppliedStyles(textNodes) + }; + this.applyStyle = function(memberId, range, info) { + var nextTextNodes = domUtils.splitBoundaries(range), textNodes = odfUtils.getTextNodes(range, false), limits; + limits = {startContainer:range.startContainer, startOffset:range.startOffset, endContainer:range.endContainer, endOffset:range.endOffset}; + formatting.applyStyle(memberId, textNodes, limits, info); + nextTextNodes.forEach(domUtils.normalizeTextNodes) + }; + function hasTextPropertyValue(range, propertyName, propertyValue) { + var hasOtherValue = true, nodes, styles, properties, container, i; + if(range.collapsed) { + container = range.startContainer; + if(container.hasChildNodes() && range.startOffset < container.childNodes.length) { + container = container.childNodes[range.startOffset] + } + nodes = [container] + }else { + nodes = odfUtils.getTextNodes(range, true) + } + styles = formatting.getAppliedStyles(nodes); + for(i = 0;i < styles.length;i += 1) { + properties = styles[i]["style:text-properties"]; + hasOtherValue = !properties || properties[propertyName] !== propertyValue; + if(hasOtherValue) { + break + } + } + return!hasOtherValue + } + this.isBold = function(range) { + return hasTextPropertyValue(range, "fo:font-weight", "bold") + }; + this.isItalic = function(range) { + return hasTextPropertyValue(range, "fo:font-style", "italic") + }; + this.hasUnderline = function(range) { + return hasTextPropertyValue(range, "style:text-underline-style", "solid") + }; + this.hasStrikeThrough = function(range) { + return hasTextPropertyValue(range, "style:text-line-through-style", "solid") + } +}; +/* + + Copyright (C) 2012-2013 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ +runtime.loadClass("gui.StyleHelper"); +runtime.loadClass("odf.OdfUtils"); +ops.OpApplyDirectStyling = function OpApplyDirectStyling() { + var memberid, timestamp, position, length, setProperties, odfUtils = new odf.OdfUtils; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; position = parseInt(data.position, 10); length = parseInt(data.length, 10); - info = data.info + setProperties = data.setProperties }; this.transform = function(otherOp, hasPriority) { return null @@ -9316,37 +9768,19 @@ ops.OpApplyStyle = function OpApplyStyle() { range.setEnd(p2.container(), p2.unfilteredDomOffset()); return range } - function intersectsNode(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 - } - function getImpactedParagraphs(range) { - var outerContainer = range.commonAncestorContainer, impactedParagraphs = []; - if(outerContainer.nodeType === Node.ELEMENT_NODE) { - impactedParagraphs = domUtils.getElementsByTagNameNS(outerContainer, textns, "p").concat(domUtils.getElementsByTagNameNS(outerContainer, textns, "h")) - } - while(outerContainer && !odfUtils.isParagraph(outerContainer)) { - outerContainer = outerContainer.parentNode - } - if(outerContainer) { - impactedParagraphs.push(outerContainer) - } - return impactedParagraphs.filter(function(n) { - return intersectsNode(range, n) - }) - } this.execute = function(odtDocument) { - var range = getRange(odtDocument), impactedParagraphs = getImpactedParagraphs(range); - odtDocument.getFormatting().applyStyle(memberid, range, info); + var range = getRange(odtDocument), impactedParagraphs = odfUtils.getImpactedParagraphs(range), styleHelper = new gui.StyleHelper(odtDocument.getFormatting()); + styleHelper.applyStyle(memberid, range, setProperties); range.detach(); odtDocument.getOdfCanvas().refreshCSS(); impactedParagraphs.forEach(function(n) { odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:n, memberId:memberid, timeStamp:timestamp}) }); + odtDocument.getOdfCanvas().rerenderAnnotations(); return true }; this.spec = function() { - return{optype:"ApplyStyle", memberid:memberid, timestamp:timestamp, position:position, length:length, info:info} + return{optype:"ApplyDirectStyling", memberid:memberid, timestamp:timestamp, position:position, length:length, setProperties:setProperties} } }; /* @@ -9467,24 +9901,46 @@ ops.OpMoveCursor = function OpMoveCursor() { return false }; this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), otherOpType = otherOpspec.optype, result = [self]; + var otherOpspec = otherOp.spec(), otherOpType = otherOpspec.optype, end = position + length, otherOpspecEnd, result = [self]; if(otherOpType === "RemoveText") { - if(otherOpspec.position + otherOpspec.length <= position) { + otherOpspecEnd = otherOpspec.position + otherOpspec.length; + if(otherOpspecEnd <= position) { position -= otherOpspec.length }else { - if(otherOpspec.position < position) { - position = otherOpspec.position + 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 + } + } } } }else { if(otherOpType === "SplitParagraph") { if(otherOpspec.position < position) { position += 1 + }else { + if(otherOpspec.position > position && otherOpspec.position < end) { + length += 1 + } } }else { if(otherOpType === "InsertText") { if(otherOpspec.position < position) { position += otherOpspec.text.length + }else { + if(otherOpspec.position > position && otherOpspec.position < end) { + length += otherOpspec.text.length + } } }else { if(otherOpType === "RemoveCursor" && otherOpspec.memberid === memberid) { @@ -9643,6 +10099,7 @@ ops.OpInsertTable = function OpInsertTable() { rootNode.insertBefore(tableNode, previousSibling ? previousSibling.nextSibling : undefined); odtDocument.getOdfCanvas().refreshSize(); odtDocument.emit(ops.OdtDocument.signalTableAdded, {tableElement:tableNode, memberId:memberid, timeStamp:timestamp}); + odtDocument.getOdfCanvas().rerenderAnnotations(); return true } return false @@ -9757,26 +10214,40 @@ ops.OpInsertText = function OpInsertText() { }) } this.execute = function(odtDocument) { - var domPosition, textNode, texts = text.split(" "), offset, length, space, previousNode, parent, refNode, ownerDocument = odtDocument.getRootNode().ownerDocument, paragraphElement, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", i; + var domPosition, previousNode, parent, refNode, ownerDocument = odtDocument.getRootNode().ownerDocument, paragraphElement, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", space = " ", tab = "\t", append = true, startIndex = 0, textToInsert, spaceTag, node, i; domPosition = odtDocument.getPositionInTextNode(position, memberid); if(domPosition) { previousNode = domPosition.textNode; parent = previousNode.parentNode; refNode = previousNode.nextSibling; - offset = domPosition.offset; paragraphElement = odtDocument.getParagraphElement(previousNode); - if(offset !== previousNode.length) { - refNode = previousNode.splitText(offset) + if(domPosition.offset !== previousNode.length) { + refNode = previousNode.splitText(domPosition.offset) } - if(texts[0].length > 0) { - previousNode.appendData(texts[0]) + for(i = 0;i < text.length;i += 1) { + if(text[i] === space || text[i] === tab) { + if(startIndex < i) { + textToInsert = text.substring(startIndex, i); + if(append) { + previousNode.appendData(textToInsert) + }else { + parent.insertBefore(ownerDocument.createTextNode(textToInsert), refNode) + } + } + startIndex = i + 1; + append = false; + spaceTag = text[i] === space ? "text:s" : "text:tab"; + node = ownerDocument.createElementNS(textns, spaceTag); + node.appendChild(ownerDocument.createTextNode(text[i])); + parent.insertBefore(node, refNode) + } } - for(i = 1;i < texts.length;i += 1) { - space = ownerDocument.createElementNS(textns, "text:s"); - space.appendChild(ownerDocument.createTextNode(" ")); - parent.insertBefore(space, refNode); - if(texts[i].length > 0) { - parent.insertBefore(ownerDocument.createTextNode(texts[i]), refNode) + textToInsert = text.substring(startIndex); + if(textToInsert.length > 0) { + if(append) { + previousNode.appendData(textToInsert) + }else { + parent.insertBefore(ownerDocument.createTextNode(textToInsert), refNode) } } triggerLayoutInWebkit(odtDocument, previousNode); @@ -9785,6 +10256,7 @@ ops.OpInsertText = function OpInsertText() { } odtDocument.getOdfCanvas().refreshSize(); odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:paragraphElement, memberId:memberid, timeStamp:timestamp}); + odtDocument.getOdfCanvas().rerenderAnnotations(); return true } return false @@ -9827,10 +10299,11 @@ ops.OpInsertText = function OpInsertText() { @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/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, text, odfUtils = new odf.OdfUtils, domUtils, editinfons = "urn:webodf:names:editinfo"; + var self = this, optype = "RemoveText", memberid, timestamp, position, length, text, odfUtils, domUtils, editinfons = "urn:webodf:names:editinfo"; this.init = function(data) { runtime.assert(data.length >= 0, "OpRemoveText only supports positive lengths"); memberid = data.memberid; @@ -9842,7 +10315,7 @@ ops.OpRemoveText = function OpRemoveText() { domUtils = new core.DomUtils }; this.transform = function(otherOp, hasPriority) { - var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, end = position + length, otherOpspecEnd, same = otherOpspec.memberid === memberid, secondOp, secondOpspec, result = [self]; + var otherOpspec = otherOp.spec(), otherOptype = otherOpspec.optype, end = position + length, otherOpspecEnd, result = [self]; if(otherOptype === optype) { otherOpspecEnd = otherOpspec.position + otherOpspec.length; if(otherOpspecEnd <= position) { @@ -9884,111 +10357,99 @@ ops.OpRemoveText = function OpRemoveText() { } return result }; - function isEmpty(node) { - var childNode; - if(!odfUtils.isParagraph(node) && (odfUtils.isGroupingElement(node) || odfUtils.isCharacterElement(node)) && node.textContent.length === 0) { + function CollapsingRules(rootNode) { + function isEmpty(node) { + var childNode; + if(odfUtils.isCharacterElement(node)) { + return false + } + if(node.nodeType === Node.TEXT_NODE) { + return node.textContent.length === 0 + } childNode = node.firstChild; while(childNode) { - if(odfUtils.isCharacterElement(childNode)) { + if(!isEmpty(childNode)) { return false } childNode = childNode.nextSibling } return true } - return false - } - function mergeParagraphs(first, second, prepend) { - var parent, child, insertionPoint; - child = prepend ? second.lastChild : second.firstChild; - if(prepend) { - insertionPoint = first.getElementsByTagNameNS(editinfons, "editinfo")[0] || first.firstChild + this.isEmpty = isEmpty; + function isCollapsibleContainer(node) { + return!odfUtils.isParagraph(node) && node !== rootNode && isEmpty(node) } - while(child) { - second.removeChild(child); + function mergeChildrenIntoParent(node) { + var parent = domUtils.mergeIntoParent(node); + if(isCollapsibleContainer(parent)) { + return mergeChildrenIntoParent(parent) + } + return parent + } + this.mergeChildrenIntoParent = mergeChildrenIntoParent + } + function mergeParagraphs(first, second, collapseRules) { + var child, mergeForward, destination = first, source = second, secondParent, insertionPoint; + if(collapseRules.isEmpty(first)) { + mergeForward = true; + if(second.parentNode !== first.parentNode) { + secondParent = second.parentNode; + first.parentNode.insertBefore(second, first.nextSibling) + } + source = first; + destination = second; + insertionPoint = destination.getElementsByTagNameNS(editinfons, "editinfo")[0] || destination.firstChild + } + while(source.hasChildNodes()) { + child = mergeForward ? source.lastChild : source.firstChild; + source.removeChild(child); if(child.localName !== "editinfo") { - if(isEmpty(child)) { - while(child.firstChild) { - first.insertBefore(child.firstChild, insertionPoint) - } - }else { - first.insertBefore(child, insertionPoint) - } + destination.insertBefore(child, insertionPoint) } - child = prepend ? second.lastChild : second.firstChild } - parent = second.parentNode; - parent.removeChild(second); - if(odfUtils.isListItem(parent) && parent.childNodes.length === 0) { - parent.parentNode.removeChild(parent) + if(secondParent && collapseRules.isEmpty(secondParent)) { + collapseRules.mergeChildrenIntoParent(secondParent) } + collapseRules.mergeChildrenIntoParent(source); + return destination } - function getPreprocessedNeighborhood(odtDocument, position, length) { - odtDocument.upgradeWhitespacesAtPosition(position); - var domPosition = odtDocument.getPositionInTextNode(position), initialTextNode = domPosition.textNode, initialTextOffset = domPosition.offset, initialParentElement = initialTextNode.parentNode, paragraphElement = odtDocument.getParagraphElement(initialParentElement), remainingLength = length, neighborhood, difference; - if(initialTextNode.data === "") { - initialParentElement.removeChild(initialTextNode); - neighborhood = odtDocument.getTextNeighborhood(position, length) - }else { - if(initialTextOffset !== 0) { - difference = remainingLength < initialTextNode.length - initialTextOffset ? remainingLength : initialTextNode.length - initialTextOffset; - initialTextNode.deleteData(initialTextOffset, difference); - odtDocument.upgradeWhitespacesAtPosition(position); - neighborhood = odtDocument.getTextNeighborhood(position, length + difference); - remainingLength -= difference; - if(difference && neighborhood[0] === initialTextNode) { - neighborhood.splice(0, 1) - } - }else { - neighborhood = odtDocument.getTextNeighborhood(position, length) + function stepsToRange(odtDocument) { + var iterator, filter = odtDocument.getPositionFilter(), startContainer, startOffset, endContainer, endOffset, remainingLength = length, range = odtDocument.getDOM().createRange(); + iterator = odtDocument.getIteratorAtPosition(position); + startContainer = iterator.container(); + startOffset = iterator.unfilteredDomOffset(); + while(remainingLength && iterator.nextPosition()) { + endContainer = iterator.container(); + endOffset = iterator.unfilteredDomOffset(); + if(filter.acceptPosition(iterator) === NodeFilter.FILTER_ACCEPT) { + remainingLength -= 1 } } - return{paragraphElement:paragraphElement, neighborhood:neighborhood, remainingLength:remainingLength} + range.setStart(startContainer, startOffset); + range.setEnd(endContainer, endOffset); + domUtils.splitBoundaries(range); + return range } this.execute = function(odtDocument) { - var neighborhood = [], paragraphElement, currentParagraphElement, nextParagraphElement, remainingLength, currentTextNode = null, currentParent = null, currentLength, preprocessedNeighborhood; - preprocessedNeighborhood = getPreprocessedNeighborhood(odtDocument, position, length); - neighborhood = preprocessedNeighborhood.neighborhood; - remainingLength = preprocessedNeighborhood.remainingLength; - paragraphElement = preprocessedNeighborhood.paragraphElement; - while(remainingLength) { - if(neighborhood[0]) { - currentTextNode = neighborhood[0]; - currentParent = currentTextNode.parentNode; - currentLength = currentTextNode.length - } - currentParagraphElement = odtDocument.getParagraphElement(currentTextNode); - if(paragraphElement !== currentParagraphElement) { - nextParagraphElement = odtDocument.getNeighboringParagraph(paragraphElement, 1); - if(nextParagraphElement) { - if(odtDocument.getWalkableParagraphLength(paragraphElement) > 1) { - mergeParagraphs(paragraphElement, nextParagraphElement, false) - }else { - mergeParagraphs(nextParagraphElement, paragraphElement, true); - paragraphElement = nextParagraphElement - } - } - remainingLength -= 1 - }else { - if(currentLength <= remainingLength) { - currentParent.removeChild(currentTextNode); - odtDocument.fixCursorPositions(memberid); - while(isEmpty(currentParent)) { - currentParent = domUtils.mergeIntoParent(currentParent) - } - remainingLength -= currentLength; - neighborhood.splice(0, 1) - }else { - currentTextNode.deleteData(0, remainingLength); - odtDocument.upgradeWhitespacesAtPosition(position); - remainingLength = 0 - } - } - } - odtDocument.fixCursorPositions(memberid); + var paragraphElement, destinationParagraph, range, textNodes, paragraphs, 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); + range.detach(); + textNodes.forEach(function(element) { + collapseRules.mergeChildrenIntoParent(element) + }); + destinationParagraph = paragraphs.reduce(function(destination, paragraph) { + return mergeParagraphs(destination, paragraph, collapseRules) + }); + odtDocument.fixCursorPositions(); odtDocument.getOdfCanvas().refreshSize(); - odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:paragraphElement, memberId:memberid, timeStamp:timestamp}); + odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:destinationParagraph || paragraphElement, memberId:memberid, timeStamp:timestamp}); odtDocument.emit(ops.OdtDocument.signalCursorMoved, odtDocument.getCursor(memberid)); + odtDocument.getOdfCanvas().rerenderAnnotations(); return true }; this.spec = function() { @@ -10031,9 +10492,6 @@ ops.OpRemoveText = function OpRemoveText() { */ ops.OpSplitParagraph = function OpSplitParagraph() { var self = this, optype = "SplitParagraph", memberid, timestamp, position, odfUtils = new odf.OdfUtils; - function isListItem(node) { - return node && node.localName === "list-item" && node.namespaceURI === "urn:oasis:names:tc:opendocument:xmlns:text:1.0" - } this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; @@ -10080,6 +10538,7 @@ ops.OpSplitParagraph = function OpSplitParagraph() { }; this.execute = function(odtDocument) { var domPosition, paragraphNode, targetNode, node, splitNode, splitChildNode, keptChildNode; + odtDocument.upgradeWhitespacesAtPosition(position); domPosition = odtDocument.getPositionInTextNode(position, memberid); if(!domPosition) { return false @@ -10131,6 +10590,7 @@ ops.OpSplitParagraph = function OpSplitParagraph() { 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}); + odtDocument.getOdfCanvas().rerenderAnnotations(); return true }; this.spec = function() { @@ -10201,6 +10661,7 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() { } odtDocument.getOdfCanvas().refreshSize(); odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {paragraphElement:paragraphNode, timeStamp:timestamp, memberId:memberid}); + odtDocument.getOdfCanvas().rerenderAnnotations(); return true } } @@ -10245,46 +10706,33 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() { @source: http://gitorious.org/webodf/webodf/ */ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { - var self = this, optype = "UpdateParagraphStyle", memberid, timestamp, styleName, setProperties, removedProperties, fons = "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0", stylens = "urn:oasis:names:tc:opendocument:xmlns:style:1.0", svgns = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0", textPropertyMapping = [{propertyName:"fontSize", attrNs:fons, attrPrefix:"fo", attrLocaName:"font-size", unit:"pt"}, {propertyName:"fontName", attrNs:stylens, attrPrefix:"style", attrLocaName:"font-name"}, - {propertyName:"color", attrNs:fons, attrPrefix:"fo", attrLocaName:"color"}, {propertyName:"backgroundColor", attrNs:fons, attrPrefix:"fo", attrLocaName:"background-color"}, {propertyName:"fontWeight", attrNs:fons, attrPrefix:"fo", attrLocaName:"font-weight"}, {propertyName:"fontStyle", attrNs:fons, attrPrefix:"fo", attrLocaName:"font-style"}, {propertyName:"underline", attrNs:stylens, attrPrefix:"style", attrLocaName:"text-underline-style"}, {propertyName:"strikethrough", attrNs:stylens, attrPrefix:"style", - attrLocaName:"text-line-through-style"}], paragraphPropertyMapping = [{propertyName:"topMargin", attrNs:fons, attrPrefix:"fo", attrLocaName:"margin-top", unit:"mm"}, {propertyName:"bottomMargin", attrNs:fons, attrPrefix:"fo", attrLocaName:"margin-bottom", unit:"mm"}, {propertyName:"leftMargin", attrNs:fons, attrPrefix:"fo", attrLocaName:"margin-left", unit:"mm"}, {propertyName:"rightMargin", attrNs:fons, attrPrefix:"fo", attrLocaName:"margin-right", unit:"mm"}, {propertyName:"textAlign", attrNs:fons, - attrPrefix:"fo", attrLocaName:"text-align"}]; - function setPropertiesInStyleNode(node, properties, propertyMapping) { - var i, m, value; - for(i = 0;i < propertyMapping.length;i += 1) { - m = propertyMapping[i]; - value = properties[m.propertyName]; - if(value !== undefined) { - node.setAttributeNS(m.attrNs, m.attrPrefix + ":" + m.attrLocaName, m.unit !== undefined ? value + m.unit : value) - } + var self = this, optype = "UpdateParagraphStyle", memberid, timestamp, styleName, setProperties, removedProperties, stylens = "urn:oasis:names:tc:opendocument:xmlns:style:1.0", svgns = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"; + function removePropertiesFromStyleNode(node, removedPropertyNames) { + var i, propertyNameParts; + for(i = 0;i < removedPropertyNames.length;i += 1) { + propertyNameParts = removedPropertyNames[i].split(":"); + node.removeAttributeNS(odf.Namespaces.resolvePrefix(propertyNameParts[0]), propertyNameParts[1]) } } - function removePropertiesFromStyleNode(node, removedPropertyNames, propertyMapping) { - var i, m; - for(i = 0;i < propertyMapping.length;i += 1) { - m = propertyMapping[i]; - if(removedPropertyNames.indexOf(m.propertyName) !== -1) { - node.removeAttributeNS(m.attrNs, m.attrLocaName) - } - } - } - function dropShadowedProperties(properties, removedPropertyNames, shadowingProperties, shadowingRemovedPropertyNames, propertyMapping) { - var i, propertyName, p; - if(!properties && !removedPropertyNames || !shadowingProperties && !shadowingRemovedPropertyNames) { - return - } - for(i = 0;i < propertyMapping.length;i += 1) { - propertyName = propertyMapping[i].propertyName; - if(shadowingProperties && shadowingProperties[propertyName] !== undefined || shadowingRemovedPropertyNames && shadowingRemovedPropertyNames.indexOf(propertyName) !== -1) { - if(properties) { - delete properties[propertyName] - } - if(removedPropertyNames) { - p = removedPropertyNames.indexOf(propertyName); - if(p !== -1) { - removedPropertyNames.splice(p, 1) + function dropShadowedProperties(properties, removedPropertyNames, shadowingProperties, shadowingRemovedPropertyNames) { + var value, i, name; + if(properties && (shadowingProperties || shadowingRemovedPropertyNames)) { + 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(removedPropertyNames && (shadowingProperties || shadowingRemovedPropertyNames)) { + 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 + } } } } @@ -10309,9 +10757,9 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { if(otherOpType === optype) { if(otherOpspec.styleName === styleName) { if(!hasPriority) { - dropShadowedProperties(setProperties ? setProperties.paragraphProperties : null, removedProperties ? removedProperties.paragraphPropertyNames : null, otherOpspec.setProperties ? otherOpspec.setProperties.paragraphProperties : null, otherOpspec.removedProperties ? otherOpspec.removedProperties.paragraphPropertyNames : null, paragraphPropertyMapping); - dropShadowedProperties(setProperties ? setProperties.textProperties : null, removedProperties ? removedProperties.textPropertyNames : null, otherOpspec.setProperties ? otherOpspec.setProperties.textProperties : null, otherOpspec.removedProperties ? otherOpspec.removedProperties.textPropertyNames : null, textPropertyMapping); - if(!(setProperties && (hasProperties(setProperties.textProperties) || hasProperties(setProperties.paragraphProperties))) && !(removedProperties && (removedProperties.textPropertyNames.length > 0 || removedProperties.paragraphPropertyNames.length > 0))) { + dropShadowedProperties(setProperties ? setProperties["style:paragraph-properties"] : null, removedProperties ? removedProperties.paragraphPropertyNames : null, otherOpspec.setProperties ? otherOpspec.setProperties["style:paragraph-properties"] : null, otherOpspec.removedProperties ? otherOpspec.removedProperties.paragraphPropertyNames : null); + dropShadowedProperties(setProperties ? setProperties["style:text-properties"] : null, removedProperties ? removedProperties.textPropertyNames : null, otherOpspec.setProperties ? otherOpspec.setProperties["style:text-properties"] : null, otherOpspec.removedProperties ? otherOpspec.removedProperties.textPropertyNames : null); + if(!(setProperties && (hasProperties(setProperties["style:text-properties"]) || hasProperties(setProperties["style:paragraph-properties"]))) && !(removedProperties && (removedProperties.textPropertyNames.length > 0 || removedProperties.paragraphPropertyNames.length > 0))) { return[] } } @@ -10326,42 +10774,43 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { return[self] }; this.execute = function(odtDocument) { - var styleNode, paragraphPropertiesNode, textPropertiesNode, fontFaceNode; + var styleNode, paragraphPropertiesNode, textPropertiesNode, fontFaceNode, fontName, formatting = odtDocument.getFormatting(); styleNode = odtDocument.getParagraphStyleElement(styleName); if(styleNode) { paragraphPropertiesNode = styleNode.getElementsByTagNameNS(stylens, "paragraph-properties")[0]; textPropertiesNode = styleNode.getElementsByTagNameNS(stylens, "text-properties")[0]; if(setProperties) { - if(paragraphPropertiesNode === undefined && setProperties.paragraphProperties) { + if(paragraphPropertiesNode === undefined && setProperties["style:paragraph-properties"]) { paragraphPropertiesNode = odtDocument.getDOM().createElementNS(stylens, "style:paragraph-properties"); styleNode.appendChild(paragraphPropertiesNode) } - if(textPropertiesNode === undefined && setProperties.textProperties) { + if(textPropertiesNode === undefined && setProperties["style:text-properties"]) { textPropertiesNode = odtDocument.getDOM().createElementNS(stylens, "style:text-properties"); styleNode.appendChild(textPropertiesNode) } - if(setProperties.paragraphProperties) { - setPropertiesInStyleNode(paragraphPropertiesNode, setProperties.paragraphProperties, paragraphPropertyMapping) + if(setProperties["style:paragraph-properties"]) { + formatting.updateStyle(paragraphPropertiesNode, setProperties["style:paragraph-properties"]) } - if(setProperties.textProperties) { - if(setProperties.textProperties.fontName && !odtDocument.getOdfCanvas().getFormatting().getFontMap().hasOwnProperty(setProperties.textProperties.fontName)) { + if(setProperties["style:text-properties"]) { + fontName = setProperties["style:text-properties"]["style:font-name"]; + if(fontName && !formatting.getFontMap().hasOwnProperty(fontName)) { fontFaceNode = odtDocument.getDOM().createElementNS(stylens, "style:font-face"); - fontFaceNode.setAttributeNS(stylens, "style:name", setProperties.textProperties.fontName); - fontFaceNode.setAttributeNS(svgns, "svg:font-family", setProperties.textProperties.fontName); + fontFaceNode.setAttributeNS(stylens, "style:name", fontName); + fontFaceNode.setAttributeNS(svgns, "svg:font-family", fontName); odtDocument.getOdfCanvas().odfContainer().rootElement.fontFaceDecls.appendChild(fontFaceNode) } - setPropertiesInStyleNode(textPropertiesNode, setProperties.textProperties, textPropertyMapping) + formatting.updateStyle(textPropertiesNode, setProperties["style:text-properties"]) } } if(removedProperties) { if(removedProperties.paragraphPropertyNames) { - removePropertiesFromStyleNode(paragraphPropertiesNode, removedProperties.paragraphPropertyNames, paragraphPropertyMapping); + removePropertiesFromStyleNode(paragraphPropertiesNode, removedProperties.paragraphPropertyNames); if(paragraphPropertiesNode.attributes.length === 0) { styleNode.removeChild(paragraphPropertiesNode) } } if(removedProperties.textPropertyNames) { - removePropertiesFromStyleNode(textPropertiesNode, removedProperties.textPropertyNames, textPropertyMapping); + removePropertiesFromStyleNode(textPropertiesNode, removedProperties.textPropertyNames); if(textPropertiesNode.attributes.length === 0) { styleNode.removeChild(textPropertiesNode) } @@ -10369,6 +10818,7 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { } odtDocument.getOdfCanvas().refreshCSS(); odtDocument.emit(ops.OdtDocument.signalParagraphStyleModified, styleName); + odtDocument.getOdfCanvas().rerenderAnnotations(); return true } return false @@ -10411,14 +10861,14 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() { @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.OpCloneParagraphStyle = function OpCloneParagraphStyle() { - var self = this, memberid, timestamp, styleName, newStyleName, newStyleDisplayName, stylens = "urn:oasis:names:tc:opendocument:xmlns:style:1.0"; +runtime.loadClass("odf.Namespaces"); +ops.OpAddParagraphStyle = function OpAddParagraphStyle() { + var self = this, memberid, timestamp, styleName, setProperties, paragraphPropertiesName = "style:paragraph-properties", textPropertiesName = "style:text-properties", svgns = odf.Namespaces.svgns, stylens = odf.Namespaces.stylens; this.init = function(data) { memberid = data.memberid; timestamp = data.timestamp; styleName = data.styleName; - newStyleName = data.newStyleName; - newStyleDisplayName = data.newStyleDisplayName + setProperties = data.setProperties }; this.transform = function(otherOp, hasPriority) { var otherSpec = otherOp.spec(); @@ -10428,24 +10878,47 @@ ops.OpCloneParagraphStyle = function OpCloneParagraphStyle() { return[self] }; this.execute = function(odtDocument) { - var styleNode = odtDocument.getParagraphStyleElement(styleName), newStyleNode; + var odfContainer = odtDocument.getOdfCanvas().odfContainer(), formatting = odtDocument.getFormatting(), dom = odtDocument.getDOM(), styleNode = dom.createElementNS(stylens, "style:style"), paragraphPropertiesNode, textPropertiesNode, fontFaceNode, fontName, ns; if(!styleNode) { return false } - newStyleNode = styleNode.cloneNode(true); - newStyleNode.setAttributeNS(stylens, "style:name", newStyleName); - if(newStyleDisplayName) { - newStyleNode.setAttributeNS(stylens, "style:display-name", newStyleDisplayName) - }else { - newStyleNode.removeAttributeNS(stylens, "display-name") + styleNode.setAttributeNS(stylens, "style:family", "paragraph"); + styleNode.setAttributeNS(stylens, "style:name", styleName); + if(setProperties) { + Object.keys(setProperties).forEach(function(propertyName) { + switch(propertyName) { + case paragraphPropertiesName: + paragraphPropertiesNode = dom.createElementNS(stylens, paragraphPropertiesName); + styleNode.appendChild(paragraphPropertiesNode); + formatting.updateStyle(paragraphPropertiesNode, setProperties[paragraphPropertiesName]); + break; + case textPropertiesName: + textPropertiesNode = dom.createElementNS(stylens, textPropertiesName); + styleNode.appendChild(textPropertiesNode); + fontName = setProperties[textPropertiesName]["style:font-name"]; + if(fontName && !formatting.getFontMap().hasOwnProperty(fontName)) { + fontFaceNode = dom.createElementNS(stylens, "style:font-face"); + fontFaceNode.setAttributeNS(stylens, "style:name", fontName); + fontFaceNode.setAttributeNS(svgns, "svg:font-family", fontName); + odfContainer.rootElement.fontFaceDecls.appendChild(fontFaceNode) + } + formatting.updateStyle(textPropertiesNode, setProperties[textPropertiesName]); + break; + default: + if(typeof setProperties[propertyName] !== "object") { + ns = odf.Namespaces.resolvePrefix(propertyName.substr(0, propertyName.indexOf(":"))); + styleNode.setAttributeNS(ns, propertyName, setProperties[propertyName]) + } + } + }) } - styleNode.parentNode.appendChild(newStyleNode); + odfContainer.rootElement.styles.appendChild(styleNode); odtDocument.getOdfCanvas().refreshCSS(); - odtDocument.emit(ops.OdtDocument.signalStyleCreated, newStyleName); + odtDocument.emit(ops.OdtDocument.signalStyleCreated, styleName); return true }; this.spec = function() { - return{optype:"CloneParagraphStyle", memberid:memberid, timestamp:timestamp, styleName:styleName, newStyleName:newStyleName, newStyleDisplayName:newStyleDisplayName} + return{optype:"AddParagraphStyle", memberid:memberid, timestamp:timestamp, styleName:styleName, setProperties:setProperties} } }; /* @@ -10555,8 +11028,112 @@ ops.OpDeleteParagraphStyle = function OpDeleteParagraphStyle() { @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ +ops.OpAddAnnotation = function OpAddAnnotation() { + var memberid, timestamp, position, length, name; + this.init = function(data) { + memberid = data.memberid; + timestamp = parseInt(data.timestamp, 10); + position = parseInt(data.position, 10); + length = parseInt(data.length, 10) || 0; + name = data.name + }; + this.transform = function(otherOp, hasPriority) { + if(otherOp || hasPriority) { + return null + } + return null + }; + function createAnnotationNode(odtDocument, date) { + var annotationNode, creatorNode, dateNode, listNode, listItemNode, paragraphNode, doc = odtDocument.getRootNode().ownerDocument; + 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); + dateNode = doc.createElementNS(odf.Namespaces.dcns, "dc:date"); + dateNode.appendChild(doc.createTextNode(date.toISOString())); + listNode = doc.createElementNS(odf.Namespaces.textns, "text:list"); + listItemNode = doc.createElementNS(odf.Namespaces.textns, "text:list-item"); + paragraphNode = doc.createElementNS(odf.Namespaces.textns, "text:p"); + listItemNode.appendChild(paragraphNode); + listNode.appendChild(listItemNode); + annotationNode.appendChild(creatorNode); + annotationNode.appendChild(dateNode); + annotationNode.appendChild(listNode); + return annotationNode + } + function createAnnotationEnd(odtDocument) { + var annotationEnd, doc = odtDocument.getRootNode().ownerDocument; + annotationEnd = doc.createElementNS(odf.Namespaces.officens, "office:annotation-end"); + annotationEnd.setAttributeNS(odf.Namespaces.officens, "office:name", name); + return annotationEnd + } + function insertNodeAtPosition(odtDocument, node, insertPosition) { + var previousNode, domPosition = odtDocument.getPositionInTextNode(insertPosition); + if(domPosition) { + previousNode = domPosition.textNode; + if(domPosition.offset !== previousNode.length) { + previousNode.splitText(domPosition.offset) + } + previousNode.parentNode.insertBefore(node, previousNode.nextSibling) + } + } + this.execute = function(odtDocument) { + var annotation = {}; + annotation.node = createAnnotationNode(odtDocument, new Date(timestamp)); + if(!annotation.node) { + return false + } + if(length) { + annotation.end = createAnnotationEnd(odtDocument); + if(!annotation.end) { + return false + } + insertNodeAtPosition(odtDocument, annotation.end, position + length) + } + insertNodeAtPosition(odtDocument, annotation.node, position); + odtDocument.getOdfCanvas().addAnnotation(annotation); + return true + }; + this.spec = function() { + return{optype:"AddAnnotation", memberid:memberid, timestamp:timestamp, position:position, length:length, name:name} + } +}; +/* + + Copyright (C) 2012-2013 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ runtime.loadClass("ops.OpAddCursor"); -runtime.loadClass("ops.OpApplyStyle"); +runtime.loadClass("ops.OpApplyDirectStyling"); runtime.loadClass("ops.OpRemoveCursor"); runtime.loadClass("ops.OpMoveCursor"); runtime.loadClass("ops.OpInsertTable"); @@ -10565,8 +11142,9 @@ runtime.loadClass("ops.OpRemoveText"); runtime.loadClass("ops.OpSplitParagraph"); runtime.loadClass("ops.OpSetParagraphStyle"); runtime.loadClass("ops.OpUpdateParagraphStyle"); -runtime.loadClass("ops.OpCloneParagraphStyle"); +runtime.loadClass("ops.OpAddParagraphStyle"); runtime.loadClass("ops.OpDeleteParagraphStyle"); +runtime.loadClass("ops.OpAddAnnotation"); ops.OperationFactory = function OperationFactory() { var specs; this.register = function(specName, specConstructor) { @@ -10586,8 +11164,8 @@ ops.OperationFactory = function OperationFactory() { } } function init() { - specs = {AddCursor:constructor(ops.OpAddCursor), ApplyStyle:constructor(ops.OpApplyStyle), InsertTable:constructor(ops.OpInsertTable), InsertText:constructor(ops.OpInsertText), RemoveText:constructor(ops.OpRemoveText), SplitParagraph:constructor(ops.OpSplitParagraph), SetParagraphStyle:constructor(ops.OpSetParagraphStyle), UpdateParagraphStyle:constructor(ops.OpUpdateParagraphStyle), CloneParagraphStyle:constructor(ops.OpCloneParagraphStyle), DeleteParagraphStyle:constructor(ops.OpDeleteParagraphStyle), - MoveCursor:constructor(ops.OpMoveCursor), RemoveCursor:constructor(ops.OpRemoveCursor)} + 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), AddParagraphStyle:constructor(ops.OpAddParagraphStyle), DeleteParagraphStyle:constructor(ops.OpDeleteParagraphStyle), + MoveCursor:constructor(ops.OpMoveCursor), RemoveCursor:constructor(ops.OpRemoveCursor), AddAnnotation:constructor(ops.OpAddAnnotation)} } init() }; @@ -10597,7 +11175,7 @@ runtime.loadClass("core.PositionFilter"); runtime.loadClass("core.LoopWatchDog"); runtime.loadClass("odf.OdfUtils"); gui.SelectionMover = function SelectionMover(cursor, rootNode) { - var self = this, odfUtils, positionIterator, cachedXOffset, timeoutHandle; + var odfUtils, positionIterator, cachedXOffset, timeoutHandle, FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT; function getOffset(el) { var x = 0, y = 0; while(el && el.nodeType === Node.ELEMENT_NODE) { @@ -10624,7 +11202,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { if(!containerOffset) { containerOffset = getOffset(container) } - runtime.assert(containerOffset, "getRect: invalid containerOffset"); + runtime.assert(containerOffset, "getRect: invalid containerOffset"); rect.top = containerOffset.top; rect.left = containerOffset.right; rect.bottom = containerOffset.bottom @@ -10643,13 +11221,12 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { } } } - runtime.assert(rect, "getRect invalid rect"); - runtime.assert(rect.top !== undefined, "getRect rect without top property"); - + runtime.assert(rect, "getRect invalid rect"); + runtime.assert(rect.top !== undefined, "getRect rect without top property"); return{top:rect.top, left:rect.left, bottom:rect.bottom} } 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; + 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(); initialRect = getRect((cursor.getNode()), 0, range); while(left > 0 && move()) { left -= 1 @@ -10688,7 +11265,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { }; function isPositionWalkable(filter) { var iterator = getIteratorAtCursor(); - if(filter.acceptPosition(iterator) === 1) { + if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { return true } return false @@ -10698,7 +11275,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { while(steps > 0 && iterator.nextPosition()) { stepCount += 1; watch.check(); - if(filter.acceptPosition(iterator) === 1) { + if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { count += stepCount; stepCount = 0; steps -= 1 @@ -10706,12 +11283,42 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { } return count } + function convertForwardStepsBetweenFilters(steps, filter1, filter2) { + var iterator = getIteratorAtCursor(), watch = new core.LoopWatchDog(1E3), stepCount = 0, count = 0; + while(steps > 0 && iterator.nextPosition()) { + watch.check(); + if(filter2.acceptPosition(iterator) === FILTER_ACCEPT) { + stepCount += 1; + if(filter1.acceptPosition(iterator) === FILTER_ACCEPT) { + count += stepCount; + stepCount = 0; + steps -= 1 + } + } + } + return count + } + function convertBackwardStepsBetweenFilters(steps, filter1, filter2) { + var iterator = getIteratorAtCursor(), watch = new core.LoopWatchDog(1E3), stepCount = 0, count = 0; + while(steps > 0 && iterator.previousPosition()) { + watch.check(); + if(filter2.acceptPosition(iterator) === FILTER_ACCEPT) { + stepCount += 1; + if(filter1.acceptPosition(iterator) === FILTER_ACCEPT) { + count += stepCount; + stepCount = 0; + steps -= 1 + } + } + } + return count + } 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) === 1) { + if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { count += stepCount; stepCount = 0; steps -= 1 @@ -10719,6 +11326,14 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { } 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); rect = getRect(c, iterator.unfilteredDomOffset(), range); @@ -10731,7 +11346,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { lastTop = top; while((direction < 0 ? iterator.previousPosition() : iterator.nextPosition()) === true) { watch.check(); - if(filter.acceptPosition(iterator) === 1) { + if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { count += 1; c = iterator.container(); rect = getRect(c, iterator.unfilteredDomOffset(), range); @@ -10773,7 +11388,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { return count * direction } function countStepsToLineBoundary(direction, filter) { - var iterator = getIteratorAtCursor(), paragraphNode = odfUtils.getParagraphElement(iterator.getCurrentNode()), count = 0, fnNextPos, increment, lastRect, rect, onSameLine, range = (rootNode.ownerDocument.createRange()); + var fnNextPos, increment, lastRect, rect, onSameLine, iterator = getIteratorAtCursor(), paragraphNode = odfUtils.getParagraphElement(iterator.getCurrentNode()), count = 0, range = (rootNode.ownerDocument.createRange()); if(direction < 0) { fnNextPos = iterator.previousPosition; increment = -1 @@ -10783,7 +11398,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { } lastRect = getRect(iterator.container(), iterator.unfilteredDomOffset(), range); while(fnNextPos.call(iterator)) { - if(filter.acceptPosition(iterator) === NodeFilter.FILTER_ACCEPT) { + if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { if(odfUtils.getParagraphElement(iterator.getCurrentNode()) !== paragraphNode) { break } @@ -10848,7 +11463,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { if(comparison < 0) { while(iterator.nextPosition()) { watch.check(); - if(filter.acceptPosition(iterator) === 1) { + if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { steps += 1 } if(iterator.container() === posElement) { @@ -10861,7 +11476,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { if(comparison > 0) { while(iterator.previousPosition()) { watch.check(); - if(filter.acceptPosition(iterator) === 1) { + if(filter.acceptPosition(iterator) === FILTER_ACCEPT) { steps -= 1 } if(iterator.container() === posElement) { @@ -10875,7 +11490,7 @@ gui.SelectionMover = function SelectionMover(cursor, rootNode) { return steps } this.getStepCounter = function() { - return{countForwardSteps:countForwardSteps, countBackwardSteps:countBackwardSteps, countLinesSteps:countLinesSteps, countStepsToLineBoundary:countStepsToLineBoundary, countStepsToPosition:countStepsToPosition, isPositionWalkable:isPositionWalkable} + return{countForwardSteps:countForwardSteps, countBackwardSteps:countBackwardSteps, convertForwardStepsBetweenFilters:convertForwardStepsBetweenFilters, convertBackwardStepsBetweenFilters:convertBackwardStepsBetweenFilters, countLinesSteps:countLinesSteps, countStepsToLineBoundary:countStepsToLineBoundary, countStepsToPosition:countStepsToPosition, isPositionWalkable:isPositionWalkable, countStepsToValidPosition:countStepsToValidPosition} }; function init() { odfUtils = new odf.OdfUtils; @@ -10944,11 +11559,11 @@ runtime.loadClass("ops.OpInsertText"); runtime.loadClass("ops.OpRemoveText"); runtime.loadClass("ops.OpSplitParagraph"); runtime.loadClass("ops.OpSetParagraphStyle"); +runtime.loadClass("ops.OpAddParagraphStyle"); runtime.loadClass("ops.OpUpdateParagraphStyle"); -runtime.loadClass("ops.OpCloneParagraphStyle"); runtime.loadClass("ops.OpDeleteParagraphStyle"); ops.OperationTransformer = function OperationTransformer() { - var self = this, operationFactory; + var operationFactory; function transformOpVsOp(opA, opB) { var oldOpB, opATransformResult, opBTransformResult; runtime.log("Crosstransforming:"); @@ -10996,7 +11611,7 @@ ops.OperationTransformer = function OperationTransformer() { operationFactory = f }; this.transform = function(opspecsA, opspecsB) { - var c, s, opsA = [], clientOp, transformedClientOps, serverOp, oldServerOp, transformResult, transformedOpsB = []; + var c, s, opsA = [], clientOp, serverOp, transformResult, transformedOpsB = []; for(c = 0;c < opspecsA.length;c += 1) { clientOp = operationFactory.create(opspecsA[c]); if(!clientOp) { @@ -11096,7 +11711,7 @@ ops.OdtCursor = function OdtCursor(memberId, odtDocument) { @source: http://gitorious.org/webodf/webodf/ */ ops.EditInfo = function EditInfo(container, odtDocument) { - var self = this, editInfoNode, editHistory = {}; + var editInfoNode, editHistory = {}; function sortEdits() { var arr = [], memberid; for(memberid in editHistory) { @@ -11192,18 +11807,21 @@ gui.Avatar = function Avatar(parentElement, avatarInitiallyVisible) { }; runtime.loadClass("gui.Avatar"); runtime.loadClass("ops.OdtCursor"); -gui.Caret = function Caret(cursor, avatarInitiallyVisible) { - var self = this, span, avatar, cursorNode, focussed = false, blinking = false, color = ""; - function blink() { - if(!focussed || !cursorNode.parentNode) { +gui.Caret = function Caret(cursor, avatarInitiallyVisible, blinkOnRangeSelect) { + var span, avatar, cursorNode, shouldBlink = false, blinking = false, blinkTimeout; + function blink(reset) { + if(!shouldBlink || !cursorNode.parentNode) { return } - if(!blinking) { + if(!blinking || reset) { + if(reset && blinkTimeout !== undefined) { + runtime.clearTimeout(blinkTimeout) + } blinking = true; - span.style.borderColor = span.style.borderColor === "transparent" ? color : "transparent"; - runtime.setTimeout(function() { + span.style.opacity = reset || span.style.opacity === "0" ? "1" : "0"; + blinkTimeout = runtime.setTimeout(function() { blinking = false; - blink() + blink(false) }, 500) } } @@ -11278,28 +11896,31 @@ gui.Caret = function Caret(cursor, avatarInitiallyVisible) { caretOffsetTopLeft.y += caretElement.offsetTop; return{left:caretOffsetTopLeft.x - margin, top:caretOffsetTopLeft.y - margin, right:caretOffsetTopLeft.x + caretElement.scrollWidth - 1 + margin, bottom:caretOffsetTopLeft.y + caretElement.scrollHeight - 1 + margin} } + this.refreshCursor = function() { + if(blinkOnRangeSelect || cursor.getSelectedRange().collapsed) { + shouldBlink = true; + blink(true) + }else { + shouldBlink = false; + span.style.opacity = "0" + } + }; this.setFocus = function() { - focussed = true; + shouldBlink = true; avatar.markAsFocussed(true); - blink() + blink(true) }; this.removeFocus = function() { - focussed = false; + shouldBlink = false; avatar.markAsFocussed(false); - span.style.borderColor = color + span.style.opacity = "0" }; this.setAvatarImageUrl = function(url) { avatar.setImageUrl(url) }; this.setColor = function(newColor) { - if(color === newColor) { - return - } - color = newColor; - if(span.style.borderColor !== "transparent") { - span.style.borderColor = color - } - avatar.setColor(color) + span.style.borderColor = newColor; + avatar.setColor(newColor) }; this.getCursor = function() { return cursor @@ -11362,7 +11983,7 @@ gui.ClickHandler = function ClickHandler() { if(clickPosition && clickPosition.x === e.screenX && clickPosition.y === e.screenY) { clickCount += 1; if(clickCount === 1) { - eventNotifier.emit(gui.ClickHandler.signalSingleClick, undefined) + eventNotifier.emit(gui.ClickHandler.signalSingleClick, e) }else { if(clickCount === 2) { eventNotifier.emit(gui.ClickHandler.signalDoubleClick, undefined) @@ -11375,7 +11996,7 @@ gui.ClickHandler = function ClickHandler() { } } }else { - eventNotifier.emit(gui.ClickHandler.signalSingleClick, undefined); + eventNotifier.emit(gui.ClickHandler.signalSingleClick, e); clickCount = 1; clickPosition = {x:e.screenX, y:e.screenY}; window.clearTimeout(clickTimer); @@ -11443,7 +12064,7 @@ gui.KeyboardHandler = function KeyboardHandler() { } function getKeyCombo(keyCode, modifiers) { if(!modifiers) { - modifiers = modifiers.None + modifiers = modifier.None } return keyCode + ":" + modifiers } @@ -11482,37 +12103,77 @@ gui.KeyboardHandler = function KeyboardHandler() { } }; gui.KeyboardHandler.Modifier = {None:0, Meta:1, Ctrl:2, Alt:4, Shift:8, MetaShift:9, CtrlShift:10, AltShift:12}; -gui.KeyboardHandler.KeyCode = {Backspace:8, Enter:13, End:35, Home:36, Left:37, Up:38, Right:39, Down:40, Delete:46, Z:90}; +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, I:73, U:85, Z:90}; (function() { return gui.KeyboardHandler })(); +/* + + 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 Clipboard() { + var xmlSerializer, textSerializer, filter; this.setDataFromRange = function(e, range) { - var result = true, setDataResult, clipboard = e.clipboardData, window = runtime.getWindow(), serializer, dom, newNode, fragmentContainer; + var result = true, setDataResult, clipboard = e.clipboardData, window = runtime.getWindow(), document = range.startContainer.ownerDocument, fragmentContainer; if(!clipboard && window) { clipboard = window.clipboardData } if(clipboard) { - serializer = new XMLSerializer; - dom = runtime.getDOMImplementation().createDocument("", "", null); - newNode = dom.importNode(range.cloneContents(), true); - fragmentContainer = dom.createElement("span"); - fragmentContainer.appendChild(newNode); - dom.appendChild(fragmentContainer); - setDataResult = clipboard.setData("text/plain", range.toString()); + fragmentContainer = document.createElement("span"); + fragmentContainer.appendChild(range.cloneContents()); + setDataResult = clipboard.setData("text/plain", textSerializer.writeToString(fragmentContainer)); result = result && setDataResult; - setDataResult = clipboard.setData("text/html", serializer.serializeToString(dom)); + setDataResult = clipboard.setData("text/html", xmlSerializer.writeToString(fragmentContainer, odf.Namespaces.namespaceMap)); result = result && setDataResult; e.preventDefault() }else { result = false } return result + }; + function init() { + xmlSerializer = new xmldom.LSSerializer; + textSerializer = new odf.TextSerializer; + filter = new odf.OdfNodeFilter; + xmlSerializer.filter = filter; + textSerializer.filter = filter } + init() }; -(function() { - return gui.Clipboard -})(); runtime.loadClass("ops.OpAddCursor"); runtime.loadClass("ops.OpRemoveCursor"); runtime.loadClass("ops.OpMoveCursor"); @@ -11521,11 +12182,14 @@ runtime.loadClass("ops.OpRemoveText"); runtime.loadClass("ops.OpSplitParagraph"); runtime.loadClass("ops.OpSetParagraphStyle"); runtime.loadClass("gui.ClickHandler"); -runtime.loadClass("gui.KeyboardHandler"); runtime.loadClass("gui.Clipboard"); +runtime.loadClass("gui.KeyboardHandler"); +runtime.loadClass("gui.StyleHelper"); gui.SessionController = function() { gui.SessionController = function SessionController(session, inputMemberId) { - var self = this, odtDocument = session.getOdtDocument(), odfUtils = new odf.OdfUtils, clipboard = new gui.Clipboard, clickHandler = new gui.ClickHandler, keyDownHandler = new gui.KeyboardHandler, keyPressHandler = new gui.KeyboardHandler, undoManager; + var odtDocument = session.getOdtDocument(), odfUtils = new odf.OdfUtils, clipboard = new gui.Clipboard, clickHandler = new gui.ClickHandler, keyDownHandler = new gui.KeyboardHandler, keyPressHandler = new gui.KeyboardHandler, styleHelper = new gui.StyleHelper(odtDocument.getFormatting()), keyboardMovementsFilter = new core.PositionFilterChain, baseFilter = odtDocument.getPositionFilter(), undoManager = null; + 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) { @@ -11570,7 +12234,7 @@ gui.SessionController = function() { var iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), canvasElement = odtDocument.getOdfCanvas().getElement(), node; node = targetNode; if(!node) { - return + return null } while(node !== canvasElement) { if(node.namespaceURI === "urn:webodf:names:cursor" && node.localName === "cursor" || node.namespaceURI === "urn:webodf:names:editinfo" && node.localName === "editinfo") { @@ -11578,7 +12242,7 @@ gui.SessionController = function() { } node = node.parentNode; if(!node) { - return + return null } } if(node !== canvasElement && targetNode !== node) { @@ -11588,17 +12252,43 @@ gui.SessionController = function() { iterator.setUnfilteredPosition(targetNode, targetOffset); return odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()) } - function select() { - var selection = runtime.getWindow().getSelection(), oldPosition = odtDocument.getCursorPosition(inputMemberId), stepsToAnchor, stepsToFocus, op; - stepsToAnchor = countStepsToNode(selection.anchorNode, selection.anchorOffset); - stepsToFocus = countStepsToNode(selection.focusNode, selection.focusOffset); - if(stepsToFocus !== 0 || stepsToAnchor !== 0) { - op = createOpMoveCursor(oldPosition + stepsToAnchor, stepsToFocus - stepsToAnchor); - session.enqueue(op) + function caretPositionFromPoint(x, y) { + var doc = odtDocument.getDOM(), result; + if(doc.caretRangeFromPoint) { + result = doc.caretRangeFromPoint(x, y); + return{container:result.startContainer, offset:result.startOffset} } + if(doc.caretPositionFromPoint) { + result = doc.caretPositionFromPoint(x, y); + return{container:result.offsetNode, offset:result.offset} + } + return null + } + function selectRange(e) { + runtime.setTimeout(function() { + var selection = runtime.getWindow().getSelection(), oldPosition = odtDocument.getCursorPosition(inputMemberId), range, caretPos, stepsToAnchor, stepsToFocus, op; + if(selection.anchorNode === null && selection.focusNode === null) { + caretPos = caretPositionFromPoint(e.clientX, e.clientY); + if(caretPos) { + range = odtDocument.getDOM().createRange(); + range.setStart(caretPos.container, caretPos.offset); + range.collapse(true); + selection.addRange(range) + } + } + stepsToAnchor = countStepsToNode(selection.anchorNode, selection.anchorOffset); + stepsToFocus = countStepsToNode(selection.focusNode, selection.focusOffset); + if(stepsToFocus !== null && stepsToFocus !== 0 || stepsToAnchor !== null && stepsToAnchor !== 0) { + op = createOpMoveCursor(oldPosition + stepsToAnchor, stepsToFocus - stepsToAnchor); + session.enqueue(op) + } + }, 0) + } + function handleContextMenu(e) { + selectRange(e) } function selectWord() { - var iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), cursorNode = odtDocument.getCursor(inputMemberId).getNode(), oldPosition = odtDocument.getCursorPosition(inputMemberId), alphaNumeric = /[A-Za-z0-9]/, stepsToStart = 0, stepsToEnd = 0, currentNode, i, c, op; + var currentNode, i, c, op, iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), cursorNode = odtDocument.getCursor(inputMemberId).getNode(), oldPosition = odtDocument.getCursorPosition(inputMemberId), alphaNumeric = /[A-Za-z0-9]/, stepsToStart = 0, stepsToEnd = 0; iterator.setUnfilteredPosition(cursorNode, 0); if(iterator.previousPosition()) { currentNode = iterator.getCurrentNode(); @@ -11633,7 +12323,7 @@ gui.SessionController = function() { } } function selectParagraph() { - var iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), oldPosition = odtDocument.getCursorPosition(inputMemberId), stepsToStart, stepsToEnd, op; + var stepsToStart, stepsToEnd, op, iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), oldPosition = odtDocument.getCursorPosition(inputMemberId); stepsToStart = odtDocument.getDistanceFromCursor(inputMemberId, paragraphNode, 0); iterator.moveToEndOfNode(paragraphNode); stepsToEnd = odtDocument.getDistanceFromCursor(inputMemberId, paragraphNode, iterator.unfilteredDomOffset()); @@ -11642,76 +12332,86 @@ gui.SessionController = function() { session.enqueue(op) } } - function sessionEnqueue(op) { - if(op) { - session.enqueue(op) + function extendCursorByAdjustment(lengthAdjust) { + var selection = odtDocument.getCursorSelection(inputMemberId), stepCounter = odtDocument.getCursor(inputMemberId).getStepCounter(), newLength; + if(lengthAdjust !== 0) { + lengthAdjust = lengthAdjust > 0 ? stepCounter.convertForwardStepsBetweenFilters(lengthAdjust, keyboardMovementsFilter, baseFilter) : -stepCounter.convertBackwardStepsBetweenFilters(-lengthAdjust, keyboardMovementsFilter, baseFilter); + newLength = selection.length + lengthAdjust; + session.enqueue(createOpMoveCursor(selection.position, newLength)) } } - function createOpMoveCursorByAdjustment(posAdjust, lenAdjust) { - var selection = odtDocument.getCursorSelection(inputMemberId), newPos, newLen; - if(posAdjust === 0 && lenAdjust === 0) { - return null + function moveCursorByAdjustment(positionAdjust) { + var position = odtDocument.getCursorPosition(inputMemberId), stepCounter = odtDocument.getCursor(inputMemberId).getStepCounter(); + if(positionAdjust !== 0) { + positionAdjust = positionAdjust > 0 ? stepCounter.convertForwardStepsBetweenFilters(positionAdjust, keyboardMovementsFilter, baseFilter) : -stepCounter.convertBackwardStepsBetweenFilters(-positionAdjust, keyboardMovementsFilter, baseFilter); + position = position + positionAdjust; + session.enqueue(createOpMoveCursor(position, 0)) } - newPos = selection.position + posAdjust; - newLen = lenAdjust !== 0 ? selection.length + lenAdjust : 0; - return createOpMoveCursor(newPos, newLen) } function moveCursorToLeft() { - sessionEnqueue(createOpMoveCursorByAdjustment(-1, 0)); + moveCursorByAdjustment(-1); return true } function moveCursorToRight() { - sessionEnqueue(createOpMoveCursorByAdjustment(1, 0)); + moveCursorByAdjustment(1); return true } function extendSelectionToLeft() { - sessionEnqueue(createOpMoveCursorByAdjustment(0, -1)); + extendCursorByAdjustment(-1); return true } function extendSelectionToRight() { - sessionEnqueue(createOpMoveCursorByAdjustment(0, 1)); + extendCursorByAdjustment(1); return true } - function createOpMoveCursorDirection(direction, extend) { - var paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), steps, op; + function moveCursorByLine(direction, extend) { + var paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), steps; runtime.assert(Boolean(paragraphNode), "SessionController: Cursor outside paragraph"); - steps = odtDocument.getCursor(inputMemberId).getStepCounter().countLinesSteps(direction, odtDocument.getPositionFilter()); - return extend ? createOpMoveCursorByAdjustment(0, steps) : createOpMoveCursorByAdjustment(steps, 0) + steps = odtDocument.getCursor(inputMemberId).getStepCounter().countLinesSteps(direction, keyboardMovementsFilter); + if(extend) { + extendCursorByAdjustment(steps) + }else { + moveCursorByAdjustment(steps) + } } function moveCursorUp() { - sessionEnqueue(createOpMoveCursorDirection(-1, false)); + moveCursorByLine(-1, false); return true } function moveCursorDown() { - sessionEnqueue(createOpMoveCursorDirection(1, false)); + moveCursorByLine(1, false); return true } function extendSelectionUp() { - sessionEnqueue(createOpMoveCursorDirection(-1, true)); + moveCursorByLine(-1, true); return true } function extendSelectionDown() { - sessionEnqueue(createOpMoveCursorDirection(1, true)); + moveCursorByLine(1, true); return true } - function createOpMoveCursorLineBoundary(direction, extend) { - var steps = odtDocument.getCursor(inputMemberId).getStepCounter().countStepsToLineBoundary(direction, odtDocument.getPositionFilter()); - return extend ? createOpMoveCursorByAdjustment(0, steps) : createOpMoveCursorByAdjustment(steps, 0) + function moveCursorToLineBoundary(direction, extend) { + var steps = odtDocument.getCursor(inputMemberId).getStepCounter().countStepsToLineBoundary(direction, keyboardMovementsFilter); + if(extend) { + extendCursorByAdjustment(steps) + }else { + moveCursorByAdjustment(steps) + } } function moveCursorToLineStart() { - sessionEnqueue(createOpMoveCursorLineBoundary(-1, false)); + moveCursorToLineBoundary(-1, false); return true } function moveCursorToLineEnd() { - sessionEnqueue(createOpMoveCursorLineBoundary(1, false)); + moveCursorToLineBoundary(1, false); return true } function extendSelectionToLineStart() { - sessionEnqueue(createOpMoveCursorLineBoundary(-1, true)); + moveCursorToLineBoundary(-1, true); return true } function extendSelectionToLineEnd() { - sessionEnqueue(createOpMoveCursorLineBoundary(1, true)); + moveCursorToLineBoundary(1, true); return true } function extendSelectionToParagraphStart() { @@ -11726,7 +12426,7 @@ gui.SessionController = function() { steps = odtDocument.getDistanceFromCursor(inputMemberId, node, 0) } } - sessionEnqueue(createOpMoveCursorByAdjustment(0, steps)); + extendCursorByAdjustment(steps); return true } function extendSelectionToParagraphEnd() { @@ -11742,31 +12442,43 @@ gui.SessionController = function() { steps = odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()) } } - sessionEnqueue(createOpMoveCursorByAdjustment(0, steps)); + extendCursorByAdjustment(steps); return true } - function createOpMoveCursorDocument(direction, extend) { + function moveCursorToDocumentBoundary(direction, extend) { var iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), steps; if(direction > 0) { iterator.moveToEnd() } steps = odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()); - return extend ? createOpMoveCursorByAdjustment(0, steps) : createOpMoveCursorByAdjustment(steps, 0) + if(extend) { + extendCursorByAdjustment(steps) + }else { + moveCursorByAdjustment(steps) + } } function moveCursorToDocumentStart() { - sessionEnqueue(createOpMoveCursorDocument(-1, false)); + moveCursorToDocumentBoundary(-1, false); return true } function moveCursorToDocumentEnd() { - sessionEnqueue(createOpMoveCursorDocument(1, false)); + moveCursorToDocumentBoundary(1, false); return true } function extendSelectionToDocumentStart() { - sessionEnqueue(createOpMoveCursorDocument(-1, true)); + moveCursorToDocumentBoundary(-1, true); return true } function extendSelectionToDocumentEnd() { - sessionEnqueue(createOpMoveCursorDocument(1, true)); + moveCursorToDocumentBoundary(1, true); + return true + } + function extendSelectionToEntireDocument() { + var iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), steps; + steps = -odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()); + iterator.moveToEnd(); + steps += odtDocument.getDistanceFromCursor(inputMemberId, iterator.container(), iterator.unfilteredDomOffset()); + session.enqueue(createOpMoveCursor(0, steps)); return true } function toForwardSelection(selection) { @@ -11786,12 +12498,13 @@ gui.SessionController = function() { if(selection.length === 0) { if(selection.position > 0 && odtDocument.getPositionInTextNode(selection.position - 1)) { op = new ops.OpRemoveText; - op.init({memberid:inputMemberId, position:selection.position - 1, length:1}) + op.init({memberid:inputMemberId, position:selection.position - 1, length:1}); + session.enqueue(op) } }else { - op = createOpRemoveSelection(selection) + op = createOpRemoveSelection(selection); + session.enqueue(op) } - sessionEnqueue(op); return true } function removeTextByDeleteKey() { @@ -11799,16 +12512,34 @@ gui.SessionController = function() { if(selection.length === 0) { if(odtDocument.getPositionInTextNode(selection.position + 1)) { op = new ops.OpRemoveText; - op.init({memberid:inputMemberId, position:selection.position, length:1}) + op.init({memberid:inputMemberId, position:selection.position, length:1}); + session.enqueue(op) } }else { - op = createOpRemoveSelection(selection) + op = createOpRemoveSelection(selection); + session.enqueue(op) } - sessionEnqueue(op); return op !== null } + function removeTextByClearKey() { + var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)); + if(selection.length !== 0) { + session.enqueue(createOpRemoveSelection(selection)) + } + return true + } + function insertText(text) { + var selection = toForwardSelection(odtDocument.getCursorSelection(inputMemberId)), op = null; + if(selection.length > 0) { + op = createOpRemoveSelection(selection); + session.enqueue(op) + } + op = new ops.OpInsertText; + op.init({memberid:inputMemberId, position:selection.position, text:text}); + session.enqueue(op) + } function enqueueParagraphSplittingOps() { - var position = odtDocument.getCursorPosition(inputMemberId), isAtEndOfParagraph = false, paragraphNode, styleName, nextStyleName, op; + var position = odtDocument.getCursorPosition(inputMemberId), op; op = new ops.OpSplitParagraph; op.init({memberid:inputMemberId, position:position}); session.enqueue(op); @@ -11816,8 +12547,10 @@ gui.SessionController = function() { } function maintainCursorSelection() { var cursor = odtDocument.getCursor(inputMemberId), selection = runtime.getWindow().getSelection(); - selection.removeAllRanges(); - selection.addRange(cursor.getSelectedRange().cloneRange()) + if(cursor) { + selection.removeAllRanges(); + selection.addRange(cursor.getSelectedRange().cloneRange()) + } } function stringFromKeyPress(event) { if(event.which === null) { @@ -11844,10 +12577,19 @@ gui.SessionController = function() { } function handleBeforeCut() { var cursor = odtDocument.getCursor(inputMemberId), selectedRange = cursor.getSelectedRange(); - return!(selectedRange.collapsed === false) + return selectedRange.collapsed !== false + } + function handleCopy(e) { + var cursor = odtDocument.getCursor(inputMemberId), selectedRange = cursor.getSelectedRange(); + if(selectedRange.collapsed) { + return + } + if(!clipboard.setDataFromRange(e, cursor.getSelectedRange())) { + runtime.log("Cut operation failed") + } } function handlePaste(e) { - var plainText, op; + var plainText, window = runtime.getWindow(); if(window.clipboardData && window.clipboardData.getData) { plainText = window.clipboardData.getData("Text") }else { @@ -11856,9 +12598,7 @@ gui.SessionController = function() { } } if(plainText) { - op = new ops.OpInsertText; - op.init({memberid:inputMemberId, position:odtDocument.getCursorPosition(inputMemberId), text:plainText}); - session.enqueue(op); + insertText(plainText); cancelEvent(e) } } @@ -11889,6 +12629,27 @@ gui.SessionController = function() { } return false } + 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 toggleBold() { + var range = odtDocument.getCursor(inputMemberId).getSelectedRange(), value = styleHelper.isBold(range) ? "normal" : "bold"; + formatTextSelection("fo:font-weight", value); + return true + } + function toggleItalic() { + var range = odtDocument.getCursor(inputMemberId).getSelectedRange(), value = styleHelper.isItalic(range) ? "normal" : "italic"; + formatTextSelection("fo:font-style", value); + return true + } + function toggleUnderline() { + var range = odtDocument.getCursor(inputMemberId).getSelectedRange(), value = styleHelper.hasUnderline(range) ? "none" : "solid"; + formatTextSelection("style:text-underline-style", value); + return true + } this.startEditing = function() { var canvasElement, op; canvasElement = odtDocument.getOdfCanvas().getElement(); @@ -11896,10 +12657,12 @@ gui.SessionController = function() { listenEvent(canvasElement, "keypress", keyPressHandler.handleEvent); listenEvent(canvasElement, "keyup", dummyHandler); listenEvent(canvasElement, "beforecut", handleBeforeCut, true); - listenEvent(canvasElement, "mouseup", clickHandler.handleMouseUp); listenEvent(canvasElement, "cut", handleCut); + listenEvent(canvasElement, "copy", handleCopy); listenEvent(canvasElement, "beforepaste", handleBeforePaste, true); listenEvent(canvasElement, "paste", handlePaste); + listenEvent(canvasElement, "mouseup", clickHandler.handleMouseUp); + listenEvent(canvasElement, "contextmenu", handleContextMenu); odtDocument.subscribe(ops.OdtDocument.signalOperationExecuted, maintainCursorSelection); odtDocument.subscribe(ops.OdtDocument.signalOperationExecuted, updateUndoStack); op = new ops.OpAddCursor; @@ -11919,9 +12682,11 @@ gui.SessionController = function() { removeEvent(canvasElement, "keyup", dummyHandler); removeEvent(canvasElement, "cut", handleCut); removeEvent(canvasElement, "beforecut", handleBeforeCut); + removeEvent(canvasElement, "copy", handleCopy); removeEvent(canvasElement, "paste", handlePaste); - removeEvent(canvasElement, "mouseup", clickHandler.handleMouseUp); removeEvent(canvasElement, "beforepaste", handleBeforePaste); + removeEvent(canvasElement, "mouseup", clickHandler.handleMouseUp); + removeEvent(canvasElement, "contextmenu", handleContextMenu); op = new ops.OpRemoveCursor; op.init({memberid:inputMemberId}); session.enqueue(op); @@ -11953,6 +12718,10 @@ gui.SessionController = function() { }; function init() { var isMacOS = runtime.getWindow().navigator.appVersion.toLowerCase().indexOf("mac") !== -1, modifier = gui.KeyboardHandler.Modifier, keyCode = gui.KeyboardHandler.KeyCode; + keyDownHandler.bind(keyCode.Tab, modifier.None, function() { + 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); @@ -11974,6 +12743,7 @@ gui.SessionController = function() { keyDownHandler.bind(keyCode.Home, modifier.CtrlShift, extendSelectionToDocumentStart); keyDownHandler.bind(keyCode.End, modifier.CtrlShift, extendSelectionToDocumentEnd); if(isMacOS) { + keyDownHandler.bind(keyCode.Clear, modifier.None, removeTextByClearKey); keyDownHandler.bind(keyCode.Left, modifier.Meta, moveCursorToLineStart); keyDownHandler.bind(keyCode.Right, modifier.Meta, moveCursorToLineEnd); keyDownHandler.bind(keyCode.Home, modifier.Meta, moveCursorToDocumentStart); @@ -11984,20 +12754,30 @@ gui.SessionController = function() { 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.B, modifier.Meta, toggleBold); + keyDownHandler.bind(keyCode.I, modifier.Meta, toggleItalic); + keyDownHandler.bind(keyCode.U, modifier.Meta, toggleUnderline); 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.B, modifier.Ctrl, toggleBold); + keyDownHandler.bind(keyCode.I, modifier.Ctrl, toggleItalic); + keyDownHandler.bind(keyCode.U, modifier.Ctrl, toggleUnderline); keyDownHandler.bind(keyCode.Z, modifier.Ctrl, undo); keyDownHandler.bind(keyCode.Z, modifier.CtrlShift, redo) } keyPressHandler.setDefault(function(e) { - var text = stringFromKeyPress(e), op = new ops.OpInsertText; - op.init({memberid:inputMemberId, position:odtDocument.getCursorPosition(inputMemberId), text:text}); - session.enqueue(op); - return true + var text = stringFromKeyPress(e); + if(text && !(e.altKey || e.ctrlKey || e.metaKey)) { + insertText(text); + return true + } + return false }); keyPressHandler.bind(keyCode.Enter, modifier.None, enqueueParagraphSplittingOps); - clickHandler.subscribe(gui.ClickHandler.signalSingleClick, select); + clickHandler.subscribe(gui.ClickHandler.signalSingleClick, selectRange); clickHandler.subscribe(gui.ClickHandler.signalDoubleClick, selectWord); clickHandler.subscribe(gui.ClickHandler.signalTripleClick, selectParagraph) } @@ -12073,7 +12853,8 @@ ops.NowjsUserModel = function NowjsUserModel(server) { } } this.getUserDetailsAndUpdates = function(memberId, subscriber) { - var userId = userIdFromMemberId(memberId), userData = cachedUserData[userId], subscribers = memberDataSubscribers[userId] = memberDataSubscribers[userId] || [], i; + var userId = userIdFromMemberId(memberId), userData = cachedUserData[userId], subscribers = memberDataSubscribers[userId] || [], i; + memberDataSubscribers[userId] = subscribers; runtime.assert(subscriber !== undefined, "missing callback"); for(i = 0;i < subscribers.length;i += 1) { if(subscribers[i].subscriber === subscriber && subscribers[i].memberId === memberId) { @@ -12218,7 +12999,8 @@ ops.PullBoxUserModel = function PullBoxUserModel(server) { serverPullingActivated = false } this.getUserDetailsAndUpdates = function(memberId, subscriber) { - var userId = userIdFromMemberId(memberId), userData = cachedUserData[userId], subscribers = memberDataSubscribers[userId] = memberDataSubscribers[userId] || [], i; + var userId = userIdFromMemberId(memberId), userData = cachedUserData[userId], subscribers = memberDataSubscribers[userId] || [], i; + memberDataSubscribers[userId] = subscribers; runtime.assert(subscriber !== undefined, "missing callback"); for(i = 0;i < subscribers.length;i += 1) { if(subscribers[i].subscriber === subscriber && subscribers[i].memberId === memberId) { @@ -12337,7 +13119,7 @@ ops.OperationRouter.prototype.push = function(op) { @source: http://gitorious.org/webodf/webodf/ */ ops.TrivialOperationRouter = function TrivialOperationRouter() { - var self = this, operationFactory, playbackFunction; + var operationFactory, playbackFunction; this.setOperationFactory = function(f) { operationFactory = f }; @@ -12352,7 +13134,7 @@ ops.TrivialOperationRouter = function TrivialOperationRouter() { } }; ops.NowjsOperationRouter = function NowjsOperationRouter(sessionId, memberid, server) { - var self = this, operationFactory, playbackFunction, nowObject = server.getNowObject(), last_server_seq = -1, reorder_queue = {}, sends_since_server_op = 0, router_sequence = 1E3; + var operationFactory, playbackFunction, nowObject = server.getNowObject(), last_server_seq = -1, reorder_queue = {}, sends_since_server_op = 0, router_sequence = 1E3; function nextNonce() { runtime.assert(memberid !== null, "Router sequence N/A without memberid"); router_sequence += 1; @@ -12462,7 +13244,7 @@ ops.NowjsOperationRouter = function NowjsOperationRouter(sessionId, memberid, se */ runtime.loadClass("ops.OperationTransformer"); ops.PullBoxOperationRouter = function PullBoxOperationRouter(sessionId, memberId, server) { - var self = this, operationFactory, singleTimeCallbackOnCompleteServerOpSpecsPlay, playbackFunction, pullingTimeOutFlag = null, triggerPushingOpsActivated = false, playUnplayedServerOpSpecsTriggered = false, syncLock = false, hasUnresolvableConflict = false, lastServerSeq = "", unsyncedClientOpspecQueue = [], unplayedServerOpspecQueue = [], operationTransformer = new ops.OperationTransformer, replayTime = 500, pushingIntervall = 3E3, pullingIntervall = 8E3; + var operationFactory, singleTimeCallbackOnCompleteServerOpSpecsPlay, playbackFunction, pullingTimeOutFlag = null, triggerPushingOpsActivated = false, playUnplayedServerOpSpecsTriggered = false, syncLock = false, hasUnresolvableConflict = false, lastServerSeq = "", unsyncedClientOpspecQueue = [], unplayedServerOpspecQueue = [], operationTransformer = new ops.OperationTransformer, replayTime = 500, pushingIntervall = 3E3, pullingIntervall = 8E3; function compressOpSpecs(opspecs) { var i, j, op, result = []; i = 0; @@ -12553,15 +13335,20 @@ ops.PullBoxOperationRouter = function PullBoxOperationRouter(sessionId, memberId }, pullingIntervall) } function doSyncOps() { - var base64 = server.getBase64(), syncedClientOpspecs; + var syncedClientOpspecs; if(syncLock || hasUnresolvableConflict) { return } syncLock = true; syncedClientOpspecs = unsyncedClientOpspecQueue; unsyncedClientOpspecQueue = []; - server.call("sync-ops:" + base64.toBase64(server.getToken()) + ":" + base64.toBase64(sessionId) + ":" + base64.toBase64(memberId) + ":" + base64.toBase64(String(lastServerSeq)) + ":" + runtime.toJson(syncedClientOpspecs), function(responseData) { - var shouldRetryInstantly = false, response = (runtime.fromJson(responseData)); + server.call({command:"sync-ops", sec_token:server.getToken(), es_id:sessionId, member_id:memberId, seq_head:String(lastServerSeq), client_ops:syncedClientOpspecs}, function(responseData) { + var shouldRetryInstantly = false, response; + try { + response = (runtime.fromJson(responseData)) + }catch(ex) { + runtime.assert(response !== undefined, "invalid sync-ops reply: [" + responseData + "]") + } runtime.log("sync-ops reply: " + responseData); if(response.result === "newOps") { if(response.ops.length > 0) { @@ -12649,9 +13436,8 @@ ops.PullBoxOperationRouter = function PullBoxOperationRouter(sessionId, memberId triggerPushingOps() }; function init() { - var base64 = server.getBase64(), - token = server.getToken(); - runtime.assert(token, "invalid token"); + var base64 = server.getBase64(), token = server.getToken(); + runtime.assert(token, "invalid token"); server.call("join-session:" + base64.toBase64(token) + ":" + base64.toBase64(sessionId) + ":" + base64.toBase64(memberId), function(responseData) { var response = Boolean(runtime.fromJson(responseData)); runtime.log("join-session reply: " + responseData); @@ -12707,12 +13493,12 @@ 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 window.setTimeout(function() { + return runtime.getWindow().setTimeout(function() { marker.style.opacity = opacity }, delay) } function deleteDecay(timer) { - window.clearTimeout(timer) + runtime.getWindow().clearTimeout(timer) } function setLastAuthor(memberid) { marker.setAttributeNS(editinfons, "editinfo:memberid", memberid) @@ -12824,19 +13610,23 @@ runtime.loadClass("gui.Caret"); runtime.loadClass("ops.TrivialUserModel"); runtime.loadClass("ops.EditInfo"); runtime.loadClass("gui.EditInfoMarker"); -gui.SessionViewOptions; +gui.SessionViewOptions = function() { + this.editInfoMarkersInitiallyVisible = true; + this.caretAvatarsInitiallyVisible = true; + this.caretBlinksOnRangeSelect = true +}; gui.SessionView = function() { function configOption(userValue, defaultValue) { return userValue !== undefined ? userValue : defaultValue } - function SessionView(viewOptions, session, caretFactory) { - var carets = {}, avatarInfoStyles, editInfons = "urn:webodf:names:editinfo", editInfoMap = {}, showEditInfoMarkers = configOption(viewOptions.editInfoMarkersInitiallyVisible, true), showCaretAvatars = configOption(viewOptions.caretAvatarsInitiallyVisible, true); - function createAvatarInfoNodeMatch(nodeName, className, memberId) { + 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 createAvatarInfoNodeMatch(nodeName, memberId, pseudoClass) { var userId = memberId.split("___")[0]; - return nodeName + "." + className + '[editinfo|memberid^="' + userId + '"]' + return nodeName + '[editinfo|memberid^="' + userId + '"]' + pseudoClass } - function getAvatarInfoStyle(nodeName, className, memberId) { - var node = avatarInfoStyles.firstChild, nodeMatch = createAvatarInfoNodeMatch(nodeName, className, memberId); + function getAvatarInfoStyle(nodeName, memberId, pseudoClass) { + var node = avatarInfoStyles.firstChild, nodeMatch = createAvatarInfoNodeMatch(nodeName, memberId, pseudoClass); while(node) { if(node.nodeType === Node.TEXT_NODE && node.data.indexOf(nodeMatch) === 0) { return node @@ -12846,23 +13636,19 @@ gui.SessionView = function() { return null } function setAvatarInfoStyle(memberId, name, color) { - function setStyle(nodeName, className, rule) { - var styleRule = createAvatarInfoNodeMatch(nodeName, className, memberId) + rule, styleNode = getAvatarInfoStyle(nodeName, className, memberId); + function setStyle(nodeName, rule, pseudoClass) { + var styleRule = createAvatarInfoNodeMatch(nodeName, memberId, pseudoClass) + rule, styleNode = getAvatarInfoStyle(nodeName, memberId, pseudoClass); if(styleNode) { styleNode.data = styleRule }else { avatarInfoStyles.appendChild(document.createTextNode(styleRule)) } } - setStyle("div", "editInfoMarker", "{ background-color: " + color + "; }"); - setStyle("span", "editInfoColor", "{ background-color: " + color + "; }"); - setStyle("span", "editInfoAuthor", ':before { content: "' + name + '"; }') - } - function removeAvatarInfoStyle(nodeName, className, memberId) { - var styleNode = getAvatarInfoStyle(nodeName, className, memberId); - if(styleNode) { - avatarInfoStyles.removeChild(styleNode) - } + setStyle("div.editInfoMarker", "{ background-color: " + color + "; }", ""); + setStyle("span.editInfoColor", "{ background-color: " + color + "; }", ""); + setStyle("span.editInfoAuthor", '{ content: "' + name + '"; }', ":before"); + setStyle("dc|creator", '{ content: "' + name + '"; display: none;}', ":before"); + setStyle("dc|creator", "{ background-color: " + color + "; }", "") } function highlightEdit(element, memberId, timestamp) { var editInfo, editInfoMarker, id = "", editInfoNode = element.getElementsByTagNameNS(editInfons, "editinfo")[0]; @@ -12893,17 +13679,13 @@ gui.SessionView = function() { } } function setCaretAvatarVisibility(visible) { - var caret, keyname; - for(keyname in carets) { - if(carets.hasOwnProperty(keyname)) { - caret = carets[keyname]; - if(visible) { - caret.showHandle() - }else { - caret.hideHandle() - } + caretManager.getCarets().forEach(function(caret) { + if(visible) { + caret.showHandle() + }else { + caret.hideHandle() } - } + }) } this.showEditInfoMarkers = function() { if(showEditInfoMarkers) { @@ -12937,10 +13719,10 @@ gui.SessionView = function() { return session }; this.getCaret = function(memberid) { - return carets[memberid] + return caretManager.getCaret(memberid) }; function renderMemberData(memberId, userData) { - var caret = carets[memberId]; + var caret = caretManager.getCaret(memberId); if(userData === undefined) { runtime.log('UserModel sent undefined data for member "' + memberId + '".'); return @@ -12955,15 +13737,14 @@ gui.SessionView = function() { setAvatarInfoStyle(memberId, userData.fullname, userData.color) } function onCursorAdded(cursor) { - var caret = caretFactory.createCaret(cursor, showCaretAvatars), memberId = cursor.getMemberId(), userModel = session.getUserModel(); - carets[memberId] = caret; + var memberId = cursor.getMemberId(), userModel = session.getUserModel(); + caretManager.registerCursor(cursor, showCaretAvatars, blinkOnRangeSelect); renderMemberData(memberId, null); userModel.getUserDetailsAndUpdates(memberId, renderMemberData); runtime.log("+++ View here +++ eagerly created an Caret for '" + memberId + "'! +++") } function onCursorRemoved(memberid) { var hasMemberEditInfo = false, keyname; - delete carets[memberid]; for(keyname in editInfoMap) { if(editInfoMap.hasOwnProperty(keyname) && editInfoMap[keyname].getEditInfo().getEdits().hasOwnProperty(memberid)) { hasMemberEditInfo = true; @@ -12985,6 +13766,7 @@ gui.SessionView = function() { avatarInfoStyles.type = "text/css"; avatarInfoStyles.media = "screen, print, handheld, projection"; avatarInfoStyles.appendChild(document.createTextNode("@namespace editinfo url(urn:webodf:names:editinfo);")); + avatarInfoStyles.appendChild(document.createTextNode("@namespace dc url(http://purl.org/dc/elements/1.1/);")); head.appendChild(avatarInfoStyles) } init() @@ -13026,29 +13808,74 @@ gui.SessionView = function() { @source: http://gitorious.org/webodf/webodf/ */ runtime.loadClass("gui.Caret"); -gui.CaretFactory = function CaretFactory(sessionController) { - this.createCaret = function(cursor, caretAvatarInitiallyVisible) { - var memberid = cursor.getMemberId(), session = sessionController.getSession(), odtDocument = session.getOdtDocument(), canvasElement = odtDocument.getOdfCanvas().getElement(), caret = new gui.Caret(cursor, caretAvatarInitiallyVisible); +gui.CaretManager = function CaretManager(sessionController) { + var carets = {}; + function getCanvasElement() { + return sessionController.getSession().getOdtDocument().getOdfCanvas().getElement() + } + function removeCaret(memberId) { + if(memberId === sessionController.getInputMemberId()) { + getCanvasElement().removeAttribute("tabindex", 0) + } + delete carets[memberId] + } + function refreshCaret(cursor) { + var caret = carets[cursor.getMemberId()]; + if(caret) { + caret.refreshCursor() + } + } + function ensureLocalCaretVisible(info) { + var caret = carets[info.memberId]; + if(info.memberId === sessionController.getInputMemberId() && caret) { + caret.ensureVisible() + } + } + function focusLocalCaret() { + var caret = carets[sessionController.getInputMemberId()]; + if(caret) { + caret.setFocus() + } + } + function blurLocalCaret() { + var caret = carets[sessionController.getInputMemberId()]; + if(caret) { + caret.removeFocus() + } + } + this.registerCursor = function(cursor, caretAvatarInitiallyVisible, blinkOnRangeSelect) { + var memberid = cursor.getMemberId(), canvasElement = getCanvasElement(), caret = new gui.Caret(cursor, caretAvatarInitiallyVisible, blinkOnRangeSelect); + carets[memberid] = caret; if(memberid === sessionController.getInputMemberId()) { runtime.log("Starting to track input on new cursor of " + memberid); - odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, function(info) { - if(info.memberId === memberid) { - caret.ensureVisible() - } - }); cursor.handleUpdate = caret.ensureVisible; canvasElement.setAttribute("tabindex", 0); - canvasElement.onfocus = caret.setFocus; - canvasElement.onblur = caret.removeFocus; canvasElement.focus() } return caret + }; + this.getCaret = function(memberid) { + return carets[memberid] + }; + this.getCarets = function() { + return Object.keys(carets).map(function(memberid) { + return carets[memberid] + }) + }; + function init() { + var session = sessionController.getSession(), odtDocument = session.getOdtDocument(), canvasElement = getCanvasElement(); + odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, ensureLocalCaretVisible); + odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, refreshCaret); + odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, removeCaret); + canvasElement.onfocus = focusLocalCaret; + canvasElement.onblur = blurLocalCaret } + init() }; runtime.loadClass("xmldom.XPath"); runtime.loadClass("odf.Namespaces"); gui.PresenterUI = function() { - var xpath = new xmldom.XPath; + var xpath = new xmldom.XPath, window = runtime.getWindow(); return function PresenterUI(odf_element) { var self = this; self.setInitialSlideMode = function() { @@ -13109,7 +13936,7 @@ gui.PresenterUI = function() { self.slideChange = function(indexChanger) { var pages = self.getPages(self.odf_canvas.odfContainer().rootElement), last = -1, i = 0, newidx, pagelist; pages.forEach(function(tuple) { - var name = tuple[0], node = tuple[1]; + var node = tuple[1]; if(node.hasAttribute("slide_current")) { last = i; node.removeAttribute("slide_current") @@ -13222,13 +14049,11 @@ gui.PresenterUI = function() { runtime.loadClass("core.PositionIterator"); runtime.loadClass("core.Cursor"); gui.XMLEdit = function XMLEdit(element, stylesheet) { - var simplecss, cssprefix, documentElement, customNS = "customns", walker = null; + var simplecss, cssprefix, documentElement, walker = null; if(!element.id) { element.id = "xml" + String(Math.random()).substring(2) } cssprefix = "#" + element.id + " "; - function installHandlers() { - } 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) { @@ -13299,16 +14124,12 @@ gui.XMLEdit = function XMLEdit(element, stylesheet) { } cancelEvent(event) } - function handleKeyPress(event) { - } function handleClick(event) { - var sel = element.ownerDocument.defaultView.getSelection(), r = sel.getRangeAt(0), n = r.startContainer; cancelEvent(event) } function initElement(element) { listenEvent(element, "click", handleClick); listenEvent(element, "keydown", handleKeyDown); - listenEvent(element, "keypress", handleKeyPress); listenEvent(element, "drop", cancelEvent); listenEvent(element, "dragend", cancelEvent); listenEvent(element, "beforepaste", cancelEvent); @@ -13381,7 +14202,7 @@ gui.XMLEdit = function XMLEdit(element, stylesheet) { } } function createCssFromXmlInstance(node) { - var prefixes = {}, css = "@namespace customns url(customns);\n", name, pre, ns, names, csssel; + var prefixes = {}, css = "@namespace customns url(customns);\n"; getNamespacePrefixes(node, prefixes); generateUniquePrefixes(prefixes); return css @@ -13603,10 +14424,11 @@ gui.UndoStateRules = function UndoStateRules() { @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ +runtime.loadClass("core.DomUtils"); runtime.loadClass("gui.UndoManager"); runtime.loadClass("gui.UndoStateRules"); gui.TrivialUndoManager = function TrivialUndoManager(defaultRules) { - var self = this, initialDoc, initialState, playFunc, odtDocument, currentUndoState = [], undoStates = [], redoStates = [], eventNotifier = new core.EventNotifier([gui.UndoManager.signalUndoStackChanged, gui.UndoManager.signalUndoStateCreated, gui.UndoManager.signalUndoStateModified, gui.TrivialUndoManager.signalDocumentRootReplaced]), undoRules = defaultRules || new gui.UndoStateRules; + var self = this, cursorns = "urn:webodf:names:cursor", domUtils = new core.DomUtils, initialDoc, initialState = [], playFunc, odtDocument, currentUndoState = [], undoStates = [], redoStates = [], eventNotifier = new core.EventNotifier([gui.UndoManager.signalUndoStackChanged, gui.UndoManager.signalUndoStateCreated, gui.UndoManager.signalUndoStateModified, gui.TrivialUndoManager.signalDocumentRootReplaced]), undoRules = defaultRules || new gui.UndoStateRules; function emitStackChange() { eventNotifier.emit(gui.UndoManager.signalUndoStackChanged, {undoAvailable:self.hasUndoStates(), redoAvailable:self.hasRedoStates()}) } @@ -13618,6 +14440,53 @@ gui.TrivialUndoManager = function TrivialUndoManager(defaultRules) { undoStates.push(currentUndoState) } } + function removeNode(node) { + var sibling = node.previousSibling || node.nextSibling; + node.parentNode.removeChild(node); + domUtils.normalizeTextNodes(sibling) + } + function removeCursors(root) { + domUtils.getElementsByTagNameNS(root, cursorns, "cursor").forEach(removeNode); + domUtils.getElementsByTagNameNS(root, cursorns, "anchor").forEach(removeNode) + } + function values(obj) { + return Object.keys(obj).map(function(key) { + return obj[key] + }) + } + function extractCursorStates(undoStates) { + var addCursor = {}, moveCursor = {}, requiredAddOps = {}, remainingAddOps, operations = undoStates.pop(); + odtDocument.getCursors().forEach(function(cursor) { + requiredAddOps[cursor.getMemberId()] = true + }); + remainingAddOps = Object.keys(requiredAddOps).length; + function processOp(op) { + var spec = op.spec(); + if(!requiredAddOps[spec.memberid]) { + return + } + switch(spec.optype) { + case "AddCursor": + if(!addCursor[spec.memberid]) { + addCursor[spec.memberid] = op; + delete requiredAddOps[spec.memberid]; + remainingAddOps -= 1 + } + break; + case "MoveCursor": + if(!moveCursor[spec.memberid]) { + moveCursor[spec.memberid] = op + } + break + } + } + while(operations && remainingAddOps > 0) { + operations.reverse(); + operations.forEach(processOp); + operations = undoStates.pop() + } + return values(addCursor).concat(values(moveCursor)) + } this.subscribe = function(signal, callback) { eventNotifier.subscribe(signal, callback) }; @@ -13642,14 +14511,16 @@ gui.TrivialUndoManager = function TrivialUndoManager(defaultRules) { emitStackChange() }; this.saveInitialState = function() { - var odfContainer = odtDocument.getOdfCanvas().odfContainer(); + var odfContainer = odtDocument.getOdfCanvas().odfContainer(), annotationManager = odtDocument.getOdfCanvas().getAnnotationManager(); + if(annotationManager) { + annotationManager.forgetAnnotations() + } initialDoc = odfContainer.rootElement.cloneNode(true); - initialState = []; + odtDocument.getOdfCanvas().refreshAnnotations(); + removeCursors(initialDoc); completeCurrentUndoState(); - undoStates.forEach(function(state) { - initialState = initialState.concat(state) - }); - currentUndoState = initialState; + undoStates.unshift(initialState); + currentUndoState = initialState = extractCursorStates(undoStates); undoStates.length = 0; redoStates.length = 0; emitStackChange() @@ -13750,49 +14621,72 @@ gui.TrivialUndoManager.signalDocumentRootReplaced = "documentRootReplaced"; */ runtime.loadClass("core.EventNotifier"); runtime.loadClass("odf.OdfUtils"); +runtime.loadClass("gui.SelectionMover"); +runtime.loadClass("gui.StyleHelper"); +runtime.loadClass("core.PositionFilterChain"); ops.OdtDocument = function OdtDocument(odfCanvas) { - var self = this, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", drawns = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0", filter, odfUtils, cursors = {}, eventNotifier = new core.EventNotifier([ops.OdtDocument.signalCursorAdded, ops.OdtDocument.signalCursorRemoved, ops.OdtDocument.signalCursorMoved, ops.OdtDocument.signalParagraphChanged, ops.OdtDocument.signalParagraphStyleModified, ops.OdtDocument.signalStyleCreated, ops.OdtDocument.signalStyleDeleted, ops.OdtDocument.signalTableAdded, - ops.OdtDocument.signalOperationExecuted, ops.OdtDocument.signalUndoStackChanged]); + var self = this, textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0", odfUtils, cursors = {}, eventNotifier = new core.EventNotifier([ops.OdtDocument.signalCursorAdded, ops.OdtDocument.signalCursorRemoved, ops.OdtDocument.signalCursorMoved, ops.OdtDocument.signalParagraphChanged, ops.OdtDocument.signalParagraphStyleModified, ops.OdtDocument.signalStyleCreated, ops.OdtDocument.signalStyleDeleted, ops.OdtDocument.signalTableAdded, ops.OdtDocument.signalOperationExecuted, ops.OdtDocument.signalUndoStackChanged]), + FILTER_ACCEPT = core.PositionFilter.FilterResult.FILTER_ACCEPT, FILTER_REJECT = core.PositionFilter.FilterResult.FILTER_REJECT, filter; function getRootNode() { var element = odfCanvas.odfContainer().getContentElement(), localName = element && element.localName; runtime.assert(localName === "text", "Unsupported content element type '" + localName + "'for OdtDocument"); return element } + function RootFilter(memberId) { + function isRoot(node) { + if(node.namespaceURI === odf.Namespaces.officens && node.localName === "text" || node.namespaceURI === odf.Namespaces.officens && node.localName === "annotation") { + return true + } + return false + } + function getRoot(node) { + while(!isRoot(node)) { + node = (node.parentNode) + } + return node + } + this.acceptPosition = function(iterator) { + var node = iterator.container(), cursorNode = cursors[memberId].getNode(); + if(getRoot(node) === getRoot(cursorNode)) { + return FILTER_ACCEPT + } + return FILTER_REJECT + } + } function TextPositionFilter() { - var accept = core.PositionFilter.FilterResult.FILTER_ACCEPT, reject = core.PositionFilter.FilterResult.FILTER_REJECT; function checkLeftRight(container, leftNode, rightNode) { var r, firstPos, rightOfChar; if(leftNode) { r = odfUtils.lookLeftForCharacter(leftNode); if(r === 1) { - return accept + return FILTER_ACCEPT } if(r === 2 && (odfUtils.scanRightForAnyCharacter(rightNode) || odfUtils.scanRightForAnyCharacter(odfUtils.nextNode(container)))) { - return accept + return FILTER_ACCEPT } } firstPos = leftNode === null && odfUtils.isParagraph(container); rightOfChar = odfUtils.lookRightForCharacter(rightNode); if(firstPos) { if(rightOfChar) { - return accept + return FILTER_ACCEPT } - return odfUtils.scanRightForAnyCharacter(rightNode) ? reject : accept + return odfUtils.scanRightForAnyCharacter(rightNode) ? FILTER_REJECT : FILTER_ACCEPT } if(!rightOfChar) { - return reject + return FILTER_REJECT } leftNode = leftNode || odfUtils.previousNode(container); - return odfUtils.scanLeftForAnyCharacter(leftNode) ? reject : accept + return odfUtils.scanLeftForAnyCharacter(leftNode) ? FILTER_REJECT : FILTER_ACCEPT } this.acceptPosition = function(iterator) { - var container = iterator.container(), nodeType = container.nodeType, localName, offset, text, leftChar, rightChar, leftNode, rightNode, r; + var container = iterator.container(), nodeType = container.nodeType, offset, text, leftChar, rightChar, leftNode, rightNode, r; if(nodeType !== Node.ELEMENT_NODE && nodeType !== Node.TEXT_NODE) { - return reject + return FILTER_REJECT } if(nodeType === Node.TEXT_NODE) { - if(!odfUtils.isGroupingElement(container.parentNode)) { - return reject + if(!odfUtils.isGroupingElement(container.parentNode) || odfUtils.isWithinTrackedChanges(container.parentNode, getRootNode())) { + return FILTER_REJECT } offset = iterator.unfilteredDomOffset(); text = container.data; @@ -13800,39 +14694,39 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { if(offset > 0) { leftChar = text.substr(offset - 1, 1); if(!odfUtils.isODFWhitespace(leftChar)) { - return accept + return FILTER_ACCEPT } if(offset > 1) { leftChar = text.substr(offset - 2, 1); if(!odfUtils.isODFWhitespace(leftChar)) { - r = accept + r = FILTER_ACCEPT }else { if(!odfUtils.isODFWhitespace(text.substr(0, offset))) { - return reject + return FILTER_REJECT } } }else { leftNode = odfUtils.previousNode(container); if(odfUtils.scanLeftForNonWhitespace(leftNode)) { - r = accept + r = FILTER_ACCEPT } } - if(r === accept) { - return odfUtils.isTrailingWhitespace(container, offset) ? reject : accept + if(r === FILTER_ACCEPT) { + return odfUtils.isTrailingWhitespace(container, offset) ? FILTER_REJECT : FILTER_ACCEPT } rightChar = text.substr(offset, 1); if(odfUtils.isODFWhitespace(rightChar)) { - return reject + return FILTER_REJECT } - return odfUtils.scanLeftForAnyCharacter(odfUtils.previousNode(container)) ? reject : accept + return odfUtils.scanLeftForAnyCharacter(odfUtils.previousNode(container)) ? FILTER_REJECT : FILTER_ACCEPT } leftNode = iterator.leftNode(); rightNode = container; container = (container.parentNode); r = checkLeftRight(container, leftNode, rightNode) }else { - if(!odfUtils.isGroupingElement(container)) { - r = reject + if(!odfUtils.isGroupingElement(container) || odfUtils.isWithinTrackedChanges(container, getRootNode())) { + r = FILTER_REJECT }else { leftNode = iterator.leftNode(); rightNode = iterator.rightNode(); @@ -13853,43 +14747,8 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { return iterator } this.getIteratorAtPosition = getIteratorAtPosition; - this.getTextNeighborhood = function(position, length) { - var iterator = getIteratorAtPosition(position), neighborhood = [], currentNeighborhood = [], currentNode, iteratedLength = 0, visited = false, inFirstNeighborhood = true, neighborhoodStartIndex = 0, segmentStartIndex, i, j; - runtime.assert(length >= 0, "OdtDocument.getTextNeighborhood only supports positive lengths"); - do { - currentNeighborhood = iterator.textNeighborhood(); - visited = false; - for(i = 0;i < neighborhood.length;i += 1) { - if(neighborhood[i] === currentNeighborhood[0]) { - visited = true; - break - } - } - if(!visited) { - segmentStartIndex = 0; - if(inFirstNeighborhood) { - currentNode = iterator.container(); - for(j = 0;j < currentNeighborhood.length;j += 1) { - if(currentNeighborhood[j] === currentNode) { - neighborhoodStartIndex = j; - break - } - } - segmentStartIndex = neighborhoodStartIndex; - inFirstNeighborhood = false - } - if(currentNeighborhood.length) { - neighborhood = neighborhood.concat(currentNeighborhood) - } - for(j = segmentStartIndex;j < currentNeighborhood.length;j += 1) { - iteratedLength += currentNeighborhood[j].data.length - } - } - }while(iterator.nextPosition() === true && iteratedLength < length); - return neighborhood.slice(neighborhoodStartIndex) - }; function getPositionInTextNode(position, memberid) { - var iterator = gui.SelectionMover.createPositionIterator(getRootNode()), lastTextNode = null, lastNode = null, node, nodeOffset = 0, cursorNode = null; + var iterator = gui.SelectionMover.createPositionIterator(getRootNode()), lastTextNode = null, node, nodeOffset = 0, cursorNode = null; runtime.assert(position >= 0, "position must be >= 0"); if(filter.acceptPosition(iterator) === 1) { node = iterator.container(); @@ -13984,19 +14843,22 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { var space = textNode.ownerDocument.createElementNS(textns, "text:s"); space.appendChild(textNode.ownerDocument.createTextNode(" ")); textNode.deleteData(offset, 1); - textNode.splitText(offset); - textNode.parentNode.insertBefore(space, textNode.nextSibling) + if(offset > 0) { + textNode = (textNode.splitText(offset)) + } + textNode.parentNode.insertBefore(space, textNode); + return space } - this.upgradeWhitespaceToElement = upgradeWhitespaceToElement; function upgradeWhitespacesAtPosition(position) { - var iterator = getIteratorAtPosition(position), container = null, offset, i = 0; + var iterator = getIteratorAtPosition(position), container, offset, i; iterator.previousPosition(); iterator.previousPosition(); - for(i = -2;i <= 2;i += 1) { + 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)) { - upgradeWhitespaceToElement(container, offset) + container = upgradeWhitespaceToElement((container), offset); + iterator.moveToEndOfNode(container) } iterator.nextPosition() } @@ -14006,36 +14868,21 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { this.getParagraphElement = getParagraphElement; this.getParagraphStyleAttributes = getParagraphStyleAttributes; this.getPositionInTextNode = getPositionInTextNode; - this.getNeighboringParagraph = function(paragraph, direction) { - var iterator = getIteratorAtPosition(0), currentParagraph = null; - iterator.setUnfilteredPosition(paragraph, 0); - do { - if(filter.acceptPosition(iterator) === 1) { - currentParagraph = getParagraphElement(iterator.container()); - if(currentParagraph !== paragraph) { - return currentParagraph - } - } - }while((direction > 0 ? iterator.nextPosition() : iterator.previousPosition()) === true); - if(currentParagraph === paragraph) { - return null - } - }; this.fixCursorPositions = function(localMemberId) { - var cursors, stepCounter, steps, filter, i; - cursors = self.getCursors(); - filter = self.getPositionFilter(); - for(i in cursors) { - if(cursors.hasOwnProperty(i)) { - stepCounter = cursors[i].getStepCounter(); - if(!stepCounter.isPositionWalkable(filter)) { - steps = -stepCounter.countBackwardSteps(1, filter); - if(steps === 0) { - steps = stepCounter.countForwardSteps(1, filter) + var posfilter = self.getPositionFilter(), memberId, cursor, stepCounter, steps; + for(memberId in cursors) { + if(cursors.hasOwnProperty(memberId)) { + cursor = cursors[memberId]; + stepCounter = cursor.getStepCounter(); + if(!stepCounter.isPositionWalkable(posfilter)) { + steps = stepCounter.countStepsToValidPosition(posfilter); + cursor.move(steps); + if(memberId === localMemberId) { + self.emit(ops.OdtDocument.signalCursorMoved, cursor) } - cursors[i].move(steps); - if(i === localMemberId) { - self.emit(ops.OdtDocument.signalCursorMoved, cursors[i]) + }else { + if(self.getCursorSelection(memberId).length === 0) { + cursor.move(0) } } } @@ -14101,6 +14948,7 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { 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"); + runtime.assert(!cursors[memberid], "OdtDocument::addCursor is adding a duplicate cursor with memberid " + memberid); cursor.move(distanceToFirstTextNode); cursors[memberid] = cursor }; @@ -14132,6 +14980,12 @@ 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) }; @@ -14141,6 +14995,9 @@ ops.OdtDocument = function OdtDocument(odfCanvas) { this.unsubscribe = function(eventid, cb) { eventNotifier.unsubscribe(eventid, cb) }; + this.createRootFilter = function(inputMemberId) { + return new RootFilter(inputMemberId) + }; function init() { filter = new TextPositionFilter; odfUtils = new odf.OdfUtils @@ -14234,5 +15091,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\noffice|document > *, office|document-content > * {\n display: none;\n}\noffice|body, office|document {\n display: inline-block;\n position: relative;\n}\n\ntext|p, text|h {\n display: block;\n padding: 0;\n margin: 0;\n line-height: normal;\n position: relative;\n min-height: 1.3em; /* prevent empty paragraphs and headings from collapsing if they are empty */\n}\n*[runtimens|containsparagraphanchor] {\n position: relative;\n}\ntext|s {\n white-space: pre;\n}\ntext|tab {\n display: inline;\n white-space: pre;\n}\ntext|line-break {\n content: \" \";\n display: block;\n}\ntext|tracked-changes {\n /*Consumers that do not support change tracking, should ignore changes.*/\n display: none;\n}\noffice|binary-data {\n display: none;\n}\noffice|text {\n display: block;\n text-align: left;\n overflow: visible;\n word-wrap: break-word;\n}\n\noffice|text::selection {\n /** Let's not draw selection highlight that overflows into the office|text\n * node when selecting content across several paragraphs\n */\n background: transparent;\n}\n\noffice|spreadsheet {\n display: block;\n border-collapse: collapse;\n empty-cells: show;\n font-family: sans-serif;\n font-size: 10pt;\n text-align: left;\n page-break-inside: avoid;\n overflow: hidden;\n}\noffice|presentation {\n display: inline-block;\n text-align: left;\n}\n#shadowContent {\n display: inline-block;\n text-align: left;\n}\ndraw|page {\n display: block;\n position: relative;\n overflow: hidden;\n}\npresentation|notes, presentation|footer-decl, presentation|date-time-decl {\n display: none;\n}\n@media print {\n draw|page {\n border: 1pt solid black;\n page-break-inside: avoid;\n }\n presentation|notes {\n /*TODO*/\n }\n}\noffice|spreadsheet text|p {\n border: 0px;\n padding: 1px;\n margin: 0px;\n}\noffice|spreadsheet table|table {\n margin: 3px;\n}\noffice|spreadsheet table|table:after {\n /* show sheet name the end of the sheet */\n /*content: attr(table|name);*/ /* gives parsing error in opera */\n}\noffice|spreadsheet table|table-row {\n counter-increment: row;\n}\noffice|spreadsheet table|table-row:before {\n width: 3em;\n background: #cccccc;\n border: 1px solid black;\n text-align: center;\n content: counter(row);\n display: table-cell;\n}\noffice|spreadsheet table|table-cell {\n border: 1px solid #cccccc;\n}\ntable|table {\n display: table;\n}\ndraw|frame table|table {\n width: 100%;\n height: 100%;\n background: white;\n}\ntable|table-header-rows {\n display: table-header-group;\n}\ntable|table-row {\n display: table-row;\n}\ntable|table-column {\n display: table-column;\n}\ntable|table-cell {\n width: 0.889in;\n display: table-cell;\n word-break: break-all; /* prevent long words from extending out the table cell */\n}\ndraw|frame {\n display: block;\n}\ndraw|image {\n display: block;\n width: 100%;\n height: 100%;\n top: 0px;\n left: 0px;\n background-repeat: no-repeat;\n background-size: 100% 100%;\n -moz-background-size: 100% 100%;\n}\n/* only show the first image in frame */\ndraw|frame > draw|image:nth-of-type(n+2) {\n display: none;\n}\ntext|list:before {\n display: none;\n content:\"\";\n}\ntext|list {\n counter-reset: list;\n}\ntext|list-item {\n display: block;\n}\ntext|number {\n display:none;\n}\n\ntext|a {\n color: blue;\n text-decoration: underline;\n cursor: pointer;\n}\ntext|note-citation {\n vertical-align: super;\n font-size: smaller;\n}\ntext|note-body {\n display: none;\n}\ntext|note:hover text|note-citation {\n background: #dddddd;\n}\ntext|note:hover text|note-body {\n display: block;\n left:1em;\n max-width: 80%;\n position: absolute;\n background: #ffffaa;\n}\nsvg|title, svg|desc {\n display: none;\n}\nvideo {\n width: 100%;\n height: 100%\n}\n\n/* below set up the cursor */\ncursor|cursor {\n display: inline;\n width: 0px;\n height: 1em;\n /* making the position relative enables the avatar to use\n the cursor as reference for its absolute position */\n position: relative;\n}\ncursor|cursor > span {\n display: inline;\n position: absolute;\n height: 1em;\n border-left: 2px solid black;\n outline: none;\n}\n\ncursor|cursor > div {\n padding: 3px;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n border: none !important;\n border-radius: 5px;\n opacity: 0.3;\n}\n\ncursor|cursor > div > img {\n border-radius: 5px;\n}\n\ncursor|cursor > div.active {\n opacity: 0.8;\n}\n\ncursor|cursor > div:after {\n content: ' ';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 43%;\n}\n\n\n.editInfoMarker {\n position: absolute;\n width: 10px;\n height: 100%;\n left: -20px;\n opacity: 0.8;\n top: 0;\n border-radius: 5px;\n background-color: transparent;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n}\n.editInfoMarker:hover {\n box-shadow: 0px 0px 8px rgba(0, 0, 0, 1);\n}\n\n.editInfoHandle {\n position: absolute;\n background-color: black;\n padding: 5px;\n border-radius: 5px;\n opacity: 0.8;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n bottom: 100%;\n margin-bottom: 10px;\n z-index: 3;\n left: -25px;\n}\n.editInfoHandle:after {\n content: ' ';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 5px;\n}\n.editInfo {\n font-family: sans-serif;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n color: white;\n width: 100%;\n height: 12pt;\n}\n.editInfoColor {\n float: left;\n width: 10pt;\n height: 10pt;\n border: 1px solid white;\n}\n.editInfoAuthor {\n float: left;\n margin-left: 5pt;\n font-size: 10pt;\n text-align: left;\n height: 12pt;\n line-height: 12pt;\n}\n.editInfoTime {\n float: right;\n margin-left: 30pt;\n font-size: 8pt;\n font-style: italic;\n color: yellow;\n height: 12pt;\n line-height: 12pt;\n}\n"; +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}\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.annotationNote {\n width: 4cm;\n position: absolute;\n display: inline;\n z-index: 10;\n}\n.annotationNote > office|annotation {\n display: block;\n}\n\n.annotationConnector {\n position: absolute;\n display: inline;\n z-index: 10;\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: inline-block;\n position: absolute;\n outline: 1px solid #ccc;\n}\n\n.annotationHighlight {\n background-color: yellow;\n position: relative;\n}\n"; diff --git a/js/webodf.js b/js/webodf.js index f55c57b0..223b0a0d 100644 --- a/js/webodf.js +++ b/js/webodf.js @@ -36,80 +36,79 @@ */ var core={},gui={},xmldom={},odf={},ops={}; // Input 1 -function Runtime(){}Runtime.ByteArray=function(h){};Runtime.prototype.getVariable=function(h){};Runtime.prototype.toJson=function(h){};Runtime.prototype.fromJson=function(h){};Runtime.ByteArray.prototype.slice=function(h,m){};Runtime.ByteArray.prototype.length=0;Runtime.prototype.byteArrayFromArray=function(h){};Runtime.prototype.byteArrayFromString=function(h,m){};Runtime.prototype.byteArrayToString=function(h,m){};Runtime.prototype.concatByteArrays=function(h,m){}; -Runtime.prototype.read=function(h,m,f,n){};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.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(e){var a="",g,d=e.length;for(g=0;gb?a+=String.fromCharCode(b):(g+=1,r=e[g],194<=b&&224>b?a+=String.fromCharCode((b&31)<<6|r&63):(g+=1,k=e[g],224<=b&&240>b?a+=String.fromCharCode((b&15)<<12|(r&63)<<6|k&63):(g+=1,l=e[g],240<=b&&245>b&&(b=(b&7)<<18|(r&63)<<12|(k&63)<<6|l&63,b-=65536,a+=String.fromCharCode((b>>10)+55296,(b&1023)+56320))))); -return a}var q;"utf8"===m?q=n(h):("binary"!==m&&this.log("Unsupported encoding: "+m),q=f(h));return q};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(e,a){var g,d,b;void 0!==a?b=e:a=e;h?(d=h.ownerDocument,b&&(g=d.createElement("span"),g.className=b,g.appendChild(d.createTextNode(b)),h.appendChild(g),h.appendChild(d.createTextNode(" "))),g=d.createElement("span"),0r?(d[k]=r,k+=1):2048>r?(d[k]=192|r>>>6,d[k+1]=128|r&63,k+=2):(d[k]=224|r>>>12&15,d[k+1]=128|r>>>6&63,d[k+2]=128|r&63,k+=3)}else for("binary"!==a&&f.log("unknown encoding: "+a),g=e.length,d=new f.ByteArray(g),b=0;bd.status||0===d.status?g(null):g("Status "+String(d.status)+": "+d.responseText||d.statusText):g("File "+e+" is empty."))}; -a=a.buffer&&!d.sendAsBinary?a.buffer:f.byteArrayToString(a,"binary");try{d.sendAsBinary?d.sendAsBinary(a):d.send(a)}catch(b){f.log("HUH? "+b+" "+a),g(b.message)}};this.deleteFile=function(e,a){delete n[e];var g=new XMLHttpRequest;g.open("DELETE",e,!0);g.onreadystatechange=function(){4===g.readyState&&(200>g.status&&300<=g.status?a(g.responseText):a(null))};g.send(null)};this.loadXML=function(e,a){var g=new XMLHttpRequest;g.open("GET",e,!0);g.overrideMimeType&&g.overrideMimeType("text/xml");g.onreadystatechange= -function(){4===g.readyState&&(0!==g.status||g.responseText?200===g.status||0===g.status?a(null,g.responseXML):a(g.responseText):a("File "+e+" is empty."))};try{g.send(null)}catch(d){a(d.message)}};this.isFile=function(e,a){f.getFileSize(e,function(g){a(-1!==g)})};this.getFileSize=function(e,a){var g=new XMLHttpRequest;g.open("HEAD",e,!0);g.onreadystatechange=function(){if(4===g.readyState){var d=g.getResponseHeader("Content-Length");d?a(parseInt(d,10)):a(-1)}};g.send(null)};this.log=m;this.assert= -function(e,a,g){if(!e)throw m("alert","ASSERTION FAILED:\n"+a),g&&g(),a;};this.setTimeout=function(e,a){setTimeout(function(){e()},a)};this.libraryPaths=function(){return["lib"]};this.setCurrentDirectory=function(e){};this.type=function(){return"BrowserRuntime"};this.getDOMImplementation=function(){return window.document.implementation};this.parseXML=function(e){return(new DOMParser).parseFromString(e,"text/xml")};this.exit=function(e){m("Calling exit with code "+String(e)+", but exit() is not implemented.")}; -this.getWindow=function(){return window}} -function NodeJSRuntime(){function h(a,d,b){a=n.resolve(q,a);"binary"!==d?f.readFile(a,d,b):f.readFile(a,null,b)}var m=this,f=require("fs"),n=require("path"),q="",e,a;this.ByteArray=function(a){return new Buffer(a)};this.byteArrayFromArray=function(a){var d=new Buffer(a.length),b,r=a.length;for(b=0;b").implementation} -function RhinoRuntime(){function h(a,g){var d;void 0!==g?d=a:g=a;"alert"===d&&print("\n!!!!! ALERT !!!!!");print(g);"alert"===d&&print("!!!!! ALERT !!!!!")}var m=this,f=Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance(),n,q,e="";f.setValidating(!1);f.setNamespaceAware(!0);f.setExpandEntityReferences(!1);f.setSchema(null);q=Packages.org.xml.sax.EntityResolver({resolveEntity:function(a,g){var d=new Packages.java.io.FileReader(g);return new Packages.org.xml.sax.InputSource(d)}});n=f.newDocumentBuilder(); -n.setEntityResolver(q);this.ByteArray=function(a){return[a]};this.byteArrayFromArray=function(a){return a};this.byteArrayFromString=function(a,g){var d=[],b,e=a.length;for(b=0;bc?a+=String.fromCharCode(c):(f+=1,h=b[f],194<=c&&224>c?a+=String.fromCharCode((c&31)<<6|h&63):(f+=1,e=b[f],224<=c&&240>c?a+=String.fromCharCode((c&15)<<12|(h&63)<<6|e&63):(f+=1,r=b[f],240<=c&&245>c&&(c=(c&7)<<18|(h&63)<<12|(e&63)<<6|r&63,c-=65536,a+=String.fromCharCode((c>>10)+55296,(c&1023)+56320))))); +return a}var b;"utf8"===g?b=h(k):("binary"!==g&&this.log("Unsupported encoding: "+g),b=l(k));return b};Runtime.getVariable=function(k){try{return eval(k)}catch(g){}};Runtime.toJson=function(k){return JSON.stringify(k)};Runtime.fromJson=function(k){return JSON.parse(k)};Runtime.getFunctionName=function(k){return void 0===k.name?(k=/function\s+(\w+)/.exec(k))&&k[1]:k.name}; +function BrowserRuntime(k){function g(a,f){var d,c,b;void 0!==f?b=a:f=a;k?(c=k.ownerDocument,b&&(d=c.createElement("span"),d.className=b,d.appendChild(c.createTextNode(b)),k.appendChild(d),k.appendChild(c.createTextNode(" "))),d=c.createElement("span"),0e?(c[g]=e,g+=1):2048>e?(c[g]=192|e>>>6,c[g+1]=128|e&63,g+=2):(c[g]=224|e>>>12&15,c[g+1]=128|e>>>6&63,c[g+2]=128|e&63,g+=3)}else for("binary"!== +f&&h.log("unknown encoding: "+f),d=a.length,c=new h.ByteArray(d),b=0;bc.status||0===c.status?d(null):d("Status "+String(c.status)+": "+c.responseText|| +c.statusText):d("File "+a+" is empty."))};f=f.buffer&&!c.sendAsBinary?f.buffer:h.byteArrayToString(f,"binary");try{c.sendAsBinary?c.sendAsBinary(f):c.send(f)}catch(g){h.log("HUH? "+g+" "+f),d(g.message)}};this.deleteFile=function(a,f){delete b[a];var d=new XMLHttpRequest;d.open("DELETE",a,!0);d.onreadystatechange=function(){4===d.readyState&&(200>d.status&&300<=d.status?f(d.responseText):f(null))};d.send(null)};this.loadXML=function(a,f){var d=new XMLHttpRequest;d.open("GET",a,!0);d.overrideMimeType&& +d.overrideMimeType("text/xml");d.onreadystatechange=function(){4===d.readyState&&(0!==d.status||d.responseText?200===d.status||0===d.status?f(null,d.responseXML):f(d.responseText):f("File "+a+" is empty."))};try{d.send(null)}catch(c){f(c.message)}};this.isFile=function(a,f){h.getFileSize(a,function(a){f(-1!==a)})};this.getFileSize=function(a,f){var d=new XMLHttpRequest;d.open("HEAD",a,!0);d.onreadystatechange=function(){if(4===d.readyState){var c=d.getResponseHeader("Content-Length");c?f(parseInt(c, +10)):l(a,"binary",function(c,a){c?f(-1):f(a.length)})}};d.send(null)};this.log=g;this.assert=function(a,f,d){if(!a)throw g("alert","ASSERTION FAILED:\n"+f),d&&d(),f;};this.setTimeout=function(a,f){return setTimeout(function(){a()},f)};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){g("Calling exit with code "+String(a)+", but exit() is not implemented.")};this.getWindow=function(){return window}} +function NodeJSRuntime(){function k(a,d,c){a=h.resolve(b,a);"binary"!==d?l.readFile(a,d,c):l.readFile(a,null,c)}var g=this,l=require("fs"),h=require("path"),b="",n,a;this.ByteArray=function(a){return new Buffer(a)};this.byteArrayFromArray=function(a){var d=new Buffer(a.length),c,b=a.length;for(c=0;c").implementation} +function RhinoRuntime(){function k(a,f){var d;void 0!==f?d=a:f=a;"alert"===d&&print("\n!!!!! ALERT !!!!!");print(f);"alert"===d&&print("!!!!! ALERT !!!!!")}var g=this,l=Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance(),h,b,n="";l.setValidating(!1);l.setNamespaceAware(!0);l.setExpandEntityReferences(!1);l.setSchema(null);b=Packages.org.xml.sax.EntityResolver({resolveEntity:function(a,f){var d=new Packages.java.io.FileReader(f);return new Packages.org.xml.sax.InputSource(d)}});h=l.newDocumentBuilder(); +h.setEntityResolver(b);this.ByteArray=function(a){return[a]};this.byteArrayFromArray=function(a){return a};this.byteArrayFromString=function(a,f){var d=[],c,b=a.length;for(c=0;c>>18],c+=u[a>>>12&63],c+=u[a>>>6&63],c+=u[a&63];k===p+1?(a=b[k]<<4,c+=u[a>>>6],c+=u[a&63],c+="=="):k===p&&(a=b[k]<<10|b[k+1]<<2,c+=u[a>>>12],c+=u[a>>>6&63],c+=u[a&63],c+="=");return c}function f(b){b=b.replace(/[^A-Za-z0-9+\/]+/g,"");var a=[],c=b.length%4,k,p=b.length,d;for(k=0;k>16,d>>8&255,d&255);a.length-=[0,0,2,1][c];return a}function n(b){var a=[],c,k=b.length,p;for(c=0;cp?a.push(p):2048>p?a.push(192|p>>>6,128|p&63):a.push(224|p>>>12&15,128|p>>>6&63,128|p&63);return a}function q(b){var a=[],c,k=b.length,p,d,l;for(c=0;cp?a.push(p):(c+=1,d=b[c],224>p?a.push((p&31)<<6|d&63):(c+=1,l=b[c],a.push((p&15)<<12|(d&63)<<6|l&63)));return a}function e(b){return m(h(b))} -function a(b){return String.fromCharCode.apply(String,f(b))}function g(b){return q(h(b))}function d(b){b=q(b);for(var a="",c=0;ca?k+=String.fromCharCode(a):(l+=1,p=b.charCodeAt(l)&255,224>a?k+=String.fromCharCode((a&31)<<6|p&63):(l+=1,d=b.charCodeAt(l)&255,k+=String.fromCharCode((a&15)<<12|(p&63)<<6|d&63)));return k}function r(a,c){function k(){var e= -l+p;e>a.length&&(e=a.length);d+=b(a,l,e);l=e;e=l===a.length;c(d,e)&&!e&&runtime.setTimeout(k,0)}var p=1E5,d="",l=0;a.lengtha;a+=1)b.push(65+a);for(a=0;26>a;a+=1)b.push(97+a);for(a= -0;10>a;a+=1)b.push(48+a);b.push(43);b.push(47);return b})();var t=function(b){var a={},c,k;c=0;for(k=b.length;c>>18],e+=q[c>>>12&63],e+=q[c>>>6&63],e+=q[c&63];d===b+1?(c=a[d]<<4,e+=q[c>>>6],e+=q[c&63],e+="=="):d===b&&(c=a[d]<<10|a[d+1]<<2,e+=q[c>>>12],e+=q[c>>>6&63],e+=q[c&63],e+="=");return e}function l(a){a=a.replace(/[^A-Za-z0-9+\/]+/g,"");var c=[],e=a.length%4,d,b=a.length,f;for(d=0;d>16,f>>8&255,f&255);c.length-=[0,0,2,1][e];return c}function h(a){var c=[],e,d=a.length,b;for(e=0;eb?c.push(b):2048>b?c.push(192|b>>>6,128|b&63):c.push(224|b>>>12&15,128|b>>>6&63,128|b&63);return c}function b(a){var c=[],e,d=a.length,b,f,m;for(e=0;eb?c.push(b):(e+=1,f=a[e],224>b?c.push((b&31)<<6|f&63):(e+=1,m=a[e],c.push((b&15)<<12|(f&63)<<6|m&63)));return c}function n(a){return g(k(a))} +function a(a){return String.fromCharCode.apply(String,l(a))}function f(a){return b(k(a))}function d(a){a=b(a);for(var c="",e=0;ec?d+=String.fromCharCode(c):(m+=1,b=a.charCodeAt(m)&255,224>c?d+=String.fromCharCode((c&31)<<6|b&63):(m+=1,f=a.charCodeAt(m)&255,d+=String.fromCharCode((c&15)<<12|(b&63)<<6|f&63)));return d}function t(a,e){function d(){var p= +m+b;p>a.length&&(p=a.length);f+=c(a,m,p);m=p;p=m===a.length;e(f,p)&&!p&&runtime.setTimeout(d,0)}var b=1E5,f="",m=0;a.length>>8):(oa(a&255),oa(a>>>8))},qa=function(){v=(v<<5^c[z+3-1]&255)&8191;x=s[32768+v];s[z&32767]=x;s[32768+v]=z},da=function(b,a){C>16-a?(p|=b<>16-C,C+=a-16):(p|=b<b;b++)c[b]=c[b+32768];H-=32768;z-=32768;y-=32768;for(b=0;8192>b;b++)a=s[32768+b],s[32768+b]=32768<=a?a-32768:0;for(b=0;32768>b;b++)a=s[b],s[b]=32768<=a?a-32768:0;k+=32768}D||(b=Aa(c,z+G,k),0>=b?D=!0:G+=b)},Ba=function(b){var a=T,k=z,p,d=O,l=32506=ca&&(a>>=2);do if(p=b,c[p+d]===g&&c[p+d-1]===t&&c[p]===c[k]&&c[++p]===c[k+1]){k+= -2;p++;do++k;while(c[k]===c[++p]&&c[++k]===c[++p]&&c[++k]===c[++p]&&c[++k]===c[++p]&&c[++k]===c[++p]&&c[++k]===c[++p]&&c[++k]===c[++p]&&c[++k]===c[++p]&&kd){H=b;d=p;if(258<=p)break;t=c[k+d-1];g=c[k+d]}}while((b=s[b&32767])>l&&0!==--a);return d},la=function(b,a){t[Z++]=a;0===b?U[a].fc++:(b--,U[w[a]+256+1].fc++,W[(256>b?aa[b]:aa[256+(b>>7)])&255].fc++,u[X++]=b,ha|=ja);ja<<=1;0===(Z&7)&&(L[sa++]=ha,ha=0,ja=1);if(2p;p++)c+=W[p].fc* -(5+ka[p]);c>>=3;if(X>=1,c<<=1;while(0<--a);return c>>1},Da=function(b,a){var c=[];c.length=16;var k=0,p;for(p=1;15>=p;p++)k=k+P[p-1]<<1,c[p]=k;for(k=0;k<=a;k++)p=b[k].dl,0!==p&&(b[k].fc=Ca(c[p]++,p))},xa=function(b){var a=b.dyn_tree,c=b.static_tree,k=b.elems,p,d=-1, -l=k;Y=0;E=573;for(p=0;pY;)p=Q[++Y]=2>d?++d:0,a[p].fc=1,$[p]=0,ea--,null!==c&&(ia-=c[p].dl);b.max_code=d;for(p=Y>>1;1<=p;p--)wa(a,p);do p=Q[1],Q[1]=Q[Y--],wa(a,1),c=Q[1],Q[--E]=p,Q[--E]=c,a[l].fc=a[p].fc+a[c].fc,$[l]=$[p]>$[c]+1?$[p]:$[c]+1,a[p].dl=a[c].dl=l,Q[1]=l++,wa(a,1);while(2<=Y);Q[--E]=Q[1];l=b.dyn_tree;p=b.extra_bits;var k=b.extra_base,c=b.max_code,e=b.max_length,t=b.static_tree,g,s,f,r,u=0;for(s=0;15>=s;s++)P[s]=0;l[Q[E]].dl=0;for(b= -E+1;573>b;b++)g=Q[b],s=l[l[g].dl].dl+1,s>e&&(s=e,u++),l[g].dl=s,g>c||(P[s]++,f=0,g>=k&&(f=p[g-k]),r=l[g].fc,ea+=r*(s+f),null!==t&&(ia+=r*(t[g].dl+f)));if(0!==u){do{for(s=e-1;0===P[s];)s--;P[s]--;P[s+1]+=2;P[e]--;u-=2}while(0c||(l[p].dl!==s&&(ea+=(s-l[p].dl)*l[p].fc,l[p].fc=s),g--)}Da(a,d)},Ea=function(b,a){var c,k=-1,p,l=b[0].dl,d=0,e=7,s=4;0===l&&(e=138,s=3);b[a+1].dl=65535;for(c=0;c<=a;c++)p=l,l=b[c+1].dl,++d=d?R[17].fc++:R[18].fc++,d=0,k=p,0===l?(e=138,s=3):p===l?(e=6,s=3):(e=7,s=4))},Fa=function(){8c?aa[c]:aa[256+(c>>7)])&255,fa(e,a),s=ka[e],0!==s&&(c-=K[e],da(c,s))),d>>=1;while(k=l?(fa(17,R),da(l-3,3)):(fa(18,R),da(l-11,7));l=0;k=p;0===d?(e=138,s=3):p===d?(e=6,s=3):(e=7,s=4)}},Ia=function(){var b;for(b=0;286>b;b++)U[b].fc=0;for(b=0;30>b;b++)W[b].fc=0;for(b=0;19>b;b++)R[b].fc=0;U[256].fc=1;ha=Z=X=sa=ea=ia=0;ja=1},ra=function(b){var a,p,k,l;l=z-y;L[sa]=ha;xa(I);xa(B);Ea(U,I.max_code);Ea(W,B.max_code);xa(J);for(k=18;3<=k&&0===R[ya[k]].dl;k--); -ea+=3*(k+1)+14;a=ea+3+7>>3;p=ia+3+7>>3;p<=a&&(a=p);if(l+4<=a&&0<=y)for(da(0+b,3),Fa(),pa(l),pa(~l),k=0;ka.len&&(s=a.len);for(t=0;tr-k&&(s=r-k);for(t=0;tu;u++)for(ga[u]= -f,g=0;g<1<u;u++)for(K[u]=f,g=0;g<1<>=7;30>u;u++)for(K[u]=f<<7,g=0;g<1<=g;g++)P[g]=0;for(g=0;143>=g;)M[g++].dl=8,P[8]++;for(;255>=g;)M[g++].dl=9,P[9]++;for(;279>=g;)M[g++].dl=7,P[7]++;for(;287>=g;)M[g++].dl=8,P[8]++;Da(M,287);for(g=0;30>g;g++)S[g].dl=5,S[g].fc=Ca(g,5);Ia()}for(g=0;8192>g;g++)s[32768+g]=0;ba=na[V].max_lazy;ca=na[V].good_length;T=na[V].max_chain;y=z=0;G=Aa(c,0,65536);if(0>=G)D= -!0,G=0;else{for(D=!1;262>G&&!D;)va();for(g=v=0;2>g;g++)v=(v<<5^c[g]&255)&8191}a=null;k=r=0;3>=V?(O=2,F=0):(F=2,A=0);l=!1}d=!0;if(0===G)return l=!0,0}if((g=Ja(b,e,t))===t)return t;if(l)return g;if(3>=V)for(;0!==G&&null===a;){qa();0!==x&&32506>=z-x&&(F=Ba(x),F>G&&(F=G));if(3<=F)if(u=la(z-H,F-3),G-=F,F<=ba){F--;do z++,qa();while(0!==--F);z++}else z+=F,F=0,v=c[z]&255,v=(v<<5^c[z+1]&255)&8191;else u=la(0,c[z]&255),G--,z++;u&&(ra(0),y=z);for(;262>G&&!D;)va()}else for(;0!==G&&null===a;){qa();O=F;N=H;F=2; -0!==x&&(O=z-x)&&(F=Ba(x),F>G&&(F=G),3===F&&4096G&&!D;)va()}0===G&&(0!==A&&la(0,c[z-1]&255),ra(1),l=!0);return g+Ja(b,g+e,t-g)};this.deflate=function(k,p){var l,f;ma=k;ta=0;"undefined"===String(typeof p)&&(p=6);(l=p)?1>l?l=1:9l;l++)U[l]=new h;W=[];W.length=61;for(l=0;61>l;l++)W[l]=new h;M=[];M.length=288;for(l=0;288>l;l++)M[l]=new h;S=[];S.length=30;for(l=0;30>l;l++)S[l]=new h;R=[];R.length=39;for(l=0;39>l;l++)R[l]=new h;I=new m;B=new m;J=new m;P=[];P.length=16;Q=[];Q.length=573;$=[];$.length=573;w=[];w.length=256;aa=[];aa.length=512;ga=[];ga.length=29;K=[];K.length=30;L=[];L.length=1024}for(var r=Array(1024),n=[];0<(l=La(r,0,r.length));){var v= -[];v.length=l;for(f=0;f>>8):(fa(a&255),fa(a>>>8))},aa=function(){p=(p<<5^m[C+3-1]&255)&8191;y=w[32768+p];w[C&32767]=y;w[32768+p]=C},ga=function(a,c){z>16-c?(u|=a<>16-z,z+=c-16):(u|=a<a;a++)m[a]=m[a+32768];P-=32768;C-=32768;v-=32768;for(a=0;8192>a;a++)c=w[32768+a],w[32768+a]=32768<=c?c-32768:0;for(a=0;32768>a;a++)c=w[a],w[a]=32768<=c?c-32768:0;e+=32768}B||(a=Ba(m,C+J,e),0>=a?B=!0:J+=a)},Ca=function(a){var c=U,e=C,d,b=N,f=32506=ka&&(c>>=2);do if(d=a,m[d+b]===h&&m[d+b-1]===g&&m[d]===m[e]&&m[++d]===m[e+1]){e+= +2;d++;do++e;while(m[e]===m[++d]&&m[++e]===m[++d]&&m[++e]===m[++d]&&m[++e]===m[++d]&&m[++e]===m[++d]&&m[++e]===m[++d]&&m[++e]===m[++d]&&m[++e]===m[++d]&&eb){P=a;b=d;if(258<=d)break;g=m[e+b-1];h=m[e+b]}a=w[a&32767]}while(a>f&&0!==--c);return b},va=function(a,c){s[Z++]=c;0===a?ca[c].fc++:(a--,ca[G[c]+256+1].fc++,W[(256>a?ea[a]:ea[256+(a>>7)])&255].fc++,q[X++]=a,qa|=x);x<<=1;0===(Z&7)&&(R[na++]=qa,qa=0,x=1);if(2b;b++)e+=W[b].fc* +(5+ra[b]);e>>=3;if(X>=1,e<<=1;while(0<--c);return e>>1},Ea=function(a,c){var e=[];e.length=16;var d=0,b;for(b=1;15>=b;b++)d=d+L[b-1]<<1,e[b]=d;for(d=0;d<=c;d++)b=a[d].dl,0!==b&&(a[d].fc=Da(e[b]++,b))},za=function(a){var c=a.dyn_tree,e=a.static_tree,d=a.elems,b,f=-1, +m=d;Y=0;la=573;for(b=0;bY;)b=K[++Y]=2>f?++f:0,c[b].fc=1,E[b]=0,ia--,null!==e&&(ma-=e[b].dl);a.max_code=f;for(b=Y>>1;1<=b;b--)ya(c,b);do b=K[1],K[1]=K[Y--],ya(c,1),e=K[1],K[--la]=b,K[--la]=e,c[m].fc=c[b].fc+c[e].fc,E[m]=E[b]>E[e]+1?E[b]:E[e]+1,c[b].dl=c[e].dl=m,K[1]=m++,ya(c,1);while(2<=Y);K[--la]=K[1];m=a.dyn_tree;b=a.extra_bits;var d=a.extra_base,e=a.max_code,p=a.max_length,g=a.static_tree,h,r,q,n,s=0;for(r=0;15>=r;r++)L[r]=0;m[K[la]].dl=0; +for(a=la+1;573>a;a++)h=K[a],r=m[m[h].dl].dl+1,r>p&&(r=p,s++),m[h].dl=r,h>e||(L[r]++,q=0,h>=d&&(q=b[h-d]),n=m[h].fc,ia+=n*(r+q),null!==g&&(ma+=n*(g[h].dl+q)));if(0!==s){do{for(r=p-1;0===L[r];)r--;L[r]--;L[r+1]+=2;L[p]--;s-=2}while(0e||(m[b].dl!==r&&(ia+=(r-m[b].dl)*m[b].fc,m[b].fc=r),h--)}Ea(c,f)},Fa=function(a,c){var e,d=-1,b,f=a[0].dl,m=0,p=7,g=4;0===f&&(p=138,g=3);a[c+1].dl=65535;for(e=0;e<=c;e++)b=f,f=a[e+1].dl,++m=m?S[17].fc++:S[18].fc++,m=0,d=b,0===f?(p=138,g=3):b===f?(p=6,g=3):(p=7,g=4))},Ga=function(){8e?ea[e]:ea[256+(e>>7)])&255,sa(p,c),g=ra[p],0!==g&&(e-=V[p],ga(e,g))),m>>=1;while(d=m?(sa(17,S),ga(m-3,3)):(sa(18,S),ga(m-11,7));m=0;d=b;0===f?(p=138,g=3):b===f?(p=6,g=3):(p=7,g=4)}},Ja=function(){var a;for(a=0;286>a;a++)ca[a].fc=0;for(a=0;30>a;a++)W[a].fc=0;for(a=0;19>a;a++)S[a].fc=0;ca[256].fc=1;qa=Z=X=na=ia=ma=0;x=1},wa=function(a){var c,e,d,b;b=C-v;R[na]=qa;za(Q);za(F);Fa(ca,Q.max_code);Fa(W,F.max_code);za(M);for(d=18;3<=d&&0=== +S[ua[d]].dl;d--);ia+=3*(d+1)+14;c=ia+3+7>>3;e=ma+3+7>>3;e<=c&&(c=e);if(b+4<=c&&0<=v)for(ga(0+a,3),Ga(),ja(b),ja(~b),d=0;da.len&&(p=a.len);for(g=0;gt-e&&(p=t-e);for(g=0;gq;q++)for(ha[q]=h,g=0;g<1<q;q++)for(V[q]=h,g=0;g<1<>=7;30>q;q++)for(V[q]=h<<7,g=0;g<1<=g;g++)L[g]=0;for(g=0;143>=g;)O[g++].dl=8,L[8]++;for(;255>=g;)O[g++].dl=9,L[9]++;for(;279>=g;)O[g++].dl=7,L[7]++;for(;287>=g;)O[g++].dl=8,L[8]++;Ea(O,287);for(g=0;30>g;g++)ba[g].dl=5,ba[g].fc=Da(g,5);Ja()}for(g=0;8192>g;g++)w[32768+g]=0;da=$[T].max_lazy;ka=$[T].good_length;U=$[T].max_chain;v=C=0;J=Ba(m, +0,65536);if(0>=J)B=!0,J=0;else{for(B=!1;262>J&&!B;)xa();for(g=p=0;2>g;g++)p=(p<<5^m[g]&255)&8191}a=null;e=t=0;3>=T?(N=2,A=0):(A=2,H=0);r=!1}d=!0;if(0===J)return r=!0,0}g=Ka(c,b,f);if(g===f)return f;if(r)return g;if(3>=T)for(;0!==J&&null===a;){aa();0!==y&&32506>=C-y&&(A=Ca(y),A>J&&(A=J));if(3<=A)if(q=va(C-P,A-3),J-=A,A<=da){A--;do C++,aa();while(0!==--A);C++}else C+=A,A=0,p=m[C]&255,p=(p<<5^m[C+1]&255)&8191;else q=va(0,m[C]&255),J--,C++;q&&(wa(0),v=C);for(;262>J&&!B;)xa()}else for(;0!==J&&null===a;){aa(); +N=A;D=P;A=2;0!==y&&(N=C-y)&&(A=Ca(y),A>J&&(A=J),3===A&&4096J&&!B;)xa()}0===J&&(0!==H&&va(0,m[C-1]&255),wa(1),r=!0);return g+Ka(c,g+b,f-g)};this.deflate=function(e,p){var h,r;oa=e;I=0;"undefined"===String(typeof p)&&(p=6);(h=p)?1>h?h=1:9h;h++)ca[h]=new k;W=[];W.length=61;for(h=0;61>h;h++)W[h]=new k;O=[];O.length=288;for(h=0;288>h;h++)O[h]=new k;ba=[];ba.length=30;for(h=0;30>h;h++)ba[h]=new k;S=[];S.length=39;for(h=0;39>h;h++)S[h]=new k;Q=new g;F=new g;M=new g;L=[];L.length=16;K=[];K.length=573;E=[];E.length=573;G=[];G.length=256;ea=[];ea.length=512;ha=[];ha.length=29;V=[];V.length=30;R=[];R.length=1024}var l=Array(1024),u=[],t=[];for(h=La(l, +0,l.length);0>8&255])};this.appendUInt32LE=function(f){m.appendArray([f&255,f>>8&255,f>>16&255,f>>24&255])};this.appendString=function(m){f=runtime.concatByteArrays(f, -runtime.byteArrayFromString(m,h))};this.getLength=function(){return f.length};this.getByteArray=function(){return f}}; +core.ByteArrayWriter=function(k){var g=this,l=new runtime.ByteArray(0);this.appendByteArrayWriter=function(g){l=runtime.concatByteArrays(l,g.getByteArray())};this.appendByteArray=function(g){l=runtime.concatByteArrays(l,g)};this.appendArray=function(g){l=runtime.concatByteArrays(l,runtime.byteArrayFromArray(g))};this.appendUInt16LE=function(h){g.appendArray([h&255,h>>8&255])};this.appendUInt32LE=function(h){g.appendArray([h&255,h>>8&255,h>>16&255,h>>24&255])};this.appendString=function(g){l=runtime.concatByteArrays(l, +runtime.byteArrayFromString(g,k))};this.getLength=function(){return l.length};this.getByteArray=function(){return l}}; // Input 6 -core.RawInflate=function(){var h,m,f=null,n,q,e,a,g,d,b,r,k,l,c,u,t,s,p=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],C=[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],y=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,99,99],v=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],x=[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],N=[16,17,18, -0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],A=function(){this.list=this.next=null},F=function(){this.n=this.b=this.e=0;this.t=null},O=function(b,a,c,p,k,l){this.BMAX=16;this.N_MAX=288;this.status=0;this.root=null;this.m=0;var d=Array(this.BMAX+1),e,s,g,t,f,u,r,m=Array(this.BMAX+1),q,n,h,v=new F,C=Array(this.BMAX);t=Array(this.N_MAX);var y,x=Array(this.BMAX+1),G,z,D;D=this.root=null;for(f=0;ff&&(l=f);for(G=1<(G-=d[u])){this.status=2;this.m=l;return}if(0>(G-=d[f]))this.status=2,this.m=l;else{d[f]+=G;x[1]=u=0;q=d;n=1;for(h=2;0<--f;)x[h++]=u+=q[n++];q=b;f=n=0;do 0!=(u=q[n++])&&(t[x[u]++]=f);while(++fy+m[1+t];){y+=m[1+t];t++;z=(z=g-y)>l?l:z;if((s=1<<(u=r-y))>b+1)for(s-=b+1,h=r;++ue&&y>y-m[t],C[t-1][u].e=v.e,C[t-1][u].b=v.b,C[t-1][u].n=v.n,C[t-1][u].t=v.t)}v.b=r-y;n>=a?v.e=99:q[n]q[n]?16:15,v.n=q[n++]): -(v.e=k[q[n]-c],v.n=p[q[n++]-c]);s=1<>y;u>=1)f^=u;for(f^=u;(f&(1<>=b;a-=b},G=function(a,p,d){var s,e,t;if(0==d)return 0;for(t=0;;){z(c);e=k.list[H(c)];for(s=e.e;16 -s;s++)q[N[s]]=0;c=7;s=new O(q,19,19,null,null,c);if(0!=s.status)return-1;k=s.root;c=s.m;t=f+r;for(d=e=0;ds)q[d++]=e=s;else if(16==s){z(2);s=3+H(2);D(2);if(d+s>t)return-1;for(;0t)return-1;for(;0B;B++)I[B]=8;for(;256>B;B++)I[B]=9;for(;280>B;B++)I[B]=7;for(;288>B;B++)I[B]=8;q=7;B=new O(I,288,257,C,y,q);if(0!=B.status){alert("HufBuild error: "+B.status);M=-1;break b}f=B.root;q=B.m;for(B=0;30>B;B++)I[B]=5;T=5;B=new O(I,30,0,v,x,T);if(1q&&(f=q);for(D=1<(D-=m[n])){this.status=2;this.m=f;return}if(0>(D-=m[q]))this.status=2,this.m=f;else{m[q]+=D;z[1]=n=0;u=m;k=1;for(w=2;0<--q;)z[w++]=n+=u[k++];u=a;q=k=0;do 0!=(n=u[k++])&&(r[z[n]++]=q);while(++qv+l[1+r];){v+=l[1+r];r++;C=(C=h-v)>f?f:C;if((p=1<<(n=s-v))>a+1)for(p-=a+1,w=s;++ng&&v>v-l[r],y[r-1][n].e=t.e,y[r-1][n].b=t.b,y[r-1][n].n=t.n,y[r-1][n].t=t.t)}t.b=s-v;k>=c?t.e=99:u[k]u[k]?16:15,t.n=u[k++]): +(t.e=b[u[k]-e],t.n=d[u[k++]-e]);p=1<>v;n>=1)q^=n;for(q^=n;(q&(1<>=c;a-=c},J=function(a,d,b){var p,h,n;if(0==b)return 0;for(n=0;;){C(m);h=e.list[P(m)];for(p=h.e;16 +f;f++)u[D[f]]=0;m=7;f=new N(u,19,19,null,null,m);if(0!=f.status)return-1;e=f.root;m=f.m;h=s+l;for(b=g=0;bf)u[b++]=g=f;else if(16==f){C(2);f=3+P(2);B(2);if(b+f>h)return-1;for(;0h)return-1;for(;0F;F++)Q[F]=8;for(;256>F;F++)Q[F]=9;for(;280>F;F++)Q[F]=7;for(;288>F;F++)Q[F]=8;b=7;F=new N(Q,288,257,z,v,b);if(0!=F.status){alert("HufBuild error: "+F.status);O=-1;break b}l=F.root;b=F.m;for(F=0;30>F;F++)Q[F]=5;U=5;F=new N(Q,30,0,p,y,U);if(1h))throw runtime.log("alert","watchdog timeout"),"timeout!";if(0m))throw runtime.log("alert","watchdog loop overflow"),"loop overflow";}}; +core.LoopWatchDog=function(k,g){var l=Date.now(),h=0;this.check=function(){var b;if(k&&(b=Date.now(),b-l>k))throw runtime.log("alert","watchdog timeout"),"timeout!";if(0g))throw runtime.log("alert","watchdog loop overflow"),"loop overflow";}}; // Input 8 -core.DomUtils=function(){function h(m,f){if(m.nodeType===Node.TEXT_NODE)if(0===m.length)m.parentNode.removeChild(m);else if(f.nodeType===Node.TEXT_NODE)return f.insertData(0,m.data),m.parentNode.removeChild(m),f;return m}this.splitBoundaries=function(m){var f=[],n;0!==m.endOffset&&(m.endContainer.nodeType===Node.TEXT_NODE&&m.endOffset!==m.endContainer.length)&&(f.push(m.endContainer.splitText(m.endOffset)),f.push(m.endContainer));0!==m.startOffset&&(m.startContainer.nodeType===Node.TEXT_NODE&&m.startOffset!== -m.startContainer.length)&&(n=m.startContainer.splitText(m.startOffset),f.push(m.startContainer),f.push(n),m.setStart(n,0));return f};this.normalizeTextNodes=function(m){m&&m.nextSibling&&(m=h(m,m.nextSibling));m&&m.previousSibling&&h(m.previousSibling,m)};this.rangeContainsNode=function(m,f){var n=f.ownerDocument.createRange(),q=f.nodeType===Node.TEXT_NODE?f.length:f.childNodes.length;n.setStart(m.startContainer,m.startOffset);n.setEnd(m.endContainer,m.endOffset);q=0===n.comparePoint(f,0)&&0===n.comparePoint(f, -q);n.detach();return q};this.mergeIntoParent=function(m){for(var f=m.parentNode;m.firstChild;)f.insertBefore(m.firstChild,m);f.removeChild(m);return f};this.getElementsByTagNameNS=function(m,f,n){return Array.prototype.slice.call(m.getElementsByTagNameNS(f,n))}}; +core.Utils=function(){this.hashString=function(k){var g=0,l,h;l=0;for(h=k.length;l= +g.compareBoundaryPoints(g.START_TO_START,l)&&0<=g.compareBoundaryPoints(g.END_TO_END,l)};this.rangesIntersect=function(g,l){return 0>=g.compareBoundaryPoints(g.END_TO_START,l)&&0<=g.compareBoundaryPoints(g.START_TO_END,l)};this.getNodesInRange=function(g,l){var h=[],b,n=g.startContainer.ownerDocument.createTreeWalker(g.commonAncestorContainer,NodeFilter.SHOW_ALL,l,!1);for(b=n.currentNode=g.startContainer;b;){if(l(b)===NodeFilter.FILTER_ACCEPT)h.push(b);else if(l(b)===NodeFilter.FILTER_REJECT)break; +b=b.parentNode}h.reverse();for(b=n.nextNode();b;)h.push(b),b=n.nextNode();return h};this.normalizeTextNodes=function(g){g&&g.nextSibling&&(g=k(g,g.nextSibling));g&&g.previousSibling&&k(g.previousSibling,g)};this.rangeContainsNode=function(g,l){var h=l.ownerDocument.createRange(),b=l.nodeType===Node.TEXT_NODE?l.length:l.childNodes.length;h.setStart(g.startContainer,g.startOffset);h.setEnd(g.endContainer,g.endOffset);b=0===h.comparePoint(l,0)&&0===h.comparePoint(l,b);h.detach();return b};this.mergeIntoParent= +function(g){for(var l=g.parentNode;g.firstChild;)l.insertBefore(g.firstChild,g);l.removeChild(g);return l};this.getElementsByTagNameNS=function(g,l,h){return Array.prototype.slice.call(g.getElementsByTagNameNS(l,h))};this.rangeIntersectsNode=function(g,l){var h=l.nodeType===Node.TEXT_NODE?l.length:l.childNodes.length;return 0>=g.comparePoint(l,0)&&0<=g.comparePoint(l,h)}}; // Input 10 +runtime.loadClass("core.DomUtils"); +core.Cursor=function(k,g){function l(a){a.parentNode&&(f.push(a.previousSibling),f.push(a.nextSibling),a.parentNode.removeChild(a))}function h(a,c,d){if(c.nodeType===Node.TEXT_NODE){runtime.assert(Boolean(c),"putCursorIntoTextNode: invalid container");var b=c.parentNode;runtime.assert(Boolean(b),"putCursorIntoTextNode: container without parent");runtime.assert(0<=d&&d<=c.length,"putCursorIntoTextNode: offset is out of bounds");0===d?b.insertBefore(a,c):(d!==c.length&&c.splitText(d),b.insertBefore(a, +c.nextSibling))}else if(c.nodeType===Node.ELEMENT_NODE){runtime.assert(Boolean(c),"putCursorIntoContainer: invalid container");for(b=c.firstChild;null!==b&&0 @@ -191,110 +194,114 @@ e.setAttributeNS("urn:webodf:names:cursor","memberId",m)}; @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -core.EventNotifier=function(h){var m={};this.emit=function(f,n){var q,e;runtime.assert(m.hasOwnProperty(f),'unknown event fired "'+f+'"');e=m[f];for(q=0;q1/l?"-0":String(l),h(b+" should be "+a+". Was "+e+".")):h(b+" should be "+a+" (of type "+typeof a+"). Was "+l+" (of type "+typeof l+").")}var a=0,g;g=function(a,b){var e=Object.keys(a),k=Object.keys(b);e.sort();k.sort();return m(e,k)&&Object.keys(a).every(function(k){var c= -a[k],e=b[k];return q(c,e)?!0:(h(c+" should be "+e+" for key "+k),!1)})};this.areNodesEqual=n;this.shouldBeNull=function(a,b){e(a,b,"null")};this.shouldBeNonNull=function(a,b){var e,k;try{k=eval(b)}catch(l){e=l}e?h(b+" should be non-null. Threw exception "+e):null!==k?runtime.log("pass",b+" is non-null."):h(b+" should be non-null. Was "+k)};this.shouldBe=e;this.countFailedTests=function(){return a}}; -core.UnitTester=function(){function h(f,q){return""+f+""}var m=0,f={};this.runTests=function(n,q,e){function a(c){if(0===c.length)f[g]=r,m+=d.countFailedTests(),q();else{l=c[0];var p=Runtime.getFunctionName(l);runtime.log("Running "+p);u=d.countFailedTests();b.setUp();l(function(){b.tearDown();r[p]=u===d.countFailedTests();a(c.slice(1))})}}var g=Runtime.getFunctionName(n),d=new core.UnitTestRunner,b=new n(d),r={},k,l,c,u,t="BrowserRuntime"=== -runtime.type();if(f.hasOwnProperty(g))runtime.log("Test "+g+" has already run.");else{t?runtime.log("Running "+h(g,'runSuite("'+g+'");')+": "+b.description()+""):runtime.log("Running "+g+": "+b.description);c=b.tests();for(k=0;kRunning "+h(n,'runTest("'+g+'","'+n+'")')+""):runtime.log("Running "+n),u=d.countFailedTests(),b.setUp(),l(),b.tearDown(),r[n]=u===d.countFailedTests()); -a(b.asyncTests())}};this.countFailedTests=function(){return m};this.results=function(){return f}}; +core.EventNotifier=function(k){var g={};this.emit=function(l,h){var b,n;runtime.assert(g.hasOwnProperty(l),'unknown event fired "'+l+'"');n=g[l];for(b=0;b "+a.length),runtime.assert(0<=l,"Error in setPosition: "+l+" < 0"),l===a.length&&(b=void 0,d.nextSibling()?b=0:d.parentNode()&&(b=1),runtime.assert(void 0!==b,"Error in setPosition: position not valid.")),!0;c=r(a);l1/g?"-0":String(g),k(c+" should be "+a+". Was "+f+".")):k(c+" should be "+a+" (of type "+typeof a+"). Was "+g+" (of type "+typeof g+").")}var a=0,f;f=function(a,c){var f=Object.keys(a),e=Object.keys(c);f.sort();e.sort();return g(f,e)&&Object.keys(a).every(function(e){var f= +a[e],g=c[e];return b(f,g)?!0:(k(f+" should be "+g+" for key "+e),!1)})};this.areNodesEqual=h;this.shouldBeNull=function(a,c){n(a,c,"null")};this.shouldBeNonNull=function(a,c){var b,e;try{e=eval(c)}catch(f){b=f}b?k(c+" should be non-null. Threw exception "+b):null!==e?runtime.log("pass",c+" is non-null."):k(c+" should be non-null. Was "+e)};this.shouldBe=n;this.countFailedTests=function(){return a}}; +core.UnitTester=function(){function k(g,b){return""+g+""}var g=0,l={};this.runTests=function(h,b,n){function a(e){if(0===e.length)l[f]=t,g+=d.countFailedTests(),b();else{r=e[0];var m=Runtime.getFunctionName(r);runtime.log("Running "+m);q=d.countFailedTests();c.setUp();r(function(){c.tearDown();t[m]=q===d.countFailedTests();a(e.slice(1))})}}var f=Runtime.getFunctionName(h),d=new core.UnitTestRunner,c=new h(d),t={},e,r,m,q,s="BrowserRuntime"=== +runtime.type();if(l.hasOwnProperty(f))runtime.log("Test "+f+" has already run.");else{s?runtime.log("Running "+k(f,'runSuite("'+f+'");')+": "+c.description()+""):runtime.log("Running "+f+": "+c.description);m=c.tests();for(e=0;eRunning "+k(h,'runTest("'+f+'","'+h+'")')+""):runtime.log("Running "+h),q=d.countFailedTests(),c.setUp(),r(),c.tearDown(),t[h]=q===d.countFailedTests()); +a(c.asyncTests())}};this.countFailedTests=function(){return g};this.results=function(){return l}}; // Input 13 -runtime.loadClass("core.PositionIterator");core.PositionFilter=function(){};core.PositionFilter.FilterResult={FILTER_ACCEPT:1,FILTER_REJECT:2,FILTER_SKIP:3};core.PositionFilter.prototype.acceptPosition=function(h){};(function(){return core.PositionFilter})(); +core.PositionIterator=function(k,g,l,h){function b(){this.acceptNode=function(a){return a.nodeType===Node.TEXT_NODE&&0===a.length?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}function n(a){this.acceptNode=function(c){return c.nodeType===Node.TEXT_NODE&&0===c.length?NodeFilter.FILTER_REJECT:a.acceptNode(c)}}function a(){var a=d.currentNode.nodeType;c=a===Node.TEXT_NODE?d.currentNode.length-1:a===Node.ELEMENT_NODE?1:0}var f=this,d,c,t;this.nextPosition=function(){if(d.currentNode===k)return!1; +if(0===c&&d.currentNode.nodeType===Node.ELEMENT_NODE)null===d.firstChild()&&(c=1);else if(d.currentNode.nodeType===Node.TEXT_NODE&&c+1 "+a.length),runtime.assert(0<=b,"Error in setPosition: "+b+" < 0"), +b===a.length&&(c=void 0,d.nextSibling()?c=0:d.parentNode()&&(c=1),runtime.assert(void 0!==c,"Error in setPosition: position not valid.")),!0;g=t(a);b>>8^d;return c^-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 q(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 e(a,b){var c,p,d,l,k,e,g,t=this;this.load=function(b){if(void 0!==t.data)b(null,t.data);else{var c=k+34+p+d+256;c+g>u&&(c=u-g);runtime.read(a,g,c,function(c,p){if(c||null===p)b(c,p);else a:{var d=p,g=new core.ByteArray(d),f=g.readUInt32LE(),u;if(67324752!==f)b("File entry signature is wrong."+f.toString()+" "+d.length.toString(),null);else{g.pos+=22;f=g.readUInt16LE();u=g.readUInt16LE();g.pos+=f+u; -if(l){d=d.slice(g.pos,g.pos+k);if(k!==d.length){b("The amount of compressed bytes read was "+d.length.toString()+" instead of "+k.toString()+" for "+t.filename+" in "+a+".",null);break a}d=s(d,e)}else d=d.slice(g.pos,g.pos+e);e!==d.length?b("The amount of bytes read was "+d.length.toString()+" instead of "+e.toString()+" for "+t.filename+" in "+a+".",null):(t.data=d,b(null,d))}}})}};this.set=function(a,b,c,p){t.filename=a;t.data=b;t.compressed=c;t.date=p};this.error=null;b&&(c=b.readUInt32LE(),33639248!== -c?this.error="Central directory entry has wrong signature at position "+(b.pos-4).toString()+' for file "'+a+'": '+b.data.length.toString():(b.pos+=6,l=b.readUInt16LE(),this.date=n(b.readUInt32LE()),b.readUInt32LE(),k=b.readUInt32LE(),e=b.readUInt32LE(),p=b.readUInt16LE(),d=b.readUInt16LE(),c=b.readUInt16LE(),b.pos+=8,g=b.readUInt32LE(),this.filename=runtime.byteArrayToString(b.data.slice(b.pos,b.pos+p),"utf8"),b.pos+=p+d+c))}function a(a,b){if(22!==a.length)b("Central directory length should be 22.", -p);else{var d=new core.ByteArray(a),l;l=d.readUInt32LE();101010256!==l?b("Central directory signature is wrong: "+l.toString(),p):(l=d.readUInt16LE(),0!==l?b("Zip files with non-zero disk numbers are not supported.",p):(l=d.readUInt16LE(),0!==l?b("Zip files with non-zero disk numbers are not supported.",p):(l=d.readUInt16LE(),t=d.readUInt16LE(),l!==t?b("Number of entries is inconsistent.",p):(l=d.readUInt32LE(),d=d.readUInt16LE(),d=u-22-l,runtime.read(h,d,u-d,function(a,d){if(a||null===d)b(a,p);else a:{var l= -new core.ByteArray(d),k,s;c=[];for(k=0;ku?m("File '"+h+"' cannot be read.",p):runtime.read(h,u-22,22,function(b,c){b||null===m||null===c?m(b,p):a(c,m)})})}; -// Input 16 -core.CSSUnits=function(){var h={"in":1,cm:2.54,mm:25.4,pt:72,pc:12};this.convert=function(m,f,n){return m*h[n]/h[f]};this.convertMeasure=function(m,f){var n,q;m&&f?(n=parseFloat(m),q=m.replace(n.toString(),""),n=this.convert(n,q,f)):n="";return n.toString()};this.getUnits=function(m){return m.substr(m.length-2,m.length)}}; -// Input 17 -xmldom.LSSerializerFilter=function(){}; +2932959818,3654703836,1088359270,936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117],b,e,d=a.length,f=0,f=0;b=-1;for(e=0;e>>8^f;return b^-1}function h(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 b(a){var c=a.getFullYear();return 1980>c?0:c-1980<< +25|a.getMonth()+1<<21|a.getDate()<<16|a.getHours()<<11|a.getMinutes()<<5|a.getSeconds()>>1}function n(a,c){var b,e,d,f,g,m,n,r=this;this.load=function(c){if(void 0!==r.data)c(null,r.data);else{var b=g+34+e+d+256;b+n>q&&(b=q-n);runtime.read(a,n,b,function(b,e){if(b||null===e)c(b,e);else a:{var d=e,p=new core.ByteArray(d),h=p.readUInt32LE(),n;if(67324752!==h)c("File entry signature is wrong."+h.toString()+" "+d.length.toString(),null);else{p.pos+=22;h=p.readUInt16LE();n=p.readUInt16LE();p.pos+=h+n; +if(f){d=d.slice(p.pos,p.pos+g);if(g!==d.length){c("The amount of compressed bytes read was "+d.length.toString()+" instead of "+g.toString()+" for "+r.filename+" in "+a+".",null);break a}d=w(d,m)}else d=d.slice(p.pos,p.pos+m);m!==d.length?c("The amount of bytes read was "+d.length.toString()+" instead of "+m.toString()+" for "+r.filename+" in "+a+".",null):(r.data=d,c(null,d))}}})}};this.set=function(a,c,b,e){r.filename=a;r.data=c;r.compressed=b;r.date=e};this.error=null;c&&(b=c.readUInt32LE(),33639248!== +b?this.error="Central directory entry has wrong signature at position "+(c.pos-4).toString()+' for file "'+a+'": '+c.data.length.toString():(c.pos+=6,f=c.readUInt16LE(),this.date=h(c.readUInt32LE()),c.readUInt32LE(),g=c.readUInt32LE(),m=c.readUInt32LE(),e=c.readUInt16LE(),d=c.readUInt16LE(),b=c.readUInt16LE(),c.pos+=8,n=c.readUInt32LE(),this.filename=runtime.byteArrayToString(c.data.slice(c.pos,c.pos+e),"utf8"),c.pos+=e+d+b))}function a(a,c){if(22!==a.length)c("Central directory length should be 22.", +u);else{var b=new core.ByteArray(a),e;e=b.readUInt32LE();101010256!==e?c("Central directory signature is wrong: "+e.toString(),u):(e=b.readUInt16LE(),0!==e?c("Zip files with non-zero disk numbers are not supported.",u):(e=b.readUInt16LE(),0!==e?c("Zip files with non-zero disk numbers are not supported.",u):(e=b.readUInt16LE(),s=b.readUInt16LE(),e!==s?c("Number of entries is inconsistent.",u):(e=b.readUInt32LE(),b=b.readUInt16LE(),b=q-22-e,runtime.read(k,b,q-b,function(a,b){if(a||null===b)c(a,u);else a:{var e= +new core.ByteArray(b),d,f;m=[];for(d=0;dq?g("File '"+k+"' cannot be read.",u):runtime.read(k,q-22,22,function(c,b){c||null===g||null===b?g(c,u):a(b,g)})})}; // Input 18 -"function"!==typeof Object.create&&(Object.create=function(h){var m=function(){};m.prototype=h;return new m}); -xmldom.LSSerializer=function(){function h(f){var e=f||{},a=function(a){var b={},d;for(d in a)a.hasOwnProperty(d)&&(b[a[d]]=d);return b}(f),g=[e],d=[a],b=0;this.push=function(){b+=1;e=g[b]=Object.create(e);a=d[b]=Object.create(a)};this.pop=function(){g[b]=void 0;d[b]=void 0;b-=1;e=g[b];a=d[b]};this.getLocalNamespaceDefinitions=function(){return a};this.getQName=function(b){var d=b.namespaceURI,l=0,c;if(!d)return b.localName;if(c=a[d])return c+":"+b.localName;do{c||!b.prefix?(c="ns"+l,l+=1):c=b.prefix; -if(e[c]===d)break;if(!e[c]){e[c]=d;a[d]=c;break}c=null}while(null===c);return c+":"+b.localName}}function m(f){return f.replace(/&/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""")}function f(q,e){var a="",g=n.filter?n.filter.acceptNode(e):NodeFilter.FILTER_ACCEPT,d;if(g===NodeFilter.FILTER_ACCEPT&&e.nodeType===Node.ELEMENT_NODE){q.push();d=q.getQName(e);var b,r=e.attributes,k,l,c,u="",t;b="<"+d;k=r.length;for(l=0;l")}if(g===NodeFilter.FILTER_ACCEPT||g===NodeFilter.FILTER_SKIP){for(g=e.firstChild;g;)a+=f(q,g),g=g.nextSibling;e.nodeValue&&(a+=m(e.nodeValue))}d&&(a+="",q.pop());return a}var n=this;this.filter=null;this.writeToString=function(q,e){if(!q)return"";var a=new h(e);return f(a,q)}}; +core.CSSUnits=function(){var k={"in":1,cm:2.54,mm:25.4,pt:72,pc:12};this.convert=function(g,l,h){return g*k[h]/k[l]};this.convertMeasure=function(g,l){var h,b;g&&l?(h=parseFloat(g),b=g.replace(h.toString(),""),h=this.convert(h,b,l)):h="";return h.toString()};this.getUnits=function(g){return g.substr(g.length-2,g.length)}}; // Input 19 -xmldom.RelaxNGParser=function(){function h(a,d){this.message=function(){d&&(a+=1===d.nodeType?" Element ":" Node ",a+=d.nodeName,d.nodeValue&&(a+=" with value '"+d.nodeValue+"'"),a+=".");return a}}function m(a){if(2>=a.e.length)return a;var d={name:a.name,e:a.e.slice(0,2)};return m({name:a.name,e:[d].concat(a.e.slice(2))})}function f(a){a=a.split(":",2);var d="",k;1===a.length?a=["",a[0]]:d=a[0];for(k in g)g[k]===d&&(a[0]=k);return a}function n(a,d){for(var k=0,l,c,e=a.name;a.e&&k=p.length)return c;0===d&&(d=0);for(var l=p.item(d);l.namespaceURI===b;){d+=1;if(d>=p.length)return c;l=p.item(d)}return l=g(a,c.attDeriv(a,p.item(d)),p,d+1)}function d(a,b,c){c.e[0].a?(a.push(c.e[0].text),b.push(c.e[0].a.ns)):d(a,b,c.e[0]);c.e[1].a?(a.push(c.e[1].text),b.push(c.e[1].a.ns)): -d(a,b,c.e[1])}var b="http://www.w3.org/2000/xmlns/",r,k,l,c,u,t,s,p,C,y,v={type:"notAllowed",nullable:!1,hash:"notAllowed",textDeriv:function(){return v},startTagOpenDeriv:function(){return v},attDeriv:function(){return v},startTagCloseDeriv:function(){return v},endTagDeriv:function(){return v}},x={type:"empty",nullable:!0,hash:"empty",textDeriv:function(){return v},startTagOpenDeriv:function(){return v},attDeriv:function(a,b){return v},startTagCloseDeriv:function(){return x},endTagDeriv:function(){return v}}, -N={type:"text",nullable:!0,hash:"text",textDeriv:function(){return N},startTagOpenDeriv:function(){return v},attDeriv:function(){return v},startTagCloseDeriv:function(){return N},endTagDeriv:function(){return v}},A,F,O;r=n("choice",function(a,b){if(a===v)return b;if(b===v||a===b)return a},function(a,b){var c={},p;q(c,{p1:a,p2:b});b=a=void 0;for(p in c)c.hasOwnProperty(p)&&(void 0===a?a=c[p]:b=void 0===b?c[p]:r(b,c[p]));return function(a,b){return{type:"choice",p1:a,p2:b,nullable:a.nullable||b.nullable, -textDeriv:function(c,p){return r(a.textDeriv(c,p),b.textDeriv(c,p))},startTagOpenDeriv:f(function(c){return r(a.startTagOpenDeriv(c),b.startTagOpenDeriv(c))}),attDeriv:function(c,p){return r(a.attDeriv(c,p),b.attDeriv(c,p))},startTagCloseDeriv:h(function(){return r(a.startTagCloseDeriv(),b.startTagCloseDeriv())}),endTagDeriv:h(function(){return r(a.endTagDeriv(),b.endTagDeriv())})}}(a,b)});k=function(a,b,c){return function(){var p={},d=0;return function(l,k){var e=b&&b(l,k),s,g;if(void 0!==e)return e; -e=l.hash||l.toString();s=k.hash||k.toString();e/g,">").replace(/'/g,"'").replace(/"/g,""")}function l(b,n){var a="",f=h.filter?h.filter.acceptNode(n):NodeFilter.FILTER_ACCEPT,d;if(f===NodeFilter.FILTER_ACCEPT&&n.nodeType===Node.ELEMENT_NODE){b.push();d=b.getQName(n);var c,k=n.attributes,e,r,m,q="",s;c="<"+d;e=k.length;for(r=0;r")}if(f===NodeFilter.FILTER_ACCEPT||f===NodeFilter.FILTER_SKIP){for(f=n.firstChild;f;)a+=l(b,f),f=f.nextSibling;n.nodeValue&&(a+=g(n.nodeValue))}d&&(a+="",b.pop());return a}var h=this;this.filter=null;this.writeToString=function(b,g){if(!b)return"";var a=new k(g);return l(a,b)}}; // Input 21 -runtime.loadClass("xmldom.RelaxNGParser"); -xmldom.RelaxNG2=function(){function h(a,e){this.message=function(){e&&(a+=e.nodeType===Node.ELEMENT_NODE?" Element ":" Node ",a+=e.nodeName,e.nodeValue&&(a+=" with value '"+e.nodeValue+"'"),a+=".");return a}}function m(a,e,d,b){return"empty"===a.name?null:q(a,e,d,b)}function f(a,g,d){if(2!==a.e.length)throw"Element with wrong # of elements: "+a.e.length;for(var b=(d=g.currentNode)?d.nodeType:0,f=null;b>Node.ELEMENT_NODE;){if(b!==Node.COMMENT_NODE&&(b!==Node.TEXT_NODE||!/^\s+$/.test(g.currentNode.nodeValue)))return[new h("Not allowed node of type "+ -b+".")];b=(d=g.nextSibling())?d.nodeType:0}if(!d)return[new h("Missing element "+a.names)];if(a.names&&-1===a.names.indexOf(e[d.namespaceURI]+":"+d.localName))return[new h("Found "+d.nodeName+" instead of "+a.names+".",d)];if(g.firstChild()){for(f=m(a.e[1],g,d);g.nextSibling();)if(b=g.currentNode.nodeType,!(g.currentNode&&g.currentNode.nodeType===Node.TEXT_NODE&&/^\s+$/.test(g.currentNode.nodeValue)||b===Node.COMMENT_NODE))return[new h("Spurious content.",g.currentNode)];if(g.parentNode()!==d)return[new h("Implementation error.")]}else f= -m(a.e[1],g,d);g.nextSibling();return f}var n,q,e;q=function(a,e,d,b){var n=a.name,k=null;if("text"===n)a:{for(var l=(a=e.currentNode)?a.nodeType:0;a!==d&&3!==l;){if(1===l){k=[new h("Element not allowed here.",a)];break a}l=(a=e.nextSibling())?a.nodeType:0}e.nextSibling();k=null}else if("data"===n)k=null;else if("value"===n)b!==a.text&&(k=[new h("Wrong value, should be '"+a.text+"', not '"+b+"'",d)]);else if("list"===n)k=null;else if("attribute"===n)a:{if(2!==a.e.length)throw"Attribute with wrong # of elements: "+ -a.e.length;n=a.localnames.length;for(k=0;k=a.e.length)return a;var b={name:a.name,e:a.e.slice(0,2)};return g({name:a.name,e:[b].concat(a.e.slice(2))})}function l(a){a=a.split(":",2);var b="",e;1===a.length?a=["",a[0]]:b=a[0];for(e in f)f[e]===b&&(a[0]=e);return a}function h(a,b){for(var e=0,d,f,g=a.name;a.e&&e=d.length)return b;0===e&&(e=0);for(var g=d.item(e);g.namespaceURI===c;){e+=1;if(e>=d.length)return b;g=d.item(e)}return g=f(a,b.attDeriv(a,d.item(e)),d,e+1)}function d(a,b,c){c.e[0].a?(a.push(c.e[0].text),b.push(c.e[0].a.ns)):d(a,b,c.e[0]);c.e[1].a?(a.push(c.e[1].text),b.push(c.e[1].a.ns)): +d(a,b,c.e[1])}var c="http://www.w3.org/2000/xmlns/",t,e,r,m,q,s,w,u,z,v,p={type:"notAllowed",nullable:!1,hash:"notAllowed",textDeriv:function(){return p},startTagOpenDeriv:function(){return p},attDeriv:function(){return p},startTagCloseDeriv:function(){return p},endTagDeriv:function(){return p}},y={type:"empty",nullable:!0,hash:"empty",textDeriv:function(){return p},startTagOpenDeriv:function(){return p},attDeriv:function(){return p},startTagCloseDeriv:function(){return y},endTagDeriv:function(){return p}}, +D={type:"text",nullable:!0,hash:"text",textDeriv:function(){return D},startTagOpenDeriv:function(){return p},attDeriv:function(){return p},startTagCloseDeriv:function(){return D},endTagDeriv:function(){return p}},H,A,N;t=h("choice",function(a,b){if(a===p)return b;if(b===p||a===b)return a},function(a,c){var e={},d;b(e,{p1:a,p2:c});c=a=void 0;for(d in e)e.hasOwnProperty(d)&&(void 0===a?a=e[d]:c=void 0===c?e[d]:t(c,e[d]));return function(a,b){return{type:"choice",p1:a,p2:b,nullable:a.nullable||b.nullable, +textDeriv:function(c,e){return t(a.textDeriv(c,e),b.textDeriv(c,e))},startTagOpenDeriv:l(function(c){return t(a.startTagOpenDeriv(c),b.startTagOpenDeriv(c))}),attDeriv:function(c,e){return t(a.attDeriv(c,e),b.attDeriv(c,e))},startTagCloseDeriv:k(function(){return t(a.startTagCloseDeriv(),b.startTagCloseDeriv())}),endTagDeriv:k(function(){return t(a.endTagDeriv(),b.endTagDeriv())})}}(a,c)});e=function(a,b,c){return function(){var e={},d=0;return function(f,g){var m=b&&b(f,g),h,p;if(void 0!==m)return m; +m=f.hash||f.toString();h=g.hash||g.toString();mNode.ELEMENT_NODE;){if(c!==Node.COMMENT_NODE&&(c!==Node.TEXT_NODE||!/^\s+$/.test(b.currentNode.nodeValue)))return[new k("Not allowed node of type "+ +c+".")];c=(d=b.nextSibling())?d.nodeType:0}if(!d)return[new k("Missing element "+a.names)];if(a.names&&-1===a.names.indexOf(n[d.namespaceURI]+":"+d.localName))return[new k("Found "+d.nodeName+" instead of "+a.names+".",d)];if(b.firstChild()){for(h=g(a.e[1],b,d);b.nextSibling();)if(c=b.currentNode.nodeType,!(b.currentNode&&b.currentNode.nodeType===Node.TEXT_NODE&&/^\s+$/.test(b.currentNode.nodeValue)||c===Node.COMMENT_NODE))return[new k("Spurious content.",b.currentNode)];if(b.parentNode()!==d)return[new k("Implementation error.")]}else h= +g(a.e[1],b,d);b.nextSibling();return h}var h,b,n;b=function(a,f,d,c){var h=a.name,e=null;if("text"===h)a:{for(var n=(a=f.currentNode)?a.nodeType:0;a!==d&&3!==n;){if(1===n){e=[new k("Element not allowed here.",a)];break a}n=(a=f.nextSibling())?a.nodeType:0}f.nextSibling();e=null}else if("data"===h)e=null;else if("value"===h)c!==a.text&&(e=[new k("Wrong value, should be '"+a.text+"', not '"+c+"'",d)]);else if("list"===h)e=null;else if("attribute"===h)a:{if(2!==a.e.length)throw"Attribute with wrong # of elements: "+ +a.e.length;h=a.localnames.length;for(e=0;e=s&&c.push(m(a.substring(b,d)))):"["===a[d]&&(0>=s&&(b=d+1),s+=1),d+=1;return d};xmldom.XPathIterator.prototype.next=function(){};xmldom.XPathIterator.prototype.reset=function(){};b=function(b,d,c){var e,f,s,p;for(e=0;e=h&&c.push(g(a.substring(b,d)))):"["===a[d]&&(0>=h&&(b=d+1),h+=1),d+=1;return d};xmldom.XPathIterator.prototype.next=function(){};xmldom.XPathIterator.prototype.reset=function(){};c=function(c,d,g){var n,l,k,u;for(n=0;n=l.getBoundingClientRect().top-w.bottom? +e.style.top=Math.abs(l.getBoundingClientRect().top-w.bottom)+20+"px":e.style.top="0px");m.style.left=h.getBoundingClientRect().width+"px";var h=m.style,l=m.getBoundingClientRect().left,k=m.getBoundingClientRect().top,w=e.getBoundingClientRect().left,u=e.getBoundingClientRect().top,z=0,v=0,z=w-l,z=z*z,v=u-k,v=v*v,l=Math.sqrt(z+v);h.width=l+"px";k=Math.asin((e.getBoundingClientRect().top-m.getBoundingClientRect().top)/parseFloat(m.style.width));m.style.transform="rotate("+k+"rad)";m.style.MozTransform= +"rotate("+k+"rad)";m.style.WebkitTransform="rotate("+k+"rad)";m.style.msTransform="rotate("+k+"rad)";f&&(w=d.getComputedStyle(f,":before").content)&&"none"!==w&&(w=w.substring(1,w.length-1),f.firstChild?f.firstChild.nodeValue=w:f.appendChild(a.createTextNode(w)))}}var n=[],a=k.ownerDocument,f=new odf.OdfUtils,d=runtime.getWindow();runtime.assert(Boolean(d),"Expected to be run in an environment which has a global window, like a browser.");this.rerenderAnnotations=b;this.addAnnotation=function(c){n.push({node:c.node, +end:c.end});h();var d=a.createElement("div"),e=a.createElement("div"),f=a.createElement("div"),g=a.createElement("div"),k=c.node;d.className="annotationWrapper";k.parentNode.insertBefore(d,k);e.className="annotationNote";e.appendChild(k);f.className="annotationConnector horizontal";g.className="annotationConnector angular";d.appendChild(e);d.appendChild(f);d.appendChild(g);c.end&&l(c);b()};this.forgetAnnotations=function(){for(;n.length;){var b=n[0],d=b.node,e=d.parentNode.parentNode;"div"===e.localName&& +(e.parentNode.insertBefore(d,e),e.parentNode.removeChild(e));for(var d=b.node.getAttributeNS(odf.Namespaces.officens,"name"),d=a.querySelectorAll('span.annotationHighlight[annotation="'+d+'"]'),f=e=void 0,g=void 0,h=void 0,e=0;e + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ +odf.OdfNodeFilter=function(){this.acceptNode=function(k){return"http://www.w3.org/1999/xhtml"===k.namespaceURI?NodeFilter.FILTER_SKIP:k.namespaceURI&&k.namespaceURI.match(/^urn:webodf:/)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}; // Input 27 /* @@ -435,55 +415,72 @@ p);d&&m(d,p)}};this.determineStylesForNode=f;l=function(a){var b,c,d,e,l,k={},g; @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -odf.OdfUtils=function(){function h(a){var b=a&&a.localName;return("p"===b||"h"===b)&&a.namespaceURI===u}function m(a){return/^[ \t\r\n]+$/.test(a)}function f(a){var b=a&&a.localName;return("span"===b||"p"===b||"h"===b)&&a.namespaceURI===u}function n(a){var b=a&&a.localName,c,d=!1;b&&(c=a.namespaceURI,c===u?d="s"===b||"tab"===b||"line-break"===b:c===t&&(d="frame"===b&&"as-char"===a.getAttributeNS(u,"anchor-type")));return d}function q(a){for(;null!==a.firstChild&&f(a);)a=a.firstChild;return a}function e(a){for(;null!== -a.lastChild&&f(a);)a=a.lastChild;return a}function a(a){for(;!h(a)&&null===a.previousSibling;)a=a.parentNode;return h(a)?null:e(a.previousSibling)}function g(a){for(;!h(a)&&null===a.nextSibling;)a=a.parentNode;return h(a)?null:q(a.nextSibling)}function d(b){for(var c=!1;b;)if(b.nodeType===Node.TEXT_NODE)if(0===b.length)b=a(b);else return!m(b.data.substr(b.length-1,1));else if(n(b)){c=!0;break}else b=a(b);return c}function b(b){var c=!1;for(b=b&&e(b);b;){if(b.nodeType===Node.TEXT_NODE&&0=b.value||"%"===b.unit)?null:b;return b||c(a)};this.parseFoLineHeight=function(a){var b;b=(b=l(a))&&(0>b.value||"%"=== -b.unit)?null:b;return b||c(a)};this.getTextNodes=function(a,b){var c=a.startContainer.ownerDocument,d=c.createRange(),e=[],l;l=c.createTreeWalker(a.commonAncestorContainer.nodeType===Node.TEXT_NODE?a.commonAncestorContainer.parentNode:a.commonAncestorContainer,NodeFilter.SHOW_ALL,function(c){d.selectNodeContents(c);if(!1===b&&c.nodeType===Node.TEXT_NODE){if(0>=a.compareBoundaryPoints(a.START_TO_START,d)&&0<=a.compareBoundaryPoints(a.END_TO_END,d))return NodeFilter.FILTER_ACCEPT}else if(-1===a.compareBoundaryPoints(a.END_TO_START, -d)&&1===a.compareBoundaryPoints(a.START_TO_END,d))return c.nodeType===Node.TEXT_NODE?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT},!1);l.currentNode=a.startContainer.previousSibling||a.startContainer.parentNode;for(c=l.nextNode();c;)e.push(c),c=l.nextNode();d.detach();return e}}; +odf.Namespaces=function(){function k(h){return g[h]||null}var g={draw:"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",fo:"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",office:"urn:oasis:names:tc:opendocument:xmlns:office:1.0",presentation:"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0",style:"urn:oasis:names:tc:opendocument:xmlns:style:1.0",svg:"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",table:"urn:oasis:names:tc:opendocument:xmlns:table:1.0",text:"urn:oasis:names:tc:opendocument:xmlns:text:1.0", +dr3d:"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0",numberns:"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",dc:"http://purl.org/dc/elements/1.1/",webodf:"urn:webodf"},l;k.lookupNamespaceURI=k;l=function(){};l.forEachPrefix=function(h){for(var b in g)g.hasOwnProperty(b)&&h(b,g[b])};l.resolvePrefix=k;l.namespaceMap=g;l.drawns="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0";l.fons="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"; +l.officens="urn:oasis:names:tc:opendocument:xmlns:office:1.0";l.presentationns="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0";l.stylens="urn:oasis:names:tc:opendocument:xmlns:style:1.0";l.svgns="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0";l.tablens="urn:oasis:names:tc:opendocument:xmlns:table:1.0";l.textns="urn:oasis:names:tc:opendocument:xmlns:text:1.0";l.dr3dns="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0";l.numberns="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"; +l.xlinkns="http://www.w3.org/1999/xlink";l.xmlns="http://www.w3.org/XML/1998/namespace";l.dcns="http://purl.org/dc/elements/1.1/";l.webodfns="urn:webodf";return l}(); // Input 28 -/* - - Copyright (C) 2012-2013 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -runtime.loadClass("core.DomUtils");runtime.loadClass("core.LoopWatchDog");runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfUtils"); -odf.TextStyleApplicator=function(h,m,f){function n(a){function b(a,d){return"object"===typeof a&&"object"===typeof d?Object.keys(a).every(function(e){return b(a[e],d[e])}):a===d}this.isStyleApplied=function(c){c=m.getAppliedStylesForElement(c);return b(a,c)}}function q(a){var e={};this.applyStyleToContainer=function(c){var g;g=c.getAttributeNS(d,"style-name");var n=c.ownerDocument;g=g||"";if(!e.hasOwnProperty(g)){var s=g,p=g,q;p?(q=m.getStyleElement(p,"text"),q.parentNode===f?n=q.cloneNode(!0):(n= -n.createElementNS(b,"style:style"),n.setAttributeNS(b,"style:parent-style-name",p),n.setAttributeNS(b,"style:family","text"),n.setAttributeNS(r,"scope","document-content"))):(n=n.createElementNS(b,"style:style"),n.setAttributeNS(b,"style:family","text"),n.setAttributeNS(r,"scope","document-content"));m.updateStyle(n,a,h);f.appendChild(n);e[s]=n}g=e[g].getAttributeNS(b,"name");c.setAttributeNS(d,"text:style-name",g)}}var e,a=new odf.OdfUtils,g=new core.DomUtils,d=odf.Namespaces.textns,b=odf.Namespaces.stylens, -r="urn:webodf:names:scope";this.applyStyle=function(b,l){var c,f,m,s,p;c={};var h;runtime.assert(l&&l["style:text-properties"],"applyStyle without any text properties");c["style:text-properties"]=l["style:text-properties"];s=new q(c);p=new n(c);e=g.splitBoundaries(b);c=a.getTextNodes(b,!1);h={startContainer:b.startContainer,startOffset:b.startOffset,endContainer:b.endContainer,endOffset:b.endOffset};c.forEach(function(b){f=p.isStyleApplied(b);if(!1===f){var c=b.ownerDocument,e=b.parentNode,l,k=b, -n=new core.LoopWatchDog(1E3);a.isParagraph(e)?(c=c.createElementNS(d,"text:span"),e.insertBefore(c,b),l=!1):(b.previousSibling&&!g.rangeContainsNode(h,b.previousSibling)?(c=e.cloneNode(!1),e.parentNode.insertBefore(c,e.nextSibling)):c=e,l=!0);for(;k&&(k===b||g.rangeContainsNode(h,k));)n.check(),e=k.nextSibling,k.parentNode!==c&&c.appendChild(k),k=e;if(k&&l)for(b=c.cloneNode(!1),c.parentNode.insertBefore(b,c.nextSibling);k;)n.check(),e=k.nextSibling,b.appendChild(k),k=e;m=c;s.applyStyleToContainer(m)}}); -e.forEach(g.normalizeTextNodes);e=null}}; +runtime.loadClass("xmldom.XPath"); +odf.StyleInfo=function(){function k(a,b){for(var c=r[a.localName],d=c&&c[a.namespaceURI],e=d?d.length:0,f,c=0;c text|list-item > text|list",e-=1;e=b+" > text|list-item > *:not(text|list):first-child";void 0!==p&&(p=e+"{margin-left:"+p+";}",a.insertRule(p,a.cssRules.length));d=b+" > text|list-item > *:not(text|list):first-child:before{"+ -d+";";d+="counter-increment:list;";d+="margin-left:"+l+";";d+="width:"+c+";";d+="display:inline-block}";try{a.insertRule(d,a.cssRules.length)}catch(g){throw g;}}function k(f,n,q,m){if("list"===n)for(var t=m.firstChild,h,v;t;){if(t.namespaceURI===s)if(h=t,"list-level-style-number"===t.localName){var E=h;v=E.getAttributeNS(u,"num-format");var y=E.getAttributeNS(u,"num-suffix"),w={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},E=E.getAttributeNS(u,"num-prefix")||"",E=w.hasOwnProperty(v)? -E+(" counter(list, "+w[v]+")"):v?E+("'"+v+"';"):E+" ''";y&&(E+=" '"+y+"'");v="content: "+E+";";r(f,q,h,v)}else"list-level-style-image"===t.localName?(v="content: none;",r(f,q,h,v)):"list-level-style-bullet"===t.localName&&(v="content: '"+h.getAttributeNS(s,"bullet-char")+"';",r(f,q,h,v));t=t.nextSibling}else if("page"===n)if(y=h=q="",t=m.getElementsByTagNameNS(u,"page-layout-properties")[0],h=t.parentNode.parentNode.parentNode.masterStyles,y="",q+=g(t,G),v=t.getElementsByTagNameNS(u,"background-image"), -0=b.value||"%"===b.unit)?null:b;return b||q(a)};this.parseFoLineHeight=function(a){var b;b=(b=m(a))&&(0>b.value|| +"%"===b.unit)?null:b;return b||q(a)};this.getImpactedParagraphs=function(a){var b=a.commonAncestorContainer,c=[];for(b.nodeType===Node.ELEMENT_NODE&&(c=v.getElementsByTagNameNS(b,w,"p").concat(v.getElementsByTagNameNS(b,w,"h")));b&&!k(b);)b=b.parentNode;b&&c.push(b);return c.filter(function(b){return v.rangeIntersectsNode(a,b)})};this.getTextNodes=function(a,b){var c=a.startContainer.ownerDocument.createRange(),d;d=v.getNodesInRange(a,function(d){c.selectNodeContents(d);if(d.nodeType===Node.TEXT_NODE){if(b&& +v.rangesIntersect(a,c)||v.containsRange(a,c))return Boolean(g(d)&&(!l(d.textContent)||r(d,0)))?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}else if(v.rangesIntersect(a,c)&&s(d))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});c.detach();return d};this.getTextElements=function(a,c){var d=a.startContainer.ownerDocument.createRange(),e;e=v.getNodesInRange(a,function(e){var f=e.nodeType;d.selectNodeContents(e);if(f===Node.TEXT_NODE){if(v.containsRange(a,d)&&(c||Boolean(g(e)&&(!l(e.textContent)|| +r(e,0)))))return NodeFilter.FILTER_ACCEPT}else if(b(e)){if(v.containsRange(a,d))return NodeFilter.FILTER_ACCEPT}else if(s(e)||h(e))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT});d.detach();return e};this.getParagraphElements=function(a){var b=a.startContainer.ownerDocument.createRange(),c;c=v.getNodesInRange(a,function(c){b.selectNodeContents(c);if(k(c)){if(v.rangesIntersect(a,b))return NodeFilter.FILTER_ACCEPT}else if(s(c)||h(c))return NodeFilter.FILTER_SKIP;return NodeFilter.FILTER_REJECT}); +b.detach();return c}}; // Input 30 -runtime.loadClass("core.Base64");runtime.loadClass("core.Zip");runtime.loadClass("xmldom.LSSerializer");runtime.loadClass("odf.StyleInfo");runtime.loadClass("odf.Namespaces"); -odf.OdfContainer=function(){function h(a,b,c){for(a=a?a.firstChild:null;a;){if(a.localName===c&&a.namespaceURI===b)return a;a=a.nextSibling}return null}function m(a){var b,c=k.length;for(b=0;bc)break;e=e.nextSibling}a.insertBefore(b,e)}}}function q(a){this.OdfContainer=a}function e(a,b,c,d){var e=this;this.size=0;this.type=null;this.name=a;this.container=c;this.onchange=this.onreadystatechange=this.document=this.mimetype=this.url=null;this.EMPTY=0;this.LOADING=1;this.DONE=2;this.state=this.EMPTY;this.load=function(){null!== -d&&(this.mimetype=b,d.loadAsDataURL(a,b,function(a,b){a&&runtime.log(a);e.url=b;if(e.onchange)e.onchange(e);if(e.onstatereadychange)e.onstatereadychange(e)}))};this.abort=function(){}}function a(a){this.length=0;this.item=function(a){}}var g=new odf.StyleInfo,d="urn:oasis:names:tc:opendocument:xmlns:office:1.0",b="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0",r="urn:webodf:names:scope",k="meta settings scripts font-face-decls styles automatic-styles master-styles body".split(" "),l=(new Date).getTime()+ -"_webodf_",c=new core.Base64;q.prototype=new function(){};q.prototype.constructor=q;q.namespaceURI=d;q.localName="document";e.prototype.load=function(){};e.prototype.getUrl=function(){return this.data?"data:;base64,"+c.toBase64(this.data):null};odf.OdfContainer=function t(c,p){function k(a){for(var b=a.firstChild,c;b;)c=b.nextSibling,b.nodeType===Node.ELEMENT_NODE?k(b):b.nodeType===Node.PROCESSING_INSTRUCTION_NODE&&a.removeChild(b),b=c}function m(a,b){for(var c=a&&a.firstChild;c;)c.nodeType===Node.ELEMENT_NODE&& -c.setAttributeNS(r,"scope",b),c=c.nextSibling}function v(a,b){var c=null,d,e,l;if(a)for(c=a.cloneNode(!0),d=c.firstChild;d;)e=d.nextSibling,d.nodeType===Node.ELEMENT_NODE&&(l=d.getAttributeNS(r,"scope"))&&l!==b&&c.removeChild(d),d=e;return c}function x(a){var b=J.rootElement.ownerDocument,c;if(a){k(a.documentElement);try{c=b.importNode(a.documentElement,!0)}catch(d){}}return c}function N(a){J.state=a;if(J.onchange)J.onchange(J);if(J.onstatereadychange)J.onstatereadychange(J)}function A(a){Y=null; -J.rootElement=a;a.fontFaceDecls=h(a,d,"font-face-decls");a.styles=h(a,d,"styles");a.automaticStyles=h(a,d,"automatic-styles");a.masterStyles=h(a,d,"master-styles");a.body=h(a,d,"body");a.meta=h(a,d,"meta")}function F(a){a=x(a);var b=J.rootElement;a&&"document-styles"===a.localName&&a.namespaceURI===d?(b.fontFaceDecls=h(a,d,"font-face-decls"),n(b,b.fontFaceDecls),b.styles=h(a,d,"styles"),n(b,b.styles),b.automaticStyles=h(a,d,"automatic-styles"),m(b.automaticStyles,"document-styles"),n(b,b.automaticStyles), -b.masterStyles=h(a,d,"master-styles"),n(b,b.masterStyles),g.prefixStyleNames(b.automaticStyles,l,b.masterStyles)):N(t.INVALID)}function O(a){a=x(a);var b,c,e;if(a&&"document-content"===a.localName&&a.namespaceURI===d){b=J.rootElement;c=h(a,d,"font-face-decls");if(b.fontFaceDecls&&c)for(e=c.firstChild;e;)b.fontFaceDecls.appendChild(e),e=c.firstChild;else c&&(b.fontFaceDecls=c,n(b,c));c=h(a,d,"automatic-styles");m(c,"document-content");if(b.automaticStyles&&c)for(e=c.firstChild;e;)b.automaticStyles.appendChild(e), -e=c.firstChild;else c&&(b.automaticStyles=c,n(b,c));b.body=h(a,d,"body");n(b,b.body)}else N(t.INVALID)}function z(a){a=x(a);var b;a&&("document-meta"===a.localName&&a.namespaceURI===d)&&(b=J.rootElement,b.meta=h(a,d,"meta"),n(b,b.meta))}function H(a){a=x(a);var b;a&&("document-settings"===a.localName&&a.namespaceURI===d)&&(b=J.rootElement,b.settings=h(a,d,"settings"),n(b,b.settings))}function D(a){a=x(a);var c;if(a&&"manifest"===a.localName&&a.namespaceURI===b)for(c=J.rootElement,c.manifest=a,a=c.manifest.firstChild;a;)a.nodeType=== -Node.ELEMENT_NODE&&("file-entry"===a.localName&&a.namespaceURI===b)&&(Q[a.getAttributeNS(b,"full-path")]=a.getAttributeNS(b,"media-type")),a=a.nextSibling}function G(a){var b=a.shift(),c,d;b?(c=b[0],d=b[1],P.loadAsDOM(c,function(b,c){d(c);J.state!==t.INVALID&&G(a)})):N(t.DONE)}function T(a){var b="";odf.Namespaces.forEachPrefix(function(a,c){b+=" xmlns:"+a+'="'+c+'"'});return''}function ba(){var a=new xmldom.LSSerializer, -b=T("document-meta");a.filter=new f;b+=a.writeToString(J.rootElement.meta,odf.Namespaces.namespaceMap);return b+""}function V(a,c){var d=document.createElementNS(b,"manifest:file-entry");d.setAttributeNS(b,"manifest:full-path",a);d.setAttributeNS(b,"manifest:media-type",c);return d}function ca(){var a=runtime.parseXML(''),c=h(a,b,"manifest"),d=new xmldom.LSSerializer,e;for(e in Q)Q.hasOwnProperty(e)&&c.appendChild(V(e, -Q[e]));d.filter=new f;return'\n'+d.writeToString(a,odf.Namespaces.namespaceMap)}function U(){var a=new xmldom.LSSerializer,b=T("document-settings");a.filter=new f;b+=a.writeToString(J.rootElement.settings,odf.Namespaces.namespaceMap);return b+""}function W(){var a=odf.Namespaces.namespaceMap,b=new xmldom.LSSerializer,c=v(J.rootElement.automaticStyles,"document-styles"),d=J.rootElement.masterStyles&&J.rootElement.masterStyles.cloneNode(!0), -e=T("document-styles");g.removePrefixFromStyleNames(c,l,d);b.filter=new f(d,c);e+=b.writeToString(J.rootElement.fontFaceDecls,a);e+=b.writeToString(J.rootElement.styles,a);e+=b.writeToString(c,a);e+=b.writeToString(d,a);return e+""}function M(){var a=odf.Namespaces.namespaceMap,b=new xmldom.LSSerializer,c=v(J.rootElement.automaticStyles,"document-content"),d=T("document-content");b.filter=new f(J.rootElement.body,c);d+=b.writeToString(c,a);d+=b.writeToString(J.rootElement.body, -a);return d+""}function S(a,b){runtime.loadXML(a,function(a,c){if(a)b(a);else{var e=x(c);e&&"document"===e.localName&&e.namespaceURI===d?(A(e),N(t.DONE)):N(t.INVALID)}})}function R(){function a(b,c){var l;c||(c=b);l=document.createElementNS(d,c);e[b]=l;e.appendChild(l)}var b=new core.Zip("",null),c=runtime.byteArrayFromString("application/vnd.oasis.opendocument.text","utf8"),e=J.rootElement,l=document.createElementNS(d,"text");b.save("mimetype",c,!1,new Date);a("meta");a("settings"); -a("scripts");a("fontFaceDecls","font-face-decls");a("styles");a("automaticStyles","automatic-styles");a("masterStyles","master-styles");a("body");e.body.appendChild(l);N(t.DONE);return b}function I(){var a,b=new Date;a=runtime.byteArrayFromString(U(),"utf8");P.save("settings.xml",a,!0,b);a=runtime.byteArrayFromString(ba(),"utf8");P.save("meta.xml",a,!0,b);a=runtime.byteArrayFromString(W(),"utf8");P.save("styles.xml",a,!0,b);a=runtime.byteArrayFromString(M(),"utf8");P.save("content.xml",a,!0,b);a= -runtime.byteArrayFromString(ca(),"utf8");P.save("META-INF/manifest.xml",a,!0,b)}function B(a,b){I();P.writeAs(a,function(a){b(a)})}var J=this,P,Q={},Y;this.onstatereadychange=p;this.parts=this.rootElement=this.state=this.onchange=null;this.setRootElement=A;this.getContentElement=function(){var a;Y||(a=J.rootElement.body,Y=a.getElementsByTagNameNS(d,"text")[0]||a.getElementsByTagNameNS(d,"presentation")[0]||a.getElementsByTagNameNS(d,"spreadsheet")[0]);return Y};this.getDocumentType=function(){var a= -J.getContentElement();return a&&a.localName};this.getPart=function(a){return new e(a,Q[a],J,P)};this.getPartData=function(a,b){P.load(a,b)};this.createByteArray=function(a,b){I();P.createByteArray(a,b)};this.saveAs=B;this.save=function(a){B(c,a)};this.getUrl=function(){return c};this.state=t.LOADING;this.rootElement=function(a){var b=document.createElementNS(a.namespaceURI,a.localName),c;a=new a;for(c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b}(q);this.parts=new a(this);P=c?new core.Zip(c,function(a, -b){P=b;a?S(c,function(b){a&&(P.error=a+"\n"+b,N(t.INVALID))}):G([["styles.xml",F],["content.xml",O],["meta.xml",z],["settings.xml",H],["META-INF/manifest.xml",D]])}):R()};odf.OdfContainer.EMPTY=0;odf.OdfContainer.LOADING=1;odf.OdfContainer.DONE=2;odf.OdfContainer.INVALID=3;odf.OdfContainer.SAVING=4;odf.OdfContainer.MODIFIED=5;odf.OdfContainer.getContainer=function(a){return new odf.OdfContainer(a,null)};return odf.OdfContainer}(); +/* + + 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.OdfUtils"); +odf.TextSerializer=function(){function k(h){var b="",n=g.filter?g.filter.acceptNode(h):NodeFilter.FILTER_ACCEPT,a=h.nodeType,f;if(n===NodeFilter.FILTER_ACCEPT||n===NodeFilter.FILTER_SKIP)for(f=h.firstChild;f;)b+=k(f),f=f.nextSibling;n===NodeFilter.FILTER_ACCEPT&&(a===Node.ELEMENT_NODE&&l.isParagraph(h)?b+="\n":a===Node.TEXT_NODE&&h.textContent&&(b+=h.textContent));return b}var g=this,l=new odf.OdfUtils;this.filter=null;this.writeToString=function(g){return g?k(g):""}}; // Input 31 /* @@ -596,10 +600,11 @@ b){P=b;a?S(c,function(b){a&&(P.error=a+"\n"+b,N(t.INVALID))}):G([["styles.xml",F @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("core.Base64");runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.OdfContainer"); -odf.FontLoader=function(){function h(f,e,a,g,d){var b,m=0,k;for(k in f)if(f.hasOwnProperty(k)){if(m===a){b=k;break}m+=1}if(!b)return d();e.getPartData(f[b].href,function(l,c){if(l)runtime.log(l);else{var k="@font-face { font-family: '"+(f[b].family||b)+"'; src: url(data:application/x-font-ttf;charset=binary;base64,"+n.convertUTF8ArrayToBase64(c)+') format("truetype"); }';try{g.insertRule(k,g.cssRules.length)}catch(m){runtime.log("Problem inserting rule in CSS: "+runtime.toJson(m)+"\nRule: "+k)}}h(f, -e,a+1,g,d)})}function m(f,e,a){h(f,e,0,a,function(){})}var f=new xmldom.XPath,n=new core.Base64;odf.FontLoader=function(){this.loadFonts=function(n,e){for(var a=n.rootElement.fontFaceDecls;e.cssRules.length;)e.deleteRule(e.cssRules.length-1);if(a){var g={},d,b,h,k;if(a)for(a=f.getODFElementsWithXPath(a,"style:font-face[svg:font-face-src]",odf.Namespaces.resolvePrefix),d=0;d text|list-item > text|list",e-=1;e=b+" > text|list-item > *:not(text|list):first-child";void 0!==f&&(f=e+"{margin-left:"+f+";}",a.insertRule(f,a.cssRules.length));d=b+" > text|list-item > *:not(text|list):first-child:before{"+ +d+";";d+="counter-increment:list;";d+="margin-left:"+g+";";d+="width:"+c+";";d+="display:inline-block}";try{a.insertRule(d,a.cssRules.length)}catch(h){throw h;}}function e(b,g,h,l){if("list"===g)for(var k=l.firstChild,p,s;k;){if(k.namespaceURI===w)if(p=k,"list-level-style-number"===k.localName){var v=p;s=v.getAttributeNS(q,"num-format");var E=v.getAttributeNS(q,"num-suffix"),G={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},v=v.getAttributeNS(q,"num-prefix")||"",v=G.hasOwnProperty(s)? +v+(" counter(list, "+G[s]+")"):s?v+("'"+s+"';"):v+" ''";E&&(v+=" '"+E+"'");s="content: "+v+";";t(b,h,p,s)}else"list-level-style-image"===k.localName?(s="content: none;",t(b,h,p,s)):"list-level-style-bullet"===k.localName&&(s="content: '"+p.getAttributeNS(w,"bullet-char")+"';",t(b,h,p,s));k=k.nextSibling}else if("page"===g)if(E=p=h="",k=l.getElementsByTagNameNS(q,"page-layout-properties")[0],p=k.parentNode.parentNode.parentNode.masterStyles,E="",h+=f(k,J),s=k.getElementsByTagNameNS(q,"background-image"), +0c)break;e=e.nextSibling}a.insertBefore(b,e)}}}function n(a){this.OdfContainer=a}function a(a, +b,c,d){var e=this;this.size=0;this.type=null;this.name=a;this.container=c;this.onchange=this.onreadystatechange=this.document=this.mimetype=this.url=null;this.EMPTY=0;this.LOADING=1;this.DONE=2;this.state=this.EMPTY;this.load=function(){null!==d&&(this.mimetype=b,d.loadAsDataURL(a,b,function(a,b){a&&runtime.log(a);e.url=b;if(e.onchange)e.onchange(e);if(e.onstatereadychange)e.onstatereadychange(e)}))}}var f=new odf.StyleInfo,d="urn:oasis:names:tc:opendocument:xmlns:office:1.0",c="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0", +t="urn:webodf:names:scope",e="meta settings scripts font-face-decls styles automatic-styles master-styles body".split(" "),r=(new Date).getTime()+"_webodf_",m=new core.Base64;n.prototype=new function(){};n.prototype.constructor=n;n.namespaceURI=d;n.localName="document";a.prototype.load=function(){};a.prototype.getUrl=function(){return this.data?"data:;base64,"+m.toBase64(this.data):null};odf.OdfContainer=function s(e,g){function m(a){for(var b=a.firstChild,c;b;)c=b.nextSibling,b.nodeType===Node.ELEMENT_NODE? +m(b):b.nodeType===Node.PROCESSING_INSTRUCTION_NODE&&a.removeChild(b),b=c}function v(a,b){for(var c=a&&a.firstChild;c;)c.nodeType===Node.ELEMENT_NODE&&c.setAttributeNS(t,"scope",b),c=c.nextSibling}function p(a,b){var c=null,d,e,f;if(a)for(c=a.cloneNode(!0),d=c.firstChild;d;)e=d.nextSibling,d.nodeType===Node.ELEMENT_NODE&&(f=d.getAttributeNS(t,"scope"))&&f!==b&&c.removeChild(d),d=e;return c}function y(a){var b=M.rootElement.ownerDocument,c;if(a){m(a.documentElement);try{c=b.importNode(a.documentElement, +!0)}catch(d){}}return c}function D(a){M.state=a;if(M.onchange)M.onchange(M);if(M.onstatereadychange)M.onstatereadychange(M)}function H(a){Y=null;M.rootElement=a;a.fontFaceDecls=k(a,d,"font-face-decls");a.styles=k(a,d,"styles");a.automaticStyles=k(a,d,"automatic-styles");a.masterStyles=k(a,d,"master-styles");a.body=k(a,d,"body");a.meta=k(a,d,"meta")}function A(a){a=y(a);var c=M.rootElement;a&&"document-styles"===a.localName&&a.namespaceURI===d?(c.fontFaceDecls=k(a,d,"font-face-decls"),b(c,c.fontFaceDecls), +c.styles=k(a,d,"styles"),b(c,c.styles),c.automaticStyles=k(a,d,"automatic-styles"),v(c.automaticStyles,"document-styles"),b(c,c.automaticStyles),c.masterStyles=k(a,d,"master-styles"),b(c,c.masterStyles),f.prefixStyleNames(c.automaticStyles,r,c.masterStyles)):D(s.INVALID)}function N(a){a=y(a);var c,e,f;if(a&&"document-content"===a.localName&&a.namespaceURI===d){c=M.rootElement;e=k(a,d,"font-face-decls");if(c.fontFaceDecls&&e)for(f=e.firstChild;f;)c.fontFaceDecls.appendChild(f),f=e.firstChild;else e&& +(c.fontFaceDecls=e,b(c,e));e=k(a,d,"automatic-styles");v(e,"document-content");if(c.automaticStyles&&e)for(f=e.firstChild;f;)c.automaticStyles.appendChild(f),f=e.firstChild;else e&&(c.automaticStyles=e,b(c,e));c.body=k(a,d,"body");b(c,c.body)}else D(s.INVALID)}function C(a){a=y(a);var c;a&&("document-meta"===a.localName&&a.namespaceURI===d)&&(c=M.rootElement,c.meta=k(a,d,"meta"),b(c,c.meta))}function P(a){a=y(a);var c;a&&("document-settings"===a.localName&&a.namespaceURI===d)&&(c=M.rootElement,c.settings= +k(a,d,"settings"),b(c,c.settings))}function B(a){a=y(a);var b;if(a&&"manifest"===a.localName&&a.namespaceURI===c)for(b=M.rootElement,b.manifest=a,a=b.manifest.firstChild;a;)a.nodeType===Node.ELEMENT_NODE&&("file-entry"===a.localName&&a.namespaceURI===c)&&(K[a.getAttributeNS(c,"full-path")]=a.getAttributeNS(c,"media-type")),a=a.nextSibling}function J(a){var b=a.shift(),c,d;b?(c=b[0],d=b[1],L.loadAsDOM(c,function(b,c){d(c);b||M.state===s.INVALID||J(a)})):D(s.DONE)}function U(a){var b="";odf.Namespaces.forEachPrefix(function(a, +c){b+=" xmlns:"+a+'="'+c+'"'});return''}function da(){var a=new xmldom.LSSerializer,b=U("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(c,"manifest:file-entry");d.setAttributeNS(c,"manifest:full-path",a);d.setAttributeNS(c,"manifest:media-type",b);return d}function ka(){var a= +runtime.parseXML(''),b=k(a,c,"manifest"),d=new xmldom.LSSerializer,e;for(e in K)K.hasOwnProperty(e)&&b.appendChild(T(e,K[e]));d.filter=new odf.OdfNodeFilter;return'\n'+d.writeToString(a,odf.Namespaces.namespaceMap)}function ca(){var a=new xmldom.LSSerializer,b=U("document-settings");a.filter=new odf.OdfNodeFilter;b+=a.writeToString(M.rootElement.settings,odf.Namespaces.namespaceMap); +return b+""}function W(){var a=odf.Namespaces.namespaceMap,b=new xmldom.LSSerializer,c=p(M.rootElement.automaticStyles,"document-styles"),d=M.rootElement.masterStyles&&M.rootElement.masterStyles.cloneNode(!0),e=U("document-styles");f.removePrefixFromStyleNames(c,r,d);b.filter=new l(d,c);e+=b.writeToString(M.rootElement.fontFaceDecls,a);e+=b.writeToString(M.rootElement.styles,a);e+=b.writeToString(c,a);e+=b.writeToString(d,a);return e+""}function O(){var a= +odf.Namespaces.namespaceMap,b=new xmldom.LSSerializer,c=p(M.rootElement.automaticStyles,"document-content"),d=U("document-content");b.filter=new h(M.rootElement.body,c);d+=b.writeToString(c,a);d+=b.writeToString(M.rootElement.body,a);return d+""}function ba(a,b){runtime.loadXML(a,function(a,c){if(a)b(a);else{var e=y(c);e&&"document"===e.localName&&e.namespaceURI===d?(H(e),D(s.DONE)):D(s.INVALID)}})}function S(){function a(b,c){var f;c||(c=b);f=document.createElementNS(d, +c);e[b]=f;e.appendChild(f)}var b=new core.Zip("",null),c=runtime.byteArrayFromString("application/vnd.oasis.opendocument.text","utf8"),e=M.rootElement,f=document.createElementNS(d,"text");b.save("mimetype",c,!1,new Date);a("meta");a("settings");a("scripts");a("fontFaceDecls","font-face-decls");a("styles");a("automaticStyles","automatic-styles");a("masterStyles","master-styles");a("body");e.body.appendChild(f);D(s.DONE);return b}function Q(){var a,b=new Date;a=runtime.byteArrayFromString(ca(),"utf8"); +L.save("settings.xml",a,!0,b);a=runtime.byteArrayFromString(da(),"utf8");L.save("meta.xml",a,!0,b);a=runtime.byteArrayFromString(W(),"utf8");L.save("styles.xml",a,!0,b);a=runtime.byteArrayFromString(O(),"utf8");L.save("content.xml",a,!0,b);a=runtime.byteArrayFromString(ka(),"utf8");L.save("META-INF/manifest.xml",a,!0,b)}function F(a,b){Q();L.writeAs(a,function(a){b(a)})}var M=this,L,K={},Y;this.onstatereadychange=g;this.rootElement=this.state=this.onchange=null;this.setRootElement=H;this.getContentElement= +function(){var a;Y||(a=M.rootElement.body,Y=a.getElementsByTagNameNS(d,"text")[0]||a.getElementsByTagNameNS(d,"presentation")[0]||a.getElementsByTagNameNS(d,"spreadsheet")[0]);return Y};this.getDocumentType=function(){var a=M.getContentElement();return a&&a.localName};this.getPart=function(b){return new a(b,K[b],M,L)};this.getPartData=function(a,b){L.load(a,b)};this.createByteArray=function(a,b){Q();L.createByteArray(a,b)};this.saveAs=F;this.save=function(a){F(e,a)};this.getUrl=function(){return e}; +this.state=s.LOADING;this.rootElement=function(a){var b=document.createElementNS(a.namespaceURI,a.localName),c;a=new a;for(c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b}(n);L=e?new core.Zip(e,function(a,b){L=b;a?ba(e,function(b){a&&(L.error=a+"\n"+b,D(s.INVALID))}):J([["styles.xml",A],["content.xml",N],["meta.xml",C],["settings.xml",P],["META-INF/manifest.xml",B]])}):S()};odf.OdfContainer.EMPTY=0;odf.OdfContainer.LOADING=1;odf.OdfContainer.DONE=2;odf.OdfContainer.INVALID=3;odf.OdfContainer.SAVING= +4;odf.OdfContainer.MODIFIED=5;odf.OdfContainer.getContainer=function(a){return new odf.OdfContainer(a,null)};return odf.OdfContainer}(); +// Input 34 /* Copyright (C) 2012-2013 KO GmbH @@ -680,40 +718,14 @@ function(b){return(b=e(b))?a(b):void 0};this.applyStyle=function(a,c,e){var l=od @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("core.DomUtils");runtime.loadClass("odf.OdfContainer");runtime.loadClass("odf.Formatting");runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.FontLoader");runtime.loadClass("odf.Style2CSS");runtime.loadClass("odf.OdfUtils"); -odf.OdfCanvas=function(){function h(){function a(d){c=!0;runtime.setTimeout(function(){try{d()}catch(e){runtime.log(e)}c=!1;0 text|list-item > *:first-child:before {";if(E=A.getAttributeNS(v,"style-name")){A=h[E];B=z.getFirstNonWhitespaceChild(A);A=void 0;if("list-level-style-number"===B.localName){A=B.getAttributeNS(p,"num-format");E=B.getAttributeNS(p,"num-suffix");var H="",H={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"}, -I=void 0,I=B.getAttributeNS(p,"num-prefix")||"",I=H.hasOwnProperty(A)?I+(" counter(list, "+H[A]+")"):A?I+("'"+A+"';"):I+" ''";E&&(I+=" '"+E+"'");A=H="content: "+I+";"}else"list-level-style-image"===B.localName?A="content: none;":"list-level-style-bullet"===B.localName&&(A="content: '"+B.getAttributeNS(v,"bullet-char")+"';");B=A}if(w){for(A=n[w];A;)w=A,A=n[w];K+="counter-increment:"+w+";";B?(B=B.replace("list",w),K+=B):K+="content:counter("+w+");"}else w="",B?(B=B.replace("list",x),K+=B):K+="content: counter("+ -x+");",K+="counter-increment:"+x+";",g.insertRule("text|list#"+x+" {counter-reset:"+x+"}",g.cssRules.length);K+="}";n[x]=w;K&&g.insertRule(K,g.cssRules.length)}f.insertBefore(D,f.firstChild);C();if(!c&&(g=[S],$.hasOwnProperty("statereadychange")))for(f=$.statereadychange,B=0;B + Copyright (C) 2012-2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -745,8 +757,85 @@ odf.CommandLineTools=function(){this.roundTrip=function(h,m,f){new odf.OdfContai @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,n){}; +runtime.loadClass("core.Utils");runtime.loadClass("odf.Namespaces");runtime.loadClass("odf.OdfContainer");runtime.loadClass("odf.StyleInfo");runtime.loadClass("odf.OdfUtils");runtime.loadClass("odf.TextStyleApplicator"); +odf.Formatting=function(){function k(a,b){Object.keys(b).forEach(function(c){try{a[c]=b[c].constructor===Object?k(a[c],b[c]):b[c]}catch(d){a[c]=b[c]}});return a}function g(a,b,d){var e,f;d=d||[c.rootElement.automaticStyles,c.rootElement.styles];for(e=d.shift();e;){for(e=e.firstChild;e;){if(e.nodeType===Node.ELEMENT_NODE&&(f=e.getAttributeNS(r,"name"),e.namespaceURI===r&&"style"===e.localName&&e.getAttributeNS(r,"family")===b&&f===a||"list-style"===b&&e.namespaceURI===m&&"list-style"===e.localName&& +f===a||"data"===b&&e.namespaceURI===q&&f===a))return e;e=e.nextSibling}e=d.shift()}return null}function l(a){for(var b={},c=a.firstChild;c;){if(c.nodeType===Node.ELEMENT_NODE&&c.namespaceURI===r)for(b[c.nodeName]={},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/ +*/ +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 k(){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(ja=x.getAttributeNS(y,"style-name")){x=q[ja];B=P.getFirstNonWhitespaceChild(x);x=void 0;if("list-level-style-number"===B.localName){x=B.getAttributeNS(z,"num-format");ja=B.getAttributeNS(z, +"num-suffix");var F="",F={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"},E=void 0,E=B.getAttributeNS(z,"num-prefix")||"",E=F.hasOwnProperty(x)?E+(" counter(list, "+F[x]+")"):x?E+("'"+x+"';"):E+" ''";ja&&(E+=" '"+ja+"'");x=F="content: "+E+";"}else"list-level-style-image"===B.localName?x="content: none;":"list-level-style-bullet"===B.localName&&(x="content: '"+B.getAttributeNS(y,"bullet-char")+"';");B=x}if(fa){for(x=k[fa];x;)fa=x,x=k[fa];aa+="counter-increment:"+fa+";"; +B?(B=B.replace("list",fa),aa+=B):aa+="content:counter("+fa+");"}else fa="",B?(B=B.replace("list",A),aa+=B):aa+="content: counter("+A+");",aa+="counter-increment:"+A+";",h.insertRule("text|list#"+A+" {counter-reset:"+A+"}",h.cssRules.length);aa+="}";k[A]=fa;aa&&h.insertRule(aa,h.cssRules.length)}m.insertBefore(J,m.firstChild);v();D(g);if(!d&&(g=[K],Z.hasOwnProperty("statereadychange")))for(h=Z.statereadychange,m=0;m @@ -781,9 +870,45 @@ ops.Server=function(){};ops.Server.prototype.connect=function(h,m){};ops.Server. @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.NowjsServer=function(){var h=this,m;this.getNowObject=function(){return m};this.connect=function(f,n){function h(){"unavailable"===m.networkStatus?(runtime.log("connection to server unavailable."),n("unavailable")):"ready"!==m.networkStatus?e>f?(runtime.log("connection to server timed out."),n("timeout")):(e+=100,runtime.getWindow().setTimeout(h,100)):(runtime.log("connection to collaboration server established."),n("ready"))}var e=0;m||(m=runtime.getVariable("now"),void 0===m&&(m={networkStatus:"unavailable"}), -h())};this.networkStatus=function(){return m?m.networkStatus:"unavailable"};this.login=function(f,n,h,e){m?m.login(f,n,h,e):e("Not connected to server")};this.createOperationRouter=function(f,n){return new ops.NowjsOperationRouter(f,n,h)};this.createUserModel=function(){return new ops.NowjsUserModel(h)}}; -// Input 37 +ops.Server=function(){};ops.Server.prototype.connect=function(k,g){};ops.Server.prototype.networkStatus=function(){};ops.Server.prototype.login=function(k,g,l,h){};ops.Server.prototype.getGenesisUrl=function(k){}; +// Input 39 +/* + + Copyright (C) 2013 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ +ops.NowjsServer=function(){var k=this,g;this.getNowObject=function(){return g};this.getGenesisUrl=function(g){return"/session/"+g+"/genesis"};this.connect=function(l,h){function b(){"unavailable"===g.networkStatus?(runtime.log("connection to server unavailable."),h("unavailable")):"ready"!==g.networkStatus?n>l?(runtime.log("connection to server timed out."),h("timeout")):(n+=100,runtime.getWindow().setTimeout(b,100)):(runtime.log("connection to collaboration server established."),h("ready"))}var n= +0;g||(g=runtime.getVariable("now"),void 0===g&&(g={networkStatus:"unavailable"}),b())};this.networkStatus=function(){return g?g.networkStatus:"unavailable"};this.login=function(l,h,b,n){g?g.login(l,h,b,n):n("Not connected to server")};this.createOperationRouter=function(g,h){return new ops.NowjsOperationRouter(g,h,k)};this.createUserModel=function(){return new ops.NowjsUserModel(k)}}; +// Input 40 /* Copyright (C) 2013 KO GmbH @@ -819,120 +944,9 @@ h())};this.networkStatus=function(){return m?m.networkStatus:"unavailable"};this @source: http://gitorious.org/webodf/webodf/ */ runtime.loadClass("core.Base64");runtime.loadClass("core.ByteArrayWriter"); -ops.PullBoxServer=function(h){function m(e,a){var g=new XMLHttpRequest,d=new core.ByteArrayWriter("utf8");runtime.log("Sending message to server: "+e);d.appendString(e);d=d.getByteArray();g.open("POST",h.url,!0);g.onreadystatechange=function(){4===g.readyState&&((200>g.status||300<=g.status)&&0===g.status&&runtime.log("Status "+String(g.status)+": "+g.responseText||g.statusText),a(g.responseText))};d=d.buffer&&!g.sendAsBinary?d.buffer:runtime.byteArrayToString(d,"binary");try{g.sendAsBinary?g.sendAsBinary(d): -g.send(d)}catch(b){runtime.log("Problem with calling server: "+b+" "+d),a(b.message)}}var f=this,n,q=new core.Base64;h=h||{};h.url=h.url||"/WSER";this.call=m;this.getBase64=function(){return q};this.getToken=function(){return n};this.connect=function(e,a){a("ready")};this.networkStatus=function(){return"ready"};this.login=function(e,a,g,d){m("login:"+q.toBase64(e)+":"+q.toBase64(a),function(a){var e=runtime.fromJson(a);runtime.log("Login reply: "+a);e.hasOwnProperty("token")?(n=e.token,runtime.log("Caching token: "+ -f.getToken()),g(e)):d(a)})};this.createOperationRouter=function(e,a){return new ops.PullBoxOperationRouter(e,a,f)};this.createUserModel=function(){return new ops.PullBoxUserModel(f)}}; -// Input 38 -/* - - Copyright (C) 2012-2013 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -ops.Operation=function(){};ops.Operation.prototype.init=function(h){};ops.Operation.prototype.transform=function(h,m){};ops.Operation.prototype.execute=function(h){};ops.Operation.prototype.spec=function(){}; -// Input 39 -/* - - Copyright (C) 2012-2013 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -ops.OpAddCursor=function(){var h=this,m,f;this.init=function(n){m=n.memberid;f=n.timestamp};this.transform=function(f,m){return[h]};this.execute=function(f){var h=f.getCursor(m);if(h)return!1;h=new ops.OdtCursor(m,f);f.addCursor(h);f.emit(ops.OdtDocument.signalCursorAdded,h);return!0};this.spec=function(){return{optype:"AddCursor",memberid:m,timestamp:f}}}; -// Input 40 -/* - - Copyright (C) 2012-2013 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -runtime.loadClass("odf.OdfUtils"); -ops.OpApplyStyle=function(){function h(a){var d=0<=e?q+e:q,g=a.getIteratorAtPosition(0<=e?q:q+e),d=e?a.getIteratorAtPosition(d):g;a=a.getDOM().createRange();a.setStart(g.container(),g.unfilteredDomOffset());a.setEnd(d.container(),d.unfilteredDomOffset());return a}function m(a){var e=a.commonAncestorContainer,k=[];for(e.nodeType===Node.ELEMENT_NODE&&(k=d.getElementsByTagNameNS(e,"urn:oasis:names:tc:opendocument:xmlns:text:1.0","p").concat(d.getElementsByTagNameNS(e,"urn:oasis:names:tc:opendocument:xmlns:text:1.0", -"h")));e&&!g.isParagraph(e);)e=e.parentNode;e&&k.push(e);return k.filter(function(d){var c=d.nodeType===Node.TEXT_NODE?d.length:d.childNodes.length;return 0>=a.comparePoint(d,0)&&0<=a.comparePoint(d,c)})}var f,n,q,e,a,g=new odf.OdfUtils,d=new core.DomUtils;this.init=function(b){f=b.memberid;n=b.timestamp;q=parseInt(b.position,10);e=parseInt(b.length,10);a=b.info};this.transform=function(a,d){return null};this.execute=function(b){var d=h(b),e=m(d);b.getFormatting().applyStyle(f,d,a);d.detach();b.getOdfCanvas().refreshCSS(); -e.forEach(function(a){b.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a,memberId:f,timeStamp:n})});return!0};this.spec=function(){return{optype:"ApplyStyle",memberid:f,timestamp:n,position:q,length:e,info:a}}}; +ops.PullBoxServer=function(k){function g(b,a){var f=new XMLHttpRequest,d=new core.ByteArrayWriter("utf8");"object"===typeof b&&(b=JSON.stringify(b));runtime.log("Sending message to server: "+b);d.appendString(b);d=d.getByteArray();f.open("POST",k.url,!0);f.onreadystatechange=function(){4===f.readyState&&((200>f.status||300<=f.status)&&0===f.status&&runtime.log("Status "+String(f.status)+": "+f.responseText||f.statusText),a(f.responseText))};d=d.buffer&&!f.sendAsBinary?d.buffer:runtime.byteArrayToString(d, +"binary");try{f.sendAsBinary?f.sendAsBinary(d):f.send(d)}catch(c){runtime.log("Problem with calling server: "+c+" "+d),a(c.message)}}var l=this,h,b=new core.Base64;k=k||{};k.url=k.url||"/WSER";this.getGenesisUrl=function(b){return"/session/"+b+"/genesis"};this.call=g;this.getBase64=function(){return b};this.getToken=function(){return h};this.setToken=function(b){h=b};this.connect=function(b,a){a("ready")};this.networkStatus=function(){return"ready"};this.login=function(n,a,f,d){g("login:"+b.toBase64(n)+ +":"+b.toBase64(a),function(a){var b=runtime.fromJson(a);runtime.log("Login reply: "+a);b.hasOwnProperty("token")?(h=b.token,runtime.log("Caching token: "+l.getToken()),f(b)):d(a)})}}; // Input 41 /* @@ -968,7 +982,7 @@ e.forEach(function(a){b.emit(ops.OdtDocument.signalParagraphChanged,{paragraphEl @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.OpRemoveCursor=function(){var h=this,m,f;this.init=function(n){m=n.memberid;f=n.timestamp};this.transform=function(f,q){var e=f.spec();return"RemoveCursor"===e.optype&&e.memberid===m?[]:[h]};this.execute=function(f){return f.removeCursor(m)?!0:!1};this.spec=function(){return{optype:"RemoveCursor",memberid:m,timestamp:f}}}; +ops.Operation=function(){};ops.Operation.prototype.init=function(k){};ops.Operation.prototype.transform=function(k,g){};ops.Operation.prototype.execute=function(k){};ops.Operation.prototype.spec=function(){}; // Input 42 /* @@ -1004,15 +1018,45 @@ ops.OpRemoveCursor=function(){var h=this,m,f;this.init=function(n){m=n.memberid; @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.OpMoveCursor=function(){var h=this,m,f,n,q;this.init=function(e){m=e.memberid;f=e.timestamp;n=parseInt(e.position,10);q=void 0!==e.length?parseInt(e.length,10):0};this.merge=function(e){return"MoveCursor"===e.optype&&e.memberid===m?(n=e.position,q=e.length,f=e.timestamp,!0):!1};this.transform=function(e,a){var g=e.spec(),d=g.optype,b=[h];"RemoveText"===d?g.position+g.length<=n?n-=g.length:g.positionb?-g.countBackwardSteps(-b,d):0;a.move(b);q&&(d=0q?-g.countBackwardSteps(-q,d):0,a.move(d,!0));e.emit(ops.OdtDocument.signalCursorMoved,a);return!0};this.spec=function(){return{optype:"MoveCursor",memberid:m, -timestamp:f,position:n,length:q}}}; +ops.OpAddCursor=function(){var k=this,g,l;this.init=function(h){g=h.memberid;l=h.timestamp};this.transform=function(g,b){return[k]};this.execute=function(h){var b=h.getCursor(g);if(b)return!1;b=new ops.OdtCursor(g,h);h.addCursor(b);h.emit(ops.OdtDocument.signalCursorAdded,b);return!0};this.spec=function(){return{optype:"AddCursor",memberid:g,timestamp:l}}}; // Input 43 -ops.OpInsertTable=function(){function h(a,b){var c;if(1===r.length)c=r[0];else if(3===r.length)switch(a){case 0:c=r[0];break;case q-1:c=r[2];break;default:c=r[1]}else c=r[a];if(1===c.length)return c[0];if(3===c.length)switch(b){case 0:return c[0];case e-1:return c[2];default:return c[1]}return c[b]}var m=this,f,n,q,e,a,g,d,b,r;this.init=function(k){f=k.memberid;n=k.timestamp;a=parseInt(k.position,10);q=parseInt(k.initialRows,10);e=parseInt(k.initialColumns,10);g=k.tableName;d=k.tableStyleName;b=k.tableColumnStyleName; -r=k.tableCellStyleMatrix};this.transform=function(b,d){var c=b.spec(),e=c.optype,g=[m];if("InsertTable"===e)g=null;else if("SplitParagraph"===e)if(c.position + + @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.DomUtils");runtime.loadClass("odf.OdfUtils"); +gui.StyleHelper=function(k){function g(b,g,a){var f=!0,d;b.collapsed?(d=b.startContainer,d.hasChildNodes()&&b.startOffset=a.textNode.length?null:a.textNode.splitText(a.offset));for(a=a.textNode;a!==d;)if(a=a.parentNode,b=a.cloneNode(!1),k){for(h&&b.appendChild(h);k.nextSibling;)b.appendChild(k.nextSibling);a.parentNode.insertBefore(b, -a.nextSibling);k=a;h=b}else a.parentNode.insertBefore(b,a),k=b,h=a;q.isListItem(h)&&(h=h.childNodes[0]);e.fixCursorPositions(m);e.getOdfCanvas().refreshSize();e.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:g,memberId:m,timeStamp:f});e.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:h,memberId:m,timeStamp:f});return!0};this.spec=function(){return{optype:"SplitParagraph",memberid:m,timestamp:f,position:n}}}; +ops.OpMoveCursor=function(){var k=this,g,l,h,b;this.init=function(n){g=n.memberid;l=n.timestamp;h=parseInt(n.position,10);b=void 0!==n.length?parseInt(n.length,10):0};this.merge=function(n){return"MoveCursor"===n.optype&&n.memberid===g?(h=n.position,b=n.length,l=n.timestamp,!0):!1};this.transform=function(n,a){var f=n.spec(),d=f.optype,c=h+b,l=[k];"RemoveText"===d?(d=f.position+f.length,d<=h?h-=f.length:f.positionh&&f.positionh&&f.positionc?-f.countBackwardSteps(-c,d):0;a.move(c);b&&(d=0b?-f.countBackwardSteps(-b, +d):0,a.move(d,!0));n.emit(ops.OdtDocument.signalCursorMoved,a);return!0};this.spec=function(){return{optype:"MoveCursor",memberid:g,timestamp:l,position:h,length:b}}}; // Input 47 -/* - - Copyright (C) 2012-2013 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -ops.OpSetParagraphStyle=function(){var h=this,m,f,n,q;this.init=function(e){m=e.memberid;f=e.timestamp;n=e.position;q=e.styleName};this.transform=function(e,a){var g=e.spec();"DeleteParagraphStyle"===g.optype&&g.styleName===q&&(q="");return[h]};this.execute=function(e){var a;if(a=e.getPositionInTextNode(n))if(a=e.getParagraphElement(a.textNode))return""!==q?a.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","text:style-name",q):a.removeAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0", -"style-name"),e.getOdfCanvas().refreshSize(),e.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a,timeStamp:f,memberId:m}),!0;return!1};this.spec=function(){return{optype:"SetParagraphStyle",memberid:m,timestamp:f,position:n,styleName:q}}}; +ops.OpInsertTable=function(){function k(a,c){var d;if(1===t.length)d=t[0];else if(3===t.length)switch(a){case 0:d=t[0];break;case b-1:d=t[2];break;default:d=t[1]}else d=t[a];if(1===d.length)return d[0];if(3===d.length)switch(c){case 0:return d[0];case n-1:return d[2];default:return d[1]}return d[c]}var g=this,l,h,b,n,a,f,d,c,t;this.init=function(e){l=e.memberid;h=e.timestamp;a=parseInt(e.position,10);b=parseInt(e.initialRows,10);n=parseInt(e.initialColumns,10);f=e.tableName;d=e.tableStyleName;c=e.tableColumnStyleName; +t=e.tableCellStyleMatrix};this.transform=function(b,c){var d=b.spec(),f=d.optype,h=[g];if("InsertTable"===f)h=null;else if("SplitParagraph"===f)if(d.position=a.textNode.length?null:a.textNode.splitText(a.offset));for(a=a.textNode;a!==d;)if(a=a.parentNode,c=a.cloneNode(!1),e){for(k&&c.appendChild(k);e.nextSibling;)c.appendChild(e.nextSibling); +a.parentNode.insertBefore(c,a.nextSibling);e=a;k=c}else a.parentNode.insertBefore(c,a),e=c,k=a;b.isListItem(k)&&(k=k.childNodes[0]);n.fixCursorPositions(g);n.getOdfCanvas().refreshSize();n.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:f,memberId:g,timeStamp:l});n.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:k,memberId:g,timeStamp:l});n.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"SplitParagraph",memberid:g,timestamp:l,position:h}}}; // Input 51 /* @@ -1322,114 +1329,9 @@ n);return!0};this.spec=function(){return{optype:"DeleteParagraphStyle",memberid: @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpApplyStyle");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");runtime.loadClass("ops.OpInsertTable");runtime.loadClass("ops.OpInsertText");runtime.loadClass("ops.OpRemoveText");runtime.loadClass("ops.OpSplitParagraph");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("ops.OpUpdateParagraphStyle");runtime.loadClass("ops.OpCloneParagraphStyle");runtime.loadClass("ops.OpDeleteParagraphStyle"); -ops.OperationFactory=function(){function h(f){return function(){return new f}}var m;this.register=function(f,h){m[f]=h};this.create=function(f){var h=null,q=m[f.optype];q&&(h=q(f),h.init(f));return h};m={AddCursor:h(ops.OpAddCursor),ApplyStyle:h(ops.OpApplyStyle),InsertTable:h(ops.OpInsertTable),InsertText:h(ops.OpInsertText),RemoveText:h(ops.OpRemoveText),SplitParagraph:h(ops.OpSplitParagraph),SetParagraphStyle:h(ops.OpSetParagraphStyle),UpdateParagraphStyle:h(ops.OpUpdateParagraphStyle),CloneParagraphStyle:h(ops.OpCloneParagraphStyle), -DeleteParagraphStyle:h(ops.OpDeleteParagraphStyle),MoveCursor:h(ops.OpMoveCursor),RemoveCursor:h(ops.OpRemoveCursor)}}; +ops.OpSetParagraphStyle=function(){var k=this,g,l,h,b;this.init=function(n){g=n.memberid;l=n.timestamp;h=n.position;b=n.styleName};this.transform=function(g,a){var f=g.spec();"DeleteParagraphStyle"===f.optype&&f.styleName===b&&(b="");return[k]};this.execute=function(n){var a;if(a=n.getPositionInTextNode(h))if(a=n.getParagraphElement(a.textNode))return""!==b?a.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","text:style-name",b):a.removeAttributeNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0", +"style-name"),n.getOdfCanvas().refreshSize(),n.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:a,timeStamp:l,memberId:g}),n.getOdfCanvas().rerenderAnnotations(),!0;return!1};this.spec=function(){return{optype:"SetParagraphStyle",memberid:g,timestamp:l,position:h,styleName:b}}}; // Input 52 -runtime.loadClass("core.Cursor");runtime.loadClass("core.PositionIterator");runtime.loadClass("core.PositionFilter");runtime.loadClass("core.LoopWatchDog");runtime.loadClass("odf.OdfUtils"); -gui.SelectionMover=function(h,m){function f(){c.setUnfilteredPosition(h.getNode(),0);return c}function n(a,b,c){var d;c.setStart(a,b);d=c.getClientRects()[0];if(!d)if(d={},a.childNodes[b-1]){c.setStart(a,b-1);c.setEnd(a,b);b=c.getClientRects()[0];if(!b){for(c=b=0;a&&a.nodeType===Node.ELEMENT_NODE;)b+=a.offsetLeft-a.scrollLeft,c+=a.offsetTop-a.scrollTop,a=a.parentNode;b={top:c,left:b}}d.top=b.top;d.left=b.right;d.bottom=b.bottom}else a.nodeType===Node.TEXT_NODE?(a.previousSibling&&(d=a.previousSibling.getClientRects()[0]), -d||(c.setStart(a,0),c.setEnd(a,b),d=c.getClientRects()[0])):d=a.getClientRects()[0];return{top:d.top,left:d.left,bottom:d.bottom}}function q(a,b,c){var d=a,e=f(),g,l=m.ownerDocument.createRange(),k=h.getSelectedRange()?h.getSelectedRange().cloneRange():m.ownerDocument.createRange(),q;for(g=n(h.getNode(),0,l);0a?-1:1;for(a=Math.abs(a);0k?h.previousPosition():h.nextPosition());)if(M.check(),1===l.acceptPosition(h)&&(t+=1,q=h.container(),T=n(q,h.unfilteredDomOffset(),W),T.top!==V)){if(T.top!== -U&&U!==V)break;U=T.top;T=Math.abs(ca-T.left);if(null===r||Ta?(g=c.previousPosition,k=-1):(g=c.nextPosition,k=1);for(h=n(c.container(),c.unfilteredDomOffset(),t);g.call(c);)if(b.acceptPosition(c)===NodeFilter.FILTER_ACCEPT){if(l.getParagraphElement(c.getCurrentNode())!== -d)break;q=n(c.container(),c.unfilteredDomOffset(),t);if(q.bottom!==h.bottom&&(h=q.top>=h.top&&q.bottomh.bottom,!h))break;e+=k;h=q}t.detach();return e}function r(a,b){for(var c=0,d;a.parentNode!==b;)runtime.assert(null!==a.parentNode,"parent is null"),a=a.parentNode;for(d=b.firstChild;d!==a;)c+=1,d=d.nextSibling;return c}function k(a,b,c){runtime.assert(null!==a,"SelectionMover.countStepsToPosition called with element===null");var d=f(),e=d.container(),g=d.unfilteredDomOffset(), -l=0,k=new core.LoopWatchDog(1E3);d.setUnfilteredPosition(a,b);a=d.container();runtime.assert(Boolean(a),"SelectionMover.countStepsToPosition: positionIterator.container() returned null");b=d.unfilteredDomOffset();d.setUnfilteredPosition(e,g);var e=a,g=b,h=d.container(),m=d.unfilteredDomOffset();if(e===h)e=m-g;else{var n=e.compareDocumentPosition(h);2===n?n=-1:4===n?n=1:10===n?(g=r(e,h),n=ge)for(;d.nextPosition()&&(k.check(),1===c.acceptPosition(d)&&(l+=1),d.container()!== -a||d.unfilteredDomOffset()!==b););else if(0 - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");runtime.loadClass("ops.OpInsertTable");runtime.loadClass("ops.OpInsertText");runtime.loadClass("ops.OpRemoveText");runtime.loadClass("ops.OpSplitParagraph");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("ops.OpUpdateParagraphStyle");runtime.loadClass("ops.OpCloneParagraphStyle");runtime.loadClass("ops.OpDeleteParagraphStyle"); -ops.OperationTransformer=function(){function h(f,n){for(var q,e,a,g=[],d=[];0=e&&(g=-n.movePointBackward(-e,a));f.handleUpdate();return g};this.handleUpdate=function(){};this.getStepCounter=function(){return n.getStepCounter()};this.getMemberId=function(){return h};this.getNode=function(){return q.getNode()};this.getAnchorNode=function(){return q.getAnchorNode()};this.getSelectedRange=function(){return q.getSelectedRange()}; -this.getOdtDocument=function(){return m};q=new core.Cursor(m.getDOM(),h);n=new gui.SelectionMover(q,m.getRootNode())}; -// Input 55 -/* - - 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.EditInfo=function(h,m){function f(){var e=[],a;for(a in q)q.hasOwnProperty(a)&&e.push({memberid:a,time:q[a].time});e.sort(function(a,d){return a.time-d.time});return e}var n,q={};this.getNode=function(){return n};this.getOdtDocument=function(){return m};this.getEdits=function(){return q};this.getSortedEdits=function(){return f()};this.addEdit=function(e,a){var g,d=e.split("___")[0];if(!q[e])for(g in q)if(q.hasOwnProperty(g)&&g.split("___")[0]===d){delete q[g];break}q[e]={time:a}};this.clearEdits= -function(){q={}};n=m.getDOM().createElementNS("urn:webodf:names:editinfo","editinfo");h.insertBefore(n,h.firstChild)}; -// Input 56 -gui.Avatar=function(h,m){var f=this,n,q,e;this.setColor=function(a){q.style.borderColor=a};this.setImageUrl=function(a){f.isVisible()?q.src=a:e=a};this.isVisible=function(){return"block"===n.style.display};this.show=function(){e&&(q.src=e,e=void 0);n.style.display="block"};this.hide=function(){n.style.display="none"};this.markAsFocussed=function(a){n.className=a?"active":""};(function(){var a=h.ownerDocument,e=a.documentElement.namespaceURI;n=a.createElementNS(e,"div");q=a.createElementNS(e,"img"); -q.width=64;q.height=64;n.appendChild(q);n.style.width="64px";n.style.height="70px";n.style.position="absolute";n.style.top="-80px";n.style.left="-34px";n.style.display=m?"block":"none";h.appendChild(n)})()}; -// Input 57 -runtime.loadClass("gui.Avatar");runtime.loadClass("ops.OdtCursor"); -gui.Caret=function(h,m){function f(){g&&a.parentNode&&!d&&(d=!0,q.style.borderColor="transparent"===q.style.borderColor?b:"transparent",runtime.setTimeout(function(){d=!1;f()},500))}function n(a){var b;if("string"===typeof a){if(""===a)return 0;b=/^(\d+)(\.\d+)?px$/.exec(a);runtime.assert(null!==b,"size ["+a+"] does not have unit px.");return parseFloat(b[1])}return a}var q,e,a,g=!1,d=!1,b="";this.setFocus=function(){g=!0;e.markAsFocussed(!0);f()};this.removeFocus=function(){g=!1;e.markAsFocussed(!1); -q.style.borderColor=b};this.setAvatarImageUrl=function(a){e.setImageUrl(a)};this.setColor=function(a){b!==a&&(b=a,"transparent"!==q.style.borderColor&&(q.style.borderColor=b),e.setColor(b))};this.getCursor=function(){return h};this.getFocusElement=function(){return q};this.toggleHandleVisibility=function(){e.isVisible()?e.hide():e.show()};this.showHandle=function(){e.show()};this.hideHandle=function(){e.hide()};this.ensureVisible=function(){var a,b,d,c,e,g,f,p=h.getOdtDocument().getOdfCanvas().getElement().parentNode; -e=f=q;d=runtime.getWindow();runtime.assert(null!==d,"Expected to be run in an environment which has a global window, like a browser.");do{e=e.parentElement;if(!e)break;g=d.getComputedStyle(e,null)}while("block"!==g.display);g=e;e=c=0;if(g&&p){b=!1;do{d=g.offsetParent;for(a=g.parentNode;a!==d;){if(a===p){a=g;var m=p,y=0;b=0;var v=void 0,x=runtime.getWindow();for(runtime.assert(null!==x,"Expected to be run in an environment which has a global window, like a browser.");a&&a!==m;)v=x.getComputedStyle(a, -null),y+=n(v.marginLeft)+n(v.borderLeftWidth)+n(v.paddingLeft),b+=n(v.marginTop)+n(v.borderTopWidth)+n(v.paddingTop),a=a.parentElement;a=y;c+=a;e+=b;b=!0;break}a=a.parentNode}if(b)break;c+=n(g.offsetLeft);e+=n(g.offsetTop);g=d}while(g&&g!==p);d=c;c=e}else c=d=0;d+=f.offsetLeft;c+=f.offsetTop;e=d-5;g=c-5;d=d+f.scrollWidth-1+5;f=c+f.scrollHeight-1+5;gp.scrollTop+p.clientHeight-1&&(p.scrollTop=f-p.clientHeight+1);ep.scrollLeft+p.clientWidth- -1&&(p.scrollLeft=d-p.clientWidth+1)};(function(){var b=h.getOdtDocument().getDOM();q=b.createElementNS(b.documentElement.namespaceURI,"span");a=h.getNode();a.appendChild(q);e=new gui.Avatar(a,m)})()}; -// Input 58 -runtime.loadClass("core.EventNotifier"); -gui.ClickHandler=function(){function h(){f=0;n=null}var m,f=0,n=null,q=new core.EventNotifier([gui.ClickHandler.signalSingleClick,gui.ClickHandler.signalDoubleClick,gui.ClickHandler.signalTripleClick]);this.subscribe=function(e,a){q.subscribe(e,a)};this.handleMouseUp=function(e){var a=runtime.getWindow();n&&n.x===e.screenX&&n.y===e.screenY?(f+=1,1===f?q.emit(gui.ClickHandler.signalSingleClick,void 0):2===f?q.emit(gui.ClickHandler.signalDoubleClick,void 0):3===f&&(a.clearTimeout(m),q.emit(gui.ClickHandler.signalTripleClick, -void 0),h())):(q.emit(gui.ClickHandler.signalSingleClick,void 0),f=1,n={x:e.screenX,y:e.screenY},a.clearTimeout(m),m=a.setTimeout(h,400))}};gui.ClickHandler.signalSingleClick="click";gui.ClickHandler.signalDoubleClick="doubleClick";gui.ClickHandler.signalTripleClick="tripleClick";(function(){return gui.ClickHandler})(); -// Input 59 /* Copyright (C) 2012-2013 KO GmbH @@ -1464,36 +1366,16 @@ void 0),h())):(q.emit(gui.ClickHandler.signalSingleClick,void 0),f=1,n={x:e.scre @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -gui.KeyboardHandler=function(){function h(f,e){e||(e=e.None);return f+":"+e}var m=gui.KeyboardHandler.Modifier,f=null,n={};this.setDefault=function(h){f=h};this.bind=function(f,e,a){f=h(f,e);runtime.assert(!1===n.hasOwnProperty(f),"tried to overwrite the callback handler of key combo: "+f);n[f]=a};this.unbind=function(f,e){var a=h(f,e);delete n[a]};this.reset=function(){f=null;n={}};this.handleEvent=function(q){var e=q.keyCode,a=m.None;q.metaKey&&(a|=m.Meta);q.ctrlKey&&(a|=m.Ctrl);q.altKey&&(a|=m.Alt); -q.shiftKey&&(a|=m.Shift);e=h(e,a);e=n[e];a=!1;e?a=e():null!==f&&(a=f(q));a&&(q.preventDefault?q.preventDefault():q.returnValue=!1)}};gui.KeyboardHandler.Modifier={None:0,Meta:1,Ctrl:2,Alt:4,Shift:8,MetaShift:9,CtrlShift:10,AltShift:12};gui.KeyboardHandler.KeyCode={Backspace:8,Enter:13,End:35,Home:36,Left:37,Up:38,Right:39,Down:40,Delete:46,Z:90};(function(){return gui.KeyboardHandler})(); -// Input 60 -gui.Clipboard=function(){this.setDataFromRange=function(h,m){var f=!0,n,q=h.clipboardData,e=runtime.getWindow(),a,g;!q&&e&&(q=e.clipboardData);q?(e=new XMLSerializer,a=runtime.getDOMImplementation().createDocument("","",null),n=a.importNode(m.cloneContents(),!0),g=a.createElement("span"),g.appendChild(n),a.appendChild(g),n=q.setData("text/plain",m.toString()),f=f&&n,n=q.setData("text/html",e.serializeToString(a)),f=f&&n,h.preventDefault()):f=!1;return f}};(function(){return gui.Clipboard})(); -// Input 61 -runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");runtime.loadClass("ops.OpInsertText");runtime.loadClass("ops.OpRemoveText");runtime.loadClass("ops.OpSplitParagraph");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("gui.ClickHandler");runtime.loadClass("gui.KeyboardHandler");runtime.loadClass("gui.Clipboard"); -gui.SessionController=function(){gui.SessionController=function(h,m){function f(a,b,c,d){var e="on"+b,g=!1;a.attachEvent&&(g=a.attachEvent(e,c));!g&&a.addEventListener&&(a.addEventListener(b,c,!1),g=!0);g&&!d||!a.hasOwnProperty(e)||(a[e]=c)}function n(a,b,c){var d="on"+b;a.detachEvent&&a.detachEvent(d,c);a.removeEventListener&&a.removeEventListener(b,c,!1);a[d]===c&&(a[d]=null)}function q(a){a.preventDefault?a.preventDefault():a.returnValue=!1}function e(a,b){var c=new ops.OpMoveCursor;c.init({memberid:m, -position:a,length:b||0});return c}function a(a,b){var c=gui.SelectionMover.createPositionIterator(w.getRootNode()),d=w.getOdfCanvas().getElement(),e;if(e=a){for(;e!==d&&!("urn:webodf:names:cursor"===e.namespaceURI&&"cursor"===e.localName||"urn:webodf:names:editinfo"===e.namespaceURI&&"editinfo"===e.localName);)if(e=e.parentNode,!e)return;e!==d&&a!==e&&(a=e.parentNode,b=Array.prototype.indexOf.call(a.childNodes,e));c.setUnfilteredPosition(a,b);return w.getDistanceFromCursor(m,c.container(),c.unfilteredDomOffset())}} -function g(){var b=runtime.getWindow().getSelection(),c=w.getCursorPosition(m),d;d=a(b.anchorNode,b.anchorOffset);b=a(b.focusNode,b.focusOffset);if(0!==b||0!==d)c=e(c+d,b-d),h.enqueue(c)}function d(){var a=gui.SelectionMover.createPositionIterator(w.getRootNode()),b=w.getCursor(m).getNode(),c=w.getCursorPosition(m),d=/[A-Za-z0-9]/,g=0,f=0,l,k,p;a.setUnfilteredPosition(b,0);if(a.previousPosition()&&(l=a.getCurrentNode(),l.nodeType===Node.TEXT_NODE))for(k=l.data.length-1;0<=k;k-=1)if(p=l.data[k],d.test(p))g-= -1;else break;a.setUnfilteredPosition(b,0);if(a.nextPosition()&&(l=a.getCurrentNode(),l.nodeType===Node.TEXT_NODE))for(k=0;ka.length&&(a.position+=a.length,a.length=-a.length);return a}function U(a){var b=new ops.OpRemoveText;b.init({memberid:m,position:a.position,length:a.length});return b}function W(){var a=ca(w.getCursorSelection(m)),b=null;0===a.length?0 + Copyright (C) 2012-2013 KO GmbH @licstart The JavaScript code in this page is free software: you can redistribute it @@ -1525,11 +1407,267 @@ ops.UserModel=function(){};ops.UserModel.prototype.getUserDetailsAndUpdates=func @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.TrivialUserModel=function(){var h={bob:{memberid:"bob",fullname:"Bob Pigeon",color:"red",imageurl:"avatar-pigeon.png"},alice:{memberid:"alice",fullname:"Alice Bee",color:"green",imageurl:"avatar-flower.png"},you:{memberid:"you",fullname:"I, Robot",color:"blue",imageurl:"avatar-joe.png"}};this.getUserDetailsAndUpdates=function(m,f){var n=m.split("___")[0];f(m,h[n]||null)};this.unsubscribeUserDetailsUpdates=function(h,f){}}; +runtime.loadClass("odf.Namespaces"); +ops.OpAddParagraphStyle=function(){var k=this,g,l,h,b,n=odf.Namespaces.svgns,a=odf.Namespaces.stylens;this.init=function(a){g=a.memberid;l=a.timestamp;h=a.styleName;b=a.setProperties};this.transform=function(a,b){var c=a.spec();return"UpdateParagraphStyle"!==c.optype&&"DeleteParagraphStyle"!==c.optype||c.styleName!==h?[k]:null};this.execute=function(f){var d=f.getOdfCanvas().odfContainer(),c=f.getFormatting(),g=f.getDOM(),e=g.createElementNS(a,"style:style"),k,m,l,s,w;if(!e)return!1;e.setAttributeNS(a, +"style:family","paragraph");e.setAttributeNS(a,"style:name",h);b&&Object.keys(b).forEach(function(f){switch(f){case "style:paragraph-properties":k=g.createElementNS(a,"style:paragraph-properties");e.appendChild(k);c.updateStyle(k,b["style:paragraph-properties"]);break;case "style:text-properties":m=g.createElementNS(a,"style:text-properties");e.appendChild(m);(s=b["style:text-properties"]["style:font-name"])&&!c.getFontMap().hasOwnProperty(s)&&(l=g.createElementNS(a,"style:font-face"),l.setAttributeNS(a, +"style:name",s),l.setAttributeNS(n,"svg:font-family",s),d.rootElement.fontFaceDecls.appendChild(l));c.updateStyle(m,b["style:text-properties"]);break;default:"object"!==typeof b[f]&&(w=odf.Namespaces.resolvePrefix(f.substr(0,f.indexOf(":"))),e.setAttributeNS(w,f,b[f]))}});d.rootElement.styles.appendChild(e);f.getOdfCanvas().refreshCSS();f.emit(ops.OdtDocument.signalStyleCreated,h);return!0};this.spec=function(){return{optype:"AddParagraphStyle",memberid:g,timestamp:l,styleName:h,setProperties:b}}}; +// Input 54 +/* + + Copyright (C) 2012-2013 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ +ops.OpDeleteParagraphStyle=function(){var k=this,g,l,h;this.init=function(b){g=b.memberid;l=b.timestamp;h=b.styleName};this.transform=function(b,g){var a=b.spec(),f=a.optype;if("DeleteParagraphStyle"===f){if(a.styleName===h)return[]}else if("SetParagraphStyle"===f&&a.styleName===h)return a.styleName="",f=new ops.OpSetParagraphStyle,f.init(a),[f,k];return[k]};this.execute=function(b){var g=b.getParagraphStyleElement(h);if(!g)return!1;g.parentNode.removeChild(g);b.getOdfCanvas().refreshCSS();b.emit(ops.OdtDocument.signalStyleDeleted, +h);return!0};this.spec=function(){return{optype:"DeleteParagraphStyle",memberid:g,timestamp:l,styleName:h}}}; +// Input 55 +/* + + Copyright (C) 2012-2013 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ +ops.OpAddAnnotation=function(){function k(a,b,d){if(d=a.getPositionInTextNode(d))a=d.textNode,d.offset!==a.length&&a.splitText(d.offset),a.parentNode.insertBefore(b,a.nextSibling)}var g,l,h,b,n;this.init=function(a){g=a.memberid;l=parseInt(a.timestamp,10);h=parseInt(a.position,10);b=parseInt(a.length,10)||0;n=a.name};this.transform=function(a,b){return null};this.execute=function(a){var f={},d=new Date(l),c,t,e,r,m;m=a.getRootNode().ownerDocument;c=m.createElementNS(odf.Namespaces.officens,"office:annotation"); +c.setAttributeNS(odf.Namespaces.officens,"office:name",n);t=m.createElementNS(odf.Namespaces.dcns,"dc:creator");t.setAttributeNS(odf.Namespaces.webodfns+":names:editinfo","editinfo:memberid",g);e=m.createElementNS(odf.Namespaces.dcns,"dc:date");e.appendChild(m.createTextNode(d.toISOString()));d=m.createElementNS(odf.Namespaces.textns,"text:list");r=m.createElementNS(odf.Namespaces.textns,"text:list-item");m=m.createElementNS(odf.Namespaces.textns,"text:p");r.appendChild(m);d.appendChild(r);c.appendChild(t); +c.appendChild(e);c.appendChild(d);f.node=c;if(!f.node)return!1;if(b){c=a.getRootNode().ownerDocument.createElementNS(odf.Namespaces.officens,"office:annotation-end");c.setAttributeNS(odf.Namespaces.officens,"office:name",n);f.end=c;if(!f.end)return!1;k(a,f.end,h+b)}k(a,f.node,h);a.getOdfCanvas().addAnnotation(f);return!0};this.spec=function(){return{optype:"AddAnnotation",memberid:g,timestamp:l,position:h,length:b,name:n}}}; +// Input 56 +/* + + Copyright (C) 2012-2013 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ +runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.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.OpAddParagraphStyle");runtime.loadClass("ops.OpDeleteParagraphStyle"); +runtime.loadClass("ops.OpAddAnnotation"); +ops.OperationFactory=function(){function k(g){return function(){return new g}}var g;this.register=function(k,h){g[k]=h};this.create=function(k){var h=null,b=g[k.optype];b&&(h=b(k),h.init(k));return h};g={AddCursor:k(ops.OpAddCursor),ApplyDirectStyling:k(ops.OpApplyDirectStyling),InsertTable:k(ops.OpInsertTable),InsertText:k(ops.OpInsertText),RemoveText:k(ops.OpRemoveText),SplitParagraph:k(ops.OpSplitParagraph),SetParagraphStyle:k(ops.OpSetParagraphStyle),UpdateParagraphStyle:k(ops.OpUpdateParagraphStyle),AddParagraphStyle:k(ops.OpAddParagraphStyle), +DeleteParagraphStyle:k(ops.OpDeleteParagraphStyle),MoveCursor:k(ops.OpMoveCursor),RemoveCursor:k(ops.OpRemoveCursor),AddAnnotation:k(ops.OpAddAnnotation)}}; +// Input 57 +runtime.loadClass("core.Cursor");runtime.loadClass("core.PositionIterator");runtime.loadClass("core.PositionFilter");runtime.loadClass("core.LoopWatchDog");runtime.loadClass("odf.OdfUtils"); +gui.SelectionMover=function(k,g){function l(){w.setUnfilteredPosition(k.getNode(),0);return w}function h(a,b,c){var d;c.setStart(a,b);d=c.getClientRects()[0];if(!d)if(d={},a.childNodes[b-1]){c.setStart(a,b-1);c.setEnd(a,b);b=c.getClientRects()[0];if(!b){for(c=b=0;a&&a.nodeType===Node.ELEMENT_NODE;)b+=a.offsetLeft-a.scrollLeft,c+=a.offsetTop-a.scrollTop,a=a.parentNode;b={top:c,left:b}}runtime.assert(b,"getRect: invalid containerOffset");d.top=b.top;d.left=b.right;d.bottom=b.bottom}else a.nodeType=== +Node.TEXT_NODE?(a.previousSibling&&(d=a.previousSibling.getClientRects()[0]),d||(c.setStart(a,0),c.setEnd(a,b),d=c.getClientRects()[0])):d=a.getClientRects()[0];runtime.assert(d,"getRect invalid rect");runtime.assert(void 0!==d.top,"getRect rect without top property");return{top:d.top,left:d.left,bottom:d.bottom}}function b(a,b,c){var d=a,e=l(),f,m=g.ownerDocument.createRange(),n=k.getSelectedRange()?k.getSelectedRange().cloneRange():g.ownerDocument.createRange(),s,q=runtime.getWindow();for(f=h(k.getNode(), +0,m);0a?-1:1;for(a=Math.abs(a);0n?k.previousPosition():k.nextPosition());)if(F.check(),m.acceptPosition(k)===v&&(q+=1,s=k.container(),z=h(s,k.unfilteredDomOffset(),Q),z.top!==O)){if(z.top!==S&&S!==O)break;S=z.top;z=Math.abs(ba-z.left);if(null===r||za?(c=m.previousPosition,d=-1):(c=m.nextPosition,d=1);for(e=h(m.container(),m.unfilteredDomOffset(),q);c.call(m);)if(b.acceptPosition(m)===v){if(s.getParagraphElement(m.getCurrentNode())!==n)break;f=h(m.container(),m.unfilteredDomOffset(),q);if(f.bottom!==e.bottom&&(e=f.top>=e.top&&f.bottome.bottom,!e))break;k+=d;e=f}q.detach();return k}function m(a,b){for(var c=0,d;a.parentNode!==b;)runtime.assert(null!==a.parentNode,"parent is null"),a=a.parentNode;for(d=b.firstChild;d!== +a;)c+=1,d=d.nextSibling;return c}function q(a,b,c){runtime.assert(null!==a,"SelectionMover.countStepsToPosition called with element===null");var d=l(),e=d.container(),f=d.unfilteredDomOffset(),g=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,f);var e=a,f=b,n=d.container(),k=d.unfilteredDomOffset();if(e===n)e=k- +f;else{var s=e.compareDocumentPosition(n);2===s?s=-1:4===s?s=1:10===s?(f=m(e,n),s=fe)for(;d.nextPosition()&&(h.check(),c.acceptPosition(d)===v&&(g+=1),d.container()!==a||d.unfilteredDomOffset()!==b););else if(0 + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ +runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");runtime.loadClass("ops.OpInsertTable");runtime.loadClass("ops.OpInsertText");runtime.loadClass("ops.OpRemoveText");runtime.loadClass("ops.OpSplitParagraph");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("ops.OpAddParagraphStyle");runtime.loadClass("ops.OpUpdateParagraphStyle");runtime.loadClass("ops.OpDeleteParagraphStyle"); +ops.OperationTransformer=function(){function k(l,h){for(var b,n,a,f=[],d=[];0=b&&(f=-h.movePointBackward(-b,a));l.handleUpdate();return f};this.handleUpdate=function(){};this.getStepCounter=function(){return h.getStepCounter()};this.getMemberId=function(){return k};this.getNode=function(){return b.getNode()};this.getAnchorNode=function(){return b.getAnchorNode()};this.getSelectedRange=function(){return b.getSelectedRange()}; +this.getOdtDocument=function(){return g};b=new core.Cursor(g.getDOM(),k);h=new gui.SelectionMover(b,g.getRootNode())}; +// Input 60 +/* + + Copyright (C) 2012 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ +ops.EditInfo=function(k,g){function l(){var g=[],a;for(a in b)b.hasOwnProperty(a)&&g.push({memberid:a,time:b[a].time});g.sort(function(a,b){return a.time-b.time});return g}var h,b={};this.getNode=function(){return h};this.getOdtDocument=function(){return g};this.getEdits=function(){return b};this.getSortedEdits=function(){return l()};this.addEdit=function(g,a){var f,d=g.split("___")[0];if(!b[g])for(f in b)if(b.hasOwnProperty(f)&&f.split("___")[0]===d){delete b[f];break}b[g]={time:a}};this.clearEdits= +function(){b={}};h=g.getDOM().createElementNS("urn:webodf:names:editinfo","editinfo");k.insertBefore(h,k.firstChild)}; +// Input 61 +gui.Avatar=function(k,g){var l=this,h,b,n;this.setColor=function(a){b.style.borderColor=a};this.setImageUrl=function(a){l.isVisible()?b.src=a:n=a};this.isVisible=function(){return"block"===h.style.display};this.show=function(){n&&(b.src=n,n=void 0);h.style.display="block"};this.hide=function(){h.style.display="none"};this.markAsFocussed=function(a){h.className=a?"active":""};(function(){var a=k.ownerDocument,f=a.documentElement.namespaceURI;h=a.createElementNS(f,"div");b=a.createElementNS(f,"img"); +b.width=64;b.height=64;h.appendChild(b);h.style.width="64px";h.style.height="70px";h.style.position="absolute";h.style.top="-80px";h.style.left="-34px";h.style.display=g?"block":"none";k.appendChild(h)})()}; +// Input 62 +runtime.loadClass("gui.Avatar");runtime.loadClass("ops.OdtCursor"); +gui.Caret=function(k,g,l){function h(a){d&&f.parentNode&&(!c||a)&&(a&&void 0!==t&&runtime.clearTimeout(t),c=!0,n.style.opacity=a||"0"===n.style.opacity?"1":"0",t=runtime.setTimeout(function(){c=!1;h(!1)},500))}function b(a){var b;if("string"===typeof a){if(""===a)return 0;b=/^(\d+)(\.\d+)?px$/.exec(a);runtime.assert(null!==b,"size ["+a+"] does not have unit px.");return parseFloat(b[1])}return a}var n,a,f,d=!1,c=!1,t;this.refreshCursor=function(){l||k.getSelectedRange().collapsed?(d=!0,h(!0)):(d= +!1,n.style.opacity="0")};this.setFocus=function(){d=!0;a.markAsFocussed(!0);h(!0)};this.removeFocus=function(){d=!1;a.markAsFocussed(!1);n.style.opacity="0"};this.setAvatarImageUrl=function(b){a.setImageUrl(b)};this.setColor=function(b){n.style.borderColor=b;a.setColor(b)};this.getCursor=function(){return k};this.getFocusElement=function(){return n};this.toggleHandleVisibility=function(){a.isVisible()?a.hide():a.show()};this.showHandle=function(){a.show()};this.hideHandle=function(){a.hide()};this.ensureVisible= +function(){var a,c,d,f,g,h,l,t=k.getOdtDocument().getOdfCanvas().getElement().parentNode;g=l=n;d=runtime.getWindow();runtime.assert(null!==d,"Expected to be run in an environment which has a global window, like a browser.");do{g=g.parentElement;if(!g)break;h=d.getComputedStyle(g,null)}while("block"!==h.display);h=g;g=f=0;if(h&&t){c=!1;do{d=h.offsetParent;for(a=h.parentNode;a!==d;){if(a===t){a=h;var v=t,p=0;c=0;var y=void 0,D=runtime.getWindow();for(runtime.assert(null!==D,"Expected to be run in an environment which has a global window, like a browser.");a&& +a!==v;)y=D.getComputedStyle(a,null),p+=b(y.marginLeft)+b(y.borderLeftWidth)+b(y.paddingLeft),c+=b(y.marginTop)+b(y.borderTopWidth)+b(y.paddingTop),a=a.parentElement;a=p;f+=a;g+=c;c=!0;break}a=a.parentNode}if(c)break;f+=b(h.offsetLeft);g+=b(h.offsetTop);h=d}while(h&&h!==t);d=f;f=g}else f=d=0;d+=l.offsetLeft;f+=l.offsetTop;g=d-5;h=f-5;d=d+l.scrollWidth-1+5;l=f+l.scrollHeight-1+5;ht.scrollTop+t.clientHeight-1&&(t.scrollTop=l-t.clientHeight+1);gt.scrollLeft+t.clientWidth-1&&(t.scrollLeft=d-t.clientWidth+1)};(function(){var b=k.getOdtDocument().getDOM();n=b.createElementNS(b.documentElement.namespaceURI,"span");f=k.getNode();f.appendChild(n);a=new gui.Avatar(f,g)})()}; +// Input 63 +runtime.loadClass("core.EventNotifier"); +gui.ClickHandler=function(){function k(){l=0;h=null}var g,l=0,h=null,b=new core.EventNotifier([gui.ClickHandler.signalSingleClick,gui.ClickHandler.signalDoubleClick,gui.ClickHandler.signalTripleClick]);this.subscribe=function(g,a){b.subscribe(g,a)};this.handleMouseUp=function(n){var a=runtime.getWindow();h&&h.x===n.screenX&&h.y===n.screenY?(l+=1,1===l?b.emit(gui.ClickHandler.signalSingleClick,n):2===l?b.emit(gui.ClickHandler.signalDoubleClick,void 0):3===l&&(a.clearTimeout(g),b.emit(gui.ClickHandler.signalTripleClick, +void 0),k())):(b.emit(gui.ClickHandler.signalSingleClick,n),l=1,h={x:n.screenX,y:n.screenY},a.clearTimeout(g),g=a.setTimeout(k,400))}};gui.ClickHandler.signalSingleClick="click";gui.ClickHandler.signalDoubleClick="doubleClick";gui.ClickHandler.signalTripleClick="tripleClick";(function(){return gui.ClickHandler})(); // Input 64 -ops.NowjsUserModel=function(h){var m={},f={},n=h.getNowObject();this.getUserDetailsAndUpdates=function(h,e){var a=h.split("___")[0],g=m[a],d=f[a]=f[a]||[],b;runtime.assert(void 0!==e,"missing callback");for(b=0;b + + @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(){function k(b,h){h||(h=g.None);return b+":"+h}var g=gui.KeyboardHandler.Modifier,l=null,h={};this.setDefault=function(b){l=b};this.bind=function(b,g,a){b=k(b,g);runtime.assert(!1===h.hasOwnProperty(b),"tried to overwrite the callback handler of key combo: "+b);h[b]=a};this.unbind=function(b,g){var a=k(b,g);delete h[a]};this.reset=function(){l=null;h={}};this.handleEvent=function(b){var n=b.keyCode,a=g.None;b.metaKey&&(a|=g.Meta);b.ctrlKey&&(a|=g.Ctrl);b.altKey&&(a|=g.Alt); +b.shiftKey&&(a|=g.Shift);n=k(n,a);n=h[n];a=!1;n?a=n():null!==l&&(a=l(b));a&&(b.preventDefault?b.preventDefault():b.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,I:73,U:85,Z:90};(function(){return gui.KeyboardHandler})(); // Input 65 /* @@ -1565,47 +1703,36 @@ function(h,e){var a=e?{userid:e.uid,fullname:e.fullname,imageurl:"/user/"+e.avat @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -ops.PullBoxUserModel=function(h){function m(){var a=h.getBase64(),e,d=[];for(e in q)q.hasOwnProperty(e)&&d.push(e);runtime.log("user-list request for : "+d.join(","));h.call("user-list:"+a.toBase64(h.getToken())+":"+d.join(","),function(a){var d=runtime.fromJson(a),f;runtime.log("user-list reply: "+a);if(d.hasOwnProperty("userdata_list"))for(a=d.userdata_list,e=0;e - - @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.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFactory=function(h){};ops.OperationRouter.prototype.setPlaybackFunction=function(h){};ops.OperationRouter.prototype.push=function(h){}; +runtime.loadClass("ops.OpAddCursor");runtime.loadClass("ops.OpRemoveCursor");runtime.loadClass("ops.OpMoveCursor");runtime.loadClass("ops.OpInsertText");runtime.loadClass("ops.OpRemoveText");runtime.loadClass("ops.OpSplitParagraph");runtime.loadClass("ops.OpSetParagraphStyle");runtime.loadClass("gui.ClickHandler");runtime.loadClass("gui.Clipboard");runtime.loadClass("gui.KeyboardHandler");runtime.loadClass("gui.StyleHelper"); +gui.SessionController=function(){gui.SessionController=function(k,g){function l(a,b,c,d){var e="on"+b,f=!1;a.attachEvent&&(f=a.attachEvent(e,c));!f&&a.addEventListener&&(a.addEventListener(b,c,!1),f=!0);f&&!d||!a.hasOwnProperty(e)||(a[e]=c)}function h(a,b,c){var d="on"+b;a.detachEvent&&a.detachEvent(d,c);a.removeEventListener&&a.removeEventListener(b,c,!1);a[d]===c&&(a[d]=null)}function b(a){a.preventDefault?a.preventDefault():a.returnValue=!1}function n(a,b){var c=new ops.OpMoveCursor;c.init({memberid:g, +position:a,length:b||0});return c}function a(a,b){var c=gui.SelectionMover.createPositionIterator(x.getRootNode()),d=x.getOdfCanvas().getElement(),e;e=a;if(!e)return null;for(;e!==d&&!("urn:webodf:names:cursor"===e.namespaceURI&&"cursor"===e.localName||"urn:webodf:names:editinfo"===e.namespaceURI&&"editinfo"===e.localName);)if(e=e.parentNode,!e)return null;e!==d&&a!==e&&(a=e.parentNode,b=Array.prototype.indexOf.call(a.childNodes,e));c.setUnfilteredPosition(a,b);return x.getDistanceFromCursor(g,c.container(), +c.unfilteredDomOffset())}function f(b){runtime.setTimeout(function(){var c=runtime.getWindow().getSelection(),d=x.getCursorPosition(g),e,f;if(null===c.anchorNode&&null===c.focusNode){e=b.clientX;f=b.clientY;var h=x.getDOM();h.caretRangeFromPoint?(e=h.caretRangeFromPoint(e,f),f={container:e.startContainer,offset:e.startOffset}):h.caretPositionFromPoint?(e=h.caretPositionFromPoint(e,f),f={container:e.offsetNode,offset:e.offset}):f=null;f&&(e=x.getDOM().createRange(),e.setStart(f.container,f.offset), +e.collapse(!0),c.addRange(e))}e=a(c.anchorNode,c.anchorOffset);c=a(c.focusNode,c.focusOffset);if(null!==c&&0!==c||null!==e&&0!==e)d=n(d+e,c-e),k.enqueue(d)},0)}function d(a){f(a)}function c(){var a,b,c,d=gui.SelectionMover.createPositionIterator(x.getRootNode()),e=x.getCursor(g).getNode(),f=x.getCursorPosition(g),h=/[A-Za-z0-9]/,m=0,l=0;d.setUnfilteredPosition(e,0);if(d.previousPosition()&&(a=d.getCurrentNode(),a.nodeType===Node.TEXT_NODE))for(b=a.data.length-1;0<=b;b-=1)if(c=a.data[b],h.test(c))m-= +1;else break;d.setUnfilteredPosition(e,0);if(d.nextPosition()&&(a=d.getCurrentNode(),a.nodeType===Node.TEXT_NODE))for(b=0;ba.length&&(a.position+=a.length,a.length=-a.length);return a}function O(a){var b=new ops.OpRemoveText;b.init({memberid:g,position:a.position,length:a.length});return b}function ba(){var a=W(x.getCursorSelection(g)),b=null;0===a.length?0 @@ -1640,12 +1767,12 @@ ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFacto @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)}}; -// Input 68 -ops.NowjsOperationRouter=function(h,m,f){function n(a){var f;f=q.create(a);runtime.log(" op in: "+runtime.toJson(a));if(null!==f)if(a=Number(a.server_seq),runtime.assert(!isNaN(a),"server seq is not a number"),a===g+1)for(e(f),g=a,b=0,f=g+1;d.hasOwnProperty(f);f+=1)e(d[f]),delete d[f],runtime.log("op with server seq "+a+" taken from hold (reordered)");else runtime.assert(a!==g+1,"received incorrect order from server"),runtime.assert(!d.hasOwnProperty(a),"reorder_queue has incoming op"),runtime.log("op with server seq "+ -a+" put on hold"),d[a]=f;else runtime.log("ignoring invalid incoming opspec: "+a)}var q,e,a=f.getNowObject(),g=-1,d={},b=0,r=1E3;this.setOperationFactory=function(a){q=a};this.setPlaybackFunction=function(a){e=a};a.ping=function(a){null!==m&&a(m)};a.receiveOp=function(a,b){a===h&&n(b)};this.push=function(d){d=d.spec();runtime.assert(null!==m,"Router sequence N/A without memberid");r+=1;d.client_nonce="C:"+m+":"+r;d.parent_op=g+"+"+b;b+=1;runtime.log("op out: "+runtime.toJson(d));a.deliverOp(h,d)}; -this.requestReplay=function(b){a.requestReplay(h,function(a){runtime.log("replaying: "+runtime.toJson(a));n(a)},function(a){runtime.log("replay done ("+a+" ops).");b&&b()})};(function(){a.memberid=m;a.joinSession(h,function(a){runtime.assert(a,"Trying to join a session which does not exists or where we are already in")})})()}; +ops.TrivialUserModel=function(){var k={bob:{memberid:"bob",fullname:"Bob Pigeon",color:"red",imageurl:"avatar-pigeon.png"},alice:{memberid:"alice",fullname:"Alice Bee",color:"green",imageurl:"avatar-flower.png"},you:{memberid:"you",fullname:"I, Robot",color:"blue",imageurl:"avatar-joe.png"}};this.getUserDetailsAndUpdates=function(g,l){var h=g.split("___")[0];l(g,k[h]||null)};this.unsubscribeUserDetailsUpdates=function(g,k){}}; // Input 69 +ops.NowjsUserModel=function(k){var g={},l={},h=k.getNowObject();this.getUserDetailsAndUpdates=function(b,k){var a=b.split("___")[0],f=g[a],d=l[a]||[],c;l[a]=d;runtime.assert(void 0!==k,"missing callback");for(c=0;c @@ -1680,21 +1807,46 @@ this.requestReplay=function(b){a.requestReplay(h,function(a){runtime.log("replay @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("ops.OperationTransformer"); -ops.PullBoxOperationRouter=function(h,m,f){function n(a){var b,c,e,f=[];for(b=0;bk?(f(1,0),g=f(0.5,1E4-k),d=f(0.2,2E4-k)):1E4<=k&&2E4>k?(f(0.5,0),d=f(0.2,2E4-k)):f(0.2,0)};this.getEdits=function(){return h.getEdits()};this.clearEdits=function(){h.clearEdits(); -e.setEdits([]);a.hasAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")&&a.removeAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")};this.getEditInfo=function(){return h};this.show=function(){a.style.display="block"};this.hide=function(){n.hideHandle();a.style.display="none"};this.showHandle=function(){e.show()};this.hideHandle=function(){e.hide()};(function(){var b=h.getOdtDocument().getDOM();a=b.createElementNS(b.documentElement.namespaceURI,"div");a.setAttribute("class","editInfoMarker"); -a.onmouseover=function(){n.showHandle()};a.onmouseout=function(){n.hideHandle()};q=h.getNode();q.appendChild(a);e=new gui.EditInfoHandle(q);m||n.hide()})()}; +/* + + Copyright (C) 2013 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ +ops.OperationRouter=function(){};ops.OperationRouter.prototype.setOperationFactory=function(k){};ops.OperationRouter.prototype.setPlaybackFunction=function(k){};ops.OperationRouter.prototype.push=function(k){}; // Input 72 /* @@ -1730,14 +1882,62 @@ a.onmouseover=function(){n.showHandle()};a.onmouseout=function(){n.hideHandle()} @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("gui.Caret");runtime.loadClass("ops.TrivialUserModel");runtime.loadClass("ops.EditInfo");runtime.loadClass("gui.EditInfoMarker"); -gui.SessionView=function(){return function(h,m,f){function n(a,b,c){c=c.split("___")[0];return a+"."+b+'[editinfo|memberid^="'+c+'"]'}function q(a,b,c){function d(b,c,e){e=n(b,c,a)+e;a:{var f=k.firstChild;for(b=n(b,c,a);f;){if(f.nodeType===Node.TEXT_NODE&&0===f.data.indexOf(b)){b=f;break a}f=f.nextSibling}b=null}b?b.data=e:k.appendChild(document.createTextNode(e))}d("div","editInfoMarker","{ background-color: "+c+"; }");d("span","editInfoColor","{ background-color: "+c+"; }");d("span","editInfoAuthor", -':before { content: "'+b+'"; }')}function e(a){var b,c;for(c in l)l.hasOwnProperty(c)&&(b=l[c],a?b.show():b.hide())}function a(a){var b,c;for(c in r)r.hasOwnProperty(c)&&(b=r[c],a?b.showHandle():b.hideHandle())}function g(a,b){var c=r[a];void 0===b?runtime.log('UserModel sent undefined data for member "'+a+'".'):(null===b&&(b={memberid:a,fullname:"Unknown Identity",color:"black",imageurl:"avatar-joe.png"}),c&&(c.setAvatarImageUrl(b.imageurl),c.setColor(b.color)),q(a,b.fullname,b.color))}function d(a){var b= -f.createCaret(a,u);a=a.getMemberId();var c=m.getUserModel();r[a]=b;g(a,null);c.getUserDetailsAndUpdates(a,g);runtime.log("+++ View here +++ eagerly created an Caret for '"+a+"'! +++")}function b(a){var b=!1,c;delete r[a];for(c in l)if(l.hasOwnProperty(c)&&l[c].getEditInfo().getEdits().hasOwnProperty(a)){b=!0;break}b||m.getUserModel().unsubscribeUserDetailsUpdates(a,g)}var r={},k,l={},c=void 0!==h.editInfoMarkersInitiallyVisible?h.editInfoMarkersInitiallyVisible:!0,u=void 0!==h.caretAvatarsInitiallyVisible? -h.caretAvatarsInitiallyVisible:!0;this.showEditInfoMarkers=function(){c||(c=!0,e(c))};this.hideEditInfoMarkers=function(){c&&(c=!1,e(c))};this.showCaretAvatars=function(){u||(u=!0,a(u))};this.hideCaretAvatars=function(){u&&(u=!1,a(u))};this.getSession=function(){return m};this.getCaret=function(a){return r[a]};(function(){var a=m.getOdtDocument(),e=document.getElementsByTagName("head")[0];a.subscribe(ops.OdtDocument.signalCursorAdded,d);a.subscribe(ops.OdtDocument.signalCursorRemoved,b);a.subscribe(ops.OdtDocument.signalParagraphChanged, -function(a){var b=a.paragraphElement,d=a.memberId;a=a.timeStamp;var e,f="",g=b.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo")[0];g?(f=g.getAttributeNS("urn:webodf:names:editinfo","id"),e=l[f]):(f=Math.random().toString(),e=new ops.EditInfo(b,m.getOdtDocument()),e=new gui.EditInfoMarker(e,c),g=b.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo")[0],g.setAttributeNS("urn:webodf:names:editinfo","id",f),l[f]=e);e.addEdit(d,new Date(a))});k=document.createElementNS(e.namespaceURI, -"style");k.type="text/css";k.media="screen, print, handheld, projection";k.appendChild(document.createTextNode("@namespace editinfo url(urn:webodf:names:editinfo);"));e.appendChild(k)})()}}(); +ops.TrivialOperationRouter=function(){var k,g;this.setOperationFactory=function(g){k=g};this.setPlaybackFunction=function(k){g=k};this.push=function(l){l=l.spec();l.timestamp=(new Date).getTime();l=k.create(l);g(l)}}; // Input 73 +ops.NowjsOperationRouter=function(k,g,l){function h(a){var g;g=b.create(a);runtime.log(" op in: "+runtime.toJson(a));if(null!==g)if(a=Number(a.server_seq),runtime.assert(!isNaN(a),"server seq is not a number"),a===f+1)for(n(g),f=a,c=0,g=f+1;d.hasOwnProperty(g);g+=1)n(d[g]),delete d[g],runtime.log("op with server seq "+a+" taken from hold (reordered)");else runtime.assert(a!==f+1,"received incorrect order from server"),runtime.assert(!d.hasOwnProperty(a),"reorder_queue has incoming op"),runtime.log("op with server seq "+ +a+" put on hold"),d[a]=g;else runtime.log("ignoring invalid incoming opspec: "+a)}var b,n,a=l.getNowObject(),f=-1,d={},c=0,t=1E3;this.setOperationFactory=function(a){b=a};this.setPlaybackFunction=function(a){n=a};a.ping=function(a){null!==g&&a(g)};a.receiveOp=function(a,b){a===k&&h(b)};this.push=function(b){b=b.spec();runtime.assert(null!==g,"Router sequence N/A without memberid");t+=1;b.client_nonce="C:"+g+":"+t;b.parent_op=f+"+"+c;c+=1;runtime.log("op out: "+runtime.toJson(b));a.deliverOp(k,b)}; +this.requestReplay=function(b){a.requestReplay(k,function(a){runtime.log("replaying: "+runtime.toJson(a));h(a)},function(a){runtime.log("replay done ("+a+" ops).");b&&b()})};(function(){a.memberid=g;a.joinSession(k,function(a){runtime.assert(a,"Trying to join a session which does not exists or where we are already in")})})()}; +// Input 74 +/* + + Copyright (C) 2013 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ +runtime.loadClass("ops.OperationTransformer"); +ops.PullBoxOperationRouter=function(k,g,l){function h(a){var b,c,e,f=[];for(b=0;be?(l(1,0),f=l(0.5,1E4-e),d=l(0.2,2E4-e)):1E4<=e&&2E4>e?(l(0.5,0),d=l(0.2,2E4-e)):l(0.2,0)};this.getEdits= +function(){return k.getEdits()};this.clearEdits=function(){k.clearEdits();n.setEdits([]);a.hasAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")&&a.removeAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")};this.getEditInfo=function(){return k};this.show=function(){a.style.display="block"};this.hide=function(){h.hideHandle();a.style.display="none"};this.showHandle=function(){n.show()};this.hideHandle=function(){n.hide()};(function(){var c=k.getOdtDocument().getDOM();a=c.createElementNS(c.documentElement.namespaceURI, +"div");a.setAttribute("class","editInfoMarker");a.onmouseover=function(){h.showHandle()};a.onmouseout=function(){h.hideHandle()};b=k.getNode();b.appendChild(a);n=new gui.EditInfoHandle(b);g||h.hide()})()}; +// Input 77 /* Copyright (C) 2012 KO GmbH @@ -1772,99 +1972,70 @@ function(a){var b=a.paragraphElement,d=a.memberId;a=a.timeStamp;var e,f="",g=b.g @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("gui.Caret");gui.CaretFactory=function(h){this.createCaret=function(m,f){var n=m.getMemberId(),q=h.getSession().getOdtDocument(),e=q.getOdfCanvas().getElement(),a=new gui.Caret(m,f);n===h.getInputMemberId()&&(runtime.log("Starting to track input on new cursor of "+n),q.subscribe(ops.OdtDocument.signalParagraphChanged,function(e){e.memberId===n&&a.ensureVisible()}),m.handleUpdate=a.ensureVisible,e.setAttribute("tabindex",0),e.onfocus=a.setFocus,e.onblur=a.removeFocus,e.focus());return a}}; -// Input 74 -runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.Namespaces"); -gui.PresenterUI=function(){var h=new xmldom.XPath;return function(m){var f=this;f.setInitialSlideMode=function(){f.startSlideMode("single")};f.keyDownHandler=function(h){if(!h.target.isContentEditable&&"input"!==h.target.nodeName)switch(h.keyCode){case 84:f.toggleToolbar();break;case 37:case 8:f.prevSlide();break;case 39:case 32:f.nextSlide();break;case 36:f.firstSlide();break;case 35:f.lastSlide()}};f.root=function(){return f.odf_canvas.odfContainer().rootElement};f.firstSlide=function(){f.slideChange(function(f, -h){return 0})};f.lastSlide=function(){f.slideChange(function(f,h){return h-1})};f.nextSlide=function(){f.slideChange(function(f,h){return f+1f?-1:f-1})};f.slideChange=function(h){var m=f.getPages(f.odf_canvas.odfContainer().rootElement),e=-1,a=0;m.forEach(function(f){f=f[1];f.hasAttribute("slide_current")&&(e=a,f.removeAttribute("slide_current"));a+=1});h=h(e,m.length);-1===h&&(h=e);m[h][1].setAttribute("slide_current","1"); -document.getElementById("pagelist").selectedIndex=h;"cont"===f.slide_mode&&window.scrollBy(0,m[h][1].getBoundingClientRect().top-30)};f.selectSlide=function(h){f.slideChange(function(f,e){return h>=e||0>h?-1:h})};f.scrollIntoContView=function(h){var m=f.getPages(f.odf_canvas.odfContainer().rootElement);0!==m.length&&window.scrollBy(0,m[h][1].getBoundingClientRect().top-30)};f.getPages=function(f){f=f.getElementsByTagNameNS(odf.Namespaces.drawns,"page");var h=[],e;for(e=0;e=a.rangeCount||!t)||(a=a.getRangeAt(0),t.setPoint(a.startContainer,a.startOffset))}function e(){var a=h.ownerDocument.defaultView.getSelection(),b,c;a.removeAllRanges();t&&t.node()&&(b=t.node(),c=b.ownerDocument.createRange(), -c.setStart(b,t.position()),c.collapse(!0),a.addRange(c))}function a(a){var b=a.charCode||a.keyCode;if(t=null,t&&37===b)q(),t.stepBackward(),e();else if(16<=b&&20>=b||33<=b&&40>=b)return;n(a)}function g(a){}function d(a){h.ownerDocument.defaultView.getSelection().getRangeAt(0);n(a)}function b(a){for(var c=a.firstChild;c&&c!==a;)c.nodeType===Node.ELEMENT_NODE&&b(c),c=c.nextSibling||c.parentNode;var d,e,f,c=a.attributes;d="";for(f=c.length-1;0<=f;f-=1)e=c.item(f),d=d+" "+e.nodeName+'="'+e.nodeValue+ -'"';a.setAttribute("customns_name",a.nodeName);a.setAttribute("customns_atts",d);c=a.firstChild;for(e=/^\s*$/;c&&c!==a;)d=c,c=c.nextSibling||c.parentNode,d.nodeType===Node.TEXT_NODE&&e.test(d.nodeValue)&&d.parentNode.removeChild(d)}function r(a,b){for(var c=a.firstChild,d,e,f;c&&c!==a;){if(c.nodeType===Node.ELEMENT_NODE)for(r(c,b),d=c.attributes,f=d.length-1;0<=f;f-=1)e=d.item(f),"http://www.w3.org/2000/xmlns/"!==e.namespaceURI||b[e.nodeValue]||(b[e.nodeValue]=e.localName);c=c.nextSibling||c.parentNode}} -function k(){var a=h.ownerDocument.createElement("style"),b;b={};r(h,b);var c={},d,e,f=0;for(d in b)if(b.hasOwnProperty(d)&&d){e=b[d];if(!e||c.hasOwnProperty(e)||"xmlns"===e){do e="ns"+f,f+=1;while(c.hasOwnProperty(e));b[d]=e}c[e]=!0}a.type="text/css";b="@namespace customns url(customns);\n"+l;a.appendChild(h.ownerDocument.createTextNode(b));m=m.parentNode.replaceChild(a,m)}var l,c,u,t=null;h.id||(h.id="xml"+String(Math.random()).substring(2));c="#"+h.id+" ";l=c+"*,"+c+":visited, "+c+":link {display:block; margin: 0px; margin-left: 10px; font-size: medium; color: black; background: white; font-variant: normal; font-weight: normal; font-style: normal; font-family: sans-serif; text-decoration: none; white-space: pre-wrap; height: auto; width: auto}\n"+ -c+":before {color: blue; content: '<' attr(customns_name) attr(customns_atts) '>';}\n"+c+":after {color: blue; content: '';}\n"+c+"{overflow: auto;}\n";(function(b){f(b,"click",d);f(b,"keydown",a);f(b,"keypress",g);f(b,"drop",n);f(b,"dragend",n);f(b,"beforepaste",n);f(b,"paste",n)})(h);this.updateCSS=k;this.setXML=function(a){a=a.documentElement||a;u=a=h.ownerDocument.importNode(a,!0);for(b(a);h.lastChild;)h.removeChild(h.lastChild);h.appendChild(a);k();t=new core.PositionIterator(a)}; -this.getXML=function(){return u}}; -// Input 76 -/* - - Copyright (C) 2013 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -gui.UndoManager=function(){};gui.UndoManager.prototype.subscribe=function(h,m){};gui.UndoManager.prototype.unsubscribe=function(h,m){};gui.UndoManager.prototype.setOdtDocument=function(h){};gui.UndoManager.prototype.saveInitialState=function(){};gui.UndoManager.prototype.resetInitialState=function(){};gui.UndoManager.prototype.setPlaybackFunction=function(h){};gui.UndoManager.prototype.hasUndoStates=function(){};gui.UndoManager.prototype.hasRedoStates=function(){}; -gui.UndoManager.prototype.moveForward=function(h){};gui.UndoManager.prototype.moveBackward=function(h){};gui.UndoManager.prototype.onOperationExecuted=function(h){};gui.UndoManager.signalUndoStackChanged="undoStackChanged";gui.UndoManager.signalUndoStateCreated="undoStateCreated";gui.UndoManager.signalUndoStateModified="undoStateModified";(function(){return gui.UndoManager})(); -// Input 77 -/* - - Copyright (C) 2013 KO GmbH - - @licstart - The JavaScript code in this page is free software: you can redistribute it - and/or modify it under the terms of the GNU Affero General Public License - (GNU AGPL) as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. The code is distributed - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. - - As additional permission under GNU AGPL version 3 section 7, you - may distribute non-source (e.g., minimized or compacted) forms of - that code without the copy of the GNU GPL normally required by - section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it by reference shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - @source: http://www.webodf.org/ - @source: http://gitorious.org/webodf/webodf/ -*/ -gui.UndoStateRules=function(){function h(f){return f.spec().optype}function 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,n){if(m(f)){if(0===n.length)return!0;var q;if(q=m(n[n.length-1]))a:{q=n.filter(m);var e=h(f),a;b:switch(e){case "RemoveText":case "InsertText":a=!0;break b;default:a=!1}if(a&&e===h(q[0])){if(1===q.length){q=!0;break a}e=q[q.length-2].spec().position; -q=q[q.length-1].spec().position;a=f.spec().position;if(q===a-(q-e)){q=!0;break a}}q=!1}return q}return!0}}; +runtime.loadClass("gui.Caret");runtime.loadClass("ops.TrivialUserModel");runtime.loadClass("ops.EditInfo");runtime.loadClass("gui.EditInfoMarker");gui.SessionViewOptions=function(){this.caretBlinksOnRangeSelect=this.caretAvatarsInitiallyVisible=this.editInfoMarkersInitiallyVisible=!0}; +gui.SessionView=function(){return function(k,g,l){function h(a,b,c){b=b.split("___")[0];return a+'[editinfo|memberid^="'+b+'"]'+c}function b(a,b,c){function d(b,c,e){c=h(b,a,e)+c;a:{var f=t.firstChild;for(b=h(b,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+"; }","")}function n(a){var b,c;for(c in e)e.hasOwnProperty(c)&&(b=e[c],a?b.show():b.hide())}function a(a){l.getCarets().forEach(function(b){a?b.showHandle():b.hideHandle()})}function f(a,c){var d=l.getCaret(a);void 0===c?runtime.log('UserModel sent undefined data for member "'+a+'".'):(null===c&&(c={memberid:a,fullname:"Unknown Identity",color:"black",imageurl:"avatar-joe.png"}), +d&&(d.setAvatarImageUrl(c.imageurl),d.setColor(c.color)),b(a,c.fullname,c.color))}function d(a){var b=a.getMemberId(),c=g.getUserModel();l.registerCursor(a,m,q);f(b,null);c.getUserDetailsAndUpdates(b,f);runtime.log("+++ View here +++ eagerly created an Caret for '"+b+"'! +++")}function c(a){var b=!1,c;for(c in e)if(e.hasOwnProperty(c)&&e[c].getEditInfo().getEdits().hasOwnProperty(a)){b=!0;break}b||g.getUserModel().unsubscribeUserDetailsUpdates(a,f)}var t,e={},r=void 0!==k.editInfoMarkersInitiallyVisible? +k.editInfoMarkersInitiallyVisible:!0,m=void 0!==k.caretAvatarsInitiallyVisible?k.caretAvatarsInitiallyVisible:!0,q=void 0!==k.caretBlinksOnRangeSelect?k.caretBlinksOnRangeSelect:!0;this.showEditInfoMarkers=function(){r||(r=!0,n(r))};this.hideEditInfoMarkers=function(){r&&(r=!1,n(r))};this.showCaretAvatars=function(){m||(m=!0,a(m))};this.hideCaretAvatars=function(){m&&(m=!1,a(m))};this.getSession=function(){return g};this.getCaret=function(a){return l.getCaret(a)};(function(){var a=g.getOdtDocument(), +b=document.getElementsByTagName("head")[0];a.subscribe(ops.OdtDocument.signalCursorAdded,d);a.subscribe(ops.OdtDocument.signalCursorRemoved,c);a.subscribe(ops.OdtDocument.signalParagraphChanged,function(a){var b=a.paragraphElement,c=a.memberId;a=a.timeStamp;var d,f="",h=b.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo")[0];h?(f=h.getAttributeNS("urn:webodf:names:editinfo","id"),d=e[f]):(f=Math.random().toString(),d=new ops.EditInfo(b,g.getOdtDocument()),d=new gui.EditInfoMarker(d,r), +h=b.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo")[0],h.setAttributeNS("urn:webodf:names:editinfo","id",f),e[f]=d);d.addEdit(c,new Date(a))});t=document.createElementNS(b.namespaceURI,"style");t.type="text/css";t.media="screen, print, handheld, projection";t.appendChild(document.createTextNode("@namespace editinfo url(urn:webodf:names:editinfo);"));t.appendChild(document.createTextNode("@namespace dc url(http://purl.org/dc/elements/1.1/);"));b.appendChild(t)})()}}(); // Input 78 +/* + + Copyright (C) 2012 KO GmbH + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ +runtime.loadClass("gui.Caret"); +gui.CaretManager=function(k){function g(){return k.getSession().getOdtDocument().getOdfCanvas().getElement()}function l(a){a===k.getInputMemberId()&&g().removeAttribute("tabindex",0);delete f[a]}function h(a){(a=f[a.getMemberId()])&&a.refreshCursor()}function b(a){var b=f[a.memberId];a.memberId===k.getInputMemberId()&&b&&b.ensureVisible()}function n(){var a=f[k.getInputMemberId()];a&&a.setFocus()}function a(){var a=f[k.getInputMemberId()];a&&a.removeFocus()}var f={};this.registerCursor=function(a, +b,h){var e=a.getMemberId(),n=g();b=new gui.Caret(a,b,h);f[e]=b;e===k.getInputMemberId()&&(runtime.log("Starting to track input on new cursor of "+e),a.handleUpdate=b.ensureVisible,n.setAttribute("tabindex",0),n.focus());return b};this.getCaret=function(a){return f[a]};this.getCarets=function(){return Object.keys(f).map(function(a){return f[a]})};(function(){var d=k.getSession().getOdtDocument(),c=g();d.subscribe(ops.OdtDocument.signalParagraphChanged,b);d.subscribe(ops.OdtDocument.signalCursorMoved, +h);d.subscribe(ops.OdtDocument.signalCursorRemoved,l);c.onfocus=n;c.onblur=a})()}; +// Input 79 +runtime.loadClass("xmldom.XPath");runtime.loadClass("odf.Namespaces"); +gui.PresenterUI=function(){var k=new xmldom.XPath,g=runtime.getWindow();return function(l){var h=this;h.setInitialSlideMode=function(){h.startSlideMode("single")};h.keyDownHandler=function(b){if(!b.target.isContentEditable&&"input"!==b.target.nodeName)switch(b.keyCode){case 84:h.toggleToolbar();break;case 37:case 8:h.prevSlide();break;case 39:case 32:h.nextSlide();break;case 36:h.firstSlide();break;case 35:h.lastSlide()}};h.root=function(){return h.odf_canvas.odfContainer().rootElement};h.firstSlide= +function(){h.slideChange(function(b,g){return 0})};h.lastSlide=function(){h.slideChange(function(b,g){return g-1})};h.nextSlide=function(){h.slideChange(function(b,g){return b+1b?-1:b-1})};h.slideChange=function(b){var k=h.getPages(h.odf_canvas.odfContainer().rootElement),a=-1,f=0;k.forEach(function(b){b=b[1];b.hasAttribute("slide_current")&&(a=f,b.removeAttribute("slide_current"));f+=1});b=b(a,k.length);-1===b&&(b=a);k[b][1].setAttribute("slide_current", +"1");document.getElementById("pagelist").selectedIndex=b;"cont"===h.slide_mode&&g.scrollBy(0,k[b][1].getBoundingClientRect().top-30)};h.selectSlide=function(b){h.slideChange(function(g,a){return b>=a||0>b?-1:b})};h.scrollIntoContView=function(b){var k=h.getPages(h.odf_canvas.odfContainer().rootElement);0!==k.length&&g.scrollBy(0,k[b][1].getBoundingClientRect().top-30)};h.getPages=function(b){b=b.getElementsByTagNameNS(odf.Namespaces.drawns,"page");var g=[],a;for(a=0;a=a.rangeCount||!q)||(a=a.getRangeAt(0),q.setPoint(a.startContainer,a.startOffset))}function n(){var a=k.ownerDocument.defaultView.getSelection(),b,c;a.removeAllRanges();q&&q.node()&&(b=q.node(),c=b.ownerDocument.createRange(), +c.setStart(b,q.position()),c.collapse(!0),a.addRange(c))}function a(a){var c=a.charCode||a.keyCode;if(q=null,q&&37===c)b(),q.stepBackward(),n();else if(16<=c&&20>=c||33<=c&&40>=c)return;h(a)}function f(a){h(a)}function d(a){for(var b=a.firstChild;b&&b!==a;)b.nodeType===Node.ELEMENT_NODE&&d(b),b=b.nextSibling||b.parentNode;var c,e,f,b=a.attributes;c="";for(f=b.length-1;0<=f;f-=1)e=b.item(f),c=c+" "+e.nodeName+'="'+e.nodeValue+'"';a.setAttribute("customns_name",a.nodeName);a.setAttribute("customns_atts", +c);b=a.firstChild;for(e=/^\s*$/;b&&b!==a;)c=b,b=b.nextSibling||b.parentNode,c.nodeType===Node.TEXT_NODE&&e.test(c.nodeValue)&&c.parentNode.removeChild(c)}function c(a,b){for(var d=a.firstChild,e,f,g;d&&d!==a;){if(d.nodeType===Node.ELEMENT_NODE)for(c(d,b),e=d.attributes,g=e.length-1;0<=g;g-=1)f=e.item(g),"http://www.w3.org/2000/xmlns/"!==f.namespaceURI||b[f.nodeValue]||(b[f.nodeValue]=f.localName);d=d.nextSibling||d.parentNode}}function t(){var a=k.ownerDocument.createElement("style"),b;b={};c(k,b); +var d={},f,h,m=0;for(f in b)if(b.hasOwnProperty(f)&&f){h=b[f];if(!h||d.hasOwnProperty(h)||"xmlns"===h){do h="ns"+m,m+=1;while(d.hasOwnProperty(h));b[f]=h}d[h]=!0}a.type="text/css";b="@namespace customns url(customns);\n"+e;a.appendChild(k.ownerDocument.createTextNode(b));g=g.parentNode.replaceChild(a,g)}var e,r,m,q=null;k.id||(k.id="xml"+String(Math.random()).substring(2));r="#"+k.id+" ";e=r+"*,"+r+":visited, "+r+":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"+ +r+":before {color: blue; content: '<' attr(customns_name) attr(customns_atts) '>';}\n"+r+":after {color: blue; content: '';}\n"+r+"{overflow: auto;}\n";(function(b){l(b,"click",f);l(b,"keydown",a);l(b,"drop",h);l(b,"dragend",h);l(b,"beforepaste",h);l(b,"paste",h)})(k);this.updateCSS=t;this.setXML=function(a){a=a.documentElement||a;m=a=k.ownerDocument.importNode(a,!0);for(d(a);k.lastChild;)k.removeChild(k.lastChild);k.appendChild(a);t();q=new core.PositionIterator(a)};this.getXML= +function(){return m}}; +// Input 81 /* Copyright (C) 2013 KO GmbH @@ -1899,12 +2070,88 @@ q=q[q.length-1].spec().position;a=f.spec().position;if(q===a-(q-e)){q=!0;break a @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("gui.UndoManager");runtime.loadClass("gui.UndoStateRules"); -gui.TrivialUndoManager=function(h){function m(){k.emit(gui.UndoManager.signalUndoStackChanged,{undoAvailable:n.hasUndoStates(),redoAvailable:n.hasRedoStates()})}function f(){d!==e&&d!==b[b.length-1]&&b.push(d)}var n=this,q,e,a,g,d=[],b=[],r=[],k=new core.EventNotifier([gui.UndoManager.signalUndoStackChanged,gui.UndoManager.signalUndoStateCreated,gui.UndoManager.signalUndoStateModified,gui.TrivialUndoManager.signalDocumentRootReplaced]),l=h||new gui.UndoStateRules;this.subscribe=function(a,b){k.subscribe(a, -b)};this.unsubscribe=function(a,b){k.unsubscribe(a,b)};this.hasUndoStates=function(){return 0 + + @licstart + The JavaScript code in this page is free software: you can redistribute it + and/or modify it under the terms of the GNU Affero General Public License + (GNU AGPL) as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. The code is distributed + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. + + As additional permission under GNU AGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + As a special exception to the AGPL, any HTML file which merely makes function + calls to this code, and for that purpose includes it by reference shall be + deemed a separate work for copyright law purposes. In addition, the copyright + holders of this code give you permission to combine this code with free + software libraries that are released under the GNU LGPL. You may copy and + distribute such a system following the terms of the GNU AGPL for this code + and the LGPL for the libraries. If you modify this code, you may extend this + exception to your version of the code, but you are not obligated to do so. + If you do not wish to do so, delete this exception statement from your + version. + + This license applies to this entire compilation. + @licend + @source: http://www.webodf.org/ + @source: http://gitorious.org/webodf/webodf/ +*/ +gui.UndoStateRules=function(){function k(g){return g.spec().optype}function g(g){switch(k(g)){case "MoveCursor":case "AddCursor":case "RemoveCursor":return!1;default:return!0}}this.getOpType=k;this.isEditOperation=g;this.isPartOfOperationSet=function(l,h){if(g(l)){if(0===h.length)return!0;var b;if(b=g(h[h.length-1]))a:{b=h.filter(g);var n=k(l),a;b:switch(n){case "RemoveText":case "InsertText":a=!0;break b;default:a=!1}if(a&&n===k(b[0])){if(1===b.length){b=!0;break a}n=b[b.length-2].spec().position; +b=b[b.length-1].spec().position;a=l.spec().position;if(b===a-(b-n)){b=!0;break a}}b=!1}return b}return!0}}; +// Input 83 +/* + + 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.DomUtils");runtime.loadClass("gui.UndoManager");runtime.loadClass("gui.UndoStateRules"); +gui.TrivialUndoManager=function(k){function g(){s.emit(gui.UndoManager.signalUndoStackChanged,{undoAvailable:a.hasUndoStates(),redoAvailable:a.hasRedoStates()})}function l(){r!==c&&r!==m[m.length-1]&&m.push(r)}function h(a){var b=a.previousSibling||a.nextSibling;a.parentNode.removeChild(a);f.normalizeTextNodes(b)}function b(a){return Object.keys(a).map(function(b){return a[b]})}function n(a){function c(a){var b=a.spec();if(g[b.memberid])switch(b.optype){case "AddCursor":d[b.memberid]||(d[b.memberid]= +a,delete g[b.memberid],h-=1);break;case "MoveCursor":f[b.memberid]||(f[b.memberid]=a)}}var d={},f={},g={},h,m=a.pop();e.getCursors().forEach(function(a){g[a.getMemberId()]=!0});for(h=Object.keys(g).length;m&&0 @@ -1939,23 +2186,23 @@ function(a){r.length=0;l.isEditOperation(a)&&d===e||!l.isPartOfOperationSet(a,d) @source: http://www.webodf.org/ @source: http://gitorious.org/webodf/webodf/ */ -runtime.loadClass("core.EventNotifier");runtime.loadClass("odf.OdfUtils"); -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){var b=gui.SelectionMover.createPositionIterator(m());for(a+=1;0=g;g+=1)c=a.container(),d=a.unfilteredDomOffset(),c.nodeType===Node.TEXT_NODE&&(" "===c.data[d]&&b.isSignificantWhitespace(c,d))&&e(c,d),a.nextPosition()};this.getParagraphStyleElement=q;this.getParagraphElement=n;this.getParagraphStyleAttributes= -function(a){return(a=q(a))?h.getFormatting().getInheritedStyleAttributes(a):null};this.getPositionInTextNode=function(a,b){var e=gui.SelectionMover.createPositionIterator(m()),f=null,g,h=0,k=null;runtime.assert(0<=a,"position must be >= 0");1===d.acceptPosition(e)?(g=e.container(),g.nodeType===Node.TEXT_NODE&&(f=g,h=0)):a+=1;for(;0=d;d+=1){b=a.container();c=a.unfilteredDomOffset();if(b.nodeType===Node.TEXT_NODE&&" "===b.data[c]&&f.isSignificantWhitespace(b, +c)){runtime.assert(" "===b.data[c],"upgradeWhitespaceToElement: textNode.data[offset] should be a literal space");var e=b.ownerDocument.createElementNS("urn:oasis:names:tc:opendocument:xmlns:text:1.0","text:s");e.appendChild(b.ownerDocument.createTextNode(" "));b.deleteData(c,1);0= 0");1===r.acceptPosition(c)?(f=c.container(),f.nodeType===Node.TEXT_NODE&&(e=f,h=0)):a+=1;for(;0 @@ -1991,7 +2238,7 @@ ops.OdtDocument.signalParagraphChanged="paragraph/changed";ops.OdtDocument.signa @source: http://gitorious.org/webodf/webodf/ */ runtime.loadClass("ops.TrivialUserModel");runtime.loadClass("ops.TrivialOperationRouter");runtime.loadClass("ops.OperationFactory");runtime.loadClass("ops.OdtDocument"); -ops.Session=function(h){var m=new ops.OperationFactory,f=new ops.OdtDocument(h),n=new ops.TrivialUserModel,q=null;this.setUserModel=function(e){n=e};this.setOperationFactory=function(e){m=e;q&&q.setOperationFactory(m)};this.setOperationRouter=function(e){q=e;e.setPlaybackFunction(function(a){a.execute(f);f.emit(ops.OdtDocument.signalOperationExecuted,a)});e.setOperationFactory(m)};this.getUserModel=function(){return n};this.getOperationFactory=function(){return m};this.getOdtDocument=function(){return f}; -this.enqueue=function(e){q.push(e)};this.setOperationRouter(new ops.TrivialOperationRouter)}; -// Input 81 -var webodf_css="@namespace draw url(urn:oasis:names:tc:opendocument:xmlns:drawing:1.0);\n@namespace fo url(urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0);\n@namespace office url(urn:oasis:names:tc:opendocument:xmlns:office:1.0);\n@namespace presentation url(urn:oasis:names:tc:opendocument:xmlns:presentation:1.0);\n@namespace style url(urn:oasis:names:tc:opendocument:xmlns:style:1.0);\n@namespace svg url(urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0);\n@namespace table url(urn:oasis:names:tc:opendocument:xmlns:table:1.0);\n@namespace text url(urn:oasis:names:tc:opendocument:xmlns:text:1.0);\n@namespace runtimens url(urn:webodf); /* namespace for runtime only */\n@namespace cursor url(urn:webodf:names:cursor);\n@namespace editinfo url(urn:webodf:names:editinfo);\n\noffice|document > *, office|document-content > * {\n display: none;\n}\noffice|body, office|document {\n display: inline-block;\n position: relative;\n}\n\ntext|p, text|h {\n display: block;\n padding: 0;\n margin: 0;\n line-height: normal;\n position: relative;\n min-height: 1.3em; /* prevent empty paragraphs and headings from collapsing if they are empty */\n}\n*[runtimens|containsparagraphanchor] {\n position: relative;\n}\ntext|s {\n white-space: pre;\n}\ntext|tab {\n display: inline;\n white-space: pre;\n}\ntext|line-break {\n content: \" \";\n display: block;\n}\ntext|tracked-changes {\n /*Consumers that do not support change tracking, should ignore changes.*/\n display: none;\n}\noffice|binary-data {\n display: none;\n}\noffice|text {\n display: block;\n text-align: left;\n overflow: visible;\n word-wrap: break-word;\n}\n\noffice|text::selection {\n /** Let's not draw selection highlight that overflows into the office|text\n * node when selecting content across several paragraphs\n */\n background: transparent;\n}\n\noffice|spreadsheet {\n display: block;\n border-collapse: collapse;\n empty-cells: show;\n font-family: sans-serif;\n font-size: 10pt;\n text-align: left;\n page-break-inside: avoid;\n overflow: hidden;\n}\noffice|presentation {\n display: inline-block;\n text-align: left;\n}\n#shadowContent {\n display: inline-block;\n text-align: left;\n}\ndraw|page {\n display: block;\n position: relative;\n overflow: hidden;\n}\npresentation|notes, presentation|footer-decl, presentation|date-time-decl {\n display: none;\n}\n@media print {\n draw|page {\n border: 1pt solid black;\n page-break-inside: avoid;\n }\n presentation|notes {\n /*TODO*/\n }\n}\noffice|spreadsheet text|p {\n border: 0px;\n padding: 1px;\n margin: 0px;\n}\noffice|spreadsheet table|table {\n margin: 3px;\n}\noffice|spreadsheet table|table:after {\n /* show sheet name the end of the sheet */\n /*content: attr(table|name);*/ /* gives parsing error in opera */\n}\noffice|spreadsheet table|table-row {\n counter-increment: row;\n}\noffice|spreadsheet table|table-row:before {\n width: 3em;\n background: #cccccc;\n border: 1px solid black;\n text-align: center;\n content: counter(row);\n display: table-cell;\n}\noffice|spreadsheet table|table-cell {\n border: 1px solid #cccccc;\n}\ntable|table {\n display: table;\n}\ndraw|frame table|table {\n width: 100%;\n height: 100%;\n background: white;\n}\ntable|table-header-rows {\n display: table-header-group;\n}\ntable|table-row {\n display: table-row;\n}\ntable|table-column {\n display: table-column;\n}\ntable|table-cell {\n width: 0.889in;\n display: table-cell;\n word-break: break-all; /* prevent long words from extending out the table cell */\n}\ndraw|frame {\n display: block;\n}\ndraw|image {\n display: block;\n width: 100%;\n height: 100%;\n top: 0px;\n left: 0px;\n background-repeat: no-repeat;\n background-size: 100% 100%;\n -moz-background-size: 100% 100%;\n}\n/* only show the first image in frame */\ndraw|frame > draw|image:nth-of-type(n+2) {\n display: none;\n}\ntext|list:before {\n display: none;\n content:\"\";\n}\ntext|list {\n counter-reset: list;\n}\ntext|list-item {\n display: block;\n}\ntext|number {\n display:none;\n}\n\ntext|a {\n color: blue;\n text-decoration: underline;\n cursor: pointer;\n}\ntext|note-citation {\n vertical-align: super;\n font-size: smaller;\n}\ntext|note-body {\n display: none;\n}\ntext|note:hover text|note-citation {\n background: #dddddd;\n}\ntext|note:hover text|note-body {\n display: block;\n left:1em;\n max-width: 80%;\n position: absolute;\n background: #ffffaa;\n}\nsvg|title, svg|desc {\n display: none;\n}\nvideo {\n width: 100%;\n height: 100%\n}\n\n/* below set up the cursor */\ncursor|cursor {\n display: inline;\n width: 0px;\n height: 1em;\n /* making the position relative enables the avatar to use\n the cursor as reference for its absolute position */\n position: relative;\n}\ncursor|cursor > span {\n display: inline;\n position: absolute;\n height: 1em;\n border-left: 2px solid black;\n outline: none;\n}\n\ncursor|cursor > div {\n padding: 3px;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n border: none !important;\n border-radius: 5px;\n opacity: 0.3;\n}\n\ncursor|cursor > div > img {\n border-radius: 5px;\n}\n\ncursor|cursor > div.active {\n opacity: 0.8;\n}\n\ncursor|cursor > div:after {\n content: ' ';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 43%;\n}\n\n\n.editInfoMarker {\n position: absolute;\n width: 10px;\n height: 100%;\n left: -20px;\n opacity: 0.8;\n top: 0;\n border-radius: 5px;\n background-color: transparent;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n}\n.editInfoMarker:hover {\n box-shadow: 0px 0px 8px rgba(0, 0, 0, 1);\n}\n\n.editInfoHandle {\n position: absolute;\n background-color: black;\n padding: 5px;\n border-radius: 5px;\n opacity: 0.8;\n box-shadow: 0px 0px 5px rgba(50, 50, 50, 0.75);\n bottom: 100%;\n margin-bottom: 10px;\n z-index: 3;\n left: -25px;\n}\n.editInfoHandle:after {\n content: ' ';\n position: absolute;\n width: 0px;\n height: 0px;\n border-style: solid;\n border-width: 8.7px 5px 0 5px;\n border-color: black transparent transparent transparent;\n\n top: 100%;\n left: 5px;\n}\n.editInfo {\n font-family: sans-serif;\n font-weight: normal;\n font-style: normal;\n text-decoration: none;\n color: white;\n width: 100%;\n height: 12pt;\n}\n.editInfoColor {\n float: left;\n width: 10pt;\n height: 10pt;\n border: 1px solid white;\n}\n.editInfoAuthor {\n float: left;\n margin-left: 5pt;\n font-size: 10pt;\n text-align: left;\n height: 12pt;\n line-height: 12pt;\n}\n.editInfoTime {\n float: right;\n margin-left: 30pt;\n font-size: 8pt;\n font-style: italic;\n color: yellow;\n height: 12pt;\n line-height: 12pt;\n}\n"; +ops.Session=function(k){var g=new ops.OperationFactory,l=new ops.OdtDocument(k),h=new ops.TrivialUserModel,b=null;this.setUserModel=function(b){h=b};this.setOperationFactory=function(h){g=h;b&&b.setOperationFactory(g)};this.setOperationRouter=function(h){b=h;h.setPlaybackFunction(function(a){a.execute(l);l.emit(ops.OdtDocument.signalOperationExecuted,a)});h.setOperationFactory(g)};this.getUserModel=function(){return h};this.getOperationFactory=function(){return g};this.getOdtDocument=function(){return l}; +this.enqueue=function(g){b.push(g)};this.setOperationRouter(new ops.TrivialOperationRouter)}; +// Input 86 +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}\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.annotationNote {\n width: 4cm;\n position: absolute;\n display: inline;\n z-index: 10;\n}\n.annotationNote > office|annotation {\n display: block;\n}\n\n.annotationConnector {\n position: absolute;\n display: inline;\n z-index: 10;\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: inline-block;\n position: absolute;\n outline: 1px solid #ccc;\n}\n\n.annotationHighlight {\n background-color: yellow;\n position: relative;\n}\n";