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">⚙</div> 63 <div id="state">▾</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