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         /**@type{!odf.Formatting.StyleData}*/
 40         setProperties,
 41         odfUtils = odf.OdfUtils,
 42         domUtils = core.DomUtils;
 43 
 44     /**
 45      * @param {!ops.OpApplyDirectStyling.InitSpec} data
 46      */
 47     this.init = function (data) {
 48         memberid = data.memberid;
 49         timestamp = data.timestamp;
 50         position = parseInt(data.position, 10);
 51         length = parseInt(data.length, 10);
 52         setProperties = data.setProperties;
 53     };
 54 
 55     this.isEdit = true;
 56     this.group = undefined;
 57 
 58     /**
 59      * Apply the specified style properties to all elements within the given range.
 60      * Currently, only text styles are applied.
 61      * @param {!ops.OdtDocument} odtDocument
 62      * @param {!Range} range Range to apply text style to
 63      * @param {!Object} info Style information. Only data within "style:text-properties" will be considered and applied
 64      */
 65     function applyStyle(odtDocument, range, info) {
 66         var odfCanvas = odtDocument.getOdfCanvas(),
 67             odfContainer = odfCanvas.odfContainer(),
 68             nextTextNodes = domUtils.splitBoundaries(range),
 69             textNodes = odfUtils.getTextNodes(range, false),
 70             textStyles;
 71 
 72         textStyles = new odf.TextStyleApplicator(
 73             new odf.ObjectNameGenerator(/**@type{!odf.OdfContainer}*/(odfContainer), memberid), // TODO: use the instance in SessionController
 74             odtDocument.getFormatting(),
 75             odfContainer.rootElement.automaticStyles
 76         );
 77         textStyles.applyStyle(textNodes, range, info);
 78         nextTextNodes.forEach(domUtils.normalizeTextNodes);
 79     }
 80 
 81     /**
 82      * @param {!ops.Document} document
 83      */
 84     this.execute = function (document) {
 85         var odtDocument = /**@type{ops.OdtDocument}*/(document),
 86             range = odtDocument.convertCursorToDomRange(position, length),
 87             impactedParagraphs = odfUtils.getParagraphElements(range);
 88 
 89         applyStyle(odtDocument, range, setProperties);
 90 
 91         range.detach();
 92         odtDocument.getOdfCanvas().refreshCSS();
 93         odtDocument.fixCursorPositions(); // The container splits may leave the cursor in an invalid spot
 94 
 95         impactedParagraphs.forEach(function (n) {
 96             odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
 97                 paragraphElement: n,
 98                 memberId: memberid,
 99                 timeStamp: timestamp
100             });
101         });
102 
103         odtDocument.getOdfCanvas().rerenderAnnotations();
104         return true;
105     };
106 
107     /**
108      * @return {!ops.OpApplyDirectStyling.Spec}
109      */
110     this.spec = function () {
111         return {
112             optype: "ApplyDirectStyling",
113             memberid: memberid,
114             timestamp: timestamp,
115             position: position,
116             length: length,
117             setProperties: setProperties
118         };
119     };
120 };
121 /**@typedef{{
122     optype:string,
123     memberid:string,
124     timestamp:number,
125     position:number,
126     length:number,
127     setProperties:!odf.Formatting.StyleData
128 }}*/
129 ops.OpApplyDirectStyling.Spec;
130 /**@typedef{{
131     memberid:string,
132     timestamp:(number|undefined),
133     position:number,
134     length:number,
135     setProperties:!odf.Formatting.StyleData
136 }}*/
137 ops.OpApplyDirectStyling.InitSpec;
138