1 /** 2 * Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com> 3 * 4 * @licstart 5 * This file is part of WebODF. 6 * 7 * WebODF is free software: you can redistribute it and/or modify it 8 * under the terms of the GNU Affero General Public License (GNU AGPL) 9 * as published by the Free Software Foundation, either version 3 of 10 * the License, or (at your option) any later version. 11 * 12 * WebODF is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Affero General Public License for more details. 16 * 17 * You should have received a copy of the GNU Affero General Public License 18 * along with WebODF. If not, see <http://www.gnu.org/licenses/>. 19 * @licend 20 * 21 * @source: http://www.webodf.org/ 22 * @source: https://github.com/kogmbh/WebODF/ 23 */ 24 25 /*global ops, runtime, gui, odf, Node, core*/ 26 27 /** 28 * @constructor 29 * @implements ops.Operation 30 */ 31 ops.OpApplyDirectStyling = function OpApplyDirectStyling() { 32 "use strict"; 33 34 var memberid, timestamp, 35 /**@type {number}*/ 36 position, 37 /**@type {number}*/ 38 length, 39 setProperties, 40 odfUtils = new odf.OdfUtils(), 41 domUtils = new core.DomUtils(); 42 43 /** 44 * @param {!ops.OpApplyDirectStyling.InitSpec} data 45 */ 46 this.init = function (data) { 47 memberid = data.memberid; 48 timestamp = data.timestamp; 49 position = parseInt(data.position, 10); 50 length = parseInt(data.length, 10); 51 setProperties = data.setProperties; 52 }; 53 54 this.isEdit = true; 55 this.group = undefined; 56 57 /** 58 * Apply the specified style properties to all elements within the given range. 59 * Currently, only text styles are applied. 60 * @param {!ops.OdtDocument} odtDocument 61 * @param {!Range} range Range to apply text style to 62 * @param {!Object} info Style information. Only data within "style:text-properties" will be considered and applied 63 */ 64 function applyStyle(odtDocument, range, info) { 65 var odfCanvas = odtDocument.getOdfCanvas(), 66 odfContainer = odfCanvas.odfContainer(), 67 nextTextNodes = domUtils.splitBoundaries(range), 68 textNodes = odfUtils.getTextNodes(range, false), 69 textStyles; 70 71 textStyles = new odf.TextStyleApplicator( 72 new odf.ObjectNameGenerator(/**@type{!odf.OdfContainer}*/(odfContainer), memberid), // TODO: use the instance in SessionController 73 odtDocument.getFormatting(), 74 odfContainer.rootElement.automaticStyles 75 ); 76 textStyles.applyStyle(textNodes, range, info); 77 nextTextNodes.forEach(domUtils.normalizeTextNodes); 78 } 79 80 /** 81 * @param {!ops.Document} document 82 */ 83 this.execute = function (document) { 84 var odtDocument = /**@type{ops.OdtDocument}*/(document), 85 range = odtDocument.convertCursorToDomRange(position, length), 86 impactedParagraphs = odfUtils.getParagraphElements(range); 87 88 applyStyle(odtDocument, range, setProperties); 89 90 range.detach(); 91 odtDocument.getOdfCanvas().refreshCSS(); 92 odtDocument.fixCursorPositions(); // The container splits may leave the cursor in an invalid spot 93 94 impactedParagraphs.forEach(function (n) { 95 odtDocument.emit(ops.OdtDocument.signalParagraphChanged, { 96 paragraphElement: n, 97 memberId: memberid, 98 timeStamp: timestamp 99 }); 100 }); 101 102 odtDocument.getOdfCanvas().rerenderAnnotations(); 103 return true; 104 }; 105 106 /** 107 * @return {!ops.OpApplyDirectStyling.Spec} 108 */ 109 this.spec = function () { 110 return { 111 optype: "ApplyDirectStyling", 112 memberid: memberid, 113 timestamp: timestamp, 114 position: position, 115 length: length, 116 setProperties: setProperties 117 }; 118 }; 119 }; 120 /**@typedef{{ 121 optype:string, 122 memberid:string, 123 timestamp:number, 124 position:number, 125 length:number, 126 setProperties:!Object 127 }}*/ 128 ops.OpApplyDirectStyling.Spec; 129 /**@typedef{{ 130 memberid:string, 131 timestamp:(number|undefined), 132 position:number, 133 length:number, 134 setProperties:!Object 135 }}*/ 136 ops.OpApplyDirectStyling.InitSpec; 137