Home | History | Annotate | Download | only in iron-overlay-behavior
      1 <!--
      2 @license
      3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
      4 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
      5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
      6 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
      7 Code distributed by Google as part of the polymer project is also
      8 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
      9 -->
     10 
     11 <link rel="import" href="../polymer/polymer.html">
     12 
     13 <!--
     14 `iron-overlay-backdrop` is a backdrop used by `Polymer.IronOverlayBehavior`. It should be a
     15 singleton.
     16 
     17 ### Styling
     18 
     19 The following custom properties and mixins are available for styling.
     20 
     21 Custom property | Description | Default
     22 -------------------------------------------|------------------------|---------
     23 `--iron-overlay-backdrop-background-color` | Backdrop background color                                     | #000
     24 `--iron-overlay-backdrop-opacity`          | Backdrop opacity                                              | 0.6
     25 `--iron-overlay-backdrop`                  | Mixin applied to `iron-overlay-backdrop`.                      | {}
     26 `--iron-overlay-backdrop-opened`           | Mixin applied to `iron-overlay-backdrop` when it is displayed | {}
     27 -->
     28 
     29 <dom-module id="iron-overlay-backdrop">
     30 
     31   <template>
     32     <style>
     33       :host {
     34         position: fixed;
     35         top: 0;
     36         left: 0;
     37         width: 100%;
     38         height: 100%;
     39         background-color: var(--iron-overlay-backdrop-background-color, #000);
     40         opacity: 0;
     41         transition: opacity 0.2s;
     42         pointer-events: none;
     43         @apply(--iron-overlay-backdrop);
     44       }
     45 
     46       :host(.opened) {
     47         opacity: var(--iron-overlay-backdrop-opacity, 0.6);
     48         pointer-events: auto;
     49         @apply(--iron-overlay-backdrop-opened);
     50       }
     51     </style>
     52 
     53     <content></content>
     54   </template>
     55 
     56 </dom-module>
     57 
     58 <script>
     59 (function() {
     60 'use strict';
     61 
     62   Polymer({
     63 
     64     is: 'iron-overlay-backdrop',
     65 
     66     properties: {
     67 
     68       /**
     69        * Returns true if the backdrop is opened.
     70        */
     71       opened: {
     72         reflectToAttribute: true,
     73         type: Boolean,
     74         value: false,
     75         observer: '_openedChanged'
     76       }
     77 
     78     },
     79 
     80     listeners: {
     81       'transitionend': '_onTransitionend'
     82     },
     83 
     84     created: function() {
     85       // Used to cancel previous requestAnimationFrame calls when opened changes.
     86       this.__openedRaf = null;
     87     },
     88 
     89     attached: function() {
     90       this.opened && this._openedChanged(this.opened);
     91     },
     92 
     93     /**
     94      * Appends the backdrop to document body if needed.
     95      */
     96     prepare: function() {
     97       if (this.opened && !this.parentNode) {
     98         Polymer.dom(document.body).appendChild(this);
     99       }
    100     },
    101 
    102     /**
    103      * Shows the backdrop.
    104      */
    105     open: function() {
    106       this.opened = true;
    107     },
    108 
    109     /**
    110      * Hides the backdrop.
    111      */
    112     close: function() {
    113       this.opened = false;
    114     },
    115 
    116     /**
    117      * Removes the backdrop from document body if needed.
    118      */
    119     complete: function() {
    120       if (!this.opened && this.parentNode === document.body) {
    121         Polymer.dom(this.parentNode).removeChild(this);
    122       }
    123     },
    124 
    125     _onTransitionend: function(event) {
    126       if (event && event.target === this) {
    127         this.complete();
    128       }
    129     },
    130 
    131     /**
    132      * @param {boolean} opened
    133      * @private
    134      */
    135     _openedChanged: function(opened) {
    136       if (opened) {
    137         // Auto-attach.
    138         this.prepare();
    139       } else {
    140         // Animation might be disabled via the mixin or opacity custom property.
    141         // If it is disabled in other ways, it's up to the user to call complete.
    142         var cs = window.getComputedStyle(this);
    143         if (cs.transitionDuration === '0s' || cs.opacity == 0) {
    144           this.complete();
    145         }
    146       }
    147 
    148       if (!this.isAttached) {
    149         return;
    150       }
    151 
    152       // Always cancel previous requestAnimationFrame.
    153       if (this.__openedRaf) {
    154         window.cancelAnimationFrame(this.__openedRaf);
    155         this.__openedRaf = null;
    156       }
    157       // Force relayout to ensure proper transitions.
    158       this.scrollTop = this.scrollTop;
    159       this.__openedRaf = window.requestAnimationFrame(function() {
    160         this.__openedRaf = null;
    161         this.toggleClass('opened', this.opened);
    162       }.bind(this));
    163     }
    164   });
    165 
    166 })();
    167 
    168 </script>
    169