| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754 | 
							- <!DOCTYPE html>
 
- <html>
 
- <head>
 
-   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
-   <title>The source code</title>
 
-   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
 
-   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
 
-   <style type="text/css">
 
-     .highlight { display: block; background-color: #ddd; }
 
-   </style>
 
-   <script type="text/javascript">
 
-     function highlight() {
 
-       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
 
-     }
 
-   </script>
 
- </head>
 
- <body onload="prettyPrint(); highlight();">
 
-   <pre class="prettyprint lang-js"><span id='Ext-draw-engine-Svg'>/**
 
- </span> * Provides specific methods to draw with SVG.
 
-  */
 
- Ext.define('Ext.draw.engine.Svg', {
 
-     /* Begin Definitions */
 
-     extend: 'Ext.draw.Surface',
 
-     requires: ['Ext.draw.Draw', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.Element'],
 
-     /* End Definitions */
 
-     engine: 'Svg',
 
-     trimRe: /^\s+|\s+$/g,
 
-     spacesRe: /\s+/,
 
-     xlink: "http:/" + "/www.w3.org/1999/xlink",
 
-     translateAttrs: {
 
-         radius: "r",
 
-         radiusX: "rx",
 
-         radiusY: "ry",
 
-         path: "d",
 
-         lineWidth: "stroke-width",
 
-         fillOpacity: "fill-opacity",
 
-         strokeOpacity: "stroke-opacity",
 
-         strokeLinejoin: "stroke-linejoin"
 
-     },
 
-     parsers: {},
 
-     minDefaults: {
 
-         circle: {
 
-             cx: 0,
 
-             cy: 0,
 
-             r: 0,
 
-             fill: "none",
 
-             stroke: null,
 
-             "stroke-width": null,
 
-             opacity: null,
 
-             "fill-opacity": null,
 
-             "stroke-opacity": null
 
-         },
 
-         ellipse: {
 
-             cx: 0,
 
-             cy: 0,
 
-             rx: 0,
 
-             ry: 0,
 
-             fill: "none",
 
-             stroke: null,
 
-             "stroke-width": null,
 
-             opacity: null,
 
-             "fill-opacity": null,
 
-             "stroke-opacity": null
 
-         },
 
-         rect: {
 
-             x: 0,
 
-             y: 0,
 
-             width: 0,
 
-             height: 0,
 
-             rx: 0,
 
-             ry: 0,
 
-             fill: "none",
 
-             stroke: null,
 
-             "stroke-width": null,
 
-             opacity: null,
 
-             "fill-opacity": null,
 
-             "stroke-opacity": null
 
-         },
 
-         text: {
 
-             x: 0,
 
-             y: 0,
 
-             "text-anchor": "start",
 
-             "font-family": null,
 
-             "font-size": null,
 
-             "font-weight": null,
 
-             "font-style": null,
 
-             fill: "#000",
 
-             stroke: null,
 
-             "stroke-width": null,
 
-             opacity: null,
 
-             "fill-opacity": null,
 
-             "stroke-opacity": null
 
-         },
 
-         path: {
 
-             d: "M0,0",
 
-             fill: "none",
 
-             stroke: null,
 
-             "stroke-width": null,
 
-             opacity: null,
 
-             "fill-opacity": null,
 
-             "stroke-opacity": null
 
-         },
 
-         image: {
 
-             x: 0,
 
-             y: 0,
 
-             width: 0,
 
-             height: 0,
 
-             preserveAspectRatio: "none",
 
-             opacity: null
 
-         }
 
-     },
 
-     createSvgElement: function(type, attrs) {
 
-         var el = this.domRef.createElementNS("http:/" + "/www.w3.org/2000/svg", type),
 
-             key;
 
-         if (attrs) {
 
-             for (key in attrs) {
 
-                 el.setAttribute(key, String(attrs[key]));
 
-             }
 
-         }
 
-         return el;
 
-     },
 
-     createSpriteElement: function(sprite) {
 
-         // Create svg element and append to the DOM.
 
-         var el = this.createSvgElement(sprite.type);
 
-         el.id = sprite.id;
 
-         if (el.style) {
 
-             el.style.webkitTapHighlightColor = "rgba(0,0,0,0)";
 
-         }
 
-         sprite.el = Ext.get(el);
 
-         this.applyZIndex(sprite); //performs the insertion
 
-         sprite.matrix = new Ext.draw.Matrix();
 
-         sprite.bbox = {
 
-             plain: 0,
 
-             transform: 0
 
-         };
 
-         this.applyAttrs(sprite);
 
-         this.applyTransformations(sprite);
 
-         sprite.fireEvent("render", sprite);
 
-         return el;
 
-     },
 
-     
 
-     getBBoxText: function (sprite) {
 
-         var bbox = {},
 
-             bb, height, width, i, ln, el;
 
-         if (sprite && sprite.el) {
 
-             el = sprite.el.dom;
 
-             try {
 
-                 bbox = el.getBBox();
 
-                 return bbox;
 
-             } catch(e) {
 
-                 // Firefox 3.0.x plays badly here
 
-             }
 
-             bbox = {x: bbox.x, y: Infinity, width: 0, height: 0};
 
-             ln = el.getNumberOfChars();
 
-             for (i = 0; i < ln; i++) {
 
-                 bb = el.getExtentOfChar(i);
 
-                 bbox.y = Math.min(bb.y, bbox.y);
 
-                 height = bb.y + bb.height - bbox.y;
 
-                 bbox.height = Math.max(bbox.height, height);
 
-                 width = bb.x + bb.width - bbox.x;
 
-                 bbox.width = Math.max(bbox.width, width);
 
-             }
 
-             return bbox;
 
-         }
 
-     },
 
-     hide: function() {
 
-         Ext.get(this.el).hide();
 
-     },
 
-     show: function() {
 
-         Ext.get(this.el).show();
 
-     },
 
-     hidePrim: function(sprite) {
 
-         this.addCls(sprite, Ext.baseCSSPrefix + 'hide-visibility');
 
-     },
 
-     showPrim: function(sprite) {
 
-         this.removeCls(sprite, Ext.baseCSSPrefix + 'hide-visibility');
 
-     },
 
-     getDefs: function() {
 
-         return this._defs || (this._defs = this.createSvgElement("defs"));
 
-     },
 
-     transform: function(sprite, matrixOnly) {
 
-         var me = this,
 
-             matrix = new Ext.draw.Matrix(),
 
-             transforms = sprite.transformations,
 
-             transformsLength = transforms.length,
 
-             i = 0,
 
-             transform, type;
 
-             
 
-         for (; i < transformsLength; i++) {
 
-             transform = transforms[i];
 
-             type = transform.type;
 
-             if (type == "translate") {
 
-                 matrix.translate(transform.x, transform.y);
 
-             }
 
-             else if (type == "rotate") {
 
-                 matrix.rotate(transform.degrees, transform.x, transform.y);
 
-             }
 
-             else if (type == "scale") {
 
-                 matrix.scale(transform.x, transform.y, transform.centerX, transform.centerY);
 
-             }
 
-         }
 
-         sprite.matrix = matrix;
 
-         if (!matrixOnly) {
 
-             sprite.el.set({transform: matrix.toSvg()});
 
-         }
 
-     },
 
-     setSize: function(width, height) {
 
-         var me = this,
 
-             el = me.el;
 
-         
 
-         width = +width || me.width;
 
-         height = +height || me.height;
 
-         me.width = width;
 
-         me.height = height;
 
-         el.setSize(width, height);
 
-         el.set({
 
-             width: width,
 
-             height: height
 
-         });
 
-         me.callParent([width, height]);
 
-     },
 
- <span id='Ext-draw-engine-Svg-method-getRegion'>    /**
 
- </span>     * Get the region for the surface's canvas area
 
-      * @returns {Ext.util.Region}
 
-      */
 
-     getRegion: function() {
 
-         // Mozilla requires using the background rect because the svg element returns an
 
-         // incorrect region. Webkit gives no region for the rect and must use the svg element.
 
-         var svgXY = this.el.getXY(),
 
-             rectXY = this.bgRect.getXY(),
 
-             max = Math.max,
 
-             x = max(svgXY[0], rectXY[0]),
 
-             y = max(svgXY[1], rectXY[1]);
 
-         return {
 
-             left: x,
 
-             top: y,
 
-             right: x + this.width,
 
-             bottom: y + this.height
 
-         };
 
-     },
 
-     onRemove: function(sprite) {
 
-         if (sprite.el) {
 
-             sprite.el.destroy();
 
-             delete sprite.el;
 
-         }
 
-         this.callParent(arguments);
 
-     },
 
-     
 
-     setViewBox: function(x, y, width, height) {
 
-         if (isFinite(x) && isFinite(y) && isFinite(width) && isFinite(height)) {
 
-             this.callParent(arguments);
 
-             this.el.dom.setAttribute("viewBox", [x, y, width, height].join(" "));
 
-         }
 
-     },
 
-     render: function (container) {
 
-         var me = this,
 
-             width,
 
-             height,
 
-             el,
 
-             defs,
 
-             bgRect,
 
-             webkitRect;
 
-         if (!me.el) {
 
-             width = me.width || 0;
 
-             height = me.height || 0;
 
-             el = me.createSvgElement('svg', {
 
-                 xmlns: "http:/" + "/www.w3.org/2000/svg",
 
-                 version: 1.1,
 
-                 width: width,
 
-                 height: height
 
-             });
 
-             defs = me.getDefs();
 
-             // Create a rect that is always the same size as the svg root; this serves 2 purposes:
 
-             // (1) It allows mouse events to be fired over empty areas in Webkit, and (2) we can
 
-             // use it rather than the svg element for retrieving the correct client rect of the
 
-             // surface in Mozilla (see https://bugzilla.mozilla.org/show_bug.cgi?id=530985)
 
-             bgRect = me.createSvgElement("rect", {
 
-                 width: "100%",
 
-                 height: "100%",
 
-                 fill: "#000",
 
-                 stroke: "none",
 
-                 opacity: 0
 
-             });
 
-             
 
-             if (Ext.isSafari3) {
 
-                 // Rect that we will show/hide to fix old WebKit bug with rendering issues.
 
-                 webkitRect = me.createSvgElement("rect", {
 
-                     x: -10,
 
-                     y: -10,
 
-                     width: "110%",
 
-                     height: "110%",
 
-                     fill: "none",
 
-                     stroke: "#000"
 
-                 });
 
-             }
 
-             el.appendChild(defs);
 
-             if (Ext.isSafari3) {
 
-                 el.appendChild(webkitRect);
 
-             }
 
-             el.appendChild(bgRect);
 
-             container.appendChild(el);
 
-             me.el = Ext.get(el);
 
-             me.bgRect = Ext.get(bgRect);
 
-             if (Ext.isSafari3) {
 
-                 me.webkitRect = Ext.get(webkitRect);
 
-                 me.webkitRect.hide();
 
-             }
 
-             me.el.on({
 
-                 scope: me,
 
-                 mouseup: me.onMouseUp,
 
-                 mousedown: me.onMouseDown,
 
-                 mouseover: me.onMouseOver,
 
-                 mouseout: me.onMouseOut,
 
-                 mousemove: me.onMouseMove,
 
-                 mouseenter: me.onMouseEnter,
 
-                 mouseleave: me.onMouseLeave,
 
-                 click: me.onClick,
 
-                 dblclick: me.onDblClick
 
-             });
 
-         }
 
-         me.renderAll();
 
-     },
 
-     // private
 
-     onMouseEnter: function(e) {
 
-         if (this.el.parent().getRegion().contains(e.getPoint())) {
 
-             this.fireEvent('mouseenter', e);
 
-         }
 
-     },
 
-     // private
 
-     onMouseLeave: function(e) {
 
-         if (!this.el.parent().getRegion().contains(e.getPoint())) {
 
-             this.fireEvent('mouseleave', e);
 
-         }
 
-     },
 
-     // @private - Normalize a delegated single event from the main container to each sprite and sprite group
 
-     processEvent: function(name, e) {
 
-         var target = e.getTarget(),
 
-             surface = this.surface,
 
-             sprite;
 
-         this.fireEvent(name, e);
 
-         // We wrap text types in a tspan, sprite is the parent.
 
-         if (target.nodeName == "tspan" && target.parentNode) {
 
-             target = target.parentNode;
 
-         }
 
-         sprite = this.items.get(target.id);
 
-         if (sprite) {
 
-             sprite.fireEvent(name, sprite, e);
 
-         }
 
-     },
 
-     /* @private - Wrap SVG text inside a tspan to allow for line wrapping.  In addition this normallizes
 
-      * the baseline for text the vertical middle of the text to be the same as VML.
 
-      */
 
-     tuneText: function (sprite, attrs) {
 
-         var el = sprite.el.dom,
 
-             tspans = [],
 
-             height, tspan, text, i, ln, texts, factor, x;
 
-         if (attrs.hasOwnProperty("text")) {
 
-             //only create new tspans for text lines if the text has been 
 
-             //updated or if it's the first time we're setting the text
 
-             //into the sprite.
 
-             //get the actual rendered text.
 
-             text = sprite.tspans && Ext.Array.map(sprite.tspans, function(t) { return t.textContent; }).join('');
 
-             if (!sprite.tspans || attrs.text != text) {
 
-                 tspans = this.setText(sprite, attrs.text);
 
-                 sprite.tspans = tspans;
 
-             //for all other cases reuse the tspans previously created.
 
-             } else {
 
-                 tspans = sprite.tspans || [];
 
-             }
 
-         }
 
-         // Normalize baseline via a DY shift of first tspan. Shift other rows by height * line height (1.2)
 
-         if (tspans.length) {
 
-             height = this.getBBoxText(sprite).height;
 
-             x = sprite.el.dom.getAttribute("x");
 
-             for (i = 0, ln = tspans.length; i < ln; i++) {
 
-                 // The text baseline for FireFox 3.0 and 3.5 is different than other SVG implementations
 
-                 // so we are going to normalize that here
 
-                 factor = (Ext.isFF3_0 || Ext.isFF3_5) ? 2 : 4;
 
-                 tspans[i].setAttribute("x", x);
 
-                 tspans[i].setAttribute("dy", i ? height * 1.2 : height / factor);
 
-             }
 
-             sprite.dirty = true;
 
-         }
 
-     },
 
-     setText: function(sprite, textString) {
 
-          var me = this,
 
-              el = sprite.el.dom,
 
-              tspans = [],
 
-              height, tspan, text, i, ln, texts;
 
-         
 
-         while (el.firstChild) {
 
-             el.removeChild(el.firstChild);
 
-         }
 
-         // Wrap each row into tspan to emulate rows
 
-         texts = String(textString).split("\n");
 
-         for (i = 0, ln = texts.length; i < ln; i++) {
 
-             text = texts[i];
 
-             if (text) {
 
-                 tspan = me.createSvgElement("tspan");
 
-                 tspan.appendChild(document.createTextNode(Ext.htmlDecode(text)));
 
-                 el.appendChild(tspan);
 
-                 tspans[i] = tspan;
 
-             }
 
-         }
 
-         return tspans;
 
-     },
 
-     renderAll: function() {
 
-         this.items.each(this.renderItem, this);
 
-     },
 
-     renderItem: function (sprite) {
 
-         if (!this.el) {
 
-             return;
 
-         }
 
-         if (!sprite.el) {
 
-             this.createSpriteElement(sprite);
 
-         }
 
-         if (sprite.zIndexDirty) {
 
-             this.applyZIndex(sprite);
 
-         }
 
-         if (sprite.dirty) {
 
-             this.applyAttrs(sprite);
 
-             if (sprite.dirtyTransform) {
 
-                 this.applyTransformations(sprite);
 
-             }
 
-         }
 
-     },
 
-     redraw: function(sprite) {
 
-         sprite.dirty = sprite.zIndexDirty = true;
 
-         this.renderItem(sprite);
 
-     },
 
-     applyAttrs: function (sprite) {
 
-         var me = this,
 
-             el = sprite.el,
 
-             group = sprite.group,
 
-             sattr = sprite.attr,
 
-             parsers = me.parsers,
 
-             //Safari does not handle linear gradients correctly in quirksmode
 
-             //ref: https://bugs.webkit.org/show_bug.cgi?id=41952
 
-             //ref: EXTJSIV-1472
 
-             gradientsMap = me.gradientsMap || {},
 
-             safariFix = Ext.isSafari && !Ext.isStrict,
 
-             groups, i, ln, attrs, font, key, style, name, rect;
 
-         if (group) {
 
-             groups = [].concat(group);
 
-             ln = groups.length;
 
-             for (i = 0; i < ln; i++) {
 
-                 group = groups[i];
 
-                 me.getGroup(group).add(sprite);
 
-             }
 
-             delete sprite.group;
 
-         }
 
-         attrs = me.scrubAttrs(sprite) || {};
 
-         // if (sprite.dirtyPath) {
 
-             sprite.bbox.plain = 0;
 
-             sprite.bbox.transform = 0;
 
-             if (sprite.type == "circle" || sprite.type == "ellipse") {
 
-                 attrs.cx = attrs.cx || attrs.x;
 
-                 attrs.cy = attrs.cy || attrs.y;
 
-             }
 
-             else if (sprite.type == "rect") {
 
-                 attrs.rx = attrs.ry = attrs.r;
 
-             }
 
-             else if (sprite.type == "path" && attrs.d) {
 
-                 attrs.d = Ext.draw.Draw.pathToString(Ext.draw.Draw.pathToAbsolute(attrs.d));
 
-             }
 
-             sprite.dirtyPath = false;
 
-         // }
 
-         // else {
 
-         //     delete attrs.d;
 
-         // }
 
-         if (attrs['clip-rect']) {
 
-             me.setClip(sprite, attrs);
 
-             delete attrs['clip-rect'];
 
-         }
 
-         if (sprite.type == 'text' && attrs.font && sprite.dirtyFont) {
 
-             el.set({ style: "font: " + attrs.font});
 
-         }
 
-         if (sprite.type == "image") {
 
-             el.dom.setAttributeNS(me.xlink, "href", attrs.src);
 
-         }
 
-         Ext.applyIf(attrs, me.minDefaults[sprite.type]);
 
-         if (sprite.dirtyHidden) {
 
-             (sattr.hidden) ? me.hidePrim(sprite) : me.showPrim(sprite);
 
-             sprite.dirtyHidden = false;
 
-         }
 
-         for (key in attrs) {
 
-             if (attrs.hasOwnProperty(key) && attrs[key] != null) {
 
-                 //Safari does not handle linear gradients correctly in quirksmode
 
-                 //ref: https://bugs.webkit.org/show_bug.cgi?id=41952
 
-                 //ref: EXTJSIV-1472
 
-                 //if we're Safari in QuirksMode and we're applying some color attribute and the value of that
 
-                 //attribute is a reference to a gradient then assign a plain color to that value instead of the gradient.
 
-                 if (safariFix && ('color|stroke|fill'.indexOf(key) > -1) && (attrs[key] in gradientsMap)) {
 
-                     attrs[key] = gradientsMap[attrs[key]];
 
-                 }
 
-                 //hidden is not a proper SVG attribute.
 
-                 if (key == 'hidden' && sprite.type == 'text') {
 
-                     continue;
 
-                 }
 
-                 if (key in parsers) {
 
-                     el.dom.setAttribute(key, parsers[key](attrs[key], sprite, me));
 
-                 } else {
 
-                     el.dom.setAttribute(key, attrs[key]);
 
-                 }
 
-             }
 
-         }
 
-         
 
-         if (sprite.type == 'text') {
 
-             me.tuneText(sprite, attrs);
 
-         }
 
-         sprite.dirtyFont = false;
 
-         //set styles
 
-         style = sattr.style;
 
-         if (style) {
 
-             el.setStyle(style);
 
-         }
 
-         sprite.dirty = false;
 
-         if (Ext.isSafari3) {
 
-             // Refreshing the view to fix bug EXTJSIV-1: rendering issue in old Safari 3
 
-             me.webkitRect.show();
 
-             setTimeout(function () {
 
-                 me.webkitRect.hide();
 
-             });
 
-         }
 
-     },
 
-     setClip: function(sprite, params) {
 
-         var me = this,
 
-             rect = params["clip-rect"],
 
-             clipEl, clipPath;
 
-         if (rect) {
 
-             if (sprite.clip) {
 
-                 sprite.clip.parentNode.parentNode.removeChild(sprite.clip.parentNode);
 
-             }
 
-             clipEl = me.createSvgElement('clipPath');
 
-             clipPath = me.createSvgElement('rect');
 
-             clipEl.id = Ext.id(null, 'ext-clip-');
 
-             clipPath.setAttribute("x", rect.x);
 
-             clipPath.setAttribute("y", rect.y);
 
-             clipPath.setAttribute("width", rect.width);
 
-             clipPath.setAttribute("height", rect.height);
 
-             clipEl.appendChild(clipPath);
 
-             me.getDefs().appendChild(clipEl);
 
-             sprite.el.dom.setAttribute("clip-path", "url(#" + clipEl.id + ")");
 
-             sprite.clip = clipPath;
 
-         } 
 
-         // if (!attrs[key]) {
 
-         //     var clip = Ext.getDoc().dom.getElementById(sprite.el.getAttribute("clip-path").replace(/(^url\(#|\)$)/g, ""));
 
-         //     clip && clip.parentNode.removeChild(clip);
 
-         //     sprite.el.setAttribute("clip-path", "");
 
-         //     delete attrss.clip;
 
-         // }
 
-     },
 
- <span id='Ext-draw-engine-Svg-method-applyZIndex'>    /**
 
- </span>     * Insert or move a given sprite's element to the correct place in the DOM list for its zIndex
 
-      * @param {Ext.draw.Sprite} sprite
 
-      */
 
-     applyZIndex: function(sprite) {
 
-         var me = this,
 
-             items = me.items,
 
-             idx = items.indexOf(sprite),
 
-             el = sprite.el,
 
-             prevEl;
 
-         if (me.el.dom.childNodes[idx + 2] !== el.dom) { //shift by 2 to account for defs and bg rect
 
-             if (idx > 0) {
 
-                 // Find the first previous sprite which has its DOM element created already
 
-                 do {
 
-                     prevEl = items.getAt(--idx).el;
 
-                 } while (!prevEl && idx > 0);
 
-             }
 
-             el.insertAfter(prevEl || me.bgRect);
 
-         }
 
-         sprite.zIndexDirty = false;
 
-     },
 
-     createItem: function (config) {
 
-         var sprite = new Ext.draw.Sprite(config);
 
-         sprite.surface = this;
 
-         return sprite;
 
-     },
 
-     addGradient: function(gradient) {
 
-         gradient = Ext.draw.Draw.parseGradient(gradient);
 
-         var me = this,
 
-             ln = gradient.stops.length,
 
-             vector = gradient.vector,
 
-             //Safari does not handle linear gradients correctly in quirksmode
 
-             //ref: https://bugs.webkit.org/show_bug.cgi?id=41952
 
-             //ref: EXTJSIV-1472
 
-             usePlain = Ext.isSafari && !Ext.isStrict,
 
-             gradientEl, stop, stopEl, i, gradientsMap;
 
-             
 
-         gradientsMap = me.gradientsMap || {};
 
-         
 
-         if (!usePlain) {
 
-             if (gradient.type == "linear") {
 
-                 gradientEl = me.createSvgElement("linearGradient");
 
-                 gradientEl.setAttribute("x1", vector[0]);
 
-                 gradientEl.setAttribute("y1", vector[1]);
 
-                 gradientEl.setAttribute("x2", vector[2]);
 
-                 gradientEl.setAttribute("y2", vector[3]);
 
-             }
 
-             else {
 
-                 gradientEl = me.createSvgElement("radialGradient");
 
-                 gradientEl.setAttribute("cx", gradient.centerX);
 
-                 gradientEl.setAttribute("cy", gradient.centerY);
 
-                 gradientEl.setAttribute("r", gradient.radius);
 
-                 if (Ext.isNumber(gradient.focalX) && Ext.isNumber(gradient.focalY)) {
 
-                     gradientEl.setAttribute("fx", gradient.focalX);
 
-                     gradientEl.setAttribute("fy", gradient.focalY);
 
-                 }
 
-             }
 
-             gradientEl.id = gradient.id;
 
-             me.getDefs().appendChild(gradientEl);
 
-             for (i = 0; i < ln; i++) {
 
-                 stop = gradient.stops[i];
 
-                 stopEl = me.createSvgElement("stop");
 
-                 stopEl.setAttribute("offset", stop.offset + "%");
 
-                 stopEl.setAttribute("stop-color", stop.color);
 
-                 stopEl.setAttribute("stop-opacity",stop.opacity);
 
-                 gradientEl.appendChild(stopEl);
 
-             }
 
-         } else {
 
-             gradientsMap['url(#' + gradient.id + ')'] = gradient.stops[0].color;
 
-         }
 
-         me.gradientsMap = gradientsMap;
 
-     },
 
- <span id='Ext-draw-engine-Svg-method-hasCls'>    /**
 
- </span>     * Checks if the specified CSS class exists on this element's DOM node.
 
-      * @param {Ext.draw.Sprite} sprite The sprite to look into.
 
-      * @param {String} className The CSS class to check for
 
-      * @return {Boolean} True if the class exists, else false
 
-      */
 
-     hasCls: function(sprite, className) {
 
-         return className && (' ' + (sprite.el.dom.getAttribute('class') || '') + ' ').indexOf(' ' + className + ' ') != -1;
 
-     },
 
-     addCls: function(sprite, className) {
 
-         var el = sprite.el,
 
-             i,
 
-             len,
 
-             v,
 
-             cls = [],
 
-             curCls =  el.getAttribute('class') || '';
 
-         // Separate case is for speed
 
-         if (!Ext.isArray(className)) {
 
-             if (typeof className == 'string' && !this.hasCls(sprite, className)) {
 
-                 el.set({ 'class': curCls + ' ' + className });
 
-             }
 
-         }
 
-         else {
 
-             for (i = 0, len = className.length; i < len; i++) {
 
-                 v = className[i];
 
-                 if (typeof v == 'string' && (' ' + curCls + ' ').indexOf(' ' + v + ' ') == -1) {
 
-                     cls.push(v);
 
-                 }
 
-             }
 
-             if (cls.length) {
 
-                 el.set({ 'class': ' ' + cls.join(' ') });
 
-             }
 
-         }
 
-     },
 
-     removeCls: function(sprite, className) {
 
-         var me = this,
 
-             el = sprite.el,
 
-             curCls =  el.getAttribute('class') || '',
 
-             i, idx, len, cls, elClasses;
 
-         if (!Ext.isArray(className)){
 
-             className = [className];
 
-         }
 
-         if (curCls) {
 
-             elClasses = curCls.replace(me.trimRe, ' ').split(me.spacesRe);
 
-             for (i = 0, len = className.length; i < len; i++) {
 
-                 cls = className[i];
 
-                 if (typeof cls == 'string') {
 
-                     cls = cls.replace(me.trimRe, '');
 
-                     idx = Ext.Array.indexOf(elClasses, cls);
 
-                     if (idx != -1) {
 
-                         Ext.Array.erase(elClasses, idx, 1);
 
-                     }
 
-                 }
 
-             }
 
-             el.set({ 'class': elClasses.join(' ') });
 
-         }
 
-     },
 
-     destroy: function() {
 
-         var me = this;
 
-         
 
-         me.callParent();
 
-         if (me.el) {
 
-             me.el.remove();
 
-         }
 
-         if (me._defs) {
 
-             Ext.get(me._defs).destroy();
 
-         }
 
-         if (me.bgRect) {
 
-             Ext.get(me.bgRect).destroy();
 
-         }
 
-         if (me.webkitRect) {
 
-             Ext.get(me.webkitRect).destroy();
 
-         }
 
-         delete me.el;
 
-     }
 
- });
 
- </pre>
 
- </body>
 
- </html>
 
 
  |