Skip to content

Commit f645672

Browse files
authored
Fixed bug on clonePosition() in prototype.js. (#2669)
1 parent 302e898 commit f645672

File tree

1 file changed

+33
-20
lines changed

1 file changed

+33
-20
lines changed

js/prototype/prototype.js

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4271,55 +4271,68 @@ Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
42714271
offsetLeft: 0
42724272
}, options || {});
42734273

4274-
var docEl = document.documentElement;
4275-
4274+
// Find page position of source.
42764275
source = $(source);
42774276
element = $(element);
42784277
var p, delta, layout, styles = {};
42794278

4279+
var isAbsolute = Element.getStyle(element, 'position') === 'absolute';
4280+
var parent = Element.getOffsetParent(element);
4281+
42804282
if (options.setLeft || options.setTop) {
4283+
// We start by measuring the source's viewport offset.
42814284
p = Element.viewportOffset(source);
4285+
4286+
// If the element we're altering is `position: fixed`, that's all the
4287+
// information we need: later we'll apply that offset to the `top` and
4288+
// `left` properties directly.
42824289
delta = [0, 0];
4283-
if (Element.getStyle(element, 'position') === 'absolute') {
4284-
var parent = Element.getOffsetParent(element);
4285-
if (parent !== document.body) delta = Element.viewportOffset(parent);
4290+
4291+
// But if it's `position: absolute`, we have to know where its offset
4292+
// parent is positioned and take those measurements into account as
4293+
// well.
4294+
if (isAbsolute && parent !== document.body) {
4295+
delta = Element.viewportOffset(parent);
42864296
}
42874297
}
42884298

42894299
function pageScrollXY() {
42904300
var x = 0, y = 0;
42914301
if (Object.isNumber(window.pageXOffset)) {
4302+
// Modern browsers.
42924303
x = window.pageXOffset;
42934304
y = window.pageYOffset;
42944305
} else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
42954306
x = document.body.scrollLeft;
42964307
y = document.body.scrollTop;
4297-
} else if (docEl && (docEl.scrollLeft || docEl.scrollTop)) {
4298-
x = docEl.scrollLeft;
4299-
y = docEl.scrollTop;
43004308
}
43014309
return { x: x, y: y };
43024310
}
43034311

4304-
var pageXY = pageScrollXY();
4305-
4306-
4307-
if (options.setWidth || options.setHeight) {
4308-
layout = Element.getLayout(source);
4309-
}
4312+
// When the offset parent is the document body, we need to account for
4313+
// scroll offsets when we set `top` and `left`. (Unless the element is
4314+
// `position: fixed`; in that case we should always ignore scroll
4315+
// position.)
4316+
var pageXY = (isAbsolute && parent === document.body) ? pageScrollXY() : { x: 0, y: 0 };
43104317

4318+
// Set position.
43114319
if (options.setLeft)
43124320
styles.left = (p[0] + pageXY.x - delta[0] + options.offsetLeft) + 'px';
43134321
if (options.setTop)
43144322
styles.top = (p[1] + pageXY.y - delta[1] + options.offsetTop) + 'px';
43154323

4316-
var currentLayout = element.getLayout();
4324+
if (options.setWidth || options.setHeight) {
4325+
layout = Element.getLayout(source);
43174326

4318-
if (options.setWidth) {
4319-
styles.width = layout.get('width') + 'px';
4320-
}
4321-
if (options.setHeight) {
4322-
styles.height = layout.get('height') + 'px';
4327+
// Use content box when setting width/height. If padding/border are
4328+
// different between source and target, that's for the user to fix;
4329+
// there's no good option for us.
4330+
if (options.setWidth) {
4331+
styles.width = layout.get('width') + 'px';
4332+
}
4333+
if (options.setHeight) {
4334+
styles.height = layout.get('height') + 'px';
4335+
}
43234336
}
43244337

43254338
return Element.setStyle(element, styles);

0 commit comments

Comments
 (0)