Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Unified Diff: ui/file_manager/file_manager/foreground/js/tooltip_controller.js

Issue 1223693002: Add tooltips to the header buttons in Files app. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix tests. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/file_manager/file_manager/foreground/js/tooltip_controller.js
diff --git a/ui/file_manager/file_manager/foreground/js/tooltip_controller.js b/ui/file_manager/file_manager/foreground/js/tooltip_controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..a6d7d3b26c9e82acec0d3c0bb19e01fafe9ce15a
--- /dev/null
+++ b/ui/file_manager/file_manager/foreground/js/tooltip_controller.js
@@ -0,0 +1,185 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Controls showing and hising tooltips when hovering over tooltipable HTML
+ * elements.
+ * @param {!HTMLElement} tooltip
+ * @param {!Array<!HTMLElement>} targets
+ * @constructor
+ * @struct
+ */
+function TooltipController(tooltip, targets) {
+ /** @private {!HTMLElement} */
+ this.tooltip_ = tooltip;
+
+ /** @private {!HTMLElement} */
+ this.tooltipLabel_ = queryRequiredElement(tooltip, '#tooltip-label');
+
+ /** @private {!Array<!HTMLElement>} */
+ this.targets_ = targets;
+
+ /** @private {HTMLElement} */
+ this.visibleTooltipTarget_ = null;
+
+ /** @private {HTMLElement} */
+ this.upcomingTooltipTarget_ = null;
+
+ /** @private {number} */
+ this.showTooltipTimerId_ = 0;
+
+ /** @private {number} */
+ this.hideTooltipTimerId_ = 0;
+
+ this.targets_.forEach(function(target) {
+ target.addEventListener('mouseover', this.onMouseOver_.bind(this, target));
+ target.addEventListener('mouseout', this.onMouseOut_.bind(this, target));
+ target.addEventListener('focus', this.onFocus_.bind(this, target));
+ target.addEventListener('blur', this.onBlur_.bind(this, target));
+ }.bind(this));
+
+ document.body.addEventListener(
+ 'mousedown', this.onDocumentMouseDown_.bind(this));
+}
+
+/**
+ * Delay for showing the tooltip in milliseconds.
+ * @const {number}
+ */
+TooltipController.SHOW_TIMEOUT = 500;
+
+/**
+ * Delay for hiding the tooltip in milliseconds.
+ * @const {number}
+ */
+TooltipController.HIDE_TIMEOUT = 250;
+
+/**
+ * @param {!HTMLElement} target
+ * @private
+ */
+TooltipController.prototype.initShowingTooltip_ = function(target) {
+ // Some tooltip is already visible.
+ if (this.visibleTooltipTarget_) {
+ if (this.hideTooltipTimerId_) {
+ clearTimeout(this.hideTooltipTimerId_);
+ this.hideTooltipTimerId_ = 0;
+ }
+ }
+
+ if (this.visibleTooltipTarget_ === target)
+ return;
+
+ this.upcomingTooltipTarget_ = target;
+ if (this.showTooltipTimerId_)
+ clearTimeout(this.showTooltipTimerId_);
+ this.showTooltipTimerId_ = setTimeout(
+ this.showTooltip_.bind(this, target),
+ this.visibleTooltipTarget_ ? 0 : TooltipController.SHOW_TIMEOUT);
+};
+
+/**
+ * @param {!HTMLElement} target
+ * @private
+ */
+TooltipController.prototype.initHidingTooltip_ = function(target) {
+ // The tooltip is not visible.
+ if (this.visibleTooltipTarget_ !== target) {
+ if (this.upcomingTooltipTarget_ === target) {
+ clearTimeout(this.showTooltipTimerId_);
+ this.showTooltipTimerId_ = 0;
+ }
+ return;
+ }
+
+ if (this.hideTooltipTimerId_)
+ clearTimeout(this.hideTooltipTimerId_);
+ this.hideTooltipTimerId_ = setTimeout(
+ this.hideTooltip_.bind(this), TooltipController.HIDE_TIMEOUT);
+};
+
+/**
+ * @param {!HTMLElement} target
+ * @private
+ */
+TooltipController.prototype.showTooltip_ = function(target) {
+ if (this.showTooltipTimerId_) {
+ clearTimeout(this.showTooltipTimerId_);
+ this.showTooltipTimerId_ = 0;
+ }
+
+ this.visibleTooltipTarget_ = target;
+
+ var label = target.getAttribute('aria-label');
+ if (!label)
+ return;
+
+ this.tooltipLabel_.textContent = label;
+ var rect = target.getBoundingClientRect();
+ this.tooltip_.style.top = Math.round(rect.top) + rect.height + 'px';
+ var left = rect.left + rect.width / 2 - this.tooltip_.offsetWidth / 2;
+ if (left + this.tooltip_.offsetWidth > document.body.offsetWidth)
+ left = document.body.offsetWidth - this.tooltip_.offsetWidth;
+ this.tooltip_.style.left = Math.round(left) + 'px';
+ this.tooltip_.setAttribute('visible', true);
+};
+
+/**
+ * @private
+ */
+TooltipController.prototype.hideTooltip_ = function() {
+ if (this.hideTooltipTimerId_) {
+ clearTimeout(this.hideTooltipTimerId_);
+ this.hideTooltipTimerId_ = 0;
+ }
+
+ this.visibleTooltipTarget_ = null;
+ this.tooltip_.removeAttribute('visible');
+};
+
+/**
+ * @param {Event} event
+ * @private
+ */
+TooltipController.prototype.onMouseOver_ = function(target, event) {
+ this.initShowingTooltip_(target);
+};
+
+/**
+ * @param {Event} event
+ * @private
+ */
+TooltipController.prototype.onMouseOut_ = function(target, event) {
+ this.initHidingTooltip_(target);
+};
+
+/**
+ * @param {Event} event
+ * @private
+ */
+TooltipController.prototype.onFocus_ = function(target, event) {
+ this.initShowingTooltip_(target);
+};
+
+/**
+ * @param {Event} event
+ * @private
+ */
+TooltipController.prototype.onBlur_ = function(target, event) {
+ this.initHidingTooltip_(target);
+};
+
+/**
+ * @param {Event} event
+ * @private
+ */
+TooltipController.prototype.onDocumentMouseDown_ = function(event) {
+ this.hideTooltip_();
+
+ // Additionally prevent any scheduled tooltips from showing up.
+ if (this.showTooltipTimerId_) {
+ clearTimeout(this.showTooltipTimerId_);
+ this.showTooltipTimerId_ = 0;
+ }
+};

Powered by Google App Engine
This is Rietveld 408576698