Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / src / ui / drag_handle.js
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 'use strict';
6
7 base.require('ui');
8 base.requireStylesheet('ui.drag_handle');
9
10 base.exportTo('ui', function() {
11
12   /**
13    * Detects when user clicks handle determines new height of container based
14    * on user's vertical mouse move and resizes the target.
15    * @constructor
16    * @extends {HTMLDivElement}
17    * You will need to set target to be the draggable element
18    */
19   var DragHandle = ui.define('x-drag-handle');
20
21   DragHandle.prototype = {
22     __proto__: HTMLDivElement.prototype,
23
24     decorate: function() {
25       this.lastMousePos_ = 0;
26       this.onMouseMove_ = this.onMouseMove_.bind(this);
27       this.onMouseUp_ = this.onMouseUp_.bind(this);
28       this.addEventListener('mousedown', this.onMouseDown_);
29       this.target_ = undefined;
30       this.horizontal = true;
31       this.observer_ = new WebKitMutationObserver(
32           this.didTargetMutate_.bind(this));
33       this.targetSizesByModeKey_ = {};
34     },
35
36     get modeKey_() {
37       return this.target_.className == '' ? '.' : this.target_.className;
38     },
39
40     get target() {
41       return this.target_;
42     },
43
44     set target(target) {
45       this.observer_.disconnect();
46       this.target_ = target;
47       if (!this.target_)
48         return;
49       this.observer_.observe(this.target_, {
50         attributes: true,
51         attributeFilter: ['class']
52       });
53     },
54
55     get horizontal() {
56       return this.horizontal_;
57     },
58
59     set horizontal(h) {
60       this.horizontal_ = h;
61       if (this.horizontal_)
62         this.className = 'horizontal-drag-handle';
63       else
64         this.className = 'vertical-drag-handle';
65     },
66
67     get vertical() {
68       return !this.horizontal_;
69     },
70
71     set vertical(v) {
72       this.horizontal = !v;
73     },
74
75     forceMutationObserverFlush_: function() {
76       var records = this.observer_.takeRecords();
77       if (records.length)
78         this.didTargetMutate_(records);
79     },
80
81     didTargetMutate_: function(e) {
82       var modeSize = this.targetSizesByModeKey_[this.modeKey_];
83       if (modeSize !== undefined) {
84         this.setTargetSize_(modeSize);
85         return;
86       }
87
88       // If we hadn't previously sized the target, then just remove any manual
89       // sizing that we applied.
90       this.target_.style[this.targetStyleKey_] = '';
91     },
92
93     get targetStyleKey_() {
94       return this.horizontal_ ? 'height' : 'width';
95     },
96
97     getTargetSize_: function() {
98       // If style is not set, start off with computed height.
99       var targetStyleKey = this.targetStyleKey_;
100       if (!this.target_.style[targetStyleKey]) {
101         this.target_.style[targetStyleKey] =
102             window.getComputedStyle(this.target_)[targetStyleKey];
103       }
104       var size = parseInt(this.target_.style[targetStyleKey]);
105       this.targetSizesByModeKey_[this.modeKey_] = size;
106       return size;
107     },
108
109     setTargetSize_: function(s) {
110       this.target_.style[this.targetStyleKey_] = s + 'px';
111       this.targetSizesByModeKey_[this.modeKey_] = s;
112     },
113
114     applyDelta_: function(delta) {
115       // Apply new size to the container.
116       var curSize = this.getTargetSize_();
117       var newSize;
118       if (this.target_ === this.nextSibling) {
119         newSize = curSize + delta;
120       } else {
121         newSize = curSize - delta;
122       }
123       this.setTargetSize_(newSize);
124     },
125
126     onMouseMove_: function(e) {
127       // Compute the difference in height position.
128       var curMousePos = this.horizontal_ ? e.clientY : e.clientX;
129       var delta = this.lastMousePos_ - curMousePos;
130
131       this.applyDelta_(delta);
132
133       this.lastMousePos_ = curMousePos;
134       e.preventDefault();
135       return true;
136     },
137
138     onMouseDown_: function(e) {
139       if (!this.target_)
140         return;
141       this.forceMutationObserverFlush_();
142       this.lastMousePos_ = this.horizontal_ ? e.clientY : e.clientX;
143       document.addEventListener('mousemove', this.onMouseMove_);
144       document.addEventListener('mouseup', this.onMouseUp_);
145       e.preventDefault();
146       return true;
147     },
148
149     onMouseUp_: function(e) {
150       document.removeEventListener('mousemove', this.onMouseMove_);
151       document.removeEventListener('mouseup', this.onMouseUp_);
152       e.preventDefault();
153     }
154   };
155
156   return {
157     DragHandle: DragHandle
158   };
159 });