1<!DOCTYPE html> 2<!-- 3Copyright (c) 2014 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/ui/base/ui.html"> 9 10<polymer-element name="tr-ui-b-drag-handle"> 11 <template> 12 <style> 13 :host { 14 -webkit-user-select: none; 15 box-sizing: border-box; 16 display: block; 17 } 18 19 :host(.horizontal-drag-handle) { 20 background-image: -webkit-gradient(linear, 21 0 0, 0 100%, 22 from(#E5E5E5), 23 to(#D1D1D1)); 24 border-bottom: 1px solid #8e8e8e; 25 border-top: 1px solid white; 26 cursor: ns-resize; 27 flex: 0 0 auto; 28 height: 7px; 29 position: relative; 30 z-index: 10; 31 } 32 33 :host(.vertical-drag-handle) { 34 background-image: -webkit-gradient(linear, 35 0 0, 100% 0, 36 from(#E5E5E5), 37 to(#D1D1D1)); 38 border-left: 1px solid white; 39 border-right: 1px solid #8e8e8e; 40 cursor: ew-resize; 41 flex: 0 0 auto; 42 position: relative; 43 width: 7px; 44 z-index: 10; 45 } 46 </style> 47 </template> 48 <script> 49 'use strict'; 50 51 Polymer({ 52 __proto__: HTMLDivElement.prototype, 53 54 created: function() { 55 this.lastMousePos_ = 0; 56 this.onMouseMove_ = this.onMouseMove_.bind(this); 57 this.onMouseUp_ = this.onMouseUp_.bind(this); 58 this.addEventListener('mousedown', this.onMouseDown_); 59 this.target_ = undefined; 60 this.horizontal = true; 61 this.observer_ = new WebKitMutationObserver( 62 this.didTargetMutate_.bind(this)); 63 this.targetSizesByModeKey_ = {}; 64 }, 65 66 get modeKey_() { 67 return this.target_.className == '' ? '.' : this.target_.className; 68 }, 69 70 get target() { 71 return this.target_; 72 }, 73 74 set target(target) { 75 this.observer_.disconnect(); 76 this.target_ = target; 77 if (!this.target_) 78 return; 79 this.observer_.observe(this.target_, { 80 attributes: true, 81 attributeFilter: ['class'] 82 }); 83 }, 84 85 get horizontal() { 86 return this.horizontal_; 87 }, 88 89 set horizontal(h) { 90 this.horizontal_ = h; 91 if (this.horizontal_) 92 this.className = 'horizontal-drag-handle'; 93 else 94 this.className = 'vertical-drag-handle'; 95 }, 96 97 get vertical() { 98 return !this.horizontal_; 99 }, 100 101 set vertical(v) { 102 this.horizontal = !v; 103 }, 104 105 forceMutationObserverFlush_: function() { 106 var records = this.observer_.takeRecords(); 107 if (records.length) 108 this.didTargetMutate_(records); 109 }, 110 111 didTargetMutate_: function(e) { 112 var modeSize = this.targetSizesByModeKey_[this.modeKey_]; 113 if (modeSize !== undefined) { 114 this.setTargetSize_(modeSize); 115 return; 116 } 117 118 // If we hadn't previously sized the target, then just remove any manual 119 // sizing that we applied. 120 this.target_.style[this.targetStyleKey_] = ''; 121 }, 122 123 get targetStyleKey_() { 124 return this.horizontal_ ? 'height' : 'width'; 125 }, 126 127 getTargetSize_: function() { 128 // If style is not set, start off with computed height. 129 var targetStyleKey = this.targetStyleKey_; 130 if (!this.target_.style[targetStyleKey]) { 131 this.target_.style[targetStyleKey] = 132 window.getComputedStyle(this.target_)[targetStyleKey]; 133 } 134 var size = parseInt(this.target_.style[targetStyleKey]); 135 this.targetSizesByModeKey_[this.modeKey_] = size; 136 return size; 137 }, 138 139 setTargetSize_: function(s) { 140 this.target_.style[this.targetStyleKey_] = s + 'px'; 141 this.targetSizesByModeKey_[this.modeKey_] = s; 142 }, 143 144 applyDelta_: function(delta) { 145 // Apply new size to the container. 146 var curSize = this.getTargetSize_(); 147 var newSize; 148 if (this.target_ === this.nextElementSibling) { 149 newSize = curSize + delta; 150 } else { 151 newSize = curSize - delta; 152 } 153 this.setTargetSize_(newSize); 154 }, 155 156 onMouseMove_: function(e) { 157 // Compute the difference in height position. 158 var curMousePos = this.horizontal_ ? e.clientY : e.clientX; 159 var delta = this.lastMousePos_ - curMousePos; 160 161 this.applyDelta_(delta); 162 163 this.lastMousePos_ = curMousePos; 164 e.preventDefault(); 165 return true; 166 }, 167 168 onMouseDown_: function(e) { 169 if (!this.target_) 170 return; 171 this.forceMutationObserverFlush_(); 172 this.lastMousePos_ = this.horizontal_ ? e.clientY : e.clientX; 173 document.addEventListener('mousemove', this.onMouseMove_); 174 document.addEventListener('mouseup', this.onMouseUp_); 175 e.preventDefault(); 176 return true; 177 }, 178 179 onMouseUp_: function(e) { 180 document.removeEventListener('mousemove', this.onMouseMove_); 181 document.removeEventListener('mouseup', this.onMouseUp_); 182 e.preventDefault(); 183 } 184 }); 185 </script> 186</polymer-element> 187