Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fixed Element.Absolutize & Element.Relativize and add Element.undoAbsolutize & Element.undoRelativize. Tested and documented. #12

Closed
wants to merge 2 commits into from

1 participant

Sébastien Grosjean
Sébastien Grosjean

Fixed Element.Absolutize & Element.Relativize and add Element.undoAbsolutize & Element.undoRelativize.
Tested and documented.

More details on this issue can be found at: https://prototype.lighthouseapp.com/projects/8886/tickets/1137-elementrelativize-does-not-work-properly

Sébastien Grosjean

Backward compatibility and disordered Element.undoAbsolutize & Element.undoRelativize calls issues at #13

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 17, 2010
  1. Sébastien Grosjean

    Fixed Element.Absolutize & Element.Relativize and add Element.undoAbs…

    ZenCocoon authored
    …olutize & Element.undoRelativize. Tested and documented.
  2. Sébastien Grosjean

    Maintain backward compatibility and fix misordered Element.undoAbsolu…

    ZenCocoon authored
    …tize & Element.undoRelativize calls.
This page is out of date. Refresh to see the latest.
85 src/prototype/dom/layout.js
View
@@ -1040,10 +1040,18 @@
*
* Turns `element` into an absolutely-positioned element _without_
* changing its position in the page layout.
+ *
+ * It also reverts back a previous [[Element.relativize]] call
+ * on this `element`.
+ *
+ * To revert back to `element`'s original position,
+ * use [[Element.undoAbsolutize]].
**/
function absolutize(element) {
element = $(element);
+ element.undoRelativize();
+
if (Element.getStyle(element, 'position') === 'absolute') {
return element;
}
@@ -1056,10 +1064,11 @@
var layout = element.getLayout();
element.store('prototype_absolutize_original_styles', {
- left: element.getStyle('left'),
- top: element.getStyle('top'),
- width: element.getStyle('width'),
- height: element.getStyle('height')
+ position: element.getStyle('position'),
+ left: element.getStyle('left'),
+ top: element.getStyle('top'),
+ width: element.getStyle('width'),
+ height: element.getStyle('height')
});
element.setStyle({
@@ -1074,27 +1083,83 @@
}
/**
+ * Element.undoAbsolutize(@element) -> Element
+ *
+ * Sets `element` back to the state it was in _before_
+ * [[Element.absolutize]] was applied to it.
+ **/
+ function undoAbsolutize(element) {
+ element = $(element);
+
+ if (Element.getStyle(element, 'position') !== 'absolute') {
+ return element;
+ }
+
+ // Restore the original styles as captured by Element#absolutize.
+ var originalStyles =
+ element.retrieve('prototype_absolutize_original_styles');
+
+ element.store('prototype_absolutize_original_styles', undefined);
+
+ if (originalStyles) element.setStyle(originalStyles);
+ return element;
+ }
+
+ /**
* Element.relativize(@element) -> Element
*
* Turns `element` into a relatively-positioned element without changing
* its position in the page layout.
*
- * Used to undo a call to [[Element.absolutize]].
+ * It also reverts back a previous [[Element.absolutize]] call
+ * on this `element`.
+ *
+ * To revert back to `element`'s original position,
+ * use [[Element.undoRelativize]].
**/
function relativize(element) {
element = $(element);
+
+ element.undoAbsolutize();
+
if (Element.getStyle(element, 'position') === 'relative') {
return element;
}
+
+ element.store('prototype_relativize_original_styles', {
+ position: element.getStyle('position')
+ });
- // Restore the original styles as captured by Element#absolutize.
+ element.setStyle({
+ position: 'relative'
+ });
+
+ return element;
+ }
+
+ /**
+ * Element.undoRelativize(@element) -> Element
+ *
+ * Sets `element` back to the state it was in _before_
+ * [[Element.relativize]] was applied to it.
+ **/
+ function undoRelativize(element) {
+ element = $(element);
+
+ if (Element.getStyle(element, 'position') !== 'relative') {
+ return element;
+ }
+
+ // Restore the original styles as captured by Element#relativize.
var originalStyles =
- element.retrieve('prototype_absolutize_original_styles');
+ element.retrieve('prototype_relativize_original_styles');
+
+ element.store('prototype_relativize_original_styles', undefined);
if (originalStyles) element.setStyle(originalStyles);
return element;
}
-
+
if (Prototype.Browser.IE) {
// IE doesn't report offsets correctly for static elements, so we change them
// to "relative" to get the values, then change them back.
@@ -1165,7 +1230,9 @@
cumulativeScrollOffset: cumulativeScrollOffset,
viewportOffset: viewportOffset,
absolutize: absolutize,
- relativize: relativize
+ undoAbsolutize: undoAbsolutize,
+ relativize: relativize,
+ undoRelativize: undoRelativize
});
function isBody(element) {
79 test/unit/dom_test.js
View
@@ -1399,20 +1399,95 @@ new Test.Unit.Runner({
testAbsolutize: function() {
$('notInlineAbsoluted', 'inlineAbsoluted').each(function(elt) {
if ('_originalLeft' in elt) delete elt._originalLeft;
+
elt.absolutize();
+
this.assertUndefined(elt._originalLeft, 'absolutize() did not detect absolute positioning');
}, this);
+
+ // make sure it store original properties and set position as absolute
+ var element = $('absolute_fixed_undefined');
+
+ if (element.retrieve('prototype_absolutize_original_styles') !== undefined)
+ element.store('prototype_absolutize_original_styles', undefined);
+
+ element.absolutize();
+
+ this.assertEqual('absolute', element.getStyle('position'));
+
+ var originalStyles = element.retrieve('prototype_absolutize_original_styles');
+ this.assertNotUndefined(originalStyles, 'absolutize() did not store original properties');
+ ['position', 'top', 'left', 'width', 'height'].each(function(property) {
+ this.assertNotUndefined(originalStyles[property],
+ 'absolutize() did not store original ' + property + ' property');
+ }, this);
+
// invoking on "absolute" positioned element should return element
var element = $('absolute_fixed_undefined').setStyle({position: 'absolute'});
this.assertEqual(element, element.absolutize());
},
-
+
+ testUndoAbsolutize: function() {
+ $('position-static', 'position-fixed', 'position-relative').each(function(elt) {
+ elt.absolutize();
+ this.assertEqual(elt, elt.undoAbsolutize());
+ this.assertEqual(elt.id.split('-').last(), elt.getStyle('position'));
+ this.assertUndefined(elt.retrieve('prototype_absolutize_original_styles'));
+ }, this);
+ // invoking on none "absolute" positioned element should return element
+ var element = $('position-untouched');
+ this.assertEqual(element, element.undoAbsolutize());
+ },
+
testRelativize: function() {
+ var element = $('absolute_fixed_undefined');
+
+ if (element.retrieve('prototype_relativize_original_styles') !== undefined)
+ element.store('prototype_relativize_original_styles', undefined);
+
+ element.relativize();
+
+ this.assertEqual('relative', element.getStyle('position'));
+
+ var originalStyles = element.retrieve('prototype_relativize_original_styles');
+ this.assertNotUndefined(originalStyles, 'relativize() did not store original properties');
+ this.assertNotUndefined(originalStyles['position'],
+ 'relativize() did not store original position property');
+
// invoking on "relative" positioned element should return element
- var element = $('absolute_fixed_undefined').setStyle({position: 'relative'});
this.assertEqual(element, element.relativize());
},
+
+ testUndoRelativize: function() {
+ $('position-static', 'position-fixed', 'position-absolute').each(function(elt) {
+ elt.relativize();
+ this.assertEqual(elt, elt.undoRelativize());
+ this.assertEqual(elt.id.split('-').last(), elt.getStyle('position'));
+ this.assertUndefined(elt.retrieve('prototype_relativize_original_styles'));
+ }, this);
+ // invoking on none "relative" positioned element should return element
+ var element = $('position-untouched');
+ this.assertEqual(element, element.undoRelativize());
+ },
+
+ testAbsolutizeThenRelativize: function() {
+ var element = $('position-static');
+ element.absolutize();
+ element.relativize();
+ element.undoAbsolutize();
+ element.undoRelativize();
+ this.assertEqual('static', element.getStyle('position'));
+ },
+ testRelativizeThenAbsolutize: function() {
+ var element = $('position-static');
+ element.relativize();
+ element.absolutize();
+ element.undoRelativize();
+ element.undoAbsolutize();
+ this.assertEqual('static', element.getStyle('position'));
+ },
+
testViewportDimensions: function() {
preservingBrowserDimensions(function() {
window.resizeTo(800, 600);
6 test/unit/fixtures/dom.html
View
@@ -265,6 +265,12 @@
<div id="notInlineAbsoluted"></div>
<div id="inlineAbsoluted" style="position: absolute"></div>
+<div id="position-static"></div>
+<div id="position-fixed" style="position: fixed;"></div>
+<div id="position-absolute" style="position: absolute;"></div>
+<div id="position-relative" style="position: relative;"></div>
+<div id="position-untouched"></div>
+
<div id="unextended"></div>
<div id="identification">
<div id="predefined_id"></div>
Something went wrong with that request. Please try again.