Commit | Line | Data |
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 |
153 | function 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 |
196 | var div = document.createElement('div');\r |
197 | div.appendChild(document.createComment(''));\r |
198 | if (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 |
328 | function isSVGElem(node) {\r |
329 | return (node.nodeType == 1 && node.namespaceURI == $.svg.svgNS);\r |
330 | }\r |
331 | \r |
332 | })(jQuery);\r |