Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/third_party/closure/goog/positioning/anchoredviewportposition.js
4206 views
1
/**
2
* @license
3
* Copyright The Closure Library Authors.
4
* SPDX-License-Identifier: Apache-2.0
5
*/
6
7
/**
8
* @fileoverview Anchored viewport positioning class.
9
*/
10
11
goog.provide('goog.positioning.AnchoredViewportPosition');
12
13
goog.require('goog.positioning');
14
goog.require('goog.positioning.AnchoredPosition');
15
goog.require('goog.positioning.Overflow');
16
goog.require('goog.positioning.OverflowStatus');
17
goog.requireType('goog.math.Box');
18
goog.requireType('goog.math.Size');
19
20
21
22
/**
23
* Encapsulates a popup position where the popup is anchored at a corner of
24
* an element. The corners are swapped if dictated by the viewport. For instance
25
* if a popup is anchored with its top left corner to the bottom left corner of
26
* the anchor the popup is either displayed below the anchor (as specified) or
27
* above it if there's not enough room to display it below.
28
*
29
* When using this positioning object it's recommended that the movable element
30
* be absolutely positioned.
31
*
32
* @param {Element} anchorElement Element the movable element should be
33
* anchored against.
34
* @param {goog.positioning.Corner} corner Corner of anchored element the
35
* movable element should be positioned at.
36
* @param {boolean=} opt_adjust Whether the positioning should be adjusted until
37
* the element fits inside the viewport even if that means that the anchored
38
* corners are ignored.
39
* @param {goog.math.Box=} opt_overflowConstraint Box object describing the
40
* dimensions in which the movable element could be shown.
41
* @constructor
42
* @extends {goog.positioning.AnchoredPosition}
43
*/
44
goog.positioning.AnchoredViewportPosition = function(
45
anchorElement, corner, opt_adjust, opt_overflowConstraint) {
46
'use strict';
47
goog.positioning.AnchoredPosition.call(this, anchorElement, corner);
48
49
/**
50
* The last resort algorithm to use if the algorithm can't fit inside
51
* the viewport.
52
*
53
* IGNORE = do nothing, just display at the preferred position.
54
*
55
* ADJUST_X | ADJUST_Y = Adjust until the element fits, even if that means
56
* that the anchored corners are ignored.
57
*
58
* @type {number}
59
* @private
60
*/
61
this.lastResortOverflow_ = opt_adjust ? (goog.positioning.Overflow.ADJUST_X |
62
goog.positioning.Overflow.ADJUST_Y) :
63
goog.positioning.Overflow.IGNORE;
64
65
/**
66
* The dimensions in which the movable element could be shown.
67
* @type {goog.math.Box|undefined}
68
* @private
69
*/
70
this.overflowConstraint_ = opt_overflowConstraint || undefined;
71
};
72
goog.inherits(
73
goog.positioning.AnchoredViewportPosition,
74
goog.positioning.AnchoredPosition);
75
76
77
/**
78
* @return {goog.math.Box|undefined} The box object describing the
79
* dimensions in which the movable element will be shown.
80
*/
81
goog.positioning.AnchoredViewportPosition.prototype.getOverflowConstraint =
82
function() {
83
'use strict';
84
return this.overflowConstraint_;
85
};
86
87
88
/**
89
* @param {goog.math.Box|undefined} overflowConstraint Box object describing the
90
* dimensions in which the movable element could be shown.
91
*/
92
goog.positioning.AnchoredViewportPosition.prototype.setOverflowConstraint =
93
function(overflowConstraint) {
94
'use strict';
95
this.overflowConstraint_ = overflowConstraint;
96
};
97
98
99
/**
100
* @return {number} A bitmask for the "last resort" overflow.
101
*/
102
goog.positioning.AnchoredViewportPosition.prototype.getLastResortOverflow =
103
function() {
104
'use strict';
105
return this.lastResortOverflow_;
106
};
107
108
109
/**
110
* @param {number} lastResortOverflow A bitmask for the "last resort" overflow,
111
* if we fail to fit the element on-screen.
112
*/
113
goog.positioning.AnchoredViewportPosition.prototype.setLastResortOverflow =
114
function(lastResortOverflow) {
115
'use strict';
116
this.lastResortOverflow_ = lastResortOverflow;
117
};
118
119
120
/**
121
* Repositions the movable element.
122
*
123
* @param {Element} movableElement Element to position.
124
* @param {goog.positioning.Corner} movableCorner Corner of the movable element
125
* that should be positioned adjacent to the anchored element.
126
* @param {goog.math.Box=} opt_margin A margin specified in pixels.
127
* @param {goog.math.Size=} opt_preferredSize The preferred size of the
128
* movableElement.
129
* @override
130
*/
131
goog.positioning.AnchoredViewportPosition.prototype.reposition = function(
132
movableElement, movableCorner, opt_margin, opt_preferredSize) {
133
'use strict';
134
var status = goog.positioning.positionAtAnchor(
135
this.element, this.corner, movableElement, movableCorner, null,
136
opt_margin,
137
goog.positioning.Overflow.FAIL_X | goog.positioning.Overflow.FAIL_Y,
138
opt_preferredSize, this.overflowConstraint_);
139
140
// If the desired position is outside the viewport try mirroring the corners
141
// horizontally or vertically.
142
if (status & goog.positioning.OverflowStatus.FAILED) {
143
var cornerFallback = this.adjustCorner(status, this.corner);
144
var movableCornerFallback = this.adjustCorner(status, movableCorner);
145
146
status = goog.positioning.positionAtAnchor(
147
this.element, cornerFallback, movableElement, movableCornerFallback,
148
null, opt_margin,
149
goog.positioning.Overflow.FAIL_X | goog.positioning.Overflow.FAIL_Y,
150
opt_preferredSize, this.overflowConstraint_);
151
152
if (status & goog.positioning.OverflowStatus.FAILED) {
153
// If that also fails, pick the best corner from the two tries,
154
// and adjust the position until it fits.
155
cornerFallback = this.adjustCorner(status, cornerFallback);
156
movableCornerFallback = this.adjustCorner(status, movableCornerFallback);
157
158
goog.positioning.positionAtAnchor(
159
this.element, cornerFallback, movableElement, movableCornerFallback,
160
null, opt_margin, this.getLastResortOverflow(), opt_preferredSize,
161
this.overflowConstraint_);
162
}
163
}
164
};
165
166
167
/**
168
* Adjusts the corner if X or Y positioning failed.
169
* @param {number} status The status of the last positionAtAnchor call.
170
* @param {goog.positioning.Corner} corner The corner to adjust.
171
* @return {goog.positioning.Corner} The adjusted corner.
172
* @protected
173
*/
174
goog.positioning.AnchoredViewportPosition.prototype.adjustCorner = function(
175
status, corner) {
176
'use strict';
177
if (status & goog.positioning.OverflowStatus.FAILED_HORIZONTAL) {
178
corner = goog.positioning.flipCornerHorizontal(corner);
179
}
180
181
if (status & goog.positioning.OverflowStatus.FAILED_VERTICAL) {
182
corner = goog.positioning.flipCornerVertical(corner);
183
}
184
185
return corner;
186
};
187
188