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, odf, runtime*/
 26 
 27 /**
 28  * Sets the paragraph style name of the specified paragraph.
 29  * The supplied position argument is expected to be the first
 30  * step within the paragraph.
 31  *
 32  * @constructor
 33  * @implements ops.Operation
 34  */
 35 ops.OpSetParagraphStyle = function OpSetParagraphStyle() {
 36     "use strict";
 37 
 38     var memberid, timestamp, position, styleName,
 39         textns = "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
 40         odfUtils = odf.OdfUtils;
 41 
 42     /**
 43      * @param {!ops.OpSetParagraphStyle.InitSpec} data
 44      */
 45     this.init = function (data) {
 46         memberid = data.memberid;
 47         timestamp = data.timestamp;
 48         position = data.position;
 49         styleName = data.styleName;
 50     };
 51 
 52     this.isEdit = true;
 53     this.group = undefined;
 54 
 55     /**
 56      * Returns true if the iterator is set to the first step within the paragraph
 57      *
 58      * @param {!ops.OdtDocument} odtDocument
 59      * @param {!Node} paragraphNode
 60      * @param {!core.PositionIterator} iterator
 61      * @return {!boolean}
 62      */
 63     function isFirstStep(odtDocument, paragraphNode, iterator) {
 64         var filters = [odtDocument.getPositionFilter()],
 65             container = iterator.container(),
 66             offset = iterator.unfilteredDomOffset(),
 67             stepIterator = odtDocument.createStepIterator(container, offset, filters, paragraphNode);
 68 
 69         return stepIterator.previousStep() === false;
 70     }
 71 
 72     /**
 73      * @param {!ops.Document} document
 74      */
 75     this.execute = function (document) {
 76         var odtDocument = /**@type{ops.OdtDocument}*/(document),
 77             iterator,
 78             paragraphNode;
 79 
 80         iterator = odtDocument.getIteratorAtPosition(position);
 81         paragraphNode = odfUtils.getParagraphElement(iterator.container());
 82         if (paragraphNode) {
 83             runtime.assert(isFirstStep(odtDocument, paragraphNode, iterator),
 84                 "SetParagraphStyle position should be the first position in the paragraph");
 85             if (styleName) {
 86                 paragraphNode.setAttributeNS(textns, 'text:style-name', styleName);
 87             } else {
 88                 paragraphNode.removeAttributeNS(textns, 'style-name');
 89             }
 90 
 91             odtDocument.getOdfCanvas().refreshSize();
 92             odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
 93                 paragraphElement: paragraphNode,
 94                 timeStamp: timestamp,
 95                 memberId: memberid
 96             });
 97 
 98             odtDocument.getOdfCanvas().rerenderAnnotations();
 99             return true;
100         }
101         return false;
102     };
103 
104     /**
105      * @return {!ops.OpSetParagraphStyle.Spec}
106      */
107     this.spec = function () {
108         return {
109             optype: "SetParagraphStyle",
110             memberid: memberid,
111             timestamp: timestamp,
112             position: position,
113             styleName: styleName
114         };
115     };
116 };
117 /**@typedef{{
118     optype:string,
119     memberid:string,
120     timestamp:number,
121     position:number,
122     styleName:string
123 }}*/
124 ops.OpSetParagraphStyle.Spec;
125 /**@typedef{{
126     memberid:string,
127     timestamp:(number|undefined),
128     position:number,
129     styleName:string
130 }}*/
131 ops.OpSetParagraphStyle.InitSpec;
132