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