voom-presenters 0.1.13 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (305) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +186 -0
  4. data/Gemfile.lock +37 -38
  5. data/HISTORY.md +61 -0
  6. data/README.md +23 -1
  7. data/app/demo/components/chips.pom +6 -0
  8. data/app/demo/components/{forms.pom → content.pom} +3 -3
  9. data/app/demo/components/date_fields.pom +1 -1
  10. data/app/demo/components/datetime_fields.pom +6 -0
  11. data/app/demo/components/drawers.pom +1 -1
  12. data/app/demo/components/file_inputs.pom +16 -0
  13. data/app/demo/components/footers.pom +1 -1
  14. data/app/demo/components/google_maps.pom +17 -0
  15. data/app/demo/components/headers.pom +1 -1
  16. data/app/demo/components/layouts.pom +36 -4
  17. data/app/demo/components/lists.pom +25 -0
  18. data/app/demo/components/nav/menu.pom +9 -2
  19. data/app/demo/components/nav/pattern_drawer.pom +5 -0
  20. data/app/demo/components/nav/pattern_menu.pom +12 -0
  21. data/app/demo/components/sliders.pom +49 -0
  22. data/app/demo/components/snackbar.pom +10 -0
  23. data/app/demo/components/steppers.pom +178 -0
  24. data/app/demo/components/tab_bars.pom +51 -0
  25. data/app/demo/components/tables.pom +85 -13
  26. data/app/demo/components/text_areas.pom +13 -0
  27. data/app/demo/components/text_fields.pom +20 -8
  28. data/app/demo/components/toggles.pom +50 -14
  29. data/app/demo/components/tooltips.pom +2 -6
  30. data/app/demo/events/actions/clear.pom +23 -0
  31. data/app/demo/events/actions/loads.pom +16 -6
  32. data/app/demo/events/actions/posts.pom +1 -1
  33. data/app/demo/events/actions/toggle_visiblity.pom +4 -3
  34. data/app/demo/events/nav/drawer.pom +2 -2
  35. data/app/demo/events/tagged_input.pom +37 -0
  36. data/app/demo/hello_world.pom +3 -0
  37. data/app/demo/markdown.pom +1 -0
  38. data/app/demo/namespaces.pom +89 -0
  39. data/app/demo/nav/top_nav.pom +12 -0
  40. data/app/demo/patterns.pom +19 -0
  41. data/app/demo/patterns/search_select.pom +104 -0
  42. data/app/demo/shared/context_list.pom +1 -1
  43. data/app/demo/styles.pom +21 -11
  44. data/component-status.yml +11 -11
  45. data/config.ru +2 -1
  46. data/lib/voom/container_methods.rb +1 -1
  47. data/lib/voom/presenters-engine.rb +29 -26
  48. data/lib/voom/presenters.rb +15 -9
  49. data/lib/voom/presenters/api/app.rb +18 -5
  50. data/lib/voom/presenters/api/router.rb +11 -49
  51. data/lib/voom/presenters/demo/echo.rb +5 -0
  52. data/lib/voom/presenters/dsl.rb +10 -4
  53. data/lib/voom/presenters/dsl/components/actions/base.rb +37 -0
  54. data/lib/voom/presenters/dsl/components/actions/clear.rb +17 -0
  55. data/lib/voom/presenters/dsl/components/actions/deletes.rb +17 -0
  56. data/lib/voom/presenters/dsl/components/actions/dialog.rb +17 -0
  57. data/lib/voom/presenters/dsl/components/actions/loads.rb +32 -0
  58. data/lib/voom/presenters/dsl/components/actions/navigates.rb +17 -0
  59. data/lib/voom/presenters/dsl/components/actions/posts.rb +17 -0
  60. data/lib/voom/presenters/dsl/components/actions/remove.rb +17 -0
  61. data/lib/voom/presenters/dsl/components/actions/replaces.rb +25 -0
  62. data/lib/voom/presenters/dsl/components/actions/snackbar.rb +17 -0
  63. data/lib/voom/presenters/dsl/components/actions/stepper.rb +17 -0
  64. data/lib/voom/presenters/dsl/components/actions/toggle_visibility.rb +17 -0
  65. data/lib/voom/presenters/dsl/components/actions/updates.rb +17 -0
  66. data/lib/voom/presenters/dsl/components/avatar.rb +4 -5
  67. data/lib/voom/presenters/dsl/components/badge.rb +1 -1
  68. data/lib/voom/presenters/dsl/components/base.rb +20 -11
  69. data/lib/voom/presenters/dsl/components/button.rb +12 -10
  70. data/lib/voom/presenters/dsl/components/card.rb +18 -19
  71. data/lib/voom/presenters/dsl/components/checkbox.rb +3 -1
  72. data/lib/voom/presenters/dsl/components/chip.rb +9 -10
  73. data/lib/voom/presenters/dsl/components/content.rb +21 -11
  74. data/lib/voom/presenters/dsl/components/date_field.rb +1 -1
  75. data/lib/voom/presenters/dsl/components/datetime_base.rb +1 -2
  76. data/lib/voom/presenters/dsl/components/datetime_field.rb +1 -1
  77. data/lib/voom/presenters/dsl/components/dialog.rb +10 -6
  78. data/lib/voom/presenters/dsl/components/drawer.rb +6 -4
  79. data/lib/voom/presenters/dsl/components/event.rb +55 -39
  80. data/lib/voom/presenters/dsl/components/event_base.rb +2 -2
  81. data/lib/voom/presenters/dsl/components/expansion_panel.rb +5 -5
  82. data/lib/voom/presenters/dsl/components/file_input.rb +22 -0
  83. data/lib/voom/presenters/dsl/components/footer.rb +1 -1
  84. data/lib/voom/presenters/dsl/components/form.rb +17 -15
  85. data/lib/voom/presenters/dsl/components/google_map.rb +40 -0
  86. data/lib/voom/presenters/dsl/components/grid.rb +58 -18
  87. data/lib/voom/presenters/dsl/components/header.rb +2 -5
  88. data/lib/voom/presenters/dsl/components/hidden_field.rb +2 -2
  89. data/lib/voom/presenters/dsl/components/icon.rb +4 -5
  90. data/lib/voom/presenters/dsl/components/icon_base.rb +3 -3
  91. data/lib/voom/presenters/dsl/components/icon_toggle.rb +2 -2
  92. data/lib/voom/presenters/dsl/components/image.rb +3 -3
  93. data/lib/voom/presenters/dsl/components/input.rb +2 -2
  94. data/lib/voom/presenters/dsl/components/list.rb +12 -10
  95. data/lib/voom/presenters/dsl/components/lists/action.rb +8 -9
  96. data/lib/voom/presenters/dsl/components/lists/actions.rb +8 -8
  97. data/lib/voom/presenters/dsl/components/lists/header.rb +2 -2
  98. data/lib/voom/presenters/dsl/components/lists/line.rb +14 -17
  99. data/lib/voom/presenters/dsl/components/lists/separator.rb +2 -2
  100. data/lib/voom/presenters/dsl/components/menu.rb +10 -12
  101. data/lib/voom/presenters/dsl/components/mixins/attaches.rb +9 -3
  102. data/lib/voom/presenters/dsl/components/mixins/avatar.rb +0 -1
  103. data/lib/voom/presenters/dsl/components/mixins/buttons.rb +1 -1
  104. data/lib/voom/presenters/dsl/components/mixins/chips.rb +1 -2
  105. data/lib/voom/presenters/dsl/components/mixins/common.rb +20 -14
  106. data/lib/voom/presenters/dsl/components/mixins/content.rb +1 -1
  107. data/lib/voom/presenters/dsl/components/mixins/date_time_fields.rb +0 -3
  108. data/lib/voom/presenters/dsl/components/mixins/dialogs.rb +1 -2
  109. data/lib/voom/presenters/dsl/components/mixins/event.rb +3 -3
  110. data/lib/voom/presenters/dsl/components/mixins/expansion_panels.rb +1 -1
  111. data/lib/voom/presenters/dsl/components/mixins/file_inputs.rb +16 -0
  112. data/lib/voom/presenters/dsl/components/mixins/google_maps.rb +15 -0
  113. data/lib/voom/presenters/dsl/components/mixins/grids.rb +1 -1
  114. data/lib/voom/presenters/dsl/components/mixins/icons.rb +0 -1
  115. data/lib/voom/presenters/dsl/components/mixins/menus.rb +1 -1
  116. data/lib/voom/presenters/dsl/components/mixins/selects.rb +0 -1
  117. data/lib/voom/presenters/dsl/components/mixins/sliders.rb +15 -0
  118. data/lib/voom/presenters/dsl/components/mixins/snackbars.rb +0 -1
  119. data/lib/voom/presenters/dsl/components/mixins/steppers.rb +15 -0
  120. data/lib/voom/presenters/dsl/components/mixins/tab_bars.rb +15 -0
  121. data/lib/voom/presenters/dsl/components/mixins/text_fields.rb +5 -3
  122. data/lib/voom/presenters/dsl/components/mixins/toggles.rb +1 -4
  123. data/lib/voom/presenters/dsl/components/mixins/tooltips.rb +0 -1
  124. data/lib/voom/presenters/dsl/components/mixins/typography.rb +43 -13
  125. data/lib/voom/presenters/dsl/components/page.rb +0 -1
  126. data/lib/voom/presenters/dsl/components/radio_button.rb +1 -1
  127. data/lib/voom/presenters/dsl/components/rich_text_area.rb +26 -0
  128. data/lib/voom/presenters/dsl/components/select.rb +4 -5
  129. data/lib/voom/presenters/dsl/components/slider.rb +39 -0
  130. data/lib/voom/presenters/dsl/components/snackbar.rb +2 -2
  131. data/lib/voom/presenters/dsl/components/stepper.rb +106 -0
  132. data/lib/voom/presenters/dsl/components/switch.rb +1 -1
  133. data/lib/voom/presenters/dsl/components/tab_bar.rb +53 -0
  134. data/lib/voom/presenters/dsl/components/table.rb +99 -27
  135. data/lib/voom/presenters/dsl/components/text_area.rb +4 -3
  136. data/lib/voom/presenters/dsl/components/text_field.rb +8 -12
  137. data/lib/voom/presenters/dsl/components/time_field.rb +1 -1
  138. data/lib/voom/presenters/dsl/components/toggle_base.rb +2 -2
  139. data/lib/voom/presenters/dsl/components/tooltip.rb +1 -2
  140. data/lib/voom/presenters/dsl/components/typography.rb +4 -5
  141. data/lib/voom/presenters/dsl/definer.rb +2 -2
  142. data/lib/voom/presenters/dsl/definition.rb +6 -4
  143. data/lib/voom/presenters/dsl/user_interface.rb +17 -21
  144. data/lib/voom/presenters/errors/parameter_validation.rb +1 -1
  145. data/lib/voom/presenters/helpers.rb +5 -5
  146. data/lib/voom/presenters/helpers/date.rb +3 -3
  147. data/lib/voom/presenters/helpers/rails.rb +7 -2
  148. data/lib/voom/presenters/helpers/rails/model_table.rb +14 -6
  149. data/lib/voom/presenters/helpers/route.rb +6 -0
  150. data/lib/voom/presenters/helpers/time.rb +1 -1
  151. data/lib/voom/presenters/namespace.rb +12 -0
  152. data/lib/voom/presenters/settings.rb +58 -37
  153. data/lib/voom/presenters/version.rb +1 -1
  154. data/lib/voom/presenters/web_client/app.rb +50 -20
  155. data/lib/voom/presenters/web_client/markdown_render.rb +24 -11
  156. data/lib/voom/presenters/web_client/router.rb +17 -52
  157. data/lib/voom/serializer.rb +2 -2
  158. data/lib/voom/trace.rb +1 -1
  159. data/presenters.gemspec +2 -1
  160. data/public/style-bundle.js +2 -2
  161. data/scripts/bump.sh +1 -0
  162. data/scripts/changelog.sh +5 -0
  163. data/scripts/deploy-demo.sh +1 -0
  164. data/scripts/release.sh +1 -1
  165. data/scripts/tag.sh +5 -0
  166. data/views/mdc/.babelrc +8 -0
  167. data/views/mdc/.eslintrc.yml +23 -0
  168. data/views/mdc/assets/js/app.js +19 -6
  169. data/views/mdc/assets/js/components/base-component.js +25 -2
  170. data/views/mdc/assets/js/components/base-container.js +47 -0
  171. data/views/mdc/assets/js/components/button.js +3 -10
  172. data/views/mdc/assets/js/components/cards.js +11 -0
  173. data/views/mdc/assets/js/components/checkboxes.js +30 -7
  174. data/views/mdc/assets/js/components/chips.js +38 -5
  175. data/views/mdc/assets/js/components/content.js +13 -0
  176. data/views/mdc/assets/js/components/data-tables.js +38 -0
  177. data/views/mdc/assets/js/components/datetime.js +61 -21
  178. data/views/mdc/assets/js/components/dialogs.js +25 -19
  179. data/views/mdc/assets/js/components/events.js +13 -3
  180. data/views/mdc/assets/js/components/events/base.js +13 -3
  181. data/views/mdc/assets/js/components/events/errors.js +1 -1
  182. data/views/mdc/assets/js/components/events/posts.js +53 -13
  183. data/views/mdc/assets/js/components/events/removes.js +20 -0
  184. data/views/mdc/assets/js/components/events/replaces.js +35 -36
  185. data/views/mdc/assets/js/components/events/stepper.js +23 -0
  186. data/views/mdc/assets/js/components/events/toggle_visibility.js +15 -11
  187. data/views/mdc/assets/js/components/file-inputs.js +29 -0
  188. data/views/mdc/assets/js/components/forms.js +8 -59
  189. data/views/mdc/assets/js/components/grid.js +20 -0
  190. data/views/mdc/assets/js/components/hidden-fields.js +33 -0
  191. data/views/mdc/assets/js/components/icon-toggles.js +7 -14
  192. data/views/mdc/assets/js/components/initialize.js +20 -1
  193. data/views/mdc/assets/js/components/lists.js +1 -1
  194. data/views/mdc/assets/js/components/menus.js +12 -13
  195. data/views/mdc/assets/js/components/mixins/visibility-observer.js +34 -0
  196. data/views/mdc/assets/js/components/radios.js +39 -0
  197. data/views/mdc/assets/js/components/rich-text-area.js +43 -0
  198. data/views/mdc/assets/js/components/selects.js +24 -23
  199. data/views/mdc/assets/js/components/sliders.js +56 -0
  200. data/views/mdc/assets/js/components/snackbar.js +14 -23
  201. data/views/mdc/assets/js/components/steppers.js +48 -0
  202. data/views/mdc/assets/js/components/switches.js +24 -23
  203. data/views/mdc/assets/js/components/tab-bars.js +14 -0
  204. data/views/mdc/assets/js/components/text-fields.js +37 -35
  205. data/views/mdc/assets/js/config.js +27 -0
  206. data/views/mdc/assets/js/mdl-stepper.js +1108 -0
  207. data/views/mdc/assets/js/utils/compatibility.js +9 -0
  208. data/views/mdc/assets/js/utils/config.js +73 -0
  209. data/views/mdc/assets/js/utils/config.test.js +59 -0
  210. data/views/mdc/assets/js/utils/urls.js +5 -2
  211. data/views/mdc/assets/scss/app.scss +11 -3
  212. data/views/mdc/assets/scss/components/button.scss +17 -2
  213. data/views/mdc/assets/scss/components/card.scss +8 -3
  214. data/views/mdc/assets/scss/components/checkbox.scss +0 -4
  215. data/views/mdc/assets/scss/components/content.scss +11 -0
  216. data/views/mdc/assets/scss/components/data-table.scss +80 -0
  217. data/views/mdc/assets/scss/components/datetime.scss +6 -0
  218. data/views/mdc/assets/scss/components/fab.scss +2 -1
  219. data/views/mdc/assets/scss/components/file-input.scss +22 -0
  220. data/views/mdc/assets/scss/components/grid.scss +59 -3
  221. data/views/mdc/assets/scss/components/image.scss +6 -0
  222. data/views/mdc/assets/scss/components/list.scss +13 -0
  223. data/views/mdc/assets/scss/components/menu.scss +1 -0
  224. data/views/mdc/assets/scss/components/radio.scss +4 -0
  225. data/views/mdc/assets/scss/components/rich-text-area.scss +37 -0
  226. data/views/mdc/assets/scss/components/slider.scss +1 -0
  227. data/views/mdc/assets/scss/components/snackbar.scss +1 -5
  228. data/views/mdc/assets/scss/components/stepper.scss +235 -0
  229. data/views/mdc/assets/scss/components/switch.scss +4 -5
  230. data/views/mdc/assets/scss/components/tab-bars.scss +4 -0
  231. data/views/mdc/assets/scss/components/textfield.scss +8 -1
  232. data/views/mdc/assets/scss/components/typography.scss +4 -0
  233. data/views/mdc/assets/scss/components/vendor/flatpickr.min.css +2 -2
  234. data/views/mdc/assets/scss/components/vendor/quill.snow.css +945 -0
  235. data/views/mdc/assets/scss/styles.scss +3 -2
  236. data/views/mdc/assets/scss/theme.scss +6 -0
  237. data/views/mdc/body/header.erb +1 -0
  238. data/views/mdc/body/snackbar.erb +1 -1
  239. data/views/mdc/components/actions/clear.rb +11 -0
  240. data/views/mdc/components/actions/delete.rb +11 -0
  241. data/views/mdc/components/actions/dialog.rb +11 -0
  242. data/views/mdc/components/actions/loads.rb +11 -0
  243. data/views/mdc/components/actions/navigates.rb +11 -0
  244. data/views/mdc/components/actions/post.rb +17 -0
  245. data/views/mdc/components/actions/remove.rb +10 -0
  246. data/views/mdc/components/actions/replaces.rb +12 -0
  247. data/views/mdc/components/actions/snackbar.rb +10 -0
  248. data/views/mdc/components/actions/stepper.rb +10 -0
  249. data/views/mdc/components/actions/toggle_visibility.rb +10 -0
  250. data/views/mdc/components/actions/update.rb +10 -0
  251. data/views/mdc/components/button.erb +9 -6
  252. data/views/mdc/components/buttons/button.erb +10 -5
  253. data/views/mdc/components/buttons/fab.erb +8 -2
  254. data/views/mdc/components/buttons/icon.erb +9 -2
  255. data/views/mdc/components/buttons/image.erb +9 -4
  256. data/views/mdc/components/{display.erb → caption.erb} +0 -0
  257. data/views/mdc/components/card.erb +6 -3
  258. data/views/mdc/components/checkbox.erb +21 -9
  259. data/views/mdc/components/chip.erb +12 -3
  260. data/views/mdc/components/content.erb +6 -1
  261. data/views/mdc/components/datetime.erb +21 -13
  262. data/views/mdc/components/dialog.erb +4 -1
  263. data/views/mdc/components/event.erb +5 -9
  264. data/views/mdc/components/file_input.erb +13 -0
  265. data/views/mdc/components/form.erb +19 -5
  266. data/views/mdc/components/google_map.erb +9 -0
  267. data/views/mdc/components/grid.erb +18 -4
  268. data/views/mdc/components/headline.erb +2 -0
  269. data/views/mdc/components/hidden_field.erb +6 -1
  270. data/views/mdc/components/icon_toggle.erb +1 -1
  271. data/views/mdc/components/list.erb +5 -2
  272. data/views/mdc/components/list/actions/switch.erb +1 -1
  273. data/views/mdc/components/list/line.erb +7 -6
  274. data/views/mdc/components/menu.erb +8 -12
  275. data/views/mdc/components/{subheading.erb → overline.erb} +0 -0
  276. data/views/mdc/components/radio_button.erb +20 -10
  277. data/views/mdc/components/rich_text_area.erb +19 -0
  278. data/views/mdc/components/select.erb +7 -3
  279. data/views/mdc/components/slider.erb +41 -0
  280. data/views/mdc/components/snackbar.erb +2 -6
  281. data/views/mdc/components/stepper.erb +47 -0
  282. data/views/mdc/components/stepper/step.erb +33 -0
  283. data/views/mdc/components/{title.erb → subtitle.erb} +0 -0
  284. data/views/mdc/components/switch.erb +27 -12
  285. data/views/mdc/components/tab_bar.erb +29 -0
  286. data/views/mdc/components/table.erb +4 -2
  287. data/views/mdc/components/table/checkbox.erb +17 -0
  288. data/views/mdc/components/table/header.erb +13 -4
  289. data/views/mdc/components/table/pagination.erb +14 -23
  290. data/views/mdc/components/table/row.erb +3 -1
  291. data/views/mdc/components/text_area.erb +17 -7
  292. data/views/mdc/components/text_field.erb +31 -13
  293. data/views/mdc/components/typography.erb +2 -2
  294. data/views/mdc/layout.erb +33 -31
  295. data/views/mdc/package-lock.json +11019 -6996
  296. data/views/mdc/package.json +46 -27
  297. data/views/mdc/webpack.config.js +1 -0
  298. metadata +112 -13
  299. data/app/demo/events/actions/autocomplete.pom +0 -32
  300. data/lib/voom/presenters/dsl/components/action.rb +0 -35
  301. data/views/mdc/assets/js/components/events/autocomplete.js +0 -96
  302. data/views/mdc/assets/js/material.js +0 -3996
  303. data/views/mdc/assets/scss/components/table-pagination.scss +0 -65
  304. data/views/mdc/components/modal.erb +0 -15
  305. data/views/mdc/components/static.erb +0 -7
