Fix OOP <webview> resize and autosize.
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / iron-iconset-svg / iron-iconset-svg-extracted.js
bloba020ee47c5e7968ccf876bdc981f790cfbda3ccb
1 /**
2    * The `iron-iconset-svg` element allows users to define their own icon sets
3    * that contain svg icons. The svg icon elements should be children of the
4    * `iron-iconset-svg` element. Multiple icons should be given distinct id's.
5    *
6    * Using svg elements to create icons has a few advantages over traditional
7    * bitmap graphics like jpg or png. Icons that use svg are vector based so they
8    * are resolution independent and should look good on any device. They are
9    * stylable via css. Icons can be themed, colorized, and even animated.
10    *
11    * Example:
12    *
13    *     <iron-iconset-svg name="my-svg-icons" size="24">
14    *       <svg>
15    *         <defs>
16    *           <g id="shape">
17    *             <rect x="50" y="50" width="50" height="50" />
18    *             <circle cx="50" cy="50" r="50" />
19    *           </g>
20    *         </defs>
21    *       </svg>
22    *     </iron-iconset-svg>
23    *
24    * This will automatically register the icon set "my-svg-icons" to the iconset
25    * database.  To use these icons from within another element, make a
26    * `iron-iconset` element and call the `byId` method
27    * to retrieve a given iconset. To apply a particular icon inside an
28    * element use the `applyIcon` method. For example:
29    *
30    *     iconset.applyIcon(iconNode, 'car');
31    *
32    * @element iron-iconset-svg
33    * @demo demo/index.html
34    */
35   Polymer({
37     is: 'iron-iconset-svg',
39     properties: {
41       /**
42        * The name of the iconset.
43        *
44        * @attribute name
45        * @type string
46        */
47       name: {
48         type: String,
49         observer: '_nameChanged'
50       },
52       /**
53        * The size of an individual icon. Note that icons must be square.
54        *
55        * @attribute iconSize
56        * @type number
57        * @default 24
58        */
59       size: {
60         type: Number,
61         value: 24
62       }
64     },
66     /**
67      * Construct an array of all icon names in this iconset.
68      *
69      * @return {!Array} Array of icon names.
70      */
71     getIconNames: function() {
72       this._icons = this._createIconMap();
73       return Object.keys(this._icons).map(function(n) {
74         return this.name + ':' + n;
75       }, this);
76     },
78     /**
79      * Applies an icon to the given element.
80      *
81      * An svg icon is prepended to the element's shadowRoot if it exists,
82      * otherwise to the element itself.
83      *
84      * @method applyIcon
85      * @param {Element} element Element to which the icon is applied.
86      * @param {string} iconName Name of the icon to apply.
87      * @return {Element} The svg element which renders the icon.
88      */
89     applyIcon: function(element, iconName) {
90       // insert svg element into shadow root, if it exists
91       element = element.root || element;
92       // Remove old svg element
93       this.removeIcon(element);
94       // install new svg element
95       var svg = this._cloneIcon(iconName);
96       if (svg) {
97         var pde = Polymer.dom(element);
98         pde.insertBefore(svg, pde.childNodes[0]);
99         return element._svgIcon = svg;
100       }
101       return null;
102     },
104     /**
105      * Remove an icon from the given element by undoing the changes effected
106      * by `applyIcon`.
107      *
108      * @param {Element} element The element from which the icon is removed.
109      */
110     removeIcon: function(element) {
111       // Remove old svg element
112       if (element._svgIcon) {
113         Polymer.dom(element).removeChild(element._svgIcon);
114         element._svgIcon = null;
115       }
116     },
118     /**
119      *
120      * When name is changed, register iconset metadata
121      *
122      */
123     _nameChanged: function() {
124       new Polymer.IronMeta({type: 'iconset', key: this.name, value: this});
125     },
127     /**
128      * Create a map of child SVG elements by id.
129      *
130      * @return {!Object} Map of id's to SVG elements.
131      */
132     _createIconMap: function() {
133       // Objects chained to Object.prototype (`{}`) have members. Specifically,
134       // on FF there is a `watch` method that confuses the icon map, so we
135       // need to use a null-based object here.
136       var icons = Object.create(null);
137       Polymer.dom(this).querySelectorAll('[id]')
138         .forEach(function(icon) {
139           icons[icon.id] = icon;
140         });
141       return icons;
142     },
144     /**
145      * Produce installable clone of the SVG element matching `id` in this
146      * iconset, or `undefined` if there is no matching element.
147      *
148      * @return {Element} Returns an installable clone of the SVG element
149      * matching `id`.
150      */
151     _cloneIcon: function(id) {
152       // create the icon map on-demand, since the iconset itself has no discrete
153       // signal to know when it's children are fully parsed
154       this._icons = this._icons || this._createIconMap();
155       return this._prepareSvgClone(this._icons[id], this.size);
156     },
158     /**
159      * @param {Element} sourceSvg
160      * @param {number} size
161      * @return {Element}
162      */
163     _prepareSvgClone: function(sourceSvg, size) {
164       if (sourceSvg) {
165         var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
166         svg.setAttribute('viewBox', ['0', '0', size, size].join(' '));
167         svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
168         // TODO(dfreedm): `pointer-events: none` works around https://crbug.com/370136
169         // TODO(sjmiles): inline style may not be ideal, but avoids requiring a shadow-root
170         svg.style.cssText = 'pointer-events: none; display: block; width: 100%; height: 100%;';
171         svg.appendChild(sourceSvg.cloneNode(true)).removeAttribute('id');
172         return svg;
173       }
174       return null;
175     }
177   });