aboutsummaryrefslogtreecommitdiff
path: root/catapult/third_party/polymer/components/iron-iconset-svg/iron-iconset-svg.html
diff options
context:
space:
mode:
Diffstat (limited to 'catapult/third_party/polymer/components/iron-iconset-svg/iron-iconset-svg.html')
-rw-r--r--catapult/third_party/polymer/components/iron-iconset-svg/iron-iconset-svg.html242
1 files changed, 242 insertions, 0 deletions
diff --git a/catapult/third_party/polymer/components/iron-iconset-svg/iron-iconset-svg.html b/catapult/third_party/polymer/components/iron-iconset-svg/iron-iconset-svg.html
new file mode 100644
index 00000000..ab07e88c
--- /dev/null
+++ b/catapult/third_party/polymer/components/iron-iconset-svg/iron-iconset-svg.html
@@ -0,0 +1,242 @@
+<!--
+@license
+Copyright (c) 2015 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
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-meta/iron-meta.html">
+
+<script>
+ /**
+ * The `iron-iconset-svg` element allows users to define their own icon sets
+ * that contain svg icons. The svg icon elements should be children of the
+ * `iron-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:
+ *
+ * <iron-iconset-svg name="my-svg-icons" size="24">
+ * <svg>
+ * <defs>
+ * <g id="shape">
+ * <rect x="12" y="0" width="12" height="24" />
+ * <circle cx="12" cy="12" r="12" />
+ * </g>
+ * </defs>
+ * </svg>
+ * </iron-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
+ * `iron-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 iron-iconset-svg
+ * @demo demo/index.html
+ * @implements {Polymer.Iconset}
+ */
+ Polymer({
+ is: 'iron-iconset-svg',
+
+ properties: {
+
+ /**
+ * The name of the iconset.
+ */
+ name: {
+ type: String,
+ observer: '_nameChanged'
+ },
+
+ /**
+ * The size of an individual icon. Note that icons must be square.
+ */
+ size: {
+ type: Number,
+ value: 24
+ },
+
+ /**
+ * Set to true to enable mirroring of icons where specified when they are
+ * stamped. Icons that should be mirrored should be decorated with a
+ * `mirror-in-rtl` attribute.
+ *
+ * NOTE: For performance reasons, direction will be resolved once per
+ * document per iconset, so moving icons in and out of RTL subtrees will
+ * not cause their mirrored state to change.
+ */
+ rtlMirroring: {
+ type: Boolean,
+ value: false
+ }
+ },
+
+ attached: function() {
+ this.style.display = 'none';
+ },
+
+ /**
+ * Construct an array of all icon names in this iconset.
+ *
+ * @return {!Array} Array of icon names.
+ */
+ getIconNames: function() {
+ this._icons = this._createIconMap();
+ return Object.keys(this._icons).map(function(n) {
+ return this.name + ':' + n;
+ }, this);
+ },
+
+ /**
+ * Applies an icon to the given element.
+ *
+ * An svg icon is prepended to the element's shadowRoot if it exists,
+ * otherwise to the element itself.
+ *
+ * If RTL mirroring is enabled, and the icon is marked to be mirrored in
+ * RTL, the element will be tested (once and only once ever for each
+ * iconset) to determine the direction of the subtree the element is in.
+ * This direction will apply to all future icon applications, although only
+ * icons marked to be mirrored will be affected.
+ *
+ * @method applyIcon
+ * @param {Element} element Element to which the icon is applied.
+ * @param {string} iconName Name of the icon to apply.
+ * @return {?Element} The svg element which renders the icon.
+ */
+ applyIcon: function(element, iconName) {
+ // insert svg element into shadow root, if it exists
+ element = element.root || element;
+ // Remove old svg element
+ this.removeIcon(element);
+ // install new svg element
+ var svg = this._cloneIcon(iconName,
+ this.rtlMirroring && this._targetIsRTL(element));
+ if (svg) {
+ var pde = Polymer.dom(element);
+ pde.insertBefore(svg, pde.childNodes[0]);
+ return element._svgIcon = svg;
+ }
+ return null;
+ },
+
+ /**
+ * Remove an icon from the given element by undoing the changes effected
+ * by `applyIcon`.
+ *
+ * @param {Element} element The element from which the icon is removed.
+ */
+ removeIcon: function(element) {
+ // Remove old svg element
+ element = element.root || element;
+ if (element._svgIcon) {
+ Polymer.dom(element).removeChild(element._svgIcon);
+ element._svgIcon = null;
+ }
+ },
+
+ /**
+ * Measures and memoizes the direction of the element. Note that this
+ * measurement is only done once and the result is memoized for future
+ * invocations.
+ */
+ _targetIsRTL: function(target) {
+ if (this.__targetIsRTL == null) {
+ if (target && target.nodeType !== Node.ELEMENT_NODE) {
+ target = target.host;
+ }
+
+ this.__targetIsRTL = target &&
+ window.getComputedStyle(target)['direction'] === 'rtl';
+ }
+
+ return this.__targetIsRTL;
+ },
+
+ /**
+ *
+ * When name is changed, register iconset metadata
+ *
+ */
+ _nameChanged: function() {
+ new Polymer.IronMeta({type: 'iconset', key: this.name, value: this});
+ this.async(function() {
+ this.fire('iron-iconset-added', this, {node: window});
+ });
+ },
+
+ /**
+ * Create a map of child SVG elements by id.
+ *
+ * @return {!Object} Map of id's to SVG elements.
+ */
+ _createIconMap: function() {
+ // Objects chained to Object.prototype (`{}`) have members. Specifically,
+ // on FF there is a `watch` method that confuses the icon map, so we
+ // need to use a null-based object here.
+ var icons = Object.create(null);
+ Polymer.dom(this).querySelectorAll('[id]')
+ .forEach(function(icon) {
+ icons[icon.id] = icon;
+ });
+ return icons;
+ },
+
+ /**
+ * Produce installable clone of the SVG element matching `id` in this
+ * iconset, or `undefined` if there is no matching element.
+ *
+ * @return {Element} Returns an installable clone of the SVG element
+ * matching `id`.
+ */
+ _cloneIcon: function(id, mirrorAllowed) {
+ // create the icon map on-demand, since the iconset itself has no discrete
+ // signal to know when it's children are fully parsed
+ this._icons = this._icons || this._createIconMap();
+ return this._prepareSvgClone(this._icons[id], this.size, mirrorAllowed);
+ },
+
+ /**
+ * @param {Element} sourceSvg
+ * @param {number} size
+ * @param {Boolean} mirrorAllowed
+ * @return {Element}
+ */
+ _prepareSvgClone: function(sourceSvg, size, mirrorAllowed) {
+ if (sourceSvg) {
+ var content = sourceSvg.cloneNode(true),
+ svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
+ viewBox = content.getAttribute('viewBox') || '0 0 ' + size + ' ' + size,
+ cssText = 'pointer-events: none; display: block; width: 100%; height: 100%;';
+
+ if (mirrorAllowed && content.hasAttribute('mirror-in-rtl')) {
+ cssText += '-webkit-transform:scale(-1,1);transform:scale(-1,1);';
+ }
+
+ svg.setAttribute('viewBox', viewBox);
+ svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
+ svg.setAttribute('focusable', 'false');
+ // TODO(dfreedm): `pointer-events: none` works around https://crbug.com/370136
+ // TODO(sjmiles): inline style may not be ideal, but avoids requiring a shadow-root
+ svg.style.cssText = cssText;
+ svg.appendChild(content).removeAttribute('id');
+ return svg;
+ }
+ return null;
+ }
+
+ });
+
+</script>