-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathembedapi.js
173 lines (151 loc) · 7.16 KB
/
embedapi.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
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']);
- Pass functions in this format:
svgCanvas.setSvgString("string")
- Or if a callback is needed:
svgCanvas.setSvgString("string")(function(data, error){
if(error){
//there was an error
}else{
//handle data
}
})
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']);
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
this.frame = frame;
//this.stack = [] //callback stack
this.callbacks = {}; //successor to stack
this.encode = embedded_svg_edit.encode;
//List of functions extracted with this:
//Run in firebug on http://svg-edit.googlecode.com/svn/trunk/docs/files/svgcanvas-js.html
//for(var i=0,q=[],f = document.querySelectorAll("div.CFunction h3.CTitle a");i<f.length;i++){q.push(f[i].name)};q
//var functions = ["clearSelection", "addToSelection", "removeFromSelection", "open", "save", "getSvgString", "setSvgString",
//"createLayer", "deleteCurrentLayer", "setCurrentLayer", "renameCurrentLayer", "setCurrentLayerPosition", "setLayerVisibility",
//"moveSelectedToLayer", "clear"];
//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",
"removeFromSelection", "addNodeToSelection", "open", "save", "getSvgString", "setSvgString", "createLayer",
"deleteCurrentLayer", "getCurrentDrawing", "setCurrentLayer", "renameCurrentLayer", "setCurrentLayerPosition",
"setLayerVisibility", "moveSelectedToLayer", "clear", "clearPath", "getNodePoint", "clonePathNode", "deletePathNode",
"getResolution", "getImageTitle", "setImageTitle", "setResolution", "setBBoxZoom", "setZoom", "getMode", "setMode",
"getStrokeColor", "setStrokeColor", "getFillColor", "setFillColor", "setStrokePaint", "setFillPaint", "getStrokeWidth",
"setStrokeWidth", "getStrokeStyle", "setStrokeStyle", "getOpacity", "setOpacity", "getFillOpacity", "setFillOpacity",
"getStrokeOpacity", "setStrokeOpacity", "getTransformList", "getBBox", "getRotationAngle", "setRotationAngle", "each",
"bind", "setIdPrefix", "getBold", "setBold", "getItalic", "setItalic", "getFontFamily", "setFontFamily", "getFontSize",
"setFontSize", "getText", "setTextContent", "setImageURL", "setRectRadius", "setSegType", "quickClone",
"changeSelectedAttributeNoUndo", "changeSelectedAttribute", "deleteSelectedElements", "groupSelectedElements",
"ungroupSelectedElement", "moveToTopSelectedElement", "moveToBottomSelectedElement", "moveSelectedElements",
"getStrokedBBox", "getVisibleElements", "cycleElement", "getUndoStackSize", "getRedoStackSize", "getNextUndoCommandText",
"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: use AddEvent for Trident browsers, currently they dont support SVG, but they do support onmessage
var t = this;
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(0,6) != "error:"){
t.callbacks[cbid](eval("("+data.substr(cbid.length+1)+")"))
}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.encode = function(obj){
//simple partial JSON encoder implementation
if(window.JSON && JSON.stringify) return JSON.stringify(obj);
var enc = arguments.callee; //for purposes of recursion
if(typeof obj == "boolean" || typeof obj == "number"){
return obj+'' //should work...
}else if(typeof obj == "string"){
//a large portion of this is stolen from Douglas Crockford's json2.js
return '"'+
obj.replace(
/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g
, function (a) {
return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
})
+'"'; //note that this isn't quite as purtyful as the usualness
}else if(obj.length){ //simple hackish test for arrayish-ness
for(var i = 0; i < obj.length; i++){
obj[i] = enc(obj[i]); //encode every sub-thingy on top
}
return "["+obj.join(",")+"]";
}else{
var pairs = []; //pairs will be stored here
for(var k in obj){ //loop through thingys
pairs.push(enc(k)+":"+enc(obj[k])); //key: value
}
return "{"+pairs.join(",")+"}" //wrap in the braces
}
}
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(this.encode(args[i]))
}
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(",")+")","*");
}, 0);
return cbid;
//this.stack.shift()("svgCanvas['"+name+"']("+argstr.join(",")+")")
}