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