Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/positioning/positioning.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 Common positioning code.
17
*
18
* @author [email protected] (Emil A Eklund)
19
*/
20
21
goog.provide('goog.positioning');
22
goog.provide('goog.positioning.Corner');
23
goog.provide('goog.positioning.CornerBit');
24
goog.provide('goog.positioning.Overflow');
25
goog.provide('goog.positioning.OverflowStatus');
26
27
goog.require('goog.asserts');
28
goog.require('goog.dom');
29
goog.require('goog.dom.TagName');
30
goog.require('goog.math.Coordinate');
31
goog.require('goog.math.Rect');
32
goog.require('goog.math.Size');
33
goog.require('goog.style');
34
goog.require('goog.style.bidi');
35
36
37
/**
38
* Enum for bits in the {@see goog.positioning.Corner) bitmap.
39
*
40
* @enum {number}
41
*/
42
goog.positioning.CornerBit = {
43
BOTTOM: 1,
44
CENTER: 2,
45
RIGHT: 4,
46
FLIP_RTL: 8
47
};
48
49
50
/**
51
* Enum for representing an element corner for positioning the popup.
52
*
53
* The START constants map to LEFT if element directionality is left
54
* to right and RIGHT if the directionality is right to left.
55
* Likewise END maps to RIGHT or LEFT depending on the directionality.
56
*
57
* @enum {number}
58
*/
59
goog.positioning.Corner = {
60
TOP_LEFT: 0,
61
TOP_RIGHT: goog.positioning.CornerBit.RIGHT,
62
BOTTOM_LEFT: goog.positioning.CornerBit.BOTTOM,
63
BOTTOM_RIGHT:
64
goog.positioning.CornerBit.BOTTOM | goog.positioning.CornerBit.RIGHT,
65
TOP_START: goog.positioning.CornerBit.FLIP_RTL,
66
TOP_END:
67
goog.positioning.CornerBit.FLIP_RTL | goog.positioning.CornerBit.RIGHT,
68
BOTTOM_START:
69
goog.positioning.CornerBit.BOTTOM | goog.positioning.CornerBit.FLIP_RTL,
70
BOTTOM_END: goog.positioning.CornerBit.BOTTOM |
71
goog.positioning.CornerBit.RIGHT | goog.positioning.CornerBit.FLIP_RTL,
72
TOP_CENTER: goog.positioning.CornerBit.CENTER,
73
BOTTOM_CENTER:
74
goog.positioning.CornerBit.BOTTOM | goog.positioning.CornerBit.CENTER
75
};
76
77
78
/**
79
* Enum for representing position handling in cases where the element would be
80
* positioned outside the viewport.
81
*
82
* @enum {number}
83
*/
84
goog.positioning.Overflow = {
85
/** Ignore overflow */
86
IGNORE: 0,
87
88
/** Try to fit horizontally in the viewport at all costs. */
89
ADJUST_X: 1,
90
91
/** If the element can't fit horizontally, report positioning failure. */
92
FAIL_X: 2,
93
94
/** Try to fit vertically in the viewport at all costs. */
95
ADJUST_Y: 4,
96
97
/** If the element can't fit vertically, report positioning failure. */
98
FAIL_Y: 8,
99
100
/** Resize the element's width to fit in the viewport. */
101
RESIZE_WIDTH: 16,
102
103
/** Resize the element's height to fit in the viewport. */
104
RESIZE_HEIGHT: 32,
105
106
/**
107
* If the anchor goes off-screen in the x-direction, position the movable
108
* element off-screen. Otherwise, try to fit horizontally in the viewport.
109
*/
110
ADJUST_X_EXCEPT_OFFSCREEN: 64 | 1,
111
112
/**
113
* If the anchor goes off-screen in the y-direction, position the movable
114
* element off-screen. Otherwise, try to fit vertically in the viewport.
115
*/
116
ADJUST_Y_EXCEPT_OFFSCREEN: 128 | 4
117
};
118
119
120
/**
121
* Enum for representing the outcome of a positioning call.
122
*
123
* @enum {number}
124
*/
125
goog.positioning.OverflowStatus = {
126
NONE: 0,
127
ADJUSTED_X: 1,
128
ADJUSTED_Y: 2,
129
WIDTH_ADJUSTED: 4,
130
HEIGHT_ADJUSTED: 8,
131
FAILED_LEFT: 16,
132
FAILED_RIGHT: 32,
133
FAILED_TOP: 64,
134
FAILED_BOTTOM: 128,
135
FAILED_OUTSIDE_VIEWPORT: 256
136
};
137
138
139
/**
140
* Shorthand to check if a status code contains any fail code.
141
* @type {number}
142
*/
143
goog.positioning.OverflowStatus.FAILED =
144
goog.positioning.OverflowStatus.FAILED_LEFT |
145
goog.positioning.OverflowStatus.FAILED_RIGHT |
146
goog.positioning.OverflowStatus.FAILED_TOP |
147
goog.positioning.OverflowStatus.FAILED_BOTTOM |
148
goog.positioning.OverflowStatus.FAILED_OUTSIDE_VIEWPORT;
149
150
151
/**
152
* Shorthand to check if horizontal positioning failed.
153
* @type {number}
154
*/
155
goog.positioning.OverflowStatus.FAILED_HORIZONTAL =
156
goog.positioning.OverflowStatus.FAILED_LEFT |
157
goog.positioning.OverflowStatus.FAILED_RIGHT;
158
159
160
/**
161
* Shorthand to check if vertical positioning failed.
162
* @type {number}
163
*/
164
goog.positioning.OverflowStatus.FAILED_VERTICAL =
165
goog.positioning.OverflowStatus.FAILED_TOP |
166
goog.positioning.OverflowStatus.FAILED_BOTTOM;
167
168
169
/**
170
* Positions a movable element relative to an anchor element. The caller
171
* specifies the corners that should touch. This functions then moves the
172
* movable element accordingly.
173
*
174
* @param {Element} anchorElement The element that is the anchor for where
175
* the movable element should position itself.
176
* @param {goog.positioning.Corner} anchorElementCorner The corner of the
177
* anchorElement for positioning the movable element.
178
* @param {Element} movableElement The element to move.
179
* @param {goog.positioning.Corner} movableElementCorner The corner of the
180
* movableElement that that should be positioned adjacent to the anchor
181
* element.
182
* @param {goog.math.Coordinate=} opt_offset An offset specified in pixels.
183
* After the normal positioning algorithm is applied, the offset is then
184
* applied. Positive coordinates move the popup closer to the center of the
185
* anchor element. Negative coordinates move the popup away from the center
186
* of the anchor element.
187
* @param {goog.math.Box=} opt_margin A margin specified in pixels.
188
* After the normal positioning algorithm is applied and any offset, the
189
* margin is then applied. Positive coordinates move the popup away from the
190
* spot it was positioned towards its center. Negative coordinates move it
191
* towards the spot it was positioned away from its center.
192
* @param {?number=} opt_overflow Overflow handling mode. Defaults to IGNORE if
193
* not specified. Bitmap, {@see goog.positioning.Overflow}.
194
* @param {goog.math.Size=} opt_preferredSize The preferred size of the
195
* movableElement.
196
* @param {goog.math.Box=} opt_viewport Box object describing the dimensions of
197
* the viewport. The viewport is specified relative to offsetParent of
198
* {@code movableElement}. In other words, the viewport can be thought of as
199
* describing a "position: absolute" element contained in the offsetParent.
200
* It defaults to visible area of nearest scrollable ancestor of
201
* {@code movableElement} (see {@code goog.style.getVisibleRectForElement}).
202
* @return {goog.positioning.OverflowStatus} Status bitmap,
203
* {@see goog.positioning.OverflowStatus}.
204
*/
205
goog.positioning.positionAtAnchor = function(
206
anchorElement, anchorElementCorner, movableElement, movableElementCorner,
207
opt_offset, opt_margin, opt_overflow, opt_preferredSize, opt_viewport) {
208
209
goog.asserts.assert(movableElement);
210
var movableParentTopLeft =
211
goog.positioning.getOffsetParentPageOffset(movableElement);
212
213
// Get the visible part of the anchor element. anchorRect is
214
// relative to anchorElement's page.
215
var anchorRect = goog.positioning.getVisiblePart_(anchorElement);
216
217
// Translate anchorRect to be relative to movableElement's page.
218
goog.style.translateRectForAnotherFrame(
219
anchorRect, goog.dom.getDomHelper(anchorElement),
220
goog.dom.getDomHelper(movableElement));
221
222
// Offset based on which corner of the element we want to position against.
223
var corner =
224
goog.positioning.getEffectiveCorner(anchorElement, anchorElementCorner);
225
var offsetLeft = anchorRect.left;
226
if (corner & goog.positioning.CornerBit.RIGHT) {
227
offsetLeft += anchorRect.width;
228
} else if (corner & goog.positioning.CornerBit.CENTER) {
229
offsetLeft += anchorRect.width / 2;
230
}
231
232
// absolutePos is a candidate position relative to the
233
// movableElement's window.
234
var absolutePos = new goog.math.Coordinate(
235
offsetLeft, anchorRect.top +
236
(corner & goog.positioning.CornerBit.BOTTOM ? anchorRect.height : 0));
237
238
// Translate absolutePos to be relative to the offsetParent.
239
absolutePos =
240
goog.math.Coordinate.difference(absolutePos, movableParentTopLeft);
241
242
// Apply offset, if specified
243
if (opt_offset) {
244
absolutePos.x +=
245
(corner & goog.positioning.CornerBit.RIGHT ? -1 : 1) * opt_offset.x;
246
absolutePos.y +=
247
(corner & goog.positioning.CornerBit.BOTTOM ? -1 : 1) * opt_offset.y;
248
}
249
250
// Determine dimension of viewport.
251
var viewport;
252
if (opt_overflow) {
253
if (opt_viewport) {
254
viewport = opt_viewport;
255
} else {
256
viewport = goog.style.getVisibleRectForElement(movableElement);
257
if (viewport) {
258
viewport.top -= movableParentTopLeft.y;
259
viewport.right -= movableParentTopLeft.x;
260
viewport.bottom -= movableParentTopLeft.y;
261
viewport.left -= movableParentTopLeft.x;
262
}
263
}
264
}
265
266
return goog.positioning.positionAtCoordinate(
267
absolutePos, movableElement, movableElementCorner, opt_margin, viewport,
268
opt_overflow, opt_preferredSize);
269
};
270
271
272
/**
273
* Calculates the page offset of the given element's
274
* offsetParent. This value can be used to translate any x- and
275
* y-offset relative to the page to an offset relative to the
276
* offsetParent, which can then be used directly with as position
277
* coordinate for {@code positionWithCoordinate}.
278
* @param {!Element} movableElement The element to calculate.
279
* @return {!goog.math.Coordinate} The page offset, may be (0, 0).
280
*/
281
goog.positioning.getOffsetParentPageOffset = function(movableElement) {
282
// Ignore offset for the BODY element unless its position is non-static.
283
// For cases where the offset parent is HTML rather than the BODY (such as in
284
// IE strict mode) there's no need to get the position of the BODY as it
285
// doesn't affect the page offset.
286
var movableParentTopLeft;
287
var parent = /** @type {?} */ (movableElement).offsetParent;
288
if (parent) {
289
var isBody = parent.tagName == goog.dom.TagName.HTML ||
290
parent.tagName == goog.dom.TagName.BODY;
291
if (!isBody || goog.style.getComputedPosition(parent) != 'static') {
292
// Get the top-left corner of the parent, in page coordinates.
293
movableParentTopLeft = goog.style.getPageOffset(parent);
294
295
if (!isBody) {
296
movableParentTopLeft = goog.math.Coordinate.difference(
297
movableParentTopLeft,
298
new goog.math.Coordinate(
299
goog.style.bidi.getScrollLeft(parent), parent.scrollTop));
300
}
301
}
302
}
303
304
return movableParentTopLeft || new goog.math.Coordinate();
305
};
306
307
308
/**
309
* Returns intersection of the specified element and
310
* goog.style.getVisibleRectForElement for it.
311
*
312
* @param {Element} el The target element.
313
* @return {!goog.math.Rect} Intersection of getVisibleRectForElement
314
* and the current bounding rectangle of the element. If the
315
* intersection is empty, returns the bounding rectangle.
316
* @private
317
*/
318
goog.positioning.getVisiblePart_ = function(el) {
319
var rect = goog.style.getBounds(el);
320
var visibleBox = goog.style.getVisibleRectForElement(el);
321
if (visibleBox) {
322
rect.intersection(goog.math.Rect.createFromBox(visibleBox));
323
}
324
return rect;
325
};
326
327
328
/**
329
* Positions the specified corner of the movable element at the
330
* specified coordinate.
331
*
332
* @param {goog.math.Coordinate} absolutePos The coordinate to position the
333
* element at.
334
* @param {Element} movableElement The element to be positioned.
335
* @param {goog.positioning.Corner} movableElementCorner The corner of the
336
* movableElement that that should be positioned.
337
* @param {goog.math.Box=} opt_margin A margin specified in pixels.
338
* After the normal positioning algorithm is applied and any offset, the
339
* margin is then applied. Positive coordinates move the popup away from the
340
* spot it was positioned towards its center. Negative coordinates move it
341
* towards the spot it was positioned away from its center.
342
* @param {goog.math.Box=} opt_viewport Box object describing the dimensions of
343
* the viewport. Required if opt_overflow is specified.
344
* @param {?number=} opt_overflow Overflow handling mode. Defaults to IGNORE if
345
* not specified, {@see goog.positioning.Overflow}.
346
* @param {goog.math.Size=} opt_preferredSize The preferred size of the
347
* movableElement. Defaults to the current size.
348
* @return {goog.positioning.OverflowStatus} Status bitmap.
349
*/
350
goog.positioning.positionAtCoordinate = function(
351
absolutePos, movableElement, movableElementCorner, opt_margin, opt_viewport,
352
opt_overflow, opt_preferredSize) {
353
absolutePos = absolutePos.clone();
354
355
// Offset based on attached corner and desired margin.
356
var corner =
357
goog.positioning.getEffectiveCorner(movableElement, movableElementCorner);
358
var elementSize = goog.style.getSize(movableElement);
359
var size =
360
opt_preferredSize ? opt_preferredSize.clone() : elementSize.clone();
361
362
var positionResult = goog.positioning.getPositionAtCoordinate(
363
absolutePos, size, corner, opt_margin, opt_viewport, opt_overflow);
364
365
if (positionResult.status & goog.positioning.OverflowStatus.FAILED) {
366
return positionResult.status;
367
}
368
369
goog.style.setPosition(movableElement, positionResult.rect.getTopLeft());
370
size = positionResult.rect.getSize();
371
if (!goog.math.Size.equals(elementSize, size)) {
372
goog.style.setBorderBoxSize(movableElement, size);
373
}
374
375
return positionResult.status;
376
};
377
378
379
/**
380
* Computes the position for an element to be placed on-screen at the
381
* specified coordinates. Returns an object containing both the resulting
382
* rectangle, and the overflow status bitmap.
383
*
384
* @param {!goog.math.Coordinate} absolutePos The coordinate to position the
385
* element at.
386
* @param {!goog.math.Size} elementSize The size of the element to be
387
* positioned.
388
* @param {goog.positioning.Corner} elementCorner The corner of the
389
* movableElement that that should be positioned.
390
* @param {goog.math.Box=} opt_margin A margin specified in pixels.
391
* After the normal positioning algorithm is applied and any offset, the
392
* margin is then applied. Positive coordinates move the popup away from the
393
* spot it was positioned towards its center. Negative coordinates move it
394
* towards the spot it was positioned away from its center.
395
* @param {goog.math.Box=} opt_viewport Box object describing the dimensions of
396
* the viewport. Required if opt_overflow is specified.
397
* @param {?number=} opt_overflow Overflow handling mode. Defaults to IGNORE
398
* if not specified, {@see goog.positioning.Overflow}.
399
* @return {{rect:!goog.math.Rect, status:goog.positioning.OverflowStatus}}
400
* Object containing the computed position and status bitmap.
401
*/
402
goog.positioning.getPositionAtCoordinate = function(
403
absolutePos, elementSize, elementCorner, opt_margin, opt_viewport,
404
opt_overflow) {
405
absolutePos = absolutePos.clone();
406
elementSize = elementSize.clone();
407
var status = goog.positioning.OverflowStatus.NONE;
408
409
if (opt_margin || elementCorner != goog.positioning.Corner.TOP_LEFT) {
410
if (elementCorner & goog.positioning.CornerBit.RIGHT) {
411
absolutePos.x -= elementSize.width + (opt_margin ? opt_margin.right : 0);
412
} else if (elementCorner & goog.positioning.CornerBit.CENTER) {
413
absolutePos.x -= elementSize.width / 2;
414
} else if (opt_margin) {
415
absolutePos.x += opt_margin.left;
416
}
417
if (elementCorner & goog.positioning.CornerBit.BOTTOM) {
418
absolutePos.y -=
419
elementSize.height + (opt_margin ? opt_margin.bottom : 0);
420
} else if (opt_margin) {
421
absolutePos.y += opt_margin.top;
422
}
423
}
424
425
// Adjust position to fit inside viewport.
426
if (opt_overflow) {
427
status = opt_viewport ?
428
goog.positioning.adjustForViewport_(
429
absolutePos, elementSize, opt_viewport, opt_overflow) :
430
goog.positioning.OverflowStatus.FAILED_OUTSIDE_VIEWPORT;
431
}
432
433
var rect = new goog.math.Rect(0, 0, 0, 0);
434
rect.left = absolutePos.x;
435
rect.top = absolutePos.y;
436
rect.width = elementSize.width;
437
rect.height = elementSize.height;
438
return {rect: rect, status: status};
439
};
440
441
442
/**
443
* Adjusts the position and/or size of an element, identified by its position
444
* and size, to fit inside the viewport. If the position or size of the element
445
* is adjusted the pos or size objects, respectively, are modified.
446
*
447
* @param {goog.math.Coordinate} pos Position of element, updated if the
448
* position is adjusted.
449
* @param {goog.math.Size} size Size of element, updated if the size is
450
* adjusted.
451
* @param {goog.math.Box} viewport Bounding box describing the viewport.
452
* @param {number} overflow Overflow handling mode,
453
* {@see goog.positioning.Overflow}.
454
* @return {goog.positioning.OverflowStatus} Status bitmap,
455
* {@see goog.positioning.OverflowStatus}.
456
* @private
457
*/
458
goog.positioning.adjustForViewport_ = function(pos, size, viewport, overflow) {
459
var status = goog.positioning.OverflowStatus.NONE;
460
461
var ADJUST_X_EXCEPT_OFFSCREEN =
462
goog.positioning.Overflow.ADJUST_X_EXCEPT_OFFSCREEN;
463
var ADJUST_Y_EXCEPT_OFFSCREEN =
464
goog.positioning.Overflow.ADJUST_Y_EXCEPT_OFFSCREEN;
465
if ((overflow & ADJUST_X_EXCEPT_OFFSCREEN) == ADJUST_X_EXCEPT_OFFSCREEN &&
466
(pos.x < viewport.left || pos.x >= viewport.right)) {
467
overflow &= ~goog.positioning.Overflow.ADJUST_X;
468
}
469
if ((overflow & ADJUST_Y_EXCEPT_OFFSCREEN) == ADJUST_Y_EXCEPT_OFFSCREEN &&
470
(pos.y < viewport.top || pos.y >= viewport.bottom)) {
471
overflow &= ~goog.positioning.Overflow.ADJUST_Y;
472
}
473
474
// Left edge outside viewport, try to move it.
475
if (pos.x < viewport.left && overflow & goog.positioning.Overflow.ADJUST_X) {
476
pos.x = viewport.left;
477
status |= goog.positioning.OverflowStatus.ADJUSTED_X;
478
}
479
480
// Ensure object is inside the viewport width if required.
481
if (overflow & goog.positioning.Overflow.RESIZE_WIDTH) {
482
// Move left edge inside viewport.
483
var originalX = pos.x;
484
if (pos.x < viewport.left) {
485
pos.x = viewport.left;
486
status |= goog.positioning.OverflowStatus.WIDTH_ADJUSTED;
487
}
488
489
// Shrink width to inside right of viewport.
490
if (pos.x + size.width > viewport.right) {
491
// Set the width to be either the new maximum width within the viewport
492
// or the width originally within the viewport, whichever is less.
493
size.width = Math.min(
494
viewport.right - pos.x, originalX + size.width - viewport.left);
495
size.width = Math.max(size.width, 0);
496
status |= goog.positioning.OverflowStatus.WIDTH_ADJUSTED;
497
}
498
}
499
500
// Right edge outside viewport, try to move it.
501
if (pos.x + size.width > viewport.right &&
502
overflow & goog.positioning.Overflow.ADJUST_X) {
503
pos.x = Math.max(viewport.right - size.width, viewport.left);
504
status |= goog.positioning.OverflowStatus.ADJUSTED_X;
505
}
506
507
// Left or right edge still outside viewport, fail if the FAIL_X option was
508
// specified, ignore it otherwise.
509
if (overflow & goog.positioning.Overflow.FAIL_X) {
510
status |=
511
(pos.x < viewport.left ? goog.positioning.OverflowStatus.FAILED_LEFT :
512
0) |
513
(pos.x + size.width > viewport.right ?
514
goog.positioning.OverflowStatus.FAILED_RIGHT :
515
0);
516
}
517
518
// Top edge outside viewport, try to move it.
519
if (pos.y < viewport.top && overflow & goog.positioning.Overflow.ADJUST_Y) {
520
pos.y = viewport.top;
521
status |= goog.positioning.OverflowStatus.ADJUSTED_Y;
522
}
523
524
// Ensure object is inside the viewport height if required.
525
if (overflow & goog.positioning.Overflow.RESIZE_HEIGHT) {
526
// Move top edge inside viewport.
527
var originalY = pos.y;
528
if (pos.y < viewport.top) {
529
pos.y = viewport.top;
530
status |= goog.positioning.OverflowStatus.HEIGHT_ADJUSTED;
531
}
532
533
// Shrink height to inside bottom of viewport.
534
if (pos.y + size.height > viewport.bottom) {
535
// Set the height to be either the new maximum height within the viewport
536
// or the height originally within the viewport, whichever is less.
537
size.height = Math.min(
538
viewport.bottom - pos.y, originalY + size.height - viewport.top);
539
size.height = Math.max(size.height, 0);
540
status |= goog.positioning.OverflowStatus.HEIGHT_ADJUSTED;
541
}
542
}
543
544
// Bottom edge outside viewport, try to move it.
545
if (pos.y + size.height > viewport.bottom &&
546
overflow & goog.positioning.Overflow.ADJUST_Y) {
547
pos.y = Math.max(viewport.bottom - size.height, viewport.top);
548
status |= goog.positioning.OverflowStatus.ADJUSTED_Y;
549
}
550
551
// Top or bottom edge still outside viewport, fail if the FAIL_Y option was
552
// specified, ignore it otherwise.
553
if (overflow & goog.positioning.Overflow.FAIL_Y) {
554
status |=
555
(pos.y < viewport.top ? goog.positioning.OverflowStatus.FAILED_TOP :
556
0) |
557
(pos.y + size.height > viewport.bottom ?
558
goog.positioning.OverflowStatus.FAILED_BOTTOM :
559
0);
560
}
561
562
return status;
563
};
564
565
566
/**
567
* Returns an absolute corner (top/bottom left/right) given an absolute
568
* or relative (top/bottom start/end) corner and the direction of an element.
569
* Absolute corners remain unchanged.
570
* @param {Element} element DOM element to test for RTL direction.
571
* @param {goog.positioning.Corner} corner The popup corner used for
572
* positioning.
573
* @return {goog.positioning.Corner} Effective corner.
574
*/
575
goog.positioning.getEffectiveCorner = function(element, corner) {
576
return /** @type {goog.positioning.Corner} */ (
577
(corner & goog.positioning.CornerBit.FLIP_RTL &&
578
goog.style.isRightToLeft(element) ?
579
corner ^ goog.positioning.CornerBit.RIGHT :
580
corner) &
581
~goog.positioning.CornerBit.FLIP_RTL);
582
};
583
584
585
/**
586
* Returns the corner opposite the given one horizontally.
587
* @param {goog.positioning.Corner} corner The popup corner used to flip.
588
* @return {goog.positioning.Corner} The opposite corner horizontally.
589
*/
590
goog.positioning.flipCornerHorizontal = function(corner) {
591
return /** @type {goog.positioning.Corner} */ (
592
corner ^ goog.positioning.CornerBit.RIGHT);
593
};
594
595
596
/**
597
* Returns the corner opposite the given one vertically.
598
* @param {goog.positioning.Corner} corner The popup corner used to flip.
599
* @return {goog.positioning.Corner} The opposite corner vertically.
600
*/
601
goog.positioning.flipCornerVertical = function(corner) {
602
return /** @type {goog.positioning.Corner} */ (
603
corner ^ goog.positioning.CornerBit.BOTTOM);
604
};
605
606
607
/**
608
* Returns the corner opposite the given one horizontally and vertically.
609
* @param {goog.positioning.Corner} corner The popup corner used to flip.
610
* @return {goog.positioning.Corner} The opposite corner horizontally and
611
* vertically.
612
*/
613
goog.positioning.flipCorner = function(corner) {
614
return /** @type {goog.positioning.Corner} */ (
615
corner ^ goog.positioning.CornerBit.BOTTOM ^
616
goog.positioning.CornerBit.RIGHT);
617
};
618
619