/** * A jQuery module to work with SVG attributes. * @module jQueryAttr * @license MIT */ /** * This fixes `$(...).attr()` to work as expected with SVG elements. * Does not currently use `*AttributeNS()` since we rarely need that. * Adds {@link external:jQuery.fn.attr}. * See {@link https://api.jquery.com/attr/} for basic documentation of `.attr()`. * * Additional functionality: * - When getting attributes, a string that's a number is returned as type number. * - If an array is supplied as the first parameter, multiple values are returned * as an object with values for each given attribute. * @function module:jQueryAttr.jQueryAttr * @param {external:jQuery} $ The jQuery object to which to add the plug-in * @returns {external:jQuery} */ export default function jQueryPluginSVG ($) { const proxied = $.fn.attr, svgns = 'http://www.w3.org/2000/svg'; /** * @typedef {PlainObject} module:jQueryAttr.Attributes */ /** * @function external:jQuery.fn.attr * @param {string|string[]|PlainObject} key * @param {string} value * @returns {external:jQuery|module:jQueryAttr.Attributes} */ $.fn.attr = function (key, value) { const len = this.length; if (!len) { return proxied.call(this, key, value); } for (let i = 0; i < len; ++i) { const elem = this[i]; // set/get SVG attribute if (elem.namespaceURI === svgns) { // Setting attribute if (value !== undefined) { elem.setAttribute(key, value); } else if (Array.isArray(key)) { // Getting attributes from array const obj = {}; let j = key.length; while (j--) { const aname = key[j]; let attr = elem.getAttribute(aname); // This returns a number when appropriate if (attr || attr === '0') { attr = isNaN(attr) ? attr : (attr - 0); } obj[aname] = attr; } return obj; } if (typeof key === 'object') { // Setting attributes from object for (const [name, val] of Object.entries(key)) { elem.setAttribute(name, val); } // Getting attribute } else { let attr = elem.getAttribute(key); if (attr || attr === '0') { attr = isNaN(attr) ? attr : (attr - 0); } return attr; } } else { return proxied.call(this, key, value); } } return this; }; return $; }