1 2 3 Polymer('core-iconset', { 4 5 /** 6 * The URL of the iconset image. 7 * 8 * @attribute src 9 * @type string 10 * @default '' 11 */ 12 src: '', 13 14 /** 15 * The width of the iconset image. This must only be specified if the 16 * icons are arranged into separate rows inside the image. 17 * 18 * @attribute width 19 * @type number 20 * @default 0 21 */ 22 width: 0, 23 24 /** 25 * A space separated list of names corresponding to icons in the iconset 26 * image file. This list must be ordered the same as the icon images 27 * in the image file. 28 * 29 * @attribute icons 30 * @type string 31 * @default '' 32 */ 33 icons: '', 34 35 /** 36 * The size of an individual icon. Note that icons must be square. 37 * 38 * @attribute iconSize 39 * @type number 40 * @default 24 41 */ 42 iconSize: 24, 43 44 /** 45 * The horizontal offset of the icon images in the inconset src image. 46 * This is typically used if the image resource contains additional images 47 * beside those intended for the iconset. 48 * 49 * @attribute offsetX 50 * @type number 51 * @default 0 52 */ 53 offsetX: 0, 54 /** 55 * The vertical offset of the icon images in the inconset src image. 56 * This is typically used if the image resource contains additional images 57 * beside those intended for the iconset. 58 * 59 * @attribute offsetY 60 * @type number 61 * @default 0 62 */ 63 offsetY: 0, 64 type: 'iconset', 65 66 created: function() { 67 this.iconMap = {}; 68 this.iconNames = []; 69 this.themes = {}; 70 }, 71 72 ready: function() { 73 // TODO(sorvell): ensure iconset's src is always relative to the main 74 // document 75 if (this.src && (this.ownerDocument !== document)) { 76 this.src = this.resolvePath(this.src, this.ownerDocument.baseURI); 77 } 78 this.super(); 79 this.updateThemes(); 80 }, 81 82 iconsChanged: function() { 83 var ox = this.offsetX; 84 var oy = this.offsetY; 85 this.icons && this.icons.split(/\s+/g).forEach(function(name, i) { 86 this.iconNames.push(name); 87 this.iconMap[name] = { 88 offsetX: ox, 89 offsetY: oy 90 } 91 if (ox + this.iconSize < this.width) { 92 ox += this.iconSize; 93 } else { 94 ox = this.offsetX; 95 oy += this.iconSize; 96 } 97 }, this); 98 }, 99 100 updateThemes: function() { 101 var ts = this.querySelectorAll('property[theme]'); 102 ts && ts.array().forEach(function(t) { 103 this.themes[t.getAttribute('theme')] = { 104 offsetX: parseInt(t.getAttribute('offsetX')) || 0, 105 offsetY: parseInt(t.getAttribute('offsetY')) || 0 106 }; 107 }, this); 108 }, 109 110 // TODO(ffu): support retrived by index e.g. getOffset(10); 111 /** 112 * Returns an object containing `offsetX` and `offsetY` properties which 113 * specify the pixel locaion in the iconset's src file for the given 114 * `icon` and `theme`. It's uncommon to call this method. It is useful, 115 * for example, to manually position a css backgroundImage to the proper 116 * offset. It's more common to use the `applyIcon` method. 117 * 118 * @method getOffset 119 * @param {String|Number} icon The name of the icon or the index of the 120 * icon within in the icon image. 121 * @param {String} theme The name of the theme. 122 * @returns {Object} An object specifying the offset of the given icon 123 * within the icon resource file; `offsetX` is the horizontal offset and 124 * `offsetY` is the vertical offset. Both values are in pixel units. 125 */ 126 getOffset: function(icon, theme) { 127 var i = this.iconMap[icon]; 128 if (!i) { 129 var n = this.iconNames[Number(icon)]; 130 i = this.iconMap[n]; 131 } 132 var t = this.themes[theme]; 133 if (i && t) { 134 return { 135 offsetX: i.offsetX + t.offsetX, 136 offsetY: i.offsetY + t.offsetY 137 } 138 } 139 return i; 140 }, 141 142 /** 143 * Applies an icon to the given element as a css background image. This 144 * method does not size the element, and it's often necessary to set 145 * the element's height and width so that the background image is visible. 146 * 147 * @method applyIcon 148 * @param {Element} element The element to which the background is 149 * applied. 150 * @param {String|Number} icon The name or index of the icon to apply. 151 * @param {Number} scale (optional, defaults to 1) A scaling factor 152 * with which the icon can be magnified. 153 * @return {Element} The icon element. 154 */ 155 applyIcon: function(element, icon, scale) { 156 var offset = this.getOffset(icon); 157 scale = scale || 1; 158 if (element && offset) { 159 var icon = element._icon || document.createElement('div'); 160 var style = icon.style; 161 style.backgroundImage = 'url(' + this.src + ')'; 162 style.backgroundPosition = (-offset.offsetX * scale + 'px') + 163 ' ' + (-offset.offsetY * scale + 'px'); 164 style.backgroundSize = scale === 1 ? 'auto' : 165 this.width * scale + 'px'; 166 if (icon.parentNode !== element) { 167 element.appendChild(icon); 168 } 169 return icon; 170 } 171 } 172 173 }); 174 175