1 // Copyright 2014 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.
5 cr
.define('print_preview', function() {
9 * Encapsulated handling of a search bubble.
11 * @extends {HTMLDivElement}
13 function SearchBubble(text
) {
14 var el
= cr
.doc
.createElement('div');
15 SearchBubble
.decorate(el
);
20 SearchBubble
.decorate = function(el
) {
21 el
.__proto__
= SearchBubble
.prototype;
25 SearchBubble
.prototype = {
26 __proto__
: HTMLDivElement
.prototype,
28 decorate: function() {
29 this.className
= 'search-bubble';
31 this.innards_
= cr
.doc
.createElement('div');
32 this.innards_
.className
= 'search-bubble-innards';
33 this.appendChild(this.innards_
);
35 // We create a timer to periodically update the position of the bubbles.
36 // While this isn't all that desirable, it's the only sure-fire way of
37 // making sure the bubbles stay in the correct location as sections
38 // may dynamically change size at any time.
39 this.intervalId
= setInterval(this.updatePosition
.bind(this), 250);
43 * Sets the text message in the bubble.
44 * @param {string} text The text the bubble will show.
47 this.innards_
.textContent
= text
;
50 /** Attach the bubble to the element. */
51 attachTo: function(element
) {
52 var parent
= element
.parentElement
;
55 if (parent
.tagName
== 'TD') {
56 // To make absolute positioning work inside a table cell we need
57 // to wrap the bubble div into another div with position:relative.
58 // This only works properly if the element is the first child of the
59 // table cell which is true for all options pages (the only place
60 // it is used on tables).
61 this.wrapper
= cr
.doc
.createElement('div');
62 this.wrapper
.className
= 'search-bubble-wrapper';
63 this.wrapper
.appendChild(this);
64 parent
.insertBefore(this.wrapper
, element
);
66 parent
.insertBefore(this, element
);
68 this.updatePosition();
71 /** Clear the interval timer and remove the element from the page. */
73 clearInterval(this.intervalId
);
75 var child
= this.wrapper
|| this;
76 var parent
= child
.parentNode
;
78 parent
.removeChild(child
);
82 * Update the position of the bubble. Called at creation time and then
83 * periodically while the bubble remains visible.
85 updatePosition: function() {
86 // This bubble is 'owned' by the next sibling.
87 var owner
= (this.wrapper
|| this).nextSibling
;
89 // If there isn't an offset parent, we have nothing to do.
90 if (!owner
.offsetParent
)
93 // Position the bubble below the location of the owner.
94 var left
= owner
.offsetLeft
+ owner
.offsetWidth
/ 2 -
96 var top
= owner
.offsetTop
+ owner
.offsetHeight
;
98 // Update the position in the CSS. Cache the last values for
100 if (left
!= this.lastLeft
) {
101 this.style
.left
= left
+ 'px';
102 this.lastLeft
= left
;
104 if (top
!= this.lastTop
) {
105 this.style
.top
= top
+ 'px';
113 SearchBubble
: SearchBubble