242 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!--
 | 
						|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
 | 
						|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 | 
						|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 | 
						|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 | 
						|
Code distributed by Google as part of the polymer project is also
 | 
						|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 | 
						|
-->
 | 
						|
 | 
						|
<!--
 | 
						|
/**
 | 
						|
 * @group Polymer Core Elements
 | 
						|
 *
 | 
						|
 * The `core-iconset` element allows users to define their own icon sets. 
 | 
						|
 * The `src` property specifies the url of the icon image. Multiple icons may
 | 
						|
 * be included in this image and they may be organized into rows.
 | 
						|
 * The `icons` property is a space separated list of names corresponding to the
 | 
						|
 * icons. The names must be ordered as the icons are ordered in the icon image.
 | 
						|
 * Icons are expected to be square and are the size specified by the `iconSize`
 | 
						|
 * property. The `width` property corresponds to the width of the icon image 
 | 
						|
 * and must be specified if icons are arranged into multiple rows in the image.
 | 
						|
 *
 | 
						|
 * All `core-iconset` elements are available for use by other `core-iconset`
 | 
						|
 * elements via a database keyed by id. Typically, an element author that wants
 | 
						|
 * to support a set of custom icons uses a `core-iconset` to retrieve 
 | 
						|
 * and use another, user-defined iconset.
 | 
						|
 *
 | 
						|
 * Example:
 | 
						|
 *
 | 
						|
 *     <core-iconset id="my-icons" src="my-icons.png" width="96" iconSize="24"
 | 
						|
 *         icons="location place starta stopb bus car train walk">
 | 
						|
 *     </core-iconset>
 | 
						|
 *
 | 
						|
 * This will automatically register the icon set "my-icons" to the iconset
 | 
						|
 * database.  To use these icons from within another element, make a 
 | 
						|
 * `core-iconset` element and call the `byId` method to retrieve a
 | 
						|
 * given iconset. To apply a particular icon to an element, use the 
 | 
						|
 * `applyIcon` method. For example:
 | 
						|
 *
 | 
						|
 *     iconset.applyIcon(iconNode, 'car');
 | 
						|
 *
 | 
						|
 * Themed icon sets are also supported. The `core-iconset` can contain child
 | 
						|
 * `property` elements that specify a theme with an offsetX and offsetY of the
 | 
						|
 * theme within the icon resource. For example.
 | 
						|
 *
 | 
						|
 *     <core-iconset id="my-icons" src="my-icons.png" width="96" iconSize="24"
 | 
						|
 *         icons="location place starta stopb bus car train walk">
 | 
						|
 *       <property theme="special" offsetX="256" offsetY="24"></property>
 | 
						|
 *     </core-iconset>
 | 
						|
 *
 | 
						|
 * Then a themed icon can be applied like this:
 | 
						|
 *
 | 
						|
 *     iconset.applyIcon(iconNode, 'car', 'special');
 | 
						|
 *
 | 
						|
 * @element core-iconset
 | 
						|
 * @extends core-meta
 | 
						|
 * @homepage github.io
 | 
						|
 */
 | 
						|
-->
 | 
						|
 | 
						|
<link rel="import" href="../core-meta/core-meta.html">
 | 
						|
 | 
						|
