Don't show merge option for detach
[scpubgit/stemmaweb.git] / root / js / jquery.svgdom.js
CommitLineData
5ba6c2b4 1/* http://keith-wood.name/svg.html\r
2 SVG/jQuery DOM compatibility for jQuery v1.4.3.\r
3 Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.\r
4 Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and \r
5 MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. \r
6 Please attribute the author if you use it. */\r
7\r
8(function($) { // Hide scope, no $ conflict\r
9\r
10/* Support adding class names to SVG nodes. */\r
11$.fn.addClass = function(origAddClass) {\r
12 return function(classNames) {\r
13 classNames = classNames || '';\r
14 return this.each(function() {\r
15 if (isSVGElem(this)) {\r
16 var node = this;\r
17 $.each(classNames.split(/\s+/), function(i, className) {\r
18 var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));\r
19 if ($.inArray(className, classes.split(/\s+/)) == -1) {\r
20 classes += (classes ? ' ' : '') + className;\r
21 (node.className ? node.className.baseVal = classes :\r
22 node.setAttribute('class', classes));\r
23 }\r
24 });\r
25 }\r
26 else {\r
27 origAddClass.apply($(this), [classNames]);\r
28 }\r
29 });\r
30 };\r
31}($.fn.addClass);\r
32\r
33/* Support removing class names from SVG nodes. */\r
34$.fn.removeClass = function(origRemoveClass) {\r
35 return function(classNames) {\r
36 classNames = classNames || '';\r
37 return this.each(function() {\r
38 if (isSVGElem(this)) {\r
39 var node = this;\r
40 $.each(classNames.split(/\s+/), function(i, className) {\r
41 var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));\r
42 classes = $.grep(classes.split(/\s+/), function(n, i) { return n != className; }).\r
43 join(' ');\r
44 (node.className ? node.className.baseVal = classes :\r
45 node.setAttribute('class', classes));\r
46 });\r
47 }\r
48 else {\r
49 origRemoveClass.apply($(this), [classNames]);\r
50 }\r
51 });\r
52 };\r
53}($.fn.removeClass);\r
54\r
55/* Support toggling class names on SVG nodes. */\r
56$.fn.toggleClass = function(origToggleClass) {\r
57 return function(className, state) {\r
58 return this.each(function() {\r
59 if (isSVGElem(this)) {\r
60 if (typeof state !== 'boolean') {\r
61 state = !$(this).hasClass(className);\r
62 }\r
63 $(this)[(state ? 'add' : 'remove') + 'Class'](className);\r
64 }\r
65 else {\r
66 origToggleClass.apply($(this), [className, state]);\r
67 }\r
68 });\r
69 };\r
70}($.fn.toggleClass);\r
71\r
72/* Support checking class names on SVG nodes. */\r
73$.fn.hasClass = function(origHasClass) {\r
74 return function(className) {\r
75 className = className || '';\r
76 var found = false;\r
77 this.each(function() {\r
78 if (isSVGElem(this)) {\r
79 var classes = (this.className ? this.className.baseVal :\r
80 this.getAttribute('class')).split(/\s+/);\r
81 found = ($.inArray(className, classes) > -1);\r
82 }\r
83 else {\r
84 found = (origHasClass.apply($(this), [className]));\r
85 }\r
86 return !found;\r
87 });\r
88 return found;\r
89 };\r
90}($.fn.hasClass);\r
91\r
92/* Support attributes on SVG nodes. */\r
93$.fn.attr = function(origAttr) {\r
94 return function(name, value, type) {\r
95 if (typeof name === 'string' && value === undefined) {\r
96 var val = origAttr.apply(this, [name, value, type]);\r
97 if (val && val.baseVal && val.baseVal.numberOfItems != null) { // Transform\r
98 value = '';\r
99 val = val.baseVal;\r
100 for (var i = 0; i < val.numberOfItems; i++) {\r
101 var item = val.getItem(i);\r
102 switch (item.type) {\r
103 case 1: value += ' matrix(' + item.matrix.a + ',' + item.matrix.b + ',' +\r
104 item.matrix.c + ',' + item.matrix.d + ',' +\r
105 item.matrix.e + ',' + item.matrix.f + ')';\r
106 break;\r
107 case 2: value += ' translate(' + item.matrix.e + ',' + item.matrix.f + ')'; break;\r
108 case 3: value += ' scale(' + item.matrix.a + ',' + item.matrix.d + ')'; break;\r
109 case 4: value += ' rotate(' + item.angle + ')'; break; // Doesn't handle new origin\r
110 case 5: value += ' skewX(' + item.angle + ')'; break;\r
111 case 6: value += ' skewY(' + item.angle + ')'; break;\r
112 }\r
113 }\r
114 val = value.substring(1);\r
115 }\r
116 return (val && val.baseVal ? val.baseVal.valueAsString : val);\r
117 }\r
118 var options = name;\r
119 if (typeof name === 'string') {\r
120 options = {};\r
121 options[name] = value;\r
122 }\r
123 return this.each(function() {\r
124 if (isSVGElem(this)) {\r
125 for (var n in options) {\r
126 var val = ($.isFunction(options[n]) ? options[n]() : options[n]);\r
127 (type ? this.style[n] = val : this.setAttribute(n, val));\r
128 }\r
129 }\r
130 else {\r
131 origAttr.apply($(this), [name, value, type]);\r
132 }\r
133 });\r
134 };\r
135}($.fn.attr);\r
136\r
137/* Support removing attributes on SVG nodes. */\r
138$.fn.removeAttr = function(origRemoveAttr) {\r
139 return function(name) {\r
140 return this.each(function() {\r
141 if (isSVGElem(this)) {\r
142 (this[name] && this[name].baseVal ? this[name].baseVal.value = '' :\r
143 this.setAttribute(name, ''));\r
144 }\r
145 else {\r
146 origRemoveAttr.apply($(this), [name]);\r
147 }\r
148 });\r
149 };\r
150}($.fn.removeAttr);\r
151\r
152/* Determine if any nodes are SVG nodes. */\r
153function anySVG(checkSet) {\r
154 for (var i = 0; i < checkSet.length; i++) {\r
155 if (checkSet[i].nodeType == 1 && checkSet[i].namespaceURI == $.svg.svgNS) {\r
156 return true;\r
157 }\r
158 }\r
159 return false;\r
160}\r
161\r
162/* Update Sizzle selectors. */\r
163\r
164$.expr.relative['+'] = function(origRelativeNext) {\r
165 return function(checkSet, part, isXML) {\r
166 origRelativeNext(checkSet, part, isXML || anySVG(checkSet));\r
167 };\r
168}($.expr.relative['+']);\r
169\r
170$.expr.relative['>'] = function(origRelativeChild) {\r
171 return function(checkSet, part, isXML) {\r
172 origRelativeChild(checkSet, part, isXML || anySVG(checkSet));\r
173 };\r
174}($.expr.relative['>']);\r
175\r
176$.expr.relative[''] = function(origRelativeDescendant) {\r
177 return function(checkSet, part, isXML) {\r
178 origRelativeDescendant(checkSet, part, isXML || anySVG(checkSet));\r
179 };\r
180}($.expr.relative['']);\r
181\r
182$.expr.relative['~'] = function(origRelativeSiblings) {\r
183 return function(checkSet, part, isXML) {\r
184 origRelativeSiblings(checkSet, part, isXML || anySVG(checkSet));\r
185 };\r
186}($.expr.relative['~']);\r
187\r
188$.expr.find.ID = function(origFindId) {\r
189 return function(match, context, isXML) {\r
190 return (isSVGElem(context) ?\r
191 [context.ownerDocument.getElementById(match[1])] :\r
192 origFindId(match, context, isXML));\r
193 };\r
194}($.expr.find.ID);\r
195\r
196var div = document.createElement('div');\r
197div.appendChild(document.createComment(''));\r
198if (div.getElementsByTagName('*').length > 0) { // Make sure no comments are found\r
199 $.expr.find.TAG = function(match, context) {\r
200 var results = context.getElementsByTagName(match[1]);\r
201 if (match[1] === '*') { // Filter out possible comments\r
202 var tmp = [];\r
203 for (var i = 0; results[i] || results.item(i); i++) {\r
204 if ((results[i] || results.item(i)).nodeType === 1) {\r
205 tmp.push(results[i] || results.item(i));\r
206 }\r
207 }\r
208 results = tmp;\r
209 }\r
210 return results;\r
211 };\r
212}\r
213\r
214$.expr.preFilter.CLASS = function(match, curLoop, inplace, result, not, isXML) {\r
215 match = ' ' + match[1].replace(/\\/g, '') + ' ';\r
216 if (isXML) {\r
217 return match;\r
218 }\r
219 for (var i = 0, elem = {}; elem != null; i++) {\r
220 elem = curLoop[i];\r
221 if (!elem) {\r
222 try {\r
223 elem = curLoop.item(i);\r
224 }\r
225 catch (e) {\r
226 // Ignore\r
227 }\r
228 }\r
229 if (elem) {\r
230 var className = (!isSVGElem(elem) ? elem.className :\r
231 (elem.className ? elem.className.baseVal : '') || elem.getAttribute('class'));\r
232 if (not ^ (className && (' ' + className + ' ').indexOf(match) > -1)) {\r
233 if (!inplace)\r
234 result.push(elem);\r
235 }\r
236 else if (inplace) {\r
237 curLoop[i] = false;\r
238 }\r
239 }\r
240 }\r
241 return false;\r
242};\r
243\r
244$.expr.filter.CLASS = function(elem, match) {\r
245 var className = (!isSVGElem(elem) ? elem.className :\r
246 (elem.className ? elem.className.baseVal : elem.getAttribute('class')));\r
247 return (' ' + className + ' ').indexOf(match) > -1;\r
248};\r
249\r
250$.expr.filter.ATTR = function(origFilterAttr) {\r
251 return function(elem, match) {\r
252 var handler = null;\r
253 if (isSVGElem(elem)) {\r
254 handler = match[1];\r
255 $.expr.attrHandle[handler] = function(elem){\r
256 var attr = elem.getAttribute(handler);\r
257 return attr && attr.baseVal || attr;\r
258 };\r
259 }\r
260 var filter = origFilterAttr(elem, match);\r
261 if (handler) {\r
262 $.expr.attrHandle[handler] = null;\r
263 }\r
264 return filter;\r
265 };\r
266}($.expr.filter.ATTR);\r
267\r
268/*\r
269 Change Sizzle initialisation (line 1425) in jQuery v1.3.2 base code...\r
270 \r
271 if ( toString.call(checkSet) === "[object Array]" ) {\r
272 if ( !prune ) {\r
273 results.push.apply( results, checkSet );\r
274 } else if ( context.nodeType === 1 ) {\r
275 for ( var i = 0; checkSet[i] != null; i++ ) {\r
276 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {\r
277 results.push( set[i] || set.item(i) ); // Here\r
278 }\r
279 }\r
280 } else {\r
281 for ( var i = 0; checkSet[i] != null; i++ ) {\r
282 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {\r
283 results.push( set[i] || set.item(i) ); // Here\r
284 }\r
285 }\r
286 }\r
287 }\r
288 \r
289 Change fallback makeArray (line 2076) implementation in jQuery Sizzle...\r
290 \r
291 if ( typeof array.length === "number" ) {\r
292 for ( var i = 0, l = array.length; i < l; i++ ) {\r
293 ret.push( array[i] || array.item(i) ); // Here\r
294 }\r
295 }\r
296*/\r
297\r
298/*\r
299 Events management requires changes to jQuery v1.3.2 base code...\r
300\r
301 In $.event.add (line 2437)...\r
302 \r
303 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {\r
304 // Bind the global event handler to the element\r
305 try { // Here\r
306 elem.addEventListener(type, handle, false);\r
307 }\r
308 catch(e) {\r
309 if (elem.attachEvent)\r
310 elem.attachEvent("on" + type, handle);\r
311 }\r
312 }\r
313\r
314 In $.event.remove (line 2521)...\r
315 \r
316 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {\r
317 try { // Here\r
318 elem.removeEventListener(type, jQuery.data(elem, "handle"), false);\r
319 }\r
320 catch (e) {\r
321 if (elem.detachEvent)\r
322 elem.detachEvent("on" + type, jQuery.data(elem, "handle"));\r
323 }\r
324 }\r
325*/\r
326\r
327/* Does this node belong to SVG? */\r
328function isSVGElem(node) {\r
329 return (node.nodeType == 1 && node.namespaceURI == $.svg.svgNS);\r
330}\r
331\r
332})(jQuery);\r