Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
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

@ZenCocoon

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

@ZenCocoon

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. @ZenCocoon

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

    ZenCocoon authored
    …olutize & Element.undoRelativize. Tested and documented.
  2. @ZenCocoon

    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.
View
85 src/prototype/dom/layout.js
@@ -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) {
View
79 test/unit/dom_test.js
@@ -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);
View
6 test/unit/fixtures/dom.html
@@ -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.