<polymer-element name="core-iconset" extends="core-meta" attributes="src width icons iconSize">
 | 
						|
  
 | 
						|
  <script>
 | 
						|
  
 | 
						|
    Polymer('core-iconset', {
 | 
						|
  
 | 
						|
      /**
 | 
						|
       * The URL of the iconset image.
 | 
						|
       *
 | 
						|
       * @attribute src
 | 
						|
       * @type string
 | 
						|
       * @default ''
 | 
						|
       */
 | 
						|
      src: '',
 | 
						|
 | 
						|
      /**
 | 
						|
       * The width of the iconset image. This must only be specified if the
 | 
						|
       * icons are arranged into separate rows inside the image.
 | 
						|
       *
 | 
						|
       * @attribute width
 | 
						|
       * @type number
 | 
						|
       * @default 0
 | 
						|
       */
 | 
						|
      width: 0,
 | 
						|
 | 
						|
      /**
 | 
						|
       * A space separated list of names corresponding to icons in the iconset
 | 
						|
       * image file. This list must be ordered the same as the icon images
 | 
						|
       * in the image file.
 | 
						|
       *
 | 
						|
       * @attribute icons
 | 
						|
       * @type string
 | 
						|
       * @default ''
 | 
						|
       */
 | 
						|
      icons: '',
 | 
						|
 | 
						|
      /**
 | 
						|
       * The size of an individual icon. Note that icons must be square.
 | 
						|
       *
 | 
						|
       * @attribute iconSize
 | 
						|
       * @type number
 | 
						|
       * @default 24
 | 
						|
       */
 | 
						|
      iconSize: 24,
 | 
						|
 | 
						|
      /**
 | 
						|
       * The horizontal offset of the icon images in the inconset src image.
 | 
						|
       * This is typically used if the image resource contains additional images
 | 
						|
       * beside those intended for the iconset.
 | 
						|
       *
 | 
						|
       * @attribute offsetX
 | 
						|
       * @type number
 | 
						|
       * @default 0
 | 
						|
       */
 | 
						|
      offsetX: 0,
 | 
						|
      /**
 | 
						|
       * The vertical offset of the icon images in the inconset src image.
 | 
						|
       * This is typically used if the image resource contains additional images
 | 
						|
       * beside those intended for the iconset.
 | 
						|
       *
 | 
						|
       * @attribute offsetY
 | 
						|
       * @type number
 | 
						|
       * @default 0
 | 
						|
       */
 | 
						|
      offsetY: 0,
 | 
						|
      type: 'iconset',
 | 
						|
 | 
						|
      created: function() {
 | 
						|
        this.iconMap = {};
 | 
						|
        this.iconNames = [];
 | 
						|
        this.themes = {};
 | 
						|
      },
 | 
						|
  
 | 
						|
      ready: function() {
 | 
						|
        // TODO(sorvell): ensure iconset's src is always relative to the main
 | 
						|
        // document
 | 
						|
        if (this.src && (this.ownerDocument !== document)) {
 | 
						|
          this.src = this.resolvePath(this.src, this.ownerDocument.baseURI);
 | 
						|
        }
 | 
						|
        this.super();
 | 
						|
        this.updateThemes();
 | 
						|
      },
 | 
						|
 | 
						|
      iconsChanged: function() {
 | 
						|
        var ox = this.offsetX;
 | 
						|
        var oy = this.offsetY;
 | 
						|
        this.icons && this.icons.split(/\s+/g).forEach(function(name, i) {
 | 
						|
          this.iconNames.push(name);
 | 
						|
          this.iconMap[name] = {
 | 
						|
            offsetX: ox,
 | 
						|
            offsetY: oy
 | 
						|
          }
 | 
						|
          if (ox + this.iconSize < this.width) {
 | 
						|
            ox += this.iconSize;
 | 
						|
          } else {
 | 
						|
            ox = this.offsetX;
 | 
						|
            oy += this.iconSize;
 | 
						|
          }
 | 
						|
        }, this);
 | 
						|
      },
 | 
						|
 | 
						|
      updateThemes: function() {
 | 
						|
        var ts = this.querySelectorAll('property[theme]');
 | 
						|
        ts && ts.array().forEach(function(t) {
 | 
						|
          this.themes[t.getAttribute('theme')] = {
 | 
						|
            offsetX: parseInt(t.getAttribute('offsetX')) || 0,
 | 
						|
            offsetY: parseInt(t.getAttribute('offsetY')) || 0
 | 
						|
          };
 | 
						|
        }, this);
 | 
						|
      },
 | 
						|
 | 
						|
      // TODO(ffu): support retrived by index e.g. getOffset(10);
 | 
						|
      /**
 | 
						|
       * Returns an object containing `offsetX` and `offsetY` properties which
 | 
						|
       * specify the pixel locaion in the iconset's src file for the given
 | 
						|
       * `icon` and `theme`. It's uncommon to call this method. It is useful,
 | 
						|
       * for example, to manually position a css backgroundImage to the proper
 | 
						|
       * offset. It's more common to use the `applyIcon` method.
 | 
						|
       *
 | 
						|
       * @method getOffset
 | 
						|
       * @param {String|Number} icon The name of the icon or the index of the
 | 
						|
       * icon within in the icon image.
 | 
						|
       * @param {String} theme The name of the theme.
 | 
						|
       * @returns {Object} An object specifying the offset of the given icon 
 | 
						|
       * within the icon resource file; `offsetX` is the horizontal offset and
 | 
						|
       * `offsetY` is the vertical offset. Both values are in pixel units.
 | 
						|
       */
 | 
						|
      getOffset: function(icon, theme) {
 | 
						|
        var i = this.iconMap[icon];
 | 
						|
        if (!i) {
 | 
						|
          var n = this.iconNames[Number(icon)];
 | 
						|
          i = this.iconMap[n];
 | 
						|
        }
 | 
						|
        var t = this.themes[theme];
 | 
						|
        if (i && t) {
 | 
						|
          return {
 | 
						|
            offsetX: i.offsetX + t.offsetX,
 | 
						|
            offsetY: i.offsetY + t.offsetY
 | 
						|
          }
 | 
						|
        }
 | 
						|
        return i;
 | 
						|
      },
 | 
						|
 | 
						|
      /**
 | 
						|
       * Applies an icon to the given element as a css background image. This
 | 
						|
       * method does not size the element, and it's often necessary to set 
 | 
						|
       * the element's height and width so that the background image is visible.
 | 
						|
       *
 | 
						|
       * @method applyIcon
 | 
						|
       * @param {Element} element The element to which the background is
 | 
						|
       * applied.
 | 
						|
       * @param {String|Number} icon The name or index of the icon to apply.
 | 
						|
       * @param {Number} scale (optional, defaults to 1) A scaling factor 
 | 
						|
       * with which the icon can be magnified.
 | 
						|
       * @return {Element} The icon element.
 | 
						|
       */
 | 
						|
      applyIcon: function(element, icon, scale) {
 | 
						|
        var offset = this.getOffset(icon);
 | 
						|
        scale = scale || 1;
 | 
						|
        if (element && offset) {
 | 
						|
          var icon = element._icon || document.createElement('div');
 | 
						|
          var style = icon.style;
 | 
						|
          style.backgroundImage = 'url(' + this.src + ')';
 | 
						|
          style.backgroundPosition = (-offset.offsetX * scale + 'px') + 
 | 
						|
             ' ' + (-offset.offsetY * scale + 'px');
 | 
						|
          style.backgroundSize = scale === 1 ? 'auto' :
 | 
						|
             this.width * scale + 'px';
 | 
						|
          if (icon.parentNode !== element) {
 | 
						|
            element.appendChild(icon);
 | 
						|
          }
 | 
						|
          return icon;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
    });
 | 
						|
 | 
						|
  </script>
 | 
						|
 | 
						|
</polymer-element>
 |