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