mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Make JX.Tooltip more conservative about positioning
Summary: Fixes T10687. Fixes T12064. - Primarily, adds a margin around the edge of the screen for the purposes of aligning the tooltip. - Also, tries to flip the tooltip if it can (e.g., if the tooltip normally goes east, try west first), then tries other positions exhastively. Test Plan: {F2309363} {F2309364} Reviewers: chad Reviewed By: chad Maniphest Tasks: T12064, T10687 Differential Revision: https://secure.phabricator.com/D17145
This commit is contained in:
parent
1f2306999b
commit
5ff02058a4
2 changed files with 73 additions and 54 deletions
|
@ -10,7 +10,7 @@ return array(
|
|||
'conpherence.pkg.css' => '0b64e988',
|
||||
'conpherence.pkg.js' => '6249a1cf',
|
||||
'core.pkg.css' => '9c725fa0',
|
||||
'core.pkg.js' => 'f998932d',
|
||||
'core.pkg.js' => 'a2ead3fe',
|
||||
'darkconsole.pkg.js' => 'e7393ebb',
|
||||
'differential.pkg.css' => 'f69afb45',
|
||||
'differential.pkg.js' => '40b18f35',
|
||||
|
@ -489,7 +489,7 @@ return array(
|
|||
'rsrc/js/core/ShapedRequest.js' => '7cbe244b',
|
||||
'rsrc/js/core/TextAreaUtils.js' => '320810c8',
|
||||
'rsrc/js/core/Title.js' => '485aaa6c',
|
||||
'rsrc/js/core/ToolTip.js' => '6323f942',
|
||||
'rsrc/js/core/ToolTip.js' => 'b5c62c3b',
|
||||
'rsrc/js/core/behavior-active-nav.js' => 'e379b58e',
|
||||
'rsrc/js/core/behavior-audio-source.js' => '59b251eb',
|
||||
'rsrc/js/core/behavior-autofocus.js' => '7319e029',
|
||||
|
@ -816,7 +816,7 @@ return array(
|
|||
'phabricator-standard-page-view' => '894d8a25',
|
||||
'phabricator-textareautils' => '320810c8',
|
||||
'phabricator-title' => '485aaa6c',
|
||||
'phabricator-tooltip' => '6323f942',
|
||||
'phabricator-tooltip' => 'b5c62c3b',
|
||||
'phabricator-ui-example-css' => '528b19de',
|
||||
'phabricator-uiexample-javelin-view' => 'd4a14807',
|
||||
'phabricator-uiexample-reactor-button' => 'd19198c8',
|
||||
|
@ -1418,12 +1418,6 @@ return array(
|
|||
'javelin-install',
|
||||
'javelin-util',
|
||||
),
|
||||
'6323f942' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
),
|
||||
'635de1ec' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -1903,6 +1897,12 @@ return array(
|
|||
'javelin-install',
|
||||
'javelin-dom',
|
||||
),
|
||||
'b5c62c3b' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
),
|
||||
'b5d57730' => array(
|
||||
'javelin-install',
|
||||
'javelin-stratcom',
|
||||
|
|
|
@ -65,15 +65,48 @@ JX.install('Tooltip', {
|
|||
|
||||
_getSmartPosition: function (align, root, node) {
|
||||
var self = JX.Tooltip;
|
||||
var pos = self._proposePosition(align, root, node);
|
||||
|
||||
// If toolip is offscreen, try to be clever
|
||||
if (!JX.Tooltip.isOnScreen(pos, node)) {
|
||||
align = self._getImprovedOrientation(pos, node);
|
||||
pos = self._proposePosition(align, root, node);
|
||||
// Figure out how to position the tooltip on screen. We will try the
|
||||
// configured aligment first.
|
||||
var try_alignments = [align];
|
||||
|
||||
// If the configured alignment does not fit, we'll try the opposite
|
||||
// alignment.
|
||||
var opposites = {
|
||||
N: 'S',
|
||||
S: 'N',
|
||||
E: 'W',
|
||||
W: 'E'
|
||||
};
|
||||
try_alignments.push(opposites[align]);
|
||||
|
||||
// Then we'll try the other alignments, in arbitrary order.
|
||||
for (var k in opposites) {
|
||||
try_alignments.push(k);
|
||||
}
|
||||
|
||||
self._setAnchor(align);
|
||||
var use_alignment = null;
|
||||
var use_pos = null;
|
||||
for (var ii = 0; ii < try_alignments.length; ii++) {
|
||||
var try_alignment = try_alignments[ii];
|
||||
|
||||
var pos = self._proposePosition(try_alignment, root, node);
|
||||
if (self.isOnScreen(pos, node)) {
|
||||
use_alignment = try_alignment;
|
||||
use_pos = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we don't come up with a good answer, default to the configured
|
||||
// alignment.
|
||||
if (use_alignment === null) {
|
||||
use_alignment = align;
|
||||
use_pos = self._proposePosition(use_alignment, root, node);
|
||||
}
|
||||
|
||||
self._setAnchor(use_alignment);
|
||||
|
||||
return pos;
|
||||
},
|
||||
|
||||
|
@ -108,56 +141,24 @@ JX.install('Tooltip', {
|
|||
},
|
||||
|
||||
isOnScreen: function (a, node) {
|
||||
var s = JX.Vector.getScroll();
|
||||
var v = JX.Vector.getViewport();
|
||||
var max_x = s.x + v.x;
|
||||
var max_y = s.y + v.y;
|
||||
|
||||
var view = this._getViewBoundaries();
|
||||
var corners = this._getNodeCornerPositions(a, node);
|
||||
|
||||
// Check if any of the corners are offscreen
|
||||
// Check if any of the corners are offscreen.
|
||||
for (var i = 0; i < corners.length; i++) {
|
||||
var corner = corners[i];
|
||||
if (corner.x < s.x ||
|
||||
corner.y < s.y ||
|
||||
corner.x > max_x ||
|
||||
corner.y > max_y) {
|
||||
if (corner.x < view.w ||
|
||||
corner.y < view.n ||
|
||||
corner.x > view.e ||
|
||||
corner.y > view.s) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
_getImprovedOrientation: function (a, node) {
|
||||
// Try to predict the "more correct" orientation
|
||||
var s = JX.Vector.getScroll();
|
||||
var v = JX.Vector.getViewport();
|
||||
var max_x = s.x + v.x;
|
||||
var max_y = s.y + v.y;
|
||||
|
||||
var corners = this._getNodeCornerPositions(a, node);
|
||||
|
||||
for (var i = 0; i < corners.length; i++) {
|
||||
var corner = corners[i];
|
||||
if (corner.y < v.y) {
|
||||
return 'S';
|
||||
} else
|
||||
if (corner.x < v.x) {
|
||||
return 'E';
|
||||
} else
|
||||
if (corner.y > max_y) {
|
||||
return 'N';
|
||||
} else
|
||||
if (corner.x > max_x) {
|
||||
return 'W';
|
||||
} else {
|
||||
return 'N';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_getNodeCornerPositions: function(pos, node) {
|
||||
// Get positions of all four corners of a node
|
||||
// Get positions of all four corners of a node.
|
||||
var n = JX.Vector.getDim(node);
|
||||
return [new JX.Vector(pos.x, pos.y),
|
||||
new JX.Vector(pos.x + n.x, pos.y),
|
||||
|
@ -165,6 +166,24 @@ JX.install('Tooltip', {
|
|||
new JX.Vector(pos.x + n.x, pos.y + n.y)];
|
||||
},
|
||||
|
||||
_getViewBoundaries: function() {
|
||||
var s = JX.Vector.getScroll();
|
||||
var v = JX.Vector.getViewport();
|
||||
var max_x = s.x + v.x;
|
||||
var max_y = s.y + v.y;
|
||||
|
||||
// Even if the corner is technically on the screen, don't allow the
|
||||
// tip to display too close to the edge of the screen.
|
||||
var margin = 16;
|
||||
|
||||
return {
|
||||
w: s.x + margin,
|
||||
e: max_x - margin,
|
||||
n: s.y + margin,
|
||||
s: max_y - margin
|
||||
};
|
||||
},
|
||||
|
||||
_setAnchor: function (align) {
|
||||
// Orient the little tail
|
||||
JX.DOM.alterClass(this._node, 'jx-tooltip-align-' + align, true);
|
||||
|
|
Loading…
Reference in a new issue