@@ -1,35 +0,0 @@
1
- require_relative 'base'
2
-
3
- module Voom
4
- module Presenters
5
- module DSL
6
- module Components
7
- class Action < Base
8
- # Options are used by the actions
9
- # Params are passed by the user
10
- attr_reader :params, :options
11
-
12
- def initialize(type:, **attribs_, &block)
13
- super(type: type, **attribs_, &block)
14
- @options = {}
15
- extract_options!
16
- @params = attribs.delete(:params) {{}}
17
- @url = nil
18
- end
19
-
20
- def url
21
- @parent.router.url(render: options[:presenter], command: options[:path], context: params)
22
- end
23
-
24
- private
25
- def extract_options!
26
- %i(path presenter target).each do |option|
27
- optionValue = attribs.delete(option)
28
- @options.merge!({option => optionValue}) if optionValue
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,96 +0,0 @@
1
- import {VSnackbar} from '../snackbar';
2
- import {VBase} from './base';
3
- import {initialize} from '../initialize';
4
-
5
- // Auto complete a datalist
6
- // The elementId is a datalist
7
- // The url is called as a GET expecting json back
8
- export class VAutoComplete extends VBase {
9
- constructor(options, url, params, event) {
10
- super(options);
11
- this.element_id = options.target;
12
- this.url = url;
13
- this.params = params;
14
- this.event = event;
15
- }
16
-
17
- call(results) {
18
- // Clear the timeout if it has already been set.
19
- // This will prevent the previous task from executing
20
- // if it has been less than <MILLISECONDS>
21
- var parentElement = this.parentElement();
22
- var updateElement = this.createUpdateElementHandler(this);
23
- var promiseObj = new Promise(function (resolve) {
24
- clearTimeout(parentElement.vTimeout);
25
- // Make a new timeout
26
- parentElement.vTimeout = setTimeout(updateElement, 500);
27
- results.push({action:'autocomplete', statusCode: 200});
28
- resolve(results);
29
- });
30
- return promiseObj;
31
- }
32
-
33
- // This is used to get a proper binding of the object
34
- // https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example
35
- createUpdateElementHandler(_this_) {
36
- return function () {
37
- _this_.updateElement();
38
- };
39
- }
40
-
41
- updateElement() {
42
- this.clearErrors();
43
- this.getData(this.populateOptions);
44
- }
45
-
46
- dataList() {
47
- return document.getElementById(this.element_id);
48
- }
49
-
50
- getData(funcProcessData) {
51
- var comp = this.component();
52
- if(comp.value().length < 2){
53
- return;
54
- }
55
- var httpRequest = new XMLHttpRequest();
56
- if (!httpRequest) {
57
- throw new Error('Cannot talk to server! Please upgrade your browser to one that supports XMLHttpRequest.');
58
- // new VSnackbar('Cannot talk to server! Please upgrade your browser to one that supports XMLHttpRequest.').display();
59
- }
60
- var dataList = this.dataList();
61
- var url = this.buildURL(this.url, this.params, this.inputValues());
62
-
63
- httpRequest.onreadystatechange = function () {
64
- if (httpRequest.readyState === XMLHttpRequest.DONE) {
65
- console.log(httpRequest.status + ':' + this.getResponseHeader('content-type'));
66
- if (httpRequest.status === 200) {
67
- var response = JSON.parse(httpRequest.responseText);
68
- funcProcessData(response, dataList);
69
- } else {
70
- console.error("Unable to autocomplete! ElementId: " + this.element_id);
71
- }
72
- }
73
- };
74
- console.log('GET:' + url);
75
- httpRequest.open('GET', url, true);
76
- httpRequest.send();
77
- }
78
-
79
- populateOptions(response, dataList) {
80
- dataList.innerHTML = "";
81
-
82
- response.forEach(function (item) {
83
- var value = item;
84
- var key = null;
85
- if (Array.isArray(item)) {
86
- value = item[0];
87
- key = item[1];
88
- }
89
- // Create a new <option> element.
90
- var option = document.createElement('option');
91
- option.value = value;
92
- option.dataset.key = key;
93
- dataList.appendChild(option);
94
- });
95
- }
96
- }
@@ -1,3996 +0,0 @@
1
- ;(function() {
2
- "use strict";
3
-
4
- /**
5
- * @license
6
- * Copyright 2015 Google Inc. All Rights Reserved.
7
- *
8
- * Licensed under the Apache License, Version 2.0 (the "License");
9
- * you may not use this file except in compliance with the License.
10
- * You may obtain a copy of the License at
11
- *
12
- * http://www.apache.org/licenses/LICENSE-2.0
13
- *
14
- * Unless required by applicable law or agreed to in writing, software
15
- * distributed under the License is distributed on an "AS IS" BASIS,
16
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
- * See the License for the specific language governing permissions and
18
- * limitations under the License.
19
- */
20
-
21
- /**
22
- * A component handler interface using the revealing module design pattern.
23
- * More details on this design pattern here:
24
- * https://github.com/jasonmayes/mdl-component-design-pattern
25
- *
26
- * @author Jason Mayes.
27
- */
28
- /* exported componentHandler */
29
-
30
- // Pre-defining the componentHandler interface, for closure documentation and
31
- // static verification.
32
- var componentHandler = {
33
- /**
34
- * Searches existing DOM for elements of our component type and upgrades them
35
- * if they have not already been upgraded.
36
- *
37
- * @param {string=} optJsClass the programatic name of the element class we
38
- * need to create a new instance of.
39
- * @param {string=} optCssClass the name of the CSS class elements of this
40
- * type will have.
41
- */
42
- upgradeDom: function(optJsClass, optCssClass) {},
43
- /**
44
- * Upgrades a specific element rather than all in the DOM.
45
- *
46
- * @param {!Element} element The element we wish to upgrade.
47
- * @param {string=} optJsClass Optional name of the class we want to upgrade
48
- * the element to.
49
- */
50
- upgradeElement: function(element, optJsClass) {},
51
- /**
52
- * Upgrades a specific list of elements rather than all in the DOM.
53
- *
54
- * @param {!Element|!Array<!Element>|!NodeList|!HTMLCollection} elements
55
- * The elements we wish to upgrade.
56
- */
57
- upgradeElements: function(elements) {},
58
- /**
59
- * Upgrades all registered components found in the current DOM. This is
60
- * automatically called on window load.
61
- */
62
- upgradeAllRegistered: function() {},
63
- /**
64
- * Allows user to be alerted to any upgrades that are performed for a given
65
- * component type
66
- *
67
- * @param {string} jsClass The class name of the MDL component we wish
68
- * to hook into for any upgrades performed.
69
- * @param {function(!HTMLElement)} callback The function to call upon an
70
- * upgrade. This function should expect 1 parameter - the HTMLElement which
71
- * got upgraded.
72
- */
73
- registerUpgradedCallback: function(jsClass, callback) {},
74
- /**
75
- * Registers a class for future use and attempts to upgrade existing DOM.
76
- *
77
- * @param {componentHandler.ComponentConfigPublic} config the registration configuration
78
- */
79
- register: function(config) {},
80
- /**
81
- * Downgrade either a given node, an array of nodes, or a NodeList.
82
- *
83
- * @param {!Node|!Array<!Node>|!NodeList} nodes
84
- */
85
- downgradeElements: function(nodes) {}
86
- };
87
-
88
- componentHandler = (function() {
89
- 'use strict';
90
-
91
- /** @type {!Array<componentHandler.ComponentConfig>} */
92
- var registeredComponents_ = [];
93
-
94
- /** @type {!Array<componentHandler.Component>} */
95
- var createdComponents_ = [];
96
-
97
- var componentConfigProperty_ = 'mdlComponentConfigInternal_';
98
-
99
- /**
100
- * Searches registered components for a class we are interested in using.
101
- * Optionally replaces a match with passed object if specified.
102
- *
103
- * @param {string} name The name of a class we want to use.
104
- * @param {componentHandler.ComponentConfig=} optReplace Optional object to replace match with.
105
- * @return {!Object|boolean}
106
- * @private
107
- */
108
- function findRegisteredClass_(name, optReplace) {
109
- for (var i = 0; i < registeredComponents_.length; i++) {
110
- if (registeredComponents_[i].className === name) {
111
- if (typeof optReplace !== 'undefined') {
112
- registeredComponents_[i] = optReplace;
113
- }
114
- return registeredComponents_[i];
115
- }
116
- }
117
- return false;
118
- }
119
-
120
- /**
121
- * Returns an array of the classNames of the upgraded classes on the element.
122
- *
123
- * @param {!Element} element The element to fetch data from.
124
- * @return {!Array<string>}
125
- * @private
126
- */
127
- function getUpgradedListOfElement_(element) {
128
- var dataUpgraded = element.getAttribute('data-upgraded');
129
- // Use `['']` as default value to conform the `,name,name...` style.
130
- return dataUpgraded === null ? [''] : dataUpgraded.split(',');
131
- }
132
-
133
- /**
134
- * Returns true if the given element has already been upgraded for the given
135
- * class.
136
- *
137
- * @param {!Element} element The element we want to check.
138
- * @param {string} jsClass The class to check for.
139
- * @returns {boolean}
140
- * @private
141
- */
142
- function isElementUpgraded_(element, jsClass) {
143
- var upgradedList = getUpgradedListOfElement_(element);
144
- return upgradedList.indexOf(jsClass) !== -1;
145
- }
146
-
147
- /**
148
- * Create an event object.
149
- *
150
- * @param {string} eventType The type name of the event.
151
- * @param {boolean} bubbles Whether the event should bubble up the DOM.
152
- * @param {boolean} cancelable Whether the event can be canceled.
153
- * @returns {!Event}
154
- */
155
- function createEvent_(eventType, bubbles, cancelable) {
156
- if ('CustomEvent' in window && typeof window.CustomEvent === 'function') {
157
- return new CustomEvent(eventType, {
158
- bubbles: bubbles,
159
- cancelable: cancelable
160
- });
161
- } else {
162
- var ev = document.createEvent('Events');
163
- ev.initEvent(eventType, bubbles, cancelable);
164
- return ev;
165
- }
166
- }
167
-
168
- /**
169
- * Searches existing DOM for elements of our component type and upgrades them
170
- * if they have not already been upgraded.
171
- *
172
- * @param {string=} optJsClass the programatic name of the element class we
173
- * need to create a new instance of.
174
- * @param {string=} optCssClass the name of the CSS class elements of this
175
- * type will have.
176
- */
177
- function upgradeDomInternal(optJsClass, optCssClass) {
178
- if (typeof optJsClass === 'undefined' &&
179
- typeof optCssClass === 'undefined') {
180
- for (var i = 0; i < registeredComponents_.length; i++) {
181
- upgradeDomInternal(registeredComponents_[i].className,
182
- registeredComponents_[i].cssClass);
183
- }
184
- } else {
185
- var jsClass = /** @type {string} */ (optJsClass);
186
- if (typeof optCssClass === 'undefined') {
187
- var registeredClass = findRegisteredClass_(jsClass);
188
- if (registeredClass) {
189
- optCssClass = registeredClass.cssClass;
190
- }
191
- }
192
-
193
- var elements = document.querySelectorAll('.' + optCssClass);
194
- for (var n = 0; n < elements.length; n++) {
195
- upgradeElementInternal(elements[n], jsClass);
196
- }
197
- }
198
- }
199
-
200
- /**
201
- * Upgrades a specific element rather than all in the DOM.
202
- *
203
- * @param {!Element} element The element we wish to upgrade.
204
- * @param {string=} optJsClass Optional name of the class we want to upgrade
205
- * the element to.
206
- */
207
- function upgradeElementInternal(element, optJsClass) {
208
- // Verify argument type.
209
- if (!(typeof element === 'object' && element instanceof Element)) {
210
- throw new Error('Invalid argument provided to upgrade MDL element.');
211
- }
212
- // Allow upgrade to be canceled by canceling emitted event.
213
- var upgradingEv = createEvent_('mdl-componentupgrading', true, true);
214
- element.dispatchEvent(upgradingEv);
215
- if (upgradingEv.defaultPrevented) {
216
- return;
217
- }
218
-
219
- var upgradedList = getUpgradedListOfElement_(element);
220
- var classesToUpgrade = [];
221
- // If jsClass is not provided scan the registered components to find the
222
- // ones matching the element's CSS classList.
223
- if (!optJsClass) {
224
- var classList = element.classList;
225
- registeredComponents_.forEach(function(component) {
226
- // Match CSS & Not to be upgraded & Not upgraded.
227
- if (classList.contains(component.cssClass) &&
228
- classesToUpgrade.indexOf(component) === -1 &&
229
- !isElementUpgraded_(element, component.className)) {
230
- classesToUpgrade.push(component);
231
- }
232
- });
233
- } else if (!isElementUpgraded_(element, optJsClass)) {
234
- classesToUpgrade.push(findRegisteredClass_(optJsClass));
235
- }
236
-
237
- // Upgrade the element for each classes.
238
- for (var i = 0, n = classesToUpgrade.length, registeredClass; i < n; i++) {
239
- registeredClass = classesToUpgrade[i];
240
- if (registeredClass) {
241
- // Mark element as upgraded.
242
- upgradedList.push(registeredClass.className);
243
- element.setAttribute('data-upgraded', upgradedList.join(','));
244
- var instance = new registeredClass.classConstructor(element);
245
- instance[componentConfigProperty_] = registeredClass;
246
- createdComponents_.push(instance);
247
- // Call any callbacks the user has registered with this component type.
248
- for (var j = 0, m = registeredClass.callbacks.length; j < m; j++) {
249
- registeredClass.callbacks[j](element);
250
- }
251
-
252
- if (registeredClass.widget) {
253
- // Assign per element instance for control over API
254
- element[registeredClass.className] = instance;
255
- }
256
- } else {
257
- throw new Error(
258
- 'Unable to find a registered component for the given class.');
259
- }
260
-
261
- var upgradedEv = createEvent_('mdl-componentupgraded', true, false);
262
- element.dispatchEvent(upgradedEv);
263
- }
264
- }
265
-
266
- /**
267
- * Upgrades a specific list of elements rather than all in the DOM.
268
- *
269
- * @param {!Element|!Array<!Element>|!NodeList|!HTMLCollection} elements
270
- * The elements we wish to upgrade.
271
- */
272
- function upgradeElementsInternal(elements) {
273
- if (!Array.isArray(elements)) {
274
- if (elements instanceof Element) {
275
- elements = [elements];
276
- } else {
277
- elements = Array.prototype.slice.call(elements);
278
- }
279
- }
280
- for (var i = 0, n = elements.length, element; i < n; i++) {
281
- element = elements[i];
282
- if (element instanceof HTMLElement) {
283
- upgradeElementInternal(element);
284
- if (element.children.length > 0) {
285
- upgradeElementsInternal(element.children);
286
- }
287
- }
288
- }
289
- }
290
-
291
- /**
292
- * Registers a class for future use and attempts to upgrade existing DOM.
293
- *
294
- * @param {componentHandler.ComponentConfigPublic} config
295
- */
296
- function registerInternal(config) {
297
- // In order to support both Closure-compiled and uncompiled code accessing
298
- // this method, we need to allow for both the dot and array syntax for
299
- // property access. You'll therefore see the `foo.bar || foo['bar']`
300
- // pattern repeated across this method.
301
- var widgetMissing = (typeof config.widget === 'undefined' &&
302
- typeof config['widget'] === 'undefined');
303
- var widget = true;
304
-
305
- if (!widgetMissing) {
306
- widget = config.widget || config['widget'];
307
- }
308
-
309
- var newConfig = /** @type {componentHandler.ComponentConfig} */ ({
310
- classConstructor: config.constructor || config['constructor'],
311
- className: config.classAsString || config['classAsString'],
312
- cssClass: config.cssClass || config['cssClass'],
313
- widget: widget,
314
- callbacks: []
315
- });
316
-
317
- registeredComponents_.forEach(function(item) {
318
- if (item.cssClass === newConfig.cssClass) {
319
- throw new Error('The provided cssClass has already been registered: ' + item.cssClass);
320
- }
321
- if (item.className === newConfig.className) {
322
- throw new Error('The provided className has already been registered');
323
- }
324
- });
325
-
326
- if (config.constructor.prototype
327
- .hasOwnProperty(componentConfigProperty_)) {
328
- throw new Error(
329
- 'MDL component classes must not have ' + componentConfigProperty_ +
330
- ' defined as a property.');
331
- }
332
-
333
- var found = findRegisteredClass_(config.classAsString, newConfig);
334
-
335
- if (!found) {
336
- registeredComponents_.push(newConfig);
337
- }
338
- }
339
-
340
- /**
341
- * Allows user to be alerted to any upgrades that are performed for a given
342
- * component type
343
- *
344
- * @param {string} jsClass The class name of the MDL component we wish
345
- * to hook into for any upgrades performed.
346
- * @param {function(!HTMLElement)} callback The function to call upon an
347
- * upgrade. This function should expect 1 parameter - the HTMLElement which
348
- * got upgraded.
349
- */
350
- function registerUpgradedCallbackInternal(jsClass, callback) {
351
- var regClass = findRegisteredClass_(jsClass);
352
- if (regClass) {
353
- regClass.callbacks.push(callback);
354
- }
355
- }
356
-
357
- /**
358
- * Upgrades all registered components found in the current DOM. This is
359
- * automatically called on window load.
360
- */
361
- function upgradeAllRegisteredInternal() {
362
- for (var n = 0; n < registeredComponents_.length; n++) {
363
- upgradeDomInternal(registeredComponents_[n].className);
364
- }
365
- }
366
-
367
- /**
368
- * Check the component for the downgrade method.
369
- * Execute if found.
370
- * Remove component from createdComponents list.
371
- *
372
- * @param {?componentHandler.Component} component
373
- */
374
- function deconstructComponentInternal(component) {
375
- if (component) {
376
- var componentIndex = createdComponents_.indexOf(component);
377
- createdComponents_.splice(componentIndex, 1);
378
-
379
- var upgrades = component.element_.getAttribute('data-upgraded').split(',');
380
- var componentPlace = upgrades.indexOf(component[componentConfigProperty_].classAsString);
381
- upgrades.splice(componentPlace, 1);
382
- component.element_.setAttribute('data-upgraded', upgrades.join(','));
383
-
384
- var ev = createEvent_('mdl-componentdowngraded', true, false);
385
- component.element_.dispatchEvent(ev);
386
- }
387
- }
388
-
389
- /**
390
- * Downgrade either a given node, an array of nodes, or a NodeList.
391
- *
392
- * @param {!Node|!Array<!Node>|!NodeList} nodes
393
- */
394
- function downgradeNodesInternal(nodes) {
395
- /**
396
- * Auxiliary function to downgrade a single node.
397
- * @param {!Node} node the node to be downgraded
398
- */
399
- var downgradeNode = function(node) {
400
- createdComponents_.filter(function(item) {
401
- return item.element_ === node;
402
- }).forEach(deconstructComponentInternal);
403
- };
404
- if (nodes instanceof Array || nodes instanceof NodeList) {
405
- for (var n = 0; n < nodes.length; n++) {
406
- downgradeNode(nodes[n]);
407
- }
408
- } else if (nodes instanceof Node) {
409
- downgradeNode(nodes);
410
- } else {
411
- throw new Error('Invalid argument provided to downgrade MDL nodes.');
412
- }
413
- }
414
-
415
- // Now return the functions that should be made public with their publicly
416
- // facing names...
417
- return {
418
- upgradeDom: upgradeDomInternal,
419
- upgradeElement: upgradeElementInternal,
420
- upgradeElements: upgradeElementsInternal,
421
- upgradeAllRegistered: upgradeAllRegisteredInternal,
422
- registerUpgradedCallback: registerUpgradedCallbackInternal,
423
- register: registerInternal,
424
- downgradeElements: downgradeNodesInternal
425
- };
426
- })();
427
-
428
- /**
429
- * Describes the type of a registered component type managed by
430
- * componentHandler. Provided for benefit of the Closure compiler.
431
- *
432
- * @typedef {{
433
- * constructor: Function,
434
- * classAsString: string,
435
- * cssClass: string,
436
- * widget: (string|boolean|undefined)
437
- * }}
438
- */
439
- componentHandler.ComponentConfigPublic; // jshint ignore:line
440
-
441
- /**
442
- * Describes the type of a registered component type managed by
443
- * componentHandler. Provided for benefit of the Closure compiler.
444
- *
445
- * @typedef {{
446
- * constructor: !Function,
447
- * className: string,
448
- * cssClass: string,
449
- * widget: (string|boolean),
450
- * callbacks: !Array<function(!HTMLElement)>
451
- * }}
452
- */
453
- componentHandler.ComponentConfig; // jshint ignore:line
454
-
455
- /**
456
- * Created component (i.e., upgraded element) type as managed by
457
- * componentHandler. Provided for benefit of the Closure compiler.
458
- *
459
- * @typedef {{
460
- * element_: !HTMLElement,
461
- * className: string,
462
- * classAsString: string,
463
- * cssClass: string,
464
- * widget: string
465
- * }}
466
- */
467
- componentHandler.Component; // jshint ignore:line
468
-
469
- // Export all symbols, for the benefit of Closure compiler.
470
- // No effect on uncompiled code.
471
- componentHandler['upgradeDom'] = componentHandler.upgradeDom;
472
- componentHandler['upgradeElement'] = componentHandler.upgradeElement;
473
- componentHandler['upgradeElements'] = componentHandler.upgradeElements;
474
- componentHandler['upgradeAllRegistered'] =
475
- componentHandler.upgradeAllRegistered;
476
- componentHandler['registerUpgradedCallback'] =
477
- componentHandler.registerUpgradedCallback;
478
- componentHandler['register'] = componentHandler.register;
479
- componentHandler['downgradeElements'] = componentHandler.downgradeElements;
480
- window.componentHandler = componentHandler;
481
- window['componentHandler'] = componentHandler;
482
-
483
- window.addEventListener('load', function() {
484
- 'use strict';
485
-
486
- /**
487
- * Performs a "Cutting the mustard" test. If the browser supports the features
488
- * tested, adds a mdl-js class to the <html> element. It then upgrades all MDL
489
- * components requiring JavaScript.
490
- */
491
- if ('classList' in document.createElement('div') &&
492
- 'querySelector' in document &&
493
- 'addEventListener' in window && Array.prototype.forEach) {
494
- document.documentElement.classList.add('mdl-js');
495
- componentHandler.upgradeAllRegistered();
496
- } else {
497
- /**
498
- * Dummy function to avoid JS errors.
499
- */
500
- componentHandler.upgradeElement = function() {};
501
- /**
502
- * Dummy function to avoid JS errors.
503
- */
504
- componentHandler.register = function() {};
505
- }
506
- });
507
-
508
- // Source: https://github.com/darius/requestAnimationFrame/blob/master/requestAnimationFrame.js
509
- // Adapted from https://gist.github.com/paulirish/1579671 which derived from
510
- // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
511
- // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
512
- // requestAnimationFrame polyfill by Erik Möller.
513
- // Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon
514
- // MIT license
515
- if (!Date.now) {
516
- /**
517
- * Date.now polyfill.
518
- * @return {number} the current Date
519
- */
520
- Date.now = function () {
521
- return new Date().getTime();
522
- };
523
- Date['now'] = Date.now;
524
- }
525
- var vendors = [
526
- 'webkit',
527
- 'moz'
528
- ];
529
- for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
530
- var vp = vendors[i];
531
- window.requestAnimationFrame = window[vp + 'RequestAnimationFrame'];
532
- window.cancelAnimationFrame = window[vp + 'CancelAnimationFrame'] || window[vp + 'CancelRequestAnimationFrame'];
533
- window['requestAnimationFrame'] = window.requestAnimationFrame;
534
- window['cancelAnimationFrame'] = window.cancelAnimationFrame;
535
- }
536
- if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
537
- var lastTime = 0;
538
- /**
539
- * requestAnimationFrame polyfill.
540
- * @param {!Function} callback the callback function.
541
- */
542
- window.requestAnimationFrame = function (callback) {
543
- var now = Date.now();
544
- var nextTime = Math.max(lastTime + 16, now);
545
- return setTimeout(function () {
546
- callback(lastTime = nextTime);
547
- }, nextTime - now);
548
- };
549
- window.cancelAnimationFrame = clearTimeout;
550
- window['requestAnimationFrame'] = window.requestAnimationFrame;
551
- window['cancelAnimationFrame'] = window.cancelAnimationFrame;
552
- }
553
- /**
554
- * @license
555
- * Copyright 2015 Google Inc. All Rights Reserved.
556
- *
557
- * Licensed under the Apache License, Version 2.0 (the "License");
558
- * you may not use this file except in compliance with the License.
559
- * You may obtain a copy of the License at
560
- *
561
- * http://www.apache.org/licenses/LICENSE-2.0
562
- *
563
- * Unless required by applicable law or agreed to in writing, software
564
- * distributed under the License is distributed on an "AS IS" BASIS,
565
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
566
- * See the License for the specific language governing permissions and
567
- * limitations under the License.
568
- */
569
- /**
570
- * Class constructor for Button MDL component.
571
- * Implements MDL component design pattern defined at:
572
- * https://github.com/jasonmayes/mdl-component-design-pattern
573
- *
574
- * @param {HTMLElement} element The element that will be upgraded.
575
- */
576
- var MaterialButton = function MaterialButton(element) {
577
- this.element_ = element;
578
- // Initialize instance.
579
- this.init();
580
- };
581
- window['MaterialButton'] = MaterialButton;
582
- /**
583
- * Store constants in one place so they can be updated easily.
584
- *
585
- * @enum {string | number}
586
- * @private
587
- */
588
- MaterialButton.prototype.Constant_ = {};
589
- /**
590
- * Store strings for class names defined by this component that are used in
591
- * JavaScript. This allows us to simply change it in one place should we
592
- * decide to modify at a later date.
593
- *
594
- * @enum {string}
595
- * @private
596
- */
597
- MaterialButton.prototype.CssClasses_ = {
598
- RIPPLE_EFFECT: 'mdl-js-ripple-effect',
599
- RIPPLE_CONTAINER: 'mdl-button__ripple-container',
600
- RIPPLE: 'mdl-ripple'
601
- };
602
- /**
603
- * Handle blur of element.
604
- *
605
- * @param {Event} event The event that fired.
606
- * @private
607
- */
608
- MaterialButton.prototype.blurHandler_ = function (event) {
609
- if (event) {
610
- this.element_.blur();
611
- }
612
- };
613
- // Public methods.
614
- /**
615
- * Disable button.
616
- *
617
- * @public
618
- */
619
- MaterialButton.prototype.disable = function () {
620
- this.element_.disabled = true;
621
- };
622
- MaterialButton.prototype['disable'] = MaterialButton.prototype.disable;
623
- /**
624
- * Enable button.
625
- *
626
- * @public
627
- */
628
- MaterialButton.prototype.enable = function () {
629
- this.element_.disabled = false;
630
- };
631
- MaterialButton.prototype['enable'] = MaterialButton.prototype.enable;
632
- /**
633
- * Initialize element.
634
- */
635
- MaterialButton.prototype.init = function () {
636
- if (this.element_) {
637
- if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
638
- var rippleContainer = document.createElement('span');
639
- rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
640
- this.rippleElement_ = document.createElement('span');
641
- this.rippleElement_.classList.add(this.CssClasses_.RIPPLE);
642
- rippleContainer.appendChild(this.rippleElement_);
643
- this.boundRippleBlurHandler = this.blurHandler_.bind(this);
644
- this.rippleElement_.addEventListener('mouseup', this.boundRippleBlurHandler);
645
- this.element_.appendChild(rippleContainer);
646
- }
647
- this.boundButtonBlurHandler = this.blurHandler_.bind(this);
648
- this.element_.addEventListener('mouseup', this.boundButtonBlurHandler);
649
- this.element_.addEventListener('mouseleave', this.boundButtonBlurHandler);
650
- }
651
- };
652
- // The component registers itself. It can assume componentHandler is available
653
- // in the global scope.
654
- componentHandler.register({
655
- constructor: MaterialButton,
656
- classAsString: 'MaterialButton',
657
- cssClass: 'mdl-js-button',
658
- widget: true
659
- });
660
- /**
661
- * @license
662
- * Copyright 2015 Google Inc. All Rights Reserved.
663
- *
664
- * Licensed under the Apache License, Version 2.0 (the "License");
665
- * you may not use this file except in compliance with the License.
666
- * You may obtain a copy of the License at
667
- *
668
- * http://www.apache.org/licenses/LICENSE-2.0
669
- *
670
- * Unless required by applicable law or agreed to in writing, software
671
- * distributed under the License is distributed on an "AS IS" BASIS,
672
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
673
- * See the License for the specific language governing permissions and
674
- * limitations under the License.
675
- */
676
- /**
677
- * Class constructor for Checkbox MDL component.
678
- * Implements MDL component design pattern defined at:
679
- * https://github.com/jasonmayes/mdl-component-design-pattern
680
- *
681
- * @constructor
682
- * @param {HTMLElement} element The element that will be upgraded.
683
- */
684
- var MaterialCheckbox = function MaterialCheckbox(element) {
685
- this.element_ = element;
686
- // Initialize instance.
687
- this.init();
688
- };
689
- window['MaterialCheckbox'] = MaterialCheckbox;
690
- /**
691
- * Store constants in one place so they can be updated easily.
692
- *
693
- * @enum {string | number}
694
- * @private
695
- */
696
- MaterialCheckbox.prototype.Constant_ = { TINY_TIMEOUT: 0.001 };
697
- /**
698
- * Store strings for class names defined by this component that are used in
699
- * JavaScript. This allows us to simply change it in one place should we
700
- * decide to modify at a later date.
701
- *
702
- * @enum {string}
703
- * @private
704
- */
705
- MaterialCheckbox.prototype.CssClasses_ = {
706
- INPUT: 'mdl-checkbox__input',
707
- BOX_OUTLINE: 'mdl-checkbox__box-outline',
708
- FOCUS_HELPER: 'mdl-checkbox__focus-helper',
709
- TICK_OUTLINE: 'mdl-checkbox__tick-outline',
710
- RIPPLE_EFFECT: 'mdl-js-ripple-effect',
711
- RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
712
- RIPPLE_CONTAINER: 'mdl-checkbox__ripple-container',
713
- RIPPLE_CENTER: 'mdl-ripple--center',
714
- RIPPLE: 'mdl-ripple',
715
- IS_FOCUSED: 'is-focused',
716
- IS_DISABLED: 'is-disabled',
717
- IS_CHECKED: 'is-checked',
718
- IS_UPGRADED: 'is-upgraded'
719
- };
720
- /**
721
- * Handle change of state.
722
- *
723
- * @param {Event} event The event that fired.
724
- * @private
725
- */
726
- MaterialCheckbox.prototype.onChange_ = function (event) {
727
- this.updateClasses_();
728
- };
729
- /**
730
- * Handle focus of element.
731
- *
732
- * @param {Event} event The event that fired.
733
- * @private
734
- */
735
- MaterialCheckbox.prototype.onFocus_ = function (event) {
736
- this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
737
- };
738
- /**
739
- * Handle lost focus of element.
740
- *
741
- * @param {Event} event The event that fired.
742
- * @private
743
- */
744
- MaterialCheckbox.prototype.onBlur_ = function (event) {
745
- this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
746
- };
747
- /**
748
- * Handle mouseup.
749
- *
750
- * @param {Event} event The event that fired.
751
- * @private
752
- */
753
- MaterialCheckbox.prototype.onMouseUp_ = function (event) {
754
- this.blur_();
755
- };
756
- /**
757
- * Handle class updates.
758
- *
759
- * @private
760
- */
761
- MaterialCheckbox.prototype.updateClasses_ = function () {
762
- this.checkDisabled();
763
- this.checkToggleState();
764
- };
765
- /**
766
- * Add blur.
767
- *
768
- * @private
769
- */
770
- MaterialCheckbox.prototype.blur_ = function () {
771
- // TODO: figure out why there's a focus event being fired after our blur,
772
- // so that we can avoid this hack.
773
- window.setTimeout(function () {
774
- this.inputElement_.blur();
775
- }.bind(this), this.Constant_.TINY_TIMEOUT);
776
- };
777
- // Public methods.
778
- /**
779
- * Check the inputs toggle state and update display.
780
- *
781
- * @public
782
- */
783
- MaterialCheckbox.prototype.checkToggleState = function () {
784
- if (this.inputElement_.checked) {
785
- this.element_.classList.add(this.CssClasses_.IS_CHECKED);
786
- } else {
787
- this.element_.classList.remove(this.CssClasses_.IS_CHECKED);
788
- }
789
- };
790
- MaterialCheckbox.prototype['checkToggleState'] = MaterialCheckbox.prototype.checkToggleState;
791
- /**
792
- * Check the inputs disabled state and update display.
793
- *
794
- * @public
795
- */
796
- MaterialCheckbox.prototype.checkDisabled = function () {
797
- if (this.inputElement_.disabled) {
798
- this.element_.classList.add(this.CssClasses_.IS_DISABLED);
799
- } else {
800
- this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
801
- }
802
- };
803
- MaterialCheckbox.prototype['checkDisabled'] = MaterialCheckbox.prototype.checkDisabled;
804
- /**
805
- * Disable checkbox.
806
- *
807
- * @public
808
- */
809
- MaterialCheckbox.prototype.disable = function () {
810
- this.inputElement_.disabled = true;
811
- this.updateClasses_();
812
- };
813
- MaterialCheckbox.prototype['disable'] = MaterialCheckbox.prototype.disable;
814
- /**
815
- * Enable checkbox.
816
- *
817
- * @public
818
- */
819
- MaterialCheckbox.prototype.enable = function () {
820
- this.inputElement_.disabled = false;
821
- this.updateClasses_();
822
- };
823
- MaterialCheckbox.prototype['enable'] = MaterialCheckbox.prototype.enable;
824
- /**
825
- * Check checkbox.
826
- *
827
- * @public
828
- */
829
- MaterialCheckbox.prototype.check = function () {
830
- this.inputElement_.checked = true;
831
- this.updateClasses_();
832
- };
833
- MaterialCheckbox.prototype['check'] = MaterialCheckbox.prototype.check;
834
- /**
835
- * Uncheck checkbox.
836
- *
837
- * @public
838
- */
839
- MaterialCheckbox.prototype.uncheck = function () {
840
- this.inputElement_.checked = false;
841
- this.updateClasses_();
842
- };
843
- MaterialCheckbox.prototype['uncheck'] = MaterialCheckbox.prototype.uncheck;
844
- /**
845
- * Initialize element.
846
- */
847
- MaterialCheckbox.prototype.init = function () {
848
- if (this.element_) {
849
- this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);
850
- var boxOutline = document.createElement('span');
851
- boxOutline.classList.add(this.CssClasses_.BOX_OUTLINE);
852
- var tickContainer = document.createElement('span');
853
- tickContainer.classList.add(this.CssClasses_.FOCUS_HELPER);
854
- var tickOutline = document.createElement('span');
855
- tickOutline.classList.add(this.CssClasses_.TICK_OUTLINE);
856
- boxOutline.appendChild(tickOutline);
857
- this.element_.appendChild(tickContainer);
858
- this.element_.appendChild(boxOutline);
859
- if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
860
- this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
861
- this.rippleContainerElement_ = document.createElement('span');
862
- this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
863
- this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT);
864
- this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
865
- this.boundRippleMouseUp = this.onMouseUp_.bind(this);
866
- this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);
867
- var ripple = document.createElement('span');
868
- ripple.classList.add(this.CssClasses_.RIPPLE);
869
- this.rippleContainerElement_.appendChild(ripple);
870
- this.element_.appendChild(this.rippleContainerElement_);
871
- }
872
- this.boundInputOnChange = this.onChange_.bind(this);
873
- this.boundInputOnFocus = this.onFocus_.bind(this);
874
- this.boundInputOnBlur = this.onBlur_.bind(this);
875
- this.boundElementMouseUp = this.onMouseUp_.bind(this);
876
- this.inputElement_.addEventListener('change', this.boundInputOnChange);
877
- this.inputElement_.addEventListener('focus', this.boundInputOnFocus);
878
- this.inputElement_.addEventListener('blur', this.boundInputOnBlur);
879
- this.element_.addEventListener('mouseup', this.boundElementMouseUp);
880
- this.updateClasses_();
881
- this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
882
- }
883
- };
884
- // The component registers itself. It can assume componentHandler is available
885
- // in the global scope.
886
- componentHandler.register({
887
- constructor: MaterialCheckbox,
888
- classAsString: 'MaterialCheckbox',
889
- cssClass: 'mdl-js-checkbox',
890
- widget: true
891
- });
892
- /**
893
- * @license
894
- * Copyright 2015 Google Inc. All Rights Reserved.
895
- *
896
- * Licensed under the Apache License, Version 2.0 (the "License");
897
- * you may not use this file except in compliance with the License.
898
- * You may obtain a copy of the License at
899
- *
900
- * http://www.apache.org/licenses/LICENSE-2.0
901
- *
902
- * Unless required by applicable law or agreed to in writing, software
903
- * distributed under the License is distributed on an "AS IS" BASIS,
904
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
905
- * See the License for the specific language governing permissions and
906
- * limitations under the License.
907
- */
908
- /**
909
- * Class constructor for icon toggle MDL component.
910
- * Implements MDL component design pattern defined at:
911
- * https://github.com/jasonmayes/mdl-component-design-pattern
912
- *
913
- * @constructor
914
- * @param {HTMLElement} element The element that will be upgraded.
915
- */
916
- var MaterialIconToggle = function MaterialIconToggle(element) {
917
- this.element_ = element;
918
- // Initialize instance.
919
- this.init();
920
- };
921
- window['MaterialIconToggle'] = MaterialIconToggle;
922
- /**
923
- * Store constants in one place so they can be updated easily.
924
- *
925
- * @enum {string | number}
926
- * @private
927
- */
928
- MaterialIconToggle.prototype.Constant_ = { TINY_TIMEOUT: 0.001 };
929
- /**
930
- * Store strings for class names defined by this component that are used in
931
- * JavaScript. This allows us to simply change it in one place should we
932
- * decide to modify at a later date.
933
- *
934
- * @enum {string}
935
- * @private
936
- */
937
- MaterialIconToggle.prototype.CssClasses_ = {
938
- INPUT: 'mdl-icon-toggle__input',
939
- JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',
940
- RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
941
- RIPPLE_CONTAINER: 'mdl-icon-toggle__ripple-container',
942
- RIPPLE_CENTER: 'mdl-ripple--center',
943
- RIPPLE: 'mdl-ripple',
944
- IS_FOCUSED: 'is-focused',
945
- IS_DISABLED: 'is-disabled',
946
- IS_CHECKED: 'is-checked'
947
- };
948
- /**
949
- * Handle change of state.
950
- *
951
- * @param {Event} event The event that fired.
952
- * @private
953
- */
954
- MaterialIconToggle.prototype.onChange_ = function (event) {
955
- this.updateClasses_();
956
- };
957
- /**
958
- * Handle focus of element.
959
- *
960
- * @param {Event} event The event that fired.
961
- * @private
962
- */
963
- MaterialIconToggle.prototype.onFocus_ = function (event) {
964
- this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
965
- };
966
- /**
967
- * Handle lost focus of element.
968
- *
969
- * @param {Event} event The event that fired.
970
- * @private
971
- */
972
- MaterialIconToggle.prototype.onBlur_ = function (event) {
973
- this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
974
- };
975
- /**
976
- * Handle mouseup.
977
- *
978
- * @param {Event} event The event that fired.
979
- * @private
980
- */
981
- MaterialIconToggle.prototype.onMouseUp_ = function (event) {
982
- this.blur_();
983
- };
984
- /**
985
- * Handle class updates.
986
- *
987
- * @private
988
- */
989
- MaterialIconToggle.prototype.updateClasses_ = function () {
990
- this.checkDisabled();
991
- this.checkToggleState();
992
- };
993
- /**
994
- * Add blur.
995
- *
996
- * @private
997
- */
998
- MaterialIconToggle.prototype.blur_ = function () {
999
- // TODO: figure out why there's a focus event being fired after our blur,
1000
- // so that we can avoid this hack.
1001
- window.setTimeout(function () {
1002
- this.inputElement_.blur();
1003
- }.bind(this), this.Constant_.TINY_TIMEOUT);
1004
- };
1005
- // Public methods.
1006
- /**
1007
- * Check the inputs toggle state and update display.
1008
- *
1009
- * @public
1010
- */
1011
- MaterialIconToggle.prototype.checkToggleState = function () {
1012
- if (this.inputElement_.checked) {
1013
- this.element_.classList.add(this.CssClasses_.IS_CHECKED);
1014
- } else {
1015
- this.element_.classList.remove(this.CssClasses_.IS_CHECKED);
1016
- }
1017
- };
1018
- MaterialIconToggle.prototype['checkToggleState'] = MaterialIconToggle.prototype.checkToggleState;
1019
- /**
1020
- * Check the inputs disabled state and update display.
1021
- *
1022
- * @public
1023
- */
1024
- MaterialIconToggle.prototype.checkDisabled = function () {
1025
- if (this.inputElement_.disabled) {
1026
- this.element_.classList.add(this.CssClasses_.IS_DISABLED);
1027
- } else {
1028
- this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
1029
- }
1030
- };
1031
- MaterialIconToggle.prototype['checkDisabled'] = MaterialIconToggle.prototype.checkDisabled;
1032
- /**
1033
- * Disable icon toggle.
1034
- *
1035
- * @public
1036
- */
1037
- MaterialIconToggle.prototype.disable = function () {
1038
- this.inputElement_.disabled = true;
1039
- this.updateClasses_();
1040
- };
1041
- MaterialIconToggle.prototype['disable'] = MaterialIconToggle.prototype.disable;
1042
- /**
1043
- * Enable icon toggle.
1044
- *
1045
- * @public
1046
- */
1047
- MaterialIconToggle.prototype.enable = function () {
1048
- this.inputElement_.disabled = false;
1049
- this.updateClasses_();
1050
- };
1051
- MaterialIconToggle.prototype['enable'] = MaterialIconToggle.prototype.enable;
1052
- /**
1053
- * Check icon toggle.
1054
- *
1055
- * @public
1056
- */
1057
- MaterialIconToggle.prototype.check = function () {
1058
- this.inputElement_.checked = true;
1059
- this.updateClasses_();
1060
- };
1061
- MaterialIconToggle.prototype['check'] = MaterialIconToggle.prototype.check;
1062
- /**
1063
- * Uncheck icon toggle.
1064
- *
1065
- * @public
1066
- */
1067
- MaterialIconToggle.prototype.uncheck = function () {
1068
- this.inputElement_.checked = false;
1069
- this.updateClasses_();
1070
- };
1071
- MaterialIconToggle.prototype['uncheck'] = MaterialIconToggle.prototype.uncheck;
1072
- /**
1073
- * Initialize element.
1074
- */
1075
- MaterialIconToggle.prototype.init = function () {
1076
- if (this.element_) {
1077
- this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);
1078
- if (this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {
1079
- this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
1080
- this.rippleContainerElement_ = document.createElement('span');
1081
- this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
1082
- this.rippleContainerElement_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT);
1083
- this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
1084
- this.boundRippleMouseUp = this.onMouseUp_.bind(this);
1085
- this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);
1086
- var ripple = document.createElement('span');
1087
- ripple.classList.add(this.CssClasses_.RIPPLE);
1088
- this.rippleContainerElement_.appendChild(ripple);
1089
- this.element_.appendChild(this.rippleContainerElement_);
1090
- }
1091
- this.boundInputOnChange = this.onChange_.bind(this);
1092
- this.boundInputOnFocus = this.onFocus_.bind(this);
1093
- this.boundInputOnBlur = this.onBlur_.bind(this);
1094
- this.boundElementOnMouseUp = this.onMouseUp_.bind(this);
1095
- this.inputElement_.addEventListener('change', this.boundInputOnChange);
1096
- this.inputElement_.addEventListener('focus', this.boundInputOnFocus);
1097
- this.inputElement_.addEventListener('blur', this.boundInputOnBlur);
1098
- this.element_.addEventListener('mouseup', this.boundElementOnMouseUp);
1099
- this.updateClasses_();
1100
- this.element_.classList.add('is-upgraded');
1101
- }
1102
- };
1103
- // The component registers itself. It can assume componentHandler is available
1104
- // in the global scope.
1105
- componentHandler.register({
1106
- constructor: MaterialIconToggle,
1107
- classAsString: 'MaterialIconToggle',
1108
- cssClass: 'mdl-js-icon-toggle',
1109
- widget: true
1110
- });
1111
- /**
1112
- * @license
1113
- * Copyright 2015 Google Inc. All Rights Reserved.
1114
- *
1115
- * Licensed under the Apache License, Version 2.0 (the "License");
1116
- * you may not use this file except in compliance with the License.
1117
- * You may obtain a copy of the License at
1118
- *
1119
- * http://www.apache.org/licenses/LICENSE-2.0
1120
- *
1121
- * Unless required by applicable law or agreed to in writing, software
1122
- * distributed under the License is distributed on an "AS IS" BASIS,
1123
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1124
- * See the License for the specific language governing permissions and
1125
- * limitations under the License.
1126
- */
1127
- /**
1128
- * Class constructor for dropdown MDL component.
1129
- * Implements MDL component design pattern defined at:
1130
- * https://github.com/jasonmayes/mdl-component-design-pattern
1131
- *
1132
- * @constructor
1133
- * @param {HTMLElement} element The element that will be upgraded.
1134
- */
1135
- var MaterialMenu = function MaterialMenu(element) {
1136
- this.element_ = element;
1137
- // Initialize instance.
1138
- this.init();
1139
- };
1140
- window['MaterialMenu'] = MaterialMenu;
1141
- /**
1142
- * Store constants in one place so they can be updated easily.
1143
- *
1144
- * @enum {string | number}
1145
- * @private
1146
- */
1147
- MaterialMenu.prototype.Constant_ = {
1148
- // Total duration of the menu animation.
1149
- TRANSITION_DURATION_SECONDS: 0.3,
1150
- // The fraction of the total duration we want to use for menu item animations.
1151
- TRANSITION_DURATION_FRACTION: 0.8,
1152
- // How long the menu stays open after choosing an option (so the user can see
1153
- // the ripple).
1154
- CLOSE_TIMEOUT: 150
1155
- };
1156
- /**
1157
- * Keycodes, for code readability.
1158
- *
1159
- * @enum {number}
1160
- * @private
1161
- */
1162
- MaterialMenu.prototype.Keycodes_ = {
1163
- ENTER: 13,
1164
- ESCAPE: 27,
1165
- SPACE: 32,
1166
- UP_ARROW: 38,
1167
- DOWN_ARROW: 40
1168
- };
1169
- /**
1170
- * Store strings for class names defined by this component that are used in
1171
- * JavaScript. This allows us to simply change it in one place should we
1172
- * decide to modify at a later date.
1173
- *
1174
- * @enum {string}
1175
- * @private
1176
- */
1177
- MaterialMenu.prototype.CssClasses_ = {
1178
- CONTAINER: 'mdl-menu__container',
1179
- OUTLINE: 'mdl-menu__outline',
1180
- ITEM: 'mdl-menu__item',
1181
- ITEM_RIPPLE_CONTAINER: 'mdl-menu__item-ripple-container',
1182
- RIPPLE_EFFECT: 'mdl-js-ripple-effect',
1183
- RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
1184
- RIPPLE: 'mdl-ripple',
1185
- // Statuses
1186
- IS_UPGRADED: 'is-upgraded',
1187
- IS_VISIBLE: 'is-visible',
1188
- IS_ANIMATING: 'is-animating',
1189
- // Alignment options
1190
- BOTTOM_LEFT: 'mdl-menu--bottom-left',
1191
- // This is the default.
1192
- BOTTOM_RIGHT: 'mdl-menu--bottom-right',
1193
- TOP_LEFT: 'mdl-menu--top-left',
1194
- TOP_RIGHT: 'mdl-menu--top-right',
1195
- UNALIGNED: 'mdl-menu--unaligned'
1196
- };
1197
- /**
1198
- * Initialize element.
1199
- */
1200
- MaterialMenu.prototype.init = function () {
1201
- if (this.element_) {
1202
- // Create container for the menu.
1203
- var container = document.createElement('div');
1204
- container.classList.add(this.CssClasses_.CONTAINER);
1205
- this.element_.parentElement.insertBefore(container, this.element_);
1206
- this.element_.parentElement.removeChild(this.element_);
1207
- container.appendChild(this.element_);
1208
- this.container_ = container;
1209
- // Create outline for the menu (shadow and background).
1210
- var outline = document.createElement('div');
1211
- outline.classList.add(this.CssClasses_.OUTLINE);
1212
- this.outline_ = outline;
1213
- container.insertBefore(outline, this.element_);
1214
- // Find the "for" element and bind events to it.
1215
- var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for');
1216
- var forEl = null;
1217
- if (forElId) {
1218
- forEl = document.getElementById(forElId);
1219
- if (forEl) {
1220
- this.forElement_ = forEl;
1221
- forEl.addEventListener('click', this.handleForClick_.bind(this));
1222
- forEl.addEventListener('keydown', this.handleForKeyboardEvent_.bind(this));
1223
- }
1224
- }
1225
- var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);
1226
- this.boundItemKeydown_ = this.handleItemKeyboardEvent_.bind(this);
1227
- this.boundItemClick_ = this.handleItemClick_.bind(this);
1228
- for (var i = 0; i < items.length; i++) {
1229
- // Add a listener to each menu item.
1230
- items[i].addEventListener('click', this.boundItemClick_);
1231
- // Add a tab index to each menu item.
1232
- items[i].tabIndex = '-1';
1233
- // Add a keyboard listener to each menu item.
1234
- items[i].addEventListener('keydown', this.boundItemKeydown_);
1235
- }
1236
- // Add ripple classes to each item, if the user has enabled ripples.
1237
- if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
1238
- this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
1239
- for (i = 0; i < items.length; i++) {
1240
- var item = items[i];
1241
- var rippleContainer = document.createElement('span');
1242
- rippleContainer.classList.add(this.CssClasses_.ITEM_RIPPLE_CONTAINER);
1243
- var ripple = document.createElement('span');
1244
- ripple.classList.add(this.CssClasses_.RIPPLE);
1245
- rippleContainer.appendChild(ripple);
1246
- item.appendChild(rippleContainer);
1247
- item.classList.add(this.CssClasses_.RIPPLE_EFFECT);
1248
- }
1249
- }
1250
- // Copy alignment classes to the container, so the outline can use them.
1251
- if (this.element_.classList.contains(this.CssClasses_.BOTTOM_LEFT)) {
1252
- this.outline_.classList.add(this.CssClasses_.BOTTOM_LEFT);
1253
- }
1254
- if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {
1255
- this.outline_.classList.add(this.CssClasses_.BOTTOM_RIGHT);
1256
- }
1257
- if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {
1258
- this.outline_.classList.add(this.CssClasses_.TOP_LEFT);
1259
- }
1260
- if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {
1261
- this.outline_.classList.add(this.CssClasses_.TOP_RIGHT);
1262
- }
1263
- if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {
1264
- this.outline_.classList.add(this.CssClasses_.UNALIGNED);
1265
- }
1266
- container.classList.add(this.CssClasses_.IS_UPGRADED);
1267
- }
1268
- };
1269
- /**
1270
- * Handles a click on the "for" element, by positioning the menu and then
1271
- * toggling it.
1272
- *
1273
- * @param {Event} evt The event that fired.
1274
- * @private
1275
- */
1276
- MaterialMenu.prototype.handleForClick_ = function (evt) {
1277
- if (this.element_ && this.forElement_) {
1278
- var rect = this.forElement_.getBoundingClientRect();
1279
- var forRect = this.forElement_.parentElement.getBoundingClientRect();
1280
- if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {
1281
- } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {
1282
- // Position below the "for" element, aligned to its right.
1283
- this.container_.style.right = forRect.right - rect.right + 'px';
1284
- this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px';
1285
- } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {
1286
- // Position above the "for" element, aligned to its left.
1287
- this.container_.style.left = this.forElement_.offsetLeft + 'px';
1288
- this.container_.style.bottom = forRect.bottom - rect.top + 'px';
1289
- } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {
1290
- // Position above the "for" element, aligned to its right.
1291
- this.container_.style.right = forRect.right - rect.right + 'px';
1292
- this.container_.style.bottom = forRect.bottom - rect.top + 'px';
1293
- } else {
1294
- // Default: position below the "for" element, aligned to its left.
1295
- this.container_.style.left = this.forElement_.offsetLeft + 'px';
1296
- this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px';
1297
- }
1298
- }
1299
- this.toggle(evt);
1300
- };
1301
- /**
1302
- * Handles a keyboard event on the "for" element.
1303
- *
1304
- * @param {Event} evt The event that fired.
1305
- * @private
1306
- */
1307
- MaterialMenu.prototype.handleForKeyboardEvent_ = function (evt) {
1308
- if (this.element_ && this.container_ && this.forElement_) {
1309
- var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])');
1310
- if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {
1311
- if (evt.keyCode === this.Keycodes_.UP_ARROW) {
1312
- evt.preventDefault();
1313
- items[items.length - 1].focus();
1314
- } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) {
1315
- evt.preventDefault();
1316
- items[0].focus();
1317
- }
1318
- }
1319
- }
1320
- };
1321
- /**
1322
- * Handles a keyboard event on an item.
1323
- *
1324
- * @param {Event} evt The event that fired.
1325
- * @private
1326
- */
1327
- MaterialMenu.prototype.handleItemKeyboardEvent_ = function (evt) {
1328
- if (this.element_ && this.container_) {
1329
- var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])');
1330
- if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {
1331
- var currentIndex = Array.prototype.slice.call(items).indexOf(evt.target);
1332
- if (evt.keyCode === this.Keycodes_.UP_ARROW) {
1333
- evt.preventDefault();
1334
- if (currentIndex > 0) {
1335
- items[currentIndex - 1].focus();
1336
- } else {
1337
- items[items.length - 1].focus();
1338
- }
1339
- } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) {
1340
- evt.preventDefault();
1341
- if (items.length > currentIndex + 1) {
1342
- items[currentIndex + 1].focus();
1343
- } else {
1344
- items[0].focus();
1345
- }
1346
- } else if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) {
1347
- evt.preventDefault();
1348
- // Send mousedown and mouseup to trigger ripple.
1349
- var e = new MouseEvent('mousedown');
1350
- evt.target.dispatchEvent(e);
1351
- e = new MouseEvent('mouseup');
1352
- evt.target.dispatchEvent(e);
1353
- // Send click.
1354
- evt.target.click();
1355
- } else if (evt.keyCode === this.Keycodes_.ESCAPE) {
1356
- evt.preventDefault();
1357
- this.hide();
1358
- }
1359
- }
1360
- }
1361
- };
1362
- /**
1363
- * Handles a click event on an item.
1364
- *
1365
- * @param {Event} evt The event that fired.
1366
- * @private
1367
- */
1368
- MaterialMenu.prototype.handleItemClick_ = function (evt) {
1369
- if (evt.target.hasAttribute('disabled')) {
1370
- evt.stopPropagation();
1371
- } else {
1372
- // Wait some time before closing menu, so the user can see the ripple.
1373
- this.closing_ = true;
1374
- window.setTimeout(function (evt) {
1375
- this.hide();
1376
- this.closing_ = false;
1377
- }.bind(this), this.Constant_.CLOSE_TIMEOUT);
1378
- }
1379
- };
1380
- /**
1381
- * Calculates the initial clip (for opening the menu) or final clip (for closing
1382
- * it), and applies it. This allows us to animate from or to the correct point,
1383
- * that is, the point it's aligned to in the "for" element.
1384
- *
1385
- * @param {number} height Height of the clip rectangle
1386
- * @param {number} width Width of the clip rectangle
1387
- * @private
1388
- */
1389
- MaterialMenu.prototype.applyClip_ = function (height, width) {
1390
- if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {
1391
- // Do not clip.
1392
- this.element_.style.clip = '';
1393
- } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {
1394
- // Clip to the top right corner of the menu.
1395
- this.element_.style.clip = 'rect(0 ' + width + 'px ' + '0 ' + width + 'px)';
1396
- } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {
1397
- // Clip to the bottom left corner of the menu.
1398
- this.element_.style.clip = 'rect(' + height + 'px 0 ' + height + 'px 0)';
1399
- } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {
1400
- // Clip to the bottom right corner of the menu.
1401
- this.element_.style.clip = 'rect(' + height + 'px ' + width + 'px ' + height + 'px ' + width + 'px)';
1402
- } else {
1403
- // Default: do not clip (same as clipping to the top left corner).
1404
- this.element_.style.clip = '';
1405
- }
1406
- };
1407
- /**
1408
- * Cleanup function to remove animation listeners.
1409
- *
1410
- * @param {Event} evt
1411
- * @private
1412
- */
1413
- MaterialMenu.prototype.removeAnimationEndListener_ = function (evt) {
1414
- evt.target.classList.remove(MaterialMenu.prototype.CssClasses_.IS_ANIMATING);
1415
- };
1416
- /**
1417
- * Adds an event listener to clean up after the animation ends.
1418
- *
1419
- * @private
1420
- */
1421
- MaterialMenu.prototype.addAnimationEndListener_ = function () {
1422
- this.element_.addEventListener('transitionend', this.removeAnimationEndListener_);
1423
- this.element_.addEventListener('webkitTransitionEnd', this.removeAnimationEndListener_);
1424
- };
1425
- /**
1426
- * Displays the menu.
1427
- *
1428
- * @public
1429
- */
1430
- MaterialMenu.prototype.show = function (evt) {
1431
- if (this.element_ && this.container_ && this.outline_) {
1432
- // Measure the inner element.
1433
- var height = this.element_.getBoundingClientRect().height;
1434
- var width = this.element_.getBoundingClientRect().width;
1435
- // Apply the inner element's size to the container and outline.
1436
- this.container_.style.width = width + 'px';
1437
- this.container_.style.height = height + 'px';
1438
- this.outline_.style.width = width + 'px';
1439
- this.outline_.style.height = height + 'px';
1440
- var transitionDuration = this.Constant_.TRANSITION_DURATION_SECONDS * this.Constant_.TRANSITION_DURATION_FRACTION;
1441
- // Calculate transition delays for individual menu items, so that they fade
1442
- // in one at a time.
1443
- var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);
1444
- for (var i = 0; i < items.length; i++) {
1445
- var itemDelay = null;
1446
- if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT) || this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {
1447
- itemDelay = (height - items[i].offsetTop - items[i].offsetHeight) / height * transitionDuration + 's';
1448
- } else {
1449
- itemDelay = items[i].offsetTop / height * transitionDuration + 's';
1450
- }
1451
- items[i].style.transitionDelay = itemDelay;
1452
- }
1453
- // Apply the initial clip to the text before we start animating.
1454
- this.applyClip_(height, width);
1455
- // Wait for the next frame, turn on animation, and apply the final clip.
1456
- // Also make it visible. This triggers the transitions.
1457
- window.requestAnimationFrame(function () {
1458
- this.element_.classList.add(this.CssClasses_.IS_ANIMATING);
1459
- this.element_.style.clip = 'rect(0 ' + width + 'px ' + height + 'px 0)';
1460
- this.container_.classList.add(this.CssClasses_.IS_VISIBLE);
1461
- }.bind(this));
1462
- // Clean up after the animation is complete.
1463
- this.addAnimationEndListener_();
1464
- // Add a click listener to the document, to close the menu.
1465
- var callback = function (e) {
1466
- // Check to see if the document is processing the same event that
1467
- // displayed the menu in the first place. If so, do nothing.
1468
- // Also check to see if the menu is in the process of closing itself, and
1469
- // do nothing in that case.
1470
- // Also check if the clicked element is a menu item
1471
- // if so, do nothing.
1472
- if (e !== evt && !this.closing_ && e.target.parentNode !== this.element_) {
1473
- document.removeEventListener('click', callback);
1474
- this.hide();
1475
- }
1476
- }.bind(this);
1477
- document.addEventListener('click', callback);
1478
- }
1479
- };
1480
- MaterialMenu.prototype['show'] = MaterialMenu.prototype.show;
1481
- /**
1482
- * Hides the menu.
1483
- *
1484
- * @public
1485
- */
1486
- MaterialMenu.prototype.hide = function () {
1487
- if (this.element_ && this.container_ && this.outline_) {
1488
- var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);
1489
- // Remove all transition delays; menu items fade out concurrently.
1490
- for (var i = 0; i < items.length; i++) {
1491
- items[i].style.removeProperty('transition-delay');
1492
- }
1493
- // Measure the inner element.
1494
- var rect = this.element_.getBoundingClientRect();
1495
- var height = rect.height;
1496
- var width = rect.width;
1497
- // Turn on animation, and apply the final clip. Also make invisible.
1498
- // This triggers the transitions.
1499
- this.element_.classList.add(this.CssClasses_.IS_ANIMATING);
1500
- this.applyClip_(height, width);
1501
- this.container_.classList.remove(this.CssClasses_.IS_VISIBLE);
1502
- // Clean up after the animation is complete.
1503
- this.addAnimationEndListener_();
1504
- }
1505
- };
1506
- MaterialMenu.prototype['hide'] = MaterialMenu.prototype.hide;
1507
- /**
1508
- * Displays or hides the menu, depending on current state.
1509
- *
1510
- * @public
1511
- */
1512
- MaterialMenu.prototype.toggle = function (evt) {
1513
- if (this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {
1514
- this.hide();
1515
- } else {
1516
- this.show(evt);
1517
- }
1518
- };
1519
- MaterialMenu.prototype['toggle'] = MaterialMenu.prototype.toggle;
1520
- // The component registers itself. It can assume componentHandler is available
1521
- // in the global scope.
1522
- componentHandler.register({
1523
- constructor: MaterialMenu,
1524
- classAsString: 'MaterialMenu',
1525
- cssClass: 'mdl-js-menu',
1526
- widget: true
1527
- });
1528
- /**
1529
- * @license
1530
- * Copyright 2015 Google Inc. All Rights Reserved.
1531
- *
1532
- * Licensed under the Apache License, Version 2.0 (the "License");
1533
- * you may not use this file except in compliance with the License.
1534
- * You may obtain a copy of the License at
1535
- *
1536
- * http://www.apache.org/licenses/LICENSE-2.0
1537
- *
1538
- * Unless required by applicable law or agreed to in writing, software
1539
- * distributed under the License is distributed on an "AS IS" BASIS,
1540
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1541
- * See the License for the specific language governing permissions and
1542
- * limitations under the License.
1543
- */
1544
- /**
1545
- * Class constructor for Progress MDL component.
1546
- * Implements MDL component design pattern defined at:
1547
- * https://github.com/jasonmayes/mdl-component-design-pattern
1548
- *
1549
- * @constructor
1550
- * @param {HTMLElement} element The element that will be upgraded.
1551
- */
1552
- var MaterialProgress = function MaterialProgress(element) {
1553
- this.element_ = element;
1554
- // Initialize instance.
1555
- this.init();
1556
- };
1557
- window['MaterialProgress'] = MaterialProgress;
1558
- /**
1559
- * Store constants in one place so they can be updated easily.
1560
- *
1561
- * @enum {string | number}
1562
- * @private
1563
- */
1564
- MaterialProgress.prototype.Constant_ = {};
1565
- /**
1566
- * Store strings for class names defined by this component that are used in
1567
- * JavaScript. This allows us to simply change it in one place should we
1568
- * decide to modify at a later date.
1569
- *
1570
- * @enum {string}
1571
- * @private
1572
- */
1573
- MaterialProgress.prototype.CssClasses_ = { INDETERMINATE_CLASS: 'mdl-progress__indeterminate' };
1574
- /**
1575
- * Set the current progress of the progressbar.
1576
- *
1577
- * @param {number} p Percentage of the progress (0-100)
1578
- * @public
1579
- */
1580
- MaterialProgress.prototype.setProgress = function (p) {
1581
- if (this.element_.classList.contains(this.CssClasses_.INDETERMINATE_CLASS)) {
1582
- return;
1583
- }
1584
- this.progressbar_.style.width = p + '%';
1585
- };
1586
- MaterialProgress.prototype['setProgress'] = MaterialProgress.prototype.setProgress;
1587
- /**
1588
- * Set the current progress of the buffer.
1589
- *
1590
- * @param {number} p Percentage of the buffer (0-100)
1591
- * @public
1592
- */
1593
- MaterialProgress.prototype.setBuffer = function (p) {
1594
- this.bufferbar_.style.width = p + '%';
1595
- this.auxbar_.style.width = 100 - p + '%';
1596
- };
1597
- MaterialProgress.prototype['setBuffer'] = MaterialProgress.prototype.setBuffer;
1598
- /**
1599
- * Initialize element.
1600
- */
1601
- MaterialProgress.prototype.init = function () {
1602
- if (this.element_) {
1603
- var el = document.createElement('div');
1604
- el.className = 'progressbar bar bar1';
1605
- this.element_.appendChild(el);
1606
- this.progressbar_ = el;
1607
- el = document.createElement('div');
1608
- el.className = 'bufferbar bar bar2';
1609
- this.element_.appendChild(el);
1610
- this.bufferbar_ = el;
1611
- el = document.createElement('div');
1612
- el.className = 'auxbar bar bar3';
1613
- this.element_.appendChild(el);
1614
- this.auxbar_ = el;
1615
- this.progressbar_.style.width = '0%';
1616
- this.bufferbar_.style.width = '100%';
1617
- this.auxbar_.style.width = '0%';
1618
- this.element_.classList.add('is-upgraded');
1619
- }
1620
- };
1621
- // The component registers itself. It can assume componentHandler is available
1622
- // in the global scope.
1623
- componentHandler.register({
1624
- constructor: MaterialProgress,
1625
- classAsString: 'MaterialProgress',
1626
- cssClass: 'mdl-js-progress',
1627
- widget: true
1628
- });
1629
- /**
1630
- * @license
1631
- * Copyright 2015 Google Inc. All Rights Reserved.
1632
- *
1633
- * Licensed under the Apache License, Version 2.0 (the "License");
1634
- * you may not use this file except in compliance with the License.
1635
- * You may obtain a copy of the License at
1636
- *
1637
- * http://www.apache.org/licenses/LICENSE-2.0
1638
- *
1639
- * Unless required by applicable law or agreed to in writing, software
1640
- * distributed under the License is distributed on an "AS IS" BASIS,
1641
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1642
- * See the License for the specific language governing permissions and
1643
- * limitations under the License.
1644
- */
1645
- /**
1646
- * Class constructor for Radio MDL component.
1647
- * Implements MDL component design pattern defined at:
1648
- * https://github.com/jasonmayes/mdl-component-design-pattern
1649
- *
1650
- * @constructor
1651
- * @param {HTMLElement} element The element that will be upgraded.
1652
- */
1653
- var MaterialRadio = function MaterialRadio(element) {
1654
- this.element_ = element;
1655
- // Initialize instance.
1656
- this.init();
1657
- };
1658
- window['MaterialRadio'] = MaterialRadio;
1659
- /**
1660
- * Store constants in one place so they can be updated easily.
1661
- *
1662
- * @enum {string | number}
1663
- * @private
1664
- */
1665
- MaterialRadio.prototype.Constant_ = { TINY_TIMEOUT: 0.001 };
1666
- /**
1667
- * Store strings for class names defined by this component that are used in
1668
- * JavaScript. This allows us to simply change it in one place should we
1669
- * decide to modify at a later date.
1670
- *
1671
- * @enum {string}
1672
- * @private
1673
- */
1674
- MaterialRadio.prototype.CssClasses_ = {
1675
- IS_FOCUSED: 'is-focused',
1676
- IS_DISABLED: 'is-disabled',
1677
- IS_CHECKED: 'is-checked',
1678
- IS_UPGRADED: 'is-upgraded',
1679
- JS_RADIO: 'mdl-js-radio',
1680
- RADIO_BTN: 'mdl-radio__button',
1681
- RADIO_OUTER_CIRCLE: 'mdl-radio__outer-circle',
1682
- RADIO_INNER_CIRCLE: 'mdl-radio__inner-circle',
1683
- RIPPLE_EFFECT: 'mdl-js-ripple-effect',
1684
- RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
1685
- RIPPLE_CONTAINER: 'mdl-radio__ripple-container',
1686
- RIPPLE_CENTER: 'mdl-ripple--center',
1687
- RIPPLE: 'mdl-ripple'
1688
- };
1689
- /**
1690
- * Handle change of state.
1691
- *
1692
- * @param {Event} event The event that fired.
1693
- * @private
1694
- */
1695
- MaterialRadio.prototype.onChange_ = function (event) {
1696
- // Since other radio buttons don't get change events, we need to look for
1697
- // them to update their classes.
1698
- var radios = document.getElementsByClassName(this.CssClasses_.JS_RADIO);
1699
- for (var i = 0; i < radios.length; i++) {
1700
- var button = radios[i].querySelector('.' + this.CssClasses_.RADIO_BTN);
1701
- // Different name == different group, so no point updating those.
1702
- if (button.getAttribute('name') === this.btnElement_.getAttribute('name')) {
1703
- if (typeof radios[i]['MaterialRadio'] !== 'undefined') {
1704
- radios[i]['MaterialRadio'].updateClasses_();
1705
- }
1706
- }
1707
- }
1708
- };
1709
- /**
1710
- * Handle focus.
1711
- *
1712
- * @param {Event} event The event that fired.
1713
- * @private
1714
- */
1715
- MaterialRadio.prototype.onFocus_ = function (event) {
1716
- this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
1717
- };
1718
- /**
1719
- * Handle lost focus.
1720
- *
1721
- * @param {Event} event The event that fired.
1722
- * @private
1723
- */
1724
- MaterialRadio.prototype.onBlur_ = function (event) {
1725
- this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
1726
- };
1727
- /**
1728
- * Handle mouseup.
1729
- *
1730
- * @param {Event} event The event that fired.
1731
- * @private
1732
- */
1733
- MaterialRadio.prototype.onMouseup_ = function (event) {
1734
- this.blur_();
1735
- };
1736
- /**
1737
- * Update classes.
1738
- *
1739
- * @private
1740
- */
1741
- MaterialRadio.prototype.updateClasses_ = function () {
1742
- this.checkDisabled();
1743
- this.checkToggleState();
1744
- };
1745
- /**
1746
- * Add blur.
1747
- *
1748
- * @private
1749
- */
1750
- MaterialRadio.prototype.blur_ = function () {
1751
- // TODO: figure out why there's a focus event being fired after our blur,
1752
- // so that we can avoid this hack.
1753
- window.setTimeout(function () {
1754
- this.btnElement_.blur();
1755
- }.bind(this), this.Constant_.TINY_TIMEOUT);
1756
- };
1757
- // Public methods.
1758
- /**
1759
- * Check the components disabled state.
1760
- *
1761
- * @public
1762
- */
1763
- MaterialRadio.prototype.checkDisabled = function () {
1764
- if (this.btnElement_.disabled) {
1765
- this.element_.classList.add(this.CssClasses_.IS_DISABLED);
1766
- } else {
1767
- this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
1768
- }
1769
- };
1770
- MaterialRadio.prototype['checkDisabled'] = MaterialRadio.prototype.checkDisabled;
1771
- /**
1772
- * Check the components toggled state.
1773
- *
1774
- * @public
1775
- */
1776
- MaterialRadio.prototype.checkToggleState = function () {
1777
- if (this.btnElement_.checked) {
1778
- this.element_.classList.add(this.CssClasses_.IS_CHECKED);
1779
- } else {
1780
- this.element_.classList.remove(this.CssClasses_.IS_CHECKED);
1781
- }
1782
- };
1783
- MaterialRadio.prototype['checkToggleState'] = MaterialRadio.prototype.checkToggleState;
1784
- /**
1785
- * Disable radio.
1786
- *
1787
- * @public
1788
- */
1789
- MaterialRadio.prototype.disable = function () {
1790
- this.btnElement_.disabled = true;
1791
- this.updateClasses_();
1792
- };
1793
- MaterialRadio.prototype['disable'] = MaterialRadio.prototype.disable;
1794
- /**
1795
- * Enable radio.
1796
- *
1797
- * @public
1798
- */
1799
- MaterialRadio.prototype.enable = function () {
1800
- this.btnElement_.disabled = false;
1801
- this.updateClasses_();
1802
- };
1803
- MaterialRadio.prototype['enable'] = MaterialRadio.prototype.enable;
1804
- /**
1805
- * Check radio.
1806
- *
1807
- * @public
1808
- */
1809
- MaterialRadio.prototype.check = function () {
1810
- this.btnElement_.checked = true;
1811
- this.onChange_(null);
1812
- };
1813
- MaterialRadio.prototype['check'] = MaterialRadio.prototype.check;
1814
- /**
1815
- * Uncheck radio.
1816
- *
1817
- * @public
1818
- */
1819
- MaterialRadio.prototype.uncheck = function () {
1820
- this.btnElement_.checked = false;
1821
- this.onChange_(null);
1822
- };
1823
- MaterialRadio.prototype['uncheck'] = MaterialRadio.prototype.uncheck;
1824
- /**
1825
- * Initialize element.
1826
- */
1827
- MaterialRadio.prototype.init = function () {
1828
- if (this.element_) {
1829
- this.btnElement_ = this.element_.querySelector('.' + this.CssClasses_.RADIO_BTN);
1830
- this.boundChangeHandler_ = this.onChange_.bind(this);
1831
- this.boundFocusHandler_ = this.onChange_.bind(this);
1832
- this.boundBlurHandler_ = this.onBlur_.bind(this);
1833
- this.boundMouseUpHandler_ = this.onMouseup_.bind(this);
1834
- var outerCircle = document.createElement('span');
1835
- outerCircle.classList.add(this.CssClasses_.RADIO_OUTER_CIRCLE);
1836
- var innerCircle = document.createElement('span');
1837
- innerCircle.classList.add(this.CssClasses_.RADIO_INNER_CIRCLE);
1838
- this.element_.appendChild(outerCircle);
1839
- this.element_.appendChild(innerCircle);
1840
- var rippleContainer;
1841
- if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
1842
- this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
1843
- rippleContainer = document.createElement('span');
1844
- rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
1845
- rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT);
1846
- rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER);
1847
- rippleContainer.addEventListener('mouseup', this.boundMouseUpHandler_);
1848
- var ripple = document.createElement('span');
1849
- ripple.classList.add(this.CssClasses_.RIPPLE);
1850
- rippleContainer.appendChild(ripple);
1851
- this.element_.appendChild(rippleContainer);
1852
- }
1853
- this.btnElement_.addEventListener('change', this.boundChangeHandler_);
1854
- this.btnElement_.addEventListener('focus', this.boundFocusHandler_);
1855
- this.btnElement_.addEventListener('blur', this.boundBlurHandler_);
1856
- this.element_.addEventListener('mouseup', this.boundMouseUpHandler_);
1857
- this.updateClasses_();
1858
- this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
1859
- }
1860
- };
1861
- // The component registers itself. It can assume componentHandler is available
1862
- // in the global scope.
1863
- componentHandler.register({
1864
- constructor: MaterialRadio,
1865
- classAsString: 'MaterialRadio',
1866
- cssClass: 'mdl-js-radio',
1867
- widget: true
1868
- });
1869
- /**
1870
- * @license
1871
- * Copyright 2015 Google Inc. All Rights Reserved.
1872
- *
1873
- * Licensed under the Apache License, Version 2.0 (the "License");
1874
- * you may not use this file except in compliance with the License.
1875
- * You may obtain a copy of the License at
1876
- *
1877
- * http://www.apache.org/licenses/LICENSE-2.0
1878
- *
1879
- * Unless required by applicable law or agreed to in writing, software
1880
- * distributed under the License is distributed on an "AS IS" BASIS,
1881
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1882
- * See the License for the specific language governing permissions and
1883
- * limitations under the License.
1884
- */
1885
- /**
1886
- * Class constructor for Slider MDL component.
1887
- * Implements MDL component design pattern defined at:
1888
- * https://github.com/jasonmayes/mdl-component-design-pattern
1889
- *
1890
- * @constructor
1891
- * @param {HTMLElement} element The element that will be upgraded.
1892
- */
1893
- var MaterialSlider = function MaterialSlider(element) {
1894
- this.element_ = element;
1895
- // Browser feature detection.
1896
- this.isIE_ = window.navigator.msPointerEnabled;
1897
- // Initialize instance.
1898
- this.init();
1899
- };
1900
- window['MaterialSlider'] = MaterialSlider;
1901
- /**
1902
- * Store constants in one place so they can be updated easily.
1903
- *
1904
- * @enum {string | number}
1905
- * @private
1906
- */
1907
- MaterialSlider.prototype.Constant_ = {};
1908
- /**
1909
- * Store strings for class names defined by this component that are used in
1910
- * JavaScript. This allows us to simply change it in one place should we
1911
- * decide to modify at a later date.
1912
- *
1913
- * @enum {string}
1914
- * @private
1915
- */
1916
- MaterialSlider.prototype.CssClasses_ = {
1917
- IE_CONTAINER: 'mdl-slider__ie-container',
1918
- SLIDER_CONTAINER: 'mdl-slider__container',
1919
- BACKGROUND_FLEX: 'mdl-slider__background-flex',
1920
- BACKGROUND_LOWER: 'mdl-slider__background-lower',
1921
- BACKGROUND_UPPER: 'mdl-slider__background-upper',
1922
- IS_LOWEST_VALUE: 'is-lowest-value',
1923
- IS_UPGRADED: 'is-upgraded'
1924
- };
1925
- /**
1926
- * Handle input on element.
1927
- *
1928
- * @param {Event} event The event that fired.
1929
- * @private
1930
- */
1931
- MaterialSlider.prototype.onInput_ = function (event) {
1932
- this.updateValueStyles_();
1933
- };
1934
- /**
1935
- * Handle change on element.
1936
- *
1937
- * @param {Event} event The event that fired.
1938
- * @private
1939
- */
1940
- MaterialSlider.prototype.onChange_ = function (event) {
1941
- this.updateValueStyles_();
1942
- };
1943
- /**
1944
- * Handle mouseup on element.
1945
- *
1946
- * @param {Event} event The event that fired.
1947
- * @private
1948
- */
1949
- MaterialSlider.prototype.onMouseUp_ = function (event) {
1950
- event.target.blur();
1951
- };
1952
- /**
1953
- * Handle mousedown on container element.
1954
- * This handler is purpose is to not require the use to click
1955
- * exactly on the 2px slider element, as FireFox seems to be very
1956
- * strict about this.
1957
- *
1958
- * @param {Event} event The event that fired.
1959
- * @private
1960
- * @suppress {missingProperties}
1961
- */
1962
- MaterialSlider.prototype.onContainerMouseDown_ = function (event) {
1963
- // If this click is not on the parent element (but rather some child)
1964
- // ignore. It may still bubble up.
1965
- if (event.target !== this.element_.parentElement) {
1966
- return;
1967
- }
1968
- // Discard the original event and create a new event that
1969
- // is on the slider element.
1970
- event.preventDefault();
1971
- var newEvent = new MouseEvent('mousedown', {
1972
- target: event.target,
1973
- buttons: event.buttons,
1974
- clientX: event.clientX,
1975
- clientY: this.element_.getBoundingClientRect().y
1976
- });
1977
- this.element_.dispatchEvent(newEvent);
1978
- };
1979
- /**
1980
- * Handle updating of values.
1981
- *
1982
- * @private
1983
- */
1984
- MaterialSlider.prototype.updateValueStyles_ = function () {
1985
- // Calculate and apply percentages to div structure behind slider.
1986
- var fraction = (this.element_.value - this.element_.min) / (this.element_.max - this.element_.min);
1987
- if (fraction === 0) {
1988
- this.element_.classList.add(this.CssClasses_.IS_LOWEST_VALUE);
1989
- } else {
1990
- this.element_.classList.remove(this.CssClasses_.IS_LOWEST_VALUE);
1991
- }
1992
- if (!this.isIE_) {
1993
- this.backgroundLower_.style.flex = fraction;
1994
- this.backgroundLower_.style.webkitFlex = fraction;
1995
- this.backgroundUpper_.style.flex = 1 - fraction;
1996
- this.backgroundUpper_.style.webkitFlex = 1 - fraction;
1997
- }
1998
- };
1999
- // Public methods.
2000
- /**
2001
- * Disable slider.
2002
- *
2003
- * @public
2004
- */
2005
- MaterialSlider.prototype.disable = function () {
2006
- this.element_.disabled = true;
2007
- };
2008
- MaterialSlider.prototype['disable'] = MaterialSlider.prototype.disable;
2009
- /**
2010
- * Enable slider.
2011
- *
2012
- * @public
2013
- */
2014
- MaterialSlider.prototype.enable = function () {
2015
- this.element_.disabled = false;
2016
- };
2017
- MaterialSlider.prototype['enable'] = MaterialSlider.prototype.enable;
2018
- /**
2019
- * Update slider value.
2020
- *
2021
- * @param {number} value The value to which to set the control (optional).
2022
- * @public
2023
- */
2024
- MaterialSlider.prototype.change = function (value) {
2025
- if (typeof value !== 'undefined') {
2026
- this.element_.value = value;
2027
- }
2028
- this.updateValueStyles_();
2029
- };
2030
- MaterialSlider.prototype['change'] = MaterialSlider.prototype.change;
2031
- /**
2032
- * Initialize element.
2033
- */
2034
- MaterialSlider.prototype.init = function () {
2035
- if (this.element_) {
2036
- if (this.isIE_) {
2037
- // Since we need to specify a very large height in IE due to
2038
- // implementation limitations, we add a parent here that trims it down to
2039
- // a reasonable size.
2040
- var containerIE = document.createElement('div');
2041
- containerIE.classList.add(this.CssClasses_.IE_CONTAINER);
2042
- this.element_.parentElement.insertBefore(containerIE, this.element_);
2043
- this.element_.parentElement.removeChild(this.element_);
2044
- containerIE.appendChild(this.element_);
2045
- } else {
2046
- // For non-IE browsers, we need a div structure that sits behind the
2047
- // slider and allows us to style the left and right sides of it with
2048
- // different colors.
2049
- var container = document.createElement('div');
2050
- container.classList.add(this.CssClasses_.SLIDER_CONTAINER);
2051
- this.element_.parentElement.insertBefore(container, this.element_);
2052
- this.element_.parentElement.removeChild(this.element_);
2053
- container.appendChild(this.element_);
2054
- var backgroundFlex = document.createElement('div');
2055
- backgroundFlex.classList.add(this.CssClasses_.BACKGROUND_FLEX);
2056
- container.appendChild(backgroundFlex);
2057
- this.backgroundLower_ = document.createElement('div');
2058
- this.backgroundLower_.classList.add(this.CssClasses_.BACKGROUND_LOWER);
2059
- backgroundFlex.appendChild(this.backgroundLower_);
2060
- this.backgroundUpper_ = document.createElement('div');
2061
- this.backgroundUpper_.classList.add(this.CssClasses_.BACKGROUND_UPPER);
2062
- backgroundFlex.appendChild(this.backgroundUpper_);
2063
- }
2064
- this.boundInputHandler = this.onInput_.bind(this);
2065
- this.boundChangeHandler = this.onChange_.bind(this);
2066
- this.boundMouseUpHandler = this.onMouseUp_.bind(this);
2067
- this.boundContainerMouseDownHandler = this.onContainerMouseDown_.bind(this);
2068
- this.element_.addEventListener('input', this.boundInputHandler);
2069
- this.element_.addEventListener('change', this.boundChangeHandler);
2070
- this.element_.addEventListener('mouseup', this.boundMouseUpHandler);
2071
- this.element_.parentElement.addEventListener('mousedown', this.boundContainerMouseDownHandler);
2072
- this.updateValueStyles_();
2073
- this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
2074
- }
2075
- };
2076
- // The component registers itself. It can assume componentHandler is available
2077
- // in the global scope.
2078
- componentHandler.register({
2079
- constructor: MaterialSlider,
2080
- classAsString: 'MaterialSlider',
2081
- cssClass: 'mdl-js-slider',
2082
- widget: true
2083
- });
2084
- /**
2085
- * Copyright 2015 Google Inc. All Rights Reserved.
2086
- *
2087
- * Licensed under the Apache License, Version 2.0 (the "License");
2088
- * you may not use this file except in compliance with the License.
2089
- * You may obtain a copy of the License at
2090
- *
2091
- * http://www.apache.org/licenses/LICENSE-2.0
2092
- *
2093
- * Unless required by applicable law or agreed to in writing, software
2094
- * distributed under the License is distributed on an "AS IS" BASIS,
2095
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2096
- * See the License for the specific language governing permissions and
2097
- * limitations under the License.
2098
- */
2099
- /**
2100
- * Class constructor for Snackbar MDL component.
2101
- * Implements MDL component design pattern defined at:
2102
- * https://github.com/jasonmayes/mdl-component-design-pattern
2103
- *
2104
- * @constructor
2105
- * @param {HTMLElement} element The element that will be upgraded.
2106
- */
2107
- var MaterialSnackbar = function MaterialSnackbar(element) {
2108
- this.element_ = element;
2109
- this.textElement_ = this.element_.querySelector('.' + this.cssClasses_.MESSAGE);
2110
- this.actionElement_ = this.element_.querySelector('.' + this.cssClasses_.ACTION);
2111
- if (!this.textElement_) {
2112
- throw new Error('There must be a message element for a snackbar.');
2113
- }
2114
- if (!this.actionElement_) {
2115
- throw new Error('There must be an action element for a snackbar.');
2116
- }
2117
- this.active = false;
2118
- this.actionHandler_ = undefined;
2119
- this.message_ = undefined;
2120
- this.actionText_ = undefined;
2121
- this.queuedNotifications_ = [];
2122
- this.setActionHidden_(true);
2123
- };
2124
- window['MaterialSnackbar'] = MaterialSnackbar;
2125
- /**
2126
- * Store constants in one place so they can be updated easily.
2127
- *
2128
- * @enum {string | number}
2129
- * @private
2130
- */
2131
- MaterialSnackbar.prototype.Constant_ = {
2132
- // The duration of the snackbar show/hide animation, in ms.
2133
- ANIMATION_LENGTH: 250
2134
- };
2135
- /**
2136
- * Store strings for class names defined by this component that are used in
2137
- * JavaScript. This allows us to simply change it in one place should we
2138
- * decide to modify at a later date.
2139
- *
2140
- * @enum {string}
2141
- * @private
2142
- */
2143
- MaterialSnackbar.prototype.cssClasses_ = {
2144
- SNACKBAR: 'mdl-snackbar',
2145
- MESSAGE: 'mdl-snackbar__text',
2146
- ACTION: 'mdl-snackbar__action',
2147
- ACTIVE: 'mdl-snackbar--active'
2148
- };
2149
- /**
2150
- * Display the snackbar.
2151
- *
2152
- * @private
2153
- */
2154
- MaterialSnackbar.prototype.displaySnackbar_ = function () {
2155
- this.element_.setAttribute('aria-hidden', 'true');
2156
- if (this.actionHandler_) {
2157
- this.actionElement_.textContent = this.actionText_;
2158
- this.actionElement_.addEventListener('click', this.actionHandler_);
2159
- this.setActionHidden_(false);
2160
- }
2161
- this.textElement_.textContent = this.message_;
2162
- this.element_.classList.add(this.cssClasses_.ACTIVE);
2163
- this.element_.setAttribute('aria-hidden', 'false');
2164
- setTimeout(this.cleanup_.bind(this), this.timeout_);
2165
- };
2166
- /**
2167
- * Show the snackbar.
2168
- *
2169
- * @param {Object} data The data for the notification.
2170
- * @public
2171
- */
2172
- MaterialSnackbar.prototype.showSnackbar = function (data) {
2173
- if (data === undefined) {
2174
- throw new Error('Please provide a data object with at least a message to display.');
2175
- }
2176
- if (data['message'] === undefined) {
2177
- throw new Error('Please provide a message to be displayed.');
2178
- }
2179
- if (data['actionHandler'] && !data['actionText']) {
2180
- throw new Error('Please provide action text with the handler.');
2181
- }
2182
- if (this.active) {
2183
- this.queuedNotifications_.push(data);
2184
- } else {
2185
- this.active = true;
2186
- this.message_ = data['message'];
2187
- if (data['timeout']) {
2188
- this.timeout_ = data['timeout'];
2189
- } else {
2190
- this.timeout_ = 2750;
2191
- }
2192
- if (data['actionHandler']) {
2193
- this.actionHandler_ = data['actionHandler'];
2194
- }
2195
- if (data['actionText']) {
2196
- this.actionText_ = data['actionText'];
2197
- }
2198
- this.displaySnackbar_();
2199
- }
2200
- };
2201
- MaterialSnackbar.prototype['showSnackbar'] = MaterialSnackbar.prototype.showSnackbar;
2202
- /**
2203
- * Check if the queue has items within it.
2204
- * If it does, display the next entry.
2205
- *
2206
- * @private
2207
- */
2208
- MaterialSnackbar.prototype.checkQueue_ = function () {
2209
- if (this.queuedNotifications_.length > 0) {
2210
- this.showSnackbar(this.queuedNotifications_.shift());
2211
- }
2212
- };
2213
- /**
2214
- * Cleanup the snackbar event listeners and accessiblity attributes.
2215
- *
2216
- * @private
2217
- */
2218
- MaterialSnackbar.prototype.cleanup_ = function () {
2219
- this.element_.classList.remove(this.cssClasses_.ACTIVE);
2220
- setTimeout(function () {
2221
- this.element_.setAttribute('aria-hidden', 'true');
2222
- this.textElement_.textContent = '';
2223
- if (!Boolean(this.actionElement_.getAttribute('aria-hidden'))) {
2224
- this.setActionHidden_(true);
2225
- this.actionElement_.textContent = '';
2226
- this.actionElement_.removeEventListener('click', this.actionHandler_);
2227
- }
2228
- this.actionHandler_ = undefined;
2229
- this.message_ = undefined;
2230
- this.actionText_ = undefined;
2231
- this.active = false;
2232
- this.checkQueue_();
2233
- }.bind(this), this.Constant_.ANIMATION_LENGTH);
2234
- };
2235
- /**
2236
- * Set the action handler hidden state.
2237
- *
2238
- * @param {boolean} value
2239
- * @private
2240
- */
2241
- MaterialSnackbar.prototype.setActionHidden_ = function (value) {
2242
- if (value) {
2243
- this.actionElement_.setAttribute('aria-hidden', 'true');
2244
- } else {
2245
- this.actionElement_.removeAttribute('aria-hidden');
2246
- }
2247
- };
2248
- // The component registers itself. It can assume componentHandler is available
2249
- // in the global scope.
2250
- componentHandler.register({
2251
- constructor: MaterialSnackbar,
2252
- classAsString: 'MaterialSnackbar',
2253
- cssClass: 'mdl-js-snackbar',
2254
- widget: true
2255
- });
2256
- /**
2257
- * @license
2258
- * Copyright 2015 Google Inc. All Rights Reserved.
2259
- *
2260
- * Licensed under the Apache License, Version 2.0 (the "License");
2261
- * you may not use this file except in compliance with the License.
2262
- * You may obtain a copy of the License at
2263
- *
2264
- * http://www.apache.org/licenses/LICENSE-2.0
2265
- *
2266
- * Unless required by applicable law or agreed to in writing, software
2267
- * distributed under the License is distributed on an "AS IS" BASIS,
2268
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2269
- * See the License for the specific language governing permissions and
2270
- * limitations under the License.
2271
- */
2272
- /**
2273
- * Class constructor for Spinner MDL component.
2274
- * Implements MDL component design pattern defined at:
2275
- * https://github.com/jasonmayes/mdl-component-design-pattern
2276
- *
2277
- * @param {HTMLElement} element The element that will be upgraded.
2278
- * @constructor
2279
- */
2280
- var MaterialSpinner = function MaterialSpinner(element) {
2281
- this.element_ = element;
2282
- // Initialize instance.
2283
- this.init();
2284
- };
2285
- window['MaterialSpinner'] = MaterialSpinner;
2286
- /**
2287
- * Store constants in one place so they can be updated easily.
2288
- *
2289
- * @enum {string | number}
2290
- * @private
2291
- */
2292
- MaterialSpinner.prototype.Constant_ = { MDL_SPINNER_LAYER_COUNT: 4 };
2293
- /**
2294
- * Store strings for class names defined by this component that are used in
2295
- * JavaScript. This allows us to simply change it in one place should we
2296
- * decide to modify at a later date.
2297
- *
2298
- * @enum {string}
2299
- * @private
2300
- */
2301
- MaterialSpinner.prototype.CssClasses_ = {
2302
- MDL_SPINNER_LAYER: 'mdl-spinner__layer',
2303
- MDL_SPINNER_CIRCLE_CLIPPER: 'mdl-spinner__circle-clipper',
2304
- MDL_SPINNER_CIRCLE: 'mdl-spinner__circle',
2305
- MDL_SPINNER_GAP_PATCH: 'mdl-spinner__gap-patch',
2306
- MDL_SPINNER_LEFT: 'mdl-spinner__left',
2307
- MDL_SPINNER_RIGHT: 'mdl-spinner__right'
2308
- };
2309
- /**
2310
- * Auxiliary method to create a spinner layer.
2311
- *
2312
- * @param {number} index Index of the layer to be created.
2313
- * @public
2314
- */
2315
- MaterialSpinner.prototype.createLayer = function (index) {
2316
- var layer = document.createElement('div');
2317
- layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER);
2318
- layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER + '-' + index);
2319
- var leftClipper = document.createElement('div');
2320
- leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER);
2321
- leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_LEFT);
2322
- var gapPatch = document.createElement('div');
2323
- gapPatch.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH);
2324
- var rightClipper = document.createElement('div');
2325
- rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER);
2326
- rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT);
2327
- var circleOwners = [
2328
- leftClipper,
2329
- gapPatch,
2330
- rightClipper
2331
- ];
2332
- for (var i = 0; i < circleOwners.length; i++) {
2333
- var circle = document.createElement('div');
2334
- circle.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE);
2335
- circleOwners[i].appendChild(circle);
2336
- }
2337
- layer.appendChild(leftClipper);
2338
- layer.appendChild(gapPatch);
2339
- layer.appendChild(rightClipper);
2340
- this.element_.appendChild(layer);
2341
- };
2342
- MaterialSpinner.prototype['createLayer'] = MaterialSpinner.prototype.createLayer;
2343
- /**
2344
- * Stops the spinner animation.
2345
- * Public method for users who need to stop the spinner for any reason.
2346
- *
2347
- * @public
2348
- */
2349
- MaterialSpinner.prototype.stop = function () {
2350
- this.element_.classList.remove('is-active');
2351
- };
2352
- MaterialSpinner.prototype['stop'] = MaterialSpinner.prototype.stop;
2353
- /**
2354
- * Starts the spinner animation.
2355
- * Public method for users who need to manually start the spinner for any reason
2356
- * (instead of just adding the 'is-active' class to their markup).
2357
- *
2358
- * @public
2359
- */
2360
- MaterialSpinner.prototype.start = function () {
2361
- this.element_.classList.add('is-active');
2362
- };
2363
- MaterialSpinner.prototype['start'] = MaterialSpinner.prototype.start;
2364
- /**
2365
- * Initialize element.
2366
- */
2367
- MaterialSpinner.prototype.init = function () {
2368
- if (this.element_) {
2369
- for (var i = 1; i <= this.Constant_.MDL_SPINNER_LAYER_COUNT; i++) {
2370
- this.createLayer(i);
2371
- }
2372
- this.element_.classList.add('is-upgraded');
2373
- }
2374
- };
2375
- // The component registers itself. It can assume componentHandler is available
2376
- // in the global scope.
2377
- componentHandler.register({
2378
- constructor: MaterialSpinner,
2379
- classAsString: 'MaterialSpinner',
2380
- cssClass: 'mdl-js-spinner',
2381
- widget: true
2382
- });
2383
- /**
2384
- * @license
2385
- * Copyright 2015 Google Inc. All Rights Reserved.
2386
- *
2387
- * Licensed under the Apache License, Version 2.0 (the "License");
2388
- * you may not use this file except in compliance with the License.
2389
- * You may obtain a copy of the License at
2390
- *
2391
- * http://www.apache.org/licenses/LICENSE-2.0
2392
- *
2393
- * Unless required by applicable law or agreed to in writing, software
2394
- * distributed under the License is distributed on an "AS IS" BASIS,
2395
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2396
- * See the License for the specific language governing permissions and
2397
- * limitations under the License.
2398
- */
2399
- /**
2400
- * Class constructor for Checkbox MDL component.
2401
- * Implements MDL component design pattern defined at:
2402
- * https://github.com/jasonmayes/mdl-component-design-pattern
2403
- *
2404
- * @constructor
2405
- * @param {HTMLElement} element The element that will be upgraded.
2406
- */
2407
- var MaterialSwitch = function MaterialSwitch(element) {
2408
- this.element_ = element;
2409
- // Initialize instance.
2410
- this.init();
2411
- };
2412
- window['MaterialSwitch'] = MaterialSwitch;
2413
- /**
2414
- * Store constants in one place so they can be updated easily.
2415
- *
2416
- * @enum {string | number}
2417
- * @private
2418
- */
2419
- MaterialSwitch.prototype.Constant_ = { TINY_TIMEOUT: 0.001 };
2420
- /**
2421
- * Store strings for class names defined by this component that are used in
2422
- * JavaScript. This allows us to simply change it in one place should we
2423
- * decide to modify at a later date.
2424
- *
2425
- * @enum {string}
2426
- * @private
2427
- */
2428
- MaterialSwitch.prototype.CssClasses_ = {
2429
- INPUT: 'mdl-switch__input',
2430
- TRACK: 'mdl-switch__track',
2431
- THUMB: 'mdl-switch__thumb',
2432
- FOCUS_HELPER: 'mdl-switch__focus-helper',
2433
- RIPPLE_EFFECT: 'mdl-js-ripple-effect',
2434
- RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
2435
- RIPPLE_CONTAINER: 'mdl-switch__ripple-container',
2436
- RIPPLE_CENTER: 'mdl-ripple--center',
2437
- RIPPLE: 'mdl-ripple',
2438
- IS_FOCUSED: 'is-focused',
2439
- IS_DISABLED: 'is-disabled',
2440
- IS_CHECKED: 'is-checked'
2441
- };
2442
- /**
2443
- * Handle change of state.
2444
- *
2445
- * @param {Event} event The event that fired.
2446
- * @private
2447
- */
2448
- MaterialSwitch.prototype.onChange_ = function (event) {
2449
- this.updateClasses_();
2450
- };
2451
- /**
2452
- * Handle focus of element.
2453
- *
2454
- * @param {Event} event The event that fired.
2455
- * @private
2456
- */
2457
- MaterialSwitch.prototype.onFocus_ = function (event) {
2458
- this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
2459
- };
2460
- /**
2461
- * Handle lost focus of element.
2462
- *
2463
- * @param {Event} event The event that fired.
2464
- * @private
2465
- */
2466
- MaterialSwitch.prototype.onBlur_ = function (event) {
2467
- this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
2468
- };
2469
- /**
2470
- * Handle mouseup.
2471
- *
2472
- * @param {Event} event The event that fired.
2473
- * @private
2474
- */
2475
- MaterialSwitch.prototype.onMouseUp_ = function (event) {
2476
- this.blur_();
2477
- };
2478
- /**
2479
- * Handle class updates.
2480
- *
2481
- * @private
2482
- */
2483
- MaterialSwitch.prototype.updateClasses_ = function () {
2484
- this.checkDisabled();
2485
- this.checkToggleState();
2486
- };
2487
- /**
2488
- * Add blur.
2489
- *
2490
- * @private
2491
- */
2492
- MaterialSwitch.prototype.blur_ = function () {
2493
- // TODO: figure out why there's a focus event being fired after our blur,
2494
- // so that we can avoid this hack.
2495
- window.setTimeout(function () {
2496
- this.inputElement_.blur();
2497
- }.bind(this), this.Constant_.TINY_TIMEOUT);
2498
- };
2499
- // Public methods.
2500
- /**
2501
- * Check the components disabled state.
2502
- *
2503
- * @public
2504
- */
2505
- MaterialSwitch.prototype.checkDisabled = function () {
2506
- if (this.inputElement_.disabled) {
2507
- this.element_.classList.add(this.CssClasses_.IS_DISABLED);
2508
- } else {
2509
- this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
2510
- }
2511
- };
2512
- MaterialSwitch.prototype['checkDisabled'] = MaterialSwitch.prototype.checkDisabled;
2513
- /**
2514
- * Check the components toggled state.
2515
- *
2516
- * @public
2517
- */
2518
- MaterialSwitch.prototype.checkToggleState = function () {
2519
- if (this.inputElement_.checked) {
2520
- this.element_.classList.add(this.CssClasses_.IS_CHECKED);
2521
- } else {
2522
- this.element_.classList.remove(this.CssClasses_.IS_CHECKED);
2523
- }
2524
- };
2525
- MaterialSwitch.prototype['checkToggleState'] = MaterialSwitch.prototype.checkToggleState;
2526
- /**
2527
- * Disable switch.
2528
- *
2529
- * @public
2530
- */
2531
- MaterialSwitch.prototype.disable = function () {
2532
- this.inputElement_.disabled = true;
2533
- this.updateClasses_();
2534
- };
2535
- MaterialSwitch.prototype['disable'] = MaterialSwitch.prototype.disable;
2536
- /**
2537
- * Enable switch.
2538
- *
2539
- * @public
2540
- */
2541
- MaterialSwitch.prototype.enable = function () {
2542
- this.inputElement_.disabled = false;
2543
- this.updateClasses_();
2544
- };
2545
- MaterialSwitch.prototype['enable'] = MaterialSwitch.prototype.enable;
2546
- /**
2547
- * Activate switch.
2548
- *
2549
- * @public
2550
- */
2551
- MaterialSwitch.prototype.on = function () {
2552
- this.inputElement_.checked = true;
2553
- this.updateClasses_();
2554
- };
2555
- MaterialSwitch.prototype['on'] = MaterialSwitch.prototype.on;
2556
- /**
2557
- * Deactivate switch.
2558
- *
2559
- * @public
2560
- */
2561
- MaterialSwitch.prototype.off = function () {
2562
- this.inputElement_.checked = false;
2563
- this.updateClasses_();
2564
- };
2565
- MaterialSwitch.prototype['off'] = MaterialSwitch.prototype.off;
2566
- /**
2567
- * Initialize element.
2568
- */
2569
- MaterialSwitch.prototype.init = function () {
2570
- if (this.element_) {
2571
- this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);
2572
- var track = document.createElement('div');
2573
- track.classList.add(this.CssClasses_.TRACK);
2574
- var thumb = document.createElement('div');
2575
- thumb.classList.add(this.CssClasses_.THUMB);
2576
- var focusHelper = document.createElement('span');
2577
- focusHelper.classList.add(this.CssClasses_.FOCUS_HELPER);
2578
- thumb.appendChild(focusHelper);
2579
- this.element_.appendChild(track);
2580
- this.element_.appendChild(thumb);
2581
- this.boundMouseUpHandler = this.onMouseUp_.bind(this);
2582
- if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
2583
- this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
2584
- this.rippleContainerElement_ = document.createElement('span');
2585
- this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
2586
- this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT);
2587
- this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
2588
- this.rippleContainerElement_.addEventListener('mouseup', this.boundMouseUpHandler);
2589
- var ripple = document.createElement('span');
2590
- ripple.classList.add(this.CssClasses_.RIPPLE);
2591
- this.rippleContainerElement_.appendChild(ripple);
2592
- this.element_.appendChild(this.rippleContainerElement_);
2593
- }
2594
- this.boundChangeHandler = this.onChange_.bind(this);
2595
- this.boundFocusHandler = this.onFocus_.bind(this);
2596
- this.boundBlurHandler = this.onBlur_.bind(this);
2597
- this.inputElement_.addEventListener('change', this.boundChangeHandler);
2598
- this.inputElement_.addEventListener('focus', this.boundFocusHandler);
2599
- this.inputElement_.addEventListener('blur', this.boundBlurHandler);
2600
- this.element_.addEventListener('mouseup', this.boundMouseUpHandler);
2601
- this.updateClasses_();
2602
- this.element_.classList.add('is-upgraded');
2603
- }
2604
- };
2605
- // The component registers itself. It can assume componentHandler is available
2606
- // in the global scope.
2607
- componentHandler.register({
2608
- constructor: MaterialSwitch,
2609
- classAsString: 'MaterialSwitch',
2610
- cssClass: 'mdl-js-switch',
2611
- widget: true
2612
- });
2613
- /**
2614
- * @license
2615
- * Copyright 2015 Google Inc. All Rights Reserved.
2616
- *
2617
- * Licensed under the Apache License, Version 2.0 (the "License");
2618
- * you may not use this file except in compliance with the License.
2619
- * You may obtain a copy of the License at
2620
- *
2621
- * http://www.apache.org/licenses/LICENSE-2.0
2622
- *
2623
- * Unless required by applicable law or agreed to in writing, software
2624
- * distributed under the License is distributed on an "AS IS" BASIS,
2625
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2626
- * See the License for the specific language governing permissions and
2627
- * limitations under the License.
2628
- */
2629
- /**
2630
- * Class constructor for Tabs MDL component.
2631
- * Implements MDL component design pattern defined at:
2632
- * https://github.com/jasonmayes/mdl-component-design-pattern
2633
- *
2634
- * @constructor
2635
- * @param {Element} element The element that will be upgraded.
2636
- */
2637
- var MaterialTabs = function MaterialTabs(element) {
2638
- // Stores the HTML element.
2639
- this.element_ = element;
2640
- // Initialize instance.
2641
- this.init();
2642
- };
2643
- window['MaterialTabs'] = MaterialTabs;
2644
- /**
2645
- * Store constants in one place so they can be updated easily.
2646
- *
2647
- * @enum {string}
2648
- * @private
2649
- */
2650
- MaterialTabs.prototype.Constant_ = {};
2651
- /**
2652
- * Store strings for class names defined by this component that are used in
2653
- * JavaScript. This allows us to simply change it in one place should we
2654
- * decide to modify at a later date.
2655
- *
2656
- * @enum {string}
2657
- * @private
2658
- */
2659
- MaterialTabs.prototype.CssClasses_ = {
2660
- TAB_CLASS: 'mdl-tabs__tab',
2661
- PANEL_CLASS: 'mdl-tabs__panel',
2662
- ACTIVE_CLASS: 'is-active',
2663
- UPGRADED_CLASS: 'is-upgraded',
2664
- MDL_JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',
2665
- MDL_RIPPLE_CONTAINER: 'mdl-tabs__ripple-container',
2666
- MDL_RIPPLE: 'mdl-ripple',
2667
- MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events'
2668
- };
2669
- /**
2670
- * Handle clicks to a tabs component
2671
- *
2672
- * @private
2673
- */
2674
- MaterialTabs.prototype.initTabs_ = function () {
2675
- if (this.element_.classList.contains(this.CssClasses_.MDL_JS_RIPPLE_EFFECT)) {
2676
- this.element_.classList.add(this.CssClasses_.MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS);
2677
- }
2678
- // Select element tabs, document panels
2679
- this.tabs_ = this.element_.querySelectorAll('.' + this.CssClasses_.TAB_CLASS);
2680
- this.panels_ = this.element_.querySelectorAll('.' + this.CssClasses_.PANEL_CLASS);
2681
- // Create new tabs for each tab element
2682
- for (var i = 0; i < this.tabs_.length; i++) {
2683
- new MaterialTab(this.tabs_[i], this);
2684
- }
2685
- this.element_.classList.add(this.CssClasses_.UPGRADED_CLASS);
2686
- };
2687
- /**
2688
- * Reset tab state, dropping active classes
2689
- *
2690
- * @private
2691
- */
2692
- MaterialTabs.prototype.resetTabState_ = function () {
2693
- for (var k = 0; k < this.tabs_.length; k++) {
2694
- this.tabs_[k].classList.remove(this.CssClasses_.ACTIVE_CLASS);
2695
- }
2696
- };
2697
- /**
2698
- * Reset panel state, droping active classes
2699
- *
2700
- * @private
2701
- */
2702
- MaterialTabs.prototype.resetPanelState_ = function () {
2703
- for (var j = 0; j < this.panels_.length; j++) {
2704
- this.panels_[j].classList.remove(this.CssClasses_.ACTIVE_CLASS);
2705
- }
2706
- };
2707
- /**
2708
- * Initialize element.
2709
- */
2710
- MaterialTabs.prototype.init = function () {
2711
- if (this.element_) {
2712
- this.initTabs_();
2713
- }
2714
- };
2715
- /**
2716
- * Constructor for an individual tab.
2717
- *
2718
- * @constructor
2719
- * @param {Element} tab The HTML element for the tab.
2720
- * @param {MaterialTabs} ctx The MaterialTabs object that owns the tab.
2721
- */
2722
- function MaterialTab(tab, ctx) {
2723
- if (tab) {
2724
- if (ctx.element_.classList.contains(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT)) {
2725
- var rippleContainer = document.createElement('span');
2726
- rippleContainer.classList.add(ctx.CssClasses_.MDL_RIPPLE_CONTAINER);
2727
- rippleContainer.classList.add(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT);
2728
- var ripple = document.createElement('span');
2729
- ripple.classList.add(ctx.CssClasses_.MDL_RIPPLE);
2730
- rippleContainer.appendChild(ripple);
2731
- tab.appendChild(rippleContainer);
2732
- }
2733
- tab.addEventListener('click', function (e) {
2734
- if (tab.getAttribute('href').charAt(0) === '#') {
2735
- e.preventDefault();
2736
- var href = tab.href.split('#')[1];
2737
- var panel = ctx.element_.querySelector('#' + href);
2738
- ctx.resetTabState_();
2739
- ctx.resetPanelState_();
2740
- tab.classList.add(ctx.CssClasses_.ACTIVE_CLASS);
2741
- panel.classList.add(ctx.CssClasses_.ACTIVE_CLASS);
2742
- }
2743
- });
2744
- }
2745
- }
2746
- // The component registers itself. It can assume componentHandler is available
2747
- // in the global scope.
2748
- componentHandler.register({
2749
- constructor: MaterialTabs,
2750
- classAsString: 'MaterialTabs',
2751
- cssClass: 'mdl-js-tabs'
2752
- });
2753
- /**
2754
- * @license
2755
- * Copyright 2015 Google Inc. All Rights Reserved.
2756
- *
2757
- * Licensed under the Apache License, Version 2.0 (the "License");
2758
- * you may not use this file except in compliance with the License.
2759
- * You may obtain a copy of the License at
2760
- *
2761
- * http://www.apache.org/licenses/LICENSE-2.0
2762
- *
2763
- * Unless required by applicable law or agreed to in writing, software
2764
- * distributed under the License is distributed on an "AS IS" BASIS,
2765
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2766
- * See the License for the specific language governing permissions and
2767
- * limitations under the License.
2768
- */
2769
- /**
2770
- * Class constructor for Textfield MDL component.
2771
- * Implements MDL component design pattern defined at:
2772
- * https://github.com/jasonmayes/mdl-component-design-pattern
2773
- *
2774
- * @constructor
2775
- * @param {HTMLElement} element The element that will be upgraded.
2776
- */
2777
- var MaterialTextfield = function MaterialTextfield(element) {
2778
- this.element_ = element;
2779
- this.maxRows = this.Constant_.NO_MAX_ROWS;
2780
- // Initialize instance.
2781
- this.init();
2782
- };
2783
- window['MaterialTextfield'] = MaterialTextfield;
2784
- /**
2785
- * Store constants in one place so they can be updated easily.
2786
- *
2787
- * @enum {string | number}
2788
- * @private
2789
- */
2790
- MaterialTextfield.prototype.Constant_ = {
2791
- NO_MAX_ROWS: -1,
2792
- MAX_ROWS_ATTRIBUTE: 'maxrows'
2793
- };
2794
- /**
2795
- * Store strings for class names defined by this component that are used in
2796
- * JavaScript. This allows us to simply change it in one place should we
2797
- * decide to modify at a later date.
2798
- *
2799
- * @enum {string}
2800
- * @private
2801
- */
2802
- MaterialTextfield.prototype.CssClasses_ = {
2803
- LABEL: 'mdl-textfield__label',
2804
- INPUT: 'mdl-textfield__input',
2805
- IS_DIRTY: 'is-dirty',
2806
- IS_FOCUSED: 'is-focused',
2807
- IS_DISABLED: 'is-disabled',
2808
- IS_INVALID: 'is-invalid',
2809
- IS_UPGRADED: 'is-upgraded',
2810
- HAS_PLACEHOLDER: 'has-placeholder'
2811
- };
2812
- /**
2813
- * Handle input being entered.
2814
- *
2815
- * @param {Event} event The event that fired.
2816
- * @private
2817
- */
2818
- MaterialTextfield.prototype.onKeyDown_ = function (event) {
2819
- var currentRowCount = event.target.value.split('\n').length;
2820
- if (event.keyCode === 13) {
2821
- if (currentRowCount >= this.maxRows) {
2822
- event.preventDefault();
2823
- }
2824
- }
2825
- };
2826
- /**
2827
- * Handle focus.
2828
- *
2829
- * @param {Event} event The event that fired.
2830
- * @private
2831
- */
2832
- MaterialTextfield.prototype.onFocus_ = function (event) {
2833
- this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
2834
- };
2835
- /**
2836
- * Handle lost focus.
2837
- *
2838
- * @param {Event} event The event that fired.
2839
- * @private
2840
- */
2841
- MaterialTextfield.prototype.onBlur_ = function (event) {
2842
- this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
2843
- };
2844
- /**
2845
- * Handle reset event from out side.
2846
- *
2847
- * @param {Event} event The event that fired.
2848
- * @private
2849
- */
2850
- MaterialTextfield.prototype.onReset_ = function (event) {
2851
- this.updateClasses_();
2852
- };
2853
- /**
2854
- * Handle class updates.
2855
- *
2856
- * @private
2857
- */
2858
- MaterialTextfield.prototype.updateClasses_ = function () {
2859
- this.checkDisabled();
2860
- this.checkValidity();
2861
- this.checkDirty();
2862
- this.checkFocus();
2863
- };
2864
- // Public methods.
2865
- /**
2866
- * Check the disabled state and update field accordingly.
2867
- *
2868
- * @public
2869
- */
2870
- MaterialTextfield.prototype.checkDisabled = function () {
2871
- if (this.input_.disabled) {
2872
- this.element_.classList.add(this.CssClasses_.IS_DISABLED);
2873
- } else {
2874
- this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
2875
- }
2876
- };
2877
- MaterialTextfield.prototype['checkDisabled'] = MaterialTextfield.prototype.checkDisabled;
2878
- /**
2879
- * Check the focus state and update field accordingly.
2880
- *
2881
- * @public
2882
- */
2883
- MaterialTextfield.prototype.checkFocus = function () {
2884
- if (Boolean(this.element_.querySelector(':focus'))) {
2885
- this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
2886
- } else {
2887
- this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
2888
- }
2889
- };
2890
- MaterialTextfield.prototype['checkFocus'] = MaterialTextfield.prototype.checkFocus;
2891
- /**
2892
- * Check the validity state and update field accordingly.
2893
- *
2894
- * @public
2895
- */
2896
- MaterialTextfield.prototype.checkValidity = function () {
2897
- if (this.input_.validity) {
2898
- if (this.input_.validity.valid) {
2899
- this.element_.classList.remove(this.CssClasses_.IS_INVALID);
2900
- } else {
2901
- this.element_.classList.add(this.CssClasses_.IS_INVALID);
2902
- }
2903
- }
2904
- };
2905
- MaterialTextfield.prototype['checkValidity'] = MaterialTextfield.prototype.checkValidity;
2906
- /**
2907
- * Check the dirty state and update field accordingly.
2908
- *
2909
- * @public
2910
- */
2911
- MaterialTextfield.prototype.checkDirty = function () {
2912
- if (this.input_.value && this.input_.value.length > 0) {
2913
- this.element_.classList.add(this.CssClasses_.IS_DIRTY);
2914
- } else {
2915
- this.element_.classList.remove(this.CssClasses_.IS_DIRTY);
2916
- }
2917
- };
2918
- MaterialTextfield.prototype['checkDirty'] = MaterialTextfield.prototype.checkDirty;
2919
- /**
2920
- * Disable text field.
2921
- *
2922
- * @public
2923
- */
2924
- MaterialTextfield.prototype.disable = function () {
2925
- this.input_.disabled = true;
2926
- this.updateClasses_();
2927
- };
2928
- MaterialTextfield.prototype['disable'] = MaterialTextfield.prototype.disable;
2929
- /**
2930
- * Enable text field.
2931
- *
2932
- * @public
2933
- */
2934
- MaterialTextfield.prototype.enable = function () {
2935
- this.input_.disabled = false;
2936
- this.updateClasses_();
2937
- };
2938
- MaterialTextfield.prototype['enable'] = MaterialTextfield.prototype.enable;
2939
- /**
2940
- * Update text field value.
2941
- *
2942
- * @param {string} value The value to which to set the control (optional).
2943
- * @public
2944
- */
2945
- MaterialTextfield.prototype.change = function (value) {
2946
- this.input_.value = value || '';
2947
- this.updateClasses_();
2948
- };
2949
- MaterialTextfield.prototype['change'] = MaterialTextfield.prototype.change;
2950
- /**
2951
- * Initialize element.
2952
- */
2953
- MaterialTextfield.prototype.init = function () {
2954
- if (this.element_) {
2955
- this.label_ = this.element_.querySelector('.' + this.CssClasses_.LABEL);
2956
- this.input_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);
2957
- if (this.input_) {
2958
- if (this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)) {
2959
- this.maxRows = parseInt(this.input_.getAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE), 10);
2960
- if (isNaN(this.maxRows)) {
2961
- this.maxRows = this.Constant_.NO_MAX_ROWS;
2962
- }
2963
- }
2964
- if (this.input_.hasAttribute('placeholder')) {
2965
- this.element_.classList.add(this.CssClasses_.HAS_PLACEHOLDER);
2966
- }
2967
- this.boundUpdateClassesHandler = this.updateClasses_.bind(this);
2968
- this.boundFocusHandler = this.onFocus_.bind(this);
2969
- this.boundBlurHandler = this.onBlur_.bind(this);
2970
- this.boundResetHandler = this.onReset_.bind(this);
2971
- this.input_.addEventListener('input', this.boundUpdateClassesHandler);
2972
- this.input_.addEventListener('focus', this.boundFocusHandler);
2973
- this.input_.addEventListener('blur', this.boundBlurHandler);
2974
- this.input_.addEventListener('reset', this.boundResetHandler);
2975
- if (this.maxRows !== this.Constant_.NO_MAX_ROWS) {
2976
- // TODO: This should handle pasting multi line text.
2977
- // Currently doesn't.
2978
- this.boundKeyDownHandler = this.onKeyDown_.bind(this);
2979
- this.input_.addEventListener('keydown', this.boundKeyDownHandler);
2980
- }
2981
- var invalid = this.element_.classList.contains(this.CssClasses_.IS_INVALID);
2982
- this.updateClasses_();
2983
- this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
2984
- if (invalid) {
2985
- this.element_.classList.add(this.CssClasses_.IS_INVALID);
2986
- }
2987
- if (this.input_.hasAttribute('autofocus')) {
2988
- this.element_.focus();
2989
- this.checkFocus();
2990
- }
2991
- }
2992
- }
2993
- };
2994
- // The component registers itself. It can assume componentHandler is available
2995
- // in the global scope.
2996
- componentHandler.register({
2997
- constructor: MaterialTextfield,
2998
- classAsString: 'MaterialTextfield',
2999
- cssClass: 'mdl-js-textfield',
3000
- widget: true
3001
- });
3002
- /**
3003
- * @license
3004
- * Copyright 2015 Google Inc. All Rights Reserved.
3005
- *
3006
- * Licensed under the Apache License, Version 2.0 (the "License");
3007
- * you may not use this file except in compliance with the License.
3008
- * You may obtain a copy of the License at
3009
- *
3010
- * http://www.apache.org/licenses/LICENSE-2.0
3011
- *
3012
- * Unless required by applicable law or agreed to in writing, software
3013
- * distributed under the License is distributed on an "AS IS" BASIS,
3014
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3015
- * See the License for the specific language governing permissions and
3016
- * limitations under the License.
3017
- */
3018
- /**
3019
- * Class constructor for Tooltip MDL component.
3020
- * Implements MDL component design pattern defined at:
3021
- * https://github.com/jasonmayes/mdl-component-design-pattern
3022
- *
3023
- * @constructor
3024
- * @param {HTMLElement} element The element that will be upgraded.
3025
- */
3026
- var MaterialTooltip = function MaterialTooltip(element) {
3027
- this.element_ = element;
3028
- // Initialize instance.
3029
- this.init();
3030
- };
3031
- window['MaterialTooltip'] = MaterialTooltip;
3032
- /**
3033
- * Store constants in one place so they can be updated easily.
3034
- *
3035
- * @enum {string | number}
3036
- * @private
3037
- */
3038
- MaterialTooltip.prototype.Constant_ = {};
3039
- /**
3040
- * Store strings for class names defined by this component that are used in
3041
- * JavaScript. This allows us to simply change it in one place should we
3042
- * decide to modify at a later date.
3043
- *
3044
- * @enum {string}
3045
- * @private
3046
- */
3047
- MaterialTooltip.prototype.CssClasses_ = {
3048
- IS_ACTIVE: 'is-active',
3049
- BOTTOM: 'mdl-tooltip--bottom',
3050
- LEFT: 'mdl-tooltip--left',
3051
- RIGHT: 'mdl-tooltip--right',
3052
- TOP: 'mdl-tooltip--top'
3053
- };
3054
- /**
3055
- * Handle mouseenter for tooltip.
3056
- *
3057
- * @param {Event} event The event that fired.
3058
- * @private
3059
- */
3060
- MaterialTooltip.prototype.handleMouseEnter_ = function (event) {
3061
- var props = event.target.getBoundingClientRect();
3062
- var left = props.left + props.width / 2;
3063
- var top = props.top + props.height / 2;
3064
- var marginLeft = -1 * (this.element_.offsetWidth / 2);
3065
- var marginTop = -1 * (this.element_.offsetHeight / 2);
3066
- if (this.element_.classList.contains(this.CssClasses_.LEFT) || this.element_.classList.contains(this.CssClasses_.RIGHT)) {
3067
- left = props.width / 2;
3068
- if (top + marginTop < 0) {
3069
- this.element_.style.top = '0';
3070
- this.element_.style.marginTop = '0';
3071
- } else {
3072
- this.element_.style.top = top + 'px';
3073
- this.element_.style.marginTop = marginTop + 'px';
3074
- }
3075
- } else {
3076
- if (left + marginLeft < 0) {
3077
- this.element_.style.left = '0';
3078
- this.element_.style.marginLeft = '0';
3079
- } else {
3080
- this.element_.style.left = left + 'px';
3081
- this.element_.style.marginLeft = marginLeft + 'px';
3082
- }
3083
- }
3084
- if (this.element_.classList.contains(this.CssClasses_.TOP)) {
3085
- this.element_.style.top = props.top - this.element_.offsetHeight - 10 + 'px';
3086
- } else if (this.element_.classList.contains(this.CssClasses_.RIGHT)) {
3087
- this.element_.style.left = props.left + props.width + 10 + 'px';
3088
- } else if (this.element_.classList.contains(this.CssClasses_.LEFT)) {
3089
- this.element_.style.left = props.left - this.element_.offsetWidth - 10 + 'px';
3090
- } else {
3091
- this.element_.style.top = props.top + props.height + 10 + 'px';
3092
- }
3093
- this.element_.classList.add(this.CssClasses_.IS_ACTIVE);
3094
- };
3095
- /**
3096
- * Hide tooltip on mouseleave or scroll
3097
- *
3098
- * @private
3099
- */
3100
- MaterialTooltip.prototype.hideTooltip_ = function () {
3101
- this.element_.classList.remove(this.CssClasses_.IS_ACTIVE);
3102
- };
3103
- /**
3104
- * Initialize element.
3105
- */
3106
- MaterialTooltip.prototype.init = function () {
3107
- if (this.element_) {
3108
- var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for');
3109
- if (forElId) {
3110
- this.forElement_ = document.getElementById(forElId);
3111
- }
3112
- if (this.forElement_) {
3113
- // It's left here because it prevents accidental text selection on Android
3114
- if (!this.forElement_.hasAttribute('tabindex')) {
3115
- this.forElement_.setAttribute('tabindex', '0');
3116
- }
3117
- this.boundMouseEnterHandler = this.handleMouseEnter_.bind(this);
3118
- this.boundMouseLeaveAndScrollHandler = this.hideTooltip_.bind(this);
3119
- this.forElement_.addEventListener('mouseenter', this.boundMouseEnterHandler, false);
3120
- this.forElement_.addEventListener('touchend', this.boundMouseEnterHandler, false);
3121
- this.forElement_.addEventListener('mouseleave', this.boundMouseLeaveAndScrollHandler, false);
3122
- window.addEventListener('scroll', this.boundMouseLeaveAndScrollHandler, true);
3123
- window.addEventListener('touchstart', this.boundMouseLeaveAndScrollHandler);
3124
- }
3125
- }
3126
- };
3127
- // The component registers itself. It can assume componentHandler is available
3128
- // in the global scope.
3129
- componentHandler.register({
3130
- constructor: MaterialTooltip,
3131
- classAsString: 'MaterialTooltip',
3132
- cssClass: 'mdl-tooltip'
3133
- });
3134
- /**
3135
- * @license
3136
- * Copyright 2015 Google Inc. All Rights Reserved.
3137
- *
3138
- * Licensed under the Apache License, Version 2.0 (the "License");
3139
- * you may not use this file except in compliance with the License.
3140
- * You may obtain a copy of the License at
3141
- *
3142
- * http://www.apache.org/licenses/LICENSE-2.0
3143
- *
3144
- * Unless required by applicable law or agreed to in writing, software
3145
- * distributed under the License is distributed on an "AS IS" BASIS,
3146
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3147
- * See the License for the specific language governing permissions and
3148
- * limitations under the License.
3149
- */
3150
- /**
3151
- * Class constructor for Layout MDL component.
3152
- * Implements MDL component design pattern defined at:
3153
- * https://github.com/jasonmayes/mdl-component-design-pattern
3154
- *
3155
- * @constructor
3156
- * @param {HTMLElement} element The element that will be upgraded.
3157
- */
3158
- var MaterialLayout = function MaterialLayout(element) {
3159
- this.element_ = element;
3160
- // Initialize instance.
3161
- this.init();
3162
- };
3163
- window['MaterialLayout'] = MaterialLayout;
3164
- /**
3165
- * Store constants in one place so they can be updated easily.
3166
- *
3167
- * @enum {string | number}
3168
- * @private
3169
- */
3170
- MaterialLayout.prototype.Constant_ = {
3171
- MAX_WIDTH: '(max-width: 1024px)',
3172
- TAB_SCROLL_PIXELS: 100,
3173
- RESIZE_TIMEOUT: 100,
3174
- MENU_ICON: '&#xE5D2;',
3175
- CHEVRON_LEFT: 'chevron_left',
3176
- CHEVRON_RIGHT: 'chevron_right'
3177
- };
3178
- /**
3179
- * Keycodes, for code readability.
3180
- *
3181
- * @enum {number}
3182
- * @private
3183
- */
3184
- MaterialLayout.prototype.Keycodes_ = {
3185
- ENTER: 13,
3186
- ESCAPE: 27,
3187
- SPACE: 32
3188
- };
3189
- /**
3190
- * Modes.
3191
- *
3192
- * @enum {number}
3193
- * @private
3194
- */
3195
- MaterialLayout.prototype.Mode_ = {
3196
- STANDARD: 0,
3197
- SEAMED: 1,
3198
- WATERFALL: 2,
3199
- SCROLL: 3
3200
- };
3201
- /**
3202
- * Store strings for class names defined by this component that are used in
3203
- * JavaScript. This allows us to simply change it in one place should we
3204
- * decide to modify at a later date.
3205
- *
3206
- * @enum {string}
3207
- * @private
3208
- */
3209
- MaterialLayout.prototype.CssClasses_ = {
3210
- CONTAINER: 'mdl-layout__container',
3211
- HEADER: 'mdl-layout__header',
3212
- DRAWER: 'mdl-layout__drawer',
3213
- CONTENT: 'mdl-layout__content',
3214
- DRAWER_BTN: 'mdl-layout__drawer-button',
3215
- ICON: 'material-icons',
3216
- JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',
3217
- RIPPLE_CONTAINER: 'mdl-layout__tab-ripple-container',
3218
- RIPPLE: 'mdl-ripple',
3219
- RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
3220
- HEADER_SEAMED: 'mdl-layout__header--seamed',
3221
- HEADER_WATERFALL: 'mdl-layout__header--waterfall',
3222
- HEADER_SCROLL: 'mdl-layout__header--scroll',
3223
- FIXED_HEADER: 'mdl-layout--fixed-header',
3224
- OBFUSCATOR: 'mdl-layout__obfuscator',
3225
- TAB_BAR: 'mdl-layout__tab-bar',
3226
- TAB_CONTAINER: 'mdl-layout__tab-bar-container',
3227
- TAB: 'mdl-layout__tab',
3228
- TAB_BAR_BUTTON: 'mdl-layout__tab-bar-button',
3229
- TAB_BAR_LEFT_BUTTON: 'mdl-layout__tab-bar-left-button',
3230
- TAB_BAR_RIGHT_BUTTON: 'mdl-layout__tab-bar-right-button',
3231
- TAB_MANUAL_SWITCH: 'mdl-layout__tab-manual-switch',
3232
- PANEL: 'mdl-layout__tab-panel',
3233
- HAS_DRAWER: 'has-drawer',
3234
- HAS_TABS: 'has-tabs',
3235
- HAS_SCROLLING_HEADER: 'has-scrolling-header',
3236
- CASTING_SHADOW: 'is-casting-shadow',
3237
- IS_COMPACT: 'is-compact',
3238
- IS_SMALL_SCREEN: 'is-small-screen',
3239
- IS_DRAWER_OPEN: 'is-visible',
3240
- IS_ACTIVE: 'is-active',
3241
- IS_UPGRADED: 'is-upgraded',
3242
- IS_ANIMATING: 'is-animating',
3243
- ON_LARGE_SCREEN: 'mdl-layout--large-screen-only',
3244
- ON_SMALL_SCREEN: 'mdl-layout--small-screen-only'
3245
- };
3246
- /**
3247
- * Handles scrolling on the content.
3248
- *
3249
- * @private
3250
- */
3251
- MaterialLayout.prototype.contentScrollHandler_ = function () {
3252
- if (this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)) {
3253
- return;
3254
- }
3255
- var headerVisible = !this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN) || this.element_.classList.contains(this.CssClasses_.FIXED_HEADER);
3256
- if (this.content_.scrollTop > 0 && !this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
3257
- this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);
3258
- this.header_.classList.add(this.CssClasses_.IS_COMPACT);
3259
- if (headerVisible) {
3260
- this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
3261
- }
3262
- } else if (this.content_.scrollTop <= 0 && this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
3263
- this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);
3264
- this.header_.classList.remove(this.CssClasses_.IS_COMPACT);
3265
- if (headerVisible) {
3266
- this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
3267
- }
3268
- }
3269
- };
3270
- /**
3271
- * Handles a keyboard event on the drawer.
3272
- *
3273
- * @param {Event} evt The event that fired.
3274
- * @private
3275
- */
3276
- MaterialLayout.prototype.keyboardEventHandler_ = function (evt) {
3277
- // Only react when the drawer is open.
3278
- if (evt.keyCode === this.Keycodes_.ESCAPE && this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) {
3279
- this.toggleDrawer();
3280
- }
3281
- };
3282
- /**
3283
- * Handles changes in screen size.
3284
- *
3285
- * @private
3286
- */
3287
- MaterialLayout.prototype.screenSizeHandler_ = function () {
3288
- if (this.screenSizeMediaQuery_.matches) {
3289
- this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN);
3290
- } else {
3291
- this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN);
3292
- // Collapse drawer (if any) when moving to a large screen size.
3293
- if (this.drawer_) {
3294
- this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);
3295
- this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);
3296
- }
3297
- }
3298
- };
3299
- /**
3300
- * Handles events of drawer button.
3301
- *
3302
- * @param {Event} evt The event that fired.
3303
- * @private
3304
- */
3305
- MaterialLayout.prototype.drawerToggleHandler_ = function (evt) {
3306
- if (evt && evt.type === 'keydown') {
3307
- if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) {
3308
- // prevent scrolling in drawer nav
3309
- evt.preventDefault();
3310
- } else {
3311
- // prevent other keys
3312
- return;
3313
- }
3314
- }
3315
- this.toggleDrawer();
3316
- };
3317
- /**
3318
- * Handles (un)setting the `is-animating` class
3319
- *
3320
- * @private
3321
- */
3322
- MaterialLayout.prototype.headerTransitionEndHandler_ = function () {
3323
- this.header_.classList.remove(this.CssClasses_.IS_ANIMATING);
3324
- };
3325
- /**
3326
- * Handles expanding the header on click
3327
- *
3328
- * @private
3329
- */
3330
- MaterialLayout.prototype.headerClickHandler_ = function () {
3331
- if (this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
3332
- this.header_.classList.remove(this.CssClasses_.IS_COMPACT);
3333
- this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
3334
- }
3335
- };
3336
- /**
3337
- * Reset tab state, dropping active classes
3338
- *
3339
- * @private
3340
- */
3341
- MaterialLayout.prototype.resetTabState_ = function (tabBar) {
3342
- for (var k = 0; k < tabBar.length; k++) {
3343
- tabBar[k].classList.remove(this.CssClasses_.IS_ACTIVE);
3344
- }
3345
- };
3346
- /**
3347
- * Reset panel state, droping active classes
3348
- *
3349
- * @private
3350
- */
3351
- MaterialLayout.prototype.resetPanelState_ = function (panels) {
3352
- for (var j = 0; j < panels.length; j++) {
3353
- panels[j].classList.remove(this.CssClasses_.IS_ACTIVE);
3354
- }
3355
- };
3356
- /**
3357
- * Toggle drawer state
3358
- *
3359
- * @public
3360
- */
3361
- MaterialLayout.prototype.toggleDrawer = function () {
3362
- var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN);
3363
- this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);
3364
- this.obfuscator_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);
3365
- // Set accessibility properties.
3366
- if (this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) {
3367
- this.drawer_.setAttribute('aria-hidden', 'false');
3368
- drawerButton.setAttribute('aria-expanded', 'true');
3369
- } else {
3370
- this.drawer_.setAttribute('aria-hidden', 'true');
3371
- drawerButton.setAttribute('aria-expanded', 'false');
3372
- }
3373
- };
3374
- MaterialLayout.prototype['toggleDrawer'] = MaterialLayout.prototype.toggleDrawer;
3375
- /**
3376
- * Initialize element.
3377
- */
3378
- MaterialLayout.prototype.init = function () {
3379
- if (this.element_) {
3380
- var container = document.createElement('div');
3381
- container.classList.add(this.CssClasses_.CONTAINER);
3382
- var focusedElement = this.element_.querySelector(':focus');
3383
- this.element_.parentElement.insertBefore(container, this.element_);
3384
- this.element_.parentElement.removeChild(this.element_);
3385
- container.appendChild(this.element_);
3386
- if (focusedElement) {
3387
- focusedElement.focus();
3388
- }
3389
- var directChildren = this.element_.childNodes;
3390
- var numChildren = directChildren.length;
3391
- for (var c = 0; c < numChildren; c++) {
3392
- var child = directChildren[c];
3393
- if (child.classList && child.classList.contains(this.CssClasses_.HEADER)) {
3394
- this.header_ = child;
3395
- }
3396
- if (child.classList && child.classList.contains(this.CssClasses_.DRAWER)) {
3397
- this.drawer_ = child;
3398
- }
3399
- if (child.classList && child.classList.contains(this.CssClasses_.CONTENT)) {
3400
- this.content_ = child;
3401
- }
3402
- }
3403
- window.addEventListener('pageshow', function (e) {
3404
- if (e.persisted) {
3405
- // when page is loaded from back/forward cache
3406
- // trigger repaint to let layout scroll in safari
3407
- this.element_.style.overflowY = 'hidden';
3408
- requestAnimationFrame(function () {
3409
- this.element_.style.overflowY = '';
3410
- }.bind(this));
3411
- }
3412
- }.bind(this), false);
3413
- if (this.header_) {
3414
- this.tabBar_ = this.header_.querySelector('.' + this.CssClasses_.TAB_BAR);
3415
- }
3416
- var mode = this.Mode_.STANDARD;
3417
- if (this.header_) {
3418
- if (this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)) {
3419
- mode = this.Mode_.SEAMED;
3420
- } else if (this.header_.classList.contains(this.CssClasses_.HEADER_WATERFALL)) {
3421
- mode = this.Mode_.WATERFALL;
3422
- this.header_.addEventListener('transitionend', this.headerTransitionEndHandler_.bind(this));
3423
- this.header_.addEventListener('click', this.headerClickHandler_.bind(this));
3424
- } else if (this.header_.classList.contains(this.CssClasses_.HEADER_SCROLL)) {
3425
- mode = this.Mode_.SCROLL;
3426
- container.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER);
3427
- }
3428
- if (mode === this.Mode_.STANDARD) {
3429
- this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);
3430
- if (this.tabBar_) {
3431
- this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW);
3432
- }
3433
- } else if (mode === this.Mode_.SEAMED || mode === this.Mode_.SCROLL) {
3434
- this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);
3435
- if (this.tabBar_) {
3436
- this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW);
3437
- }
3438
- } else if (mode === this.Mode_.WATERFALL) {
3439
- // Add and remove shadows depending on scroll position.
3440
- // Also add/remove auxiliary class for styling of the compact version of
3441
- // the header.
3442
- this.content_.addEventListener('scroll', this.contentScrollHandler_.bind(this));
3443
- this.contentScrollHandler_();
3444
- }
3445
- }
3446
- // Add drawer toggling button to our layout, if we have an openable drawer.
3447
- if (this.drawer_) {
3448
- var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN);
3449
- if (!drawerButton) {
3450
- drawerButton = document.createElement('div');
3451
- drawerButton.setAttribute('aria-expanded', 'false');
3452
- drawerButton.setAttribute('role', 'button');
3453
- drawerButton.setAttribute('tabindex', '0');
3454
- drawerButton.classList.add(this.CssClasses_.DRAWER_BTN);
3455
- var drawerButtonIcon = document.createElement('i');
3456
- drawerButtonIcon.classList.add(this.CssClasses_.ICON);
3457
- drawerButtonIcon.innerHTML = this.Constant_.MENU_ICON;
3458
- drawerButton.appendChild(drawerButtonIcon);
3459
- }
3460
- if (this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)) {
3461
- //If drawer has ON_LARGE_SCREEN class then add it to the drawer toggle button as well.
3462
- drawerButton.classList.add(this.CssClasses_.ON_LARGE_SCREEN);
3463
- } else if (this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)) {
3464
- //If drawer has ON_SMALL_SCREEN class then add it to the drawer toggle button as well.
3465
- drawerButton.classList.add(this.CssClasses_.ON_SMALL_SCREEN);
3466
- }
3467
- drawerButton.addEventListener('click', this.drawerToggleHandler_.bind(this));
3468
- drawerButton.addEventListener('keydown', this.drawerToggleHandler_.bind(this));
3469
- // Add a class if the layout has a drawer, for altering the left padding.
3470
- // Adds the HAS_DRAWER to the elements since this.header_ may or may
3471
- // not be present.
3472
- this.element_.classList.add(this.CssClasses_.HAS_DRAWER);
3473
- // If we have a fixed header, add the button to the header rather than
3474
- // the layout.
3475
- if (this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)) {
3476
- this.header_.insertBefore(drawerButton, this.header_.firstChild);
3477
- } else {
3478
- this.element_.insertBefore(drawerButton, this.content_);
3479
- }
3480
- var obfuscator = document.createElement('div');
3481
- obfuscator.classList.add(this.CssClasses_.OBFUSCATOR);
3482
- this.element_.appendChild(obfuscator);
3483
- obfuscator.addEventListener('click', this.drawerToggleHandler_.bind(this));
3484
- this.obfuscator_ = obfuscator;
3485
- this.drawer_.addEventListener('keydown', this.keyboardEventHandler_.bind(this));
3486
- this.drawer_.setAttribute('aria-hidden', 'true');
3487
- }
3488
- // Keep an eye on screen size, and add/remove auxiliary class for styling
3489
- // of small screens.
3490
- this.screenSizeMediaQuery_ = window.matchMedia(this.Constant_.MAX_WIDTH);
3491
- this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this));
3492
- this.screenSizeHandler_();
3493
- // Initialize tabs, if any.
3494
- if (this.header_ && this.tabBar_) {
3495
- this.element_.classList.add(this.CssClasses_.HAS_TABS);
3496
- var tabContainer = document.createElement('div');
3497
- tabContainer.classList.add(this.CssClasses_.TAB_CONTAINER);
3498
- this.header_.insertBefore(tabContainer, this.tabBar_);
3499
- this.header_.removeChild(this.tabBar_);
3500
- var leftButton = document.createElement('div');
3501
- leftButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);
3502
- leftButton.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON);
3503
- var leftButtonIcon = document.createElement('i');
3504
- leftButtonIcon.classList.add(this.CssClasses_.ICON);
3505
- leftButtonIcon.textContent = this.Constant_.CHEVRON_LEFT;
3506
- leftButton.appendChild(leftButtonIcon);
3507
- leftButton.addEventListener('click', function () {
3508
- this.tabBar_.scrollLeft -= this.Constant_.TAB_SCROLL_PIXELS;
3509
- }.bind(this));
3510
- var rightButton = document.createElement('div');
3511
- rightButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);
3512
- rightButton.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON);
3513
- var rightButtonIcon = document.createElement('i');
3514
- rightButtonIcon.classList.add(this.CssClasses_.ICON);
3515
- rightButtonIcon.textContent = this.Constant_.CHEVRON_RIGHT;
3516
- rightButton.appendChild(rightButtonIcon);
3517
- rightButton.addEventListener('click', function () {
3518
- this.tabBar_.scrollLeft += this.Constant_.TAB_SCROLL_PIXELS;
3519
- }.bind(this));
3520
- tabContainer.appendChild(leftButton);
3521
- tabContainer.appendChild(this.tabBar_);
3522
- tabContainer.appendChild(rightButton);
3523
- // Add and remove tab buttons depending on scroll position and total
3524
- // window size.
3525
- var tabUpdateHandler = function () {
3526
- if (this.tabBar_.scrollLeft > 0) {
3527
- leftButton.classList.add(this.CssClasses_.IS_ACTIVE);
3528
- } else {
3529
- leftButton.classList.remove(this.CssClasses_.IS_ACTIVE);
3530
- }
3531
- if (this.tabBar_.scrollLeft < this.tabBar_.scrollWidth - this.tabBar_.offsetWidth) {
3532
- rightButton.classList.add(this.CssClasses_.IS_ACTIVE);
3533
- } else {
3534
- rightButton.classList.remove(this.CssClasses_.IS_ACTIVE);
3535
- }
3536
- }.bind(this);
3537
- this.tabBar_.addEventListener('scroll', tabUpdateHandler);
3538
- tabUpdateHandler();
3539
- // Update tabs when the window resizes.
3540
- var windowResizeHandler = function () {
3541
- // Use timeouts to make sure it doesn't happen too often.
3542
- if (this.resizeTimeoutId_) {
3543
- clearTimeout(this.resizeTimeoutId_);
3544
- }
3545
- this.resizeTimeoutId_ = setTimeout(function () {
3546
- tabUpdateHandler();
3547
- this.resizeTimeoutId_ = null;
3548
- }.bind(this), this.Constant_.RESIZE_TIMEOUT);
3549
- }.bind(this);
3550
- window.addEventListener('resize', windowResizeHandler);
3551
- if (this.tabBar_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {
3552
- this.tabBar_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
3553
- }
3554
- // Select element tabs, document panels
3555
- var tabs = this.tabBar_.querySelectorAll('.' + this.CssClasses_.TAB);
3556
- var panels = this.content_.querySelectorAll('.' + this.CssClasses_.PANEL);
3557
- // Create new tabs for each tab element
3558
- for (var i = 0; i < tabs.length; i++) {
3559
- new MaterialLayoutTab(tabs[i], tabs, panels, this);
3560
- }
3561
- }
3562
- this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
3563
- }
3564
- };
3565
- /**
3566
- * Constructor for an individual tab.
3567
- *
3568
- * @constructor
3569
- * @param {HTMLElement} tab The HTML element for the tab.
3570
- * @param {!Array<HTMLElement>} tabs Array with HTML elements for all tabs.
3571
- * @param {!Array<HTMLElement>} panels Array with HTML elements for all panels.
3572
- * @param {MaterialLayout} layout The MaterialLayout object that owns the tab.
3573
- */
3574
- function MaterialLayoutTab(tab, tabs, panels, layout) {
3575
- /**
3576
- * Auxiliary method to programmatically select a tab in the UI.
3577
- */
3578
- function selectTab() {
3579
- var href = tab.href.split('#')[1];
3580
- var panel = layout.content_.querySelector('#' + href);
3581
- layout.resetTabState_(tabs);
3582
- layout.resetPanelState_(panels);
3583
- tab.classList.add(layout.CssClasses_.IS_ACTIVE);
3584
- panel.classList.add(layout.CssClasses_.IS_ACTIVE);
3585
- }
3586
- if (layout.tabBar_.classList.contains(layout.CssClasses_.JS_RIPPLE_EFFECT)) {
3587
- var rippleContainer = document.createElement('span');
3588
- rippleContainer.classList.add(layout.CssClasses_.RIPPLE_CONTAINER);
3589
- rippleContainer.classList.add(layout.CssClasses_.JS_RIPPLE_EFFECT);
3590
- var ripple = document.createElement('span');
3591
- ripple.classList.add(layout.CssClasses_.RIPPLE);
3592
- rippleContainer.appendChild(ripple);
3593
- tab.appendChild(rippleContainer);
3594
- }
3595
- if (!layout.tabBar_.classList.contains(layout.CssClasses_.TAB_MANUAL_SWITCH)) {
3596
- tab.addEventListener('click', function (e) {
3597
- if (tab.getAttribute('href').charAt(0) === '#') {
3598
- e.preventDefault();
3599
- selectTab();
3600
- }
3601
- });
3602
- }
3603
- tab.show = selectTab;
3604
- }
3605
- window['MaterialLayoutTab'] = MaterialLayoutTab;
3606
- // The component registers itself. It can assume componentHandler is available
3607
- // in the global scope.
3608
- componentHandler.register({
3609
- constructor: MaterialLayout,
3610
- classAsString: 'MaterialLayout',
3611
- cssClass: 'mdl-js-layout'
3612
- });
3613
- /**
3614
- * @license
3615
- * Copyright 2015 Google Inc. All Rights Reserved.
3616
- *
3617
- * Licensed under the Apache License, Version 2.0 (the "License");
3618
- * you may not use this file except in compliance with the License.
3619
- * You may obtain a copy of the License at
3620
- *
3621
- * http://www.apache.org/licenses/LICENSE-2.0
3622
- *
3623
- * Unless required by applicable law or agreed to in writing, software
3624
- * distributed under the License is distributed on an "AS IS" BASIS,
3625
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3626
- * See the License for the specific language governing permissions and
3627
- * limitations under the License.
3628
- */
3629
- /**
3630
- * Class constructor for Data Table Card MDL component.
3631
- * Implements MDL component design pattern defined at:
3632
- * https://github.com/jasonmayes/mdl-component-design-pattern
3633
- *
3634
- * @constructor
3635
- * @param {Element} element The element that will be upgraded.
3636
- */
3637
- var MaterialDataTable = function MaterialDataTable(element) {
3638
- this.element_ = element;
3639
- // Initialize instance.
3640
- this.init();
3641
- };
3642
- window['MaterialDataTable'] = MaterialDataTable;
3643
- /**
3644
- * Store constants in one place so they can be updated easily.
3645
- *
3646
- * @enum {string | number}
3647
- * @private
3648
- */
3649
- MaterialDataTable.prototype.Constant_ = {};
3650
- /**
3651
- * Store strings for class names defined by this component that are used in
3652
- * JavaScript. This allows us to simply change it in one place should we
3653
- * decide to modify at a later date.
3654
- *
3655
- * @enum {string}
3656
- * @private
3657
- */
3658
- MaterialDataTable.prototype.CssClasses_ = {
3659
- DATA_TABLE: 'mdl-data-table',
3660
- SELECTABLE: 'mdl-data-table--selectable',
3661
- SELECT_ELEMENT: 'mdl-data-table__select',
3662
- IS_SELECTED: 'is-selected',
3663
- IS_UPGRADED: 'is-upgraded'
3664
- };
3665
- /**
3666
- * Generates and returns a function that toggles the selection state of a
3667
- * single row (or multiple rows).
3668
- *
3669
- * @param {Element} checkbox Checkbox that toggles the selection state.
3670
- * @param {Element} row Row to toggle when checkbox changes.
3671
- * @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes.
3672
- * @private
3673
- */
3674
- MaterialDataTable.prototype.selectRow_ = function (checkbox, row, opt_rows) {
3675
- if (row) {
3676
- return function () {
3677
- if (checkbox.checked) {
3678
- row.classList.add(this.CssClasses_.IS_SELECTED);
3679
- } else {
3680
- row.classList.remove(this.CssClasses_.IS_SELECTED);
3681
- }
3682
- }.bind(this);
3683
- }
3684
- if (opt_rows) {
3685
- return function () {
3686
- var i;
3687
- var el;
3688
- if (checkbox.checked) {
3689
- for (i = 0; i < opt_rows.length; i++) {
3690
- el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox');
3691
- el['MaterialCheckbox'].check();
3692
- opt_rows[i].classList.add(this.CssClasses_.IS_SELECTED);
3693
- }
3694
- } else {
3695
- for (i = 0; i < opt_rows.length; i++) {
3696
- el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox');
3697
- el['MaterialCheckbox'].uncheck();
3698
- opt_rows[i].classList.remove(this.CssClasses_.IS_SELECTED);
3699
- }
3700
- }
3701
- }.bind(this);
3702
- }
3703
- };
3704
- /**
3705
- * Creates a checkbox for a single or or multiple rows and hooks up the
3706
- * event handling.
3707
- *
3708
- * @param {Element} row Row to toggle when checkbox changes.
3709
- * @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes.
3710
- * @private
3711
- */
3712
- MaterialDataTable.prototype.createCheckbox_ = function (row, opt_rows) {
3713
- var label = document.createElement('label');
3714
- var labelClasses = [
3715
- 'mdl-checkbox',
3716
- 'mdl-js-checkbox',
3717
- 'mdl-js-ripple-effect',
3718
- this.CssClasses_.SELECT_ELEMENT
3719
- ];
3720
- label.className = labelClasses.join(' ');
3721
- var checkbox = document.createElement('input');
3722
- checkbox.type = 'checkbox';
3723
- checkbox.classList.add('mdl-checkbox__input');
3724
- if (row) {
3725
- checkbox.checked = row.classList.contains(this.CssClasses_.IS_SELECTED);
3726
- checkbox.addEventListener('change', this.selectRow_(checkbox, row));
3727
- } else if (opt_rows) {
3728
- checkbox.addEventListener('change', this.selectRow_(checkbox, null, opt_rows));
3729
- }
3730
- label.appendChild(checkbox);
3731
- componentHandler.upgradeElement(label, 'MaterialCheckbox');
3732
- return label;
3733
- };
3734
- /**
3735
- * Initialize element.
3736
- */
3737
- MaterialDataTable.prototype.init = function () {
3738
- if (this.element_) {
3739
- var firstHeader = this.element_.querySelector('th');
3740
- var bodyRows = Array.prototype.slice.call(this.element_.querySelectorAll('tbody tr'));
3741
- var footRows = Array.prototype.slice.call(this.element_.querySelectorAll('tfoot tr'));
3742
- var rows = bodyRows.concat(footRows);
3743
- if (this.element_.classList.contains(this.CssClasses_.SELECTABLE)) {
3744
- var th = document.createElement('th');
3745
- var headerCheckbox = this.createCheckbox_(null, rows);
3746
- th.appendChild(headerCheckbox);
3747
- firstHeader.parentElement.insertBefore(th, firstHeader);
3748
- for (var i = 0; i < rows.length; i++) {
3749
- var firstCell = rows[i].querySelector('td');
3750
- if (firstCell) {
3751
- var td = document.createElement('td');
3752
- if (rows[i].parentNode.nodeName.toUpperCase() === 'TBODY') {
3753
- var rowCheckbox = this.createCheckbox_(rows[i]);
3754
- td.appendChild(rowCheckbox);
3755
- }
3756
- rows[i].insertBefore(td, firstCell);
3757
- }
3758
- }
3759
- this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
3760
- }
3761
- }
3762
- };
3763
- // The component registers itself. It can assume componentHandler is available
3764
- // in the global scope.
3765
- componentHandler.register({
3766
- constructor: MaterialDataTable,
3767
- classAsString: 'MaterialDataTable',
3768
- cssClass: 'mdl-js-data-table'
3769
- });
3770
- /**
3771
- * @license
3772
- * Copyright 2015 Google Inc. All Rights Reserved.
3773
- *
3774
- * Licensed under the Apache License, Version 2.0 (the "License");
3775
- * you may not use this file except in compliance with the License.
3776
- * You may obtain a copy of the License at
3777
- *
3778
- * http://www.apache.org/licenses/LICENSE-2.0
3779
- *
3780
- * Unless required by applicable law or agreed to in writing, software
3781
- * distributed under the License is distributed on an "AS IS" BASIS,
3782
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3783
- * See the License for the specific language governing permissions and
3784
- * limitations under the License.
3785
- */
3786
- /**
3787
- * Class constructor for Ripple MDL component.
3788
- * Implements MDL component design pattern defined at:
3789
- * https://github.com/jasonmayes/mdl-component-design-pattern
3790
- *
3791
- * @constructor
3792
- * @param {HTMLElement} element The element that will be upgraded.
3793
- */
3794
- var MaterialRipple = function MaterialRipple(element) {
3795
- this.element_ = element;
3796
- // Initialize instance.
3797
- this.init();
3798
- };
3799
- window['MaterialRipple'] = MaterialRipple;
3800
- /**
3801
- * Store constants in one place so they can be updated easily.
3802
- *
3803
- * @enum {string | number}
3804
- * @private
3805
- */
3806
- MaterialRipple.prototype.Constant_ = {
3807
- INITIAL_SCALE: 'scale(0.0001, 0.0001)',
3808
- INITIAL_SIZE: '1px',
3809
- INITIAL_OPACITY: '0.4',
3810
- FINAL_OPACITY: '0',
3811
- FINAL_SCALE: ''
3812
- };
3813
- /**
3814
- * Store strings for class names defined by this component that are used in
3815
- * JavaScript. This allows us to simply change it in one place should we
3816
- * decide to modify at a later date.
3817
- *
3818
- * @enum {string}
3819
- * @private
3820
- */
3821
- MaterialRipple.prototype.CssClasses_ = {
3822
- RIPPLE_CENTER: 'mdl-ripple--center',
3823
- RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
3824
- RIPPLE: 'mdl-ripple',
3825
- IS_ANIMATING: 'is-animating',
3826
- IS_VISIBLE: 'is-visible'
3827
- };
3828
- /**
3829
- * Handle mouse / finger down on element.
3830
- *
3831
- * @param {Event} event The event that fired.
3832
- * @private
3833
- */
3834
- MaterialRipple.prototype.downHandler_ = function (event) {
3835
- if (!this.rippleElement_.style.width && !this.rippleElement_.style.height) {
3836
- var rect = this.element_.getBoundingClientRect();
3837
- this.boundHeight = rect.height;
3838
- this.boundWidth = rect.width;
3839
- this.rippleSize_ = Math.sqrt(rect.width * rect.width + rect.height * rect.height) * 2 + 2;
3840
- this.rippleElement_.style.width = this.rippleSize_ + 'px';
3841
- this.rippleElement_.style.height = this.rippleSize_ + 'px';
3842
- }
3843
- this.rippleElement_.classList.add(this.CssClasses_.IS_VISIBLE);
3844
- if (event.type === 'mousedown' && this.ignoringMouseDown_) {
3845
- this.ignoringMouseDown_ = false;
3846
- } else {
3847
- if (event.type === 'touchstart') {
3848
- this.ignoringMouseDown_ = true;
3849
- }
3850
- var frameCount = this.getFrameCount();
3851
- if (frameCount > 0) {
3852
- return;
3853
- }
3854
- this.setFrameCount(1);
3855
- var bound = event.currentTarget.getBoundingClientRect();
3856
- var x;
3857
- var y;
3858
- // Check if we are handling a keyboard click.
3859
- if (event.clientX === 0 && event.clientY === 0) {
3860
- x = Math.round(bound.width / 2);
3861
- y = Math.round(bound.height / 2);
3862
- } else {
3863
- var clientX = event.clientX !== undefined ? event.clientX : event.touches[0].clientX;
3864
- var clientY = event.clientY !== undefined ? event.clientY : event.touches[0].clientY;
3865
- x = Math.round(clientX - bound.left);
3866
- y = Math.round(clientY - bound.top);
3867
- }
3868
- this.setRippleXY(x, y);
3869
- this.setRippleStyles(true);
3870
- window.requestAnimationFrame(this.animFrameHandler.bind(this));
3871
- }
3872
- };
3873
- /**
3874
- * Handle mouse / finger up on element.
3875
- *
3876
- * @param {Event} event The event that fired.
3877
- * @private
3878
- */
3879
- MaterialRipple.prototype.upHandler_ = function (event) {
3880
- // Don't fire for the artificial "mouseup" generated by a double-click.
3881
- if (event && event.detail !== 2) {
3882
- // Allow a repaint to occur before removing this class, so the animation
3883
- // shows for tap events, which seem to trigger a mouseup too soon after
3884
- // mousedown.
3885
- window.setTimeout(function () {
3886
- this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE);
3887
- }.bind(this), 0);
3888
- }
3889
- };
3890
- /**
3891
- * Initialize element.
3892
- */
3893
- MaterialRipple.prototype.init = function () {
3894
- if (this.element_) {
3895
- var recentering = this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER);
3896
- if (!this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)) {
3897
- this.rippleElement_ = this.element_.querySelector('.' + this.CssClasses_.RIPPLE);
3898
- this.frameCount_ = 0;
3899
- this.rippleSize_ = 0;
3900
- this.x_ = 0;
3901
- this.y_ = 0;
3902
- // Touch start produces a compat mouse down event, which would cause a
3903
- // second ripples. To avoid that, we use this property to ignore the first
3904
- // mouse down after a touch start.
3905
- this.ignoringMouseDown_ = false;
3906
- this.boundDownHandler = this.downHandler_.bind(this);
3907
- this.element_.addEventListener('mousedown', this.boundDownHandler);
3908
- this.element_.addEventListener('touchstart', this.boundDownHandler);
3909
- this.boundUpHandler = this.upHandler_.bind(this);
3910
- this.element_.addEventListener('mouseup', this.boundUpHandler);
3911
- this.element_.addEventListener('mouseleave', this.boundUpHandler);
3912
- this.element_.addEventListener('touchend', this.boundUpHandler);
3913
- this.element_.addEventListener('blur', this.boundUpHandler);
3914
- /**
3915
- * Getter for frameCount_.
3916
- * @return {number} the frame count.
3917
- */
3918
- this.getFrameCount = function () {
3919
- return this.frameCount_;
3920
- };
3921
- /**
3922
- * Setter for frameCount_.
3923
- * @param {number} fC the frame count.
3924
- */
3925
- this.setFrameCount = function (fC) {
3926
- this.frameCount_ = fC;
3927
- };
3928
- /**
3929
- * Getter for rippleElement_.
3930
- * @return {Element} the ripple element.
3931
- */
3932
- this.getRippleElement = function () {
3933
- return this.rippleElement_;
3934
- };
3935
- /**
3936
- * Sets the ripple X and Y coordinates.
3937
- * @param {number} newX the new X coordinate
3938
- * @param {number} newY the new Y coordinate
3939
- */
3940
- this.setRippleXY = function (newX, newY) {
3941
- this.x_ = newX;
3942
- this.y_ = newY;
3943
- };
3944
- /**
3945
- * Sets the ripple styles.
3946
- * @param {boolean} start whether or not this is the start frame.
3947
- */
3948
- this.setRippleStyles = function (start) {
3949
- if (this.rippleElement_ !== null) {
3950
- var transformString;
3951
- var scale;
3952
- var size;
3953
- var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)';
3954
- if (start) {
3955
- scale = this.Constant_.INITIAL_SCALE;
3956
- size = this.Constant_.INITIAL_SIZE;
3957
- } else {
3958
- scale = this.Constant_.FINAL_SCALE;
3959
- size = this.rippleSize_ + 'px';
3960
- if (recentering) {
3961
- offset = 'translate(' + this.boundWidth / 2 + 'px, ' + this.boundHeight / 2 + 'px)';
3962
- }
3963
- }
3964
- transformString = 'translate(-50%, -50%) ' + offset + scale;
3965
- this.rippleElement_.style.webkitTransform = transformString;
3966
- this.rippleElement_.style.msTransform = transformString;
3967
- this.rippleElement_.style.transform = transformString;
3968
- if (start) {
3969
- this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING);
3970
- } else {
3971
- this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING);
3972
- }
3973
- }
3974
- };
3975
- /**
3976
- * Handles an animation frame.
3977
- */
3978
- this.animFrameHandler = function () {
3979
- if (this.frameCount_-- > 0) {
3980
- window.requestAnimationFrame(this.animFrameHandler.bind(this));
3981
- } else {
3982
- this.setRippleStyles(false);
3983
- }
3984
- };
3985
- }
3986
- }
3987
- };
3988
- // The component registers itself. It can assume componentHandler is available
3989
- // in the global scope.
3990
- componentHandler.register({
3991
- constructor: MaterialRipple,
3992
- classAsString: 'MaterialRipple',
3993
- cssClass: 'mdl-js-ripple-effect',
3994
- widget: false
3995
- });
3996
- }());