material_design_lite-sass 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +11 -0
  5. data/CHANGELOG.md +5 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +108 -0
  9. data/Rakefile +4 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +7 -0
  12. data/lib/material_design_lite-sass.rb +46 -0
  13. data/lib/material_design_lite/sass/engine.rb +13 -0
  14. data/lib/material_design_lite/sass/version.rb +5 -0
  15. data/material_design_lite-sass.gemspec +28 -0
  16. data/vendor/assets/javascripts/material.js +3919 -0
  17. data/vendor/assets/javascripts/material/button.js +132 -0
  18. data/vendor/assets/javascripts/material/checkbox.js +265 -0
  19. data/vendor/assets/javascripts/material/data-table.js +149 -0
  20. data/vendor/assets/javascripts/material/icon-toggle.js +248 -0
  21. data/vendor/assets/javascripts/material/layout.js +434 -0
  22. data/vendor/assets/javascripts/material/mdlComponentHandler.js +346 -0
  23. data/vendor/assets/javascripts/material/menu.js +468 -0
  24. data/vendor/assets/javascripts/material/progress.js +116 -0
  25. data/vendor/assets/javascripts/material/rAF.js +38 -0
  26. data/vendor/assets/javascripts/material/radio.js +257 -0
  27. data/vendor/assets/javascripts/material/ripple.js +244 -0
  28. data/vendor/assets/javascripts/material/slider.js +252 -0
  29. data/vendor/assets/javascripts/material/spinner.js +140 -0
  30. data/vendor/assets/javascripts/material/switch.js +269 -0
  31. data/vendor/assets/javascripts/material/tabs.js +152 -0
  32. data/vendor/assets/javascripts/material/textfield.js +247 -0
  33. data/vendor/assets/javascripts/material/tooltip.js +146 -0
  34. data/vendor/assets/stylesheets/_material.scss +50 -0
  35. data/vendor/assets/stylesheets/material/_animation.scss +34 -0
  36. data/vendor/assets/stylesheets/material/_badge.scss +66 -0
  37. data/vendor/assets/stylesheets/material/_button.scss +298 -0
  38. data/vendor/assets/stylesheets/material/_card.scss +111 -0
  39. data/vendor/assets/stylesheets/material/_checkbox.scss +175 -0
  40. data/vendor/assets/stylesheets/material/_color-definitions.scss +599 -0
  41. data/vendor/assets/stylesheets/material/_data-table.scss +105 -0
  42. data/vendor/assets/stylesheets/material/_functions.scss +3 -0
  43. data/vendor/assets/stylesheets/material/_grid.scss +180 -0
  44. data/vendor/assets/stylesheets/material/_icon-toggle.scss +121 -0
  45. data/vendor/assets/stylesheets/material/_layout.scss +580 -0
  46. data/vendor/assets/stylesheets/material/_mega_footer.scss +309 -0
  47. data/vendor/assets/stylesheets/material/_menu.scss +193 -0
  48. data/vendor/assets/stylesheets/material/_mini_footer.scss +88 -0
  49. data/vendor/assets/stylesheets/material/_mixins.scss +268 -0
  50. data/vendor/assets/stylesheets/material/_palette.scss +2303 -0
  51. data/vendor/assets/stylesheets/material/_progress.scss +115 -0
  52. data/vendor/assets/stylesheets/material/_radio.scss +155 -0
  53. data/vendor/assets/stylesheets/material/_resets.scss +55 -0
  54. data/vendor/assets/stylesheets/material/_ripple.scss +42 -0
  55. data/vendor/assets/stylesheets/material/_shadow.scss +42 -0
  56. data/vendor/assets/stylesheets/material/_slider.scss +396 -0
  57. data/vendor/assets/stylesheets/material/_spinner.scss +248 -0
  58. data/vendor/assets/stylesheets/material/_switch.scss +199 -0
  59. data/vendor/assets/stylesheets/material/_tabs.scss +115 -0
  60. data/vendor/assets/stylesheets/material/_textfield.scss +190 -0
  61. data/vendor/assets/stylesheets/material/_tooltip.scss +66 -0
  62. data/vendor/assets/stylesheets/material/_typography.scss +297 -0
  63. data/vendor/assets/stylesheets/material/_variables.scss +572 -0
  64. data/vendor/assets/stylesheets/material/resets/_h5bp.scss +284 -0
  65. data/vendor/assets/stylesheets/material/resets/_mobile.scss +25 -0
  66. metadata +151 -0
