1<!DOCTYPE html>
2<!--
3Copyright (c) 2015 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/base/base.html">
9
10<polymer-element name="tr-ui-b-dropdown">
11  <template>
12    <style>
13    :host {
14      position: relative;
15      display: flex;
16    }
17    #outer {
18      display: flex;
19      flex: 0 0 auto;
20      padding: 1px 4px 1px 4px;
21      -webkit-user-select: none;
22      cursor: default;
23    }
24
25    #state {
26      display: flex;
27      flex: 0 0 auto;
28      margin-left: 2px;
29      margin-right: 0px;
30      flex: 0 0 auto;
31    }
32
33    #icon {
34      display: flex;
35      flex: 0 0 auto;
36      flex: 0 0 auto;
37    }
38    dialog {
39      position: absolute;
40      padding: 0;
41      border: 0;
42      margin: 0;
43    }
44    dialog::backdrop {
45      background: rgba(0,0,0,.05);
46    }
47
48    #dialog-frame {
49      background-color: #fff;
50      display: flex;
51      flex-direction: column;
52      flex: 1 1 auto;
53      padding: 6px;
54      border: 1px solid black;
55      -webkit-user-select: none;
56      cursor: default;
57    }
58    </style>
59    <tr-ui-b-toolbar-button id="outer"
60        on-keydown="{{ onOuterKeyDown_ }}"
61        on-click="{{ onOuterClick_ }}">
62      <div id="icon">&#9881;</div>
63      <div id="state">&#9662;</div>
64    </tr-ui-b-toolbar-button>
65    <dialog id="dialog"
66        on-click="{{ onDialogClick_ }}"
67        on-cancel="{{ onDialogCancel_ }}">
68      <div id="dialog-frame">
69        <content></content>
70      </div>
71    </dialog>
72  </template>
73  <script>
74  'use strict';
75
76  Polymer({
77    ready: function() {
78      this.$.outer.tabIndex = 0;
79    },
80
81    get iconElement() {
82      return this.$.icon;
83    },
84
85    onOuterKeyDown_: function(e) {
86      if (e.keyCode === ' '.charCodeAt(0)) {
87        this.toggle_();
88        e.preventDefault();
89        e.stopPropagation();
90      }
91    },
92
93    onOuterClick_: function(e) {
94      var or = this.$.outer.getBoundingClientRect();
95      var inside = true;
96      inside &= e.clientX >= or.left;
97      inside &= e.clientX < or.right;
98      inside &= e.clientY >= or.top;
99      inside &= e.clientY < or.bottom;
100      if (!inside)
101        return;
102
103      e.preventDefault();
104      this.toggle_();
105    },
106
107    toggle_: function() {
108      if (!this.isOpen)
109        this.show();
110      else
111        this.close();
112    },
113
114    show: function() {
115      if (this.isOpen)
116        return;
117
118      this.$.outer.classList.add('open');
119
120      var ddr = this.$.outer.getBoundingClientRect();
121      var rW = Math.max(ddr.width, 150);
122      this.$.dialog.style.minWidth = rW + 'px';
123      this.$.dialog.showModal();
124
125      var ddw = this.$.outer.getBoundingClientRect().width;
126      var w = this.$.dialog.getBoundingClientRect().width;
127      this.$.dialog.style.top = ddr.bottom - 1 + 'px';
128      this.$.dialog.style.left = ddr.left + 'px';
129    },
130
131    onDialogClick_: function(e) {
132      if (!this.isOpen)
133        return;
134      if (e.srcElement !== this.$.dialog)
135        return;
136      e.preventDefault();
137      this.close();
138    },
139
140    onDialogCancel_: function(e) {
141      e.preventDefault();
142      this.close();
143    },
144
145    close: function() {
146      if (!this.isOpen)
147        return;
148      this.$.dialog.close();
149      this.$.outer.classList.remove('open');
150      this.$.outer.focus();
151    },
152
153    get isOpen() {
154      return this.$.dialog.hasAttribute('open');
155    }
156  });
157  </script>
158</polymer-element>
159