//**************************************************************************** // Copyright (c) 2005, Coveo Solutions Inc. //**************************************************************************** //**************************************************************************** // Shortcut for document.getElementById(...). //**************************************************************************** function G(p_Id) { return document.getElementById(p_Id); } //**************************************************************************** // Returns whether the current browser is Internet Explorer. //**************************************************************************** function CNL_IsIE() { return navigator.userAgent.indexOf('MSIE') != -1; } //**************************************************************************** // Returns whether the browser is in standard mode. //**************************************************************************** function CNL_IsStandard() { // I tested those with IE, FireFox and Opera. return document.compatMode != 'BackCompat' && document.compatMode != 'QuirksMode'; } //**************************************************************************** // Adds an event handler to an object. // p_Target - The object tag fires the event. // p_Event - The name of the event. // p_Handler - The event handler to register. //**************************************************************************** function CNL_WireEvent(p_Target, p_Event, p_Handler) { if (CNL_IsIE()) { p_Target.attachEvent(p_Event, p_Handler); } else { // addEventLister takes an event type that is usually the name of the // event with the 'on' at the start removed. if (p_Event.substring(0, 2) != 'on') { throw "Unknown event type: " + p_Event; } var name = p_Event.substring(2, p_Event.length); p_Target.addEventListener(name, p_Handler, false); } } //**************************************************************************** // Stops the propagation of an event. // p_Event - The event whose propagation to stop. //**************************************************************************** function CNL_StopPropagation(p_Event) { if (CNL_IsIE()) { p_Event.cancelBubble = true; } else { p_Event.stopPropagation(); } } //**************************************************************************** // Cancels an event (prevents it from bubbling up, and disable the default action). // p_Event - The event to cancel. //**************************************************************************** function CNL_CancelEvent(p_Event) { if (CNL_IsIE()) { p_Event.cancelBubble = true; p_Event.returnValue = false; } else { p_Event.stopPropagation(); p_Event.preventDefault(); } } //**************************************************************************** // Returns a new XMLHttpRequest object. //**************************************************************************** function CNL_CreateXmlHttpRequest() { var req; if (CNL_IsIE()) { req = new ActiveXObject("Microsoft.XMLHTTP"); } else { req = new XMLHttpRequest(); } return req; } //**************************************************************************** // Performs a SelectNodes in a cross-browser compatible way. // p_Node - The node on which to perform the operation. // p_XPath - The xpath expression to use. // Returns the matching nodes. //**************************************************************************** function CNL_SelectNodes(p_Node, p_XPath) { var nodes; if (CNL_IsIE()) { nodes = p_Node.selectNodes(p_XPath); } else { var resolver = p_Node.createNSResolver(p_Node); var results = p_Node.evaluate(p_XPath, p_Node, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); nodes = new Array(); for (i = 0; i < results.snapshotLength; ++i) { nodes.push(results.snapshotItem(i)); } } return nodes; } //**************************************************************************** // Performs a SelectSingleNode in a cross-browser compatible way. // p_Node - The node on which to perform the operation. // p_XPath - The xpath expression to use. // Returns the first matching node, if any, and null otherwise. //**************************************************************************** function CNL_SelectSingleNode(p_Node, p_XPath) { var node; if (CNL_IsIE()) { node = p_Node.selectSingleNode(p_XPath); } else { var nodes = CNL_SelectNodes(p_Node, p_XPath); node = nodes.length != 0 ? nodes[0] : null; } return node; } //**************************************************************************** // Returns the text content of an xml node. //**************************************************************************** function CNL_GetTextContent(p_Node) { return CNL_IsIE() ? p_Node.text : p_Node.textContent; } //**************************************************************************** // Converts an RGB value to a color string. // p_Red - The Red component. // p_Green - The Green component. // p_Blue - The Blue component. // Returns The color as a string (in the #xxxxxx format). //**************************************************************************** function CNL_RGBToString(p_Red, p_Green, p_Blue) { var r = p_Red.toString(16); if (r.length == 1) { r = '0' + r; } var g = p_Green.toString(16); if (g.length == 1) { g = '0' + g; } var b = p_Blue.toString(16); if (b.length == 1) { b = '0' + b; } return ('#' + r + g + b).toUpperCase(); } //**************************************************************************** // Sets the absolute position of an object, relative to the document. // p_Object - The object whose position should be set. // p_X - The X offset from the left of the document. // p_Y - The Y offset from the top of the document. //**************************************************************************** function CNL_SetPosition(p_Object, p_X, p_Y) { p_Object.style.left = p_X + 'px'; p_Object.style.top = p_Y + 'px'; } //**************************************************************************** // Retrieves the absolute position of an HTML object (in pixels) from the top of the document. // p_Object - The object whose position to retrieve. // Returns an object that contains the information. //**************************************************************************** function CNL_GetPosition(p_Object) { var pos = new Object(); pos.m_Left = 0; pos.m_Top = 0; var obj = p_Object; while (obj != null) { pos.m_Left += obj.offsetLeft - obj.scrollLeft; pos.m_Top += obj.offsetTop - obj.scrollTop; obj = obj.offsetParent; } return pos; } //**************************************************************************** // Retrieves the size of an HTML object (in pixels). // p_Object - The object whose size to retrieve. // Returns An object that contains the information. //**************************************************************************** function CNL_GetSize(p_Object) { var size = new Object(); size.m_Width = p_Object.offsetWidth; size.m_Height = p_Object.offsetHeight; return size; } //**************************************************************************** // Sets the size of an object. // p_Object - The object whose size should be set. // p_Width - The width to set. // p_Height - The height to set. //**************************************************************************** function CNL_SetSize(p_Object, p_Width, p_Height) { p_Object.style.width = p_Width + 'px'; p_Object.style.height = p_Height + 'px'; } //**************************************************************************** // Retrieves the bounding rectangle of an HTML object (in pixels). // p_Object - The object whose bounding rectangle to retrieve. // Returns An object that contains the information. //**************************************************************************** function CNL_GetBoundingRectangle(p_Object) { var pos = CNL_GetPosition(p_Object); var size = CNL_GetSize(p_Object); var rect = new Object(); rect.m_Left = pos.m_Left; rect.m_Top = pos.m_Top; rect.m_Right = pos.m_Left + size.m_Width; rect.m_Bottom = pos.m_Top + size.m_Height; return rect; } //**************************************************************************** // Retrieves the bounding of the region that is visible in the window (in pixels). // Returns An object that contains the information. //**************************************************************************** function CNL_GetVisibleRectangle() { var rect = new Object(); if (CNL_IsStandard()) { rect.m_Left = document.documentElement.scrollLeft; rect.m_Top = document.documentElement.scrollTop; rect.m_Right = rect.m_Left + document.documentElement.clientWidth; rect.m_Bottom = rect.m_Top + document.documentElement.clientHeight; } else { rect.m_Left = document.body.scrollLeft; rect.m_Top = document.body.scrollTop; rect.m_Right = rect.m_Left + document.body.clientWidth; rect.m_Bottom = rect.m_Top + document.body.clientHeight; } return rect; } //**************************************************************************** // Checks if a point is within a rectangle. // p_X - The X coordinate. // p_Y - The Y coordinate. // p_Rect - The rectangle. // Returns Whether the point is within the rectangle. //**************************************************************************** function CNL_IsWithin(p_X, p_Y, p_Rect) { return p_X >= p_Rect.m_Left && p_X < p_Rect.m_Right && p_Y >= p_Rect.m_Top && p_Y < p_Rect.m_Bottom; } //**************************************************************************** // Checks if a rectangle is within another rectangle. // p_Inside - The rectangle that should be inside. // p_Outside - The rectangle that should contain p_Inside. // Returns Whether the first rectangle is within the second one. //**************************************************************************** function CNL_IsRectangleWithin(p_Inside, p_Outside) { return CNL_IsWithin(p_Inside.m_Left, p_Inside.m_Top, p_Outside) && CNL_IsWithin(p_Inside.m_Right, p_Inside.m_Top, p_Outside) && CNL_IsWithin(p_Inside.m_Left, p_Inside.m_Bottom, p_Outside) && CNL_IsWithin(p_Inside.m_Right, p_Inside.m_Bottom, p_Outside); } //**************************************************************************** // Checks if two rectangles overlap. // p_Rect1 - The first rectangle. // p_Rect2 - The second rectangle. // Returns Whether the two rectangles overlap. //**************************************************************************** function CNL_IsOverlap(p_Rect1, p_Rect2) { // Look for an horizontal overlap var horiz = (p_Rect1.m_Left >= p_Rect2.m_Left && p_Rect1.m_Left < p_Rect2.m_Right) || (p_Rect1.m_Right > p_Rect2.m_Left && p_Rect1.m_Right < p_Rect2.m_Right) || (p_Rect2.m_Left >= p_Rect1.m_Left && p_Rect2.m_Left < p_Rect1.m_Right) || (p_Rect2.m_Right > p_Rect1.m_Left && p_Rect2.m_Right < p_Rect1.m_Right); // Look for a vertical overlap var vert = (p_Rect1.m_Top >= p_Rect2.m_Top && p_Rect1.m_Top < p_Rect2.m_Bottom) || (p_Rect1.m_Bottom > p_Rect2.m_Top && p_Rect1.m_Bottom < p_Rect2.m_Bottom) || (p_Rect2.m_Top >= p_Rect1.m_Top && p_Rect2.m_Top < p_Rect1.m_Bottom) || (p_Rect2.m_Bottom > p_Rect1.m_Top && p_Rect2.m_Bottom < p_Rect1.m_Bottom); return horiz && vert; } //**************************************************************************** // Positions an object relative to another. // p_Object - The object to position. // p_Reference - The object to position relatively to. // p_Position - Where to place the object from the other. //**************************************************************************** function CNL_PositionObject(p_Object, p_Reference, p_Position) { // Determine the default major and minor positions var position1; var position2; if (p_Position == 'LeftBelow') { position1 = 'Left'; position2 = 'Below'; } else if (p_Position == 'LeftAbove') { position1 = 'Left'; position2 = 'Above'; } else if (p_Position == 'AboveLeft') { position1 = 'Above'; position2 = 'Left'; } else if (p_Position == 'AboveRight') { position1 = 'Above'; position2 = 'Right'; } else if (p_Position == 'RightBelow') { position1 = 'Right'; position2 = 'Below'; } else if (p_Position == 'RightAbove') { position1 = 'Right'; position2 = 'Above'; } else if (p_Position == 'BelowLeft') { position1 = 'Below'; position2 = 'Left'; } else if (p_Position == 'BelowRight') { position1 = 'Below'; position2 = 'Right'; } else { throw 'Invalid value for p_Position'; } var left; var top; var done = false; var attempts = 0; var osize = CNL_GetSize(p_Object); var rrect = CNL_GetBoundingRectangle(p_Reference); var vrect = CNL_GetVisibleRectangle(); // Try 3 times to position the object. Globally speaking, when first iteration // fails, the invert position on all bad levels will be tried. If this position // is bad too, we want to allow another iteration to revert positions to the // initial ones (which are better when everything is bad). while (!done && attempts < 3) { // Position the object using the two indicators if (position1 == 'Left') { left = rrect.m_Left - osize.m_Width; } else if (position1 == 'Right') { left = rrect.m_Right - 1; } else if (position1 == 'Above') { top = rrect.m_Top - osize.m_Height; } else if (position1 == 'Below') { top = rrect.m_Bottom - 1; } if (position2 == 'Left') { left = rrect.m_Left; } else if (position2 == 'Right') { left = rrect.m_Right - osize.m_Width; } else if (position2 == 'Above') { top = rrect.m_Bottom - osize.m_Height; } else if (position2 == 'Below') { top = rrect.m_Top; } // Invert major and/or minor positions when needed done = true; var right = left + osize.m_Width; var bottom = top + osize.m_Height; if (left < vrect.m_Left || right >= vrect.m_Right) { if (position1 == 'Left') { position1 = 'Right'; } else if (position1 == 'Right') { position1 = 'Left' } else if (position2 == 'Left') { position2 = 'Right' } else if (position2 == 'Right') { position2 = 'Left' } done = false; } if (top < vrect.m_Top || bottom >= vrect.m_Bottom) { if (position1 == 'Above') { position1 = 'Below'; } else if (position1 == 'Below') { position1 = 'Above' } else if (position2 == 'Above') { position2 = 'Below' } else if (position2 == 'Below') { position2 = 'Above' } done = false; } ++attempts; } CNL_SetPosition(p_Object, left, top); } //**************************************************************************** // Fits the width of an element to the client width of it's parent. // p_Element - The element whose width to set. // Works only under IE! //**************************************************************************** function CNL_FitToParentWidth(p_Element) { var borderWidth = parseInt(p_Element.currentStyle.borderLeftWidth) + parseInt(p_Element.currentStyle.borderRightWidth); var paddingWidth = parseInt(p_Element.currentStyle.paddingLeft) + parseInt(p_Element.currentStyle.paddingRight); var available = p_Element.parentElement.scrollWidth - parseInt(p_Element.parentElement.currentStyle.paddingLeft) - parseInt(p_Element.parentElement.currentStyle.paddingRight); p_Element.style.pixelWidth = available - borderWidth - paddingWidth; } //**************************************************************************** // Resizes an iframe to it's content. // p_IFrame - The iframe to resize. //**************************************************************************** function CNL_ResizeIFrame(p_IFrame) { var width = p_IFrame.contentWindow.document.documentElement.scrollWidth; var height = p_IFrame.contentWindow.document.documentElement.scrollHeight; CNL_SetSize(p_IFrame, width, height); } //**************************************************************************** // Sets the opacity of an object. // p_Object - The object whose opacity should be set. // p_Opacity - The opacity to set (from 0 to 1). //**************************************************************************** function CNL_SetOpacity(p_Object, p_Opacity) { if (p_Opacity != 1) { if (CNL_IsIE()) { p_Object.style.filter = 'alpha(opacity=' + p_Opacity * 100 + ')'; } else { p_Object.style.opacity = p_Opacity; } } else { if (CNL_IsIE()) { p_Object.style.filter = ''; } else { p_Object.style.opacity = ''; } } } //**************************************************************************** // Retrieves the position of a mouse click relative to an object. // p_Event - The event object. // p_Reference - The reference element to use to size the iframe. //**************************************************************************** function CNL_GetMouseClickPosition(p_Event, p_Reference) { var rpos = CNL_GetPosition(p_Reference); // First compute the click offset from the page var px, py; if (CNL_IsIE()) { // IE provides the offset from the clicked object. var tpos = CNL_GetPosition(p_Event.srcElement); px = tpos.m_Left + p_Event.offsetX; py = tpos.m_Top + p_Event.offsetY; } else { // FireFox provides the offset from the page px = p_Event.pageX; py = p_Event.pageY; } // Then compute the offset from the reference var rpos = CNL_GetPosition(p_Reference); var pos = new Object(); pos.m_Left = px - rpos.m_Left; pos.m_Top = py - rpos.m_Top; return pos; }