blob: edf33c425c3023e0fedc87aabf80f08aaa1cf527 [file] [log] [blame]
<!--
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-svg` element allows users to define their own icon sets
* that contain svg icons. The svg icon elements should be children of the
* `core-iconset-svg` element. Multiple icons should be given distinct id's.
*
* Using svg elements to create icons has a few advantages over traditional
* bitmap graphics like jpg or png. Icons that use svg are vector based so they
* are resolution independent and should look good on any device. They are
* stylable via css. Icons can be themed, colorized, and even animated.
*
* Example:
*
* <core-iconset-svg id="my-svg-icons" iconSize="24">
* <svg>
* <defs>
* <g id="shape">
* <rect x="50" y="50" width="50" height="50" />
* <circle cx="50" cy="50" r="50" />
* </g>
* </defs>
* </svg>
* </core-iconset-svg>
*
* This will automatically register the icon set "my-svg-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 inside an
* element use the `applyIcon` method. For example:
*
* iconset.applyIcon(iconNode, 'car');
*
* @element core-iconset-svg
* @extends core-meta
* @homepage github.io
*/
-->
<link rel="import" href="../core-iconset/core-iconset.html">
<polymer-element name="core-iconset-svg" extends="core-meta" attributes="iconSize">
<script>
Polymer('core-iconset-svg', {
/**
* The size of an individual icon. Note that icons must be square.
*
* @attribute iconSize
* @type number
* @default 24
*/
iconSize: 24,
type: 'iconset',
created: function() {
this._icons = {};
},
ready: function() {
this.super();
this.updateIcons();
},
iconById: function(id) {
return this._icons[id] || (this._icons[id] = this.querySelector('[id="' + id +'"]'));
},
cloneIcon: function(id) {
var icon = this.iconById(id);
if (icon) {
var content = icon.cloneNode(true);
content.removeAttribute('id');
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('viewBox', '0 0 ' + this.iconSize + ' ' +
this.iconSize);
// NOTE(dfreedm): work around https://crbug.com/370136
svg.style.pointerEvents = 'none';
svg.appendChild(content);
return svg;
}
},
get iconNames() {
if (!this._iconNames) {
this._iconNames = this.findIconNames();
}
return this._iconNames;
},
findIconNames: function() {
var icons = this.querySelectorAll('[id]').array();
if (icons.length) {
return icons.map(function(n){ return n.id });
}
},
/**
* Applies an icon to the given element. The svg icon is added to the
* element's shadowRoot if one exists or directly to itself.
*
* @method applyIcon
* @param {Element} element The element to which the icon is
* applied.
* @param {String|Number} icon The name the icon to apply.
* @return {Element} The icon element
*/
applyIcon: function(element, icon) {
var root = element;
// remove old
var old = root.querySelector('svg');
if (old) {
old.remove();
}
// install new
var svg = this.cloneIcon(icon);
if (!svg) {
return;
}
svg.setAttribute('height', '100%');
svg.setAttribute('width', '100%');
svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
svg.style.display = 'block';
root.insertBefore(svg, root.firstElementChild);
return svg;
},
/**
* Tell users of the iconset, that the set has loaded.
* This finds all elements matching the selector argument and calls
* the method argument on them.
* @method updateIcons
* @param selector {string} css selector to identify iconset users,
* defaults to '[icon]'
* @param method {string} method to call on found elements,
* defaults to 'updateIcon'
*/
updateIcons: function(selector, method) {
selector = selector || '[icon]';
method = method || 'updateIcon';
var deep = window.ShadowDOMPolyfill ? '' : 'html /deep/ ';
var i$ = document.querySelectorAll(deep + selector);
for (var i=0, e; e=i$[i]; i++) {
if (e[method]) {
e[method].call(e);
}
}
}
});
</script>
</polymer-element>