You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ar...@apache.org on 2008/02/23 17:48:01 UTC
svn commit: r630473 - in
/myfaces/trinidad/branches/ar_panelPopup_positioning:
trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/
trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/
Author: arobinson74
Date: Sat Feb 23 08:48:00 2008
New Revision: 630473
URL: http://svn.apache.org/viewvc?rev=630473&view=rev
Log:
Fixes for panelPopup positioning
Modified:
myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/web.xml
myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Core.js
myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/PanelPopup.js
Modified: myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/web.xml?rev=630473&r1=630472&r2=630473&view=diff
==============================================================================
--- myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/web.xml (original)
+++ myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/web.xml Sat Feb 23 08:48:00 2008
@@ -94,6 +94,10 @@
<param-name>org.apache.myfaces.trinidad.resource.DEBUG</param-name>
<param-value>false</param-value>
</context-param>
+ <context-param>
+ <param-name>org.apache.myfaces.trinidad.DEBUG_JAVASCRIPT</param-name>
+ <param-value>true</param-value>
+ </context-param>
<!-- With setting this parameter you are able to specify the logical
outcome prefix to launch the dialog framework. If not set, the
Modified: myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Core.js
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Core.js?rev=630473&r1=630472&r2=630473&view=diff
==============================================================================
--- myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Core.js (original)
+++ myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Core.js Sat Feb 23 08:48:00 2008
@@ -4550,3 +4550,188 @@
return proxyFunction;
}
+
+/**
+ * Get the client window size.
+ * TODO - make this public?
+ *
+ * @return {Object} the client size of the window. The returned object will have w and h properties.
+ */
+TrUIUtils._getWindowClientSize = function()
+{
+ var func;
+
+ if (TrUIUtils['_getWinClientSize'] == null)
+ {
+ // IE is abnormal
+ if(_agent.isIE)
+ {
+ TrUIUtils._getWinClientSize = function()
+ {
+ var e = ((document.compatMode == "BackCompat") ? document.body : document.documentElement);
+ return { w: e.clientWidth, h: e.clientHeight };
+ }
+ }
+ else
+ {
+ TrUIUtils._getWinClientSize = function()
+ {
+ return { w: window.innerWidth, h: window.innerHeight };
+ }
+ }
+ }
+
+ return TrUIUtils._getWinClientSize();
+}
+
+/**
+ * Return the offset bounds of an element
+ * TODO - make this public?
+ *
+ * @param elem {String or Element} the ID of an element or an element reference
+ * @return {Object} the returned object will have x, y, w and h properties.
+ * Returns null if the element does not exist
+ */
+TrUIUtils._getElementBounds = function(elem)
+{
+ if (typeof(elem) == "string")
+ {
+ elem = document.getElementById(elem);
+ }
+ if (!elem)
+ {
+ return null;
+ }
+ var loc = TrUIUtils._getElementLocation(elem);
+ return { x: loc.x, y: loc.y, w: elem.offsetWidth, h: elem.offsetHeight };
+}
+
+/**
+ * Get the location of an element in relation to the view port.
+ * This will return the same co-ordinates as browser events (i.e. mouse event locations).
+ * TODO - make this public?
+ *
+ * @param elem {String or Element} the ID of an element or an element reference
+ * @return {Object} the location on the page. The returned object will have x and y properties.
+ * Returns null if the element does not exist
+ */
+TrUIUtils._getElementLocation = function(elem)
+{
+ if (typeof(elem) == "string")
+ {
+ elem = document.getElementById(elem);
+ }
+ if (!elem)
+ {
+ return null;
+ }
+
+ var func;
+
+ if (TrUIUtils['_getElemLoc'] == null)
+ {
+ // if possible, use more accurate browser specific methods
+ if (_agent.isGecko)
+ {
+ TrUIUtils._getElemLoc = function(elem)
+ {
+ var doc = elem.ownerDocument;
+ var box = doc.getBoxObjectFor(elem);
+ var loc = { x: box.screenX, y: box.screenY };
+ box = doc.getBoxObjectFor(doc.documentElement);
+ loc.x -= box.screenX;
+ loc.y -= box.screenY;
+ return loc;
+ }
+ }
+ else if(_agent.isIE)
+ {
+ TrUIUtils._getElemLoc = function(elem)
+ {
+ var doc = elem.ownerDocument;
+ var rect = elem.getBoundingClientRect();
+ var loc = { x: rect.left, y: rect.top };
+ var docElem = doc.documentElement;
+ var scrollLeft = docElem.scrollLeft;
+
+ var rtl = docElem["dir"] == "rtl";
+ // IE scroll bar adjustment
+ if (rtl)
+ {
+ scrollLeft += docElem.clientWidth - docElem.scrollWidth;
+ }
+ loc.x -= docElem.clientLeft - scrollLeft;
+ loc.y -= (docElem.clientTop - docElem.scrollTop);
+ return loc;
+ }
+ }
+ else
+ {
+ TrUIUtils._getElemLoc = function(elem)
+ {
+ var win = elem.ownerDocument.contentWindow;
+ // use offset* properties to determine location
+ var curleft = 0;
+ var curtop = 0;
+ for (var obj = elem; obj && obj != win; obj = obj.offsetParent)
+ {
+ curleft += obj.offsetLeft;
+ curtop += obj.offsetTop;
+ }
+ return { x: curleft, y: curtop };
+ }
+ }
+ }
+
+ return TrUIUtils._getElemLoc(elem);
+}
+
+
+/**
+ * Get a css property as its JavaScript variable name
+ */
+TrUIUtils._cssToJs = function(prop)
+{
+ var jsProp = '';
+ var upperNext = false;
+ for (var c = 0; c < prop.length; c++)
+ {
+ if (prop.charAt(c) == '-')
+ {
+ upperNext = true;
+ continue;
+ }
+
+ if (upperNext)
+ {
+ jsProp += prop.charAt(c).toUpperCase();
+ }
+ else
+ {
+ jsProp += prop.charAt(c);
+ }
+
+ upperNext = false;
+ }
+
+ return jsProp;
+}
+
+/**
+ * Get a calculated CSS style value
+ */
+TrUIUtils._getStyle = function(element, prop)
+{
+ if (element.currentStyle)
+ {
+ // remove dashes and uppercase next letter
+ var jsProp = this._cssToJs(prop);
+ return element.currentStyle[jsProp];
+ }
+ else if (window.getComputedStyle)
+ {
+ return document.defaultView.getComputedStyle(element, '')
+ .getPropertyValue(prop);
+ }
+ return '';
+}
\ No newline at end of file
Modified: myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/PanelPopup.js
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/PanelPopup.js?rev=630473&r1=630472&r2=630473&view=diff
==============================================================================
--- myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/PanelPopup.js (original)
+++ myfaces/trinidad/branches/ar_panelPopup_positioning/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/PanelPopup.js Sat Feb 23 08:48:00 2008
@@ -367,7 +367,6 @@
//add mask to body
document.body.appendChild(TrPanelPopup._mask);
-
}
TrPanelPopup._mask.style.display = "block";
@@ -387,184 +386,125 @@
/**
* Check to see if a point lies inside the bounds of an element
*/
-TrPanelPopup.prototype._hitTest = function(element, point)
+TrPanelPopup.prototype._hitTest = function(element, eventLoc)
{
- var pos = this._getElementPosition(element);
- if (pos.x > point.x || pos.y > point.y)
- {
- return false;
- }
- return pos.x + element.offsetWidth >= point.x &&
- pos.y + element.offsetHeight >= point.y;
+ var b = TrUIUtils._getElementBounds(element);
+
+ return b.x <= eventLoc.pageX && (b.x + b.w) >= eventLoc.pageX &&
+ b.y <= eventLoc.pageY && (b.y + b.h) >= eventLoc.pageY;
}
/**
* Reposition an element to ensure that it fits on the screen
*/
-TrPanelPopup.prototype._fitOnScreen = function(element)
+TrPanelPopup.prototype._fitOnScreen = function(element, windowSize)
{
- var vis = this._getStyle(element, 'visibility');
+ var vis = TrUIUtils._getStyle(element, 'visibility');
element.style.visibility = 'hidden';
- if (element.origX)
+ var b = TrUIUtils._getElementBounds(element);
+ var parentLoc = TrUIUtils._getElementLocation(element.offsetParent);
+ var posType = TrUIUtils._getStyle(element.offsetParent, 'position');
+ var parentOffset;
+ if (posType == 'relative' || posType == 'absolute')
{
- element.style.left = element.origX + 'px';
+ parentOffset = { left: parentLoc.x, top: parentLoc.y };
}
- if (element.origY)
+ else
{
- element.style.top = element.origY + 'px';
+ parentOffset = { left: 0, top: 0 };
+ }
+
+ // calculate the client location of the popup (not the page location)
+ var clientLoc = {
+ x: b.x - (document.body.scrollLeft || document.documentElement.scrollLeft),
+ y: b.y - (document.body.scrollTop || document.documentElement.scrollTop)
+ };
+
+ // is the popup off the page to the left?
+ if (b.x < 0)
+ {
+ element.style.left = (0 - parentOffset.left) + 'px';
+ }
+ // is it off the page to the right?
+ else if (clientLoc.x + b.w > windowSize.w)
+ {
+ element.style.left = (element.offsetLeft - (clientLoc.x + b.w - windowSize.w)) + 'px';
}
- var w = element.offsetWidth;
- var h = element.offsetHeight;
- var pos = this._getElementPosition(element);
- var x = pos.x;
- var y = pos.y;
- var ww = document.body.offsetWidth;
- var wh = document.body.offsetHeight;
-
- var parentPos = this._getElementPosition(element.parentNode);
- if (x + w > ww)
+ // is the popup off the top of the page?
+ if (b.y < 0)
{
- var diff = (x + w) - ww;
- var ox = element.offsetLeft;
- if (!element.origX)
- {
- element.origX = ox;
- }
- element.style.left = (ox - diff - parentPos.x) + 'px';
+ element.style.top = (0 - parentOffset.top) + 'px';
}
- if (y + h > wh)
+ // is it past the bottom the page?
+ else if (clientLoc.y + b.h > windowSize.h)
{
- var diff = (y + h) - wh;
- var oy = element.offsetTop;
- if (!element.origY)
- {
- element.origY = oy;
- }
- element.style.top = (oy - diff - parentPos.y) + 'px';
+ element.style.top = (element.offsetTop - (clientLoc.y + b.h - windowSize.h)) + 'px';
}
element.style.visibility = vis;
}
/**
- * Get the Page X and Y of an event
+ * Get the page X and Y and the client X and Y of an event
*/
TrPanelPopup.prototype._getEventPosition = function(event)
{
- return {
- x: (event.pageX || (event.clientX +
- (document.documentElement.scrollLeft || document.body.scrollLeft))),
- y: (event.pageY || (event.clientY +
- (document.documentElement.scrollTop || document.body.scrollTop)))
+ // all browsers
+ var pos = {
+ clientX: event.clientX,
+ clientY: event.clientY,
+ pageX: event.pageX,
+ pageY: event.pageY
};
-}
-
-/**
- * Check if the browser is Internet Explorer
- */
-TrPanelPopup.prototype._isIE = function()
-{
- return navigator.appVersion.indexOf("MSIE") != -1;
-}
-/**
- * Get the position of an element relative to the page, not
- * its parent
- */
-TrPanelPopup.prototype._getElementPosition = function(element)
-{
- var curleft = 0;
- var curtop = 0;
- var obj = element;
- while (obj)
- {
- curleft += obj.offsetLeft;
- curtop += obj.offsetTop;
- obj = obj.offsetParent;
- }
- return { x: curleft, y: curtop };
-}
-
-/**
- * Get a css property as its JavaScript variable name
- */
-TrPanelPopup.prototype._cssToJs = function(prop)
-{
- var jsProp = '';
- var upperNext = false;
- for (var c = 0; c < prop.length; c++)
+ if (pos.pageX == null)
{
- if (prop.charAt(c) == '-')
- {
- upperNext = true;
- continue;
- }
-
- if (upperNext)
- {
- jsProp += prop.charAt(c).toUpperCase();
- }
- else
- {
- jsProp += prop.charAt(c);
- }
-
- upperNext = false;
+ pos.pageX = event.clientX
+ + (document.body.scrollLeft || document.documentElement.scrollLeft);
+ pos.pageY = event.clientY
+ + (document.body.scrollTop || document.documentElement.scrollTop);
}
-
- return jsProp;
-}
-/**
- * Get a calculated CSS style value
- */
-TrPanelPopup.prototype._getStyle = function(element, prop)
-{
- if (element.currentStyle)
- {
- // remove dashes and uppercase next letter
- var jsProp = this._cssToJs(prop);
- return element.currentStyle[jsProp];
- }
- else if (window.getComputedStyle)
- {
- return document.defaultView.getComputedStyle(element, '')
- .getPropertyValue(prop);
- }
- return '';
+ return pos;
}
/**
* Function to center an element on the screen
*/
-TrPanelPopup.prototype._centerOnScreen = function(element)
+TrPanelPopup.prototype._centerOnScreen = function(element, windowSize)
{
element.style.position = 'absolute';
- var vis = this._getStyle(element, 'visibility');
- element.style.visibility = 'hidden'; // stop flickering
- var parentPos = this._getElementPosition(element.parentNode);
-
- var loc;
- if (this._isIE())
- {
- loc = document.body.scrollLeft +
- ((document.body.clientWidth - element.clientWidth) / 2) -
- parentPos.x;
- element.style.left = ((loc>0)?loc:0) + "px";
- loc = document.body.scrollTop +
- ((document.body.clientHeight - element.clientHeight) / 2) -
- parentPos.y;
- element.style.top = ((loc>0)?loc:0) + "px";
+ var vis = TrUIUtils._getStyle(element, 'visibility');
+ element.style.visibility = 'hidden'; // prevent flickering
+ var parentLoc = TrUIUtils._getElementLocation(element.offsetParent);
+ var pageLoc = TrUIUtils._getElementBounds(element);
+ var posType = TrUIUtils._getStyle(element.offsetParent, 'position');
+ var parentOffset;
+ if (posType == 'relative' || posType == 'absolute')
+ {
+ parentOffset = { left: parentLoc.x, top: parentLoc.y };
}
else
{
- loc = window.pageXOffset + ((window.innerWidth - element.clientWidth) / 2) -
- parentPos.x;
- element.style.left = ((loc>0)?loc:0) + "px"
- loc = window.pageYOffset + ((window.innerHeight - element.clientHeight)/2) -
- parentPos.y;
- element.style.top= ((loc>0)?loc:0) + "px"
+ parentOffset = { left: 0, top: 0 };
}
+
+ // calculate the client location of the popup (not the page location)
+ var clientLoc = {
+ x: pageLoc.x - (document.body.scrollLeft || document.documentElement.scrollLeft),
+ y: pageLoc.y - (document.body.scrollTop || document.documentElement.scrollTop)
+ };
+
+ element.style.left = Math.max(0,
+ (windowSize.w / 2 - element.clientWidth / 2)
+ - parentOffset.left
+ + (pageLoc.x - clientLoc.x)) + 'px';
+
+ element.style.top = Math.max(0,
+ (windowSize.h / 2 - element.clientHeight / 2)
+ - parentOffset.top
+ + (pageLoc.y - clientLoc.y)) + 'px';
+
element.style.visibility = vis;
}
@@ -588,45 +528,77 @@
/**
* Position the popup ensuring it doesn't go off-page, and if centered, then
* center in the middle of the current window.
- **/
+ */
TrPanelPopup.prototype._calcPosition = function(event)
{
var popup = this.getContent();
event = window.event || event;
- var parent = this._getOffsetParent();
- if (!this._centered)
- {
- var pos = this._getEventPosition(event);
- var parentPos = this._getElementPosition(parent);
- popup.style.left = (pos.x - parentPos.x +
- this.getRelativeOffsetX()) + 'px';
- popup.style.top = (pos.y - parentPos.y +
- this.getRelativeOffsetY()) + 'px';
- }
-
+ var parent = this._getOffsetParent();
+ // get the window size before the popup may alter it
+ var wSize = TrUIUtils._getWindowClientSize();
+
if (!popup.origParent)
{
popup.origParent = popup.parentNode;
- }
-
+ }
parent.appendChild(popup);
+
+ if (!this._centered)
+ {
+ var eventP = this._getEventPosition(event);
+ var parLoc = TrUIUtils._getElementLocation(popup.offsetParent);
+ var posType = TrUIUtils._getStyle(popup.offsetParent, 'position');
+ var parentOffset;
+ if (posType == 'relative' || posType == 'absolute')
+ {
+ parentOffset = { left: parLoc.x, top: parLoc.y };
+ }
+ else
+ {
+ parentOffset = { left: 0, top: 0 };
+ }
+
+ // set the location to the location of the event on the page
+ // adjusted to the parent location on the page
+ // adjusted by the relative offset of the popup
+ popup.style.left = (eventP.pageX - parentOffset.left + this.getRelativeOffsetX() -
+ this._getSideOffset(popup, "Left")) + 'px';
+
+ popup.style.top = (eventP.pageY - parentOffset.top + this.getRelativeOffsetY() -
+ this._getSideOffset(popup, "Top")) + 'px';
+ }
if (this._centered)
{
- this._centerOnScreen(popup);
+ this._centerOnScreen(popup, wSize);
}
else
{
- this._fitOnScreen(popup);
+ this._fitOnScreen(popup, wSize);
}
if (!this.isModal())
{
- var pos = this._getEventPosition(event);
- TrPanelPopup._resizeIeIframe(pos.x, pos.y,
- popup.offsetWidth, popup.offsetHeight);
+ var b = TrUIUtils._getElementBounds(popup);
+ TrPanelPopup._resizeIeIframe(b.x, b.y, b.w, b.h);
+ }
+}
+
+TrPanelPopup.prototype._getSideOffset = function(elem, side)
+{
+ var arr = [ "border", "padding", "margin" ];
+ var val = 0;
+ for (var i = 0; i < arr.length; ++i)
+ {
+ var o = TrUIUtils._getStyle(elem, arr[i] + side);
+ o = parseInt(o);
+ if (!isNaN(o))
+ {
+ val += o;
+ }
}
+ return val;
}
/**
@@ -637,7 +609,7 @@
return false;
}
-/*
+/**
* Sizes/resizes the modal mask if the window size changes
*/
TrPanelPopup._setMaskSize = function()
@@ -646,34 +618,17 @@
if (!TrPanelPopup._mask)
return;
- if (window.innerHeight!=window.undefined)
- fullHeight = window.innerHeight;
- else if (document.compatMode=='CSS1Compat')
- fullHeight = document.documentElement.clientHeight;
- else if (document.body)
- fullHeight = document.body.clientHeight;
-
- if (window.innerWidth!=window.undefined)
- fullWidth = window.innerWidth;
- else if (document.compatMode=='CSS1Compat')
- fullWidth = document.documentElement.clientWidth;
- else if (document.body)
- fullWidth = document.body.clientWidth;
+ var wSize = TrUIUtils._getWindowClientSize();
+ var scrollWidth = document.documentElement.scrollWidth || document.body.scrollWidth;
+ var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
- // Determine what's bigger, scrollHeight or fullHeight / width
- if (fullHeight > document.body.scrollHeight)
- {
- popHeight = fullHeight;
- }
- else
- {
- popHeight = document.body.scrollHeight
- }
+ var w = Math.max(wSize.w, scrollWidth);
+ var h = Math.max(wSize.h, scrollHeight);
- TrPanelPopup._mask.style.height = popHeight + "px";
- TrPanelPopup._mask.style.width = document.body.scrollWidth + "px";
+ TrPanelPopup._mask.style.width = w + "px";
+ TrPanelPopup._mask.style.height = h + "px";
- TrPanelPopup._resizeIeIframe(0, 0, document.body.scrollWidth, popHeight);
+ TrPanelPopup._resizeIeIframe(0, 0, w, h);
}
/**
@@ -719,8 +674,11 @@
TrPanelPopup._maskIframe.name = "TrPanelPopup._ieOnlyZIndexIframe";
TrPanelPopup._maskIframe.style.cssText = "display: none; left: 0px; position: absolute; top: 0px; z-index: 4999;";
TrPanelPopup._maskIframe.style.filter = "progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)";
- // FIXME: should this be set to avoid SSL warnings?
- //TrPanelPopup._maskIframe.src = "javascript:false;"
+ // avoid SSL warnings in IE
+ if (_agent.isIE)
+ {
+ TrPanelPopup._maskIframe.src = "javascript:false;";
+ }
document.body.appendChild(TrPanelPopup._maskIframe);
}
}
@@ -746,8 +704,11 @@
TrHoverPopup.prototype.showPopup = function(event)
{
// Setup event listener for mouse leaving trigger or content elements
- _addEvent(this.getTrigger(), "mouseout", this._hoverCallbackFunction);
- _addEvent(this.getContent(), "mouseout", this._hoverCallbackFunction);
+ //_addEvent(this.getTrigger(), "mouseout", this._hoverCallbackFunction);
+ //_addEvent(this.getContent(), "mouseout", this._hoverCallbackFunction);
+
+ // mouse out on the elements didn't always get called, so use mouse move
+ _addEvent(document.body, "mousemove", this._hoverCallbackFunction);
this.show(event);
}
@@ -769,8 +730,10 @@
}
// Cancel event listeners
- _removeEvent(this.getTrigger(), "mouseout", this._hoverCallbackFunction);
- _removeEvent(this.getContent(), "mouseout", this._hoverCallbackFunction);
+ // mouse out on the elements didn't always get called, so use mouse move
+ //_removeEvent(this.getTrigger(), "mouseout", this._hoverCallbackFunction);
+ //_removeEvent(this.getContent(), "mouseout", this._hoverCallbackFunction);
+ _removeEvent(document.body, "mousemove", this._hoverCallbackFunction);
this.hide(event);