Index: chrome/browser/resources/chromeos/login/bubble.js |
diff --git a/chrome/browser/resources/chromeos/login/bubble.js b/chrome/browser/resources/chromeos/login/bubble.js |
index 8e5d1541904cff48828bebf947a093c3ad25c622..59a0e0a194023287e998089619e49417cf2aa11c 100644 |
--- a/chrome/browser/resources/chromeos/login/bubble.js |
+++ b/chrome/browser/resources/chromeos/login/bubble.js |
@@ -15,6 +15,17 @@ cr.define('cr.ui', function() { |
*/ |
var Bubble = cr.ui.define('div'); |
+ /** |
+ * Bubble attachment side. |
+ * @enum {string} |
+ */ |
+ Bubble.Attachment = { |
+ RIGHT: 'bubble-right', |
+ LEFT: 'bubble-left', |
+ TOP: 'bubble-top', |
+ BOTTOM: 'bubble-bottom' |
+ }; |
+ |
Bubble.prototype = { |
__proto__: HTMLDivElement.prototype, |
@@ -32,23 +43,32 @@ cr.define('cr.ui', function() { |
}, |
/** |
+ * Sets the attachment of the bubble. |
+ * @param {!Attachment} attachment Bubble attachment. |
+ */ |
+ setAttachment_: function (attachment) { |
+ for (var k in Bubble.Attachment) { |
+ var v = Bubble.Attachment[k]; |
+ this.classList[v == attachment ? 'add' : 'remove'](v); |
+ } |
+ }, |
+ |
+ /** |
* Shows the bubble for given anchor element. |
- * @param {number} x X position of bubble's reference point. |
- * @param {number} y Y position of bubble's reference point. |
+ * @param {!Object} pos Bubble position (left, top, right, bottom in px). |
* @param {HTMLElement} content Content to show in bubble. |
- * @public |
+ * @param {!Attachment} attachment Bubble attachment (on which side of the |
+ * specified position it should be displayed). |
+ * @private |
*/ |
- showContentAt: function(x, y, content) { |
- const ARROW_OFFSET = 14; |
- |
- var anchorX = x - ARROW_OFFSET; |
- var anchorY = y; |
- |
- this.style.left = anchorX + 'px'; |
- this.style.top = anchorY + 'px'; |
- |
+ showContentAt_: function(pos, content, attachment) { |
+ for (var k in pos) { |
+ if (typeof pos[k] == 'number') |
+ this.style[k] = pos[k] + 'px'; |
+ } |
this.innerHTML = ''; |
this.appendChild(content); |
+ this.setAttachment_(attachment); |
this.hidden = false; |
this.classList.remove('faded'); |
}, |
@@ -57,30 +77,94 @@ cr.define('cr.ui', function() { |
* Shows the bubble for given anchor element. |
* @param {!HTMLElement} el Anchor element of the bubble. |
* @param {HTMLElement} content Content to show in bubble. |
+ * @param {!Attachment} attachment Bubble attachment (on which side of the |
+ * element it should be displayed). |
+ * @param {number=} opt_offset Offset of the bubble attachment point from |
+ * left (for vertical attachment) or top (for horizontal attachment) |
+ * side of the element. If not specified, the bubble is positioned to |
+ * be aligned with the left/top side of the element but not farther than |
+ * half of it's weight/height. |
+ * @param {number=} opt_padding Optional padding of the bubble. |
* @public |
*/ |
- showContentForElement: function(el, content) { |
- const HORIZONTAL_PADDING = 10; |
- const VERTICAL_PADDING = 5; |
- |
- var elementOrigin = cr.ui.login.DisplayManager.getOffset(el); |
- var anchorX = elementOrigin.left + HORIZONTAL_PADDING; |
- var anchorY = elementOrigin.top + el.offsetHeight + VERTICAL_PADDING; |
+ showContentForElement: function(el, content, attachment, |
+ opt_offset, opt_padding) { |
+ const ARROW_OFFSET = 25; |
+ const DEFAULT_PADDING = 18; |
+ |
+ if (typeof opt_padding == 'undefined') |
+ opt_padding = DEFAULT_PADDING; |
+ |
+ var origin = cr.ui.login.DisplayManager.getPosition(el); |
+ var offset = typeof opt_offset == 'undefined' ? |
+ [ Math.min(ARROW_OFFSET, el.offsetWidth/2), |
+ Math.min(ARROW_OFFSET, el.offsetHeight/2) ] : |
+ [ opt_offset, opt_offset ]; |
+ |
+ var pos = {}; |
+ if (isRTL()) { |
+ switch (attachment) { |
+ case Bubble.Attachment.TOP: |
+ pos.right = origin.right + offset[0] - ARROW_OFFSET; |
+ pos.bottom = origin.bottom + el.offsetHeight + opt_padding; |
+ break; |
+ case Bubble.Attachment.RIGHT: |
+ pos.top = origin.top + offset[1] - ARROW_OFFSET; |
+ pos.right = origin.right + el.offsetWidth + opt_padding; |
+ break; |
+ case Bubble.Attachment.BOTTOM: |
+ pos.right = origin.right + offset[0] - ARROW_OFFSET; |
+ pos.top = origin.top + el.offsetHeight + opt_padding; |
+ break; |
+ case Bubble.Attachment.LEFT: |
+ pos.top = origin.top + offset[1] - ARROW_OFFSET; |
+ pos.left = origin.left + el.offsetWidth + opt_padding; |
+ break; |
+ } |
+ } else { |
+ switch (attachment) { |
+ case Bubble.Attachment.TOP: |
+ pos.left = origin.left + offset[0] - ARROW_OFFSET; |
+ pos.bottom = origin.bottom + el.offsetHeight + opt_padding; |
+ break; |
+ case Bubble.Attachment.RIGHT: |
+ pos.top = origin.top + offset[1] - ARROW_OFFSET; |
+ pos.left = origin.left + el.offsetWidth + opt_padding; |
+ break; |
+ case Bubble.Attachment.BOTTOM: |
+ pos.left = origin.left + offset[0] - ARROW_OFFSET; |
+ pos.top = origin.top + el.offsetHeight + opt_padding; |
+ break; |
+ case Bubble.Attachment.LEFT: |
+ pos.top = origin.top + offset[1] - ARROW_OFFSET; |
+ pos.right = origin.right + el.offsetWidth + opt_padding; |
+ break; |
+ } |
+ } |
this.anchor_ = el; |
- this.showContentAt(anchorX, anchorY, content); |
+ this.showContentAt_(pos, content, attachment); |
}, |
/** |
* Shows the bubble for given anchor element. |
* @param {!HTMLElement} el Anchor element of the bubble. |
* @param {string} text Text content to show in bubble. |
+ * @param {!Attachment} attachment Bubble attachment (on which side of the |
+ * element it should be displayed). |
+ * @param {number=} opt_offset Offset of the bubble attachment point from |
+ * left (for vertical attachment) or top (for horizontal attachment) |
+ * side of the element. If not specified, the bubble is positioned to |
+ * be aligned with the left/top side of the element but not farther than |
+ * half of it's weight/height. |
+ * @param {number=} opt_padding Optional padding of the bubble. |
* @public |
*/ |
- showTextForElement: function(el, text) { |
+ showTextForElement: function(el, text, attachment, |
+ opt_offset, opt_padding) { |
var span = this.ownerDocument.createElement('span'); |
span.textContent = text; |
- this.showContentForElement(el, span); |
+ this.showContentForElement(el, span, attachment, opt_offset, opt_padding); |
}, |
/** |