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 runtime, odf, ops */
 26 
 27 /**
 28  * @constructor
 29  * @implements ops.Operation
 30  */
 31 ops.OpInsertImage = function OpInsertImage() {
 32     "use strict";
 33 
 34     var memberid, timestamp, position, filename, frameWidth, frameHeight, frameStyleName, frameName,
 35         drawns = odf.Namespaces.drawns,
 36         svgns = odf.Namespaces.svgns,
 37         textns = odf.Namespaces.textns,
 38         xlinkns = odf.Namespaces.xlinkns,
 39         odfUtils = odf.OdfUtils;
 40 
 41     /**
 42      * @param {!ops.OpInsertImage.InitSpec} data
 43      */
 44     this.init = function (data) {
 45         memberid = data.memberid;
 46         timestamp = data.timestamp;
 47         position = data.position;
 48         filename = data.filename;
 49         frameWidth = data.frameWidth;
 50         frameHeight = data.frameHeight;
 51         frameStyleName = data.frameStyleName;
 52         frameName = data.frameName;
 53     };
 54 
 55     this.isEdit = true;
 56     this.group = undefined;
 57 
 58     /**
 59      * @param {!Document} document
 60      * @return {!Element}
 61      */
 62     function createFrameElement(document) {
 63         var imageNode = document.createElementNS(drawns, 'draw:image'),
 64             frameNode = document.createElementNS(drawns, 'draw:frame');
 65 
 66         imageNode.setAttributeNS(xlinkns, 'xlink:href', filename);
 67         imageNode.setAttributeNS(xlinkns, 'xlink:type', 'simple');
 68         imageNode.setAttributeNS(xlinkns, 'xlink:show', 'embed');
 69         imageNode.setAttributeNS(xlinkns, 'xlink:actuate', 'onLoad');
 70 
 71         frameNode.setAttributeNS(drawns, 'draw:style-name', frameStyleName);
 72         frameNode.setAttributeNS(drawns, 'draw:name', frameName);
 73         frameNode.setAttributeNS(textns, 'text:anchor-type', 'as-char');
 74         frameNode.setAttributeNS(svgns, 'svg:width', frameWidth);
 75         frameNode.setAttributeNS(svgns, 'svg:height', frameHeight);
 76         frameNode.appendChild(imageNode);
 77 
 78         return frameNode;
 79     }
 80 
 81     /**
 82      * @param {!ops.Document} document
 83      */
 84     this.execute = function (document) {
 85         var odtDocument = /**@type{ops.OdtDocument}*/(document),
 86             odfCanvas = odtDocument.getOdfCanvas(),
 87             domPosition = odtDocument.getTextNodeAtStep(position, memberid),
 88             textNode, refNode, paragraphElement, frameElement;
 89 
 90         if (!domPosition) {
 91             return false;
 92         }
 93 
 94         textNode = domPosition.textNode;
 95         paragraphElement = odfUtils.getParagraphElement(textNode);
 96         refNode = domPosition.offset !== textNode.length ?
 97             textNode.splitText(domPosition.offset) : textNode.nextSibling;
 98         frameElement = createFrameElement(odtDocument.getDOMDocument());
 99         textNode.parentNode.insertBefore(frameElement, refNode);
100         odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position: position});
101 
102         // clean up any empty text node which was created by odtDocument.getTextNodeAtStep
103         if (textNode.length === 0) {
104             textNode.parentNode.removeChild(textNode);
105         }
106 
107         odfCanvas.addCssForFrameWithImage(frameElement);
108         odfCanvas.refreshCSS();
109         odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
110             paragraphElement: paragraphElement,
111             memberId: memberid,
112             timeStamp: timestamp
113         });
114         odfCanvas.rerenderAnnotations();
115         return true;
116     };
117 
118     /**
119      * @return {!ops.OpInsertImage.Spec}
120      */
121     this.spec = function () {
122         return {
123             optype: "InsertImage",
124             memberid: memberid,
125             timestamp: timestamp,
126             filename: filename,
127             position: position,
128             frameWidth: frameWidth,
129             frameHeight: frameHeight,
130             frameStyleName: frameStyleName,
131             frameName: frameName
132         };
133     };
134 };
135 /**@typedef{{
136     optype:string,
137     memberid:string,
138     timestamp:number,
139     filename:string,
140     position:number,
141     frameWidth:string,
142     frameHeight:string,
143     frameStyleName:string,
144     frameName:string
145 }}*/
146 ops.OpInsertImage.Spec;
147 /**@typedef{{
148     memberid:string,
149     timestamp:(number|undefined),
150     filename:string,
151     position:number,
152     frameWidth:string,
153     frameHeight:string,
154     frameStyleName:string,
155     frameName:string
156 }}*/
157 ops.OpInsertImage.InitSpec;
158