OLD | NEW |
| (Empty) |
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 cr.define('options', function() { | |
6 var BubbleBase = cr.ui.BubbleBase; | |
7 | |
8 var OptionsBubble = cr.ui.define('div'); | |
9 | |
10 OptionsBubble.prototype = { | |
11 // Set up the prototype chain. | |
12 __proto__: BubbleBase.prototype, | |
13 | |
14 /** | |
15 * Initialization function for the cr.ui framework. | |
16 */ | |
17 decorate: function() { | |
18 BubbleBase.prototype.decorate.call(this); | |
19 this.classList.add('options-bubble'); | |
20 }, | |
21 | |
22 /** | |
23 * Set the DOM sibling node, i.e. the node as whose sibling the bubble | |
24 * should join the DOM to ensure that focusable elements inside the bubble | |
25 * follow the target element in the document's tab order. Only available | |
26 * when the bubble is not being shown. | |
27 * @param {HTMLElement} node The new DOM sibling node. | |
28 */ | |
29 set domSibling(node) { | |
30 if (!this.hidden) | |
31 return; | |
32 | |
33 this.domSibling_ = node; | |
34 }, | |
35 | |
36 /** | |
37 * Show the bubble. | |
38 */ | |
39 show: function() { | |
40 if (!this.hidden) | |
41 return; | |
42 | |
43 BubbleBase.prototype.show.call(this); | |
44 this.domSibling_.showingBubble = true; | |
45 | |
46 var doc = this.ownerDocument; | |
47 this.eventTracker_.add(doc, 'mousewheel', this, true); | |
48 this.eventTracker_.add(doc, 'scroll', this, true); | |
49 this.eventTracker_.add(doc, 'elementFocused', this, true); | |
50 this.eventTracker_.add(window, 'resize', this); | |
51 }, | |
52 | |
53 /** | |
54 * Hide the bubble. | |
55 */ | |
56 hide: function() { | |
57 BubbleBase.prototype.hide.call(this); | |
58 this.domSibling_.showingBubble = false; | |
59 }, | |
60 | |
61 /** | |
62 * Handle events, closing the bubble when the user clicks or moves the focus | |
63 * outside the bubble and its target element, scrolls the underlying | |
64 * document or resizes the window. | |
65 * @param {Event} event The event. | |
66 */ | |
67 handleEvent: function(event) { | |
68 BubbleBase.prototype.handleEvent.call(this, event); | |
69 | |
70 switch (event.type) { | |
71 // Close the bubble when the user clicks outside it, except if it is a | |
72 // left-click on the bubble's target element (allowing the target to | |
73 // handle the event and close the bubble itself). | |
74 case 'mousedown': | |
75 if (event.button == 0 && this.anchorNode_.contains(event.target)) | |
76 break; | |
77 // Close the bubble when the underlying document is scrolled. | |
78 case 'mousewheel': | |
79 case 'scroll': | |
80 if (this.contains(event.target)) | |
81 break; | |
82 // Close the bubble when the window is resized. | |
83 case 'resize': | |
84 this.hide(); | |
85 break; | |
86 // Close the bubble when the focus moves to an element that is not the | |
87 // bubble target and is not inside the bubble. | |
88 case 'elementFocused': | |
89 if (!this.anchorNode_.contains(event.target) && | |
90 !this.contains(event.target)) { | |
91 this.hide(); | |
92 } | |
93 break; | |
94 } | |
95 }, | |
96 | |
97 /** | |
98 * Attach the bubble to the document's DOM, making it a sibling of the | |
99 * |domSibling_| so that focusable elements inside the bubble follow the | |
100 * target element in the document's tab order. | |
101 * @private | |
102 */ | |
103 attachToDOM_: function() { | |
104 var parent = this.domSibling_.parentNode; | |
105 parent.insertBefore(this, this.domSibling_.nextSibling); | |
106 }, | |
107 }; | |
108 | |
109 return { | |
110 OptionsBubble: OptionsBubble | |
111 }; | |
112 }); | |
OLD | NEW |