diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -9,8 +9,8 @@ 'names' => array( 'conpherence.pkg.css' => 'e25569a9', 'conpherence.pkg.js' => '6249a1cf', - 'core.pkg.css' => '25cda14d', - 'core.pkg.js' => 'f1e0e26f', + 'core.pkg.css' => '7cd6d9cb', + 'core.pkg.js' => '1fa7c0c5', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '4815647b', 'differential.pkg.js' => 'ddfeb49b', @@ -29,7 +29,7 @@ 'rsrc/css/aphront/phabricator-nav-view.css' => 'b29426e9', 'rsrc/css/aphront/table-view.css' => '213a5981', 'rsrc/css/aphront/tokenizer.css' => '9a8cb501', - 'rsrc/css/aphront/tooltip.css' => '3f325821', + 'rsrc/css/aphront/tooltip.css' => '8f9faa9a', 'rsrc/css/aphront/typeahead-browse.css' => '8904346a', 'rsrc/css/aphront/typeahead.css' => 'd4f16145', 'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af', @@ -486,7 +486,7 @@ 'rsrc/js/core/ShapedRequest.js' => '7cbe244b', 'rsrc/js/core/TextAreaUtils.js' => '320810c8', 'rsrc/js/core/Title.js' => '485aaa6c', - 'rsrc/js/core/ToolTip.js' => 'd02f7181', + 'rsrc/js/core/ToolTip.js' => '8fadb715', 'rsrc/js/core/behavior-active-nav.js' => 'e379b58e', 'rsrc/js/core/behavior-audio-source.js' => '59b251eb', 'rsrc/js/core/behavior-autofocus.js' => '7319e029', @@ -553,7 +553,7 @@ 'aphront-panel-view-css' => '8427b78d', 'aphront-table-view-css' => '213a5981', 'aphront-tokenizer-control-css' => '9a8cb501', - 'aphront-tooltip-css' => '3f325821', + 'aphront-tooltip-css' => '8f9faa9a', 'aphront-typeahead-control-css' => 'd4f16145', 'application-search-view-css' => '20ae9d85', 'auth-css' => '0877ed6e', @@ -811,7 +811,7 @@ 'phabricator-standard-page-view' => '894d8a25', 'phabricator-textareautils' => '320810c8', 'phabricator-title' => '485aaa6c', - 'phabricator-tooltip' => 'd02f7181', + 'phabricator-tooltip' => '8fadb715', 'phabricator-ui-example-css' => '528b19de', 'phabricator-uiexample-javelin-view' => 'd4a14807', 'phabricator-uiexample-reactor-button' => 'd19198c8', @@ -1602,6 +1602,12 @@ 'javelin-stratcom', 'javelin-util', ), + '8fadb715' => array( + 'javelin-install', + 'javelin-util', + 'javelin-dom', + 'javelin-vector', + ), '8ff5e24c' => array( 'javelin-behavior', 'javelin-stratcom', @@ -2016,12 +2022,6 @@ 'cd2b9b77' => array( 'phui-oi-list-view-css', ), - 'd02f7181' => array( - 'javelin-install', - 'javelin-util', - 'javelin-dom', - 'javelin-vector', - ), 'd0c516d5' => array( 'javelin-behavior', 'javelin-dom', diff --git a/webroot/rsrc/css/aphront/tooltip.css b/webroot/rsrc/css/aphront/tooltip.css --- a/webroot/rsrc/css/aphront/tooltip.css +++ b/webroot/rsrc/css/aphront/tooltip.css @@ -5,8 +5,25 @@ .jx-tooltip-container { position: absolute; padding: 5px; - opacity: 1; - transition: opacity 0.25s ease; +} + +.jx-tooltip-appear { + animation: 0.5s tooltip-appear; + + /* Without this, there's a nasty pop-in effect at the end of the animation + when Safari changes font smoothing. The text becomes visibly more bold + after the last frame of animation. */ + -webkit-font-smoothing: subpixel-antialiased; +} + +@keyframes tooltip-appear { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } } .jx-tooltip-hidden { diff --git a/webroot/rsrc/js/core/ToolTip.js b/webroot/rsrc/js/core/ToolTip.js --- a/webroot/rsrc/js/core/ToolTip.js +++ b/webroot/rsrc/js/core/ToolTip.js @@ -11,6 +11,7 @@ statics: { _node: null, + _last: null, _lock: 0, show : function(root, scale, align, content) { @@ -46,7 +47,7 @@ var node = JX.$N( 'div', - { className: 'jx-tooltip-container jx-tooltip-hidden' }, + { className: 'jx-tooltip-container' }, node_inner); node.style.maxWidth = scale + 'px'; @@ -61,7 +62,28 @@ // Jump through some hoops trying to auto-position the tooltip var pos = self._getSmartPosition(align, root, node); pos.setPos(node); - JX.DOM.alterClass(node, 'jx-tooltip-hidden', false); + + // Animate the tip if we haven't shown any tips recently. If we are + // already showing a tip (or hid one very recently) just show the tip + // immediately. This makes hunting for a particular item by mousing + // through tips smoother: you only have to sit through the animation + // once, at the beginning. + + var is_recent = false; + + var last_tip = self._last; + if (last_tip) { + // If we recently hid a tip, compute how many milliseconds ago we + // hid it. + var last_tip_age = (new Date().getTime() - self._last); + if (last_tip_age < 500) { + is_recent = true; + } + } + + if (!is_recent) { + JX.DOM.alterClass(node, 'jx-tooltip-appear', true); + } }, _getSmartPosition: function (align, root, node) { @@ -194,6 +216,7 @@ if (this._node) { JX.DOM.remove(this._node); this._node = null; + this._last = new Date().getTime(); } },