@@ -0,0 +1,248 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2015 Google Inc. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Class constructor for icon toggle MDL component.
20
+ * Implements MDL component design pattern defined at:
21
+ * https://github.com/jasonmayes/mdl-component-design-pattern
22
+ * @param {HTMLElement} element The element that will be upgraded.
23
+ */
24
+ function MaterialIconToggle(element) {
25
+ 'use strict';
26
+
27
+ this.element_ = element;
28
+
29
+ // Initialize instance.
30
+ this.init();
31
+ }
32
+
33
+ /**
34
+ * Store constants in one place so they can be updated easily.
35
+ * @enum {string | number}
36
+ * @private
37
+ */
38
+ MaterialIconToggle.prototype.Constant_ = {
39
+ TINY_TIMEOUT: 0.001
40
+ };
41
+
42
+ /**
43
+ * Store strings for class names defined by this component that are used in
44
+ * JavaScript. This allows us to simply change it in one place should we
45
+ * decide to modify at a later date.
46
+ * @enum {string}
47
+ * @private
48
+ */
49
+ MaterialIconToggle.prototype.CssClasses_ = {
50
+ INPUT: 'mdl-icon-toggle__input',
51
+ JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',
52
+ RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
53
+ RIPPLE_CONTAINER: 'mdl-icon-toggle__ripple-container',
54
+ RIPPLE_CENTER: 'mdl-ripple--center',
55
+ RIPPLE: 'mdl-ripple',
56
+ IS_FOCUSED: 'is-focused',
57
+ IS_DISABLED: 'is-disabled',
58
+ IS_CHECKED: 'is-checked'
59
+ };
60
+
61
+ /**
62
+ * Handle change of state.
63
+ * @param {Event} event The event that fired.
64
+ * @private
65
+ */
66
+ MaterialIconToggle.prototype.onChange_ = function(event) {
67
+ 'use strict';
68
+
69
+ this.updateClasses_();
70
+ };
71
+
72
+ /**
73
+ * Handle focus of element.
74
+ * @param {Event} event The event that fired.
75
+ * @private
76
+ */
77
+ MaterialIconToggle.prototype.onFocus_ = function(event) {
78
+ 'use strict';
79
+
80
+ this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
81
+ };
82
+
83
+ /**
84
+ * Handle lost focus of element.
85
+ * @param {Event} event The event that fired.
86
+ * @private
87
+ */
88
+ MaterialIconToggle.prototype.onBlur_ = function(event) {
89
+ 'use strict';
90
+
91
+ this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
92
+ };
93
+
94
+ /**
95
+ * Handle mouseup.
96
+ * @param {Event} event The event that fired.
97
+ * @private
98
+ */
99
+ MaterialIconToggle.prototype.onMouseUp_ = function(event) {
100
+ 'use strict';
101
+
102
+ this.blur_();
103
+ };
104
+
105
+ /**
106
+ * Handle class updates.
107
+ * @param {HTMLElement} button The button whose classes we should update.
108
+ * @param {HTMLElement} label The label whose classes we should update.
109
+ * @private
110
+ */
111
+ MaterialIconToggle.prototype.updateClasses_ = function() {
112
+ 'use strict';
113
+
114
+ if (this.inputElement_.disabled) {
115
+ this.element_.classList.add(this.CssClasses_.IS_DISABLED);
116
+ } else {
117
+ this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
118
+ }
119
+
120
+ if (this.inputElement_.checked) {
121
+ this.element_.classList.add(this.CssClasses_.IS_CHECKED);
122
+ } else {
123
+ this.element_.classList.remove(this.CssClasses_.IS_CHECKED);
124
+ }
125
+ };
126
+
127
+ /**
128
+ * Add blur.
129
+ * @private
130
+ */
131
+ MaterialIconToggle.prototype.blur_ = function(event) {
132
+ 'use strict';
133
+
134
+ // TODO: figure out why there's a focus event being fired after our blur,
135
+ // so that we can avoid this hack.
136
+ window.setTimeout(function() {
137
+ this.inputElement_.blur();
138
+ }.bind(this), this.Constant_.TINY_TIMEOUT);
139
+ };
140
+
141
+ // Public methods.
142
+
143
+ /**
144
+ * Disable icon toggle.
145
+ * @public
146
+ */
147
+ MaterialIconToggle.prototype.disable = function() {
148
+ 'use strict';
149
+
150
+ this.inputElement_.disabled = true;
151
+ this.updateClasses_();
152
+ };
153
+
154
+ /**
155
+ * Enable icon toggle.
156
+ * @public
157
+ */
158
+ MaterialIconToggle.prototype.enable = function() {
159
+ 'use strict';
160
+
161
+ this.inputElement_.disabled = false;
162
+ this.updateClasses_();
163
+ };
164
+
165
+ /**
166
+ * Check icon toggle.
167
+ * @public
168
+ */
169
+ MaterialIconToggle.prototype.check = function() {
170
+ 'use strict';
171
+
172
+ this.inputElement_.checked = true;
173
+ this.updateClasses_();
174
+ };
175
+
176
+ /**
177
+ * Uncheck icon toggle.
178
+ * @public
179
+ */
180
+ MaterialIconToggle.prototype.uncheck = function() {
181
+ 'use strict';
182
+
183
+ this.inputElement_.checked = false;
184
+ this.updateClasses_();
185
+ };
186
+
187
+ /**
188
+ * Initialize element.
189
+ */
190
+ MaterialIconToggle.prototype.init = function() {
191
+ 'use strict';
192
+
193
+ if (this.element_) {
194
+ this.inputElement_ =
195
+ this.element_.querySelector('.' + this.CssClasses_.INPUT);
196
+
197
+ if (this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {
198
+ this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
199
+ this.rippleContainerElement_ = document.createElement('span');
200
+ this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
201
+ this.rippleContainerElement_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT);
202
+ this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
203
+ this.boundRippleMouseUp = this.onMouseUp_.bind(this);
204
+ this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);
205
+
206
+ var ripple = document.createElement('span');
207
+ ripple.classList.add(this.CssClasses_.RIPPLE);
208
+
209
+ this.rippleContainerElement_.appendChild(ripple);
210
+ this.element_.appendChild(this.rippleContainerElement_);
211
+ }
212
+
213
+ this.boundInputOnChange = this.onChange_.bind(this);
214
+ this.boundInputOnFocus = this.onFocus_.bind(this);
215
+ this.boundInputOnBlur = this.onBlur_.bind(this);
216
+ this.boundElementOnMouseUp = this.onMouseUp_.bind(this);
217
+ this.inputElement_.addEventListener('change', this.boundInputOnChange);
218
+ this.inputElement_.addEventListener('focus', this.boundInputOnFocus);
219
+ this.inputElement_.addEventListener('blur', this.boundInputOnBlur);
220
+ this.element_.addEventListener('mouseup', this.boundElementOnMouseUp);
221
+
222
+ this.updateClasses_();
223
+ this.element_.classList.add('is-upgraded');
224
+ }
225
+ };
226
+
227
+ /*
228
+ * Downgrade the component
229
+ */
230
+ MaterialIconToggle.prototype.mdlDowngrade_ = function() {
231
+ 'use strict';
232
+ if (this.rippleContainerElement_) {
233
+ this.rippleContainerElement_.removeEventListener('mouseup', this.boundRippleMouseUp);
234
+ }
235
+ this.inputElement_.removeEventListener('change', this.boundInputOnChange);
236
+ this.inputElement_.removeEventListener('focus', this.boundInputOnFocus);
237
+ this.inputElement_.removeEventListener('blur', this.boundInputOnBlur);
238
+ this.element_.removeEventListener('mouseup', this.boundElementOnMouseUp);
239
+ };
240
+
241
+ // The component registers itself. It can assume componentHandler is available
242
+ // in the global scope.
243
+ componentHandler.register({
244
+ constructor: MaterialIconToggle,
245
+ classAsString: 'MaterialIconToggle',
246
+ cssClass: 'mdl-js-icon-toggle',
247
+ widget: true
248
+ });
@@ -0,0 +1,434 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2015 Google Inc. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Class constructor for Layout MDL component.
20
+ * Implements MDL component design pattern defined at:
21
+ * https://github.com/jasonmayes/mdl-component-design-pattern
22
+ * @param {HTMLElement} element The element that will be upgraded.
23
+ */
24
+ function MaterialLayout(element) {
25
+ 'use strict';
26
+
27
+ this.element_ = element;
28
+
29
+ // Initialize instance.
30
+ this.init();
31
+ }
32
+
33
+ /**
34
+ * Store constants in one place so they can be updated easily.
35
+ * @enum {string | number}
36
+ * @private
37
+ */
38
+ MaterialLayout.prototype.Constant_ = {
39
+ MAX_WIDTH: '(max-width: 850px)',
40
+ TAB_SCROLL_PIXELS: 100,
41
+
42
+ MENU_ICON: 'menu',
43
+ CHEVRON_LEFT: 'chevron_left',
44
+ CHEVRON_RIGHT: 'chevron_right'
45
+ };
46
+
47
+ /**
48
+ * Modes.
49
+ * @enum {number}
50
+ * @private
51
+ */
52
+ MaterialLayout.prototype.Mode_ = {
53
+ STANDARD: 0,
54
+ SEAMED: 1,
55
+ WATERFALL: 2,
56
+ SCROLL: 3
57
+ };
58
+
59
+ /**
60
+ * Store strings for class names defined by this component that are used in
61
+ * JavaScript. This allows us to simply change it in one place should we
62
+ * decide to modify at a later date.
63
+ * @enum {string}
64
+ * @private
65
+ */
66
+ MaterialLayout.prototype.CssClasses_ = {
67
+ CONTAINER: 'mdl-layout__container',
68
+ HEADER: 'mdl-layout__header',
69
+ DRAWER: 'mdl-layout__drawer',
70
+ CONTENT: 'mdl-layout__content',
71
+ DRAWER_BTN: 'mdl-layout__drawer-button',
72
+
73
+ ICON: 'material-icons',
74
+
75
+ JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',
76
+ RIPPLE_CONTAINER: 'mdl-layout__tab-ripple-container',
77
+ RIPPLE: 'mdl-ripple',
78
+ RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
79
+
80
+ HEADER_SEAMED: 'mdl-layout__header--seamed',
81
+ HEADER_WATERFALL: 'mdl-layout__header--waterfall',
82
+ HEADER_SCROLL: 'mdl-layout__header--scroll',
83
+
84
+ FIXED_HEADER: 'mdl-layout--fixed-header',
85
+ OBFUSCATOR: 'mdl-layout__obfuscator',
86
+
87
+ TAB_BAR: 'mdl-layout__tab-bar',
88
+ TAB_CONTAINER: 'mdl-layout__tab-bar-container',
89
+ TAB: 'mdl-layout__tab',
90
+ TAB_BAR_BUTTON: 'mdl-layout__tab-bar-button',
91
+ TAB_BAR_LEFT_BUTTON: 'mdl-layout__tab-bar-left-button',
92
+ TAB_BAR_RIGHT_BUTTON: 'mdl-layout__tab-bar-right-button',
93
+ PANEL: 'mdl-layout__tab-panel',
94
+
95
+ HAS_DRAWER: 'has-drawer',
96
+ HAS_TABS: 'has-tabs',
97
+ HAS_SCROLLING_HEADER: 'has-scrolling-header',
98
+ CASTING_SHADOW: 'is-casting-shadow',
99
+ IS_COMPACT: 'is-compact',
100
+ IS_SMALL_SCREEN: 'is-small-screen',
101
+ IS_DRAWER_OPEN: 'is-visible',
102
+ IS_ACTIVE: 'is-active',
103
+ IS_UPGRADED: 'is-upgraded',
104
+ IS_ANIMATING: 'is-animating',
105
+
106
+ ON_LARGE_SCREEN : 'mdl-layout--large-screen-only',
107
+ ON_SMALL_SCREEN : 'mdl-layout--small-screen-only'
108
+
109
+ };
110
+
111
+ /**
112
+ * Handles scrolling on the content.
113
+ * @private
114
+ */
115
+ MaterialLayout.prototype.contentScrollHandler_ = function() {
116
+ 'use strict';
117
+
118
+ if (this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)) {
119
+ return;
120
+ }
121
+
122
+ if (this.content_.scrollTop > 0 &&
123
+ !this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
124
+ this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);
125
+ this.header_.classList.add(this.CssClasses_.IS_COMPACT);
126
+ this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
127
+ } else if (this.content_.scrollTop <= 0 &&
128
+ this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
129
+ this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);
130
+ this.header_.classList.remove(this.CssClasses_.IS_COMPACT);
131
+ this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
132
+ }
133
+ };
134
+
135
+ /**
136
+ * Handles changes in screen size.
137
+ * @private
138
+ */
139
+ MaterialLayout.prototype.screenSizeHandler_ = function() {
140
+ 'use strict';
141
+
142
+ if (this.screenSizeMediaQuery_.matches) {
143
+ this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN);
144
+ } else {
145
+ this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN);
146
+ // Collapse drawer (if any) when moving to a large screen size.
147
+ if (this.drawer_) {
148
+ this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);
149
+ }
150
+ }
151
+ };
152
+
153
+ /**
154
+ * Handles toggling of the drawer.
155
+ * @param {Element} drawer The drawer container element.
156
+ * @private
157
+ */
158
+ MaterialLayout.prototype.drawerToggleHandler_ = function() {
159
+ 'use strict';
160
+
161
+ this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);
162
+ };
163
+
164
+ /**
165
+ * Handles (un)setting the `is-animating` class
166
+ */
167
+ MaterialLayout.prototype.headerTransitionEndHandler = function() {
168
+ 'use strict';
169
+
170
+ this.header_.classList.remove(this.CssClasses_.IS_ANIMATING);
171
+ };
172
+
173
+ /**
174
+ * Handles expanding the header on click
175
+ */
176
+ MaterialLayout.prototype.headerClickHandler = function() {
177
+ 'use strict';
178
+
179
+ if (this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
180
+ this.header_.classList.remove(this.CssClasses_.IS_COMPACT);
181
+ this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
182
+ }
183
+ };
184
+
185
+ /**
186
+ * Reset tab state, dropping active classes
187
+ * @private
188
+ */
189
+ MaterialLayout.prototype.resetTabState_ = function(tabBar) {
190
+ 'use strict';
191
+
192
+ for (var k = 0; k < tabBar.length; k++) {
193
+ tabBar[k].classList.remove(this.CssClasses_.IS_ACTIVE);
194
+ }
195
+ };
196
+
197
+ /**
198
+ * Reset panel state, droping active classes
199
+ * @private
200
+ */
201
+ MaterialLayout.prototype.resetPanelState_ = function(panels) {
202
+ 'use strict';
203
+
204
+ for (var j = 0; j < panels.length; j++) {
205
+ panels[j].classList.remove(this.CssClasses_.IS_ACTIVE);
206
+ }
207
+ };
208
+
209
+ /**
210
+ * Initialize element.
211
+ */
212
+ MaterialLayout.prototype.init = function() {
213
+ 'use strict';
214
+
215
+ if (this.element_) {
216
+ var container = document.createElement('div');
217
+ container.classList.add(this.CssClasses_.CONTAINER);
218
+ this.element_.parentElement.insertBefore(container, this.element_);
219
+ this.element_.parentElement.removeChild(this.element_);
220
+ container.appendChild(this.element_);
221
+
222
+ var directChildren = this.element_.childNodes;
223
+ for (var c = 0; c < directChildren.length; c++) {
224
+ var child = directChildren[c];
225
+ if (child.classList &&
226
+ child.classList.contains(this.CssClasses_.HEADER)) {
227
+ this.header_ = child;
228
+ }
229
+
230
+ if (child.classList &&
231
+ child.classList.contains(this.CssClasses_.DRAWER)) {
232
+ this.drawer_ = child;
233
+ }
234
+
235
+ if (child.classList &&
236
+ child.classList.contains(this.CssClasses_.CONTENT)) {
237
+ this.content_ = child;
238
+ }
239
+ }
240
+
241
+ if (this.header_) {
242
+ this.tabBar_ = this.header_.querySelector('.' + this.CssClasses_.TAB_BAR);
243
+ }
244
+
245
+ var mode = this.Mode_.STANDARD;
246
+
247
+ // Keep an eye on screen size, and add/remove auxiliary class for styling
248
+ // of small screens.
249
+ this.screenSizeMediaQuery_ = window.matchMedia(this.Constant_.MAX_WIDTH);
250
+ this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this));
251
+ this.screenSizeHandler_();
252
+
253
+ if (this.header_) {
254
+ if (this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)) {
255
+ mode = this.Mode_.SEAMED;
256
+ } else if (this.header_.classList.contains(
257
+ this.CssClasses_.HEADER_WATERFALL)) {
258
+ mode = this.Mode_.WATERFALL;
259
+ this.header_.addEventListener('transitionend',
260
+ this.headerTransitionEndHandler.bind(this));
261
+ this.header_.addEventListener('click',
262
+ this.headerClickHandler.bind(this));
263
+ } else if (this.header_.classList.contains(
264
+ this.CssClasses_.HEADER_SCROLL)) {
265
+ mode = this.Mode_.SCROLL;
266
+ container.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER);
267
+ }
268
+
269
+ if (mode === this.Mode_.STANDARD) {
270
+ this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);
271
+ if (this.tabBar_) {
272
+ this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW);
273
+ }
274
+ } else if (mode === this.Mode_.SEAMED || mode === this.Mode_.SCROLL) {
275
+ this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);
276
+ if (this.tabBar_) {
277
+ this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW);
278
+ }
279
+ } else if (mode === this.Mode_.WATERFALL) {
280
+ // Add and remove shadows depending on scroll position.
281
+ // Also add/remove auxiliary class for styling of the compact version of
282
+ // the header.
283
+ this.content_.addEventListener('scroll',
284
+ this.contentScrollHandler_.bind(this));
285
+ this.contentScrollHandler_();
286
+ }
287
+ }
288
+
289
+ // Add drawer toggling button to our layout, if we have an openable drawer.
290
+ if (this.drawer_) {
291
+ var drawerButton = document.createElement('div');
292
+ drawerButton.classList.add(this.CssClasses_.DRAWER_BTN);
293
+
294
+ if (this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)) {
295
+ //If drawer has ON_LARGE_SCREEN class then add it to the drawer toggle button as well.
296
+ drawerButton.classList.add(this.CssClasses_.ON_LARGE_SCREEN);
297
+ } else if (this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)) {
298
+ //If drawer has ON_SMALL_SCREEN class then add it to the drawer toggle button as well.
299
+ drawerButton.classList.add(this.CssClasses_.ON_SMALL_SCREEN);
300
+ }
301
+ var drawerButtonIcon = document.createElement('i');
302
+ drawerButtonIcon.classList.add(this.CssClasses_.ICON);
303
+ drawerButtonIcon.textContent = this.Constant_.MENU_ICON;
304
+ drawerButton.appendChild(drawerButtonIcon);
305
+ drawerButton.addEventListener('click',
306
+ this.drawerToggleHandler_.bind(this));
307
+
308
+ // Add a class if the layout has a drawer, for altering the left padding.
309
+ // Adds the HAS_DRAWER to the elements since this.header_ may or may
310
+ // not be present.
311
+ this.element_.classList.add(this.CssClasses_.HAS_DRAWER);
312
+
313
+ // If we have a fixed header, add the button to the header rather than
314
+ // the layout.
315
+ if (this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)) {
316
+ this.header_.insertBefore(drawerButton, this.header_.firstChild);
317
+ } else {
318
+ this.element_.insertBefore(drawerButton, this.content_);
319
+ }
320
+
321
+ var obfuscator = document.createElement('div');
322
+ obfuscator.classList.add(this.CssClasses_.OBFUSCATOR);
323
+ this.element_.appendChild(obfuscator);
324
+ obfuscator.addEventListener('click',
325
+ this.drawerToggleHandler_.bind(this));
326
+ }
327
+
328
+ // Initialize tabs, if any.
329
+ if (this.header_ && this.tabBar_) {
330
+ this.element_.classList.add(this.CssClasses_.HAS_TABS);
331
+
332
+ var tabContainer = document.createElement('div');
333
+ tabContainer.classList.add(this.CssClasses_.TAB_CONTAINER);
334
+ this.header_.insertBefore(tabContainer, this.tabBar_);
335
+ this.header_.removeChild(this.tabBar_);
336
+
337
+ var leftButton = document.createElement('div');
338
+ leftButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);
339
+ leftButton.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON);
340
+ var leftButtonIcon = document.createElement('i');
341
+ leftButtonIcon.classList.add(this.CssClasses_.ICON);
342
+ leftButtonIcon.textContent = this.Constant_.CHEVRON_LEFT;
343
+ leftButton.appendChild(leftButtonIcon);
344
+ leftButton.addEventListener('click', function() {
345
+ this.tabBar_.scrollLeft -= this.Constant_.TAB_SCROLL_PIXELS;
346
+ }.bind(this));
347
+
348
+ var rightButton = document.createElement('div');
349
+ rightButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);
350
+ rightButton.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON);
351
+ var rightButtonIcon = document.createElement('i');
352
+ rightButtonIcon.classList.add(this.CssClasses_.ICON);
353
+ rightButtonIcon.textContent = this.Constant_.CHEVRON_RIGHT;
354
+ rightButton.appendChild(rightButtonIcon);
355
+ rightButton.addEventListener('click', function() {
356
+ this.tabBar_.scrollLeft += this.Constant_.TAB_SCROLL_PIXELS;
357
+ }.bind(this));
358
+
359
+ tabContainer.appendChild(leftButton);
360
+ tabContainer.appendChild(this.tabBar_);
361
+ tabContainer.appendChild(rightButton);
362
+
363
+ // Add and remove buttons depending on scroll position.
364
+ var tabScrollHandler = function() {
365
+ if (this.tabBar_.scrollLeft > 0) {
366
+ leftButton.classList.add(this.CssClasses_.IS_ACTIVE);
367
+ } else {
368
+ leftButton.classList.remove(this.CssClasses_.IS_ACTIVE);
369
+ }
370
+
371
+ if (this.tabBar_.scrollLeft <
372
+ this.tabBar_.scrollWidth - this.tabBar_.offsetWidth) {
373
+ rightButton.classList.add(this.CssClasses_.IS_ACTIVE);
374
+ } else {
375
+ rightButton.classList.remove(this.CssClasses_.IS_ACTIVE);
376
+ }
377
+ }.bind(this);
378
+
379
+ this.tabBar_.addEventListener('scroll', tabScrollHandler);
380
+ tabScrollHandler();
381
+
382
+ if (this.tabBar_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {
383
+ this.tabBar_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
384
+ }
385
+
386
+ // Select element tabs, document panels
387
+ var tabs = this.tabBar_.querySelectorAll('.' + this.CssClasses_.TAB);
388
+ var panels = this.content_.querySelectorAll('.' + this.CssClasses_.PANEL);
389
+
390
+ // Create new tabs for each tab element
391
+ for (var i = 0; i < tabs.length; i++) {
392
+ new MaterialLayoutTab(tabs[i], tabs, panels, this);
393
+ }
394
+ }
395
+
396
+ this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
397
+ }
398
+ };
399
+
400
+ function MaterialLayoutTab(tab, tabs, panels, layout) {
401
+ 'use strict';
402
+
403
+ if (tab) {
404
+ if (layout.tabBar_.classList.contains(
405
+ layout.CssClasses_.JS_RIPPLE_EFFECT)) {
406
+ var rippleContainer = document.createElement('span');
407
+ rippleContainer.classList.add(layout.CssClasses_.RIPPLE_CONTAINER);
408
+ rippleContainer.classList.add(layout.CssClasses_.JS_RIPPLE_EFFECT);
409
+ var ripple = document.createElement('span');
410
+ ripple.classList.add(layout.CssClasses_.RIPPLE);
411
+ rippleContainer.appendChild(ripple);
412
+ tab.appendChild(rippleContainer);
413
+ }
414
+
415
+ tab.addEventListener('click', function(e) {
416
+ e.preventDefault();
417
+ var href = tab.href.split('#')[1];
418
+ var panel = layout.content_.querySelector('#' + href);
419
+ layout.resetTabState_(tabs);
420
+ layout.resetPanelState_(panels);
421
+ tab.classList.add(layout.CssClasses_.IS_ACTIVE);
422
+ panel.classList.add(layout.CssClasses_.IS_ACTIVE);
423
+ });
424
+
425
+ }
426
+ }
427
+
428
+ // The component registers itself. It can assume componentHandler is available
429
+ // in the global scope.
430
+ componentHandler.register({
431
+ constructor: MaterialLayout,
432
+ classAsString: 'MaterialLayout',
433
+ cssClass: 'mdl-js-layout'
434
+ });