diff --git a/editor/embedapi.html b/editor/embedapi.html
index 1d9ff98e..d6fd32fc 100644
--- a/editor/embedapi.html
+++ b/editor/embedapi.html
@@ -1,19 +1,23 @@
-
-
+
+
+
Embed API
-
-
-
-
+
+
-
-
+
+
+
+
-
+
diff --git a/editor/embedapi.js b/editor/embedapi.js
index f16e3dd0..120ccbe5 100644
--- a/editor/embedapi.js
+++ b/editor/embedapi.js
@@ -1,42 +1,10 @@
/*
-function embedded_svg_edit(frame){
- //initialize communication
- this.frame = frame;
- this.stack = []; //callback stack
-
- var editapi = this;
-
- window.addEventListener("message", function(e){
- if(e.data.substr(0,5) == "ERROR"){
- editapi.stack.splice(0,1)[0](e.data,"error")
- }else{
- editapi.stack.splice(0,1)[0](e.data)
- }
- }, false)
-}
-
-embedded_svg_edit.prototype.call = function(code, callback){
- this.stack.push(callback);
- this.frame.contentWindow.postMessage(code,"*");
-}
-
-embedded_svg_edit.prototype.getSvgString = function(callback){
- this.call("svgCanvas.getSvgString()", callback)
-}
-
-embedded_svg_edit.prototype.setSvgString = function(svg){
- this.call("svgCanvas.setSvgString('"+svg.replace(/'/g, "\\'")+"')");
-}
-*/
-
-
-/*
Embedded SVG-edit API
General usage:
- Have an iframe somewhere pointing to a version of svg-edit > r1000
- Initialize the magic with:
-var svgCanvas = new embedded_svg_edit(window.frames['svgedit']);
+var svgCanvas = new EmbeddedSVGEdit(window.frames['svgedit']);
- Pass functions in this format:
svgCanvas.setSvgString("string")
- Or if a callback is needed:
@@ -52,15 +20,33 @@ Everything is done with the same API as the real svg-edit,
and all documentation is unchanged. The only difference is
when handling returns, the callback notation is used instead.
-var blah = new embedded_svg_edit(window.frames['svgedit']);
+var blah = new EmbeddedSVGEdit(window.frames['svgedit']);
blah.clearSelection("woot","blah",1337,[1,2,3,4,5,"moo"],-42,{a: "tree",b:6, c: 9})(function(){console.log("GET DATA",arguments)})
*/
-function embedded_svg_edit(frame){
- //initialize communication
+(function () {'use strict';
+
+var cbid = 0;
+
+function getCallbackSetter (d) {
+ return function(){
+ var t = this, // new callback
+ args = [].slice.call(arguments),
+ cbid = t.send(d, args, function(){}); // the callback (currently it's nothing, but will be set later)
+
+ return function(newcallback){
+ t.callbacks[cbid] = newcallback; // set callback
+ };
+ };
+}
+
+function EmbeddedSVGEdit(frame){
+ if (!(this instanceof EmbeddedSVGEdit)) { // Allow invocation without "new" keyword
+ return new EmbeddedSVGEdit(frame);
+ }
+ // initialize communication
this.frame = frame;
- //this.stack = [] //callback stack
- this.callbacks = {}; //successor to stack
+ this.callbacks = {}; // successor to stack
//List of functions extracted with this:
//Run in firebug on http://svg-edit.googlecode.com/svn/trunk/docs/files/svgcanvas-js.html
@@ -72,7 +58,9 @@ function embedded_svg_edit(frame){
//Newer, well, it extracts things that aren't documented as well. All functions accessible through the normal thingy can now be accessed though the API
//var l=[];for(var i in svgCanvas){if(typeof svgCanvas[i] == "function"){l.push(i)}};
//run in svgedit itself
- var functions = ["updateElementFromJson", "embedImage", "fixOperaXML", "clearSelection", "addToSelection",
+ var i,
+ t = this,
+ functions = ["updateElementFromJson", "embedImage", "fixOperaXML", "clearSelection", "addToSelection",
"removeFromSelection", "addNodeToSelection", "open", "save", "getSvgString", "setSvgString", "createLayer",
"deleteCurrentLayer", "getCurrentDrawing", "setCurrentLayer", "renameCurrentLayer", "setCurrentLayerPosition",
"setLayerVisibility", "moveSelectedToLayer", "clear", "clearPath", "getNodePoint", "clonePathNode", "deletePathNode",
@@ -88,51 +76,41 @@ function embedded_svg_edit(frame){
"getNextRedoCommandText", "undo", "redo", "cloneSelectedElements", "alignSelectedElements", "getZoom", "getVersion",
"setIconSize", "setLang", "setCustomHandlers"];
- //TODO: rewrite the following, it's pretty scary.
- for(var i = 0; i < functions.length; i++){
- this[functions[i]] = (function(d){
- return function(){
- var t = this; //new callback
- for(var g = 0, args = []; g < arguments.length; g++){
- args.push(arguments[g]);
- }
- var cbid = t.send(d, args, function(){}); //the callback (currently it's nothing, but will be set later
-
- return function(newcallback){
- t.callbacks[cbid] = newcallback; //set callback
- };
- };
- })(functions[i]);
+ // TODO: rewrite the following, it's pretty scary.
+ for(i = 0; i < functions.length; i++){
+ this[functions[i]] = getCallbackSetter(functions[i]);
}
- //TODO: use AddEvent for Trident browsers, currently they dont support SVG, but they do support onmessage
- var t = this;
+
+ // Older IE may need a polyfill for addEventListener, but so it would for SVG
window.addEventListener("message", function(e){
- if(e.data.substr(0,4) == "SVGe"){ //because svg-edit is too longish
- var data = e.data.substr(4);
- var cbid = data.substr(0, data.indexOf(";"));
- if(t.callbacks[cbid]){
- if(data.substr(cbid.length + 1,6) != "error:"){
- t.callbacks[cbid](eval("("+data.substr(cbid.length+1)+")"));
- }else{
- t.callbacks[cbid](data, "error");
- }
+ if (!e.data || typeof e.data !== "object" || e.data.namespace !== "svg-edit") {
+ return;
+ }
+ var data = e.data.result || e.data.error,
+ cbid = e.data.id;
+ if(t.callbacks[cbid]){
+ if(e.data.result){
+ t.callbacks[cbid](data);
+ }else{
+ t.callbacks[cbid](data, "error");
}
}
- //this.stack.shift()[0](e.data,e.data.substr(0,5) == "ERROR"?'error':null) //replace with shift
}, false);
}
-embedded_svg_edit.prototype.send = function(name, args, callback){
- var cbid = Math.floor(Math.random()*31776352877+993577).toString();
- //this.stack.push(callback);
- this.callbacks[cbid] = callback;
- for(var argstr = [], i = 0; i < args.length; i++){
- argstr.push(JSON.stringify(args[i]));
- }
+EmbeddedSVGEdit.prototype.send = function(name, args, callback){
var t = this;
- setTimeout(function(){//delay for the callback to be set in case its synchronous
- t.frame.contentWindow.postMessage(cbid+";svgCanvas['"+name+"']("+argstr.join(",")+")","*");
+ cbid++;
+
+ this.callbacks[cbid] = callback;
+ setTimeout(function(){ // delay for the callback to be set in case its synchronous
+ // Todo: Handle non-JSON arguments and return values (undefined, nonfinite numbers, functions, and built-in objects like Date, RegExp), etc.?
+ t.frame.contentWindow.postMessage({namespace: "svgCanvas", id: cbid, name: name, args: args}, '*');
}, 0);
return cbid;
- //this.stack.shift()("svgCanvas['"+name+"']("+argstr.join(",")+")")
};
+
+window.embedded_svg_edit = EmbeddedSVGEdit; // Export old, deprecated API
+window.EmbeddedSVGEdit = EmbeddedSVGEdit; // Follows common JS convention of CamelCase and, as enforced in JSLint, of initial caps for constructors
+
+}());
diff --git a/editor/extensions/ext-imagelib.js b/editor/extensions/ext-imagelib.js
index 9b2d3d29..5e9c27b3 100644
--- a/editor/extensions/ext-imagelib.js
+++ b/editor/extensions/ext-imagelib.js
@@ -64,7 +64,7 @@ svgEditor.addExtension("imagelib", function() {
// Receive postMessage data
var response = evt.data;
- if(!response) {
+ if(!response || typeof response !== "string") { // Todo: Should namespace postMessage API for this extension and filter out here
// Do nothing
return;
}
diff --git a/editor/svg-editor.js b/editor/svg-editor.js
index 1466bfbd..e13cd2e5 100644
--- a/editor/svg-editor.js
+++ b/editor/svg-editor.js
@@ -4571,11 +4571,16 @@
// Callback handler for embedapi.js
try {
window.addEventListener('message', function(e) {
- var cbid = parseInt(e.data.substr(0, e.data.indexOf(';')), 10);
+ if (!e.data || typeof e.data !== 'object' || e.data.namespace !== 'svgCanvas') {
+ return;
+ }
+ var cbid = e.data.id,
+ name = e.data.name,
+ args = e.data.args;
try {
- e.source.postMessage('SVGe'+cbid+';'+JSON.stringify(eval(e.data)), '*');
+ e.source.postMessage({namespace: 'svg-edit', id: cbid, result: svgCanvas[name](args)}, '*');
} catch(err) {
- e.source.postMessage('SVGe'+cbid+';error:'+err.message, '*');
+ e.source.postMessage({namespace: 'svg-edit', id: cbid, error: err.message}, '*');
}
}, false);
} catch(err) {