From 11f3f8c02a3af6d59751235c3523cdab238f595c Mon Sep 17 00:00:00 2001 From: Ananya Sen Date: Thu, 24 May 2012 16:50:01 -0700 Subject: - multiple element copy/paste - in progress Signed-off-by: Ananya Sen --- js/controllers/clipboard-controller.js | 268 ++++++++++++++++++++++++++------- 1 file changed, 210 insertions(+), 58 deletions(-) diff --git a/js/controllers/clipboard-controller.js b/js/controllers/clipboard-controller.js index 7b4f8f32..354933a1 100644 --- a/js/controllers/clipboard-controller.js +++ b/js/controllers/clipboard-controller.js @@ -9,9 +9,7 @@ No rights, expressed or implied, whatsoever to this software are provided by Mot var Montage = require("montage/core/core").Montage, Component = require("montage/ui/component").Component, NJUtils = require("js/lib/NJUtils").NJUtils, - World = require("js/lib/drawing/world").World, - ShapesController = require("js/controllers/elements/shapes-controller").ShapesController, - ShapeModel = require("js/models/shape-model").ShapeModel; + World = require("js/lib/drawing/world").World; var ClipboardController = exports.ClipboardController = Montage.create(Component, { hasTemplate: { @@ -33,7 +31,7 @@ var ClipboardController = exports.ClipboardController = Montage.create(Component }, copiedObjects:{ - value: null + value: [] }, _copyFlag:{ @@ -67,43 +65,12 @@ var ClipboardController = exports.ClipboardController = Montage.create(Component }, handleCopy:{ - value:function(clipboardEvent){ - var elem = null, computedStyles = null, originalStyleAttr = null, computedStylesStr = "", i=0, stylePropertyName=""; + value:function(clipboardEvent, test){ if(this.application.ninja.documentController.activeDocument.currentView === "code") return; - if(this.application.ninja.selectedElements.length > 0){ - //handling 1 selected element for now - - if(this.application.ninja.selectedElements[0].tagName === "CANVAS"){ - this.copiedObjects = this.application.ninja.selectedElements[0]; - } - - elem = this.application.ninja.selectedElements[0]; - originalStyleAttr = elem.getAttribute("style");//preserve the current styles - elem.removeAttribute("style"); + this.copy(clipboardEvent); - //build the computed style attribute - computedStyles = elem.ownerDocument.defaultView.getComputedStyle(elem); - - //todo: consider cleaning up the position data [or making posiiton:relative with 0,0] from the computed styles, - // so that the object is pasted onto expernal applicaitons [like gmail] with no offset - - for (i = 0; i < computedStyles.length; i++) { - stylePropertyName = computedStyles[i]; - computedStylesStr = computedStylesStr + stylePropertyName + ":" + computedStyles.getPropertyValue(stylePropertyName) + ";"; - } - elem.setAttribute("style", computedStylesStr); - - //set clipboard data - clipboardEvent.clipboardData.setData('text/html', ''+this.application.ninja.selectedElements[0].outerHTML);//copying first selected element for POC - //clipboardEvent.clipboardData.setData('ninja', 'test');//works - - elem.setAttribute("style", originalStyleAttr);//reset style after copying to clipboard - - //end - handling 1 selected element - - clipboardEvent.preventDefault(); - } + clipboardEvent.preventDefault(); } }, @@ -114,27 +81,125 @@ var ClipboardController = exports.ClipboardController = Montage.create(Component //TODO: return if stage is not focussed var clipboardData = clipboardEvent.clipboardData, + ninjaData = clipboardData.getData("ninja"), htmlData = clipboardData.getData("text/html"), textData = clipboardData.getData("text/plain"); - this.pasteItems(htmlData, textData); + this.pasteItems(ninjaData, htmlData, textData); clipboardEvent.preventDefault(); } }, - pasteItems:{ - value: function(htmlData, textData){ - var data = null, i=0, + pasteItems:{//todo: change to pasteNinja, pasteHTML, etc + value: function(ninjaData, htmlData, textData){ + var i=0, pasteDataObject=null, clipboardHelper=this.createClipboardHelper(), pastedElements = null, node = null, styles = null; - data = htmlData || textData; + if(ninjaData){//=> copy from ninja + //paste using in-memory clipboard helper + + + - if(htmlData){ + //TODO: cleanse HTML + + this.application.ninja.selectedElements.length = 0; + NJevent("selectionChange", {"elements": this.application.ninja.selectedElements, "isDocument": true} ); + + clipboardHelper.innerHTML = htmlData;//add the copied html to generate the nodes + + while(clipboardHelper.hasChildNodes()){ + if(clipboardHelper.lastChild.tagName === "META") { + clipboardHelper.removeChild(clipboardHelper.lastChild);//remove unnecesary meta tag + } + else if (clipboardHelper.lastChild.tagName === "CANVAS"){//temporary - we probably won't need to serialize this to the system clipboard + + //only handling 1 canvas for POC + + + //clone copied canvas + var canvas = document.application.njUtils.make("canvas", this.copiedObjects.className, this.application.ninja.currentDocument); + canvas.width = this.copiedObjects.width; + canvas.height = this.copiedObjects.height; + //end - clone copied canvas + + if (!canvas.getAttribute( "data-RDGE-id" )) canvas.setAttribute( "data-RDGE-id", NJUtils.generateRandom() ); + document.application.njUtils.createModelWithShape(canvas); + + styles = canvas.elementModel.data || {}; + styles.top = "" + (this.application.ninja.elementMediator.getProperty(this.copiedObjects, "top", parseInt) - 50) + "px"; + styles.left = "" + (this.application.ninja.elementMediator.getProperty(this.copiedObjects, "left", parseInt) - 50) + "px"; + + this.application.ninja.elementMediator.addElements(canvas, styles, false); + + var world, worldData = this.copiedObjects.elementModel.shapeModel.GLWorld.exportJSON(); + if(worldData) + { + + var jObj; + var index = worldData.indexOf( ';' ); + if ((worldData[0] === 'v') && (index < 24)) + { + // JSON format. separate the version info from the JSON info + var jStr = worldData.substr( index+1 ); + jObj = JSON.parse( jStr ); + + world = new World(canvas, jObj.webGL); + canvas.elementModel.shapeModel.GLWorld = world; + canvas.elementModel.shapeModel.useWebGl = jObj.webGL; + world.importJSON(jObj); + this.application.ninja.currentDocument.buildShapeModel( canvas.elementModel, world ); + } + + } + + NJevent("elementAdded", canvas); + + + clipboardHelper.removeChild(clipboardHelper.lastChild); + } + else if(clipboardHelper.lastChild.nodeType === 3){//TextNode + node = clipboardHelper.removeChild(clipboardHelper.lastChild); + + //USE styles controller to create the styles of the div and span + var doc = this.application.ninja.currentDocument ? this.application.ninja.currentDocument._document : document; + var aspan = doc.createElement("span"); + aspan.appendChild(node); + var adiv = doc.createElement("div"); + adiv.appendChild(aspan); + styles = {"top":"100px", "left":"100px"}; + + + this.pastePositioned(node, styles); + } + else { + node = clipboardHelper.removeChild(clipboardHelper.lastChild); + + if(node.removeAttribute) {node.removeAttribute("style");}//remove the computed styles attribute which is placed only for pasting to external applications + + //get class string while copying .... generate styles from class + //styles = {"top":"100px", "left":"100px"}; + + this.pastePositioned(node, styles); + } + + } + + this.application.ninja.documentController.activeDocument.needsSave = true; + + + + + + + return; + } + else if(htmlData){ //TODO: cleanse HTML this.application.ninja.selectedElements.length = 0; @@ -259,20 +324,6 @@ var ClipboardController = exports.ClipboardController = Montage.create(Component } }, - samplePasteJson:{ - value:{ - "htmlString" : "
", - "styles": {"position": "absolute", - "top": "304px", - "left": "318px", - "width": "125px", - "height": "71px", - "background-image": "none", - "background-color": "#2EFF5B"} - - } - }, - createClipboardHelper:{ value:function(){ var doc = this.application.ninja.currentDocument ? this.application.ninja.currentDocument._document : document, @@ -290,5 +341,106 @@ var ClipboardController = exports.ClipboardController = Montage.create(Component } return clipboardHelper; } + }, + + /* + parameters: + */ + copy:{ + value: function(clipboardEvent){ + var j=0, htmlToClipboard = "", ninjaClipboardObj = {}; + this.copiedObjects.length = 0; + + if(clipboardEvent){ + for(j=0; j < this.application.ninja.selectedElements.length; j++){//copying from stage + this.copiedObjects.push(this.application.ninja.selectedElements[j]); + + if(this.application.ninja.selectedElements[0].tagName === "CANVAS"){ + if(!ninjaClipboardObj.canvas){ + ninjaClipboardObj.canvas = true; + } + }else{ + htmlToClipboard = htmlToClipboard + this.prepareOuterHtml(this.application.ninja.selectedElements[j]); + if(!ninjaClipboardObj.plainHtml){ + ninjaClipboardObj.plainHtml = true; + } + } + + } + //set clipboard data + clipboardEvent.clipboardData.setData('ninja', '' + JSON.stringify(ninjaClipboardObj)); + clipboardEvent.clipboardData.setData('text/html', '' + htmlToClipboard + '');//copying first selected element for POC + } + } + }, + + prepareOuterHtml:{ + value: function(elem){ + var computedStyles = null, originalStyleAttr = null, computedStylesStr = "", i=0, stylePropertyName="", outerHtml = ""; + + originalStyleAttr = elem.getAttribute("style");//preserve the current styles + elem.removeAttribute("style"); + + //build the computed style attribute + computedStyles = elem.ownerDocument.defaultView.getComputedStyle(elem); + + //todo: consider cleaning up the position data [or making position:relative with 0,0] from the computed styles, + // so that the object is pasted onto expernal applicaitons [like gmail] with no offset + + for (i = 0; i < computedStyles.length; i++) { + stylePropertyName = computedStyles[i]; + computedStylesStr = computedStylesStr + stylePropertyName + ":" + computedStyles.getPropertyValue(stylePropertyName) + ";"; + } + elem.setAttribute("style", computedStylesStr); + + outerHtml = elem.outerHTML; + + elem.setAttribute("style", originalStyleAttr);//reset style after copying to clipboard + + + return outerHtml; + } + }, + + copyMontageComponents:{ + value: function(){ + + } + }, + + /* + parameters: + */ + paste:{ + value: function(){ + + } + }, + + pasteHTML:{ + value: function(){ + + } + }, + + pasteImage:{ + value:function(){ + + } + }, + + pasteCanvasObjects:{ + value:function(){ + + } + }, + + pasteMontageComponents:{ + value: function(){ + + } } + + + }); \ No newline at end of file -- cgit v1.2.3