OLD | NEW |
(Empty) | |
| 1 |
| 2 |
| 3 Polymer({ |
| 4 |
| 5 is: 'iron-iconset-svg', |
| 6 |
| 7 properties: { |
| 8 |
| 9 /** |
| 10 * The name of the iconset. |
| 11 * |
| 12 * @attribute name |
| 13 * @type string |
| 14 * @default '' |
| 15 */ |
| 16 name: { |
| 17 type: String, |
| 18 observer: '_nameChanged' |
| 19 }, |
| 20 |
| 21 /** |
| 22 * Array of fully-qualitifed icon names in the iconset. |
| 23 */ |
| 24 iconNames: { |
| 25 type: Array, |
| 26 notify: true |
| 27 }, |
| 28 |
| 29 /** |
| 30 * The size of an individual icon. Note that icons must be square. |
| 31 * |
| 32 * @attribute iconSize |
| 33 * @type number |
| 34 * @default 24 |
| 35 */ |
| 36 size: { |
| 37 type: Number, |
| 38 value: 24 |
| 39 } |
| 40 |
| 41 }, |
| 42 |
| 43 /** |
| 44 * Applies an icon to the given element. |
| 45 * |
| 46 * An svg icon is prepended to the element's shadowRoot if it exists, |
| 47 * otherwise to the element itself. |
| 48 * |
| 49 * @method applyIcon |
| 50 * @param {Element} element Element to which the icon is applied. |
| 51 * @param {String} icon Name of the icon to apply. |
| 52 * @return {Element} The svg element which renders the icon. |
| 53 */ |
| 54 applyIcon: function(element, iconName) { |
| 55 // insert svg element into shadow root, if it exists |
| 56 element = element.root || element; |
| 57 // Remove old svg element |
| 58 this.removeIcon(element); |
| 59 // install new svg element |
| 60 var svg = this._cloneIcon(iconName); |
| 61 if (svg) { |
| 62 // TODO(sjmiles): I know, `with` is the devil ... except it isn't |
| 63 with (Polymer.dom(element)) { |
| 64 insertBefore(svg, childNodes[0]); |
| 65 } |
| 66 return element._svgIcon = svg; |
| 67 } |
| 68 }, |
| 69 |
| 70 /** |
| 71 * Remove an icon from the given element by undoing the changes effected |
| 72 * by `applyIcon`. |
| 73 * |
| 74 * @param {Element} element The element from which the icon is removed. |
| 75 */ |
| 76 removeIcon: function(element) { |
| 77 // Remove old svg element |
| 78 if (element._svgIcon) { |
| 79 Polymer.dom(element).removeChild(element._svgIcon); |
| 80 element._svgIcon = null; |
| 81 } |
| 82 }, |
| 83 |
| 84 /** |
| 85 * |
| 86 * When name is changed, either register a new iconset with the included |
| 87 * icons, or if there are no children, set up a meta-iconset. |
| 88 * |
| 89 */ |
| 90 _nameChanged: function() { |
| 91 new Polymer.IronMeta({type: 'iconset', key: this.name, value: this}); |
| 92 // icons (descendents) must exist a-priori |
| 93 this._icons = this._createIconMap(); |
| 94 this.iconNames = this._getIconNames(); |
| 95 }, |
| 96 |
| 97 /** |
| 98 * Array of all icon names in this iconset. |
| 99 * |
| 100 * @return {Array} Array of icon names. |
| 101 */ |
| 102 _getIconNames: function() { |
| 103 return Object.keys(this._icons).map(function(n) { |
| 104 return this.name + ':' + n; |
| 105 }, this); |
| 106 }, |
| 107 |
| 108 /** |
| 109 * Create a map of child SVG elements by id. |
| 110 * |
| 111 * @return {Object} Map of id's to SVG elements. |
| 112 */ |
| 113 _createIconMap: function() { |
| 114 // Objects chained to Object.prototype (`{}`) have members. Specifically, |
| 115 // on FF there is a `watch` method that confuses the icon map, so we |
| 116 // need to use a null-based object here. |
| 117 var icons = Object.create(null); |
| 118 Polymer.dom(this).querySelectorAll('[id]') |
| 119 .forEach(function(icon) { |
| 120 icons[icon.id] = icon; |
| 121 }); |
| 122 return icons; |
| 123 }, |
| 124 |
| 125 /** |
| 126 * Produce installable clone of the SVG element matching `id` in this |
| 127 * iconset, or `undefined` if there is no matching element. |
| 128 * |
| 129 * @return {Object} Returns an installable clone of the SVG element |
| 130 * matching `id`. |
| 131 */ |
| 132 _cloneIcon: function(id) { |
| 133 return this._prepareSvgClone(this._icons[id], this.size); |
| 134 }, |
| 135 |
| 136 _prepareSvgClone: function(sourceSvg, size) { |
| 137 if (sourceSvg) { |
| 138 var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); |
| 139 svg.setAttribute('viewBox', ['0', '0', size, size].join(' ')); |
| 140 svg.setAttribute('preserveAspectRatio', 'xMidYMid meet'); |
| 141 // TODO(dfreedm): `pointer-events: none` works around https://crbug.com/
370136 |
| 142 // TODO(sjmiles): inline style may not be ideal, but avoids requiring a
shadow-root |
| 143 svg.style.cssText = 'pointer-events: none; display: block; width: 100%;
height: 100%;'; |
| 144 svg.appendChild(sourceSvg.cloneNode(true)).removeAttribute('id'); |
| 145 return svg; |
| 146 } |
| 147 } |
| 148 |
| 149 }); |
OLD | NEW |