diff options
Diffstat (limited to 'js/dojo/dojox/gfx/utils.js')
| -rw-r--r-- | js/dojo/dojox/gfx/utils.js | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/js/dojo/dojox/gfx/utils.js b/js/dojo/dojox/gfx/utils.js new file mode 100644 index 0000000..2facaff --- /dev/null +++ b/js/dojo/dojox/gfx/utils.js @@ -0,0 +1,306 @@ +//>>built +define("dojox/gfx/utils", ["dojo/_base/kernel","dojo/_base/lang","./_base", "dojo/_base/html","dojo/_base/array", "dojo/_base/window", "dojo/_base/json", + "dojo/_base/Deferred", "dojo/_base/sniff", "require","dojo/_base/config"], + function(kernel, lang, g, html, arr, win, jsonLib, Deferred, has, require, config){ + var gu = g.utils = {}; + /*===== g= dojox.gfx; gu = dojox.gfx.utils; =====*/ + + lang.mixin(gu, { + forEach: function( + /*dojox.gfx.Surface|dojox.gfx.Shape*/ object, + /*Function|String|Array*/ f, /*Object?*/ o + ){ + // summary: + // Takes a shape or a surface and applies a function "f" to in the context of "o" + // (or global, if missing). If "shape" was a surface or a group, it applies the same + // function to all children recursively effectively visiting all shapes of the underlying scene graph. + // object : The gfx container to iterate. + // f : The function to apply. + // o : The scope. + o = o || win.global; + f.call(o, object); + if(object instanceof g.Surface || object instanceof g.Group){ + arr.forEach(object.children, function(shape){ + gu.forEach(shape, f, o); + }); + } + }, + + serialize: function( + /* dojox.gfx.Surface|dojox.gfx.Shape */ object + ){ + // summary: + // Takes a shape or a surface and returns a DOM object, which describes underlying shapes. + var t = {}, v, isSurface = object instanceof g.Surface; + if(isSurface || object instanceof g.Group){ + t.children = arr.map(object.children, gu.serialize); + if(isSurface){ + return t.children; // Array + } + }else{ + t.shape = object.getShape(); + } + if(object.getTransform){ + v = object.getTransform(); + if(v){ t.transform = v; } + } + if(object.getStroke){ + v = object.getStroke(); + if(v){ t.stroke = v; } + } + if(object.getFill){ + v = object.getFill(); + if(v){ t.fill = v; } + } + if(object.getFont){ + v = object.getFont(); + if(v){ t.font = v; } + } + return t; // Object + }, + + toJson: function( + /* dojox.gfx.Surface|dojox.gfx.Shape */ object, + /* Boolean? */ prettyPrint + ){ + // summary: + // Works just like serialize() but returns a JSON string. If prettyPrint is true, the string is pretty-printed to make it more human-readable. + return jsonLib.toJson(gu.serialize(object), prettyPrint); // String + }, + + deserialize: function( + /* dojox.gfx.Surface|dojox.gfx.Shape */ parent, + /* dojox.gfx.Shape|Array */ object + ){ + // summary: + // Takes a surface or a shape and populates it with an object produced by serialize(). + if(object instanceof Array){ + return arr.map(object, lang.hitch(null, gu.deserialize, parent)); // Array + } + var shape = ("shape" in object) ? parent.createShape(object.shape) : parent.createGroup(); + if("transform" in object){ + shape.setTransform(object.transform); + } + if("stroke" in object){ + shape.setStroke(object.stroke); + } + if("fill" in object){ + shape.setFill(object.fill); + } + if("font" in object){ + shape.setFont(object.font); + } + if("children" in object){ + arr.forEach(object.children, lang.hitch(null, gu.deserialize, shape)); + } + return shape; // dojox.gfx.Shape + }, + + fromJson: function( + /* dojox.gfx.Surface|dojox.gfx.Shape */ parent, + /* String */ json){ + // summary: + // Works just like deserialize() but takes a JSON representation of the object. + return gu.deserialize(parent, jsonLib.fromJson(json)); // Array || dojox.gfx.Shape + }, + + toSvg: function(/*GFX object*/surface){ + // summary: + // Function to serialize a GFX surface to SVG text. + // description: + // Function to serialize a GFX surface to SVG text. The value of this output + // is that there are numerous serverside parser libraries that can render + // SVG into images in various formats. This provides a way that GFX objects + // can be captured in a known format and sent serverside for serialization + // into an image. + // surface: + // The GFX surface to serialize. + // returns: + // Deferred object that will be called when SVG serialization is complete. + + //Since the init and even surface creation can be async, we need to + //return a deferred that will be called when content has serialized. + var deferred = new Deferred(); + + if(g.renderer === "svg"){ + //If we're already in SVG mode, this is easy and quick. + try{ + var svg = gu._cleanSvg(gu._innerXML(surface.rawNode)); + deferred.callback(svg); + }catch(e){ + deferred.errback(e); + } + }else{ + //Okay, now we have to get creative with hidden iframes and the like to + //serialize SVG. + if (!gu._initSvgSerializerDeferred) { + gu._initSvgSerializer(); + } + var jsonForm = gu.toJson(surface); + var serializer = function(){ + try{ + var sDim = surface.getDimensions(); + var width = sDim.width; + var height = sDim.height; + + //Create an attach point in the iframe for the contents. + var node = gu._gfxSvgProxy.document.createElement("div"); + gu._gfxSvgProxy.document.body.appendChild(node); + //Set the node scaling. + win.withDoc(gu._gfxSvgProxy.document, function() { + html.style(node, "width", width); + html.style(node, "height", height); + }, this); + + //Create temp surface to render object to and render. + var ts = gu._gfxSvgProxy[dojox._scopeName].gfx.createSurface(node, width, height); + + //It's apparently possible that a suface creation is async, so we need to use + //the whenLoaded function. Probably not needed for SVG, but making it common + var draw = function(surface) { + try{ + gu._gfxSvgProxy[dojox._scopeName].gfx.utils.fromJson(surface, jsonForm); + + //Get contents and remove temp surface. + var svg = gu._cleanSvg(node.innerHTML); + surface.clear(); + surface.destroy(); + gu._gfxSvgProxy.document.body.removeChild(node); + deferred.callback(svg); + }catch(e){ + deferred.errback(e); + } + }; + ts.whenLoaded(null,draw); + }catch (ex) { + deferred.errback(ex); + } + }; + //See if we can call it directly or pass it to the deferred to be + //called on initialization. + if(gu._initSvgSerializerDeferred.fired > 0){ + serializer(); + }else{ + gu._initSvgSerializerDeferred.addCallback(serializer); + } + } + return deferred; //dojo.Deferred that will be called when serialization finishes. + }, + + //iFrame document used for handling SVG serialization. + _gfxSvgProxy: null, + + //Serializer loaded. + _initSvgSerializerDeferred: null, + + _svgSerializerInitialized: function() { + // summary: + // Internal function to call when the serializer init completed. + // tags: + // private + gu._initSvgSerializerDeferred.callback(true); + }, + + _initSvgSerializer: function(){ + // summary: + // Internal function to initialize the hidden iframe where SVG rendering + // will occur. + // tags: + // private + if(!gu._initSvgSerializerDeferred){ + gu._initSvgSerializerDeferred = new Deferred(); + var f = win.doc.createElement("iframe"); + html.style(f, { + display: "none", + position: "absolute", + width: "1em", + height: "1em", + top: "-10000px" + }); + var intv; + if(has("ie")){ + f.onreadystatechange = function(){ + if(f.contentWindow.document.readyState == "complete"){ + f.onreadystatechange = function() {}; + intv = setInterval(function() { + if(f.contentWindow[kernel.scopeMap["dojo"][1]._scopeName] && + f.contentWindow[kernel.scopeMap["dojox"][1]._scopeName].gfx && + f.contentWindow[kernel.scopeMap["dojox"][1]._scopeName].gfx.utils){ + clearInterval(intv); + f.contentWindow.parent[kernel.scopeMap["dojox"][1]._scopeName].gfx.utils._gfxSvgProxy = f.contentWindow; + f.contentWindow.parent[kernel.scopeMap["dojox"][1]._scopeName].gfx.utils._svgSerializerInitialized(); + } + }, 50); + } + }; + }else{ + f.onload = function(){ + f.onload = function() {}; + intv = setInterval(function() { + if(f.contentWindow[kernel.scopeMap["dojo"][1]._scopeName] && + f.contentWindow[kernel.scopeMap["dojox"][1]._scopeName].gfx && + f.contentWindow[kernel.scopeMap["dojox"][1]._scopeName].gfx.utils){ + clearInterval(intv); + f.contentWindow.parent[kernel.scopeMap["dojox"][1]._scopeName].gfx.utils._gfxSvgProxy = f.contentWindow; + f.contentWindow.parent[kernel.scopeMap["dojox"][1]._scopeName].gfx.utils._svgSerializerInitialized(); + } + }, 50); + }; + } + //We have to load the GFX SVG proxy frame. Default is to use the one packaged in dojox. + var uri = (config["dojoxGfxSvgProxyFrameUrl"]||require.toUrl("dojox/gfx/resources/gfxSvgProxyFrame.html")); + f.setAttribute("src", uri.toString()); + win.body().appendChild(f); + } + }, + + _innerXML: function(/*Node*/node){ + // summary: + // Implementation of MS's innerXML function, borrowed from dojox.xml.parser. + // node: + // The node from which to generate the XML text representation. + // tags: + // private + if(node.innerXML){ + return node.innerXML; //String + }else if(node.xml){ + return node.xml; //String + }else if(typeof XMLSerializer != "undefined"){ + return (new XMLSerializer()).serializeToString(node); //String + } + return null; + }, + + _cleanSvg: function(svg) { + // summary: + // Internal function that cleans up artifacts in extracted SVG content. + // tags: + // private + if(svg){ + //Make sure the namespace is set. + if(svg.indexOf("xmlns=\"http://www.w3.org/2000/svg\"") == -1){ + svg = svg.substring(4, svg.length); + svg = "<svg xmlns=\"http://www.w3.org/2000/svg\"" + svg; + } + //Same for xmlns:xlink (missing in Chrome and Safari) + if(svg.indexOf("xmlns:xlink=\"http://www.w3.org/1999/xlink\"") == -1){ + svg = svg.substring(4, svg.length); + svg = "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\"" + svg; + } + //and add namespace to href attribute if not done yet + //(FF 5+ adds xlink:href but not the xmlns def) + if(svg.indexOf("xlink:href") === -1){ + svg = svg.replace(/href\s*=/g, "xlink:href="); + } + //Do some other cleanup, like stripping out the + //dojoGfx attributes and quoting ids. + svg = svg.replace(/\bdojoGfx\w*\s*=\s*(['"])\w*\1/g, ""); + svg = svg.replace(/\b__gfxObject__\s*=\s*(['"])\w*\1/g, ""); + svg = svg.replace(/[=]([^"']+?)(\s|>)/g,'="$1"$2'); + } + return svg; //Cleaned SVG text. + } + }); + + return gu; +}); |
