todo_rails 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/todo_rails/version.rb +1 -1
- data/vendor/assets/bower.json +8 -0
- data/vendor/assets/bower_components/angular-animate/README.md +68 -0
- data/vendor/assets/bower_components/angular-animate/angular-animate.js +3721 -0
- data/vendor/assets/bower_components/angular-animate/angular-animate.min.js +52 -0
- data/vendor/assets/bower_components/angular-animate/angular-animate.min.js.map +8 -0
- data/vendor/assets/bower_components/angular-animate/bower.json +9 -0
- data/vendor/assets/bower_components/angular-animate/index.js +2 -0
- data/vendor/assets/bower_components/angular-animate/package.json +26 -0
- data/vendor/assets/bower_components/angular-aria/README.md +67 -0
- data/vendor/assets/bower_components/angular-aria/angular-aria.js +393 -0
- data/vendor/assets/bower_components/angular-aria/angular-aria.min.js +13 -0
- data/vendor/assets/bower_components/angular-aria/angular-aria.min.js.map +8 -0
- data/vendor/assets/bower_components/angular-aria/bower.json +9 -0
- data/vendor/assets/bower_components/angular-aria/index.js +2 -0
- data/vendor/assets/bower_components/angular-aria/package.json +27 -0
- data/vendor/assets/bower_components/angular-material/CHANGELOG.md +1599 -0
- data/vendor/assets/bower_components/angular-material/LICENSE +21 -0
- data/vendor/assets/bower_components/angular-material/README.md +211 -0
- data/vendor/assets/bower_components/angular-material/angular-material-mocks.js +77 -0
- data/vendor/assets/bower_components/angular-material/angular-material.css +7183 -0
- data/vendor/assets/bower_components/angular-material/angular-material.js +15406 -0
- data/vendor/assets/bower_components/angular-material/angular-material.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/angular-material.min.js +14 -0
- data/vendor/assets/bower_components/angular-material/bower.json +14 -0
- data/vendor/assets/bower_components/angular-material/demos/bottomSheet/demoBasicUsage/img/icons/copy.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/bottomSheet/demoBasicUsage/img/icons/copy2.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/bottomSheet/demoBasicUsage/img/icons/facebook.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/bottomSheet/demoBasicUsage/img/icons/hangout.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/bottomSheet/demoBasicUsage/img/icons/mail.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/bottomSheet/demoBasicUsage/img/icons/message.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/bottomSheet/demoBasicUsage/img/icons/print.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/bottomSheet/demoBasicUsage/img/icons/share-arrow.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/bottomSheet/demoBasicUsage/img/icons/twitter.svg +2 -0
- data/vendor/assets/bower_components/angular-material/demos/bottomSheet/demoBasicUsage/img/icons/upload.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/chips/demoBasicUsage/style.scss +39 -0
- data/vendor/assets/bower_components/angular-material/demos/chips/demoContactChips/style.scss +47 -0
- data/vendor/assets/bower_components/angular-material/demos/gridList/demoBasicUsage/style.scss +75 -0
- data/vendor/assets/bower_components/angular-material/demos/gridList/demoDynamicTiles/style.scss +78 -0
- data/vendor/assets/bower_components/angular-material/demos/gridList/demoResponsiveUsage/style.scss +0 -0
- data/vendor/assets/bower_components/angular-material/demos/icon/demoLoadSvgIconsFromUrl/img/icons/addShoppingCart.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/icon/demoLoadSvgIconsFromUrl/img/icons/android.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/icon/demoLoadSvgIconsFromUrl/img/icons/cake.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/icon/demoSvgIconSets/assets/cake.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/icon/demoSvgIconSets/assets/core-icons.svg +26 -0
- data/vendor/assets/bower_components/angular-material/demos/icon/demoSvgIconSets/assets/social-icons.svg +26 -0
- data/vendor/assets/bower_components/angular-material/demos/icon/demoSvgIconsFromURL/img/icons/addShoppingCart.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/icon/demoSvgIconsFromURL/img/icons/android.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/icon/demoSvgIconsFromURL/img/icons/cake.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/icon/demoUsingTemplateCache/assets/android.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/icon/demoUsingTemplateCache/assets/cake.svg +1 -0
- data/vendor/assets/bower_components/angular-material/demos/icon/demoUsingTemplateCache/assets/core-icons.svg +26 -0
- data/vendor/assets/bower_components/angular-material/demos/input/demoIcons/icons/ic_email_24px.svg +4 -0
- data/vendor/assets/bower_components/angular-material/demos/input/demoIcons/icons/ic_person_24px.svg +4 -0
- data/vendor/assets/bower_components/angular-material/demos/input/demoIcons/icons/ic_phone_24px.svg +4 -0
- data/vendor/assets/bower_components/angular-material/demos/input/demoIcons/icons/ic_place_24px.svg +4 -0
- data/vendor/assets/bower_components/angular-material/demos/input/demoIcons/style.scss +18 -0
- data/vendor/assets/bower_components/angular-material/demos/list/demoListControls/img/100-0.jpeg +0 -0
- data/vendor/assets/bower_components/angular-material/demos/list/demoListControls/img/100-1.jpeg +0 -0
- data/vendor/assets/bower_components/angular-material/demos/list/demoListControls/img/100-2.jpeg +0 -0
- data/vendor/assets/bower_components/angular-material/demos/tabs/demoDynamicHeight/style.scss +13 -0
- data/vendor/assets/bower_components/angular-material/demos/tabs/demoDynamicTabs/style.scss +44 -0
- data/vendor/assets/bower_components/angular-material/demos/tabs/demoStaticTabs/style.scss +25 -0
- data/vendor/assets/bower_components/angular-material/demos/toolbar/demoBasicUsage/img/icons/favorite.svg +4 -0
- data/vendor/assets/bower_components/angular-material/demos/toolbar/demoBasicUsage/img/icons/menu.svg +4 -0
- data/vendor/assets/bower_components/angular-material/demos/toolbar/demoBasicUsage/img/icons/more_vert.svg +4 -0
- data/vendor/assets/bower_components/angular-material/index.js +12 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/autocomplete/autocomplete-default-theme.css +24 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/autocomplete/autocomplete.css +220 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/autocomplete/autocomplete.js +951 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/backdrop/backdrop-default-theme.css +9 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/backdrop/backdrop.css +59 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/backdrop/backdrop.js +38 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/bottomSheet/bottomSheet-default-theme.css +16 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/bottomSheet/bottomSheet.css +170 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/bottomSheet/bottomSheet.js +267 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/button/button-default-theme.css +94 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/button/button.css +158 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/button/button.js +135 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/card/card-default-theme.css +12 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/card/card.css +34 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/card/card.js +84 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/checkbox/checkbox-default-theme.css +47 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/checkbox/checkbox.css +124 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/checkbox/checkbox.js +166 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/chips/chips-default-theme.css +24 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/chips/chips.css +131 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/chips/chips.js +949 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/content/content-default-theme.css +9 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/content/content.css +20 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/content/content.js +84 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/core/core.css +2594 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/core/core.js +3772 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/core/default-theme.js +4 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/dialog/dialog-default-theme.css +12 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/dialog/dialog.css +111 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/dialog/dialog.js +713 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/divider/divider-default-theme.css +9 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/divider/divider.css +14 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/divider/divider.js +45 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/fabActions/fabActions.js +57 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/fabSpeedDial/fabSpeedDial.css +100 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/fabSpeedDial/fabSpeedDial.js +236 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/fabToolbar/fabToolbar.css +74 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/fabToolbar/fabToolbar.js +218 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/fabTrigger/fabTrigger.js +54 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/gridList/gridList-default-theme.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/gridList/gridList.css +68 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/gridList/gridList.js +762 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/icon/icon-default-theme.css +15 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/icon/icon.css +20 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/icon/icon.js +783 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/input/input-default-theme.css +46 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/input/input.css +162 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/input/input.js +371 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/list/list-default-theme.css +23 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/list/list.css +147 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/list/list.js +273 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/menu/menu-default-theme.css +11 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/menu/menu.css +121 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/menu/menu.js +620 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/progressCircular/progressCircular-default-theme.css +36 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/progressCircular/progressCircular.css +1409 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/progressCircular/progressCircular.js +109 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/progressLinear/progressLinear-default-theme.css +27 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/progressLinear/progressLinear.css +287 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/progressLinear/progressLinear.js +126 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/radioButton/radioButton-default-theme.css +47 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/radioButton/radioButton.css +91 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/radioButton/radioButton.js +312 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/select/select-default-theme.css +42 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/select/select.css +170 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/select/select.js +1055 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/sidenav/sidenav-default-theme.css +9 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/sidenav/sidenav.css +99 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/sidenav/sidenav.js +424 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/slider/slider-default-theme.css +56 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/slider/slider.css +220 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/slider/slider.js +403 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/sticky/sticky.css +21 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/sticky/sticky.js +315 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/subheader/subheader-default-theme.css +16 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/subheader/subheader.css +63 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/subheader/subheader.js +93 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/swipe/swipe.js +72 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/switch/switch-default-theme.css +33 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/switch/switch.css +110 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/switch/switch.js +169 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/tabs/tabs-arrow.svg +7 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/tabs/tabs-default-theme.css +82 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/tabs/tabs.css +274 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/tabs/tabs.js +1060 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/textField/textField-default-theme.css +30 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/textField/textField.css +111 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/textField/textField.js +145 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/toast/toast-default-theme.css +18 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/toast/toast.css +119 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/toast/toast.js +265 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/toolbar/toolbar-default-theme.css +20 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/toolbar/toolbar.css +83 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/toolbar/toolbar.js +169 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/tooltip/tooltip-default-theme.css +11 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/tooltip/tooltip.css +72 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/tooltip/tooltip.js +267 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/whiteframe/whiteframe.css +25 -0
- data/vendor/assets/bower_components/angular-material/modules/closure/whiteframe/whiteframe.js +15 -0
- data/vendor/assets/bower_components/angular-material/modules/css/angular-material-layout.css +2375 -0
- data/vendor/assets/bower_components/angular-material/modules/js/autocomplete/autocomplete-default-theme.css +24 -0
- data/vendor/assets/bower_components/angular-material/modules/js/autocomplete/autocomplete-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/autocomplete/autocomplete.css +220 -0
- data/vendor/assets/bower_components/angular-material/modules/js/autocomplete/autocomplete.js +951 -0
- data/vendor/assets/bower_components/angular-material/modules/js/autocomplete/autocomplete.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/autocomplete/autocomplete.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/autocomplete/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/backdrop/backdrop-default-theme.css +9 -0
- data/vendor/assets/bower_components/angular-material/modules/js/backdrop/backdrop-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/backdrop/backdrop.css +59 -0
- data/vendor/assets/bower_components/angular-material/modules/js/backdrop/backdrop.js +39 -0
- data/vendor/assets/bower_components/angular-material/modules/js/backdrop/backdrop.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/backdrop/backdrop.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/backdrop/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/bottomSheet/bottomSheet-default-theme.css +16 -0
- data/vendor/assets/bower_components/angular-material/modules/js/bottomSheet/bottomSheet-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/bottomSheet/bottomSheet.css +170 -0
- data/vendor/assets/bower_components/angular-material/modules/js/bottomSheet/bottomSheet.js +267 -0
- data/vendor/assets/bower_components/angular-material/modules/js/bottomSheet/bottomSheet.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/bottomSheet/bottomSheet.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/bottomSheet/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/button/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/button/button-default-theme.css +94 -0
- data/vendor/assets/bower_components/angular-material/modules/js/button/button-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/button/button.css +158 -0
- data/vendor/assets/bower_components/angular-material/modules/js/button/button.js +136 -0
- data/vendor/assets/bower_components/angular-material/modules/js/button/button.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/button/button.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/card/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/card/card-default-theme.css +12 -0
- data/vendor/assets/bower_components/angular-material/modules/js/card/card-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/card/card.css +34 -0
- data/vendor/assets/bower_components/angular-material/modules/js/card/card.js +85 -0
- data/vendor/assets/bower_components/angular-material/modules/js/card/card.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/card/card.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/checkbox/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/checkbox/checkbox-default-theme.css +47 -0
- data/vendor/assets/bower_components/angular-material/modules/js/checkbox/checkbox-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/checkbox/checkbox.css +124 -0
- data/vendor/assets/bower_components/angular-material/modules/js/checkbox/checkbox.js +167 -0
- data/vendor/assets/bower_components/angular-material/modules/js/checkbox/checkbox.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/checkbox/checkbox.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/chips/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/chips/chips-default-theme.css +24 -0
- data/vendor/assets/bower_components/angular-material/modules/js/chips/chips-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/chips/chips.css +131 -0
- data/vendor/assets/bower_components/angular-material/modules/js/chips/chips.js +949 -0
- data/vendor/assets/bower_components/angular-material/modules/js/chips/chips.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/chips/chips.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/content/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/content/content-default-theme.css +9 -0
- data/vendor/assets/bower_components/angular-material/modules/js/content/content-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/content/content.css +20 -0
- data/vendor/assets/bower_components/angular-material/modules/js/content/content.js +85 -0
- data/vendor/assets/bower_components/angular-material/modules/js/content/content.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/content/content.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/core/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/core/core.css +2594 -0
- data/vendor/assets/bower_components/angular-material/modules/js/core/core.js +3772 -0
- data/vendor/assets/bower_components/angular-material/modules/js/core/core.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/core/core.min.js +10 -0
- data/vendor/assets/bower_components/angular-material/modules/js/core/default-theme.js +4 -0
- data/vendor/assets/bower_components/angular-material/modules/js/dialog/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/dialog/dialog-default-theme.css +12 -0
- data/vendor/assets/bower_components/angular-material/modules/js/dialog/dialog-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/dialog/dialog.css +111 -0
- data/vendor/assets/bower_components/angular-material/modules/js/dialog/dialog.js +713 -0
- data/vendor/assets/bower_components/angular-material/modules/js/dialog/dialog.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/dialog/dialog.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/divider/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/divider/divider-default-theme.css +9 -0
- data/vendor/assets/bower_components/angular-material/modules/js/divider/divider-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/divider/divider.css +14 -0
- data/vendor/assets/bower_components/angular-material/modules/js/divider/divider.js +46 -0
- data/vendor/assets/bower_components/angular-material/modules/js/divider/divider.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/divider/divider.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabActions/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabActions/fabActions.js +58 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabActions/fabActions.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabSpeedDial/bower.json +9 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabSpeedDial/fabSpeedDial.css +100 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabSpeedDial/fabSpeedDial.js +235 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabSpeedDial/fabSpeedDial.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabSpeedDial/fabSpeedDial.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabToolbar/bower.json +9 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabToolbar/fabToolbar.css +74 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabToolbar/fabToolbar.js +217 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabToolbar/fabToolbar.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabToolbar/fabToolbar.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabTrigger/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabTrigger/fabTrigger.js +55 -0
- data/vendor/assets/bower_components/angular-material/modules/js/fabTrigger/fabTrigger.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/gridList/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/gridList/gridList.css +68 -0
- data/vendor/assets/bower_components/angular-material/modules/js/gridList/gridList.js +763 -0
- data/vendor/assets/bower_components/angular-material/modules/js/gridList/gridList.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/gridList/gridList.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/icon/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/icon/icon-default-theme.css +15 -0
- data/vendor/assets/bower_components/angular-material/modules/js/icon/icon-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/icon/icon.css +20 -0
- data/vendor/assets/bower_components/angular-material/modules/js/icon/icon.js +784 -0
- data/vendor/assets/bower_components/angular-material/modules/js/icon/icon.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/icon/icon.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/input/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/input/input-default-theme.css +46 -0
- data/vendor/assets/bower_components/angular-material/modules/js/input/input-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/input/input.css +162 -0
- data/vendor/assets/bower_components/angular-material/modules/js/input/input.js +372 -0
- data/vendor/assets/bower_components/angular-material/modules/js/input/input.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/input/input.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/list/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/list/list-default-theme.css +23 -0
- data/vendor/assets/bower_components/angular-material/modules/js/list/list-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/list/list.css +147 -0
- data/vendor/assets/bower_components/angular-material/modules/js/list/list.js +274 -0
- data/vendor/assets/bower_components/angular-material/modules/js/list/list.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/list/list.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/menu/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/menu/menu-default-theme.css +11 -0
- data/vendor/assets/bower_components/angular-material/modules/js/menu/menu-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/menu/menu.css +121 -0
- data/vendor/assets/bower_components/angular-material/modules/js/menu/menu.js +620 -0
- data/vendor/assets/bower_components/angular-material/modules/js/menu/menu.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/menu/menu.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressCircular/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressCircular/progressCircular-default-theme.css +36 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressCircular/progressCircular-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressCircular/progressCircular.css +1409 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressCircular/progressCircular.js +110 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressCircular/progressCircular.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressCircular/progressCircular.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressLinear/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressLinear/progressLinear-default-theme.css +27 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressLinear/progressLinear-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressLinear/progressLinear.css +287 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressLinear/progressLinear.js +127 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressLinear/progressLinear.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/progressLinear/progressLinear.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/radioButton/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/radioButton/radioButton-default-theme.css +47 -0
- data/vendor/assets/bower_components/angular-material/modules/js/radioButton/radioButton-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/radioButton/radioButton.css +91 -0
- data/vendor/assets/bower_components/angular-material/modules/js/radioButton/radioButton.js +313 -0
- data/vendor/assets/bower_components/angular-material/modules/js/radioButton/radioButton.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/radioButton/radioButton.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/select/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/select/select-default-theme.css +42 -0
- data/vendor/assets/bower_components/angular-material/modules/js/select/select-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/select/select.css +170 -0
- data/vendor/assets/bower_components/angular-material/modules/js/select/select.js +1055 -0
- data/vendor/assets/bower_components/angular-material/modules/js/select/select.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/select/select.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/sidenav/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/sidenav/sidenav-default-theme.css +9 -0
- data/vendor/assets/bower_components/angular-material/modules/js/sidenav/sidenav-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/sidenav/sidenav.css +99 -0
- data/vendor/assets/bower_components/angular-material/modules/js/sidenav/sidenav.js +424 -0
- data/vendor/assets/bower_components/angular-material/modules/js/sidenav/sidenav.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/sidenav/sidenav.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/slider/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/slider/slider-default-theme.css +56 -0
- data/vendor/assets/bower_components/angular-material/modules/js/slider/slider-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/slider/slider.css +220 -0
- data/vendor/assets/bower_components/angular-material/modules/js/slider/slider.js +404 -0
- data/vendor/assets/bower_components/angular-material/modules/js/slider/slider.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/slider/slider.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/sticky/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/sticky/sticky.css +21 -0
- data/vendor/assets/bower_components/angular-material/modules/js/sticky/sticky.js +315 -0
- data/vendor/assets/bower_components/angular-material/modules/js/sticky/sticky.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/sticky/sticky.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/subheader/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/subheader/subheader-default-theme.css +16 -0
- data/vendor/assets/bower_components/angular-material/modules/js/subheader/subheader-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/subheader/subheader.css +63 -0
- data/vendor/assets/bower_components/angular-material/modules/js/subheader/subheader.js +93 -0
- data/vendor/assets/bower_components/angular-material/modules/js/subheader/subheader.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/subheader/subheader.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/swipe/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/swipe/swipe.js +73 -0
- data/vendor/assets/bower_components/angular-material/modules/js/swipe/swipe.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/switch/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/switch/switch-default-theme.css +33 -0
- data/vendor/assets/bower_components/angular-material/modules/js/switch/switch-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/switch/switch.css +110 -0
- data/vendor/assets/bower_components/angular-material/modules/js/switch/switch.js +169 -0
- data/vendor/assets/bower_components/angular-material/modules/js/switch/switch.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/switch/switch.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tabs/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tabs/tabs-default-theme.css +82 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tabs/tabs-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tabs/tabs.css +274 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tabs/tabs.js +1060 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tabs/tabs.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tabs/tabs.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/textField/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/textField/textField-default-theme.css +30 -0
- data/vendor/assets/bower_components/angular-material/modules/js/textField/textField-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/textField/textField.css +111 -0
- data/vendor/assets/bower_components/angular-material/modules/js/textField/textField.js +143 -0
- data/vendor/assets/bower_components/angular-material/modules/js/textField/textField.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/textField/textField.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toast/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toast/toast-default-theme.css +18 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toast/toast-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toast/toast.css +119 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toast/toast.js +265 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toast/toast.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toast/toast.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toolbar/bower.json +8 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toolbar/toolbar-default-theme.css +20 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toolbar/toolbar-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toolbar/toolbar.css +83 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toolbar/toolbar.js +169 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toolbar/toolbar.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/toolbar/toolbar.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tooltip/bower.json +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tooltip/tooltip-default-theme.css +11 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tooltip/tooltip-default-theme.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tooltip/tooltip.css +72 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tooltip/tooltip.js +268 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tooltip/tooltip.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/tooltip/tooltip.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/modules/js/whiteframe/bower.json +5 -0
- data/vendor/assets/bower_components/angular-material/modules/js/whiteframe/whiteframe.css +25 -0
- data/vendor/assets/bower_components/angular-material/modules/js/whiteframe/whiteframe.js +16 -0
- data/vendor/assets/bower_components/angular-material/modules/js/whiteframe/whiteframe.min.css +6 -0
- data/vendor/assets/bower_components/angular-material/modules/js/whiteframe/whiteframe.min.js +7 -0
- data/vendor/assets/bower_components/angular-material/package.json +48 -0
- data/vendor/assets/bower_components/angular/README.md +64 -0
- data/vendor/assets/bower_components/angular/angular-csp.css +21 -0
- data/vendor/assets/bower_components/angular/angular.js +28364 -0
- data/vendor/assets/bower_components/angular/angular.min.js +290 -0
- data/vendor/assets/bower_components/angular/angular.min.js.gzip +0 -0
- data/vendor/assets/bower_components/angular/angular.min.js.map +8 -0
- data/vendor/assets/bower_components/angular/bower.json +8 -0
- data/vendor/assets/bower_components/angular/index.js +2 -0
- data/vendor/assets/bower_components/angular/package.json +25 -0
- data/vendor/assets/bower_components/lodash/LICENSE +22 -0
- data/vendor/assets/bower_components/lodash/bower.json +19 -0
- data/vendor/assets/bower_components/lodash/lodash.js +12351 -0
- data/vendor/assets/bower_components/lodash/lodash.min.js +99 -0
- data/vendor/assets/bower_components/restangular/CHANGELOG.md +18 -0
- data/vendor/assets/bower_components/restangular/CONTRIBUTE.md +31 -0
- data/vendor/assets/bower_components/restangular/Gruntfile.js +149 -0
- data/vendor/assets/bower_components/restangular/README.md +1336 -0
- data/vendor/assets/bower_components/restangular/bower.json +19 -0
- data/vendor/assets/bower_components/restangular/dist/restangular.js +1355 -0
- data/vendor/assets/bower_components/restangular/dist/restangular.min.js +6 -0
- data/vendor/assets/bower_components/restangular/dist/restangular.zip +0 -0
- data/vendor/assets/bower_components/restangular/karma.conf.js +74 -0
- data/vendor/assets/bower_components/restangular/karma.underscore.conf.js +74 -0
- data/vendor/assets/bower_components/restangular/license.md +21 -0
- data/vendor/assets/bower_components/restangular/package.json +55 -0
- data/vendor/assets/bower_components/restangular/src/restangular.js +1350 -0
- data/vendor/assets/bower_components/restangular/test/restangularSpec.js +1136 -0
- metadata +424 -1
@@ -0,0 +1,3772 @@
|
|
1
|
+
/*!
|
2
|
+
* Angular Material Design
|
3
|
+
* https://github.com/angular/material
|
4
|
+
* @license MIT
|
5
|
+
* v0.10.0
|
6
|
+
*/
|
7
|
+
goog.provide('ng.material.core');
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
/**
|
12
|
+
* Initialization function that validates environment
|
13
|
+
* requirements.
|
14
|
+
*/
|
15
|
+
angular
|
16
|
+
.module('material.core', [ 'material.core.gestures', 'material.core.theming' ])
|
17
|
+
.config( MdCoreConfigure );
|
18
|
+
|
19
|
+
|
20
|
+
function MdCoreConfigure($provide, $mdThemingProvider) {
|
21
|
+
|
22
|
+
$provide.decorator('$$rAF', ["$delegate", rAFDecorator]);
|
23
|
+
|
24
|
+
$mdThemingProvider.theme('default')
|
25
|
+
.primaryPalette('indigo')
|
26
|
+
.accentPalette('pink')
|
27
|
+
.warnPalette('red')
|
28
|
+
.backgroundPalette('grey');
|
29
|
+
}
|
30
|
+
MdCoreConfigure.$inject = ["$provide", "$mdThemingProvider"];
|
31
|
+
|
32
|
+
function rAFDecorator( $delegate ) {
|
33
|
+
/**
|
34
|
+
* Use this to throttle events that come in often.
|
35
|
+
* The throttled function will always use the *last* invocation before the
|
36
|
+
* coming frame.
|
37
|
+
*
|
38
|
+
* For example, window resize events that fire many times a second:
|
39
|
+
* If we set to use an raf-throttled callback on window resize, then
|
40
|
+
* our callback will only be fired once per frame, with the last resize
|
41
|
+
* event that happened before that frame.
|
42
|
+
*
|
43
|
+
* @param {function} callback function to debounce
|
44
|
+
*/
|
45
|
+
$delegate.throttle = function(cb) {
|
46
|
+
var queueArgs, alreadyQueued, queueCb, context;
|
47
|
+
return function debounced() {
|
48
|
+
queueArgs = arguments;
|
49
|
+
context = this;
|
50
|
+
queueCb = cb;
|
51
|
+
if (!alreadyQueued) {
|
52
|
+
alreadyQueued = true;
|
53
|
+
$delegate(function() {
|
54
|
+
queueCb.apply(context, queueArgs);
|
55
|
+
alreadyQueued = false;
|
56
|
+
});
|
57
|
+
}
|
58
|
+
};
|
59
|
+
};
|
60
|
+
return $delegate;
|
61
|
+
}
|
62
|
+
|
63
|
+
angular.module('material.core')
|
64
|
+
.factory('$mdConstant', MdConstantFactory);
|
65
|
+
|
66
|
+
function MdConstantFactory($$rAF, $sniffer) {
|
67
|
+
|
68
|
+
var webkit = /webkit/i.test($sniffer.vendorPrefix);
|
69
|
+
function vendorProperty(name) {
|
70
|
+
return webkit ? ('webkit' + name.charAt(0).toUpperCase() + name.substring(1)) : name;
|
71
|
+
}
|
72
|
+
|
73
|
+
return {
|
74
|
+
KEY_CODE: {
|
75
|
+
ENTER: 13,
|
76
|
+
ESCAPE: 27,
|
77
|
+
SPACE: 32,
|
78
|
+
LEFT_ARROW : 37,
|
79
|
+
UP_ARROW : 38,
|
80
|
+
RIGHT_ARROW : 39,
|
81
|
+
DOWN_ARROW : 40,
|
82
|
+
TAB : 9,
|
83
|
+
BACKSPACE: 8,
|
84
|
+
DELETE: 46
|
85
|
+
},
|
86
|
+
CSS: {
|
87
|
+
/* Constants */
|
88
|
+
TRANSITIONEND: 'transitionend' + (webkit ? ' webkitTransitionEnd' : ''),
|
89
|
+
ANIMATIONEND: 'animationend' + (webkit ? ' webkitAnimationEnd' : ''),
|
90
|
+
|
91
|
+
TRANSFORM: vendorProperty('transform'),
|
92
|
+
TRANSFORM_ORIGIN: vendorProperty('transformOrigin'),
|
93
|
+
TRANSITION: vendorProperty('transition'),
|
94
|
+
TRANSITION_DURATION: vendorProperty('transitionDuration'),
|
95
|
+
ANIMATION_PLAY_STATE: vendorProperty('animationPlayState'),
|
96
|
+
ANIMATION_DURATION: vendorProperty('animationDuration'),
|
97
|
+
ANIMATION_NAME: vendorProperty('animationName'),
|
98
|
+
ANIMATION_TIMING: vendorProperty('animationTimingFunction'),
|
99
|
+
ANIMATION_DIRECTION: vendorProperty('animationDirection')
|
100
|
+
},
|
101
|
+
MEDIA: {
|
102
|
+
'sm': '(max-width: 600px)',
|
103
|
+
'gt-sm': '(min-width: 600px)',
|
104
|
+
'md': '(min-width: 600px) and (max-width: 960px)',
|
105
|
+
'gt-md': '(min-width: 960px)',
|
106
|
+
'lg': '(min-width: 960px) and (max-width: 1200px)',
|
107
|
+
'gt-lg': '(min-width: 1200px)'
|
108
|
+
},
|
109
|
+
MEDIA_PRIORITY: [
|
110
|
+
'gt-lg',
|
111
|
+
'lg',
|
112
|
+
'gt-md',
|
113
|
+
'md',
|
114
|
+
'gt-sm',
|
115
|
+
'sm'
|
116
|
+
]
|
117
|
+
};
|
118
|
+
}
|
119
|
+
MdConstantFactory.$inject = ["$$rAF", "$sniffer"];
|
120
|
+
|
121
|
+
angular
|
122
|
+
.module('material.core')
|
123
|
+
.config( ["$provide", function($provide){
|
124
|
+
$provide.decorator('$mdUtil', ['$delegate', function ($delegate){
|
125
|
+
/**
|
126
|
+
* Inject the iterator facade to easily support iteration and accessors
|
127
|
+
* @see iterator below
|
128
|
+
*/
|
129
|
+
$delegate.iterator = MdIterator;
|
130
|
+
|
131
|
+
return $delegate;
|
132
|
+
}
|
133
|
+
]);
|
134
|
+
}]);
|
135
|
+
|
136
|
+
/**
|
137
|
+
* iterator is a list facade to easily support iteration and accessors
|
138
|
+
*
|
139
|
+
* @param items Array list which this iterator will enumerate
|
140
|
+
* @param reloop Boolean enables iterator to consider the list as an endless reloop
|
141
|
+
*/
|
142
|
+
function MdIterator(items, reloop) {
|
143
|
+
var trueFn = function() { return true; };
|
144
|
+
|
145
|
+
if (items && !angular.isArray(items)) {
|
146
|
+
items = Array.prototype.slice.call(items);
|
147
|
+
}
|
148
|
+
|
149
|
+
reloop = !!reloop;
|
150
|
+
var _items = items || [ ];
|
151
|
+
|
152
|
+
// Published API
|
153
|
+
return {
|
154
|
+
items: getItems,
|
155
|
+
count: count,
|
156
|
+
|
157
|
+
inRange: inRange,
|
158
|
+
contains: contains,
|
159
|
+
indexOf: indexOf,
|
160
|
+
itemAt: itemAt,
|
161
|
+
|
162
|
+
findBy: findBy,
|
163
|
+
|
164
|
+
add: add,
|
165
|
+
remove: remove,
|
166
|
+
|
167
|
+
first: first,
|
168
|
+
last: last,
|
169
|
+
next: angular.bind(null, findSubsequentItem, false),
|
170
|
+
previous: angular.bind(null, findSubsequentItem, true),
|
171
|
+
|
172
|
+
hasPrevious: hasPrevious,
|
173
|
+
hasNext: hasNext
|
174
|
+
|
175
|
+
};
|
176
|
+
|
177
|
+
/**
|
178
|
+
* Publish copy of the enumerable set
|
179
|
+
* @returns {Array|*}
|
180
|
+
*/
|
181
|
+
function getItems() {
|
182
|
+
return [].concat(_items);
|
183
|
+
}
|
184
|
+
|
185
|
+
/**
|
186
|
+
* Determine length of the list
|
187
|
+
* @returns {Array.length|*|number}
|
188
|
+
*/
|
189
|
+
function count() {
|
190
|
+
return _items.length;
|
191
|
+
}
|
192
|
+
|
193
|
+
/**
|
194
|
+
* Is the index specified valid
|
195
|
+
* @param index
|
196
|
+
* @returns {Array.length|*|number|boolean}
|
197
|
+
*/
|
198
|
+
function inRange(index) {
|
199
|
+
return _items.length && ( index > -1 ) && (index < _items.length );
|
200
|
+
}
|
201
|
+
|
202
|
+
/**
|
203
|
+
* Can the iterator proceed to the next item in the list; relative to
|
204
|
+
* the specified item.
|
205
|
+
*
|
206
|
+
* @param item
|
207
|
+
* @returns {Array.length|*|number|boolean}
|
208
|
+
*/
|
209
|
+
function hasNext(item) {
|
210
|
+
return item ? inRange(indexOf(item) + 1) : false;
|
211
|
+
}
|
212
|
+
|
213
|
+
/**
|
214
|
+
* Can the iterator proceed to the previous item in the list; relative to
|
215
|
+
* the specified item.
|
216
|
+
*
|
217
|
+
* @param item
|
218
|
+
* @returns {Array.length|*|number|boolean}
|
219
|
+
*/
|
220
|
+
function hasPrevious(item) {
|
221
|
+
return item ? inRange(indexOf(item) - 1) : false;
|
222
|
+
}
|
223
|
+
|
224
|
+
/**
|
225
|
+
* Get item at specified index/position
|
226
|
+
* @param index
|
227
|
+
* @returns {*}
|
228
|
+
*/
|
229
|
+
function itemAt(index) {
|
230
|
+
return inRange(index) ? _items[index] : null;
|
231
|
+
}
|
232
|
+
|
233
|
+
/**
|
234
|
+
* Find all elements matching the key/value pair
|
235
|
+
* otherwise return null
|
236
|
+
*
|
237
|
+
* @param val
|
238
|
+
* @param key
|
239
|
+
*
|
240
|
+
* @return array
|
241
|
+
*/
|
242
|
+
function findBy(key, val) {
|
243
|
+
return _items.filter(function(item) {
|
244
|
+
return item[key] === val;
|
245
|
+
});
|
246
|
+
}
|
247
|
+
|
248
|
+
/**
|
249
|
+
* Add item to list
|
250
|
+
* @param item
|
251
|
+
* @param index
|
252
|
+
* @returns {*}
|
253
|
+
*/
|
254
|
+
function add(item, index) {
|
255
|
+
if ( !item ) return -1;
|
256
|
+
|
257
|
+
if (!angular.isNumber(index)) {
|
258
|
+
index = _items.length;
|
259
|
+
}
|
260
|
+
|
261
|
+
_items.splice(index, 0, item);
|
262
|
+
|
263
|
+
return indexOf(item);
|
264
|
+
}
|
265
|
+
|
266
|
+
/**
|
267
|
+
* Remove item from list...
|
268
|
+
* @param item
|
269
|
+
*/
|
270
|
+
function remove(item) {
|
271
|
+
if ( contains(item) ){
|
272
|
+
_items.splice(indexOf(item), 1);
|
273
|
+
}
|
274
|
+
}
|
275
|
+
|
276
|
+
/**
|
277
|
+
* Get the zero-based index of the target item
|
278
|
+
* @param item
|
279
|
+
* @returns {*}
|
280
|
+
*/
|
281
|
+
function indexOf(item) {
|
282
|
+
return _items.indexOf(item);
|
283
|
+
}
|
284
|
+
|
285
|
+
/**
|
286
|
+
* Boolean existence check
|
287
|
+
* @param item
|
288
|
+
* @returns {boolean}
|
289
|
+
*/
|
290
|
+
function contains(item) {
|
291
|
+
return item && (indexOf(item) > -1);
|
292
|
+
}
|
293
|
+
|
294
|
+
/**
|
295
|
+
* Return first item in the list
|
296
|
+
* @returns {*}
|
297
|
+
*/
|
298
|
+
function first() {
|
299
|
+
return _items.length ? _items[0] : null;
|
300
|
+
}
|
301
|
+
|
302
|
+
/**
|
303
|
+
* Return last item in the list...
|
304
|
+
* @returns {*}
|
305
|
+
*/
|
306
|
+
function last() {
|
307
|
+
return _items.length ? _items[_items.length - 1] : null;
|
308
|
+
}
|
309
|
+
|
310
|
+
/**
|
311
|
+
* Find the next item. If reloop is true and at the end of the list, it will go back to the
|
312
|
+
* first item. If given, the `validate` callback will be used to determine whether the next item
|
313
|
+
* is valid. If not valid, it will try to find the next item again.
|
314
|
+
*
|
315
|
+
* @param {boolean} backwards Specifies the direction of searching (forwards/backwards)
|
316
|
+
* @param {*} item The item whose subsequent item we are looking for
|
317
|
+
* @param {Function=} validate The `validate` function
|
318
|
+
* @param {integer=} limit The recursion limit
|
319
|
+
*
|
320
|
+
* @returns {*} The subsequent item or null
|
321
|
+
*/
|
322
|
+
function findSubsequentItem(backwards, item, validate, limit) {
|
323
|
+
validate = validate || trueFn;
|
324
|
+
|
325
|
+
var curIndex = indexOf(item);
|
326
|
+
while (true) {
|
327
|
+
if (!inRange(curIndex)) return null;
|
328
|
+
|
329
|
+
var nextIndex = curIndex + (backwards ? -1 : 1);
|
330
|
+
var foundItem = null;
|
331
|
+
if (inRange(nextIndex)) {
|
332
|
+
foundItem = _items[nextIndex];
|
333
|
+
} else if (reloop) {
|
334
|
+
foundItem = backwards ? last() : first();
|
335
|
+
nextIndex = indexOf(foundItem);
|
336
|
+
}
|
337
|
+
|
338
|
+
if ((foundItem === null) || (nextIndex === limit)) return null;
|
339
|
+
if (validate(foundItem)) return foundItem;
|
340
|
+
|
341
|
+
if (angular.isUndefined(limit)) limit = nextIndex;
|
342
|
+
|
343
|
+
curIndex = nextIndex;
|
344
|
+
}
|
345
|
+
}
|
346
|
+
}
|
347
|
+
|
348
|
+
|
349
|
+
angular.module('material.core')
|
350
|
+
.factory('$mdMedia', mdMediaFactory);
|
351
|
+
|
352
|
+
/**
|
353
|
+
* @ngdoc service
|
354
|
+
* @name $mdMedia
|
355
|
+
* @module material.core
|
356
|
+
*
|
357
|
+
* @description
|
358
|
+
* `$mdMedia` is used to evaluate whether a given media query is true or false given the
|
359
|
+
* current device's screen / window size. The media query will be re-evaluated on resize, allowing
|
360
|
+
* you to register a watch.
|
361
|
+
*
|
362
|
+
* `$mdMedia` also has pre-programmed support for media queries that match the layout breakpoints.
|
363
|
+
* (`sm`, `gt-sm`, `md`, `gt-md`, `lg`, `gt-lg`).
|
364
|
+
*
|
365
|
+
* @returns {boolean} a boolean representing whether or not the given media query is true or false.
|
366
|
+
*
|
367
|
+
* @usage
|
368
|
+
* <hljs lang="js">
|
369
|
+
* app.controller('MyController', function($mdMedia, $scope) {
|
370
|
+
* $scope.$watch(function() { return $mdMedia('lg'); }, function(big) {
|
371
|
+
* $scope.bigScreen = big;
|
372
|
+
* });
|
373
|
+
*
|
374
|
+
* $scope.screenIsSmall = $mdMedia('sm');
|
375
|
+
* $scope.customQuery = $mdMedia('(min-width: 1234px)');
|
376
|
+
* $scope.anotherCustom = $mdMedia('max-width: 300px');
|
377
|
+
* });
|
378
|
+
* </hljs>
|
379
|
+
*/
|
380
|
+
|
381
|
+
function mdMediaFactory($mdConstant, $rootScope, $window) {
|
382
|
+
var queries = {};
|
383
|
+
var mqls = {};
|
384
|
+
var results = {};
|
385
|
+
var normalizeCache = {};
|
386
|
+
|
387
|
+
$mdMedia.getResponsiveAttribute = getResponsiveAttribute;
|
388
|
+
$mdMedia.getQuery = getQuery;
|
389
|
+
$mdMedia.watchResponsiveAttributes = watchResponsiveAttributes;
|
390
|
+
|
391
|
+
return $mdMedia;
|
392
|
+
|
393
|
+
function $mdMedia(query) {
|
394
|
+
var validated = queries[query];
|
395
|
+
if (angular.isUndefined(validated)) {
|
396
|
+
validated = queries[query] = validate(query);
|
397
|
+
}
|
398
|
+
|
399
|
+
var result = results[validated];
|
400
|
+
if (angular.isUndefined(result)) {
|
401
|
+
result = add(validated);
|
402
|
+
}
|
403
|
+
|
404
|
+
return result;
|
405
|
+
}
|
406
|
+
|
407
|
+
function validate(query) {
|
408
|
+
return $mdConstant.MEDIA[query] ||
|
409
|
+
((query.charAt(0) !== '(') ? ('(' + query + ')') : query);
|
410
|
+
}
|
411
|
+
|
412
|
+
function add(query) {
|
413
|
+
var result = mqls[query] = $window.matchMedia(query);
|
414
|
+
result.addListener(onQueryChange);
|
415
|
+
return (results[result.media] = !!result.matches);
|
416
|
+
}
|
417
|
+
|
418
|
+
function onQueryChange(query) {
|
419
|
+
$rootScope.$evalAsync(function() {
|
420
|
+
results[query.media] = !!query.matches;
|
421
|
+
});
|
422
|
+
}
|
423
|
+
|
424
|
+
function getQuery(name) {
|
425
|
+
return mqls[name];
|
426
|
+
}
|
427
|
+
|
428
|
+
function getResponsiveAttribute(attrs, attrName) {
|
429
|
+
for (var i = 0; i < $mdConstant.MEDIA_PRIORITY.length; i++) {
|
430
|
+
var mediaName = $mdConstant.MEDIA_PRIORITY[i];
|
431
|
+
if (!mqls[queries[mediaName]].matches) {
|
432
|
+
continue;
|
433
|
+
}
|
434
|
+
|
435
|
+
var normalizedName = getNormalizedName(attrs, attrName + '-' + mediaName);
|
436
|
+
if (attrs[normalizedName]) {
|
437
|
+
return attrs[normalizedName];
|
438
|
+
}
|
439
|
+
}
|
440
|
+
|
441
|
+
// fallback on unprefixed
|
442
|
+
return attrs[getNormalizedName(attrs, attrName)];
|
443
|
+
}
|
444
|
+
|
445
|
+
function watchResponsiveAttributes(attrNames, attrs, watchFn) {
|
446
|
+
var unwatchFns = [];
|
447
|
+
attrNames.forEach(function(attrName) {
|
448
|
+
var normalizedName = getNormalizedName(attrs, attrName);
|
449
|
+
if (attrs[normalizedName]) {
|
450
|
+
unwatchFns.push(
|
451
|
+
attrs.$observe(normalizedName, angular.bind(void 0, watchFn, null)));
|
452
|
+
}
|
453
|
+
|
454
|
+
for (var mediaName in $mdConstant.MEDIA) {
|
455
|
+
normalizedName = getNormalizedName(attrs, attrName + '-' + mediaName);
|
456
|
+
if (!attrs[normalizedName]) {
|
457
|
+
return;
|
458
|
+
}
|
459
|
+
|
460
|
+
unwatchFns.push(attrs.$observe(normalizedName, angular.bind(void 0, watchFn, mediaName)));
|
461
|
+
}
|
462
|
+
});
|
463
|
+
|
464
|
+
return function unwatch() {
|
465
|
+
unwatchFns.forEach(function(fn) { fn(); })
|
466
|
+
};
|
467
|
+
}
|
468
|
+
|
469
|
+
// Improves performance dramatically
|
470
|
+
function getNormalizedName(attrs, attrName) {
|
471
|
+
return normalizeCache[attrName] ||
|
472
|
+
(normalizeCache[attrName] = attrs.$normalize(attrName));
|
473
|
+
}
|
474
|
+
}
|
475
|
+
mdMediaFactory.$inject = ["$mdConstant", "$rootScope", "$window"];
|
476
|
+
|
477
|
+
/*
|
478
|
+
* This var has to be outside the angular factory, otherwise when
|
479
|
+
* there are multiple material apps on the same page, each app
|
480
|
+
* will create its own instance of this array and the app's IDs
|
481
|
+
* will not be unique.
|
482
|
+
*/
|
483
|
+
var nextUniqueId = 0;
|
484
|
+
|
485
|
+
angular.module('material.core')
|
486
|
+
.factory('$mdUtil', ["$cacheFactory", "$document", "$timeout", "$q", "$window", "$mdConstant", function($cacheFactory, $document, $timeout, $q, $window, $mdConstant) {
|
487
|
+
var Util;
|
488
|
+
|
489
|
+
function getNode(el) {
|
490
|
+
return el[0] || el;
|
491
|
+
}
|
492
|
+
|
493
|
+
return Util = {
|
494
|
+
now: window.performance ?
|
495
|
+
angular.bind(window.performance, window.performance.now) :
|
496
|
+
Date.now,
|
497
|
+
|
498
|
+
clientRect: function(element, offsetParent, isOffsetRect) {
|
499
|
+
var node = getNode(element);
|
500
|
+
offsetParent = getNode(offsetParent || node.offsetParent || document.body);
|
501
|
+
var nodeRect = node.getBoundingClientRect();
|
502
|
+
|
503
|
+
// The user can ask for an offsetRect: a rect relative to the offsetParent,
|
504
|
+
// or a clientRect: a rect relative to the page
|
505
|
+
var offsetRect = isOffsetRect ?
|
506
|
+
offsetParent.getBoundingClientRect() :
|
507
|
+
{ left: 0, top: 0, width: 0, height: 0 };
|
508
|
+
return {
|
509
|
+
left: nodeRect.left - offsetRect.left,
|
510
|
+
top: nodeRect.top - offsetRect.top,
|
511
|
+
width: nodeRect.width,
|
512
|
+
height: nodeRect.height
|
513
|
+
};
|
514
|
+
},
|
515
|
+
offsetRect: function(element, offsetParent) {
|
516
|
+
return Util.clientRect(element, offsetParent, true);
|
517
|
+
},
|
518
|
+
|
519
|
+
// Annoying method to copy nodes to an array, thanks to IE
|
520
|
+
nodesToArray: function (nodes) {
|
521
|
+
var results = [];
|
522
|
+
for (var i = 0; i < nodes.length; ++i) {
|
523
|
+
results.push(nodes.item(i));
|
524
|
+
}
|
525
|
+
return results;
|
526
|
+
},
|
527
|
+
|
528
|
+
// Disables scroll around the passed element.
|
529
|
+
disableScrollAround: function(element) {
|
530
|
+
if (Util.disableScrollAround._enableScrolling) return Util.disableScrollAround._enableScrolling;
|
531
|
+
element = angular.element(element);
|
532
|
+
var body = $document[0].body,
|
533
|
+
restoreBody = disableBodyScroll(),
|
534
|
+
restoreElement = disableElementScroll();
|
535
|
+
|
536
|
+
return Util.disableScrollAround._enableScrolling = function () {
|
537
|
+
restoreBody();
|
538
|
+
restoreElement();
|
539
|
+
delete Util.disableScrollAround._enableScrolling;
|
540
|
+
};
|
541
|
+
|
542
|
+
// Creates a virtual scrolling mask to absorb touchmove, keyboard, scrollbar clicking, and wheel events
|
543
|
+
function disableElementScroll() {
|
544
|
+
var zIndex = $window.getComputedStyle(element[0]).zIndex - 1;
|
545
|
+
if (isNaN(zIndex)) zIndex = 99;
|
546
|
+
var scrollMask = angular.element(
|
547
|
+
'<div class="md-scroll-mask" style="z-index: ' + zIndex + '">' +
|
548
|
+
' <div class="md-scroll-mask-bar"></div>' +
|
549
|
+
'</div>');
|
550
|
+
body.appendChild(scrollMask[0]);
|
551
|
+
|
552
|
+
scrollMask.on('wheel', preventDefault);
|
553
|
+
scrollMask.on('touchmove', preventDefault);
|
554
|
+
$document.on('keydown', disableKeyNav);
|
555
|
+
|
556
|
+
return function restoreScroll () {
|
557
|
+
scrollMask.off('wheel');
|
558
|
+
scrollMask.off('touchmove');
|
559
|
+
scrollMask[0].parentNode.removeChild(scrollMask[0]);
|
560
|
+
$document.off('keydown', disableKeyNav);
|
561
|
+
delete Util.disableScrollAround._enableScrolling;
|
562
|
+
};
|
563
|
+
|
564
|
+
// Prevent keypresses from elements inside the body
|
565
|
+
// used to stop the keypresses that could cause the page to scroll
|
566
|
+
// (arrow keys, spacebar, tab, etc).
|
567
|
+
function disableKeyNav(e) {
|
568
|
+
//-- temporarily removed this logic, will possibly re-add at a later date
|
569
|
+
return;
|
570
|
+
if (!element[0].contains(e.target)) {
|
571
|
+
e.preventDefault();
|
572
|
+
e.stopImmediatePropagation();
|
573
|
+
}
|
574
|
+
}
|
575
|
+
|
576
|
+
function preventDefault(e) {
|
577
|
+
e.preventDefault();
|
578
|
+
}
|
579
|
+
}
|
580
|
+
|
581
|
+
// Converts the body to a position fixed block and translate it to the proper scroll
|
582
|
+
// position
|
583
|
+
function disableBodyScroll() {
|
584
|
+
var restoreStyle = body.getAttribute('style') || '';
|
585
|
+
var scrollOffset = body.scrollTop + body.parentElement.scrollTop;
|
586
|
+
|
587
|
+
applyStyles(body, {
|
588
|
+
position: 'fixed',
|
589
|
+
width: '100%',
|
590
|
+
overflowY: 'scroll',
|
591
|
+
top: -scrollOffset + 'px'
|
592
|
+
});
|
593
|
+
|
594
|
+
return function restoreScroll() {
|
595
|
+
body.setAttribute('style', restoreStyle);
|
596
|
+
body.scrollTop = scrollOffset;
|
597
|
+
};
|
598
|
+
}
|
599
|
+
|
600
|
+
function applyStyles (el, styles) {
|
601
|
+
for (var key in styles) {
|
602
|
+
el.style[key] = styles[key];
|
603
|
+
}
|
604
|
+
}
|
605
|
+
},
|
606
|
+
enableScrolling: function () {
|
607
|
+
var method = this.disableScrollAround._enableScrolling;
|
608
|
+
method && method();
|
609
|
+
},
|
610
|
+
floatingScrollbars: function() {
|
611
|
+
if (this.floatingScrollbars.cached === undefined) {
|
612
|
+
var tempNode = angular.element('<div style="width: 100%; z-index: -1; position: absolute; height: 35px; overflow-y: scroll"><div style="height: 60;"></div></div>');
|
613
|
+
$document[0].body.appendChild(tempNode[0]);
|
614
|
+
this.floatingScrollbars.cached = (tempNode[0].offsetWidth == tempNode[0].childNodes[0].offsetWidth);
|
615
|
+
tempNode.remove();
|
616
|
+
}
|
617
|
+
return this.floatingScrollbars.cached;
|
618
|
+
},
|
619
|
+
|
620
|
+
// Mobile safari only allows you to set focus in click event listeners...
|
621
|
+
forceFocus: function(element) {
|
622
|
+
var node = element[0] || element;
|
623
|
+
|
624
|
+
document.addEventListener('click', function focusOnClick(ev) {
|
625
|
+
if (ev.target === node && ev.$focus) {
|
626
|
+
node.focus();
|
627
|
+
ev.stopImmediatePropagation();
|
628
|
+
ev.preventDefault();
|
629
|
+
node.removeEventListener('click', focusOnClick);
|
630
|
+
}
|
631
|
+
}, true);
|
632
|
+
|
633
|
+
var newEvent = document.createEvent('MouseEvents');
|
634
|
+
newEvent.initMouseEvent('click', false, true, window, {}, 0, 0, 0, 0,
|
635
|
+
false, false, false, false, 0, null);
|
636
|
+
newEvent.$material = true;
|
637
|
+
newEvent.$focus = true;
|
638
|
+
node.dispatchEvent(newEvent);
|
639
|
+
},
|
640
|
+
|
641
|
+
transitionEndPromise: function(element, opts) {
|
642
|
+
opts = opts || {};
|
643
|
+
var deferred = $q.defer();
|
644
|
+
element.on($mdConstant.CSS.TRANSITIONEND, finished);
|
645
|
+
function finished(ev) {
|
646
|
+
// Make sure this transitionend didn't bubble up from a child
|
647
|
+
if (!ev || ev.target === element[0]) {
|
648
|
+
element.off($mdConstant.CSS.TRANSITIONEND, finished);
|
649
|
+
deferred.resolve();
|
650
|
+
}
|
651
|
+
}
|
652
|
+
if (opts.timeout) $timeout(finished, opts.timeout);
|
653
|
+
return deferred.promise;
|
654
|
+
},
|
655
|
+
|
656
|
+
fakeNgModel: function() {
|
657
|
+
return {
|
658
|
+
$fake: true,
|
659
|
+
$setTouched: angular.noop,
|
660
|
+
$setViewValue: function(value) {
|
661
|
+
this.$viewValue = value;
|
662
|
+
this.$render(value);
|
663
|
+
this.$viewChangeListeners.forEach(function(cb) { cb(); });
|
664
|
+
},
|
665
|
+
$isEmpty: function(value) {
|
666
|
+
return ('' + value).length === 0;
|
667
|
+
},
|
668
|
+
$parsers: [],
|
669
|
+
$formatters: [],
|
670
|
+
$viewChangeListeners: [],
|
671
|
+
$render: angular.noop
|
672
|
+
};
|
673
|
+
},
|
674
|
+
|
675
|
+
// Returns a function, that, as long as it continues to be invoked, will not
|
676
|
+
// be triggered. The function will be called after it stops being called for
|
677
|
+
// N milliseconds.
|
678
|
+
// @param wait Integer value of msecs to delay (since last debounce reset); default value 10 msecs
|
679
|
+
// @param invokeApply should the $timeout trigger $digest() dirty checking
|
680
|
+
debounce: function (func, wait, scope, invokeApply) {
|
681
|
+
var timer;
|
682
|
+
|
683
|
+
return function debounced() {
|
684
|
+
var context = scope,
|
685
|
+
args = Array.prototype.slice.call(arguments);
|
686
|
+
|
687
|
+
$timeout.cancel(timer);
|
688
|
+
timer = $timeout(function() {
|
689
|
+
|
690
|
+
timer = undefined;
|
691
|
+
func.apply(context, args);
|
692
|
+
|
693
|
+
}, wait || 10, invokeApply );
|
694
|
+
};
|
695
|
+
},
|
696
|
+
|
697
|
+
// Returns a function that can only be triggered every `delay` milliseconds.
|
698
|
+
// In other words, the function will not be called unless it has been more
|
699
|
+
// than `delay` milliseconds since the last call.
|
700
|
+
throttle: function throttle(func, delay) {
|
701
|
+
var recent;
|
702
|
+
return function throttled() {
|
703
|
+
var context = this;
|
704
|
+
var args = arguments;
|
705
|
+
var now = Util.now();
|
706
|
+
|
707
|
+
if (!recent || (now - recent > delay)) {
|
708
|
+
func.apply(context, args);
|
709
|
+
recent = now;
|
710
|
+
}
|
711
|
+
};
|
712
|
+
},
|
713
|
+
|
714
|
+
/**
|
715
|
+
* Measures the number of milliseconds taken to run the provided callback
|
716
|
+
* function. Uses a high-precision timer if available.
|
717
|
+
*/
|
718
|
+
time: function time(cb) {
|
719
|
+
var start = Util.now();
|
720
|
+
cb();
|
721
|
+
return Util.now() - start;
|
722
|
+
},
|
723
|
+
|
724
|
+
/**
|
725
|
+
* Get a unique ID.
|
726
|
+
*
|
727
|
+
* @returns {string} an unique numeric string
|
728
|
+
*/
|
729
|
+
nextUid: function() {
|
730
|
+
return '' + nextUniqueId++;
|
731
|
+
},
|
732
|
+
|
733
|
+
// Stop watchers and events from firing on a scope without destroying it,
|
734
|
+
// by disconnecting it from its parent and its siblings' linked lists.
|
735
|
+
disconnectScope: function disconnectScope(scope) {
|
736
|
+
if (!scope) return;
|
737
|
+
|
738
|
+
// we can't destroy the root scope or a scope that has been already destroyed
|
739
|
+
if (scope.$root === scope) return;
|
740
|
+
if (scope.$$destroyed ) return;
|
741
|
+
|
742
|
+
var parent = scope.$parent;
|
743
|
+
scope.$$disconnected = true;
|
744
|
+
|
745
|
+
// See Scope.$destroy
|
746
|
+
if (parent.$$childHead === scope) parent.$$childHead = scope.$$nextSibling;
|
747
|
+
if (parent.$$childTail === scope) parent.$$childTail = scope.$$prevSibling;
|
748
|
+
if (scope.$$prevSibling) scope.$$prevSibling.$$nextSibling = scope.$$nextSibling;
|
749
|
+
if (scope.$$nextSibling) scope.$$nextSibling.$$prevSibling = scope.$$prevSibling;
|
750
|
+
|
751
|
+
scope.$$nextSibling = scope.$$prevSibling = null;
|
752
|
+
|
753
|
+
},
|
754
|
+
|
755
|
+
// Undo the effects of disconnectScope above.
|
756
|
+
reconnectScope: function reconnectScope(scope) {
|
757
|
+
if (!scope) return;
|
758
|
+
|
759
|
+
// we can't disconnect the root node or scope already disconnected
|
760
|
+
if (scope.$root === scope) return;
|
761
|
+
if (!scope.$$disconnected) return;
|
762
|
+
|
763
|
+
var child = scope;
|
764
|
+
|
765
|
+
var parent = child.$parent;
|
766
|
+
child.$$disconnected = false;
|
767
|
+
// See Scope.$new for this logic...
|
768
|
+
child.$$prevSibling = parent.$$childTail;
|
769
|
+
if (parent.$$childHead) {
|
770
|
+
parent.$$childTail.$$nextSibling = child;
|
771
|
+
parent.$$childTail = child;
|
772
|
+
} else {
|
773
|
+
parent.$$childHead = parent.$$childTail = child;
|
774
|
+
}
|
775
|
+
},
|
776
|
+
|
777
|
+
/*
|
778
|
+
* getClosest replicates jQuery.closest() to walk up the DOM tree until it finds a matching nodeName
|
779
|
+
*
|
780
|
+
* @param el Element to start walking the DOM from
|
781
|
+
* @param tagName Tag name to find closest to el, such as 'form'
|
782
|
+
*/
|
783
|
+
getClosest: function getClosest(el, tagName, onlyParent) {
|
784
|
+
if (el instanceof angular.element) el = el[0];
|
785
|
+
tagName = tagName.toUpperCase();
|
786
|
+
if (onlyParent) el = el.parentNode;
|
787
|
+
if (!el) return null;
|
788
|
+
do {
|
789
|
+
if (el.nodeName === tagName) {
|
790
|
+
return el;
|
791
|
+
}
|
792
|
+
} while (el = el.parentNode);
|
793
|
+
return null;
|
794
|
+
},
|
795
|
+
|
796
|
+
/**
|
797
|
+
* Functional equivalent for $element.filter(‘md-bottom-sheet’)
|
798
|
+
* useful with interimElements where the element and its container are important...
|
799
|
+
*/
|
800
|
+
extractElementByName: function (element, nodeName) {
|
801
|
+
for (var i = 0, len = element.length; i < len; i++) {
|
802
|
+
if (element[i].nodeName.toLowerCase() === nodeName){
|
803
|
+
return angular.element(element[i]);
|
804
|
+
}
|
805
|
+
}
|
806
|
+
return element;
|
807
|
+
},
|
808
|
+
|
809
|
+
/**
|
810
|
+
* Give optional properties with no value a boolean true by default
|
811
|
+
*/
|
812
|
+
initOptionalProperties: function (scope, attr, defaults ) {
|
813
|
+
defaults = defaults || { };
|
814
|
+
angular.forEach(scope.$$isolateBindings, function (binding, key) {
|
815
|
+
if (binding.optional && angular.isUndefined(scope[key])) {
|
816
|
+
var hasKey = attr.hasOwnProperty(attr.$normalize(binding.attrName));
|
817
|
+
|
818
|
+
scope[key] = angular.isDefined(defaults[key]) ? defaults[key] : hasKey;
|
819
|
+
}
|
820
|
+
});
|
821
|
+
}
|
822
|
+
|
823
|
+
};
|
824
|
+
|
825
|
+
}]);
|
826
|
+
|
827
|
+
/*
|
828
|
+
* Since removing jQuery from the demos, some code that uses `element.focus()` is broken.
|
829
|
+
*
|
830
|
+
* We need to add `element.focus()`, because it's testable unlike `element[0].focus`.
|
831
|
+
*
|
832
|
+
* TODO(ajoslin): This should be added in a better place later.
|
833
|
+
*/
|
834
|
+
|
835
|
+
angular.element.prototype.focus = angular.element.prototype.focus || function() {
|
836
|
+
if (this.length) {
|
837
|
+
this[0].focus();
|
838
|
+
}
|
839
|
+
return this;
|
840
|
+
};
|
841
|
+
angular.element.prototype.blur = angular.element.prototype.blur || function() {
|
842
|
+
if (this.length) {
|
843
|
+
this[0].blur();
|
844
|
+
}
|
845
|
+
return this;
|
846
|
+
};
|
847
|
+
|
848
|
+
|
849
|
+
angular.module('material.core')
|
850
|
+
.service('$mdAria', AriaService);
|
851
|
+
|
852
|
+
/*
|
853
|
+
* ngInject
|
854
|
+
*/
|
855
|
+
function AriaService($$rAF, $log, $window) {
|
856
|
+
|
857
|
+
return {
|
858
|
+
expect: expect,
|
859
|
+
expectAsync: expectAsync,
|
860
|
+
expectWithText: expectWithText
|
861
|
+
};
|
862
|
+
|
863
|
+
/**
|
864
|
+
* Check if expected attribute has been specified on the target element or child
|
865
|
+
* @param element
|
866
|
+
* @param attrName
|
867
|
+
* @param {optional} defaultValue What to set the attr to if no value is found
|
868
|
+
*/
|
869
|
+
function expect(element, attrName, defaultValue) {
|
870
|
+
var node = element[0] || element;
|
871
|
+
|
872
|
+
// if node exists and neither it nor its children have the attribute
|
873
|
+
if (node &&
|
874
|
+
((!node.hasAttribute(attrName) ||
|
875
|
+
node.getAttribute(attrName).length === 0) &&
|
876
|
+
!childHasAttribute(node, attrName))) {
|
877
|
+
|
878
|
+
defaultValue = angular.isString(defaultValue) ? defaultValue.trim() : '';
|
879
|
+
if (defaultValue.length) {
|
880
|
+
element.attr(attrName, defaultValue);
|
881
|
+
} else {
|
882
|
+
$log.warn('ARIA: Attribute "', attrName, '", required for accessibility, is missing on node:', node);
|
883
|
+
}
|
884
|
+
|
885
|
+
}
|
886
|
+
}
|
887
|
+
|
888
|
+
function expectAsync(element, attrName, defaultValueGetter) {
|
889
|
+
// Problem: when retrieving the element's contents synchronously to find the label,
|
890
|
+
// the text may not be defined yet in the case of a binding.
|
891
|
+
// There is a higher chance that a binding will be defined if we wait one frame.
|
892
|
+
$$rAF(function() {
|
893
|
+
expect(element, attrName, defaultValueGetter());
|
894
|
+
});
|
895
|
+
}
|
896
|
+
|
897
|
+
function expectWithText(element, attrName) {
|
898
|
+
expectAsync(element, attrName, function() {
|
899
|
+
return getText(element);
|
900
|
+
});
|
901
|
+
}
|
902
|
+
|
903
|
+
function getText(element) {
|
904
|
+
return element.text().trim();
|
905
|
+
}
|
906
|
+
|
907
|
+
function childHasAttribute(node, attrName) {
|
908
|
+
var hasChildren = node.hasChildNodes(),
|
909
|
+
hasAttr = false;
|
910
|
+
|
911
|
+
function isHidden(el) {
|
912
|
+
var style = el.currentStyle ? el.currentStyle : $window.getComputedStyle(el);
|
913
|
+
return (style.display === 'none');
|
914
|
+
}
|
915
|
+
|
916
|
+
if(hasChildren) {
|
917
|
+
var children = node.childNodes;
|
918
|
+
for(var i=0; i<children.length; i++){
|
919
|
+
var child = children[i];
|
920
|
+
if(child.nodeType === 1 && child.hasAttribute(attrName)) {
|
921
|
+
if(!isHidden(child)){
|
922
|
+
hasAttr = true;
|
923
|
+
}
|
924
|
+
}
|
925
|
+
}
|
926
|
+
}
|
927
|
+
return hasAttr;
|
928
|
+
}
|
929
|
+
}
|
930
|
+
AriaService.$inject = ["$$rAF", "$log", "$window"];
|
931
|
+
|
932
|
+
angular.module('material.core')
|
933
|
+
.service('$mdCompiler', mdCompilerService);
|
934
|
+
|
935
|
+
function mdCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {
|
936
|
+
/* jshint validthis: true */
|
937
|
+
|
938
|
+
/*
|
939
|
+
* @ngdoc service
|
940
|
+
* @name $mdCompiler
|
941
|
+
* @module material.core
|
942
|
+
* @description
|
943
|
+
* The $mdCompiler service is an abstraction of angular's compiler, that allows the developer
|
944
|
+
* to easily compile an element with a templateUrl, controller, and locals.
|
945
|
+
*
|
946
|
+
* @usage
|
947
|
+
* <hljs lang="js">
|
948
|
+
* $mdCompiler.compile({
|
949
|
+
* templateUrl: 'modal.html',
|
950
|
+
* controller: 'ModalCtrl',
|
951
|
+
* locals: {
|
952
|
+
* modal: myModalInstance;
|
953
|
+
* }
|
954
|
+
* }).then(function(compileData) {
|
955
|
+
* compileData.element; // modal.html's template in an element
|
956
|
+
* compileData.link(myScope); //attach controller & scope to element
|
957
|
+
* });
|
958
|
+
* </hljs>
|
959
|
+
*/
|
960
|
+
|
961
|
+
/*
|
962
|
+
* @ngdoc method
|
963
|
+
* @name $mdCompiler#compile
|
964
|
+
* @description A helper to compile an HTML template/templateUrl with a given controller,
|
965
|
+
* locals, and scope.
|
966
|
+
* @param {object} options An options object, with the following properties:
|
967
|
+
*
|
968
|
+
* - `controller` - `{(string=|function()=}` Controller fn that should be associated with
|
969
|
+
* newly created scope or the name of a registered controller if passed as a string.
|
970
|
+
* - `controllerAs` - `{string=}` A controller alias name. If present the controller will be
|
971
|
+
* published to scope under the `controllerAs` name.
|
972
|
+
* - `template` - `{string=}` An html template as a string.
|
973
|
+
* - `templateUrl` - `{string=}` A path to an html template.
|
974
|
+
* - `transformTemplate` - `{function(template)=}` A function which transforms the template after
|
975
|
+
* it is loaded. It will be given the template string as a parameter, and should
|
976
|
+
* return a a new string representing the transformed template.
|
977
|
+
* - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
|
978
|
+
* be injected into the controller. If any of these dependencies are promises, the compiler
|
979
|
+
* will wait for them all to be resolved, or if one is rejected before the controller is
|
980
|
+
* instantiated `compile()` will fail..
|
981
|
+
* * `key` - `{string}`: a name of a dependency to be injected into the controller.
|
982
|
+
* * `factory` - `{string|function}`: If `string` then it is an alias for a service.
|
983
|
+
* Otherwise if function, then it is injected and the return value is treated as the
|
984
|
+
* dependency. If the result is a promise, it is resolved before its value is
|
985
|
+
* injected into the controller.
|
986
|
+
*
|
987
|
+
* @returns {object=} promise A promise, which will be resolved with a `compileData` object.
|
988
|
+
* `compileData` has the following properties:
|
989
|
+
*
|
990
|
+
* - `element` - `{element}`: an uncompiled element matching the provided template.
|
991
|
+
* - `link` - `{function(scope)}`: A link function, which, when called, will compile
|
992
|
+
* the element and instantiate the provided controller (if given).
|
993
|
+
* - `locals` - `{object}`: The locals which will be passed into the controller once `link` is
|
994
|
+
* called. If `bindToController` is true, they will be coppied to the ctrl instead
|
995
|
+
* - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.
|
996
|
+
*/
|
997
|
+
this.compile = function(options) {
|
998
|
+
var templateUrl = options.templateUrl;
|
999
|
+
var template = options.template || '';
|
1000
|
+
var controller = options.controller;
|
1001
|
+
var controllerAs = options.controllerAs;
|
1002
|
+
var resolve = options.resolve || {};
|
1003
|
+
var locals = options.locals || {};
|
1004
|
+
var transformTemplate = options.transformTemplate || angular.identity;
|
1005
|
+
var bindToController = options.bindToController;
|
1006
|
+
|
1007
|
+
// Take resolve values and invoke them.
|
1008
|
+
// Resolves can either be a string (value: 'MyRegisteredAngularConst'),
|
1009
|
+
// or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})
|
1010
|
+
angular.forEach(resolve, function(value, key) {
|
1011
|
+
if (angular.isString(value)) {
|
1012
|
+
resolve[key] = $injector.get(value);
|
1013
|
+
} else {
|
1014
|
+
resolve[key] = $injector.invoke(value);
|
1015
|
+
}
|
1016
|
+
});
|
1017
|
+
//Add the locals, which are just straight values to inject
|
1018
|
+
//eg locals: { three: 3 }, will inject three into the controller
|
1019
|
+
angular.extend(resolve, locals);
|
1020
|
+
|
1021
|
+
if (templateUrl) {
|
1022
|
+
resolve.$template = $http.get(templateUrl, {cache: $templateCache})
|
1023
|
+
.then(function(response) {
|
1024
|
+
return response.data;
|
1025
|
+
});
|
1026
|
+
} else {
|
1027
|
+
resolve.$template = $q.when(template);
|
1028
|
+
}
|
1029
|
+
|
1030
|
+
// Wait for all the resolves to finish if they are promises
|
1031
|
+
return $q.all(resolve).then(function(locals) {
|
1032
|
+
|
1033
|
+
var template = transformTemplate(locals.$template);
|
1034
|
+
var element = options.element || angular.element('<div>').html(template.trim()).contents();
|
1035
|
+
var linkFn = $compile(element);
|
1036
|
+
|
1037
|
+
//Return a linking function that can be used later when the element is ready
|
1038
|
+
return {
|
1039
|
+
locals: locals,
|
1040
|
+
element: element,
|
1041
|
+
link: function link(scope) {
|
1042
|
+
locals.$scope = scope;
|
1043
|
+
|
1044
|
+
//Instantiate controller if it exists, because we have scope
|
1045
|
+
if (controller) {
|
1046
|
+
var invokeCtrl = $controller(controller, locals, true);
|
1047
|
+
if (bindToController) {
|
1048
|
+
angular.extend(invokeCtrl.instance, locals);
|
1049
|
+
}
|
1050
|
+
var ctrl = invokeCtrl();
|
1051
|
+
//See angular-route source for this logic
|
1052
|
+
element.data('$ngControllerController', ctrl);
|
1053
|
+
element.children().data('$ngControllerController', ctrl);
|
1054
|
+
|
1055
|
+
if (controllerAs) {
|
1056
|
+
scope[controllerAs] = ctrl;
|
1057
|
+
}
|
1058
|
+
}
|
1059
|
+
return linkFn(scope);
|
1060
|
+
}
|
1061
|
+
};
|
1062
|
+
});
|
1063
|
+
|
1064
|
+
};
|
1065
|
+
}
|
1066
|
+
mdCompilerService.$inject = ["$q", "$http", "$injector", "$compile", "$controller", "$templateCache"];
|
1067
|
+
|
1068
|
+
var HANDLERS = {};
|
1069
|
+
/* The state of the current 'pointer'
|
1070
|
+
* The pointer represents the state of the current touch.
|
1071
|
+
* It contains normalized x and y coordinates from DOM events,
|
1072
|
+
* as well as other information abstracted from the DOM.
|
1073
|
+
*/
|
1074
|
+
var pointer, lastPointer, forceSkipClickHijack = false;
|
1075
|
+
|
1076
|
+
// Used to attach event listeners once when multiple ng-apps are running.
|
1077
|
+
var isInitialized = false;
|
1078
|
+
|
1079
|
+
angular
|
1080
|
+
.module('material.core.gestures', [ ])
|
1081
|
+
.provider('$mdGesture', MdGestureProvider)
|
1082
|
+
.factory('$$MdGestureHandler', MdGestureHandler)
|
1083
|
+
.run( attachToDocument );
|
1084
|
+
|
1085
|
+
/**
|
1086
|
+
* @ngdoc service
|
1087
|
+
* @name $mdGestureProvider
|
1088
|
+
* @module material.core.gestures
|
1089
|
+
*
|
1090
|
+
* @description
|
1091
|
+
* In some scenarios on Mobile devices (without jQuery), the click events should NOT be hijacked.
|
1092
|
+
* `$mdGestureProvider` is used to configure the Gesture module to ignore or skip click hijacking on mobile
|
1093
|
+
* devices.
|
1094
|
+
*
|
1095
|
+
* <hljs lang="js">
|
1096
|
+
* app.config(function($mdGestureProvider) {
|
1097
|
+
*
|
1098
|
+
* // For mobile devices without jQuery loaded, do not
|
1099
|
+
* // intercept click events during the capture phase.
|
1100
|
+
* $mdGestureProvider.skipClickHijack();
|
1101
|
+
*
|
1102
|
+
* });
|
1103
|
+
* </hljs>
|
1104
|
+
*
|
1105
|
+
*/
|
1106
|
+
function MdGestureProvider() { }
|
1107
|
+
|
1108
|
+
MdGestureProvider.prototype = {
|
1109
|
+
|
1110
|
+
// Publish access to setter to configure a variable BEFORE the
|
1111
|
+
// $mdGesture service is instantiated...
|
1112
|
+
skipClickHijack: function() {
|
1113
|
+
return forceSkipClickHijack = true;
|
1114
|
+
},
|
1115
|
+
|
1116
|
+
/**
|
1117
|
+
* $get is used to build an instance of $mdGesture
|
1118
|
+
* ngInject
|
1119
|
+
*/
|
1120
|
+
$get : ["$$MdGestureHandler", "$$rAF", "$timeout", function($$MdGestureHandler, $$rAF, $timeout) {
|
1121
|
+
return new MdGesture($$MdGestureHandler, $$rAF, $timeout);
|
1122
|
+
}]
|
1123
|
+
};
|
1124
|
+
|
1125
|
+
|
1126
|
+
|
1127
|
+
/**
|
1128
|
+
* MdGesture factory construction function
|
1129
|
+
* ngInject
|
1130
|
+
*/
|
1131
|
+
function MdGesture($$MdGestureHandler, $$rAF, $timeout) {
|
1132
|
+
var userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
1133
|
+
var isIos = userAgent.match(/ipad|iphone|ipod/i);
|
1134
|
+
var isAndroid = userAgent.match(/android/i);
|
1135
|
+
var hasJQuery = (typeof window.jQuery !== 'undefined') && (angular.element === window.jQuery);
|
1136
|
+
|
1137
|
+
var self = {
|
1138
|
+
handler: addHandler,
|
1139
|
+
register: register,
|
1140
|
+
// On mobile w/out jQuery, we normally intercept clicks. Should we skip that?
|
1141
|
+
isHijackingClicks: (isIos || isAndroid) && !hasJQuery && !forceSkipClickHijack
|
1142
|
+
};
|
1143
|
+
|
1144
|
+
if (self.isHijackingClicks) {
|
1145
|
+
self.handler('click', {
|
1146
|
+
options: {
|
1147
|
+
maxDistance: 6
|
1148
|
+
},
|
1149
|
+
onEnd: function (ev, pointer) {
|
1150
|
+
if (pointer.distance < this.state.options.maxDistance) {
|
1151
|
+
this.dispatchEvent(ev, 'click');
|
1152
|
+
}
|
1153
|
+
}
|
1154
|
+
});
|
1155
|
+
}
|
1156
|
+
|
1157
|
+
/*
|
1158
|
+
* Register an element to listen for a handler.
|
1159
|
+
* This allows an element to override the default options for a handler.
|
1160
|
+
* Additionally, some handlers like drag and hold only dispatch events if
|
1161
|
+
* the domEvent happens inside an element that's registered to listen for these events.
|
1162
|
+
*
|
1163
|
+
* @see GestureHandler for how overriding of default options works.
|
1164
|
+
* @example $mdGesture.register(myElement, 'drag', { minDistance: 20, horziontal: false })
|
1165
|
+
*/
|
1166
|
+
function register(element, handlerName, options) {
|
1167
|
+
var handler = HANDLERS[handlerName.replace(/^\$md./, '')];
|
1168
|
+
if (!handler) {
|
1169
|
+
throw new Error('Failed to register element with handler ' + handlerName + '. ' +
|
1170
|
+
'Available handlers: ' + Object.keys(HANDLERS).join(', '));
|
1171
|
+
}
|
1172
|
+
return handler.registerElement(element, options);
|
1173
|
+
}
|
1174
|
+
|
1175
|
+
/*
|
1176
|
+
* add a handler to $mdGesture. see below.
|
1177
|
+
*/
|
1178
|
+
function addHandler(name, definition) {
|
1179
|
+
var handler = new $$MdGestureHandler(name);
|
1180
|
+
angular.extend(handler, definition);
|
1181
|
+
HANDLERS[name] = handler;
|
1182
|
+
|
1183
|
+
return self;
|
1184
|
+
}
|
1185
|
+
|
1186
|
+
/*
|
1187
|
+
* Register handlers. These listen to touch/start/move events, interpret them,
|
1188
|
+
* and dispatch gesture events depending on options & conditions. These are all
|
1189
|
+
* instances of GestureHandler.
|
1190
|
+
* @see GestureHandler
|
1191
|
+
*/
|
1192
|
+
return self
|
1193
|
+
/*
|
1194
|
+
* The press handler dispatches an event on touchdown/touchend.
|
1195
|
+
* It's a simple abstraction of touch/mouse/pointer start and end.
|
1196
|
+
*/
|
1197
|
+
.handler('press', {
|
1198
|
+
onStart: function (ev, pointer) {
|
1199
|
+
this.dispatchEvent(ev, '$md.pressdown');
|
1200
|
+
},
|
1201
|
+
onEnd: function (ev, pointer) {
|
1202
|
+
this.dispatchEvent(ev, '$md.pressup');
|
1203
|
+
}
|
1204
|
+
})
|
1205
|
+
|
1206
|
+
/*
|
1207
|
+
* The hold handler dispatches an event if the user keeps their finger within
|
1208
|
+
* the same <maxDistance> area for <delay> ms.
|
1209
|
+
* The hold handler will only run if a parent of the touch target is registered
|
1210
|
+
* to listen for hold events through $mdGesture.register()
|
1211
|
+
*/
|
1212
|
+
.handler('hold', {
|
1213
|
+
options: {
|
1214
|
+
maxDistance: 6,
|
1215
|
+
delay: 500
|
1216
|
+
},
|
1217
|
+
onCancel: function () {
|
1218
|
+
$timeout.cancel(this.state.timeout);
|
1219
|
+
},
|
1220
|
+
onStart: function (ev, pointer) {
|
1221
|
+
// For hold, require a parent to be registered with $mdGesture.register()
|
1222
|
+
// Because we prevent scroll events, this is necessary.
|
1223
|
+
if (!this.state.registeredParent) return this.cancel();
|
1224
|
+
|
1225
|
+
this.state.pos = {x: pointer.x, y: pointer.y};
|
1226
|
+
this.state.timeout = $timeout(angular.bind(this, function holdDelayFn() {
|
1227
|
+
this.dispatchEvent(ev, '$md.hold');
|
1228
|
+
this.cancel(); //we're done!
|
1229
|
+
}), this.state.options.delay, false);
|
1230
|
+
},
|
1231
|
+
onMove: function (ev, pointer) {
|
1232
|
+
// Don't scroll while waiting for hold.
|
1233
|
+
// If we don't preventDefault touchmove events here, Android will assume we don't
|
1234
|
+
// want to listen to anymore touch events. It will start scrolling and stop sending
|
1235
|
+
// touchmove events.
|
1236
|
+
ev.preventDefault();
|
1237
|
+
|
1238
|
+
// If the user moves greater than <maxDistance> pixels, stop the hold timer
|
1239
|
+
// set in onStart
|
1240
|
+
var dx = this.state.pos.x - pointer.x;
|
1241
|
+
var dy = this.state.pos.y - pointer.y;
|
1242
|
+
if (Math.sqrt(dx * dx + dy * dy) > this.options.maxDistance) {
|
1243
|
+
this.cancel();
|
1244
|
+
}
|
1245
|
+
},
|
1246
|
+
onEnd: function () {
|
1247
|
+
this.onCancel();
|
1248
|
+
}
|
1249
|
+
})
|
1250
|
+
|
1251
|
+
/*
|
1252
|
+
* The drag handler dispatches a drag event if the user holds and moves his finger greater than
|
1253
|
+
* <minDistance> px in the x or y direction, depending on options.horizontal.
|
1254
|
+
* The drag will be cancelled if the user moves his finger greater than <minDistance>*<cancelMultiplier> in
|
1255
|
+
* the perpindicular direction. Eg if the drag is horizontal and the user moves his finger <minDistance>*<cancelMultiplier>
|
1256
|
+
* pixels vertically, this handler won't consider the move part of a drag.
|
1257
|
+
*/
|
1258
|
+
.handler('drag', {
|
1259
|
+
options: {
|
1260
|
+
minDistance: 6,
|
1261
|
+
horizontal: true,
|
1262
|
+
cancelMultiplier: 1.5
|
1263
|
+
},
|
1264
|
+
onStart: function (ev) {
|
1265
|
+
// For drag, require a parent to be registered with $mdGesture.register()
|
1266
|
+
if (!this.state.registeredParent) this.cancel();
|
1267
|
+
},
|
1268
|
+
onMove: function (ev, pointer) {
|
1269
|
+
var shouldStartDrag, shouldCancel;
|
1270
|
+
// Don't scroll while deciding if this touchmove qualifies as a drag event.
|
1271
|
+
// If we don't preventDefault touchmove events here, Android will assume we don't
|
1272
|
+
// want to listen to anymore touch events. It will start scrolling and stop sending
|
1273
|
+
// touchmove events.
|
1274
|
+
ev.preventDefault();
|
1275
|
+
|
1276
|
+
if (!this.state.dragPointer) {
|
1277
|
+
if (this.state.options.horizontal) {
|
1278
|
+
shouldStartDrag = Math.abs(pointer.distanceX) > this.state.options.minDistance;
|
1279
|
+
shouldCancel = Math.abs(pointer.distanceY) > this.state.options.minDistance * this.state.options.cancelMultiplier;
|
1280
|
+
} else {
|
1281
|
+
shouldStartDrag = Math.abs(pointer.distanceY) > this.state.options.minDistance;
|
1282
|
+
shouldCancel = Math.abs(pointer.distanceX) > this.state.options.minDistance * this.state.options.cancelMultiplier;
|
1283
|
+
}
|
1284
|
+
|
1285
|
+
if (shouldStartDrag) {
|
1286
|
+
// Create a new pointer representing this drag, starting at this point where the drag started.
|
1287
|
+
this.state.dragPointer = makeStartPointer(ev);
|
1288
|
+
updatePointerState(ev, this.state.dragPointer);
|
1289
|
+
this.dispatchEvent(ev, '$md.dragstart', this.state.dragPointer);
|
1290
|
+
|
1291
|
+
} else if (shouldCancel) {
|
1292
|
+
this.cancel();
|
1293
|
+
}
|
1294
|
+
} else {
|
1295
|
+
this.dispatchDragMove(ev);
|
1296
|
+
}
|
1297
|
+
},
|
1298
|
+
// Only dispatch dragmove events every frame; any more is unnecessray
|
1299
|
+
dispatchDragMove: $$rAF.throttle(function (ev) {
|
1300
|
+
// Make sure the drag didn't stop while waiting for the next frame
|
1301
|
+
if (this.state.isRunning) {
|
1302
|
+
updatePointerState(ev, this.state.dragPointer);
|
1303
|
+
this.dispatchEvent(ev, '$md.drag', this.state.dragPointer);
|
1304
|
+
}
|
1305
|
+
}),
|
1306
|
+
onEnd: function (ev, pointer) {
|
1307
|
+
if (this.state.dragPointer) {
|
1308
|
+
updatePointerState(ev, this.state.dragPointer);
|
1309
|
+
this.dispatchEvent(ev, '$md.dragend', this.state.dragPointer);
|
1310
|
+
}
|
1311
|
+
}
|
1312
|
+
})
|
1313
|
+
|
1314
|
+
/*
|
1315
|
+
* The swipe handler will dispatch a swipe event if, on the end of a touch,
|
1316
|
+
* the velocity and distance were high enough.
|
1317
|
+
* TODO: add vertical swiping with a `horizontal` option similar to the drag handler.
|
1318
|
+
*/
|
1319
|
+
.handler('swipe', {
|
1320
|
+
options: {
|
1321
|
+
minVelocity: 0.65,
|
1322
|
+
minDistance: 10
|
1323
|
+
},
|
1324
|
+
onEnd: function (ev, pointer) {
|
1325
|
+
if (Math.abs(pointer.velocityX) > this.state.options.minVelocity &&
|
1326
|
+
Math.abs(pointer.distanceX) > this.state.options.minDistance) {
|
1327
|
+
var eventType = pointer.directionX == 'left' ? '$md.swipeleft' : '$md.swiperight';
|
1328
|
+
this.dispatchEvent(ev, eventType);
|
1329
|
+
}
|
1330
|
+
}
|
1331
|
+
});
|
1332
|
+
|
1333
|
+
}
|
1334
|
+
MdGesture.$inject = ["$$MdGestureHandler", "$$rAF", "$timeout"];
|
1335
|
+
|
1336
|
+
/**
|
1337
|
+
* MdGestureHandler
|
1338
|
+
* A GestureHandler is an object which is able to dispatch custom dom events
|
1339
|
+
* based on native dom {touch,pointer,mouse}{start,move,end} events.
|
1340
|
+
*
|
1341
|
+
* A gesture will manage its lifecycle through the start,move,end, and cancel
|
1342
|
+
* functions, which are called by native dom events.
|
1343
|
+
*
|
1344
|
+
* A gesture has the concept of 'options' (eg a swipe's required velocity), which can be
|
1345
|
+
* overridden by elements registering through $mdGesture.register()
|
1346
|
+
*/
|
1347
|
+
function GestureHandler (name) {
|
1348
|
+
this.name = name;
|
1349
|
+
this.state = {};
|
1350
|
+
}
|
1351
|
+
|
1352
|
+
function MdGestureHandler() {
|
1353
|
+
var hasJQuery = (typeof window.jQuery !== 'undefined') && (angular.element === window.jQuery);
|
1354
|
+
|
1355
|
+
GestureHandler.prototype = {
|
1356
|
+
options: {},
|
1357
|
+
// jQuery listeners don't work with custom DOMEvents, so we have to dispatch events
|
1358
|
+
// differently when jQuery is loaded
|
1359
|
+
dispatchEvent: hasJQuery ? jQueryDispatchEvent : nativeDispatchEvent,
|
1360
|
+
|
1361
|
+
// These are overridden by the registered handler
|
1362
|
+
onStart: angular.noop,
|
1363
|
+
onMove: angular.noop,
|
1364
|
+
onEnd: angular.noop,
|
1365
|
+
onCancel: angular.noop,
|
1366
|
+
|
1367
|
+
// onStart sets up a new state for the handler, which includes options from the
|
1368
|
+
// nearest registered parent element of ev.target.
|
1369
|
+
start: function (ev, pointer) {
|
1370
|
+
if (this.state.isRunning) return;
|
1371
|
+
var parentTarget = this.getNearestParent(ev.target);
|
1372
|
+
// Get the options from the nearest registered parent
|
1373
|
+
var parentTargetOptions = parentTarget && parentTarget.$mdGesture[this.name] || {};
|
1374
|
+
|
1375
|
+
this.state = {
|
1376
|
+
isRunning: true,
|
1377
|
+
// Override the default options with the nearest registered parent's options
|
1378
|
+
options: angular.extend({}, this.options, parentTargetOptions),
|
1379
|
+
// Pass in the registered parent node to the state so the onStart listener can use
|
1380
|
+
registeredParent: parentTarget
|
1381
|
+
};
|
1382
|
+
this.onStart(ev, pointer);
|
1383
|
+
},
|
1384
|
+
move: function (ev, pointer) {
|
1385
|
+
if (!this.state.isRunning) return;
|
1386
|
+
this.onMove(ev, pointer);
|
1387
|
+
},
|
1388
|
+
end: function (ev, pointer) {
|
1389
|
+
if (!this.state.isRunning) return;
|
1390
|
+
this.onEnd(ev, pointer);
|
1391
|
+
this.state.isRunning = false;
|
1392
|
+
},
|
1393
|
+
cancel: function (ev, pointer) {
|
1394
|
+
this.onCancel(ev, pointer);
|
1395
|
+
this.state = {};
|
1396
|
+
},
|
1397
|
+
|
1398
|
+
// Find and return the nearest parent element that has been registered to
|
1399
|
+
// listen for this handler via $mdGesture.register(element, 'handlerName').
|
1400
|
+
getNearestParent: function (node) {
|
1401
|
+
var current = node;
|
1402
|
+
while (current) {
|
1403
|
+
if ((current.$mdGesture || {})[this.name]) {
|
1404
|
+
return current;
|
1405
|
+
}
|
1406
|
+
current = current.parentNode;
|
1407
|
+
}
|
1408
|
+
return null;
|
1409
|
+
},
|
1410
|
+
|
1411
|
+
// Called from $mdGesture.register when an element reigsters itself with a handler.
|
1412
|
+
// Store the options the user gave on the DOMElement itself. These options will
|
1413
|
+
// be retrieved with getNearestParent when the handler starts.
|
1414
|
+
registerElement: function (element, options) {
|
1415
|
+
var self = this;
|
1416
|
+
element[0].$mdGesture = element[0].$mdGesture || {};
|
1417
|
+
element[0].$mdGesture[this.name] = options || {};
|
1418
|
+
element.on('$destroy', onDestroy);
|
1419
|
+
|
1420
|
+
return onDestroy;
|
1421
|
+
|
1422
|
+
function onDestroy() {
|
1423
|
+
delete element[0].$mdGesture[self.name];
|
1424
|
+
element.off('$destroy', onDestroy);
|
1425
|
+
}
|
1426
|
+
}
|
1427
|
+
};
|
1428
|
+
|
1429
|
+
return GestureHandler;
|
1430
|
+
|
1431
|
+
/*
|
1432
|
+
* Dispatch an event with jQuery
|
1433
|
+
* TODO: Make sure this sends bubbling events
|
1434
|
+
*
|
1435
|
+
* @param srcEvent the original DOM touch event that started this.
|
1436
|
+
* @param eventType the name of the custom event to send (eg 'click' or '$md.drag')
|
1437
|
+
* @param eventPointer the pointer object that matches this event.
|
1438
|
+
*/
|
1439
|
+
function jQueryDispatchEvent(srcEvent, eventType, eventPointer) {
|
1440
|
+
eventPointer = eventPointer || pointer;
|
1441
|
+
var eventObj = new angular.element.Event(eventType);
|
1442
|
+
|
1443
|
+
eventObj.$material = true;
|
1444
|
+
eventObj.pointer = eventPointer;
|
1445
|
+
eventObj.srcEvent = srcEvent;
|
1446
|
+
|
1447
|
+
angular.extend(eventObj, {
|
1448
|
+
clientX: eventPointer.x,
|
1449
|
+
clientY: eventPointer.y,
|
1450
|
+
screenX: eventPointer.x,
|
1451
|
+
screenY: eventPointer.y,
|
1452
|
+
pageX: eventPointer.x,
|
1453
|
+
pageY: eventPointer.y,
|
1454
|
+
ctrlKey: srcEvent.ctrlKey,
|
1455
|
+
altKey: srcEvent.altKey,
|
1456
|
+
shiftKey: srcEvent.shiftKey,
|
1457
|
+
metaKey: srcEvent.metaKey
|
1458
|
+
});
|
1459
|
+
angular.element(eventPointer.target).trigger(eventObj);
|
1460
|
+
}
|
1461
|
+
|
1462
|
+
/*
|
1463
|
+
* NOTE: nativeDispatchEvent is very performance sensitive.
|
1464
|
+
* @param srcEvent the original DOM touch event that started this.
|
1465
|
+
* @param eventType the name of the custom event to send (eg 'click' or '$md.drag')
|
1466
|
+
* @param eventPointer the pointer object that matches this event.
|
1467
|
+
*/
|
1468
|
+
function nativeDispatchEvent(srcEvent, eventType, eventPointer) {
|
1469
|
+
eventPointer = eventPointer || pointer;
|
1470
|
+
var eventObj;
|
1471
|
+
|
1472
|
+
if (eventType === 'click') {
|
1473
|
+
eventObj = document.createEvent('MouseEvents');
|
1474
|
+
eventObj.initMouseEvent(
|
1475
|
+
'click', true, true, window, srcEvent.detail,
|
1476
|
+
eventPointer.x, eventPointer.y, eventPointer.x, eventPointer.y,
|
1477
|
+
srcEvent.ctrlKey, srcEvent.altKey, srcEvent.shiftKey, srcEvent.metaKey,
|
1478
|
+
srcEvent.button, srcEvent.relatedTarget || null
|
1479
|
+
);
|
1480
|
+
|
1481
|
+
} else {
|
1482
|
+
eventObj = document.createEvent('CustomEvent');
|
1483
|
+
eventObj.initCustomEvent(eventType, true, true, {});
|
1484
|
+
}
|
1485
|
+
eventObj.$material = true;
|
1486
|
+
eventObj.pointer = eventPointer;
|
1487
|
+
eventObj.srcEvent = srcEvent;
|
1488
|
+
eventPointer.target.dispatchEvent(eventObj);
|
1489
|
+
}
|
1490
|
+
|
1491
|
+
}
|
1492
|
+
|
1493
|
+
/**
|
1494
|
+
* Attach Gestures: hook document and check shouldHijack clicks
|
1495
|
+
* ngInject
|
1496
|
+
*/
|
1497
|
+
function attachToDocument( $mdGesture, $$MdGestureHandler ) {
|
1498
|
+
|
1499
|
+
// Polyfill document.contains for IE11.
|
1500
|
+
// TODO: move to util
|
1501
|
+
document.contains || (document.contains = function (node) {
|
1502
|
+
return document.body.contains(node);
|
1503
|
+
});
|
1504
|
+
|
1505
|
+
if (!isInitialized && $mdGesture.isHijackingClicks ) {
|
1506
|
+
/*
|
1507
|
+
* If hijack clicks is true, we preventDefault any click that wasn't
|
1508
|
+
* sent by ngMaterial. This is because on older Android & iOS, a false, or 'ghost',
|
1509
|
+
* click event will be sent ~400ms after a touchend event happens.
|
1510
|
+
* The only way to know if this click is real is to prevent any normal
|
1511
|
+
* click events, and add a flag to events sent by material so we know not to prevent those.
|
1512
|
+
*
|
1513
|
+
* Two exceptions to click events that should be prevented are:
|
1514
|
+
* - click events sent by the keyboard (eg form submit)
|
1515
|
+
* - events that originate from an Ionic app
|
1516
|
+
*/
|
1517
|
+
document.addEventListener('click', function clickHijacker(ev) {
|
1518
|
+
var isKeyClick = ev.clientX === 0 && ev.clientY === 0;
|
1519
|
+
if (!isKeyClick && !ev.$material && !ev.isIonicTap) {
|
1520
|
+
ev.preventDefault();
|
1521
|
+
ev.stopPropagation();
|
1522
|
+
}
|
1523
|
+
}, true);
|
1524
|
+
|
1525
|
+
isInitialized = true;
|
1526
|
+
}
|
1527
|
+
|
1528
|
+
// Listen to all events to cover all platforms.
|
1529
|
+
var START_EVENTS = 'mousedown touchstart pointerdown';
|
1530
|
+
var MOVE_EVENTS = 'mousemove touchmove pointermove';
|
1531
|
+
var END_EVENTS = 'mouseup mouseleave touchend touchcancel pointerup pointercancel';
|
1532
|
+
|
1533
|
+
angular.element(document)
|
1534
|
+
.on(START_EVENTS, gestureStart)
|
1535
|
+
.on(MOVE_EVENTS, gestureMove)
|
1536
|
+
.on(END_EVENTS, gestureEnd)
|
1537
|
+
// For testing
|
1538
|
+
.on('$$mdGestureReset', function gestureClearCache () {
|
1539
|
+
lastPointer = pointer = null;
|
1540
|
+
});
|
1541
|
+
|
1542
|
+
/*
|
1543
|
+
* When a DOM event happens, run all registered gesture handlers' lifecycle
|
1544
|
+
* methods which match the DOM event.
|
1545
|
+
* Eg when a 'touchstart' event happens, runHandlers('start') will call and
|
1546
|
+
* run `handler.cancel()` and `handler.start()` on all registered handlers.
|
1547
|
+
*/
|
1548
|
+
function runHandlers(handlerEvent, event) {
|
1549
|
+
var handler;
|
1550
|
+
for (var name in HANDLERS) {
|
1551
|
+
handler = HANDLERS[name];
|
1552
|
+
if( handler instanceof $$MdGestureHandler ) {
|
1553
|
+
|
1554
|
+
if (handlerEvent === 'start') {
|
1555
|
+
// Run cancel to reset any handlers' state
|
1556
|
+
handler.cancel();
|
1557
|
+
}
|
1558
|
+
handler[handlerEvent](event, pointer);
|
1559
|
+
|
1560
|
+
}
|
1561
|
+
}
|
1562
|
+
}
|
1563
|
+
|
1564
|
+
/*
|
1565
|
+
* gestureStart vets if a start event is legitimate (and not part of a 'ghost click' from iOS/Android)
|
1566
|
+
* If it is legitimate, we initiate the pointer state and mark the current pointer's type
|
1567
|
+
* For example, for a touchstart event, mark the current pointer as a 'touch' pointer, so mouse events
|
1568
|
+
* won't effect it.
|
1569
|
+
*/
|
1570
|
+
function gestureStart(ev) {
|
1571
|
+
// If we're already touched down, abort
|
1572
|
+
if (pointer) return;
|
1573
|
+
|
1574
|
+
var now = +Date.now();
|
1575
|
+
|
1576
|
+
// iOS & old android bug: after a touch event, a click event is sent 350 ms later.
|
1577
|
+
// If <400ms have passed, don't allow an event of a different type than the previous event
|
1578
|
+
if (lastPointer && !typesMatch(ev, lastPointer) && (now - lastPointer.endTime < 1500)) {
|
1579
|
+
return;
|
1580
|
+
}
|
1581
|
+
|
1582
|
+
pointer = makeStartPointer(ev);
|
1583
|
+
|
1584
|
+
runHandlers('start', ev);
|
1585
|
+
}
|
1586
|
+
/*
|
1587
|
+
* If a move event happens of the right type, update the pointer and run all the move handlers.
|
1588
|
+
* "of the right type": if a mousemove happens but our pointer started with a touch event, do nothing.
|
1589
|
+
*/
|
1590
|
+
function gestureMove(ev) {
|
1591
|
+
if (!pointer || !typesMatch(ev, pointer)) return;
|
1592
|
+
|
1593
|
+
updatePointerState(ev, pointer);
|
1594
|
+
runHandlers('move', ev);
|
1595
|
+
}
|
1596
|
+
/*
|
1597
|
+
* If an end event happens of the right type, update the pointer, run endHandlers, and save the pointer as 'lastPointer'
|
1598
|
+
*/
|
1599
|
+
function gestureEnd(ev) {
|
1600
|
+
if (!pointer || !typesMatch(ev, pointer)) return;
|
1601
|
+
|
1602
|
+
updatePointerState(ev, pointer);
|
1603
|
+
pointer.endTime = +Date.now();
|
1604
|
+
|
1605
|
+
runHandlers('end', ev);
|
1606
|
+
|
1607
|
+
lastPointer = pointer;
|
1608
|
+
pointer = null;
|
1609
|
+
}
|
1610
|
+
|
1611
|
+
}
|
1612
|
+
attachToDocument.$inject = ["$mdGesture", "$$MdGestureHandler"];
|
1613
|
+
|
1614
|
+
// ********************
|
1615
|
+
// Module Functions
|
1616
|
+
// ********************
|
1617
|
+
|
1618
|
+
/*
|
1619
|
+
* Initiate the pointer. x, y, and the pointer's type.
|
1620
|
+
*/
|
1621
|
+
function makeStartPointer(ev) {
|
1622
|
+
var point = getEventPoint(ev);
|
1623
|
+
var startPointer = {
|
1624
|
+
startTime: +Date.now(),
|
1625
|
+
target: ev.target,
|
1626
|
+
// 'p' for pointer events, 'm' for mouse, 't' for touch
|
1627
|
+
type: ev.type.charAt(0)
|
1628
|
+
};
|
1629
|
+
startPointer.startX = startPointer.x = point.pageX;
|
1630
|
+
startPointer.startY = startPointer.y = point.pageY;
|
1631
|
+
return startPointer;
|
1632
|
+
}
|
1633
|
+
|
1634
|
+
/*
|
1635
|
+
* return whether the pointer's type matches the event's type.
|
1636
|
+
* Eg if a touch event happens but the pointer has a mouse type, return false.
|
1637
|
+
*/
|
1638
|
+
function typesMatch(ev, pointer) {
|
1639
|
+
return ev && pointer && ev.type.charAt(0) === pointer.type;
|
1640
|
+
}
|
1641
|
+
|
1642
|
+
/*
|
1643
|
+
* Update the given pointer based upon the given DOMEvent.
|
1644
|
+
* Distance, velocity, direction, duration, etc
|
1645
|
+
*/
|
1646
|
+
function updatePointerState(ev, pointer) {
|
1647
|
+
var point = getEventPoint(ev);
|
1648
|
+
var x = pointer.x = point.pageX;
|
1649
|
+
var y = pointer.y = point.pageY;
|
1650
|
+
|
1651
|
+
pointer.distanceX = x - pointer.startX;
|
1652
|
+
pointer.distanceY = y - pointer.startY;
|
1653
|
+
pointer.distance = Math.sqrt(
|
1654
|
+
pointer.distanceX * pointer.distanceX + pointer.distanceY * pointer.distanceY
|
1655
|
+
);
|
1656
|
+
|
1657
|
+
pointer.directionX = pointer.distanceX > 0 ? 'right' : pointer.distanceX < 0 ? 'left' : '';
|
1658
|
+
pointer.directionY = pointer.distanceY > 0 ? 'up' : pointer.distanceY < 0 ? 'down' : '';
|
1659
|
+
|
1660
|
+
pointer.duration = +Date.now() - pointer.startTime;
|
1661
|
+
pointer.velocityX = pointer.distanceX / pointer.duration;
|
1662
|
+
pointer.velocityY = pointer.distanceY / pointer.duration;
|
1663
|
+
}
|
1664
|
+
|
1665
|
+
/*
|
1666
|
+
* Normalize the point where the DOM event happened whether it's touch or mouse.
|
1667
|
+
* @returns point event obj with pageX and pageY on it.
|
1668
|
+
*/
|
1669
|
+
function getEventPoint(ev) {
|
1670
|
+
ev = ev.originalEvent || ev; // support jQuery events
|
1671
|
+
return (ev.touches && ev.touches[0]) ||
|
1672
|
+
(ev.changedTouches && ev.changedTouches[0]) ||
|
1673
|
+
ev;
|
1674
|
+
}
|
1675
|
+
|
1676
|
+
angular.module('material.core')
|
1677
|
+
.provider('$$interimElement', InterimElementProvider);
|
1678
|
+
|
1679
|
+
/*
|
1680
|
+
* @ngdoc service
|
1681
|
+
* @name $$interimElement
|
1682
|
+
* @module material.core
|
1683
|
+
*
|
1684
|
+
* @description
|
1685
|
+
*
|
1686
|
+
* Factory that contructs `$$interimElement.$service` services.
|
1687
|
+
* Used internally in material design for elements that appear on screen temporarily.
|
1688
|
+
* The service provides a promise-like API for interacting with the temporary
|
1689
|
+
* elements.
|
1690
|
+
*
|
1691
|
+
* ```js
|
1692
|
+
* app.service('$mdToast', function($$interimElement) {
|
1693
|
+
* var $mdToast = $$interimElement(toastDefaultOptions);
|
1694
|
+
* return $mdToast;
|
1695
|
+
* });
|
1696
|
+
* ```
|
1697
|
+
* @param {object=} defaultOptions Options used by default for the `show` method on the service.
|
1698
|
+
*
|
1699
|
+
* @returns {$$interimElement.$service}
|
1700
|
+
*
|
1701
|
+
*/
|
1702
|
+
|
1703
|
+
function InterimElementProvider() {
|
1704
|
+
createInterimElementProvider.$get = InterimElementFactory;
|
1705
|
+
InterimElementFactory.$inject = ["$document", "$q", "$rootScope", "$timeout", "$rootElement", "$animate", "$interpolate", "$mdCompiler", "$mdTheming"];
|
1706
|
+
return createInterimElementProvider;
|
1707
|
+
|
1708
|
+
/**
|
1709
|
+
* Returns a new provider which allows configuration of a new interimElement
|
1710
|
+
* service. Allows configuration of default options & methods for options,
|
1711
|
+
* as well as configuration of 'preset' methods (eg dialog.basic(): basic is a preset method)
|
1712
|
+
*/
|
1713
|
+
function createInterimElementProvider(interimFactoryName) {
|
1714
|
+
var EXPOSED_METHODS = ['onHide', 'onShow', 'onRemove'];
|
1715
|
+
|
1716
|
+
var customMethods = {};
|
1717
|
+
var providerConfig = {
|
1718
|
+
presets: {}
|
1719
|
+
};
|
1720
|
+
|
1721
|
+
var provider = {
|
1722
|
+
setDefaults: setDefaults,
|
1723
|
+
addPreset: addPreset,
|
1724
|
+
addMethod: addMethod,
|
1725
|
+
$get: factory
|
1726
|
+
};
|
1727
|
+
|
1728
|
+
/**
|
1729
|
+
* all interim elements will come with the 'build' preset
|
1730
|
+
*/
|
1731
|
+
provider.addPreset('build', {
|
1732
|
+
methods: ['controller', 'controllerAs', 'resolve',
|
1733
|
+
'template', 'templateUrl', 'themable', 'transformTemplate', 'parent']
|
1734
|
+
});
|
1735
|
+
|
1736
|
+
factory.$inject = ["$$interimElement", "$animate", "$injector"];
|
1737
|
+
return provider;
|
1738
|
+
|
1739
|
+
/**
|
1740
|
+
* Save the configured defaults to be used when the factory is instantiated
|
1741
|
+
*/
|
1742
|
+
function setDefaults(definition) {
|
1743
|
+
providerConfig.optionsFactory = definition.options;
|
1744
|
+
providerConfig.methods = (definition.methods || []).concat(EXPOSED_METHODS);
|
1745
|
+
return provider;
|
1746
|
+
}
|
1747
|
+
|
1748
|
+
/**
|
1749
|
+
* Add a method to the factory that isn't specific to any interim element operations
|
1750
|
+
*/
|
1751
|
+
|
1752
|
+
function addMethod(name, fn) {
|
1753
|
+
customMethods[name] = fn;
|
1754
|
+
return provider;
|
1755
|
+
}
|
1756
|
+
|
1757
|
+
/**
|
1758
|
+
* Save the configured preset to be used when the factory is instantiated
|
1759
|
+
*/
|
1760
|
+
function addPreset(name, definition) {
|
1761
|
+
definition = definition || {};
|
1762
|
+
definition.methods = definition.methods || [];
|
1763
|
+
definition.options = definition.options || function() { return {}; };
|
1764
|
+
|
1765
|
+
if (/^cancel|hide|show$/.test(name)) {
|
1766
|
+
throw new Error("Preset '" + name + "' in " + interimFactoryName + " is reserved!");
|
1767
|
+
}
|
1768
|
+
if (definition.methods.indexOf('_options') > -1) {
|
1769
|
+
throw new Error("Method '_options' in " + interimFactoryName + " is reserved!");
|
1770
|
+
}
|
1771
|
+
providerConfig.presets[name] = {
|
1772
|
+
methods: definition.methods.concat(EXPOSED_METHODS),
|
1773
|
+
optionsFactory: definition.options,
|
1774
|
+
argOption: definition.argOption
|
1775
|
+
};
|
1776
|
+
return provider;
|
1777
|
+
}
|
1778
|
+
|
1779
|
+
/**
|
1780
|
+
* Create a factory that has the given methods & defaults implementing interimElement
|
1781
|
+
*/
|
1782
|
+
/* ngInject */
|
1783
|
+
function factory($$interimElement, $animate, $injector) {
|
1784
|
+
var defaultMethods;
|
1785
|
+
var defaultOptions;
|
1786
|
+
var interimElementService = $$interimElement();
|
1787
|
+
|
1788
|
+
/*
|
1789
|
+
* publicService is what the developer will be using.
|
1790
|
+
* It has methods hide(), cancel(), show(), build(), and any other
|
1791
|
+
* presets which were set during the config phase.
|
1792
|
+
*/
|
1793
|
+
var publicService = {
|
1794
|
+
hide: interimElementService.hide,
|
1795
|
+
cancel: interimElementService.cancel,
|
1796
|
+
show: showInterimElement
|
1797
|
+
};
|
1798
|
+
|
1799
|
+
defaultMethods = providerConfig.methods || [];
|
1800
|
+
// This must be invoked after the publicService is initialized
|
1801
|
+
defaultOptions = invokeFactory(providerConfig.optionsFactory, {});
|
1802
|
+
|
1803
|
+
// Copy over the simple custom methods
|
1804
|
+
angular.forEach(customMethods, function(fn, name) {
|
1805
|
+
publicService[name] = fn;
|
1806
|
+
});
|
1807
|
+
|
1808
|
+
angular.forEach(providerConfig.presets, function(definition, name) {
|
1809
|
+
var presetDefaults = invokeFactory(definition.optionsFactory, {});
|
1810
|
+
var presetMethods = (definition.methods || []).concat(defaultMethods);
|
1811
|
+
|
1812
|
+
// Every interimElement built with a preset has a field called `$type`,
|
1813
|
+
// which matches the name of the preset.
|
1814
|
+
// Eg in preset 'confirm', options.$type === 'confirm'
|
1815
|
+
angular.extend(presetDefaults, { $type: name });
|
1816
|
+
|
1817
|
+
// This creates a preset class which has setter methods for every
|
1818
|
+
// method given in the `.addPreset()` function, as well as every
|
1819
|
+
// method given in the `.setDefaults()` function.
|
1820
|
+
//
|
1821
|
+
// @example
|
1822
|
+
// .setDefaults({
|
1823
|
+
// methods: ['hasBackdrop', 'clickOutsideToClose', 'escapeToClose', 'targetEvent'],
|
1824
|
+
// options: dialogDefaultOptions
|
1825
|
+
// })
|
1826
|
+
// .addPreset('alert', {
|
1827
|
+
// methods: ['title', 'ok'],
|
1828
|
+
// options: alertDialogOptions
|
1829
|
+
// })
|
1830
|
+
//
|
1831
|
+
// Set values will be passed to the options when interimElemnt.show() is called.
|
1832
|
+
function Preset(opts) {
|
1833
|
+
this._options = angular.extend({}, presetDefaults, opts);
|
1834
|
+
}
|
1835
|
+
angular.forEach(presetMethods, function(name) {
|
1836
|
+
Preset.prototype[name] = function(value) {
|
1837
|
+
this._options[name] = value;
|
1838
|
+
return this;
|
1839
|
+
};
|
1840
|
+
});
|
1841
|
+
|
1842
|
+
// Create shortcut method for one-linear methods
|
1843
|
+
if (definition.argOption) {
|
1844
|
+
var methodName = 'show' + name.charAt(0).toUpperCase() + name.slice(1);
|
1845
|
+
publicService[methodName] = function(arg) {
|
1846
|
+
var config = publicService[name](arg);
|
1847
|
+
return publicService.show(config);
|
1848
|
+
};
|
1849
|
+
}
|
1850
|
+
|
1851
|
+
// eg $mdDialog.alert() will return a new alert preset
|
1852
|
+
publicService[name] = function(arg) {
|
1853
|
+
// If argOption is supplied, eg `argOption: 'content'`, then we assume
|
1854
|
+
// if the argument is not an options object then it is the `argOption` option.
|
1855
|
+
//
|
1856
|
+
// @example `$mdToast.simple('hello')` // sets options.content to hello
|
1857
|
+
// // because argOption === 'content'
|
1858
|
+
if (arguments.length && definition.argOption && !angular.isObject(arg) &&
|
1859
|
+
!angular.isArray(arg)) {
|
1860
|
+
return (new Preset())[definition.argOption](arg);
|
1861
|
+
} else {
|
1862
|
+
return new Preset(arg);
|
1863
|
+
}
|
1864
|
+
|
1865
|
+
};
|
1866
|
+
});
|
1867
|
+
|
1868
|
+
return publicService;
|
1869
|
+
|
1870
|
+
function showInterimElement(opts) {
|
1871
|
+
// opts is either a preset which stores its options on an _options field,
|
1872
|
+
// or just an object made up of options
|
1873
|
+
if (opts && opts._options) opts = opts._options;
|
1874
|
+
return interimElementService.show(
|
1875
|
+
angular.extend({}, defaultOptions, opts)
|
1876
|
+
);
|
1877
|
+
}
|
1878
|
+
|
1879
|
+
/**
|
1880
|
+
* Helper to call $injector.invoke with a local of the factory name for
|
1881
|
+
* this provider.
|
1882
|
+
* If an $mdDialog is providing options for a dialog and tries to inject
|
1883
|
+
* $mdDialog, a circular dependency error will happen.
|
1884
|
+
* We get around that by manually injecting $mdDialog as a local.
|
1885
|
+
*/
|
1886
|
+
function invokeFactory(factory, defaultVal) {
|
1887
|
+
var locals = {};
|
1888
|
+
locals[interimFactoryName] = publicService;
|
1889
|
+
return $injector.invoke(factory || function() { return defaultVal; }, {}, locals);
|
1890
|
+
}
|
1891
|
+
|
1892
|
+
}
|
1893
|
+
|
1894
|
+
}
|
1895
|
+
|
1896
|
+
/* ngInject */
|
1897
|
+
function InterimElementFactory($document, $q, $rootScope, $timeout, $rootElement, $animate,
|
1898
|
+
$interpolate, $mdCompiler, $mdTheming ) {
|
1899
|
+
var startSymbol = $interpolate.startSymbol(),
|
1900
|
+
endSymbol = $interpolate.endSymbol(),
|
1901
|
+
usesStandardSymbols = ((startSymbol === '{{') && (endSymbol === '}}')),
|
1902
|
+
processTemplate = usesStandardSymbols ? angular.identity : replaceInterpolationSymbols;
|
1903
|
+
|
1904
|
+
return function createInterimElementService() {
|
1905
|
+
/*
|
1906
|
+
* @ngdoc service
|
1907
|
+
* @name $$interimElement.$service
|
1908
|
+
*
|
1909
|
+
* @description
|
1910
|
+
* A service used to control inserting and removing an element into the DOM.
|
1911
|
+
*
|
1912
|
+
*/
|
1913
|
+
var stack = [];
|
1914
|
+
var service;
|
1915
|
+
return service = {
|
1916
|
+
show: show,
|
1917
|
+
hide: hide,
|
1918
|
+
cancel: cancel
|
1919
|
+
};
|
1920
|
+
|
1921
|
+
/*
|
1922
|
+
* @ngdoc method
|
1923
|
+
* @name $$interimElement.$service#show
|
1924
|
+
* @kind function
|
1925
|
+
*
|
1926
|
+
* @description
|
1927
|
+
* Adds the `$interimElement` to the DOM and returns a promise that will be resolved or rejected
|
1928
|
+
* with hide or cancel, respectively.
|
1929
|
+
*
|
1930
|
+
* @param {*} options is hashMap of settings
|
1931
|
+
* @returns a Promise
|
1932
|
+
*
|
1933
|
+
*/
|
1934
|
+
function show(options) {
|
1935
|
+
if (stack.length) {
|
1936
|
+
return service.cancel().then(function() {
|
1937
|
+
return show(options);
|
1938
|
+
});
|
1939
|
+
} else {
|
1940
|
+
var interimElement = new InterimElement(options);
|
1941
|
+
stack.push(interimElement);
|
1942
|
+
return interimElement.show().then(function() {
|
1943
|
+
return interimElement.deferred.promise;
|
1944
|
+
});
|
1945
|
+
}
|
1946
|
+
}
|
1947
|
+
|
1948
|
+
/*
|
1949
|
+
* @ngdoc method
|
1950
|
+
* @name $$interimElement.$service#hide
|
1951
|
+
* @kind function
|
1952
|
+
*
|
1953
|
+
* @description
|
1954
|
+
* Removes the `$interimElement` from the DOM and resolves the promise returned from `show`
|
1955
|
+
*
|
1956
|
+
* @param {*} resolveParam Data to resolve the promise with
|
1957
|
+
* @returns a Promise that will be resolved after the element has been removed.
|
1958
|
+
*
|
1959
|
+
*/
|
1960
|
+
function hide(response) {
|
1961
|
+
var interimElement = stack.shift();
|
1962
|
+
return interimElement && interimElement.remove().then(function() {
|
1963
|
+
interimElement.deferred.resolve(response);
|
1964
|
+
});
|
1965
|
+
}
|
1966
|
+
|
1967
|
+
/*
|
1968
|
+
* @ngdoc method
|
1969
|
+
* @name $$interimElement.$service#cancel
|
1970
|
+
* @kind function
|
1971
|
+
*
|
1972
|
+
* @description
|
1973
|
+
* Removes the `$interimElement` from the DOM and rejects the promise returned from `show`
|
1974
|
+
*
|
1975
|
+
* @param {*} reason Data to reject the promise with
|
1976
|
+
* @returns Promise that will be resolved after the element has been removed.
|
1977
|
+
*
|
1978
|
+
*/
|
1979
|
+
function cancel(reason) {
|
1980
|
+
var interimElement = stack.shift();
|
1981
|
+
return $q.when(interimElement && interimElement.remove().then(function() {
|
1982
|
+
interimElement.deferred.reject(reason);
|
1983
|
+
}));
|
1984
|
+
}
|
1985
|
+
|
1986
|
+
|
1987
|
+
/*
|
1988
|
+
* Internal Interim Element Object
|
1989
|
+
* Used internally to manage the DOM element and related data
|
1990
|
+
*/
|
1991
|
+
function InterimElement(options) {
|
1992
|
+
var self;
|
1993
|
+
var hideTimeout, element, showDone, removeDone;
|
1994
|
+
|
1995
|
+
options = options || {};
|
1996
|
+
options = angular.extend({
|
1997
|
+
preserveScope: false,
|
1998
|
+
scope: options.scope || $rootScope.$new(options.isolateScope),
|
1999
|
+
onShow: function(scope, element, options) {
|
2000
|
+
return $animate.enter(element, options.parent);
|
2001
|
+
},
|
2002
|
+
onRemove: function(scope, element, options) {
|
2003
|
+
// Element could be undefined if a new element is shown before
|
2004
|
+
// the old one finishes compiling.
|
2005
|
+
return element && $animate.leave(element) || $q.when();
|
2006
|
+
}
|
2007
|
+
}, options);
|
2008
|
+
|
2009
|
+
if (options.template) {
|
2010
|
+
options.template = processTemplate(options.template);
|
2011
|
+
}
|
2012
|
+
|
2013
|
+
return self = {
|
2014
|
+
options: options,
|
2015
|
+
deferred: $q.defer(),
|
2016
|
+
show: function() {
|
2017
|
+
var compilePromise;
|
2018
|
+
if (options.skipCompile) {
|
2019
|
+
compilePromise = $q(function(resolve) {
|
2020
|
+
resolve({
|
2021
|
+
locals: {},
|
2022
|
+
link: function() { return options.element; }
|
2023
|
+
});
|
2024
|
+
});
|
2025
|
+
} else {
|
2026
|
+
compilePromise = $mdCompiler.compile(options);
|
2027
|
+
}
|
2028
|
+
|
2029
|
+
return showDone = compilePromise.then(function(compileData) {
|
2030
|
+
angular.extend(compileData.locals, self.options);
|
2031
|
+
|
2032
|
+
element = compileData.link(options.scope);
|
2033
|
+
|
2034
|
+
// Search for parent at insertion time, if not specified
|
2035
|
+
if (angular.isFunction(options.parent)) {
|
2036
|
+
options.parent = options.parent(options.scope, element, options);
|
2037
|
+
} else if (angular.isString(options.parent)) {
|
2038
|
+
options.parent = angular.element($document[0].querySelector(options.parent));
|
2039
|
+
}
|
2040
|
+
|
2041
|
+
// If parent querySelector/getter function fails, or it's just null,
|
2042
|
+
// find a default.
|
2043
|
+
if (!(options.parent || {}).length) {
|
2044
|
+
var el;
|
2045
|
+
if ($rootElement[0] && $rootElement[0].querySelector) {
|
2046
|
+
el = $rootElement[0].querySelector(':not(svg) > body');
|
2047
|
+
}
|
2048
|
+
if (!el) el = $rootElement[0];
|
2049
|
+
if (el.nodeName == '#comment') {
|
2050
|
+
el = $document[0].body;
|
2051
|
+
}
|
2052
|
+
options.parent = angular.element(el);
|
2053
|
+
}
|
2054
|
+
|
2055
|
+
if (options.themable) $mdTheming(element);
|
2056
|
+
var ret = options.onShow(options.scope, element, options);
|
2057
|
+
return $q.when(ret)
|
2058
|
+
.then(function(){
|
2059
|
+
// Issue onComplete callback when the `show()` finishes
|
2060
|
+
(options.onComplete || angular.noop)(options.scope, element, options);
|
2061
|
+
startHideTimeout();
|
2062
|
+
});
|
2063
|
+
|
2064
|
+
function startHideTimeout() {
|
2065
|
+
if (options.hideDelay) {
|
2066
|
+
hideTimeout = $timeout(service.cancel, options.hideDelay) ;
|
2067
|
+
}
|
2068
|
+
}
|
2069
|
+
}, function(reason) { showDone = true; self.deferred.reject(reason); });
|
2070
|
+
},
|
2071
|
+
cancelTimeout: function() {
|
2072
|
+
if (hideTimeout) {
|
2073
|
+
$timeout.cancel(hideTimeout);
|
2074
|
+
hideTimeout = undefined;
|
2075
|
+
}
|
2076
|
+
},
|
2077
|
+
remove: function() {
|
2078
|
+
self.cancelTimeout();
|
2079
|
+
return removeDone = $q.when(showDone).then(function() {
|
2080
|
+
var ret = element ? options.onRemove(options.scope, element, options) : true;
|
2081
|
+
return $q.when(ret).then(function() {
|
2082
|
+
if (!options.preserveScope) options.scope.$destroy();
|
2083
|
+
removeDone = true;
|
2084
|
+
});
|
2085
|
+
});
|
2086
|
+
}
|
2087
|
+
};
|
2088
|
+
}
|
2089
|
+
};
|
2090
|
+
|
2091
|
+
/*
|
2092
|
+
* Replace `{{` and `}}` in a string (usually a template) with the actual start-/endSymbols used
|
2093
|
+
* for interpolation. This allows pre-defined templates (for components such as dialog, toast etc)
|
2094
|
+
* to continue to work in apps that use custom interpolation start-/endSymbols.
|
2095
|
+
*
|
2096
|
+
* @param {string} text The text in which to replace `{{` / `}}`
|
2097
|
+
* @returns {string} The modified string using the actual interpolation start-/endSymbols
|
2098
|
+
*/
|
2099
|
+
function replaceInterpolationSymbols(text) {
|
2100
|
+
if (!text || !angular.isString(text)) return text;
|
2101
|
+
return text.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol);
|
2102
|
+
}
|
2103
|
+
}
|
2104
|
+
|
2105
|
+
}
|
2106
|
+
|
2107
|
+
/**
|
2108
|
+
* @ngdoc module
|
2109
|
+
* @name material.core.componentRegistry
|
2110
|
+
*
|
2111
|
+
* @description
|
2112
|
+
* A component instance registration service.
|
2113
|
+
* Note: currently this as a private service in the SideNav component.
|
2114
|
+
*/
|
2115
|
+
angular.module('material.core')
|
2116
|
+
.factory('$mdComponentRegistry', ComponentRegistry);
|
2117
|
+
|
2118
|
+
/*
|
2119
|
+
* @private
|
2120
|
+
* @ngdoc factory
|
2121
|
+
* @name ComponentRegistry
|
2122
|
+
* @module material.core.componentRegistry
|
2123
|
+
*
|
2124
|
+
*/
|
2125
|
+
function ComponentRegistry($log, $q) {
|
2126
|
+
|
2127
|
+
var self;
|
2128
|
+
var instances = [ ];
|
2129
|
+
var pendings = { };
|
2130
|
+
|
2131
|
+
return self = {
|
2132
|
+
/**
|
2133
|
+
* Used to print an error when an instance for a handle isn't found.
|
2134
|
+
*/
|
2135
|
+
notFoundError: function(handle) {
|
2136
|
+
$log.error('No instance found for handle', handle);
|
2137
|
+
},
|
2138
|
+
/**
|
2139
|
+
* Return all registered instances as an array.
|
2140
|
+
*/
|
2141
|
+
getInstances: function() {
|
2142
|
+
return instances;
|
2143
|
+
},
|
2144
|
+
|
2145
|
+
/**
|
2146
|
+
* Get a registered instance.
|
2147
|
+
* @param handle the String handle to look up for a registered instance.
|
2148
|
+
*/
|
2149
|
+
get: function(handle) {
|
2150
|
+
if ( !isValidID(handle) ) return null;
|
2151
|
+
|
2152
|
+
var i, j, instance;
|
2153
|
+
for(i = 0, j = instances.length; i < j; i++) {
|
2154
|
+
instance = instances[i];
|
2155
|
+
if(instance.$$mdHandle === handle) {
|
2156
|
+
return instance;
|
2157
|
+
}
|
2158
|
+
}
|
2159
|
+
return null;
|
2160
|
+
},
|
2161
|
+
|
2162
|
+
/**
|
2163
|
+
* Register an instance.
|
2164
|
+
* @param instance the instance to register
|
2165
|
+
* @param handle the handle to identify the instance under.
|
2166
|
+
*/
|
2167
|
+
register: function(instance, handle) {
|
2168
|
+
if ( !handle ) return angular.noop;
|
2169
|
+
|
2170
|
+
instance.$$mdHandle = handle;
|
2171
|
+
instances.push(instance);
|
2172
|
+
resolveWhen();
|
2173
|
+
|
2174
|
+
return deregister;
|
2175
|
+
|
2176
|
+
/**
|
2177
|
+
* Remove registration for an instance
|
2178
|
+
*/
|
2179
|
+
function deregister() {
|
2180
|
+
var index = instances.indexOf(instance);
|
2181
|
+
if (index !== -1) {
|
2182
|
+
instances.splice(index, 1);
|
2183
|
+
}
|
2184
|
+
}
|
2185
|
+
|
2186
|
+
/**
|
2187
|
+
* Resolve any pending promises for this instance
|
2188
|
+
*/
|
2189
|
+
function resolveWhen() {
|
2190
|
+
var dfd = pendings[handle];
|
2191
|
+
if ( dfd ) {
|
2192
|
+
dfd.resolve( instance );
|
2193
|
+
delete pendings[handle];
|
2194
|
+
}
|
2195
|
+
}
|
2196
|
+
},
|
2197
|
+
|
2198
|
+
/**
|
2199
|
+
* Async accessor to registered component instance
|
2200
|
+
* If not available then a promise is created to notify
|
2201
|
+
* all listeners when the instance is registered.
|
2202
|
+
*/
|
2203
|
+
when : function(handle) {
|
2204
|
+
if ( isValidID(handle) ) {
|
2205
|
+
var deferred = $q.defer();
|
2206
|
+
var instance = self.get(handle);
|
2207
|
+
|
2208
|
+
if ( instance ) {
|
2209
|
+
deferred.resolve( instance );
|
2210
|
+
} else {
|
2211
|
+
pendings[handle] = deferred;
|
2212
|
+
}
|
2213
|
+
|
2214
|
+
return deferred.promise;
|
2215
|
+
}
|
2216
|
+
return $q.reject("Invalid `md-component-id` value.");
|
2217
|
+
}
|
2218
|
+
|
2219
|
+
};
|
2220
|
+
|
2221
|
+
function isValidID(handle){
|
2222
|
+
return handle && (handle !== "");
|
2223
|
+
}
|
2224
|
+
|
2225
|
+
}
|
2226
|
+
ComponentRegistry.$inject = ["$log", "$q"];
|
2227
|
+
|
2228
|
+
(function() {
|
2229
|
+
'use strict';
|
2230
|
+
|
2231
|
+
/**
|
2232
|
+
* @ngdoc service
|
2233
|
+
* @name $mdButtonInkRipple
|
2234
|
+
* @module material.core
|
2235
|
+
*
|
2236
|
+
* @description
|
2237
|
+
* Provides ripple effects for md-button. See $mdInkRipple service for all possible configuration options.
|
2238
|
+
*
|
2239
|
+
* @param {object=} scope Scope within the current context
|
2240
|
+
* @param {object=} element The element the ripple effect should be applied to
|
2241
|
+
* @param {object=} options (Optional) Configuration options to override the defaultripple configuration
|
2242
|
+
*/
|
2243
|
+
|
2244
|
+
angular.module('material.core')
|
2245
|
+
.factory('$mdButtonInkRipple', MdButtonInkRipple);
|
2246
|
+
|
2247
|
+
function MdButtonInkRipple($mdInkRipple) {
|
2248
|
+
return {
|
2249
|
+
attach: attach
|
2250
|
+
};
|
2251
|
+
|
2252
|
+
function attach(scope, element, options) {
|
2253
|
+
var elementOptions = optionsForElement(element);
|
2254
|
+
return $mdInkRipple.attach(scope, element, angular.extend(elementOptions, options));
|
2255
|
+
};
|
2256
|
+
|
2257
|
+
function optionsForElement(element) {
|
2258
|
+
if (element.hasClass('md-icon-button')) {
|
2259
|
+
return {
|
2260
|
+
isMenuItem: element.hasClass('md-menu-item'),
|
2261
|
+
fitRipple: true,
|
2262
|
+
center: true
|
2263
|
+
};
|
2264
|
+
} else {
|
2265
|
+
return {
|
2266
|
+
isMenuItem: element.hasClass('md-menu-item'),
|
2267
|
+
dimBackground: true
|
2268
|
+
}
|
2269
|
+
}
|
2270
|
+
};
|
2271
|
+
}
|
2272
|
+
MdButtonInkRipple.$inject = ["$mdInkRipple"];;
|
2273
|
+
})();
|
2274
|
+
|
2275
|
+
(function() {
|
2276
|
+
'use strict';
|
2277
|
+
|
2278
|
+
/**
|
2279
|
+
* @ngdoc service
|
2280
|
+
* @name $mdCheckboxInkRipple
|
2281
|
+
* @module material.core
|
2282
|
+
*
|
2283
|
+
* @description
|
2284
|
+
* Provides ripple effects for md-checkbox. See $mdInkRipple service for all possible configuration options.
|
2285
|
+
*
|
2286
|
+
* @param {object=} scope Scope within the current context
|
2287
|
+
* @param {object=} element The element the ripple effect should be applied to
|
2288
|
+
* @param {object=} options (Optional) Configuration options to override the defaultripple configuration
|
2289
|
+
*/
|
2290
|
+
|
2291
|
+
angular.module('material.core')
|
2292
|
+
.factory('$mdCheckboxInkRipple', MdCheckboxInkRipple);
|
2293
|
+
|
2294
|
+
function MdCheckboxInkRipple($mdInkRipple) {
|
2295
|
+
return {
|
2296
|
+
attach: attach
|
2297
|
+
};
|
2298
|
+
|
2299
|
+
function attach(scope, element, options) {
|
2300
|
+
return $mdInkRipple.attach(scope, element, angular.extend({
|
2301
|
+
center: true,
|
2302
|
+
dimBackground: false,
|
2303
|
+
fitRipple: true
|
2304
|
+
}, options));
|
2305
|
+
};
|
2306
|
+
}
|
2307
|
+
MdCheckboxInkRipple.$inject = ["$mdInkRipple"];;
|
2308
|
+
})();
|
2309
|
+
|
2310
|
+
(function() {
|
2311
|
+
'use strict';
|
2312
|
+
|
2313
|
+
/**
|
2314
|
+
* @ngdoc service
|
2315
|
+
* @name $mdListInkRipple
|
2316
|
+
* @module material.core
|
2317
|
+
*
|
2318
|
+
* @description
|
2319
|
+
* Provides ripple effects for md-list. See $mdInkRipple service for all possible configuration options.
|
2320
|
+
*
|
2321
|
+
* @param {object=} scope Scope within the current context
|
2322
|
+
* @param {object=} element The element the ripple effect should be applied to
|
2323
|
+
* @param {object=} options (Optional) Configuration options to override the defaultripple configuration
|
2324
|
+
*/
|
2325
|
+
|
2326
|
+
angular.module('material.core')
|
2327
|
+
.factory('$mdListInkRipple', MdListInkRipple);
|
2328
|
+
|
2329
|
+
function MdListInkRipple($mdInkRipple) {
|
2330
|
+
return {
|
2331
|
+
attach: attach
|
2332
|
+
};
|
2333
|
+
|
2334
|
+
function attach(scope, element, options) {
|
2335
|
+
return $mdInkRipple.attach(scope, element, angular.extend({
|
2336
|
+
center: false,
|
2337
|
+
dimBackground: true,
|
2338
|
+
outline: false,
|
2339
|
+
rippleSize: 'full'
|
2340
|
+
}, options));
|
2341
|
+
};
|
2342
|
+
}
|
2343
|
+
MdListInkRipple.$inject = ["$mdInkRipple"];;
|
2344
|
+
})();
|
2345
|
+
|
2346
|
+
angular.module('material.core')
|
2347
|
+
.factory('$mdInkRipple', InkRippleService)
|
2348
|
+
.directive('mdInkRipple', InkRippleDirective)
|
2349
|
+
.directive('mdNoInk', attrNoDirective())
|
2350
|
+
.directive('mdNoBar', attrNoDirective())
|
2351
|
+
.directive('mdNoStretch', attrNoDirective());
|
2352
|
+
|
2353
|
+
function InkRippleDirective($mdButtonInkRipple, $mdCheckboxInkRipple) {
|
2354
|
+
return {
|
2355
|
+
controller: angular.noop,
|
2356
|
+
link: function (scope, element, attr) {
|
2357
|
+
if (attr.hasOwnProperty('mdInkRippleCheckbox')) {
|
2358
|
+
$mdCheckboxInkRipple.attach(scope, element);
|
2359
|
+
} else {
|
2360
|
+
$mdButtonInkRipple.attach(scope, element);
|
2361
|
+
}
|
2362
|
+
}
|
2363
|
+
};
|
2364
|
+
}
|
2365
|
+
InkRippleDirective.$inject = ["$mdButtonInkRipple", "$mdCheckboxInkRipple"];
|
2366
|
+
|
2367
|
+
function InkRippleService($window, $timeout) {
|
2368
|
+
|
2369
|
+
return {
|
2370
|
+
attach: attach
|
2371
|
+
};
|
2372
|
+
|
2373
|
+
function attach(scope, element, options) {
|
2374
|
+
if (element.controller('mdNoInk')) return angular.noop;
|
2375
|
+
|
2376
|
+
options = angular.extend({
|
2377
|
+
colorElement: element,
|
2378
|
+
mousedown: true,
|
2379
|
+
hover: true,
|
2380
|
+
focus: true,
|
2381
|
+
center: false,
|
2382
|
+
mousedownPauseTime: 150,
|
2383
|
+
dimBackground: false,
|
2384
|
+
outline: false,
|
2385
|
+
fullRipple: true,
|
2386
|
+
isMenuItem: false,
|
2387
|
+
fitRipple: false
|
2388
|
+
}, options);
|
2389
|
+
|
2390
|
+
var rippleSize,
|
2391
|
+
controller = element.controller('mdInkRipple') || {},
|
2392
|
+
counter = 0,
|
2393
|
+
ripples = [],
|
2394
|
+
states = [],
|
2395
|
+
isActiveExpr = element.attr('md-highlight'),
|
2396
|
+
isActive = false,
|
2397
|
+
isHeld = false,
|
2398
|
+
node = element[0],
|
2399
|
+
rippleSizeSetting = element.attr('md-ripple-size'),
|
2400
|
+
color = parseColor(element.attr('md-ink-ripple')) || parseColor(options.colorElement.length && $window.getComputedStyle(options.colorElement[0]).color || 'rgb(0, 0, 0)');
|
2401
|
+
|
2402
|
+
switch (rippleSizeSetting) {
|
2403
|
+
case 'full':
|
2404
|
+
options.fullRipple = true;
|
2405
|
+
break;
|
2406
|
+
case 'partial':
|
2407
|
+
options.fullRipple = false;
|
2408
|
+
break;
|
2409
|
+
}
|
2410
|
+
|
2411
|
+
// expose onInput for ripple testing
|
2412
|
+
if (options.mousedown) {
|
2413
|
+
element.on('$md.pressdown', onPressDown)
|
2414
|
+
.on('$md.pressup', onPressUp);
|
2415
|
+
}
|
2416
|
+
|
2417
|
+
controller.createRipple = createRipple;
|
2418
|
+
|
2419
|
+
if (isActiveExpr) {
|
2420
|
+
scope.$watch(isActiveExpr, function watchActive(newValue) {
|
2421
|
+
isActive = newValue;
|
2422
|
+
if (isActive && !ripples.length) {
|
2423
|
+
$timeout(function () { createRipple(0, 0); }, 0, false);
|
2424
|
+
}
|
2425
|
+
angular.forEach(ripples, updateElement);
|
2426
|
+
});
|
2427
|
+
}
|
2428
|
+
|
2429
|
+
// Publish self-detach method if desired...
|
2430
|
+
return function detach() {
|
2431
|
+
element.off('$md.pressdown', onPressDown)
|
2432
|
+
.off('$md.pressup', onPressUp);
|
2433
|
+
getRippleContainer().remove();
|
2434
|
+
};
|
2435
|
+
|
2436
|
+
/**
|
2437
|
+
* Gets the current ripple container
|
2438
|
+
* If there is no ripple container, it creates one and returns it
|
2439
|
+
*
|
2440
|
+
* @returns {angular.element} ripple container element
|
2441
|
+
*/
|
2442
|
+
function getRippleContainer() {
|
2443
|
+
var container = element.data('$mdRippleContainer');
|
2444
|
+
if (container) return container;
|
2445
|
+
container = angular.element('<div class="md-ripple-container">');
|
2446
|
+
element.append(container);
|
2447
|
+
element.data('$mdRippleContainer', container);
|
2448
|
+
return container;
|
2449
|
+
}
|
2450
|
+
|
2451
|
+
function parseColor(color) {
|
2452
|
+
if (!color) return;
|
2453
|
+
if (color.indexOf('rgba') === 0) return color.replace(/\d?\.?\d*\s*\)\s*$/, '0.1)');
|
2454
|
+
if (color.indexOf('rgb') === 0) return rgbToRGBA(color);
|
2455
|
+
if (color.indexOf('#') === 0) return hexToRGBA(color);
|
2456
|
+
|
2457
|
+
/**
|
2458
|
+
* Converts a hex value to an rgba string
|
2459
|
+
*
|
2460
|
+
* @param {string} hex value (3 or 6 digits) to be converted
|
2461
|
+
*
|
2462
|
+
* @returns {string} rgba color with 0.1 alpha
|
2463
|
+
*/
|
2464
|
+
function hexToRGBA(color) {
|
2465
|
+
var hex = color.charAt(0) === '#' ? color.substr(1) : color,
|
2466
|
+
dig = hex.length / 3,
|
2467
|
+
red = hex.substr(0, dig),
|
2468
|
+
grn = hex.substr(dig, dig),
|
2469
|
+
blu = hex.substr(dig * 2);
|
2470
|
+
if (dig === 1) {
|
2471
|
+
red += red;
|
2472
|
+
grn += grn;
|
2473
|
+
blu += blu;
|
2474
|
+
}
|
2475
|
+
return 'rgba(' + parseInt(red, 16) + ',' + parseInt(grn, 16) + ',' + parseInt(blu, 16) + ',0.1)';
|
2476
|
+
}
|
2477
|
+
|
2478
|
+
/**
|
2479
|
+
* Converts rgb value to rgba string
|
2480
|
+
*
|
2481
|
+
* @param {string} rgb color string
|
2482
|
+
*
|
2483
|
+
* @returns {string} rgba color with 0.1 alpha
|
2484
|
+
*/
|
2485
|
+
function rgbToRGBA(color) {
|
2486
|
+
return color.replace(')', ', 0.1)').replace('(', 'a(');
|
2487
|
+
}
|
2488
|
+
|
2489
|
+
}
|
2490
|
+
|
2491
|
+
function removeElement(elem, wait) {
|
2492
|
+
ripples.splice(ripples.indexOf(elem), 1);
|
2493
|
+
if (ripples.length === 0) {
|
2494
|
+
getRippleContainer().css({ backgroundColor: '' });
|
2495
|
+
}
|
2496
|
+
$timeout(function () { elem.remove(); }, wait, false);
|
2497
|
+
}
|
2498
|
+
|
2499
|
+
function updateElement(elem) {
|
2500
|
+
var index = ripples.indexOf(elem),
|
2501
|
+
state = states[index] || {},
|
2502
|
+
elemIsActive = ripples.length > 1 ? false : isActive,
|
2503
|
+
elemIsHeld = ripples.length > 1 ? false : isHeld;
|
2504
|
+
if (elemIsActive || state.animating || elemIsHeld) {
|
2505
|
+
elem.addClass('md-ripple-visible');
|
2506
|
+
} else if (elem) {
|
2507
|
+
elem.removeClass('md-ripple-visible');
|
2508
|
+
if (options.outline) {
|
2509
|
+
elem.css({
|
2510
|
+
width: rippleSize + 'px',
|
2511
|
+
height: rippleSize + 'px',
|
2512
|
+
marginLeft: (rippleSize * -1) + 'px',
|
2513
|
+
marginTop: (rippleSize * -1) + 'px'
|
2514
|
+
});
|
2515
|
+
}
|
2516
|
+
removeElement(elem, options.outline ? 450 : 650);
|
2517
|
+
}
|
2518
|
+
}
|
2519
|
+
|
2520
|
+
/**
|
2521
|
+
* Creates a ripple at the provided coordinates
|
2522
|
+
*
|
2523
|
+
* @param {number} left cursor position
|
2524
|
+
* @param {number} top cursor position
|
2525
|
+
*
|
2526
|
+
* @returns {angular.element} the generated ripple element
|
2527
|
+
*/
|
2528
|
+
function createRipple(left, top) {
|
2529
|
+
|
2530
|
+
color = parseColor(element.attr('md-ink-ripple')) || parseColor($window.getComputedStyle(options.colorElement[0]).color || 'rgb(0, 0, 0)');
|
2531
|
+
|
2532
|
+
var container = getRippleContainer(),
|
2533
|
+
size = getRippleSize(left, top),
|
2534
|
+
css = getRippleCss(size, left, top),
|
2535
|
+
elem = getRippleElement(css),
|
2536
|
+
index = ripples.indexOf(elem),
|
2537
|
+
state = states[index] || {};
|
2538
|
+
|
2539
|
+
rippleSize = size;
|
2540
|
+
|
2541
|
+
state.animating = true;
|
2542
|
+
|
2543
|
+
$timeout(function () {
|
2544
|
+
if (options.dimBackground) {
|
2545
|
+
container.css({ backgroundColor: color });
|
2546
|
+
}
|
2547
|
+
elem.addClass('md-ripple-placed md-ripple-scaled');
|
2548
|
+
if (options.outline) {
|
2549
|
+
elem.css({
|
2550
|
+
borderWidth: (size * 0.5) + 'px',
|
2551
|
+
marginLeft: (size * -0.5) + 'px',
|
2552
|
+
marginTop: (size * -0.5) + 'px'
|
2553
|
+
});
|
2554
|
+
} else {
|
2555
|
+
elem.css({ left: '50%', top: '50%' });
|
2556
|
+
}
|
2557
|
+
updateElement(elem);
|
2558
|
+
$timeout(function () {
|
2559
|
+
state.animating = false;
|
2560
|
+
updateElement(elem);
|
2561
|
+
}, (options.outline ? 450 : 225), false);
|
2562
|
+
}, 0, false);
|
2563
|
+
|
2564
|
+
return elem;
|
2565
|
+
|
2566
|
+
/**
|
2567
|
+
* Creates the ripple element with the provided css
|
2568
|
+
*
|
2569
|
+
* @param {object} css properties to be applied
|
2570
|
+
*
|
2571
|
+
* @returns {angular.element} the generated ripple element
|
2572
|
+
*/
|
2573
|
+
function getRippleElement(css) {
|
2574
|
+
var elem = angular.element('<div class="md-ripple" data-counter="' + counter++ + '">');
|
2575
|
+
ripples.unshift(elem);
|
2576
|
+
states.unshift({ animating: true });
|
2577
|
+
container.append(elem);
|
2578
|
+
css && elem.css(css);
|
2579
|
+
return elem;
|
2580
|
+
}
|
2581
|
+
|
2582
|
+
/**
|
2583
|
+
* Calculate the ripple size
|
2584
|
+
*
|
2585
|
+
* @returns {number} calculated ripple diameter
|
2586
|
+
*/
|
2587
|
+
function getRippleSize(left, top) {
|
2588
|
+
var width = container.prop('offsetWidth'),
|
2589
|
+
height = container.prop('offsetHeight'),
|
2590
|
+
multiplier, size, rect;
|
2591
|
+
if (options.isMenuItem) {
|
2592
|
+
size = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
|
2593
|
+
} else if (options.outline) {
|
2594
|
+
rect = node.getBoundingClientRect();
|
2595
|
+
left -= rect.left;
|
2596
|
+
top -= rect.top;
|
2597
|
+
width = Math.max(left, width - left);
|
2598
|
+
height = Math.max(top, height - top);
|
2599
|
+
size = 2 * Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
|
2600
|
+
} else {
|
2601
|
+
multiplier = options.fullRipple ? 1.1 : 0.8;
|
2602
|
+
size = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)) * multiplier;
|
2603
|
+
if (options.fitRipple) {
|
2604
|
+
size = Math.min(height, width, size);
|
2605
|
+
}
|
2606
|
+
}
|
2607
|
+
return size;
|
2608
|
+
}
|
2609
|
+
|
2610
|
+
/**
|
2611
|
+
* Generates the ripple css
|
2612
|
+
*
|
2613
|
+
* @param {number} the diameter of the ripple
|
2614
|
+
* @param {number} the left cursor offset
|
2615
|
+
* @param {number} the top cursor offset
|
2616
|
+
*
|
2617
|
+
* @returns {{backgroundColor: string, borderColor: string, width: string, height: string}}
|
2618
|
+
*/
|
2619
|
+
function getRippleCss(size, left, top) {
|
2620
|
+
var rect = node.getBoundingClientRect(),
|
2621
|
+
css = {
|
2622
|
+
backgroundColor: rgbaToRGB(color),
|
2623
|
+
borderColor: rgbaToRGB(color),
|
2624
|
+
width: size + 'px',
|
2625
|
+
height: size + 'px'
|
2626
|
+
};
|
2627
|
+
|
2628
|
+
if (options.outline) {
|
2629
|
+
css.width = 0;
|
2630
|
+
css.height = 0;
|
2631
|
+
} else {
|
2632
|
+
css.marginLeft = css.marginTop = (size * -0.5) + 'px';
|
2633
|
+
}
|
2634
|
+
|
2635
|
+
if (options.center) {
|
2636
|
+
css.left = css.top = '50%';
|
2637
|
+
} else {
|
2638
|
+
css.left = Math.round((left - rect.left) / container.prop('offsetWidth') * 100) + '%';
|
2639
|
+
css.top = Math.round((top - rect.top) / container.prop('offsetHeight') * 100) + '%';
|
2640
|
+
}
|
2641
|
+
|
2642
|
+
return css;
|
2643
|
+
|
2644
|
+
/**
|
2645
|
+
* Converts rgba string to rgb, removing the alpha value
|
2646
|
+
*
|
2647
|
+
* @param {string} rgba color
|
2648
|
+
*
|
2649
|
+
* @returns {string} rgb color
|
2650
|
+
*/
|
2651
|
+
function rgbaToRGB(color) {
|
2652
|
+
return color.replace('rgba', 'rgb').replace(/,[^\),]+\)/, ')');
|
2653
|
+
}
|
2654
|
+
}
|
2655
|
+
}
|
2656
|
+
|
2657
|
+
/**
|
2658
|
+
* Handles user input start and stop events
|
2659
|
+
*
|
2660
|
+
*/
|
2661
|
+
function onPressDown(ev) {
|
2662
|
+
if (!isRippleAllowed()) return;
|
2663
|
+
|
2664
|
+
createRipple(ev.pointer.x, ev.pointer.y);
|
2665
|
+
isHeld = true;
|
2666
|
+
}
|
2667
|
+
function onPressUp() {
|
2668
|
+
isHeld = false;
|
2669
|
+
var ripple = ripples[ ripples.length - 1 ];
|
2670
|
+
$timeout(function () { updateElement(ripple); }, 0, false);
|
2671
|
+
}
|
2672
|
+
|
2673
|
+
/**
|
2674
|
+
* Determines if the ripple is allowed
|
2675
|
+
*
|
2676
|
+
* @returns {boolean} true if the ripple is allowed, false if not
|
2677
|
+
*/
|
2678
|
+
function isRippleAllowed() {
|
2679
|
+
var parent = node.parentNode;
|
2680
|
+
var grandparent = parent && parent.parentNode;
|
2681
|
+
var ancestor = grandparent && grandparent.parentNode;
|
2682
|
+
return !isDisabled(node) && !isDisabled(parent) && !isDisabled(grandparent) && !isDisabled(ancestor);
|
2683
|
+
function isDisabled (elem) {
|
2684
|
+
return elem && elem.hasAttribute && elem.hasAttribute('disabled');
|
2685
|
+
}
|
2686
|
+
}
|
2687
|
+
|
2688
|
+
}
|
2689
|
+
}
|
2690
|
+
InkRippleService.$inject = ["$window", "$timeout"];
|
2691
|
+
|
2692
|
+
/**
|
2693
|
+
* noink/nobar/nostretch directive: make any element that has one of
|
2694
|
+
* these attributes be given a controller, so that other directives can
|
2695
|
+
* `require:` these and see if there is a `no<xxx>` parent attribute.
|
2696
|
+
*
|
2697
|
+
* @usage
|
2698
|
+
* <hljs lang="html">
|
2699
|
+
* <parent md-no-ink>
|
2700
|
+
* <child detect-no>
|
2701
|
+
* </child>
|
2702
|
+
* </parent>
|
2703
|
+
* </hljs>
|
2704
|
+
*
|
2705
|
+
* <hljs lang="js">
|
2706
|
+
* myApp.directive('detectNo', function() {
|
2707
|
+
* return {
|
2708
|
+
* require: ['^?mdNoInk', ^?mdNoBar'],
|
2709
|
+
* link: function(scope, element, attr, ctrls) {
|
2710
|
+
* var noinkCtrl = ctrls[0];
|
2711
|
+
* var nobarCtrl = ctrls[1];
|
2712
|
+
* if (noInkCtrl) {
|
2713
|
+
* alert("the md-no-ink flag has been specified on an ancestor!");
|
2714
|
+
* }
|
2715
|
+
* if (nobarCtrl) {
|
2716
|
+
* alert("the md-no-bar flag has been specified on an ancestor!");
|
2717
|
+
* }
|
2718
|
+
* }
|
2719
|
+
* };
|
2720
|
+
* });
|
2721
|
+
* </hljs>
|
2722
|
+
*/
|
2723
|
+
function attrNoDirective() {
|
2724
|
+
return function() {
|
2725
|
+
return {
|
2726
|
+
controller: angular.noop
|
2727
|
+
};
|
2728
|
+
};
|
2729
|
+
}
|
2730
|
+
|
2731
|
+
(function() {
|
2732
|
+
'use strict';
|
2733
|
+
|
2734
|
+
/**
|
2735
|
+
* @ngdoc service
|
2736
|
+
* @name $mdTabInkRipple
|
2737
|
+
* @module material.core
|
2738
|
+
*
|
2739
|
+
* @description
|
2740
|
+
* Provides ripple effects for md-tabs. See $mdInkRipple service for all possible configuration options.
|
2741
|
+
*
|
2742
|
+
* @param {object=} scope Scope within the current context
|
2743
|
+
* @param {object=} element The element the ripple effect should be applied to
|
2744
|
+
* @param {object=} options (Optional) Configuration options to override the defaultripple configuration
|
2745
|
+
*/
|
2746
|
+
|
2747
|
+
angular.module('material.core')
|
2748
|
+
.factory('$mdTabInkRipple', MdTabInkRipple);
|
2749
|
+
|
2750
|
+
function MdTabInkRipple($mdInkRipple) {
|
2751
|
+
return {
|
2752
|
+
attach: attach
|
2753
|
+
};
|
2754
|
+
|
2755
|
+
function attach(scope, element, options) {
|
2756
|
+
return $mdInkRipple.attach(scope, element, angular.extend({
|
2757
|
+
center: false,
|
2758
|
+
dimBackground: true,
|
2759
|
+
outline: false,
|
2760
|
+
rippleSize: 'full'
|
2761
|
+
}, options));
|
2762
|
+
};
|
2763
|
+
}
|
2764
|
+
MdTabInkRipple.$inject = ["$mdInkRipple"];;
|
2765
|
+
})();
|
2766
|
+
|
2767
|
+
angular.module('material.core.theming.palette', [])
|
2768
|
+
.constant('$mdColorPalette', {
|
2769
|
+
'red': {
|
2770
|
+
'50': '#ffebee',
|
2771
|
+
'100': '#ffcdd2',
|
2772
|
+
'200': '#ef9a9a',
|
2773
|
+
'300': '#e57373',
|
2774
|
+
'400': '#ef5350',
|
2775
|
+
'500': '#f44336',
|
2776
|
+
'600': '#e53935',
|
2777
|
+
'700': '#d32f2f',
|
2778
|
+
'800': '#c62828',
|
2779
|
+
'900': '#b71c1c',
|
2780
|
+
'A100': '#ff8a80',
|
2781
|
+
'A200': '#ff5252',
|
2782
|
+
'A400': '#ff1744',
|
2783
|
+
'A700': '#d50000',
|
2784
|
+
'contrastDefaultColor': 'light',
|
2785
|
+
'contrastDarkColors': '50 100 200 300 400 A100',
|
2786
|
+
'contrastStrongLightColors': '500 600 700 A200 A400 A700'
|
2787
|
+
},
|
2788
|
+
'pink': {
|
2789
|
+
'50': '#fce4ec',
|
2790
|
+
'100': '#f8bbd0',
|
2791
|
+
'200': '#f48fb1',
|
2792
|
+
'300': '#f06292',
|
2793
|
+
'400': '#ec407a',
|
2794
|
+
'500': '#e91e63',
|
2795
|
+
'600': '#d81b60',
|
2796
|
+
'700': '#c2185b',
|
2797
|
+
'800': '#ad1457',
|
2798
|
+
'900': '#880e4f',
|
2799
|
+
'A100': '#ff80ab',
|
2800
|
+
'A200': '#ff4081',
|
2801
|
+
'A400': '#f50057',
|
2802
|
+
'A700': '#c51162',
|
2803
|
+
'contrastDefaultColor': 'light',
|
2804
|
+
'contrastDarkColors': '50 100 200 300 400 A100',
|
2805
|
+
'contrastStrongLightColors': '500 600 A200 A400 A700'
|
2806
|
+
},
|
2807
|
+
'purple': {
|
2808
|
+
'50': '#f3e5f5',
|
2809
|
+
'100': '#e1bee7',
|
2810
|
+
'200': '#ce93d8',
|
2811
|
+
'300': '#ba68c8',
|
2812
|
+
'400': '#ab47bc',
|
2813
|
+
'500': '#9c27b0',
|
2814
|
+
'600': '#8e24aa',
|
2815
|
+
'700': '#7b1fa2',
|
2816
|
+
'800': '#6a1b9a',
|
2817
|
+
'900': '#4a148c',
|
2818
|
+
'A100': '#ea80fc',
|
2819
|
+
'A200': '#e040fb',
|
2820
|
+
'A400': '#d500f9',
|
2821
|
+
'A700': '#aa00ff',
|
2822
|
+
'contrastDefaultColor': 'light',
|
2823
|
+
'contrastDarkColors': '50 100 200 A100',
|
2824
|
+
'contrastStrongLightColors': '300 400 A200 A400 A700'
|
2825
|
+
},
|
2826
|
+
'deep-purple': {
|
2827
|
+
'50': '#ede7f6',
|
2828
|
+
'100': '#d1c4e9',
|
2829
|
+
'200': '#b39ddb',
|
2830
|
+
'300': '#9575cd',
|
2831
|
+
'400': '#7e57c2',
|
2832
|
+
'500': '#673ab7',
|
2833
|
+
'600': '#5e35b1',
|
2834
|
+
'700': '#512da8',
|
2835
|
+
'800': '#4527a0',
|
2836
|
+
'900': '#311b92',
|
2837
|
+
'A100': '#b388ff',
|
2838
|
+
'A200': '#7c4dff',
|
2839
|
+
'A400': '#651fff',
|
2840
|
+
'A700': '#6200ea',
|
2841
|
+
'contrastDefaultColor': 'light',
|
2842
|
+
'contrastDarkColors': '50 100 200 A100',
|
2843
|
+
'contrastStrongLightColors': '300 400 A200'
|
2844
|
+
},
|
2845
|
+
'indigo': {
|
2846
|
+
'50': '#e8eaf6',
|
2847
|
+
'100': '#c5cae9',
|
2848
|
+
'200': '#9fa8da',
|
2849
|
+
'300': '#7986cb',
|
2850
|
+
'400': '#5c6bc0',
|
2851
|
+
'500': '#3f51b5',
|
2852
|
+
'600': '#3949ab',
|
2853
|
+
'700': '#303f9f',
|
2854
|
+
'800': '#283593',
|
2855
|
+
'900': '#1a237e',
|
2856
|
+
'A100': '#8c9eff',
|
2857
|
+
'A200': '#536dfe',
|
2858
|
+
'A400': '#3d5afe',
|
2859
|
+
'A700': '#304ffe',
|
2860
|
+
'contrastDefaultColor': 'light',
|
2861
|
+
'contrastDarkColors': '50 100 200 A100',
|
2862
|
+
'contrastStrongLightColors': '300 400 A200 A400'
|
2863
|
+
},
|
2864
|
+
'blue': {
|
2865
|
+
'50': '#e3f2fd',
|
2866
|
+
'100': '#bbdefb',
|
2867
|
+
'200': '#90caf9',
|
2868
|
+
'300': '#64b5f6',
|
2869
|
+
'400': '#42a5f5',
|
2870
|
+
'500': '#2196f3',
|
2871
|
+
'600': '#1e88e5',
|
2872
|
+
'700': '#1976d2',
|
2873
|
+
'800': '#1565c0',
|
2874
|
+
'900': '#0d47a1',
|
2875
|
+
'A100': '#82b1ff',
|
2876
|
+
'A200': '#448aff',
|
2877
|
+
'A400': '#2979ff',
|
2878
|
+
'A700': '#2962ff',
|
2879
|
+
'contrastDefaultColor': 'light',
|
2880
|
+
'contrastDarkColors': '100 200 300 400 A100',
|
2881
|
+
'contrastStrongLightColors': '500 600 700 A200 A400 A700'
|
2882
|
+
},
|
2883
|
+
'light-blue': {
|
2884
|
+
'50': '#e1f5fe',
|
2885
|
+
'100': '#b3e5fc',
|
2886
|
+
'200': '#81d4fa',
|
2887
|
+
'300': '#4fc3f7',
|
2888
|
+
'400': '#29b6f6',
|
2889
|
+
'500': '#03a9f4',
|
2890
|
+
'600': '#039be5',
|
2891
|
+
'700': '#0288d1',
|
2892
|
+
'800': '#0277bd',
|
2893
|
+
'900': '#01579b',
|
2894
|
+
'A100': '#80d8ff',
|
2895
|
+
'A200': '#40c4ff',
|
2896
|
+
'A400': '#00b0ff',
|
2897
|
+
'A700': '#0091ea',
|
2898
|
+
'contrastDefaultColor': 'dark',
|
2899
|
+
'contrastLightColors': '500 600 700 800 900 A700',
|
2900
|
+
'contrastStrongLightColors': '500 600 700 800 A700'
|
2901
|
+
},
|
2902
|
+
'cyan': {
|
2903
|
+
'50': '#e0f7fa',
|
2904
|
+
'100': '#b2ebf2',
|
2905
|
+
'200': '#80deea',
|
2906
|
+
'300': '#4dd0e1',
|
2907
|
+
'400': '#26c6da',
|
2908
|
+
'500': '#00bcd4',
|
2909
|
+
'600': '#00acc1',
|
2910
|
+
'700': '#0097a7',
|
2911
|
+
'800': '#00838f',
|
2912
|
+
'900': '#006064',
|
2913
|
+
'A100': '#84ffff',
|
2914
|
+
'A200': '#18ffff',
|
2915
|
+
'A400': '#00e5ff',
|
2916
|
+
'A700': '#00b8d4',
|
2917
|
+
'contrastDefaultColor': 'dark',
|
2918
|
+
'contrastLightColors': '500 600 700 800 900',
|
2919
|
+
'contrastStrongLightColors': '500 600 700 800'
|
2920
|
+
},
|
2921
|
+
'teal': {
|
2922
|
+
'50': '#e0f2f1',
|
2923
|
+
'100': '#b2dfdb',
|
2924
|
+
'200': '#80cbc4',
|
2925
|
+
'300': '#4db6ac',
|
2926
|
+
'400': '#26a69a',
|
2927
|
+
'500': '#009688',
|
2928
|
+
'600': '#00897b',
|
2929
|
+
'700': '#00796b',
|
2930
|
+
'800': '#00695c',
|
2931
|
+
'900': '#004d40',
|
2932
|
+
'A100': '#a7ffeb',
|
2933
|
+
'A200': '#64ffda',
|
2934
|
+
'A400': '#1de9b6',
|
2935
|
+
'A700': '#00bfa5',
|
2936
|
+
'contrastDefaultColor': 'dark',
|
2937
|
+
'contrastLightColors': '500 600 700 800 900',
|
2938
|
+
'contrastStrongLightColors': '500 600 700'
|
2939
|
+
},
|
2940
|
+
'green': {
|
2941
|
+
'50': '#e8f5e9',
|
2942
|
+
'100': '#c8e6c9',
|
2943
|
+
'200': '#a5d6a7',
|
2944
|
+
'300': '#81c784',
|
2945
|
+
'400': '#66bb6a',
|
2946
|
+
'500': '#4caf50',
|
2947
|
+
'600': '#43a047',
|
2948
|
+
'700': '#388e3c',
|
2949
|
+
'800': '#2e7d32',
|
2950
|
+
'900': '#1b5e20',
|
2951
|
+
'A100': '#b9f6ca',
|
2952
|
+
'A200': '#69f0ae',
|
2953
|
+
'A400': '#00e676',
|
2954
|
+
'A700': '#00c853',
|
2955
|
+
'contrastDefaultColor': 'dark',
|
2956
|
+
'contrastLightColors': '500 600 700 800 900',
|
2957
|
+
'contrastStrongLightColors': '500 600 700'
|
2958
|
+
},
|
2959
|
+
'light-green': {
|
2960
|
+
'50': '#f1f8e9',
|
2961
|
+
'100': '#dcedc8',
|
2962
|
+
'200': '#c5e1a5',
|
2963
|
+
'300': '#aed581',
|
2964
|
+
'400': '#9ccc65',
|
2965
|
+
'500': '#8bc34a',
|
2966
|
+
'600': '#7cb342',
|
2967
|
+
'700': '#689f38',
|
2968
|
+
'800': '#558b2f',
|
2969
|
+
'900': '#33691e',
|
2970
|
+
'A100': '#ccff90',
|
2971
|
+
'A200': '#b2ff59',
|
2972
|
+
'A400': '#76ff03',
|
2973
|
+
'A700': '#64dd17',
|
2974
|
+
'contrastDefaultColor': 'dark',
|
2975
|
+
'contrastLightColors': '800 900',
|
2976
|
+
'contrastStrongLightColors': '800 900'
|
2977
|
+
},
|
2978
|
+
'lime': {
|
2979
|
+
'50': '#f9fbe7',
|
2980
|
+
'100': '#f0f4c3',
|
2981
|
+
'200': '#e6ee9c',
|
2982
|
+
'300': '#dce775',
|
2983
|
+
'400': '#d4e157',
|
2984
|
+
'500': '#cddc39',
|
2985
|
+
'600': '#c0ca33',
|
2986
|
+
'700': '#afb42b',
|
2987
|
+
'800': '#9e9d24',
|
2988
|
+
'900': '#827717',
|
2989
|
+
'A100': '#f4ff81',
|
2990
|
+
'A200': '#eeff41',
|
2991
|
+
'A400': '#c6ff00',
|
2992
|
+
'A700': '#aeea00',
|
2993
|
+
'contrastDefaultColor': 'dark',
|
2994
|
+
'contrastLightColors': '900',
|
2995
|
+
'contrastStrongLightColors': '900'
|
2996
|
+
},
|
2997
|
+
'yellow': {
|
2998
|
+
'50': '#fffde7',
|
2999
|
+
'100': '#fff9c4',
|
3000
|
+
'200': '#fff59d',
|
3001
|
+
'300': '#fff176',
|
3002
|
+
'400': '#ffee58',
|
3003
|
+
'500': '#ffeb3b',
|
3004
|
+
'600': '#fdd835',
|
3005
|
+
'700': '#fbc02d',
|
3006
|
+
'800': '#f9a825',
|
3007
|
+
'900': '#f57f17',
|
3008
|
+
'A100': '#ffff8d',
|
3009
|
+
'A200': '#ffff00',
|
3010
|
+
'A400': '#ffea00',
|
3011
|
+
'A700': '#ffd600',
|
3012
|
+
'contrastDefaultColor': 'dark'
|
3013
|
+
},
|
3014
|
+
'amber': {
|
3015
|
+
'50': '#fff8e1',
|
3016
|
+
'100': '#ffecb3',
|
3017
|
+
'200': '#ffe082',
|
3018
|
+
'300': '#ffd54f',
|
3019
|
+
'400': '#ffca28',
|
3020
|
+
'500': '#ffc107',
|
3021
|
+
'600': '#ffb300',
|
3022
|
+
'700': '#ffa000',
|
3023
|
+
'800': '#ff8f00',
|
3024
|
+
'900': '#ff6f00',
|
3025
|
+
'A100': '#ffe57f',
|
3026
|
+
'A200': '#ffd740',
|
3027
|
+
'A400': '#ffc400',
|
3028
|
+
'A700': '#ffab00',
|
3029
|
+
'contrastDefaultColor': 'dark'
|
3030
|
+
},
|
3031
|
+
'orange': {
|
3032
|
+
'50': '#fff3e0',
|
3033
|
+
'100': '#ffe0b2',
|
3034
|
+
'200': '#ffcc80',
|
3035
|
+
'300': '#ffb74d',
|
3036
|
+
'400': '#ffa726',
|
3037
|
+
'500': '#ff9800',
|
3038
|
+
'600': '#fb8c00',
|
3039
|
+
'700': '#f57c00',
|
3040
|
+
'800': '#ef6c00',
|
3041
|
+
'900': '#e65100',
|
3042
|
+
'A100': '#ffd180',
|
3043
|
+
'A200': '#ffab40',
|
3044
|
+
'A400': '#ff9100',
|
3045
|
+
'A700': '#ff6d00',
|
3046
|
+
'contrastDefaultColor': 'dark',
|
3047
|
+
'contrastLightColors': '800 900',
|
3048
|
+
'contrastStrongLightColors': '800 900'
|
3049
|
+
},
|
3050
|
+
'deep-orange': {
|
3051
|
+
'50': '#fbe9e7',
|
3052
|
+
'100': '#ffccbc',
|
3053
|
+
'200': '#ffab91',
|
3054
|
+
'300': '#ff8a65',
|
3055
|
+
'400': '#ff7043',
|
3056
|
+
'500': '#ff5722',
|
3057
|
+
'600': '#f4511e',
|
3058
|
+
'700': '#e64a19',
|
3059
|
+
'800': '#d84315',
|
3060
|
+
'900': '#bf360c',
|
3061
|
+
'A100': '#ff9e80',
|
3062
|
+
'A200': '#ff6e40',
|
3063
|
+
'A400': '#ff3d00',
|
3064
|
+
'A700': '#dd2c00',
|
3065
|
+
'contrastDefaultColor': 'light',
|
3066
|
+
'contrastDarkColors': '50 100 200 300 400 A100 A200',
|
3067
|
+
'contrastStrongLightColors': '500 600 700 800 900 A400 A700'
|
3068
|
+
},
|
3069
|
+
'brown': {
|
3070
|
+
'50': '#efebe9',
|
3071
|
+
'100': '#d7ccc8',
|
3072
|
+
'200': '#bcaaa4',
|
3073
|
+
'300': '#a1887f',
|
3074
|
+
'400': '#8d6e63',
|
3075
|
+
'500': '#795548',
|
3076
|
+
'600': '#6d4c41',
|
3077
|
+
'700': '#5d4037',
|
3078
|
+
'800': '#4e342e',
|
3079
|
+
'900': '#3e2723',
|
3080
|
+
'A100': '#d7ccc8',
|
3081
|
+
'A200': '#bcaaa4',
|
3082
|
+
'A400': '#8d6e63',
|
3083
|
+
'A700': '#5d4037',
|
3084
|
+
'contrastDefaultColor': 'light',
|
3085
|
+
'contrastDarkColors': '50 100 200',
|
3086
|
+
'contrastStrongLightColors': '300 400'
|
3087
|
+
},
|
3088
|
+
'grey': {
|
3089
|
+
'50': '#fafafa',
|
3090
|
+
'100': '#f5f5f5',
|
3091
|
+
'200': '#eeeeee',
|
3092
|
+
'300': '#e0e0e0',
|
3093
|
+
'400': '#bdbdbd',
|
3094
|
+
'500': '#9e9e9e',
|
3095
|
+
'600': '#757575',
|
3096
|
+
'700': '#616161',
|
3097
|
+
'800': '#424242',
|
3098
|
+
'900': '#212121',
|
3099
|
+
'1000': '#000000',
|
3100
|
+
'A100': '#ffffff',
|
3101
|
+
'A200': '#eeeeee',
|
3102
|
+
'A400': '#bdbdbd',
|
3103
|
+
'A700': '#616161',
|
3104
|
+
'contrastDefaultColor': 'dark',
|
3105
|
+
'contrastLightColors': '600 700 800 900'
|
3106
|
+
},
|
3107
|
+
'blue-grey': {
|
3108
|
+
'50': '#eceff1',
|
3109
|
+
'100': '#cfd8dc',
|
3110
|
+
'200': '#b0bec5',
|
3111
|
+
'300': '#90a4ae',
|
3112
|
+
'400': '#78909c',
|
3113
|
+
'500': '#607d8b',
|
3114
|
+
'600': '#546e7a',
|
3115
|
+
'700': '#455a64',
|
3116
|
+
'800': '#37474f',
|
3117
|
+
'900': '#263238',
|
3118
|
+
'A100': '#cfd8dc',
|
3119
|
+
'A200': '#b0bec5',
|
3120
|
+
'A400': '#78909c',
|
3121
|
+
'A700': '#455a64',
|
3122
|
+
'contrastDefaultColor': 'light',
|
3123
|
+
'contrastDarkColors': '50 100 200 300',
|
3124
|
+
'contrastStrongLightColors': '400 500'
|
3125
|
+
}
|
3126
|
+
});
|
3127
|
+
|
3128
|
+
angular.module('material.core.theming', ['material.core.theming.palette'])
|
3129
|
+
.directive('mdTheme', ThemingDirective)
|
3130
|
+
.directive('mdThemable', ThemableDirective)
|
3131
|
+
.provider('$mdTheming', ThemingProvider)
|
3132
|
+
.run(generateThemes);
|
3133
|
+
|
3134
|
+
/**
|
3135
|
+
* @ngdoc provider
|
3136
|
+
* @name $mdThemingProvider
|
3137
|
+
* @module material.core
|
3138
|
+
*
|
3139
|
+
* @description Provider to configure the `$mdTheming` service.
|
3140
|
+
*/
|
3141
|
+
|
3142
|
+
/**
|
3143
|
+
* @ngdoc method
|
3144
|
+
* @name $mdThemingProvider#setDefaultTheme
|
3145
|
+
* @param {string} themeName Default theme name to be applied to elements. Default value is `default`.
|
3146
|
+
*/
|
3147
|
+
|
3148
|
+
/**
|
3149
|
+
* @ngdoc method
|
3150
|
+
* @name $mdThemingProvider#alwaysWatchTheme
|
3151
|
+
* @param {boolean} watch Whether or not to always watch themes for changes and re-apply
|
3152
|
+
* classes when they change. Default is `false`. Enabling can reduce performance.
|
3153
|
+
*/
|
3154
|
+
|
3155
|
+
/* Some Example Valid Theming Expressions
|
3156
|
+
* =======================================
|
3157
|
+
*
|
3158
|
+
* Intention group expansion: (valid for primary, accent, warn, background)
|
3159
|
+
*
|
3160
|
+
* {{primary-100}} - grab shade 100 from the primary palette
|
3161
|
+
* {{primary-100-0.7}} - grab shade 100, apply opacity of 0.7
|
3162
|
+
* {{primary-hue-1}} - grab the shade assigned to hue-1 from the primary palette
|
3163
|
+
* {{primary-hue-1-0.7}} - apply 0.7 opacity to primary-hue-1
|
3164
|
+
* {{primary-color}} - Generates .md-hue-1, .md-hue-2, .md-hue-3 with configured shades set for each hue
|
3165
|
+
* {{primary-color-0.7}} - Apply 0.7 opacity to each of the above rules
|
3166
|
+
* {{primary-contrast}} - Generates .md-hue-1, .md-hue-2, .md-hue-3 with configured contrast (ie. text) color shades set for each hue
|
3167
|
+
* {{primary-contrast-0.7}} - Apply 0.7 opacity to each of the above rules
|
3168
|
+
*
|
3169
|
+
* Foreground expansion: Applies rgba to black/white foreground text
|
3170
|
+
*
|
3171
|
+
* {{foreground-1}} - used for primary text
|
3172
|
+
* {{foreground-2}} - used for secondary text/divider
|
3173
|
+
* {{foreground-3}} - used for disabled text
|
3174
|
+
* {{foreground-4}} - used for dividers
|
3175
|
+
*
|
3176
|
+
*/
|
3177
|
+
|
3178
|
+
// In memory generated CSS rules; registered by theme.name
|
3179
|
+
var GENERATED = { };
|
3180
|
+
|
3181
|
+
// In memory storage of defined themes and color palettes (both loaded by CSS, and user specified)
|
3182
|
+
var PALETTES;
|
3183
|
+
var THEMES;
|
3184
|
+
|
3185
|
+
var DARK_FOREGROUND = {
|
3186
|
+
name: 'dark',
|
3187
|
+
'1': 'rgba(0,0,0,0.87)',
|
3188
|
+
'2': 'rgba(0,0,0,0.54)',
|
3189
|
+
'3': 'rgba(0,0,0,0.26)',
|
3190
|
+
'4': 'rgba(0,0,0,0.12)'
|
3191
|
+
};
|
3192
|
+
var LIGHT_FOREGROUND = {
|
3193
|
+
name: 'light',
|
3194
|
+
'1': 'rgba(255,255,255,1.0)',
|
3195
|
+
'2': 'rgba(255,255,255,0.7)',
|
3196
|
+
'3': 'rgba(255,255,255,0.3)',
|
3197
|
+
'4': 'rgba(255,255,255,0.12)'
|
3198
|
+
};
|
3199
|
+
|
3200
|
+
var DARK_SHADOW = '1px 1px 0px rgba(0,0,0,0.4), -1px -1px 0px rgba(0,0,0,0.4)';
|
3201
|
+
var LIGHT_SHADOW = '';
|
3202
|
+
|
3203
|
+
var DARK_CONTRAST_COLOR = colorToRgbaArray('rgba(0,0,0,0.87)');
|
3204
|
+
var LIGHT_CONTRAST_COLOR = colorToRgbaArray('rgba(255,255,255,0.87');
|
3205
|
+
var STRONG_LIGHT_CONTRAST_COLOR = colorToRgbaArray('rgb(255,255,255)');
|
3206
|
+
|
3207
|
+
var THEME_COLOR_TYPES = ['primary', 'accent', 'warn', 'background'];
|
3208
|
+
var DEFAULT_COLOR_TYPE = 'primary';
|
3209
|
+
|
3210
|
+
// A color in a theme will use these hues by default, if not specified by user.
|
3211
|
+
var LIGHT_DEFAULT_HUES = {
|
3212
|
+
'accent': {
|
3213
|
+
'default': 'A200',
|
3214
|
+
'hue-1': 'A100',
|
3215
|
+
'hue-2': 'A400',
|
3216
|
+
'hue-3': 'A700'
|
3217
|
+
},
|
3218
|
+
'background': {
|
3219
|
+
'default': 'A100',
|
3220
|
+
'hue-1': '300',
|
3221
|
+
'hue-2': '800',
|
3222
|
+
'hue-3': '900'
|
3223
|
+
}
|
3224
|
+
};
|
3225
|
+
|
3226
|
+
var DARK_DEFAULT_HUES = {
|
3227
|
+
'background': {
|
3228
|
+
'default': '800',
|
3229
|
+
'hue-1': '300',
|
3230
|
+
'hue-2': '600',
|
3231
|
+
'hue-3': '900'
|
3232
|
+
}
|
3233
|
+
};
|
3234
|
+
THEME_COLOR_TYPES.forEach(function(colorType) {
|
3235
|
+
// Color types with unspecified default hues will use these default hue values
|
3236
|
+
var defaultDefaultHues = {
|
3237
|
+
'default': '500',
|
3238
|
+
'hue-1': '300',
|
3239
|
+
'hue-2': '800',
|
3240
|
+
'hue-3': 'A100'
|
3241
|
+
};
|
3242
|
+
if (!LIGHT_DEFAULT_HUES[colorType]) LIGHT_DEFAULT_HUES[colorType] = defaultDefaultHues;
|
3243
|
+
if (!DARK_DEFAULT_HUES[colorType]) DARK_DEFAULT_HUES[colorType] = defaultDefaultHues;
|
3244
|
+
});
|
3245
|
+
|
3246
|
+
var VALID_HUE_VALUES = [
|
3247
|
+
'50', '100', '200', '300', '400', '500', '600',
|
3248
|
+
'700', '800', '900', 'A100', 'A200', 'A400', 'A700'
|
3249
|
+
];
|
3250
|
+
|
3251
|
+
function ThemingProvider($mdColorPalette) {
|
3252
|
+
PALETTES = { };
|
3253
|
+
THEMES = { };
|
3254
|
+
|
3255
|
+
var themingProvider;
|
3256
|
+
var defaultTheme = 'default';
|
3257
|
+
var alwaysWatchTheme = false;
|
3258
|
+
|
3259
|
+
// Load JS Defined Palettes
|
3260
|
+
angular.extend(PALETTES, $mdColorPalette);
|
3261
|
+
|
3262
|
+
// Default theme defined in core.js
|
3263
|
+
|
3264
|
+
ThemingService.$inject = ["$rootScope", "$log"];
|
3265
|
+
return themingProvider = {
|
3266
|
+
definePalette: definePalette,
|
3267
|
+
extendPalette: extendPalette,
|
3268
|
+
theme: registerTheme,
|
3269
|
+
|
3270
|
+
setDefaultTheme: function(theme) {
|
3271
|
+
defaultTheme = theme;
|
3272
|
+
},
|
3273
|
+
alwaysWatchTheme: function(alwaysWatch) {
|
3274
|
+
alwaysWatchTheme = alwaysWatch;
|
3275
|
+
},
|
3276
|
+
$get: ThemingService,
|
3277
|
+
_LIGHT_DEFAULT_HUES: LIGHT_DEFAULT_HUES,
|
3278
|
+
_DARK_DEFAULT_HUES: DARK_DEFAULT_HUES,
|
3279
|
+
_PALETTES: PALETTES,
|
3280
|
+
_THEMES: THEMES,
|
3281
|
+
_parseRules: parseRules,
|
3282
|
+
_rgba: rgba
|
3283
|
+
};
|
3284
|
+
|
3285
|
+
// Example: $mdThemingProvider.definePalette('neonRed', { 50: '#f5fafa', ... });
|
3286
|
+
function definePalette(name, map) {
|
3287
|
+
map = map || {};
|
3288
|
+
PALETTES[name] = checkPaletteValid(name, map);
|
3289
|
+
return themingProvider;
|
3290
|
+
}
|
3291
|
+
|
3292
|
+
// Returns an new object which is a copy of a given palette `name` with variables from
|
3293
|
+
// `map` overwritten
|
3294
|
+
// Example: var neonRedMap = $mdThemingProvider.extendPalette('red', { 50: '#f5fafafa' });
|
3295
|
+
function extendPalette(name, map) {
|
3296
|
+
return checkPaletteValid(name, angular.extend({}, PALETTES[name] || {}, map) );
|
3297
|
+
}
|
3298
|
+
|
3299
|
+
// Make sure that palette has all required hues
|
3300
|
+
function checkPaletteValid(name, map) {
|
3301
|
+
var missingColors = VALID_HUE_VALUES.filter(function(field) {
|
3302
|
+
return !map[field];
|
3303
|
+
});
|
3304
|
+
if (missingColors.length) {
|
3305
|
+
throw new Error("Missing colors %1 in palette %2!"
|
3306
|
+
.replace('%1', missingColors.join(', '))
|
3307
|
+
.replace('%2', name));
|
3308
|
+
}
|
3309
|
+
|
3310
|
+
return map;
|
3311
|
+
}
|
3312
|
+
|
3313
|
+
// Register a theme (which is a collection of color palettes to use with various states
|
3314
|
+
// ie. warn, accent, primary )
|
3315
|
+
// Optionally inherit from an existing theme
|
3316
|
+
// $mdThemingProvider.theme('custom-theme').primaryPalette('red');
|
3317
|
+
function registerTheme(name, inheritFrom) {
|
3318
|
+
if (THEMES[name]) return THEMES[name];
|
3319
|
+
|
3320
|
+
inheritFrom = inheritFrom || 'default';
|
3321
|
+
|
3322
|
+
var parentTheme = typeof inheritFrom === 'string' ? THEMES[inheritFrom] : inheritFrom;
|
3323
|
+
var theme = new Theme(name);
|
3324
|
+
|
3325
|
+
if (parentTheme) {
|
3326
|
+
angular.forEach(parentTheme.colors, function(color, colorType) {
|
3327
|
+
theme.colors[colorType] = {
|
3328
|
+
name: color.name,
|
3329
|
+
// Make sure a COPY of the hues is given to the child color,
|
3330
|
+
// not the same reference.
|
3331
|
+
hues: angular.extend({}, color.hues)
|
3332
|
+
};
|
3333
|
+
});
|
3334
|
+
}
|
3335
|
+
THEMES[name] = theme;
|
3336
|
+
|
3337
|
+
return theme;
|
3338
|
+
}
|
3339
|
+
|
3340
|
+
function Theme(name) {
|
3341
|
+
var self = this;
|
3342
|
+
self.name = name;
|
3343
|
+
self.colors = {};
|
3344
|
+
|
3345
|
+
self.dark = setDark;
|
3346
|
+
setDark(false);
|
3347
|
+
|
3348
|
+
function setDark(isDark) {
|
3349
|
+
isDark = arguments.length === 0 ? true : !!isDark;
|
3350
|
+
|
3351
|
+
// If no change, abort
|
3352
|
+
if (isDark === self.isDark) return;
|
3353
|
+
|
3354
|
+
self.isDark = isDark;
|
3355
|
+
|
3356
|
+
self.foregroundPalette = self.isDark ? LIGHT_FOREGROUND : DARK_FOREGROUND;
|
3357
|
+
self.foregroundShadow = self.isDark ? DARK_SHADOW : LIGHT_SHADOW;
|
3358
|
+
|
3359
|
+
// Light and dark themes have different default hues.
|
3360
|
+
// Go through each existing color type for this theme, and for every
|
3361
|
+
// hue value that is still the default hue value from the previous light/dark setting,
|
3362
|
+
// set it to the default hue value from the new light/dark setting.
|
3363
|
+
var newDefaultHues = self.isDark ? DARK_DEFAULT_HUES : LIGHT_DEFAULT_HUES;
|
3364
|
+
var oldDefaultHues = self.isDark ? LIGHT_DEFAULT_HUES : DARK_DEFAULT_HUES;
|
3365
|
+
angular.forEach(newDefaultHues, function(newDefaults, colorType) {
|
3366
|
+
var color = self.colors[colorType];
|
3367
|
+
var oldDefaults = oldDefaultHues[colorType];
|
3368
|
+
if (color) {
|
3369
|
+
for (var hueName in color.hues) {
|
3370
|
+
if (color.hues[hueName] === oldDefaults[hueName]) {
|
3371
|
+
color.hues[hueName] = newDefaults[hueName];
|
3372
|
+
}
|
3373
|
+
}
|
3374
|
+
}
|
3375
|
+
});
|
3376
|
+
|
3377
|
+
return self;
|
3378
|
+
}
|
3379
|
+
|
3380
|
+
THEME_COLOR_TYPES.forEach(function(colorType) {
|
3381
|
+
var defaultHues = (self.isDark ? DARK_DEFAULT_HUES : LIGHT_DEFAULT_HUES)[colorType];
|
3382
|
+
self[colorType + 'Palette'] = function setPaletteType(paletteName, hues) {
|
3383
|
+
var color = self.colors[colorType] = {
|
3384
|
+
name: paletteName,
|
3385
|
+
hues: angular.extend({}, defaultHues, hues)
|
3386
|
+
};
|
3387
|
+
|
3388
|
+
Object.keys(color.hues).forEach(function(name) {
|
3389
|
+
if (!defaultHues[name]) {
|
3390
|
+
throw new Error("Invalid hue name '%1' in theme %2's %3 color %4. Available hue names: %4"
|
3391
|
+
.replace('%1', name)
|
3392
|
+
.replace('%2', self.name)
|
3393
|
+
.replace('%3', paletteName)
|
3394
|
+
.replace('%4', Object.keys(defaultHues).join(', '))
|
3395
|
+
);
|
3396
|
+
}
|
3397
|
+
});
|
3398
|
+
Object.keys(color.hues).map(function(key) {
|
3399
|
+
return color.hues[key];
|
3400
|
+
}).forEach(function(hueValue) {
|
3401
|
+
if (VALID_HUE_VALUES.indexOf(hueValue) == -1) {
|
3402
|
+
throw new Error("Invalid hue value '%1' in theme %2's %3 color %4. Available hue values: %5"
|
3403
|
+
.replace('%1', hueValue)
|
3404
|
+
.replace('%2', self.name)
|
3405
|
+
.replace('%3', colorType)
|
3406
|
+
.replace('%4', paletteName)
|
3407
|
+
.replace('%5', VALID_HUE_VALUES.join(', '))
|
3408
|
+
);
|
3409
|
+
}
|
3410
|
+
});
|
3411
|
+
return self;
|
3412
|
+
};
|
3413
|
+
|
3414
|
+
self[colorType + 'Color'] = function() {
|
3415
|
+
var args = Array.prototype.slice.call(arguments);
|
3416
|
+
console.warn('$mdThemingProviderTheme.' + colorType + 'Color() has been deprecated. ' +
|
3417
|
+
'Use $mdThemingProviderTheme.' + colorType + 'Palette() instead.');
|
3418
|
+
return self[colorType + 'Palette'].apply(self, args);
|
3419
|
+
};
|
3420
|
+
});
|
3421
|
+
}
|
3422
|
+
|
3423
|
+
/**
|
3424
|
+
* @ngdoc service
|
3425
|
+
* @name $mdTheming
|
3426
|
+
*
|
3427
|
+
* @description
|
3428
|
+
*
|
3429
|
+
* Service that makes an element apply theming related classes to itself.
|
3430
|
+
*
|
3431
|
+
* ```js
|
3432
|
+
* app.directive('myFancyDirective', function($mdTheming) {
|
3433
|
+
* return {
|
3434
|
+
* restrict: 'e',
|
3435
|
+
* link: function(scope, el, attrs) {
|
3436
|
+
* $mdTheming(el);
|
3437
|
+
* }
|
3438
|
+
* };
|
3439
|
+
* });
|
3440
|
+
* ```
|
3441
|
+
* @param {el=} element to apply theming to
|
3442
|
+
*/
|
3443
|
+
/* ngInject */
|
3444
|
+
function ThemingService($rootScope, $log) {
|
3445
|
+
|
3446
|
+
applyTheme.inherit = function(el, parent) {
|
3447
|
+
var ctrl = parent.controller('mdTheme');
|
3448
|
+
|
3449
|
+
var attrThemeValue = el.attr('md-theme-watch');
|
3450
|
+
if ( (alwaysWatchTheme || angular.isDefined(attrThemeValue)) && attrThemeValue != 'false') {
|
3451
|
+
var deregisterWatch = $rootScope.$watch(function() {
|
3452
|
+
return ctrl && ctrl.$mdTheme || defaultTheme;
|
3453
|
+
}, changeTheme);
|
3454
|
+
el.on('$destroy', deregisterWatch);
|
3455
|
+
} else {
|
3456
|
+
var theme = ctrl && ctrl.$mdTheme || defaultTheme;
|
3457
|
+
changeTheme(theme);
|
3458
|
+
}
|
3459
|
+
|
3460
|
+
function changeTheme(theme) {
|
3461
|
+
if (!registered(theme)) {
|
3462
|
+
$log.warn('Attempted to use unregistered theme \'' + theme + '\'. ' +
|
3463
|
+
'Register it with $mdThemingProvider.theme().');
|
3464
|
+
}
|
3465
|
+
var oldTheme = el.data('$mdThemeName');
|
3466
|
+
if (oldTheme) el.removeClass('md-' + oldTheme +'-theme');
|
3467
|
+
el.addClass('md-' + theme + '-theme');
|
3468
|
+
el.data('$mdThemeName', theme);
|
3469
|
+
}
|
3470
|
+
};
|
3471
|
+
|
3472
|
+
applyTheme.THEMES = angular.extend({}, THEMES);
|
3473
|
+
applyTheme.defaultTheme = function() { return defaultTheme; };
|
3474
|
+
applyTheme.registered = registered;
|
3475
|
+
|
3476
|
+
return applyTheme;
|
3477
|
+
|
3478
|
+
function registered(themeName) {
|
3479
|
+
if (themeName === undefined || themeName === '') return true;
|
3480
|
+
return applyTheme.THEMES[themeName] !== undefined;
|
3481
|
+
}
|
3482
|
+
|
3483
|
+
function applyTheme(scope, el) {
|
3484
|
+
// Allow us to be invoked via a linking function signature.
|
3485
|
+
if (el === undefined) {
|
3486
|
+
el = scope;
|
3487
|
+
scope = undefined;
|
3488
|
+
}
|
3489
|
+
if (scope === undefined) {
|
3490
|
+
scope = $rootScope;
|
3491
|
+
}
|
3492
|
+
applyTheme.inherit(el, el);
|
3493
|
+
}
|
3494
|
+
}
|
3495
|
+
}
|
3496
|
+
ThemingProvider.$inject = ["$mdColorPalette"];
|
3497
|
+
|
3498
|
+
function ThemingDirective($mdTheming, $interpolate, $log) {
|
3499
|
+
return {
|
3500
|
+
priority: 100,
|
3501
|
+
link: {
|
3502
|
+
pre: function(scope, el, attrs) {
|
3503
|
+
var ctrl = {
|
3504
|
+
$setTheme: function(theme) {
|
3505
|
+
if (!$mdTheming.registered(theme)) {
|
3506
|
+
$log.warn('attempted to use unregistered theme \'' + theme + '\'');
|
3507
|
+
}
|
3508
|
+
ctrl.$mdTheme = theme;
|
3509
|
+
}
|
3510
|
+
};
|
3511
|
+
el.data('$mdThemeController', ctrl);
|
3512
|
+
ctrl.$setTheme($interpolate(attrs.mdTheme)(scope));
|
3513
|
+
attrs.$observe('mdTheme', ctrl.$setTheme);
|
3514
|
+
}
|
3515
|
+
}
|
3516
|
+
};
|
3517
|
+
}
|
3518
|
+
ThemingDirective.$inject = ["$mdTheming", "$interpolate", "$log"];
|
3519
|
+
|
3520
|
+
function ThemableDirective($mdTheming) {
|
3521
|
+
return $mdTheming;
|
3522
|
+
}
|
3523
|
+
ThemableDirective.$inject = ["$mdTheming"];
|
3524
|
+
|
3525
|
+
function parseRules(theme, colorType, rules) {
|
3526
|
+
checkValidPalette(theme, colorType);
|
3527
|
+
|
3528
|
+
rules = rules.replace(/THEME_NAME/g, theme.name);
|
3529
|
+
var generatedRules = [];
|
3530
|
+
var color = theme.colors[colorType];
|
3531
|
+
|
3532
|
+
var themeNameRegex = new RegExp('.md-' + theme.name + '-theme', 'g');
|
3533
|
+
// Matches '{{ primary-color }}', etc
|
3534
|
+
var hueRegex = new RegExp('(\'|")?{{\\s*(' + colorType + ')-(color|contrast)-?(\\d\\.?\\d*)?\\s*}}(\"|\')?','g');
|
3535
|
+
var simpleVariableRegex = /'?"?\{\{\s*([a-zA-Z]+)-(A?\d+|hue\-[0-3]|shadow)-?(\d\.?\d*)?\s*\}\}'?"?/g;
|
3536
|
+
var palette = PALETTES[color.name];
|
3537
|
+
|
3538
|
+
// find and replace simple variables where we use a specific hue, not an entire palette
|
3539
|
+
// eg. "{{primary-100}}"
|
3540
|
+
//\(' + THEME_COLOR_TYPES.join('\|') + '\)'
|
3541
|
+
rules = rules.replace(simpleVariableRegex, function(match, colorType, hue, opacity) {
|
3542
|
+
if (colorType === 'foreground') {
|
3543
|
+
if (hue == 'shadow') {
|
3544
|
+
return theme.foregroundShadow;
|
3545
|
+
} else {
|
3546
|
+
return theme.foregroundPalette[hue] || theme.foregroundPalette['1'];
|
3547
|
+
}
|
3548
|
+
}
|
3549
|
+
if (hue.indexOf('hue') === 0) {
|
3550
|
+
hue = theme.colors[colorType].hues[hue];
|
3551
|
+
}
|
3552
|
+
return rgba( (PALETTES[ theme.colors[colorType].name ][hue] || '').value, opacity );
|
3553
|
+
});
|
3554
|
+
|
3555
|
+
// For each type, generate rules for each hue (ie. default, md-hue-1, md-hue-2, md-hue-3)
|
3556
|
+
angular.forEach(color.hues, function(hueValue, hueName) {
|
3557
|
+
var newRule = rules
|
3558
|
+
.replace(hueRegex, function(match, _, colorType, hueType, opacity) {
|
3559
|
+
return rgba(palette[hueValue][hueType === 'color' ? 'value' : 'contrast'], opacity);
|
3560
|
+
});
|
3561
|
+
if (hueName !== 'default') {
|
3562
|
+
newRule = newRule.replace(themeNameRegex, '.md-' + theme.name + '-theme.md-' + hueName);
|
3563
|
+
}
|
3564
|
+
|
3565
|
+
// Don't apply a selector rule to the default theme, making it easier to override
|
3566
|
+
// styles of the base-component
|
3567
|
+
if (theme.name == 'default') {
|
3568
|
+
newRule = newRule.replace(/\.md-default-theme/g, '');
|
3569
|
+
}
|
3570
|
+
generatedRules.push(newRule);
|
3571
|
+
});
|
3572
|
+
|
3573
|
+
return generatedRules;
|
3574
|
+
}
|
3575
|
+
|
3576
|
+
// Generate our themes at run time given the state of THEMES and PALETTES
|
3577
|
+
function generateThemes($injector) {
|
3578
|
+
|
3579
|
+
var head = document.getElementsByTagName('head')[0];
|
3580
|
+
var firstChild = head ? head.firstElementChild : null;
|
3581
|
+
var themeCss = $injector.has('$MD_THEME_CSS') ? $injector.get('$MD_THEME_CSS') : '';
|
3582
|
+
|
3583
|
+
if ( !firstChild ) return;
|
3584
|
+
if (themeCss.length === 0) return; // no rules, so no point in running this expensive task
|
3585
|
+
|
3586
|
+
// Expose contrast colors for palettes to ensure that text is always readable
|
3587
|
+
angular.forEach(PALETTES, sanitizePalette);
|
3588
|
+
|
3589
|
+
// MD_THEME_CSS is a string generated by the build process that includes all the themable
|
3590
|
+
// components as templates
|
3591
|
+
|
3592
|
+
// Break the CSS into individual rules
|
3593
|
+
var rulesByType = {};
|
3594
|
+
var rules = themeCss
|
3595
|
+
.split(/\}(?!(\}|'|"|;))/)
|
3596
|
+
.filter(function(rule) { return rule && rule.length; })
|
3597
|
+
.map(function(rule) { return rule.trim() + '}'; });
|
3598
|
+
|
3599
|
+
|
3600
|
+
var ruleMatchRegex = new RegExp('md-(' + THEME_COLOR_TYPES.join('|') + ')', 'g');
|
3601
|
+
|
3602
|
+
THEME_COLOR_TYPES.forEach(function(type) {
|
3603
|
+
rulesByType[type] = '';
|
3604
|
+
});
|
3605
|
+
|
3606
|
+
|
3607
|
+
// Sort the rules based on type, allowing us to do color substitution on a per-type basis
|
3608
|
+
rules.forEach(function(rule) {
|
3609
|
+
var match = rule.match(ruleMatchRegex);
|
3610
|
+
// First: test that if the rule has '.md-accent', it goes into the accent set of rules
|
3611
|
+
for (var i = 0, type; type = THEME_COLOR_TYPES[i]; i++) {
|
3612
|
+
if (rule.indexOf('.md-' + type) > -1) {
|
3613
|
+
return rulesByType[type] += rule;
|
3614
|
+
}
|
3615
|
+
}
|
3616
|
+
|
3617
|
+
// If no eg 'md-accent' class is found, try to just find 'accent' in the rule and guess from
|
3618
|
+
// there
|
3619
|
+
for (i = 0; type = THEME_COLOR_TYPES[i]; i++) {
|
3620
|
+
if (rule.indexOf(type) > -1) {
|
3621
|
+
return rulesByType[type] += rule;
|
3622
|
+
}
|
3623
|
+
}
|
3624
|
+
|
3625
|
+
// Default to the primary array
|
3626
|
+
return rulesByType[DEFAULT_COLOR_TYPE] += rule;
|
3627
|
+
});
|
3628
|
+
|
3629
|
+
// For each theme, use the color palettes specified for
|
3630
|
+
// `primary`, `warn` and `accent` to generate CSS rules.
|
3631
|
+
|
3632
|
+
angular.forEach(THEMES, function(theme) {
|
3633
|
+
if ( !GENERATED[theme.name] ) {
|
3634
|
+
|
3635
|
+
|
3636
|
+
THEME_COLOR_TYPES.forEach(function(colorType) {
|
3637
|
+
var styleStrings = parseRules(theme, colorType, rulesByType[colorType]);
|
3638
|
+
while (styleStrings.length) {
|
3639
|
+
var style = document.createElement('style');
|
3640
|
+
style.setAttribute('type', 'text/css');
|
3641
|
+
style.appendChild(document.createTextNode(styleStrings.shift()));
|
3642
|
+
head.insertBefore(style, firstChild);
|
3643
|
+
}
|
3644
|
+
});
|
3645
|
+
|
3646
|
+
|
3647
|
+
if (theme.colors.primary.name == theme.colors.accent.name) {
|
3648
|
+
console.warn("$mdThemingProvider: Using the same palette for primary and" +
|
3649
|
+
" accent. This violates the material design spec.");
|
3650
|
+
}
|
3651
|
+
|
3652
|
+
GENERATED[theme.name] = true;
|
3653
|
+
}
|
3654
|
+
});
|
3655
|
+
|
3656
|
+
|
3657
|
+
// *************************
|
3658
|
+
// Internal functions
|
3659
|
+
// *************************
|
3660
|
+
|
3661
|
+
// The user specifies a 'default' contrast color as either light or dark,
|
3662
|
+
// then explicitly lists which hues are the opposite contrast (eg. A100 has dark, A200 has light)
|
3663
|
+
function sanitizePalette(palette) {
|
3664
|
+
var defaultContrast = palette.contrastDefaultColor;
|
3665
|
+
var lightColors = palette.contrastLightColors || [];
|
3666
|
+
var strongLightColors = palette.contrastStrongLightColors || [];
|
3667
|
+
var darkColors = palette.contrastDarkColors || [];
|
3668
|
+
|
3669
|
+
// These colors are provided as space-separated lists
|
3670
|
+
if (typeof lightColors === 'string') lightColors = lightColors.split(' ');
|
3671
|
+
if (typeof strongLightColors === 'string') strongLightColors = strongLightColors.split(' ');
|
3672
|
+
if (typeof darkColors === 'string') darkColors = darkColors.split(' ');
|
3673
|
+
|
3674
|
+
// Cleanup after ourselves
|
3675
|
+
delete palette.contrastDefaultColor;
|
3676
|
+
delete palette.contrastLightColors;
|
3677
|
+
delete palette.contrastStrongLightColors;
|
3678
|
+
delete palette.contrastDarkColors;
|
3679
|
+
|
3680
|
+
// Change { 'A100': '#fffeee' } to { 'A100': { value: '#fffeee', contrast:DARK_CONTRAST_COLOR }
|
3681
|
+
angular.forEach(palette, function(hueValue, hueName) {
|
3682
|
+
if (angular.isObject(hueValue)) return; // Already converted
|
3683
|
+
// Map everything to rgb colors
|
3684
|
+
var rgbValue = colorToRgbaArray(hueValue);
|
3685
|
+
if (!rgbValue) {
|
3686
|
+
throw new Error("Color %1, in palette %2's hue %3, is invalid. Hex or rgb(a) color expected."
|
3687
|
+
.replace('%1', hueValue)
|
3688
|
+
.replace('%2', palette.name)
|
3689
|
+
.replace('%3', hueName));
|
3690
|
+
}
|
3691
|
+
|
3692
|
+
palette[hueName] = {
|
3693
|
+
value: rgbValue,
|
3694
|
+
contrast: getContrastColor()
|
3695
|
+
};
|
3696
|
+
function getContrastColor() {
|
3697
|
+
if (defaultContrast === 'light') {
|
3698
|
+
if (darkColors.indexOf(hueName) > -1) {
|
3699
|
+
return DARK_CONTRAST_COLOR;
|
3700
|
+
} else {
|
3701
|
+
return strongLightColors.indexOf(hueName) > -1 ? STRONG_LIGHT_CONTRAST_COLOR
|
3702
|
+
: LIGHT_CONTRAST_COLOR;
|
3703
|
+
}
|
3704
|
+
} else {
|
3705
|
+
if (lightColors.indexOf(hueName) > -1) {
|
3706
|
+
return strongLightColors.indexOf(hueName) > -1 ? STRONG_LIGHT_CONTRAST_COLOR
|
3707
|
+
: LIGHT_CONTRAST_COLOR;
|
3708
|
+
} else {
|
3709
|
+
return DARK_CONTRAST_COLOR;
|
3710
|
+
}
|
3711
|
+
}
|
3712
|
+
}
|
3713
|
+
});
|
3714
|
+
}
|
3715
|
+
|
3716
|
+
|
3717
|
+
}
|
3718
|
+
generateThemes.$inject = ["$injector"];
|
3719
|
+
|
3720
|
+
function checkValidPalette(theme, colorType) {
|
3721
|
+
// If theme attempts to use a palette that doesnt exist, throw error
|
3722
|
+
if (!PALETTES[ (theme.colors[colorType] || {}).name ]) {
|
3723
|
+
throw new Error(
|
3724
|
+
"You supplied an invalid color palette for theme %1's %2 palette. Available palettes: %3"
|
3725
|
+
.replace('%1', theme.name)
|
3726
|
+
.replace('%2', colorType)
|
3727
|
+
.replace('%3', Object.keys(PALETTES).join(', '))
|
3728
|
+
);
|
3729
|
+
}
|
3730
|
+
}
|
3731
|
+
|
3732
|
+
function colorToRgbaArray(clr) {
|
3733
|
+
if (angular.isArray(clr) && clr.length == 3) return clr;
|
3734
|
+
if (/^rgb/.test(clr)) {
|
3735
|
+
return clr.replace(/(^\s*rgba?\(|\)\s*$)/g, '').split(',').map(function(value, i) {
|
3736
|
+
return i == 3 ? parseFloat(value, 10) : parseInt(value, 10);
|
3737
|
+
});
|
3738
|
+
}
|
3739
|
+
if (clr.charAt(0) == '#') clr = clr.substring(1);
|
3740
|
+
if (!/^([a-fA-F0-9]{3}){1,2}$/g.test(clr)) return;
|
3741
|
+
|
3742
|
+
var dig = clr.length / 3;
|
3743
|
+
var red = clr.substr(0, dig);
|
3744
|
+
var grn = clr.substr(dig, dig);
|
3745
|
+
var blu = clr.substr(dig * 2);
|
3746
|
+
if (dig === 1) {
|
3747
|
+
red += red;
|
3748
|
+
grn += grn;
|
3749
|
+
blu += blu;
|
3750
|
+
}
|
3751
|
+
return [parseInt(red, 16), parseInt(grn, 16), parseInt(blu, 16)];
|
3752
|
+
}
|
3753
|
+
|
3754
|
+
function rgba(rgbArray, opacity) {
|
3755
|
+
if ( !rgbArray ) return "rgb('0,0,0')";
|
3756
|
+
|
3757
|
+
if (rgbArray.length == 4) {
|
3758
|
+
rgbArray = angular.copy(rgbArray);
|
3759
|
+
opacity ? rgbArray.pop() : opacity = rgbArray.pop();
|
3760
|
+
}
|
3761
|
+
return opacity && (typeof opacity == 'number' || (typeof opacity == 'string' && opacity.length)) ?
|
3762
|
+
'rgba(' + rgbArray.join(',') + ',' + opacity + ')' :
|
3763
|
+
'rgb(' + rgbArray.join(',') + ')';
|
3764
|
+
}
|
3765
|
+
|
3766
|
+
|
3767
|
+
(function(){
|
3768
|
+
angular.module("material.core").constant("$MD_THEME_CSS", "/* mixin definition ; sets LTR and RTL within the same style call */md-autocomplete.md-THEME_NAME-theme { background: '{{background-50}}'; } md-autocomplete.md-THEME_NAME-theme[disabled] { background: '{{background-100}}'; } md-autocomplete.md-THEME_NAME-theme button md-icon path { fill: '{{background-600}}'; } md-autocomplete.md-THEME_NAME-theme button:after { background: '{{background-600-0.3}}'; }.md-autocomplete-suggestions.md-THEME_NAME-theme { background: '{{background-50}}'; } .md-autocomplete-suggestions.md-THEME_NAME-theme li { color: '{{background-900}}'; } .md-autocomplete-suggestions.md-THEME_NAME-theme li .highlight { color: '{{background-600}}'; } .md-autocomplete-suggestions.md-THEME_NAME-theme li:hover, .md-autocomplete-suggestions.md-THEME_NAME-theme li.selected { background: '{{background-200}}'; }md-backdrop.md-opaque.md-THEME_NAME-theme { background-color: '{{foreground-4-0.5}}'; }md-bottom-sheet.md-THEME_NAME-theme { background-color: '{{background-50}}'; border-top-color: '{{background-300}}'; } md-bottom-sheet.md-THEME_NAME-theme.md-list md-list-item { color: '{{foreground-1}}'; } md-bottom-sheet.md-THEME_NAME-theme .md-subheader { background-color: '{{background-50}}'; } md-bottom-sheet.md-THEME_NAME-theme .md-subheader { color: '{{foreground-1}}'; }a.md-button.md-THEME_NAME-theme, .md-button.md-THEME_NAME-theme { border-radius: 3px; } a.md-button.md-THEME_NAME-theme:not([disabled]):hover, .md-button.md-THEME_NAME-theme:not([disabled]):hover { background-color: '{{background-500-0.2}}'; } a.md-button.md-THEME_NAME-theme:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme:not([disabled]).md-focused { background-color: '{{background-500-0.2}}'; } a.md-button.md-THEME_NAME-theme:not([disabled]).md-icon-button:hover, .md-button.md-THEME_NAME-theme:not([disabled]).md-icon-button:hover { background-color: transparent; } a.md-button.md-THEME_NAME-theme.md-fab, .md-button.md-THEME_NAME-theme.md-fab { border-radius: 50%; background-color: '{{accent-color}}'; color: '{{accent-contrast}}'; } a.md-button.md-THEME_NAME-theme.md-fab md-icon, .md-button.md-THEME_NAME-theme.md-fab md-icon { color: '{{accent-contrast}}'; } a.md-button.md-THEME_NAME-theme.md-fab:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-fab:not([disabled]):hover { background-color: '{{accent-color}}'; } a.md-button.md-THEME_NAME-theme.md-fab:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-fab:not([disabled]).md-focused { background-color: '{{accent-A700}}'; } a.md-button.md-THEME_NAME-theme.md-icon-button, .md-button.md-THEME_NAME-theme.md-icon-button { border-radius: 50%; } a.md-button.md-THEME_NAME-theme.md-primary, .md-button.md-THEME_NAME-theme.md-primary { color: '{{primary-color}}'; } a.md-button.md-THEME_NAME-theme.md-primary.md-raised, a.md-button.md-THEME_NAME-theme.md-primary.md-fab, .md-button.md-THEME_NAME-theme.md-primary.md-raised, .md-button.md-THEME_NAME-theme.md-primary.md-fab { color: '{{primary-contrast}}'; background-color: '{{primary-color}}'; } a.md-button.md-THEME_NAME-theme.md-primary.md-raised:not([disabled]) md-icon, a.md-button.md-THEME_NAME-theme.md-primary.md-fab:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-primary.md-raised:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-primary.md-fab:not([disabled]) md-icon { color: '{{primary-contrast}}'; } a.md-button.md-THEME_NAME-theme.md-primary.md-raised:not([disabled]):hover, a.md-button.md-THEME_NAME-theme.md-primary.md-fab:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-primary.md-raised:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-primary.md-fab:not([disabled]):hover { background-color: '{{primary-color}}'; } a.md-button.md-THEME_NAME-theme.md-primary.md-raised:not([disabled]).md-focused, a.md-button.md-THEME_NAME-theme.md-primary.md-fab:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-primary.md-raised:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-primary.md-fab:not([disabled]).md-focused { background-color: '{{primary-600}}'; } a.md-button.md-THEME_NAME-theme.md-primary:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-primary:not([disabled]) md-icon { color: '{{primary-color}}'; } a.md-button.md-THEME_NAME-theme.md-fab, .md-button.md-THEME_NAME-theme.md-fab { border-radius: 50%; background-color: '{{accent-color}}'; color: '{{accent-contrast}}'; } a.md-button.md-THEME_NAME-theme.md-fab:not([disabled]) .md-icon, .md-button.md-THEME_NAME-theme.md-fab:not([disabled]) .md-icon { color: '{{accent-contrast}}'; } a.md-button.md-THEME_NAME-theme.md-fab:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-fab:not([disabled]):hover { background-color: '{{accent-color}}'; } a.md-button.md-THEME_NAME-theme.md-fab:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-fab:not([disabled]).md-focused { background-color: '{{accent-A700}}'; } a.md-button.md-THEME_NAME-theme.md-raised, .md-button.md-THEME_NAME-theme.md-raised { color: '{{background-contrast}}'; background-color: '{{background-50}}'; } a.md-button.md-THEME_NAME-theme.md-raised:not([disabled]) .md-icon, .md-button.md-THEME_NAME-theme.md-raised:not([disabled]) .md-icon { color: '{{background-contrast}}'; } a.md-button.md-THEME_NAME-theme.md-raised:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-raised:not([disabled]):hover { background-color: '{{background-50}}'; } a.md-button.md-THEME_NAME-theme.md-raised:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-raised:not([disabled]).md-focused { background-color: '{{background-200}}'; } a.md-button.md-THEME_NAME-theme.md-warn, .md-button.md-THEME_NAME-theme.md-warn { color: '{{warn-color}}'; } a.md-button.md-THEME_NAME-theme.md-warn.md-raised, a.md-button.md-THEME_NAME-theme.md-warn.md-fab, .md-button.md-THEME_NAME-theme.md-warn.md-raised, .md-button.md-THEME_NAME-theme.md-warn.md-fab { color: '{{warn-contrast}}'; background-color: '{{warn-color}}'; } a.md-button.md-THEME_NAME-theme.md-warn.md-raised:not([disabled]) md-icon, a.md-button.md-THEME_NAME-theme.md-warn.md-fab:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-warn.md-raised:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-warn.md-fab:not([disabled]) md-icon { color: '{{warn-contrast}}'; } a.md-button.md-THEME_NAME-theme.md-warn.md-raised:not([disabled]):hover, a.md-button.md-THEME_NAME-theme.md-warn.md-fab:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-warn.md-raised:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-warn.md-fab:not([disabled]):hover { background-color: '{{warn-color}}'; } a.md-button.md-THEME_NAME-theme.md-warn.md-raised:not([disabled]).md-focused, a.md-button.md-THEME_NAME-theme.md-warn.md-fab:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-warn.md-raised:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-warn.md-fab:not([disabled]).md-focused { background-color: '{{warn-700}}'; } a.md-button.md-THEME_NAME-theme.md-warn:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-warn:not([disabled]) md-icon { color: '{{warn-color}}'; } a.md-button.md-THEME_NAME-theme.md-accent, .md-button.md-THEME_NAME-theme.md-accent { color: '{{accent-color}}'; } a.md-button.md-THEME_NAME-theme.md-accent.md-raised, a.md-button.md-THEME_NAME-theme.md-accent.md-fab, .md-button.md-THEME_NAME-theme.md-accent.md-raised, .md-button.md-THEME_NAME-theme.md-accent.md-fab { color: '{{accent-contrast}}'; background-color: '{{accent-color}}'; } a.md-button.md-THEME_NAME-theme.md-accent.md-raised:not([disabled]) md-icon, a.md-button.md-THEME_NAME-theme.md-accent.md-fab:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-accent.md-raised:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-accent.md-fab:not([disabled]) md-icon { color: '{{accent-contrast}}'; } a.md-button.md-THEME_NAME-theme.md-accent.md-raised:not([disabled]):hover, a.md-button.md-THEME_NAME-theme.md-accent.md-fab:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-accent.md-raised:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-accent.md-fab:not([disabled]):hover { background-color: '{{accent-color}}'; } a.md-button.md-THEME_NAME-theme.md-accent.md-raised:not([disabled]).md-focused, a.md-button.md-THEME_NAME-theme.md-accent.md-fab:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-accent.md-raised:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-accent.md-fab:not([disabled]).md-focused { background-color: '{{accent-700}}'; } a.md-button.md-THEME_NAME-theme.md-accent:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-accent:not([disabled]) md-icon { color: '{{accent-color}}'; } a.md-button.md-THEME_NAME-theme[disabled], a.md-button.md-THEME_NAME-theme.md-raised[disabled], a.md-button.md-THEME_NAME-theme.md-fab[disabled], a.md-button.md-THEME_NAME-theme.md-accent[disabled], a.md-button.md-THEME_NAME-theme.md-warn[disabled], .md-button.md-THEME_NAME-theme[disabled], .md-button.md-THEME_NAME-theme.md-raised[disabled], .md-button.md-THEME_NAME-theme.md-fab[disabled], .md-button.md-THEME_NAME-theme.md-accent[disabled], .md-button.md-THEME_NAME-theme.md-warn[disabled] { color: '{{foreground-3}}'; cursor: not-allowed; } a.md-button.md-THEME_NAME-theme[disabled] md-icon, a.md-button.md-THEME_NAME-theme.md-raised[disabled] md-icon, a.md-button.md-THEME_NAME-theme.md-fab[disabled] md-icon, a.md-button.md-THEME_NAME-theme.md-accent[disabled] md-icon, a.md-button.md-THEME_NAME-theme.md-warn[disabled] md-icon, .md-button.md-THEME_NAME-theme[disabled] md-icon, .md-button.md-THEME_NAME-theme.md-raised[disabled] md-icon, .md-button.md-THEME_NAME-theme.md-fab[disabled] md-icon, .md-button.md-THEME_NAME-theme.md-accent[disabled] md-icon, .md-button.md-THEME_NAME-theme.md-warn[disabled] md-icon { color: '{{foreground-3}}'; } a.md-button.md-THEME_NAME-theme.md-raised[disabled], a.md-button.md-THEME_NAME-theme.md-fab[disabled], .md-button.md-THEME_NAME-theme.md-raised[disabled], .md-button.md-THEME_NAME-theme.md-fab[disabled] { background-color: '{{foreground-4}}'; } a.md-button.md-THEME_NAME-theme[disabled], .md-button.md-THEME_NAME-theme[disabled] { background-color: transparent; }md-card.md-THEME_NAME-theme { background-color: '{{background-color}}'; border-radius: 2px; } md-card.md-THEME_NAME-theme .md-card-image { border-radius: 2px 2px 0 0; }md-checkbox.md-THEME_NAME-theme .md-ripple { color: '{{accent-600}}'; }md-checkbox.md-THEME_NAME-theme.md-checked .md-ripple { color: '{{background-600}}'; }md-checkbox.md-THEME_NAME-theme.md-checked.md-focused .md-container:before { background-color: '{{accent-color-0.26}}'; }md-checkbox.md-THEME_NAME-theme .md-icon { border-color: '{{foreground-2}}'; }md-checkbox.md-THEME_NAME-theme.md-checked .md-icon { background-color: '{{accent-color-0.87}}'; }md-checkbox.md-THEME_NAME-theme.md-checked .md-icon:after { border-color: '{{background-200}}'; }md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary .md-ripple { color: '{{primary-600}}'; }md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-ripple { color: '{{background-600}}'; }md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary .md-icon { border-color: '{{foreground-2}}'; }md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-icon { background-color: '{{primary-color-0.87}}'; }md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked.md-focused .md-container:before { background-color: '{{primary-color-0.26}}'; }md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-icon:after { border-color: '{{background-200}}'; }md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn .md-ripple { color: '{{warn-600}}'; }md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn .md-icon { border-color: '{{foreground-2}}'; }md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked .md-icon { background-color: '{{warn-color-0.87}}'; }md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked.md-focused:not([disabled]) .md-container:before { background-color: '{{warn-color-0.26}}'; }md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked .md-icon:after { border-color: '{{background-200}}'; }md-checkbox.md-THEME_NAME-theme[disabled] .md-icon { border-color: '{{foreground-3}}'; }md-checkbox.md-THEME_NAME-theme[disabled].md-checked .md-icon { background-color: '{{foreground-3}}'; }md-checkbox.md-THEME_NAME-theme[disabled] .md-label { color: '{{foreground-3}}'; }md-chips.md-THEME_NAME-theme .md-chips { box-shadow: 0 1px '{{background-300}}'; } md-chips.md-THEME_NAME-theme .md-chips.md-focused { box-shadow: 0 2px '{{primary-color}}'; }md-chips.md-THEME_NAME-theme .md-chip { background: '{{background-300}}'; color: '{{background-800}}'; } md-chips.md-THEME_NAME-theme .md-chip.md-focused { background: '{{primary-color}}'; color: '{{primary-contrast}}'; } md-chips.md-THEME_NAME-theme .md-chip.md-focused md-icon { color: '{{primary-contrast}}'; }md-chips.md-THEME_NAME-theme md-chip-remove .md-button md-icon path { fill: '{{background-500}}'; }.md-contact-suggestion span.md-contact-email { color: '{{background-400}}'; }md-content.md-THEME_NAME-theme { background-color: '{{background-color}}'; }md-dialog.md-THEME_NAME-theme { border-radius: 4px; background-color: '{{background-color}}'; } md-dialog.md-THEME_NAME-theme.md-content-overflow .md-actions { border-top-color: '{{foreground-4}}'; }md-divider.md-THEME_NAME-theme { border-top-color: '{{foreground-4}}'; }md-icon.md-THEME_NAME-theme { color: '{{foreground-2}}'; } md-icon.md-THEME_NAME-theme.md-primary { color: '{{primary-color}}'; } md-icon.md-THEME_NAME-theme.md-accent { color: '{{accent-color}}'; } md-icon.md-THEME_NAME-theme.md-warn { color: '{{warn-color}}'; }md-input-container.md-THEME_NAME-theme .md-input { color: '{{foreground-1}}'; border-color: '{{foreground-4}}'; text-shadow: '{{foreground-shadow}}'; } md-input-container.md-THEME_NAME-theme .md-input::-webkit-input-placeholder, md-input-container.md-THEME_NAME-theme .md-input::-moz-placeholder, md-input-container.md-THEME_NAME-theme .md-input:-moz-placeholder, md-input-container.md-THEME_NAME-theme .md-input:-ms-input-placeholder { color: '{{foreground-3}}'; }md-input-container.md-THEME_NAME-theme > md-icon { color: '{{foreground-1}}'; }md-input-container.md-THEME_NAME-theme label, md-input-container.md-THEME_NAME-theme .md-placeholder { text-shadow: '{{foreground-shadow}}'; color: '{{foreground-3}}'; }md-input-container.md-THEME_NAME-theme ng-messages, md-input-container.md-THEME_NAME-theme [ng-message], md-input-container.md-THEME_NAME-theme [data-ng-message], md-input-container.md-THEME_NAME-theme [x-ng-message] { color: '{{warn-500}}'; }md-input-container.md-THEME_NAME-theme:not(.md-input-invalid).md-input-has-value label { color: '{{foreground-2}}'; }md-input-container.md-THEME_NAME-theme:not(.md-input-invalid).md-input-focused .md-input { border-color: '{{primary-500}}'; }md-input-container.md-THEME_NAME-theme:not(.md-input-invalid).md-input-focused label { color: '{{primary-500}}'; }md-input-container.md-THEME_NAME-theme:not(.md-input-invalid).md-input-focused md-icon { color: '{{primary-500}}'; }md-input-container.md-THEME_NAME-theme:not(.md-input-invalid).md-input-focused.md-accent .md-input { border-color: '{{accent-500}}'; }md-input-container.md-THEME_NAME-theme:not(.md-input-invalid).md-input-focused.md-accent label { color: '{{accent-500}}'; }md-input-container.md-THEME_NAME-theme:not(.md-input-invalid).md-input-focused.md-warn .md-input { border-color: '{{warn-500}}'; }md-input-container.md-THEME_NAME-theme:not(.md-input-invalid).md-input-focused.md-warn label { color: '{{warn-500}}'; }md-input-container.md-THEME_NAME-theme.md-input-invalid .md-input { border-color: '{{warn-500}}'; }md-input-container.md-THEME_NAME-theme.md-input-invalid.md-input-focused label { color: '{{warn-500}}'; }md-input-container.md-THEME_NAME-theme.md-input-invalid ng-message, md-input-container.md-THEME_NAME-theme.md-input-invalid data-ng-message, md-input-container.md-THEME_NAME-theme.md-input-invalid x-ng-message, md-input-container.md-THEME_NAME-theme.md-input-invalid [ng-message], md-input-container.md-THEME_NAME-theme.md-input-invalid [data-ng-message], md-input-container.md-THEME_NAME-theme.md-input-invalid [x-ng-message], md-input-container.md-THEME_NAME-theme.md-input-invalid .md-char-counter { color: '{{warn-500}}'; }md-input-container.md-THEME_NAME-theme .md-input[disabled], [disabled] md-input-container.md-THEME_NAME-theme .md-input { border-bottom-color: transparent; color: '{{foreground-3}}'; background-image: linear-gradient(to right, '{{foreground-3}}' 0%, '{{foreground-3}}' 33%, transparent 0%); background-image: -ms-linear-gradient(left, transparent 0%, '{{foreground-3}}' 100%); }md-list.md-THEME_NAME-theme md-list-item.md-2-line .md-list-item-text h3, md-list.md-THEME_NAME-theme md-list-item.md-2-line .md-list-item-text h4, md-list.md-THEME_NAME-theme md-list-item.md-3-line .md-list-item-text h3, md-list.md-THEME_NAME-theme md-list-item.md-3-line .md-list-item-text h4 { color: '{{foreground-1}}'; }md-list.md-THEME_NAME-theme md-list-item.md-2-line .md-list-item-text p, md-list.md-THEME_NAME-theme md-list-item.md-3-line .md-list-item-text p { color: '{{foreground-2}}'; }md-list.md-THEME_NAME-theme .md-proxy-focus.md-focused div.md-no-style { background-color: '{{background-100}}'; }md-list.md-THEME_NAME-theme md-list-item > md-icon { color: '{{foreground-2}}'; } md-list.md-THEME_NAME-theme md-list-item > md-icon.md-highlight { color: '{{primary-color}}'; } md-list.md-THEME_NAME-theme md-list-item > md-icon.md-highlight.md-accent { color: '{{accent-color}}'; }md-list.md-THEME_NAME-theme md-list-item button { background-color: '{{background-color}}'; } md-list.md-THEME_NAME-theme md-list-item button.md-button:not([disabled]):hover { background-color: '{{background-color}}'; }md-menu-content.md-THEME_NAME-theme { background-color: '{{background-color}}'; } md-menu-content.md-THEME_NAME-theme md-menu-divider { background-color: '{{foreground-4}}'; }md-progress-circular.md-THEME_NAME-theme { background-color: transparent; } md-progress-circular.md-THEME_NAME-theme .md-inner .md-gap { border-top-color: '{{primary-color}}'; border-bottom-color: '{{primary-color}}'; } md-progress-circular.md-THEME_NAME-theme .md-inner .md-left .md-half-circle, md-progress-circular.md-THEME_NAME-theme .md-inner .md-right .md-half-circle { border-top-color: '{{primary-color}}'; } md-progress-circular.md-THEME_NAME-theme .md-inner .md-right .md-half-circle { border-right-color: '{{primary-color}}'; } md-progress-circular.md-THEME_NAME-theme .md-inner .md-left .md-half-circle { border-left-color: '{{primary-color}}'; } md-progress-circular.md-THEME_NAME-theme.md-warn .md-inner .md-gap { border-top-color: '{{warn-color}}'; border-bottom-color: '{{warn-color}}'; } md-progress-circular.md-THEME_NAME-theme.md-warn .md-inner .md-left .md-half-circle, md-progress-circular.md-THEME_NAME-theme.md-warn .md-inner .md-right .md-half-circle { border-top-color: '{{warn-color}}'; } md-progress-circular.md-THEME_NAME-theme.md-warn .md-inner .md-right .md-half-circle { border-right-color: '{{warn-color}}'; } md-progress-circular.md-THEME_NAME-theme.md-warn .md-inner .md-left .md-half-circle { border-left-color: '{{warn-color}}'; } md-progress-circular.md-THEME_NAME-theme.md-accent .md-inner .md-gap { border-top-color: '{{accent-color}}'; border-bottom-color: '{{accent-color}}'; } md-progress-circular.md-THEME_NAME-theme.md-accent .md-inner .md-left .md-half-circle, md-progress-circular.md-THEME_NAME-theme.md-accent .md-inner .md-right .md-half-circle { border-top-color: '{{accent-color}}'; } md-progress-circular.md-THEME_NAME-theme.md-accent .md-inner .md-right .md-half-circle { border-right-color: '{{accent-color}}'; } md-progress-circular.md-THEME_NAME-theme.md-accent .md-inner .md-left .md-half-circle { border-left-color: '{{accent-color}}'; }md-progress-linear.md-THEME_NAME-theme .md-container { background-color: '{{primary-100}}'; }md-progress-linear.md-THEME_NAME-theme .md-bar { background-color: '{{primary-color}}'; }md-progress-linear.md-THEME_NAME-theme.md-warn .md-container { background-color: '{{warn-100}}'; }md-progress-linear.md-THEME_NAME-theme.md-warn .md-bar { background-color: '{{warn-color}}'; }md-progress-linear.md-THEME_NAME-theme.md-accent .md-container { background-color: '{{accent-100}}'; }md-progress-linear.md-THEME_NAME-theme.md-accent .md-bar { background-color: '{{accent-color}}'; }md-progress-linear.md-THEME_NAME-theme[md-mode=buffer].md-warn .md-bar1 { background-color: '{{warn-100}}'; }md-progress-linear.md-THEME_NAME-theme[md-mode=buffer].md-warn .md-dashed:before { background: radial-gradient('{{warn-100}}' 0%, '{{warn-100}}' 16%, transparent 42%); }md-progress-linear.md-THEME_NAME-theme[md-mode=buffer].md-accent .md-bar1 { background-color: '{{accent-100}}'; }md-progress-linear.md-THEME_NAME-theme[md-mode=buffer].md-accent .md-dashed:before { background: radial-gradient('{{accent-100}}' 0%, '{{accent-100}}' 16%, transparent 42%); }md-radio-button.md-THEME_NAME-theme .md-off { border-color: '{{foreground-2}}'; }md-radio-button.md-THEME_NAME-theme .md-on { background-color: '{{accent-color-0.87}}'; }md-radio-button.md-THEME_NAME-theme.md-checked .md-off { border-color: '{{accent-color-0.87}}'; }md-radio-button.md-THEME_NAME-theme.md-checked .md-ink-ripple { color: '{{accent-color-0.87}}'; }md-radio-button.md-THEME_NAME-theme .md-container .md-ripple { color: '{{accent-600}}'; }md-radio-group.md-THEME_NAME-theme:not([disabled]) .md-primary .md-on, md-radio-group.md-THEME_NAME-theme:not([disabled]).md-primary .md-on, md-radio-button.md-THEME_NAME-theme:not([disabled]) .md-primary .md-on, md-radio-button.md-THEME_NAME-theme:not([disabled]).md-primary .md-on { background-color: '{{primary-color-0.87}}'; }md-radio-group.md-THEME_NAME-theme:not([disabled]) .md-primary .md-checked .md-off, md-radio-group.md-THEME_NAME-theme:not([disabled]) .md-primary.md-checked .md-off, md-radio-group.md-THEME_NAME-theme:not([disabled]).md-primary .md-checked .md-off, md-radio-group.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-off, md-radio-button.md-THEME_NAME-theme:not([disabled]) .md-primary .md-checked .md-off, md-radio-button.md-THEME_NAME-theme:not([disabled]) .md-primary.md-checked .md-off, md-radio-button.md-THEME_NAME-theme:not([disabled]).md-primary .md-checked .md-off, md-radio-button.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-off { border-color: '{{primary-color-0.87}}'; }md-radio-group.md-THEME_NAME-theme:not([disabled]) .md-primary .md-checked .md-ink-ripple, md-radio-group.md-THEME_NAME-theme:not([disabled]) .md-primary.md-checked .md-ink-ripple, md-radio-group.md-THEME_NAME-theme:not([disabled]).md-primary .md-checked .md-ink-ripple, md-radio-group.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-ink-ripple, md-radio-button.md-THEME_NAME-theme:not([disabled]) .md-primary .md-checked .md-ink-ripple, md-radio-button.md-THEME_NAME-theme:not([disabled]) .md-primary.md-checked .md-ink-ripple, md-radio-button.md-THEME_NAME-theme:not([disabled]).md-primary .md-checked .md-ink-ripple, md-radio-button.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-ink-ripple { color: '{{primary-color-0.87}}'; }md-radio-group.md-THEME_NAME-theme:not([disabled]) .md-primary .md-container .md-ripple, md-radio-group.md-THEME_NAME-theme:not([disabled]).md-primary .md-container .md-ripple, md-radio-button.md-THEME_NAME-theme:not([disabled]) .md-primary .md-container .md-ripple, md-radio-button.md-THEME_NAME-theme:not([disabled]).md-primary .md-container .md-ripple { color: '{{primary-600}}'; }md-radio-group.md-THEME_NAME-theme:not([disabled]) .md-warn .md-on, md-radio-group.md-THEME_NAME-theme:not([disabled]).md-warn .md-on, md-radio-button.md-THEME_NAME-theme:not([disabled]) .md-warn .md-on, md-radio-button.md-THEME_NAME-theme:not([disabled]).md-warn .md-on { background-color: '{{warn-color-0.87}}'; }md-radio-group.md-THEME_NAME-theme:not([disabled]) .md-warn .md-checked .md-off, md-radio-group.md-THEME_NAME-theme:not([disabled]) .md-warn.md-checked .md-off, md-radio-group.md-THEME_NAME-theme:not([disabled]).md-warn .md-checked .md-off, md-radio-group.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked .md-off, md-radio-button.md-THEME_NAME-theme:not([disabled]) .md-warn .md-checked .md-off, md-radio-button.md-THEME_NAME-theme:not([disabled]) .md-warn.md-checked .md-off, md-radio-button.md-THEME_NAME-theme:not([disabled]).md-warn .md-checked .md-off, md-radio-button.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked .md-off { border-color: '{{warn-color-0.87}}'; }md-radio-group.md-THEME_NAME-theme:not([disabled]) .md-warn .md-checked .md-ink-ripple, md-radio-group.md-THEME_NAME-theme:not([disabled]) .md-warn.md-checked .md-ink-ripple, md-radio-group.md-THEME_NAME-theme:not([disabled]).md-warn .md-checked .md-ink-ripple, md-radio-group.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked .md-ink-ripple, md-radio-button.md-THEME_NAME-theme:not([disabled]) .md-warn .md-checked .md-ink-ripple, md-radio-button.md-THEME_NAME-theme:not([disabled]) .md-warn.md-checked .md-ink-ripple, md-radio-button.md-THEME_NAME-theme:not([disabled]).md-warn .md-checked .md-ink-ripple, md-radio-button.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked .md-ink-ripple { color: '{{warn-color-0.87}}'; }md-radio-group.md-THEME_NAME-theme:not([disabled]) .md-warn .md-container .md-ripple, md-radio-group.md-THEME_NAME-theme:not([disabled]).md-warn .md-container .md-ripple, md-radio-button.md-THEME_NAME-theme:not([disabled]) .md-warn .md-container .md-ripple, md-radio-button.md-THEME_NAME-theme:not([disabled]).md-warn .md-container .md-ripple { color: '{{warn-600}}'; }md-radio-group.md-THEME_NAME-theme[disabled], md-radio-button.md-THEME_NAME-theme[disabled] { color: '{{foreground-3}}'; } md-radio-group.md-THEME_NAME-theme[disabled] .md-container .md-off, md-radio-button.md-THEME_NAME-theme[disabled] .md-container .md-off { border-color: '{{foreground-3}}'; } md-radio-group.md-THEME_NAME-theme[disabled] .md-container .md-on, md-radio-button.md-THEME_NAME-theme[disabled] .md-container .md-on { border-color: '{{foreground-3}}'; }md-radio-group.md-THEME_NAME-theme.md-focused:not(:empty) .md-checked .md-container:before { background-color: '{{accent-color-0.26}}'; }md-radio-group.md-THEME_NAME-theme.md-focused:not(:empty) .md-checked:not([disabled]).md-primary .md-container:before { background-color: '{{primary-color-0.26}}'; }md-radio-group.md-THEME_NAME-theme.md-focused:not(:empty) .md-checked.md-primary .md-container:before { background-color: '{{warn-color-0.26}}'; }md-select.md-THEME_NAME-theme.ng-invalid.ng-dirty .md-select-label { color: '{{warn-500}}' !important; border-bottom-color: '{{warn-500}}' !important; }md-select.md-THEME_NAME-theme:not([disabled]):focus .md-select-label { border-bottom-color: '{{primary-color}}'; color: '{{ foreground-1 }}'; } md-select.md-THEME_NAME-theme:not([disabled]):focus .md-select-label.md-placeholder { color: '{{ foreground-1 }}'; }md-select.md-THEME_NAME-theme:not([disabled]):focus.md-accent .md-select-label { border-bottom-color: '{{accent-color}}'; }md-select.md-THEME_NAME-theme:not([disabled]):focus.md-warn .md-select-label { border-bottom-color: '{{warn-color}}'; }md-select.md-THEME_NAME-theme[disabled] .md-select-label { color: '{{foreground-3}}'; } md-select.md-THEME_NAME-theme[disabled] .md-select-label.md-placeholder { color: '{{foreground-3}}'; }md-select.md-THEME_NAME-theme .md-select-label { border-bottom-color: '{{foreground-4}}'; } md-select.md-THEME_NAME-theme .md-select-label.md-placeholder { color: '{{foreground-2}}'; }md-select-menu.md-THEME_NAME-theme md-optgroup { color: '{{foreground-2}}'; } md-select-menu.md-THEME_NAME-theme md-optgroup md-option { color: '{{foreground-1}}'; }md-select-menu.md-THEME_NAME-theme md-option[selected] { color: '{{primary-500}}'; } md-select-menu.md-THEME_NAME-theme md-option[selected]:focus { color: '{{primary-600}}'; } md-select-menu.md-THEME_NAME-theme md-option[selected].md-accent { color: '{{accent-500}}'; } md-select-menu.md-THEME_NAME-theme md-option[selected].md-accent:focus { color: '{{accent-600}}'; }md-select-menu.md-THEME_NAME-theme md-option:focus:not([selected]) { background: '{{background-200}}'; }md-sidenav.md-THEME_NAME-theme { background-color: '{{background-color}}'; }md-slider.md-THEME_NAME-theme .md-track { background-color: '{{foreground-3}}'; }md-slider.md-THEME_NAME-theme .md-track-ticks { background-color: '{{foreground-4}}'; }md-slider.md-THEME_NAME-theme .md-focus-thumb { background-color: '{{foreground-2}}'; }md-slider.md-THEME_NAME-theme .md-focus-ring { border-color: '{{foreground-4}}'; }md-slider.md-THEME_NAME-theme .md-disabled-thumb { border-color: '{{background-color}}'; }md-slider.md-THEME_NAME-theme.md-min .md-thumb:after { background-color: '{{background-color}}'; }md-slider.md-THEME_NAME-theme .md-track.md-track-fill { background-color: '{{accent-color}}'; }md-slider.md-THEME_NAME-theme .md-thumb:after { border-color: '{{accent-color}}'; background-color: '{{accent-color}}'; }md-slider.md-THEME_NAME-theme .md-sign { background-color: '{{accent-color}}'; } md-slider.md-THEME_NAME-theme .md-sign:after { border-top-color: '{{accent-color}}'; }md-slider.md-THEME_NAME-theme .md-thumb-text { color: '{{accent-contrast}}'; }md-slider.md-THEME_NAME-theme.md-warn .md-track.md-track-fill { background-color: '{{warn-color}}'; }md-slider.md-THEME_NAME-theme.md-warn .md-thumb:after { border-color: '{{warn-color}}'; background-color: '{{warn-color}}'; }md-slider.md-THEME_NAME-theme.md-warn .md-sign { background-color: '{{warn-color}}'; } md-slider.md-THEME_NAME-theme.md-warn .md-sign:after { border-top-color: '{{warn-color}}'; }md-slider.md-THEME_NAME-theme.md-warn .md-thumb-text { color: '{{warn-contrast}}'; }md-slider.md-THEME_NAME-theme.md-primary .md-track.md-track-fill { background-color: '{{primary-color}}'; }md-slider.md-THEME_NAME-theme.md-primary .md-thumb:after { border-color: '{{primary-color}}'; background-color: '{{primary-color}}'; }md-slider.md-THEME_NAME-theme.md-primary .md-sign { background-color: '{{primary-color}}'; } md-slider.md-THEME_NAME-theme.md-primary .md-sign:after { border-top-color: '{{primary-color}}'; }md-slider.md-THEME_NAME-theme.md-primary .md-thumb-text { color: '{{primary-contrast}}'; }md-slider.md-THEME_NAME-theme[disabled] .md-thumb:after { border-color: '{{foreground-3}}'; }md-slider.md-THEME_NAME-theme[disabled]:not(.md-min) .md-thumb:after { background-color: '{{foreground-3}}'; }.md-subheader.md-THEME_NAME-theme { color: '{{ foreground-2-0.23 }}'; background-color: '{{background-color}}'; } .md-subheader.md-THEME_NAME-theme.md-primary { color: '{{primary-color}}'; } .md-subheader.md-THEME_NAME-theme.md-accent { color: '{{accent-color}}'; } .md-subheader.md-THEME_NAME-theme.md-warn { color: '{{warn-color}}'; }md-tabs.md-THEME_NAME-theme md-tabs-wrapper { background-color: transparent; border-color: '{{foreground-4}}'; }md-tabs.md-THEME_NAME-theme .md-paginator md-icon { color: '{{primary-color}}'; }md-tabs.md-THEME_NAME-theme md-ink-bar { color: '{{accent-color}}'; background: '{{accent-color}}'; }md-tabs.md-THEME_NAME-theme .md-tab { color: '{{foreground-2}}'; } md-tabs.md-THEME_NAME-theme .md-tab[disabled] { color: '{{foreground-3}}'; } md-tabs.md-THEME_NAME-theme .md-tab.md-active, md-tabs.md-THEME_NAME-theme .md-tab.md-focused { color: '{{primary-color}}'; } md-tabs.md-THEME_NAME-theme .md-tab.md-focused { background: '{{primary-color-0.1}}'; } md-tabs.md-THEME_NAME-theme .md-tab .md-ripple-container { color: '{{accent-100}}'; }md-tabs.md-THEME_NAME-theme.md-accent md-tabs-wrapper { background-color: '{{accent-color}}'; }md-tabs.md-THEME_NAME-theme.md-accent md-tab-item:not([disabled]) { color: '{{accent-100}}'; } md-tabs.md-THEME_NAME-theme.md-accent md-tab-item:not([disabled]).md-active, md-tabs.md-THEME_NAME-theme.md-accent md-tab-item:not([disabled]).md-focused { color: '{{accent-contrast}}'; } md-tabs.md-THEME_NAME-theme.md-accent md-tab-item:not([disabled]).md-focused { background: '{{accent-contrast-0.1}}'; }md-tabs.md-THEME_NAME-theme.md-accent md-ink-bar { color: '{{primary-600-1}}'; background: '{{primary-600-1}}'; }md-tabs.md-THEME_NAME-theme.md-primary md-tabs-wrapper { background-color: '{{primary-color}}'; }md-tabs.md-THEME_NAME-theme.md-primary md-tab-item:not([disabled]) { color: '{{primary-100}}'; } md-tabs.md-THEME_NAME-theme.md-primary md-tab-item:not([disabled]).md-active, md-tabs.md-THEME_NAME-theme.md-primary md-tab-item:not([disabled]).md-focused { color: '{{primary-contrast}}'; } md-tabs.md-THEME_NAME-theme.md-primary md-tab-item:not([disabled]).md-focused { background: '{{primary-contrast-0.1}}'; }md-tabs.md-THEME_NAME-theme.md-warn md-tabs-wrapper { background-color: '{{warn-color}}'; }md-tabs.md-THEME_NAME-theme.md-warn md-tab-item:not([disabled]) { color: '{{warn-100}}'; } md-tabs.md-THEME_NAME-theme.md-warn md-tab-item:not([disabled]).md-active, md-tabs.md-THEME_NAME-theme.md-warn md-tab-item:not([disabled]).md-focused { color: '{{warn-contrast}}'; } md-tabs.md-THEME_NAME-theme.md-warn md-tab-item:not([disabled]).md-focused { background: '{{warn-contrast-0.1}}'; }md-toolbar > md-tabs.md-THEME_NAME-theme md-tabs-wrapper { background-color: '{{primary-color}}'; }md-toolbar > md-tabs.md-THEME_NAME-theme md-tab-item:not([disabled]) { color: '{{primary-100}}'; } md-toolbar > md-tabs.md-THEME_NAME-theme md-tab-item:not([disabled]).md-active, md-toolbar > md-tabs.md-THEME_NAME-theme md-tab-item:not([disabled]).md-focused { color: '{{primary-contrast}}'; } md-toolbar > md-tabs.md-THEME_NAME-theme md-tab-item:not([disabled]).md-focused { background: '{{primary-contrast-0.1}}'; }md-toolbar.md-accent > md-tabs.md-THEME_NAME-theme md-tabs-wrapper { background-color: '{{accent-color}}'; }md-toolbar.md-accent > md-tabs.md-THEME_NAME-theme md-tab-item:not([disabled]) { color: '{{accent-100}}'; } md-toolbar.md-accent > md-tabs.md-THEME_NAME-theme md-tab-item:not([disabled]).md-active, md-toolbar.md-accent > md-tabs.md-THEME_NAME-theme md-tab-item:not([disabled]).md-focused { color: '{{accent-contrast}}'; } md-toolbar.md-accent > md-tabs.md-THEME_NAME-theme md-tab-item:not([disabled]).md-focused { background: '{{accent-contrast-0.1}}'; }md-toolbar.md-accent > md-tabs.md-THEME_NAME-theme md-ink-bar { color: '{{primary-600-1}}'; background: '{{primary-600-1}}'; }md-toolbar.md-warn > md-tabs.md-THEME_NAME-theme md-tabs-wrapper { background-color: '{{warn-color}}'; }md-toolbar.md-warn > md-tabs.md-THEME_NAME-theme md-tab-item:not([disabled]) { color: '{{warn-100}}'; } md-toolbar.md-warn > md-tabs.md-THEME_NAME-theme md-tab-item:not([disabled]).md-active, md-toolbar.md-warn > md-tabs.md-THEME_NAME-theme md-tab-item:not([disabled]).md-focused { color: '{{warn-contrast}}'; } md-toolbar.md-warn > md-tabs.md-THEME_NAME-theme md-tab-item:not([disabled]).md-focused { background: '{{warn-contrast-0.1}}'; }md-switch.md-THEME_NAME-theme .md-thumb { background-color: '{{background-50}}'; }md-switch.md-THEME_NAME-theme .md-bar { background-color: '{{background-500}}'; }md-switch.md-THEME_NAME-theme.md-checked .md-thumb { background-color: '{{accent-color}}'; }md-switch.md-THEME_NAME-theme.md-checked .md-bar { background-color: '{{accent-color-0.5}}'; }md-switch.md-THEME_NAME-theme.md-checked.md-focused .md-thumb:before { background-color: '{{accent-color-0.26}}'; }md-switch.md-THEME_NAME-theme.md-checked.md-primary .md-thumb { background-color: '{{primary-color}}'; }md-switch.md-THEME_NAME-theme.md-checked.md-primary .md-bar { background-color: '{{primary-color-0.5}}'; }md-switch.md-THEME_NAME-theme.md-checked.md-primary.md-focused .md-thumb:before { background-color: '{{primary-color-0.26}}'; }md-switch.md-THEME_NAME-theme.md-checked.md-warn .md-thumb { background-color: '{{warn-color}}'; }md-switch.md-THEME_NAME-theme.md-checked.md-warn .md-bar { background-color: '{{warn-color-0.5}}'; }md-switch.md-THEME_NAME-theme.md-checked.md-warn.md-focused .md-thumb:before { background-color: '{{warn-color-0.26}}'; }md-switch.md-THEME_NAME-theme[disabled] .md-thumb { background-color: '{{background-400}}'; }md-switch.md-THEME_NAME-theme[disabled] .md-bar { background-color: '{{foreground-4}}'; }md-toast.md-THEME_NAME-theme { background-color: #323232; color: '{{background-50}}'; } md-toast.md-THEME_NAME-theme .md-button { color: '{{background-50}}'; } md-toast.md-THEME_NAME-theme .md-button.md-highlight { color: '{{primary-A200}}'; } md-toast.md-THEME_NAME-theme .md-button.md-highlight.md-accent { color: '{{accent-A200}}'; } md-toast.md-THEME_NAME-theme .md-button.md-highlight.md-warn { color: '{{warn-A200}}'; }md-toolbar.md-THEME_NAME-theme { background-color: '{{primary-color}}'; color: '{{primary-contrast}}'; } md-toolbar.md-THEME_NAME-theme md-icon { color: '{{primary-contrast}}'; } md-toolbar.md-THEME_NAME-theme .md-button { color: '{{primary-contrast}}'; } md-toolbar.md-THEME_NAME-theme.md-accent { background-color: '{{accent-color}}'; color: '{{accent-contrast}}'; } md-toolbar.md-THEME_NAME-theme.md-warn { background-color: '{{warn-color}}'; color: '{{warn-contrast}}'; }md-tooltip.md-THEME_NAME-theme { color: '{{background-A100}}'; } md-tooltip.md-THEME_NAME-theme .md-background { background-color: '{{foreground-2}}'; }");
|
3769
|
+
})();
|
3770
|
+
|
3771
|
+
|
3772
|
+
ng.material.core = angular.module("material.core");
|