• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1
2(function() {
3
4  // mono-state
5  var meta;
6
7  Polymer('core-icon', {
8
9    /**
10     * The URL of an image for the icon. If the src property is specified,
11     * the icon property should not be.
12     *
13     * @attribute src
14     * @type string
15     * @default ''
16     */
17    src: '',
18
19    /**
20     * Specifies the icon name or index in the set of icons available in
21     * the icon's icon set. If the icon property is specified,
22     * the src property should not be.
23     *
24     * @attribute icon
25     * @type string
26     * @default ''
27     */
28    icon: '',
29
30    /**
31     * Alternative text content for accessibility support.
32     * If alt is present and not empty, it will set the element's role to img and add an aria-label whose content matches alt.
33     * If alt is present and is an empty string, '', it will hide the element from the accessibility layer
34     * If alt is not present, it will set the element's role to img and the element will fallback to using the icon attribute for its aria-label.
35     *
36     * @attribute alt
37     * @type string
38     * @default ''
39     */
40    alt: null,
41
42    observe: {
43      'icon': 'updateIcon',
44      'alt': 'updateAlt'
45    },
46
47    defaultIconset: 'icons',
48
49    ready: function() {
50      if (!meta) {
51        meta = document.createElement('core-iconset');
52      }
53
54      // Allow user-provided `aria-label` in preference to any other text alternative.
55      if (this.hasAttribute('aria-label')) {
56        // Set `role` if it has not been overridden.
57        if (!this.hasAttribute('role')) {
58          this.setAttribute('role', 'img');
59        }
60        return;
61      }
62      this.updateAlt();
63    },
64
65    srcChanged: function() {
66      var icon = this._icon || document.createElement('div');
67      icon.textContent = '';
68      icon.setAttribute('fit', '');
69      icon.style.backgroundImage = 'url(' + this.src + ')';
70      icon.style.backgroundPosition = 'center';
71      icon.style.backgroundSize = '100%';
72      if (!icon.parentNode) {
73        this.appendChild(icon);
74      }
75      this._icon = icon;
76    },
77
78    getIconset: function(name) {
79      return meta.byId(name || this.defaultIconset);
80    },
81
82    updateIcon: function(oldVal, newVal) {
83      if (!this.icon) {
84        this.updateAlt();
85        return;
86      }
87      var parts = String(this.icon).split(':');
88      var icon = parts.pop();
89      if (icon) {
90        var set = this.getIconset(parts.pop());
91        if (set) {
92          this._icon = set.applyIcon(this, icon);
93          if (this._icon) {
94            this._icon.setAttribute('fit', '');
95          }
96        }
97      }
98      // Check to see if we're using the old icon's name for our a11y fallback
99      if (oldVal) {
100        if (oldVal.split(':').pop() == this.getAttribute('aria-label')) {
101          this.updateAlt();
102        }
103      }
104    },
105
106    updateAlt: function() {
107      // Respect the user's decision to remove this element from
108      // the a11y tree
109      if (this.getAttribute('aria-hidden')) {
110        return;
111      }
112
113      // Remove element from a11y tree if `alt` is empty, otherwise
114      // use `alt` as `aria-label`.
115      if (this.alt === '') {
116        this.setAttribute('aria-hidden', 'true');
117        if (this.hasAttribute('role')) {
118          this.removeAttribute('role');
119        }
120        if (this.hasAttribute('aria-label')) {
121          this.removeAttribute('aria-label');
122        }
123      } else {
124        this.setAttribute('aria-label', this.alt ||
125                                        this.icon.split(':').pop());
126        if (!this.hasAttribute('role')) {
127          this.setAttribute('role', 'img');
128        }
129        if (this.hasAttribute('aria-hidden')) {
130          this.removeAttribute('aria-hidden');
131        }
132      }
133    }
134
135  });
136
137})();
138