From 2830ac2ac5fd3bde2cb0412a32361abbada9e6dc Mon Sep 17 00:00:00 2001 From: Tobie Langel Date: Sun, 3 Feb 2008 22:29:29 +0000 Subject: [PATCH] prototype: Prevent Element#cumulativeOffset, Element#getOffsetParent, Element#positionedOffset, Element#viewportOffset and Element#clonePosition from throwing an error in IE when called on a parent-less element. Closes #9416, #10192, #10248. --- CHANGELOG | 2 ++ src/dom.js | 13 +++++++++++++ test/unit/dom.html | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 1415858..1b67198 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +* Prevent Element#cumulativeOffset, Element#getOffsetParent, Element#positionedOffset, Element#viewportOffset and Element#clonePosition from throwing an error in IE when called on a parent-less element. Closes #9416, #10192, #10248. [ronstoney, psiborg, kangax] + * Prevent Enumerable#eachSlice from entering into an endless loop if passed an argument smaller than 1. Closes #10665. [kangax, Tobie Langel] * Allow Selector to correctly detect the presence of namespaced attributes. Closes #10987. [Samuel Lebeau, Tobie Langel] diff --git a/src/dom.js b/src/dom.js index 6b44eed..d790b0e 100644 --- a/src/dom.js +++ b/src/dom.js @@ -717,6 +717,9 @@ else if (Prototype.Browser.IE) { Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap( function(proceed, element) { element = $(element); + // IE throws an error if element is not in document + try { element.offsetParent } + catch(e) { return $(document.body) } var position = element.getStyle('position'); if (position !== 'static') return proceed(element); element.setStyle({ position: 'relative' }); @@ -730,6 +733,8 @@ else if (Prototype.Browser.IE) { Element.Methods[method] = Element.Methods[method].wrap( function(proceed, element) { element = $(element); + try { element.offsetParent } + catch(e) { return Element._returnOffset(0,0) } var position = element.getStyle('position'); if (position !== 'static') return proceed(element); // Trigger hasLayout on the offset parent so that IE6 reports @@ -744,6 +749,14 @@ else if (Prototype.Browser.IE) { } ); }); + + Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap( + function(proceed, element) { + try { element.offsetParent } + catch(e) { return Element._returnOffset(0,0) } + return proceed(element); + } + ); Element.Methods.getStyle = function(element, style) { element = $(element); diff --git a/test/unit/dom.html b/test/unit/dom.html index c72face..0a7f629 100644 --- a/test/unit/dom.html +++ b/test/unit/dom.html @@ -1618,6 +1618,18 @@ var afu = $('absolute_fixed_undefined'); assertEnumEqual([afu.offsetLeft, afu.offsetTop], afu.positionedOffset()); + + var element = new Element('div'), offset = element.positionedOffset(); + assertEnumEqual([0,0], offset); + assertIdentical(0, offset.top); + assertIdentical(0, offset.left); + }}, + + testCumulativeOffset: function() {with(this) { + var element = new Element('div'), offset = element.cumulativeOffset(); + assertEnumEqual([0,0], offset); + assertIdentical(0, offset.top); + assertIdentical(0, offset.left); }}, testViewportOffset: function() {with(this) { @@ -1629,6 +1641,10 @@ $('absolute_relative').viewportOffset()); assertEnumEqual([20,30], $('absolute_relative_undefined').viewportOffset()); + var element = new Element('div'), offset = element.viewportOffset(); + assertEnumEqual([0,0], offset); + assertIdentical(0, offset.top); + assertIdentical(0, offset.left); }}, testOffsetParent: function() {with(this) { @@ -1636,6 +1652,8 @@ assertEqual('body_absolute', $('absolute_relative').getOffsetParent().id); assertEqual('absolute_relative', $('inline').getOffsetParent().id); assertEqual('absolute_relative', $('absolute_relative_undefined').getOffsetParent().id); + + assertEqual(document.body, new Element('div').getOffsetParent()); }}, testAbsolutize: function() {with(this) {