UNPKG

svg-boundings

Version:

Get bounding rect of SVG shape elements.

146 lines (129 loc) 4.64 kB
'use strict'; var Helper = require('../util/helper'); var RE_NUMBER_ATTRIBUTES = /^(?:[cr]?x\d?|[cr]?y\d?|width|height|r|letter\-spacing)$/i; function isSVGElement(object) { return ( typeof SVGElement === 'object' ? object instanceof SVGElement : object && typeof object === 'object' && object !== null && object.nodeType === 1 && typeof object.nodeName === 'string' ); } function isCheerioObject($object) { return $object.cheerio && typeof $object.attr === 'function'; } function type(object) { var type = object.type; if (isSVGElement(object)) type = object.nodeName; else if (isCheerioObject(object)) type = object.get(0).tagName; return type; } function attributesFromSVGElement(element, names) { var attributes = {}; names.forEach(function(name) { var value = element.getAttribute(name); if (RE_NUMBER_ATTRIBUTES.test(name)) value = parseFloat(value) || 0; if (name === 'transform' || name === 'gradientTransform') { if (value) {value = Helper.normalizeTransform(value);} } if (value != null) attributes[name] = value; }); attributes.type = element.nodeName; return attributes; } function attributesFromCheerioObject($element, names) { var attributes = {}; names.forEach(function(name) { var value = $element.attr(name); if (RE_NUMBER_ATTRIBUTES.test(name)) value = parseFloat(value) || 0; if (name === 'transform' || name === 'gradientTransform') { if (value) { value = Helper.normalizeTransform(value); } } if (value != null) attributes[name] = value; }); attributes.type = $element.get(0).tagName; return attributes; } function attributesFromElement(element, names) { if (isSVGElement(element)) return attributesFromSVGElement(element, names); else if (isCheerioObject(element)) return attributesFromCheerioObject(element, names); else return null; } function textObject(textEl) { var isSVGEl = false; if (isSVGElement(textEl)) isSVGEl = true; else if (isCheerioObject(textEl)) {} // do nothing else return null; var attributes = {}; var children = isSVGEl ? textEl.children : textEl.children(); // no <tspan> if (children.length === 0) { attributes = attributesFromElement(textEl, ['transform', 'font-size', 'letter-spacing']); attributes.text = isSVGEl ? textEl.textContent : textEl.text(); attributes.children = []; return attributes; } // has <tspan> attributes = attributesFromElement(textEl, ['transform', 'font-size', 'letter-spacing']); attributes.children = []; if (isSVGEl) { Array.prototype.forEach.call(children, function(childEl) { if (type(childEl) !== 'tspan') return; var obj = attributesFromElement(childEl, ['x', 'y', 'font-size', 'letter-spacing']); obj.text = childEl.textContent; attributes.children.push(obj); }); } else { children.each(function(i) { var $child = children.eq(i); if (type($child) !== 'tspan') return; var obj = attributesFromElement($child, ['x', 'y', 'font-size', 'letter-spacing']); obj.text = $child.text(); attributes.children.push(obj); }); } return attributes; } function elementObject(element) { if (element.constructor.name === 'Object') return element; var obj = null; switch(type(element).toLowerCase()) { case 'lineargradient': obj = attributesFromElement(element, ['x1', 'y1', 'x2', 'y2', 'gradientTransform']); break; case 'radialgradient': obj = attributesFromElement(element, ['cx', 'cy', 'r', 'fx', 'fy', 'gradientTransform']); break; case 'text': obj = textObject(element); break; case 'line': obj = attributesFromElement(element, ['x1', 'y1', 'x2', 'y2', 'stroke-width']); break; case 'rect': obj = attributesFromElement(element, ['x', 'y', 'width', 'height', 'transform', 'stroke-width']); break; case 'polyline': obj = attributesFromElement(element, ['points', 'stroke-width']); break; case 'polygon': obj = attributesFromElement(element, ['points', 'stroke-width']); break; case 'circle': obj = attributesFromElement(element, ['cx', 'cy', 'r', 'transform', 'stroke-width']); break; case 'ellipse': obj = attributesFromElement(element, ['cx', 'cy', 'rx', 'ry', 'transform', 'stroke-width']); break; case 'path': obj = attributesFromElement(element, ['d', 'stroke-width', 'transform']); break; case 'image': obj = attributesFromElement(element, ['width', 'height', 'transform']); break; } return obj; } module.exports = elementObject;