/* $Id$ */
/** @file
* Common JavaScript functions
*/
/*
*
* Copyright (C) 2012-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
/**
* Checks if the given value is a decimal integer value.
*
* @returns true if it is, false if it's isn't.
* @param sValue The value to inspect.
*/
{
if (typeof sValue != 'undefined')
{
var intRegex = /^\d+$/;
{
return true;
}
}
return false;
}
/**
* Removes the element with the specified ID.
*/
{
if (oElement)
{
}
}
/**
* Sets the value of the element with id @a sInputId to the keys of aoItems
* (comma separated).
*/
{
var sKey;
{
{
}
}
}
/**
* Get the Window.devicePixelRatio in a safe way.
*
* @returns Floating point ratio. 1.0 means it's a 1:1 ratio.
*/
function getDevicePixelRatio()
{
var fpRatio = 1.0;
if (window.devicePixelRatio)
{
fpRatio = 1.0;
}
return fpRatio;
}
/**
* Tries to figure out the DPI of the device in the X direction.
*
* @returns DPI on success, null on failure.
*/
function getDeviceXDotsPerInch()
{
{
return window.deviceXDPI;
}
else if (window.devicePixelRatio && window.devicePixelRatio >= 0.5 && window.devicePixelRatio <= 10.0)
{
}
else
{
cDotsPerInch = null;
}
return cDotsPerInch;
}
/**
* Gets the width of the given element (downscaled).
*
* Useful when using the element to figure the size of a image
* or similar.
*
* @returns Number of pixels. null if oElement is bad.
* @param oElement The element (not ID).
*/
{
return oElement.offsetWidth;
return null;
}
/** By element ID version of getElementWidth. */
{
}
/**
* Gets the real unscaled width of the given element.
*
* Useful when using the element to figure the size of a image
* or similar.
*
* @returns Number of screen pixels. null if oElement is bad.
* @param oElement The element (not ID).
*/
{
return null;
}
/** By element ID version of getUnscaledElementWidth. */
{
}
/**
* Sets the value of an input field element (give by ID).
*
* @param sFieldId The field ID (required for updating).
* @param sValue The field value.
*/
{
if (oInputElement)
{
return true;
}
return false;
}
/**
* Adds a hidden input field to a form.
*
* @returns The new input field element.
* @param oFormElement The form to append it to.
* @param sName The field name.
* @param sValue The field value.
* @param sFieldId The field ID (optional).
*/
{
if (sFieldId)
return oNew;
}
/** By element ID version of addHiddenInputFieldToForm. */
{
}
/**
*
* @returns The new input field element.
* @param sFormId The ID of the form to amend.
* @param sName The field name.
* @param sValue The field value.
* @param sFieldId The field ID (required for updating).
*/
{
var oInputElement = null;
if (sFieldId)
{
}
if (oInputElement)
{
}
else
{
}
return oInputElement;
}
/**
* Adds a width and a dpi input to the given form element if possible to
* determine the values.
*
* This is normally employed in an onlick hook, but then you must specify IDs or
* the browser may end up adding it several times.
*
* @param sFormId The ID of the form to amend.
* @param sWidthSrcId The ID of the element to calculate the width
* value from.
* @param sWidthName The name of the width value.
* @param sDpiName The name of the dpi value.
*/
{
var cDotsPerInch = getDeviceXDotsPerInch();
if (cx)
{
}
if (cDotsPerInch)
{
addUpdateHiddenInputFieldToFormById(sFormId, sDpiName, cDotsPerInch, sFormId + '-' + sDpiName + '-id');
}
}
/** @name Custom Tooltips
* @{
*/
/** Where we keep tooltip elements when not displayed. */
var g_dTooltips = {};
var g_oCurrentTooltip = null;
var g_idTooltipShowTimer = null;
var g_idTooltipHideTimer = null;
/**
* Cancel showing/replacing/repositing a tooltip.
*/
function tooltipResetShowTimer()
{
if (g_idTooltipShowTimer)
{
g_idTooltipShowTimer = null;
}
}
/**
* Cancel hiding of the current tooltip.
*/
function tooltipResetHideTimer()
{
if (g_idTooltipHideTimer)
{
g_idTooltipHideTimer = null;
}
}
/**
* Really hide the tooltip.
*/
function tooltipReallyHide()
{
if (g_oCurrentTooltip)
{
//console.log('tooltipReallyHide: ' + g_oCurrentTooltip);
g_oCurrentTooltip = null;
}
}
/**
* Schedule the tooltip for hiding.
*/
function tooltipHide()
{
function tooltipDelayedHide()
{
}
/*
* Cancel any pending show and schedule hiding if necessary.
*/
if (g_oCurrentTooltip && !g_idTooltipHideTimer)
{
}
return true;
}
/**
* Function that is repositions the tooltip when it's shown.
*
* Used directly, via onload, and hackish timers to catch all browsers and
* whatnot.
*
* Will set several tooltip member variables related to position and space.
*/
function tooltipRepositionOnLoad()
{
if (g_oCurrentTooltip)
{
var xPos;
var yPos;
/*
* Decide where to put the thing.
*/
{
}
{
}
else
{
}
{
}
{
}
else
{
}
}
return true;
}
/**
* Really show the tooltip.
*
* @param oTooltip The tooltip object.
* @param oRelTo What to put the tooltip adjecent to.
*/
{
var oRect;
if (g_oCurrentTooltip == oTooltip)
{
//console.log('moving tooltip');
}
else if (g_oCurrentTooltip)
{
//console.log('removing current tooltip and showing new');
}
else
{
//console.log('showing tooltip');
}
/*
* This function does the repositioning at some point.
*/
{
oTooltip.oElm.onload = function(){ tooltipRepositionOnLoad(); setTimeout(tooltipRepositionOnLoad, 0); };
}
}
/**
* Tooltip onmouseenter handler .
*/
function tooltipElementOnMouseEnter()
{
//console.log('tooltipElementOnMouseEnter: arguments.length='+arguments.length+' [0]='+arguments[0]);
//console.log('ENT: currentTarget='+arguments[0].currentTarget);
return true;
}
/**
* Tooltip onmouseout handler.
*
* @remarks We only use this and onmouseenter for one tooltip element (iframe
* for svn, because chrome is sending onmouseout events after
* onmouseneter for the next element, which would confuse this simple
* code.
*/
function tooltipElementOnMouseOut()
{
//console.log('tooltipElementOnMouseOut: arguments.length='+arguments.length+' [0]='+arguments[0]);
//console.log('OUT: currentTarget='+arguments[0].currentTarget);
tooltipHide();
return true;
}
/**
* iframe.onload hook that repositions and resizes the tooltip.
*
* This is a little hacky and we're calling it one or three times too many to
* work around various browser differences too.
*/
function svnHistoryTooltipOnLoad()
{
//console.log('svnHistoryTooltipOnLoad');
/*
* Resize the tooltip to better fit the content.
*/
tooltipRepositionOnLoad(); /* Sets cxMax and cyMax. */
{
var cy;
{
//console.log('svnHistoryTooltipOnLoad: overflowX -> hidden');
}
else
{
}
{
}
{
//console.log('svnHistoryTooltipOnLoad: overflowY -> hidden');
}
else
{
}
//console.log('cyNeeded='+cyNeeded+' cyMax='+g_oCurrentTooltip.cyMax+' cySpace='+cySpace+' cy='+cy);
//console.log('oSubElement.offsetTop='+oSubElement.offsetTop);
//console.log('svnHistoryTooltipOnLoad: cx='+cx+'cxMax='+g_oCurrentTooltip.cxMax+' cxNeeded='+cxNeeded+' cy='+cy+' cyMax='+g_oCurrentTooltip.cyMax);
}
return true;
}
/**
* Calculates the last revision to get when showing a tooltip for @a iRevision.
*
* A tooltip covers several change log entries, both to limit the number of
* tooltips to load and to give context. The exact number is defined by
* g_cTooltipSvnRevisions.
*
* @returns Last revision in a tooltip.
* @param iRevision The revision number.
*/
{
}
/**
* Calculates a unique ID for the tooltip element.
*
* This is also used as dictionary index.
*
* @returns tooltip ID value (string).
* @param sRepository The repository name.
* @param iRevision The revision number.
*/
{
}
/**
* The onmouseenter event handler for creating the tooltip.
*
* @param oEvt The event.
* @param sRepository The repository name.
* @param iRevision The revision number.
*
* @remarks onmouseout must be set to call tooltipHide.
*/
{
//console.log('svnHistoryTooltipShow ' + sRepository);
function svnHistoryTooltipDelayedShow()
{
var oSubElement;
var sSrc;
//console.log('svnHistoryTooltipDelayedShow ' + sRepository + ' ' + oTooltip);
if (!oTooltip)
{
/*
* Create a new tooltip element.
*/
//console.log('creating ' + sKey);
oTooltip = {};
oSubElement.onload = function() {svnHistoryTooltipOnLoad(); setTimeout(svnHistoryTooltipOnLoad,0);};
}
else
{
}
+ '&cEntries=' + g_cTooltipSvnRevisions
+ '#r' + iRevision);
/* Resize and repositioning hacks. */
}
/*
* Delay the change.
*/
}
/** @} */
/** @name Debugging and Introspection
* @{
*/
/**
* Python-like dir() implementation.
*
* @returns Array of names associated with oObj.
* @param oObj The object under inspection. If not specified we'll
* look at the window object.
*/
{
var aRet = [];
var dTmp = {};
if (!oObj)
{
}
{
{
{
}
}
}
return aRet;
}
/**
* Python-like dir() implementation, shallow version.
*
* @returns Array of names associated with oObj.
* @param oObj The object under inspection. If not specified we'll
* look at the window object.
*/
{
var aRet = [];
var dTmp = {};
if (oObj)
{
for (var i in oObj)
{
}
}
return aRet;
}
{
{
{
}
else
{
{
}
}
}
return sType;
}
/**
* Dumps the given object to the console.
*
* @param oObj The object under inspection.
* @param sPrefix What to prefix the log output with.
*/
{
var aMembers;
var sType;
/*
* Defaults
*/
if (!oObj)
{
}
if (!sPrefix)
{
if (sName)
{
}
else
{
sPrefix = 'dbgDumpObj:';
}
}
if (!sName)
{
sName = '';
}
/*
* The object itself.
*/
/*
* The members.
*/
{
}
return true;
}
{
var sRet;
switch (sType)
{
case 'function':
{
break;
}
case 'object':
{
if (oObj !== null)
{
sRet += '\n';
}
else
{
sRet += ' null\n';
}
break;
}
case 'string':
{
{
}
else
{
sRet += '\n';
}
break;
}
case 'Oops!':
break;
default:
break;
}
return sRet;
}
{
while (i > 0)
{
i--;
{
return true;
}
}
return false;
}
{
var sRet = '';
var i;
{
//var sName = i;
var oMember;
var sType;
var oEx;
try
{
}
catch (oEx)
{
oMember = null;
sType = 'Oops!';
}
//sRet += '[' + i + '/' + aMembers.length + ']';
if ( sType == 'object'
&& oObj !== null)
{
{
}
else if ( sName == 'previousSibling'
|| sName == 'previousElement'
|| sName == 'lastChild'
|| sName == 'firstElementChild'
|| sName == 'lastElementChild'
|| sName == 'nextElementSibling'
|| sName == 'prevElementSibling'
|| sName == 'parentElement'
|| sName == 'ownerDocument')
{
}
{
sRet += ' <too deep>!\n';
}
else
{
{
}
else
{
sRet += dbgDumpObjTreeWorker(oMember, sPrefix.substring(0, sPrefix.length - 2) + ' | ', aParentObjs, cMaxDepth);
}
aParentObjs.pop();
}
}
}
return sRet;
}
/**
* Dumps the given object and all it's subobjects to the console.
*
* @returns String dump of the object.
* @param oObj The object under inspection.
* @param sName The object name (optional).
* @param sPrefix What to prefix the log output with (optional).
* @param cMaxDepth The max depth, optional.
*/
{
var sType;
var sRet;
var oEx;
/*
* Defaults
*/
if (!sPrefix)
{
sPrefix = '';
}
if (!sName)
{
sName = '??';
}
if (!cMaxDepth)
{
cMaxDepth = 2;
}
/*
* The object itself.
*/
try
{
}
catch (oEx)
{
sType = 'Oops!';
}
{
var aParentObjs = Array();
}
return sRet;
}
{
var i;
{
}
return true;
}
{
}
/** @} */