All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.adf.jsLibsDebug.Core.js Maven / Gradle / Ivy

The newest version!
/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */

// Flag used by partial page rendering and the back issue
// to indicate whether or not we need to restore the saved inline scripts.
var _pprBackRestoreInlineScripts = false;

// _pprBlocking is true if we're blocked waiting on a PPR event
var _pprBlocking = false;

// ER 4014884: block on every submit if requested.
var _blockOnEverySubmit = false;

// Controls whether or not Trinidad will allow the first click to go through in
// certain instances. When a PPR event occurs, we block all subsequent user
// input until it completes. However, there may be instances where the client
// wants to receive the very first click. For example, If the user has entered
// text in a textInput field with autoSubmit attached, then
// immediately clicked a submit button two events will be triggered - an
// onChange followed by an onClick. The onChange will trigger the autoSubmit
// which will immediately start the PPR blocking, so the onClick will get
// consumed by the blocking code and no submit will occur. Setting this value
// to true will allow the click to go through. This value can be controlled by
// the firstClickPassed attribute on the body element.
// TODO: Because PPR is now queued, is this still relevant?
var _pprFirstClickPass = false;

// We block using a special DIV element. This is its name
var _pprdivElementName = 'tr_pprBlockingDiv';

// stores the variables needed to load the libraries for IE
var _pprLibStore;


// The time at which we started the latest PPR block
var _pprBlockStartTime = 0;


// A holder for the pending timeout (Gecko only).
var _pprBlockingTimeout = null;

// Keeps track of the last element to initiate a PPR request
var _pprEventElement = null;

// We block input while a PPR request is in transit.
// _pprSavedCursor holds the cursor that the client had before the PPR event
// and _pprSavedCursorFlag keeps track of if we set _pprSavedCursor.
// var _pprSavedCursor = null;
var _pprSavedCursorFlag = false;

// Keeps track of whether the user has actually made a choice from the popup
var _pprChoiceChanged = false;


// Object containing information about the user agent
var _agent = new Object();

// Object for the last time we submitted
var _lastDateSubmitted;

// Object for the last time we reset a form
var _lastDateReset = 0;

// Variables tracking the last time we validated a field, and the last time the
// validation actually failed.
var _lastDateValidated  = 0;
var _lastValidationFailure  = 0;


// Keeps track of arguments that will be needed for a delayed event
var _delayedEventParams = new Object();

// this is the id of the component which gets the initial focus when the
// page loads.
var _initialFocusID = null;

// Certain Trinidad facilities can request that focus be set to a particular node,
// or the node AFTER a particular node following a PPR update. These three
// variables store the values needed to track down that node.
var _TrFocusRequestDoc = null;
var _TrFocusRequestID = null;
var _TrFocusRequestNext = false;

// Flag to indicate if inline validation is event based.
var _TrEventBasedValidation = false;

// _checkUnload is set on our body tag and is called when the window
// unloads. In our dialog windows, we call _checkUnload via an intermediary
// function _unloadADFDialog to work around Google's pop-up blocker
// feature which blocks onUnload event handlers from window's opened
// with window.open.
// We don't want to call _checkUnload twice in a row,
// once from dialog code and once from body's onUnload event handler,
// so we block the second call in _unloadADFDialog.
var _blockCheckUnloadFromDialog = false;


// variables needed if _submitForm was called before the form had
// completely rendered.
var _saveForm = null;
var _saveDoValidate = null;
var _saveParameters = null;
var _submitRejected = false;
var _inPartialSubmit = false;

// Flag used for timing issues with radioButtons
var _pendingRadioButton = false;

// List of mouse event names to capture
var _IE_MOUSE_CAPTURE_EVENTS = [
  "onclick",
  "ondblclick",
  "onmousedown",
  "onmousemove",
  "onmouseout",
  "onmouseover",
  "onmouseup"
  ];

// List of mouse event names to capture
var _GECKO_MOUSE_CAPTURE_EVENTS = [
  "click",
  "mousedown",
  "mouseup",
  "mouseover",
  "mousemove",
  "mouseout",
  "contextmenu"
  ];

/**
 * Return true if the agent is at least the specified agent type and version.
 */
function _atLeast(
  kind,
  version
  )
{
  return (!kind    || (kind    == _agent.kind))    &&
         (!version || (version <= _agent.version));
}


/**
 * Return true if the agent is at most the specified agent type and version.
 */
function _atMost(
  kind,
  version
  )
{
  return (kind == _agent.kind) && (version >= _agent.version);
}

function _supportsDOM()
{
  var retVal = false;

  if (_agent.isIE)
  {
    retVal = _agent.version >= 5.5;
  }
  else if (_agent.isNav)
  {
    retVal = false;
  }
  else if (_agent.isGecko || _agent.isSafari || _agent.isOpera)
  {
    retVal = true;
  }
  else if(_agent.isBlackBerry)
  {
    retVal = false;
    retVal = _agent.version >= 4.6;
  }

  return retVal;
}

/**
 * initialize information about the agent
 */
function _agentInit()
{
  // convert all characters to lowercase to simplify testing
  var agentString = navigator.userAgent.toLowerCase();

  // note that this only returns m.n (e.g. if the
  // version number is 2.3.4, this returns the float 2.3)
  var version = parseFloat(navigator.appVersion);

  // note that isBlackBerry refers to the BlackBerry browser
  // we do not currently specify the BlackBerry platform
  // because it is not necessary (if we decide to support
  // other browsers on the BlackBerry platform it may become necessary)
  var isBlackBerry      = false;
  var isGecko           = false;
  var isIE              = false;
  var isMac             = false;
  var isNav             = false;
  var isOpera           = false;
  var isPIE             = false;
  var isSafari          = false;
  var isSolaris         = false;
  var isWindows         = false;
  var isWindowsMobile6  = false;
  var isNokiaPhone      = false;
  var kind              = "unknown";

  // Group IE and IE based browsers such as IE Mobile on WM5 and WM6
  var isIEGroup         = false;

  // Indicate browser's PPR capability support
  var pprUnsupported    = false;

  // Indicate whether the browser and platform are capable of
  // sending PPR requests via JSF Ajax
  var useJsfAjax = true;

  // Flag to indicate that document object is sufficiently implemented to
  // provide good level of access to HTML, XHTML and XML document.
  // For example, Windows Mobile 5 and Blackberry does not implement
  // document.body, document.forms or document.documentElement and this
  // flag is set to false. Some features implemented in Core.js and
  // Page.js are not executed for the browsers when it is set to false.
  var supportsDomDocument = true;

  // Identifies browsers that do not support node.nodeType
  var supportsNodeType    = true;

  // Indicate browser's validation capability support
  var supportsValidation  = true;

  if (agentString.indexOf("msie") != -1)
  {
    // extract ie's version from the ie string
    var matches = agentString.match(/msie (.*);/);
    version = parseFloat(matches[1]);
    isIEGroup = true;

    // All IE based mobile browsers
    if (agentString.indexOf("windows ce") != -1)
    {
      supportsNodeType = false;
      supportsDomDocument = false;
      supportsValidation = false;

      // PPC200X and Windows Mobile 5
      if (agentString.indexOf("ppc") != -1 &&
          version >= 4.0)
      {
        // This user agent indicates the browser is WindowsMobile 5 or
        // earlier version of PIE
        isPIE = true;

        // Windows Mobile 5 DOM and XMLHttpRequest support are not
        // sufficient to support PPR in this framework effectively.
        pprUnsupported = true;
        kind = "pie";
      }
      else
      {
        // This user agent indicates the browser is WindowsMobile 6 PIE
        isWindowsMobile6 = true;
        // A new kind string was given to WM6 browser as the
        // capability is significantly different from predecessors.
        kind = "iemobile";
        // Switch off JSF ajax for time being. There are still unresolved
        // issues with Mojarra in supporting mobile-browsers
        useJsfAjax = false;
      }
    }
    else
    {
      isIE = true;
      kind = "ie";
    }
  }
  else if (agentString.indexOf("opera") != -1)
  {
    isOpera = true;
    kind = "opera";
  }
  else if ((agentString.indexOf("applewebkit") != -1) ||
           (agentString.indexOf("safari") != -1))
  {
    isSafari = true
    kind = "safari";
  }
  else if (agentString.indexOf("gecko/") != -1)
  {
    isGecko = true;
    kind = "gecko";
    version = 1.0;
  }
  else if(agentString.indexOf("blackberry") != -1)
  {
    // if we support non-BlackBerry Browser agents on blackberry
    // devices in the future, we may need to revisit this because
    // those agents may include "blackberry" in the User-Agent
    // string; we can't just check if the User-Agent "starts with"
    // blackberry because navigator.userAgent on BlackBery Browser 4.0
    // starts with Mozilla/4.0 (even though the User-Agent sent to the
    // server starts with BlackBerry/)

    // BlackBerry Browser 4.0+ supports navigator.appVersion,
    // and earlier versions don't support script, so we can
    // leave the version as defined above

    // BlackBerryXXXX/Y.Y.Y.Y is the BlackBerry user agent format
    // XXXX is the model number and Y.Y.Y.Y is the OS version number.
    // At this moment, BlackBerry below version 4.6 is regarded as
    // basic HTML browser for the JS performance reason.
    // The following lines should be uncommented when we decide to
    // handle BlackBerry version 4.0~4.5 separate from the batch of
    // Basic HTML browsers after its JS performance improves.
    /*
    var versionStart = agentString.substring(agentString.indexOf(
                                                      "blackberry") + 9);
    versionStart = versionStart.substring(versionStart.indexOf("/") + 1);
    version = parseFloat(versionStart);

    if (version < 4.6)
    {
      pprUnsupported = true;
      supportsDomDocument = false;
      supportsValidation = false;
    }
    */

    isBlackBerry = true;
    kind = "blackberry";
    // Switch off the JSF ajax for time being. There are still unresolved
    // issues with Mojarra in supporting mobile browsers
    useJsfAjax = false;
  }
  else if ((agentString.indexOf('mozilla')    != -1) &&
           (agentString.indexOf('spoofer')    == -1) &&
           (agentString.indexOf('compatible') == -1))
  {
    if (version >= 5.0)
    {
      isGecko = true;
      kind = "gecko";
      version = 1.0;
    }
    else
    {
      isNav = true;
      kind = "nn";
    }
  }
  if (agentString.indexOf('win') != -1)
  {
    isWindows = true;
  }
  else if (agentString.indexOf('mac') != -1)
  {
    isMac = true;
  }
  else if (agentString.indexOf('sunos') != -1)
  {
    isSolaris = true;
  }
  else if ((agentString.indexOf('symbian') != -1) ||
           (agentString.indexOf('nokia') != -1))
  {
     isNokiaPhone = true;
     pprUnsupported = true;
  }

  _agent.isBlackBerry           = isBlackBerry;
  _agent.isGecko                = isGecko;
  _agent.isIE                   = isIE;
  _agent.isIEGroup              = isIEGroup;
  _agent.isMac                  = isMac;
  _agent.isNav                  = isNav;
  _agent.isNokiaPhone           = isNokiaPhone;
  _agent.isOpera                = isOpera;
  _agent.isPIE                  = isPIE;
  _agent.isSafari               = isSafari;
  _agent.isSolaris              = isSolaris;
  _agent.isWindows              = isWindows;
  _agent.isWindowsMobile6       = isWindowsMobile6;
  _agent.kind                   = kind;
  _agent.pprUnsupported         = pprUnsupported;
  _agent.useJsfAjax             = useJsfAjax;
  _agent.supportsDomDocument    = supportsDomDocument;
  _agent.supportsNodeType       = supportsNodeType;
  _agent.supportsValidation     = supportsValidation;
  _agent.version                = version;

  _agent.atLeast                = _atLeast;
  _agent.atMost                 = _atMost;
}


_agentInit();

// available features in ie
var _ieFeatures =
{
  channelmode:1, // ie 5.0
  copyhistory:1,
  directories:1,
  fullscreen:1,  // ie 5.0
  height:1,
  location:1,
  menubar:1,
  resizable:1,
  scrollbars:1,
  status:1,
  titlebar:1,    // ie 5.0 when trusted
  toolbar:1,
  width:1
};

// available features in Netscape
var _nnFeatures =
{
  alwayslowered:1,
  alwaysraised:1,
  copyhistory:1,
  dependent:1,
  directories:1,
  height:1,
  hotkeys:1,
  innerheight:1,
  innerwidth:1,
  location:1,
  menubar:1,
  outerwidth:1,
  outerheight:1,
  resizable:1,
  scrollbars:1,
  status:1,
  titlebar:1,
  toolbar:1,
  width:1,
  "z-lock":1
}

// override values for modeless windows. Values in this
// list can't be overridden by the caller for modeless windows
var _modelessFeatureOverrides =
{
};

// override values for modal windows. Values in this
// list can't be overridden by the caller for modal windows
var _modalFeatureOverrides =
{
};


var _featureDefaults =
{
  // default values for features of document windows
  document:
  {
    channelmode:false,
    copyhistory:true,
    dependent:false,
    directories:true,
    fullscreen:false,
    hotkeys:false,
    location:true,
    menubar:true,
    resizable:true,
    scrollbars:true,
    status:true,
    toolbar:true
  },
  // default values for features of dialog windows
  dialog:
  {
    channelmode:false,
    copyhistory:false,
    dependent:true,
    directories:false,
    fullscreen:false,
    hotkeys:true,
    location:false,
    menubar:false,
    resizable:true,
    scrollbars:true,
    status:true
  }
}


// featues that require signbing in order to be set
var _signedFeatures =
{
  alwayslowered:1,
  alwaysraised:1,
  titlebar:1,
  "z-lock":1
};

// features that are boolean values
var _booleanFeatures =
{
  alwayslowered:1,
  alwaysraised:1,
  channelmode:1,
  copyhistory:1,
  dependent:1,
  directories:1,
  fullscreen:1,
  hotkeys:1,
  location:1,
  menubar:1,
  resizable:1,
  scrollbars:1,
  status:1,
  titlebar:1,
  toolbar:1,
  "z-lock":1
};


/**
 * Adds an event handler to an element.
 * @param obj The element against which the event handler should be registered
 * @param exType The event handler type such as 'change', 'blur', 'click' etc.
 * @param fn The function to call when the event occurs
 */
function _addEvent(obj, evType, fn)
{
  if (obj.addEventListener)
  {
    obj.addEventListener(evType, fn, false);
    return true;
  }
  else if (obj.attachEvent)
  {
    var r = obj.attachEvent("on"+evType, fn);
    return r;
  }
  else
  {
    return false;
  }
}

/**
 * Removes an event handler from an element.
 * @param obj The element against which the event handler is regsitered
 * @param exType The event handler type such as 'change', 'blur', 'click' etc.
 * @param fn The event handler function to remove from the element
 */
function _removeEvent(obj, evType, fn)
{
  // TODO: abstract onto Agent object
  if (obj.removeEventListener)
  {
    obj.removeEventListener(evType, fn, false);
    return true;
  }
  else if (obj.detachEvent)
  {
    var r = obj.detachEvent("on"+evType, fn);
    return r;
  }
  else
  {
    return false;
  }
}

/**
 * Gets the preferred width of the content
 */
function _getBodyWidth(
  element,
  offsetWidth,
  offsetLeft
  )
{
  var maxWidth = _getContentWidth(element, offsetWidth, 0);

  // bogusly double the offset to guess the right margin...
  // However, in right to left languages, the left margin can get very large,
  // and cause the window to become huge (Bug 2846393). Limit it to an
  // empirically reasonable value.
  var marginWidth = 10;

  if (_isLTR() || (offsetLeft <= 5))
  {
      marginWidth = 2 * offsetLeft;
  }

  return maxWidth + marginWidth;
}

/**
 * Gets the preferred width of the content
 */
function _getContentWidth(
  element,
  offsetWidth,
  offsetLeft
  )
{
  var children = element.childNodes;

  // XXXSafari: what to do here?
  var isIE = _agent.isIE;

  var hasContentProp = (isIE)
                         ? "canHaveHTML"
                         : "tagName";
  var maxWidth = 0;

  for (var i = 0; i < children.length; i++)
  {
    var currChild = children[i];

    if (currChild[hasContentProp] && (currChild.offsetWidth > 0))
    {
      var currWidth = 0;
      var currOffsetWidth = currChild["offsetWidth"];

      if (!isIE)
      {
        if ((currOffsetWidth == offsetWidth) ||
            (currOffsetWidth <= 1))
        {
          var currOffsetLeft = currChild.offsetLeft;
          if (currChild.parentNode != currChild.offsetParent)
          {
            currOffsetLeft = currOffsetLeft -
                             (currChild.parentNode.offsetLeft);
          }

          currWidth = _getContentWidth(currChild,
                                       currOffsetWidth,
                                       currOffsetLeft);
        }
        else
        {
          currWidth = currOffsetWidth;
        }
      }
      else
      {
        currWidth = currChild["clientWidth"];

        if (currWidth == 0)
        {
          var currOffsetLeft = currChild.offsetLeft;
          if (currChild.parentElement != currChild.offsetParent)
          {
            currOffsetLeft = currOffsetLeft -
                             (currChild.parentElement.offsetLeft);
          }

          currWidth = _getContentWidth(currChild,
                                       currOffsetWidth,
                                       currOffsetLeft);
        }
      }

      if (currWidth > maxWidth)
      {
        maxWidth = currWidth;
      }
    }
  }

  // handle error cases
  if (maxWidth == 0)
    maxWidth = offsetWidth;

  return maxWidth + offsetLeft;
}

/**
 * Safely returns the parent window of a window, or undefined if security doesn't allow us to
 * retrieve the parent
 */
function _getParentWindow(currWindow)
{
  var parentWindow = currWindow.parent;

  try
  {
    // dummy read to test security error
    parentWindow.name;

    return parentWindow;
  }
  catch (e)
  {
    return undefined;
  }
}

/**
 * Safely retrieve the top accessible window
 */
function _getTop(currWindow)
{
  // since top might be in another domain, crawl up as high as possible manually
  var currParentWindow = _getParentWindow(currWindow);

  while (currParentWindow && (currParentWindow != currWindow))
  {
    currWindow = currParentWindow;
    currParentWindow = _getParentWindow(currWindow);
  }

  return currWindow;
}


/**
 * renders transparent image for spacing
 */
function t(width,height)
{

  // if the transparent url is not null render img tag
  if (_tURL)
  {
    document.write('');
  }
}



/**
 * Returns the object containing the dependent windows.
 */
function _getDependents(
  parentWindow,
  createIfNecessary
  )
{
  var depends;

  if (parentWindow)
  {
    depends = parentWindow["_dependents"];

    if (!depends)
    {
      if (createIfNecessary)
      {
        depends = new Object();
        parentWindow["_dependents"] = depends;
      }
    }
  }

  return depends;
}

/**
 * Get the named dependent
 */
function _getDependent(
  parentWindow,
  dependentName
  )
{
  var depends = _getDependents(parentWindow);
  var dependent;

  if (depends)
  {
    dependent = depends[dependentName];
  }

  return dependent;
}


/**
 * Sets the value of the named dependent
 */
function _setDependent(
  parentWindow,
  dependentName,
  dependentValue
  )
{
  var depends = _getDependents(parentWindow, true);

  if (depends)
  {
    depends[dependentName] = dependentValue;
  }
}


/**
 * Returns the dependent which is modal.
 */
function _getModalDependent(
  parentWindow
  )
{
  return _getDependent(parentWindow, "modalWindow");
}


/**
 * Returns true if the passed in dependent is the modal dependent
 * of the parent window,
 */
function _isModalDependent(
  parentWindow,
  dependent
  )
{
  return (dependent == _getModalDependent(parentWindow));
}


/**
 * Called by our modal windows when changes are applied and
 * the window is closed to make sure that the parent window
 * is updated appropriately. Due to bug 3184718 (Google
 * pop-up blocker does not call onUnload event handlers from
 * dialog windows) we cannot rely on _checkUnload being
 * called by the unload event. We call this function
 * instead which in turn calls _checkUnload.
 */
function _unloadADFDialog(
  event
  )
{
  // _checkUnload is called from body's
  // unload event when
  // We use this flag to keep it from
  // running through _checkUnload function twice.
  // If Google's pop-up blocker is
  // not enabled, then _checkUnload is called from body's
  // unload event as well as from here.

  _blockCheckUnloadFromDialog = false;
  _checkUnload(event);
  _blockCheckUnloadFromDialog = true;
}

/**
 * Called by the unload handler of modal windows to call the event
 * handler and make sure that the parent window is updated appropriately
 * to show that no modal window is up anymore.
 */
function _checkUnload(
  event
  )
{
  //PH:set the right event object;
  event = _getEventObj();

  // Make sure we don't run through this function twice
  // when we close a dialog. The
  // _unloadADFDialog function blocks a second run
  // using the _blockCheckUnloadFromDialog flag.

  if (_blockCheckUnloadFromDialog)
  {
    _blockCheckUnloadFromDialog = false;
    return;
  }

  // Check to see if we are a modal window that has been
  // abandoned (who's parent has changed out from under us).
  // In this case, we skip the unload handler, since the
  // modal window no longer has permission to access its
  // parent, and JavaScript errors may occur
  if (_isModalAbandoned())
    return;

  // Check to see if we have an open modal child window
  var modalWindow = _getModalDependent(window);
  if (modalWindow != null)
  {
    // If we are being unloaded before our modal child has been
    // closed, that means that the user must have navigated
    // to a new page just before the modal window was displayed.
    // In this case, let's just close our modal child.  We need
    // to be extra careful to make sure that the modal child does
    // not try to access any properties on the parent window
    // when closing, because the modal child may no longer have
    // permission to access us at this point.  Set a property
    // on the modal window to let it know that it has been
    // abandoned.
    _setModalAbandoned(modalWindow);

    // Now we can safely close the modal window
    modalWindow.close();
  }

  var topWindow = _getTop(self);

  if (!topWindow)
    return;

  var parentWindow = topWindow["opener"];

  if (!parentWindow)
    return;

  var unloader = _getDependent(parentWindow, self.name);

  if (_isModalDependent(parentWindow, self))
  {
    // remove the modal window
    _setDependent(parentWindow, "modalWindow", (void 0));

    parentWindow.onfocus = null;

    if (_agent.supportsDomDocument)
    {
      var parentBody = parentWindow.document.body;

      // release the ie mouse grab
      if (_agent.atLeast("ie", 4))
      {
        if (_agent.atLeast("ie", 5) && _agent.isWindows)
        {
          parentBody.onlosecapture = null;

          _removeModalCaptureIE(parentBody);
        }
        parentBody.style.filter = null;
      }

      if (_agent.isGecko)
      {
        if (parentBody != (void 0))
        {
          _removeModalCaptureGecko(parentWindow, parentBody);
        }
      }
    }
  }

  if (unloader != (void 0))
  {
    // remove our dependent info
    _setDependent(parentWindow, self.name, (void 0));

    // try the passed in event (netscape way first), then
    // try to get the event the IE way
    if (event == (void 0))
      event = self.event;

    // call the unloader with the unloading window and the event
    unloader(topWindow, event);
  }
}

// Adds a (IE-specific) capture to the specified element
// for blocking mouse events during modal dialog display
function _addModalCaptureIE(element)
{
  // Captured events still bubble on IE.  Register
  // mouse event handlers to cancel event bubbling
  // and save away old listeners so we can restore
  // them when the capture is removed.
  var savedListeners = new Object();
  var events = _IE_MOUSE_CAPTURE_EVENTS;
  var eventCount = events.length;

  for (var i = 0; i < eventCount; i++)
  {
    var eventName = events[i];
    savedListeners[eventName] = element[eventName];
    element[eventName] = _captureEventIE;
  }

  // Stash away the saved listener somewhere where
  // we can get at them later
  window._modalSavedListeners = savedListeners;

  // Set the capture
  window._trIeCapture = element;
  window._trIeCaptureCurrent = true;
  element.setCapture();
}

// Removes a (IE-specific) capture added via _addModalCaptureIE()
function _removeModalCaptureIE(element)
{
  // Release the capture
  element.releaseCapture();

  // Restore event handlers that were saved away
  // during _addModalCaptureIE().
  var savedListeners = window._modalSavedListeners;

  if (savedListeners)
  {
    var events = _IE_MOUSE_CAPTURE_EVENTS;
    var eventCount = events.length;

    for (var i = 0; i < eventCount; i++)
    {
      var eventName = events[i];

      element[eventName] = savedListeners[eventName];
    }

    window._modalSavedListeners = null;
  }
  window._trIeCapture = undefined;
}

// Captures (and consumes) events during modal grabs
// on IE browsers
function _captureEventIE()
{
  // do not capture events outside the document body, this leads to the inability for users
  // to click on IE toolbars, menubars, etc.
  var event = window.event;
  if (event.screenY >= window.screenTop && event.screenX >= window.screenLeft)
  {
    if (!window._trIeCaptureCurrent && window._trIeCapture)
    {
      window._trIeCaptureCurrent = true;
      window._trIeCapture.setCapture();
    }
    event.cancelBubble = true;
  }
  else if (window._trIeCapture)
  {
    window._trIeCaptureCurrent = false;
    window._trIeCapture.releaseCapture();
  }
}

// Adds a (Gecko-specific) capture to the specified element
// for blocking mouse events during modal dialog display
function _addModalCaptureGecko(element)
{
  var events = _GECKO_MOUSE_CAPTURE_EVENTS;
  var eventCount = events.length;

  for (var i = 0; i < eventCount; i++)
  {
    var eventName = events[i];
    element.addEventListener(eventName, _captureEventGecko, true);
  }
}

// Removes a (Gecko-specific) capture added via _addModalCapture()
function _removeModalCaptureGecko(parentWindow, element)
{
  var events = _GECKO_MOUSE_CAPTURE_EVENTS;
  var eventCount = events.length;

  for (var i = 0; i < eventCount; i++)
  {
    var eventName = events[i];
    element.removeEventListener(eventName,
                                parentWindow._captureEventGecko,
                                true);
  }
}

// Captures (and consumes) events during modal grabs
// on Gecko browsers
function _captureEventGecko(
  event
  )
{
  // Stop propagation and suppress default action
  event.stopPropagation();
  window.preventDefault = true;
}

// Tests whether the current window is an "abandoned"
// modal window.  This is a modal window who's parent
// window has navigated to a new page, in which case
// the modal window is out of context.
function _isModalAbandoned()
{
  // We look for the _abandoned property on the modal window.
  // Note that in the LOV case, we actually have two onunload
  // event handlers that need to be suppressed: The onunload
  // handler for the LOV window and the onunload handler for
  // the actual contents of the LOV window which are nested
  // within a frame.  So, we check for the _abandoned property
  // on the "top" window.
  var topWindow = _getTop(self);

  return topWindow._abandoned;
}

// Marks the specified modal window as abandoned
function _setModalAbandoned(
  modalWindow
  )
{
  // Just set the _abandoned property on the modal window.
  modalWindow._abandoned = true;
}


/**
 * Function that returns a single key/value pair String
 */
function _getKeyValueString(
  target,
  keyName,
  index
  )
{
  var value = target[keyName];

  if (typeof(value) == "function")
  {
    value = "[function]";
  }

  // XXXSafari: what to do here?
  var separator = (_agent.isGecko)
                    ? ((index + 1) % 3 == 0)
                      ? '\n'
                      : '    '
                    : '\t';

  return keyName + ':' + value + separator;
}

function _dumpSuppress(
  target
  )
{
  _dump(target, {innerText:1, outerText:1, outerHTML:1, innerHTML:1});
}

/**
 * Utility for dumping the contents of a JavaScript object.
 */
function _dump(
  target,
  suppressProps,
  name
  )
{
  var props = "";

  if (target)
  {
    // default the name if none provided
    if (!name)
    {
      name = target["name"];
    }

    //
    // Because we need to catch exceptions that IE throws if
    // for some object reads, we need to have separate ie and netscape
    // code for the exception catching.  Unfortunately, "try" and
    // catch are reserved words, so we have to dynamically create
    // our adding function so that Netscape doesn't throw it's own
    // exception when it parses our file
    //
    // var adderContent = "return i + ':' + target[i] + '\\n';";
    var adderContent = "return _getKeyValueString(target, key, index);";

    // wrap adder content with a try and eat the bogus ie exception
    if (_agent.atLeast("ie", 5) || _agent.isGecko || _agent.isSafari)
      adderContent = "try{" + adderContent + "}catch(e){return '';}";

    var adder = new Function("target", "key", "index", adderContent);
    var propCount = 0;
    var propArray = new Array();

    for (var key in target)
    {
      // don't add properties that should be suppressed
      if ((!suppressProps || !suppressProps[key]) && !key.match(/DOM/))
      {
        propArray[propCount] = key;
        propCount++;
      }
    }

    // sort the array so that we can find stuff
    propArray.sort();

    for (var i = 0; i < propArray.length; i++)
    {
      props += adder(target, propArray[i], i);
    }
  }
  else
  {
    // the object to dump was undefined
    name = "(Undefined)";
  }

  // tell the user that the object has no properties
  if (props == "")
  {
    props = "No properties";
  }

  alert(name + ":\n" + props);
}

function _getJavascriptId(name)
{
  return name.split(':').join('_');
}

function _getFormName(form)
{
  var name = form.name;

  if ((typeof name) != 'string')
  {
    if (_agent.isIE)
    {
      name = form.attributes['name'].nodeValue;
    }
    else
    {
      name = form.getAttribute('name');
    }
  }

  return name;
}


/**
 * Calls the correct validations function for the form and returns true
 * if the validation succeeded.
 */
function _validateForm(
  form,
  source
  )
{
  // Blackberry does not set valiation script in the fields
  // and it is not possible to execute validation.
  // Return true if validation is not supported.
  if (!_agent.supportsValidation)
  {
    return true;
  }

  var funcName = '_' + _getJavascriptId(_getFormName(form)) + 'Validator';
  var formWind = window[funcName];
  if (formWind)
  {
    try
    {
      ret = formWind(form, source);
    }
    catch (e)
    {
      // Validator did not execute normally.
      // In case for mobile devices, BlackBerry, Nokia, Windows Mobile and PPC
      // return true in order to submit the form.
      if (_agent.isPIE || _agent.isNokiaPhone || _agent.isBlackBerry)
      {
        ret = true;
      }
      else
      {
        ret = false;
      }
    }
      return ret;
  }

  return false;
}


/**
 * Validate the specified field.
 */
function _valField(
  formName,
  nameInForm
  )
{
  if (nameInForm)
  {
    // get the target whose validation we want to run
    var target = document.forms[formName][nameInForm];

    // get its onblur function
    var blurFunc = target.onblur;

    if (blurFunc)
    {
      // FIXME: this is *NOT* portable.  Safari, for example,
      // does not implement toString() on functions this way,
      // and nothing requires that it does
      var valFunc = blurFunc.toString();

      // whack off the beginning and end of the function, leaving the content
      var valContents = valFunc.substring(valFunc.indexOf("{") + 1,
                                          valFunc.lastIndexOf("}"));

      var targetString = "document.forms['" +
                         formName +
                         "']['" +
                         nameInForm +
                         "']";

      // replace 'this' with the actual target
      valContents = valContents.replace(/this/, targetString);

      // trim off last argument
      var lastArg = valContents.lastIndexOf(",");

      valContents = valContents.substring(0, lastArg) + ")";

      // perform the validation
      eval(valContents);
    }
  }
}

function _validateAlert(
  form,
  source,
  validators,
  globalMessage,
  errorTitle
  )
{
  if (!validators)
    validators = _getValidators(form);

  var failureMap = _multiValidate(form, source,  validators);

  var firstFailure = true;
  var failureString = errorTitle + '\n';

  for (var currId in validators)
  {
    // Get the messages array for currId, skip if none
    var messages = failureMap[currId];
    if (!messages || messages.length==0)
      continue;

    // Get the input element
    var currInput = _getFormElement(form, currId);
    if (!currInput)
      continue;

    // Get the label text for this input
    var label = validators[currId].label;

    // Loop through the messages for this input
    for (var j=0; j < messages.length; j = j+2)
    {
      // Move the focus back to the first failed field
      if (firstFailure)
      {
        _setFocus(currInput);
        firstFailure = false;
      }

      // Get the current message
      var facesMessage = messages[j];

      if (_agent.isNokiaPhone)
      {
        errorString = _getGlobalErrorString(currInput,
                            globalMessage,
                            facesMessage,
                            label);
      }
      else
      {
        errorString = _getGlobalErrorString(currInput,
                            globalMessage,
                            facesMessage.getDetail(),
                            label);
      }

      failureString += errorString + '\n';
    }
  }

  if (firstFailure)
    return true;

  // Show the error and note the time we finished this validation.
  // Record the validation both before and after the alert so that we
  // halt any validations caused by events triggered along with this
  // one, or by the closing of this alert.
  _recordValidation(true, 0);
  alert(failureString);
  _recordValidation(true, 0);

  return false;
}

function _validateInline(
  form,
  source,
  validators
  )
{
  // If not passed explicitly, return
  if (!validators)
    validators = _getValidators(form);

  var failureMap = _multiValidate(form, source,  validators);

  var noFailures = true;

  for (var currId in validators)
  {
    var foundMsg = false;

    // Get the icon if any
    var iconElem = _getElementById(document, currId + "::icon");

    // If component hasn't got a message element, then skip
    var msgElem = _getElementById(document, currId+ "::msg");

    // Clear any existing inline message
    if (msgElem && msgElem.innerHTML !="")
      msgElem.innerHTML = "";

    // Clear any existing messages from the MessageBox
    TrMessageBox.removeMessages(currId);

    // Get the messages array for currId, skip if none
    var messages = failureMap[currId];
    if (!messages || messages.length==0)
    {
      // Hide the inline message and icon
      if (msgElem)
        msgElem.style.display = "none";
      if (iconElem)
        iconElem.style.display = "none";
      continue;
    }

    // Get the input element
    var currInput = _getFormElement(form, currId);
    if (!currInput)
      continue;

    // Get the label text for this input
    var label = validators[currId].label;

    // Loop through the messages for this input
    for (var j=0; j < messages.length; j = j+2)
    {
      if (noFailures)
      {
        noFailures = false;

        // Move the focus back to the first failed field
        // TODO - Remove once inline validation uses onblur/onchange
        _setFocus(currInput);
      }

      // Get the current message
      var facesMessage = messages[j];

      if (msgElem)
      {
        if (_agent.isNokiaPhone)
        {
          msgElem.innerHTML = facesMessage;
        }
        else
        {
          msgElem.innerHTML = facesMessage.getDetail();
        }
      }

      // if there's nowhere to display the message in either
      // summary or detail, then pop an alert to warn the page developer
      if (!msgElem && !TrMessageBox.isPresent())
      {
        if (_agent.isNokiaPhone)
        {
          alert("Field Error [" + currId + "] - " + facesMessage);
        }
        else
        {
          alert("Field Error [" + currId + "] - " + facesMessage.getDetail());
        }
      }

      // Add the message to the MessageBox
      TrMessageBox.addMessage(currId, label, facesMessage);
    }

    // If we got this far, we know there's something to display so
    // make the inline message and icon visible.
    if (msgElem)
      msgElem.style.display = "";
    if (iconElem)
      iconElem.style.display = "";
  }

  return noFailures;
}

/**
 * Performs validation on the supplied input element.  If validation fails
 * the appropriate message will be displayed in the message component for this
 * input field.
 * 

* The simplest usage of this method is from the onblur attribute of the * input component. e.g. onblur="_validateInput(event);" *

* @param event(Event) The event object provided by the event handler. * @param falseOnFail(boolean) Force method to return false if validation failed. * @return boolean, false if validation failed and falseOnFail set to true, otherwise true. */ // TODO: make this a public function only after hanging it on // a namespaced object, *and* making it not specific to inline // validation function _validateInput(event, falseOnFail) { if (!event) return true; // Get the element associated with the event var inputElem = event.target || event.srcElement; if (!inputElem || !inputElem.id) return true; var form = _getForm(inputElem); if (!form) return true; var validators = _getValidators(form); if (!validators) return true; var id = inputElem.id; var descriptor = validators[id]; // If we couldn't find the descriptor by id, then try by name // as it might be a radio button if (!descriptor && inputElem.name) { id = inputElem.name; descriptor = validators[id]; } if (!descriptor) return true; // Create a new temporary validators object and run with just the // one descriptor var validatorsToRun = new Object(); validatorsToRun[id] = descriptor; // Call inline validation using only the appropriate validators var retval = _validateInline(form, null, validatorsToRun, 1, null); // Only return the actual outcome if asked to do so if (falseOnFail) return retval; } // Records the time of this validation event. // If fail is set, this is a validation failure, that is noted also. function _recordValidation(fail, now) { if (!now) now = new Date(); _lastDateValidated = now; if (fail) _lastValidationFailure = now; } // returns true if a validation has occurred "recently" // failures: True means only report on recent failures, false means report on // any validation. function _recentValidation(failures) { var retVal = false; var timeWindow = 250; // Assuming that a reasonable user won't close the dialog and change the // text within a quarter of a second, we ignore any validations within // 250ms. of the last failed validation. The timings I've seen here range // in the 60 - 90 ms. range, but that is on fast development machines. We // could probably lower this to 150 if we're seeing dropped validations // for really fast, ambitious users. // With Macintosh IE, we manage to crash the browser! if (_agent.isMac) { // The iBook can have diffs of up to about 480 ms. // Call it 600 to be safe. timeWindow = 600; } var newDate = new Date(); var diff; // If failures are requested, the caller is only interested in failures. // If simple validation requested, caller interested in any validation fail // or not. diff = newDate - _lastValidationFailure; if ((diff >= 0) && (diff < timeWindow)) { retVal = true; } else if (!failures) { diff = newDate - _lastDateValidated; if ((diff >= 0) && (diff < timeWindow)) { retVal = true; } } return retVal; } /** * Used to submit a selected item in a choice as if it's a commandLink * or commandButton */ function _commandChoice( form, choice ) { var src = document.forms[form].elements[choice].value; // need this strange [0] for when choice repeated, // for example a processChoiceBar in actions facet of panelPage. if (src == void(0)) src = (document.forms[form].elements[choice])[0].value; // if it starts with a '#', it's an url. var gtIndex = src.indexOf("#"); if ( gtIndex == 0) window.document.location.href = src.substring(1,src.length); else { var openBracketIndex = src.indexOf("["); var srcID = src.substring(0, openBracketIndex); var validateString = src.substring(openBracketIndex+1, openBracketIndex+2) var validate = parseInt(validateString); submitForm(form,validate,{source:srcID}); } } /** * Attempts to submits the form, potentially firing validation and notifying * any Cabo onSubmit handlers registered on the form, returning * true if the submission actually occurred. *

* If the doValidate parameter is false, no validation will * be performed, and the form is guaranteed to be submitted. Otherwise, * the form will be submitted if both the validation succeeds and any * registered Cabo onSubmit handlers do not return false. *

* @param form The form to submit. This can either be the name of the form * in the current document, the index of the form * in the current document or the form itself. * @param doValidate boolean value specifying whether validation should * occur before the form is submitted. (As per a common Javascript * idiom, it is acceptable to pass true/false as well as 0/1). If * this parameter is ommitted, it defaults to true. * @param parameters a single Javascript object that specifies * all the additional key-value pairs to submit. There must be * pre-existing <input type="hidden"> elements as targets * for each of these parameters. */ function submitForm( form, doValidate, parameters, isPartial, event ) { // If we've delayed any sort of event submission, we won't want to do it at // all now that the form is getting submitted. Blow away the saved data. Any // timeout handler will cancel the event submission if the data no longer // exists. var pending = true; if (_agent.isIEGroup) { pending = false; // keep track of whether there was a pending event for (var key in _delayedEventParams) { pending = true; break; } } if (pending) { _delayedEventParams = new Object(); _delayedEventParams["reset"] = true; } // if the form was passed as a form name, get the form object if ((typeof form) == "string") { form = document[form]; } // if the form was passed as a form index, get the form object else if ((typeof form) == "number") { form = document.forms[form]; } // we had better have a form now if (!form) return false; // Check to see if submitForm is called before the form // has been rendered completely. If so, save the parameters // and return. At the end of the form, we always call _submitFormCheck // which will re-call submitForm if it had been rejected. // This is for bug 2752257. // Bug #3058770: In LovInput, we have to hack up a form for NLS. It's not // validated, so there is no real validator, we've just hacked one. The // submit always sets doValidate to false. Just make sure that you never use // this validator if doValidate is false (it might just be the value '1'). var formComplete = window["_"+ _getJavascriptId(_getFormName(form)) + "Validator"]; if (formComplete == (void 0)) { _saveFormForLaterSubmit(form, doValidate, parameters); // Do not submit the form, // since the form hasn't been rendered completely yet. return false; } // Bug 1789483: ignore a second form submission that happens // less than 0.5 seconds after the first one var newDate = new Date(); if (_recentSubmit(newDate)) { // However if we're allowing the first click through... we queue up this // submit. if (_pprFirstClickPass && _pprBlocking) { _saveFormForLaterSubmit(form, doValidate, parameters); } return; } // just in case, clear it the delayed submit flags _submitRejected = false; _inPartialSubmit = false; _lastDateSubmitted = newDate; // default value for doValidate is true if (doValidate == (void 0)) doValidate = true; // assume that we should submit the form var doSubmit = true; // validate the form if necessary, and don't submit the // form if validation fails var paramSource; if (parameters != null) paramSource = parameters.source; else paramSource = ""; if (doValidate && !_validateForm(form, paramSource)) doSubmit = false; // // If we have an onSubmit handler, call it // var onSubmit = window["_" + _getJavascriptId(_getFormName(form)) + "_Submit"]; if (typeof onSubmit != "undefined" && doSubmit) { // create function so that "return" is handled correctly, var func = new Function("doValidate", onSubmit); var handlerResult; // WindowsMobile 5 doesn't support installing Funtion object // to "this", so just invoke the Function object instead. if (_agent.isPIE) { handlerResult = func(event); } else { // install the function on the object so that "this" is // handled correctly form._tempFunc = func; // call the submit handler with the doValidate flag, handlerResult = form._tempFunc(doValidate); // uninstall the temporary function form._tempFunc = (void 0); } // if we're validating and the handler returns false, // don't submit the form if (doValidate && (handlerResult == false)) { doSubmit = false; } } if (doSubmit) { // reset any hidden form values before submitting TrPage.getInstance()._resetHiddenValues(form); // While WM6 can support PPR, WM5 and PPC lacks enough support // for DOM and/or HMLHTTP. Disable partial form post for PPC and // WM5. if (isPartial && _supportsPPR()) { // In the case of Windows-mobile(WM) browsers, during rendering, // Trinidad stores the value of the request-header field, UA-pixels, // into a hidden-parameter's value attribute. WM browsers' PPRs don't // contain UA-pixels in their request-headers. So during a WM browser's // PPR, we need to manually set the field, UA-pixels, into the // request-header with the hidden parameter's value. if (_agent.isPIE || _agent.isWindowsMobile6) { var header = new Array(1); header['UA-pixels'] = form.elements['uapixels'].value; TrPage.getInstance().sendPartialFormPost(form, parameters, header); } else { TrPage.getInstance().sendPartialFormPost(form, parameters, null, event); } } else { // // assign any dynamic values before submitting // var isDOM = _supportsDOM(); var tempParams = new Object(); if (parameters) { for (var paramName in parameters) { var paramValue = parameters[paramName]; if (paramValue != (void 0)) { // do not try to get properties from the form element directly. // Some code somewhere was setting an htmlInputElement as // a property on the formElement, but not as a child. // This was causing bug 4536656. // I can't yet figure out who is setting the htmlInputElement as // a property (instead of a child). // As a workaround get them from the elements array instead. // In any case it is always safe to get the element from the // elements array. //var hiddenField = form[paramName]; var hiddenField = form.elements[paramName]; if (_agent.isPIE) { hiddenField.value = paramValue; } else { var hiddenFieldCreated = false; // See if the hidden field exists. And, because // of some rather strange IE behavior w/regards to // form.elements['id'], make sure we haven't accidentally // grabbed a string if (hiddenField && (typeof(hiddenField) != "string")) { // This condition was added to support enter key // on forms for hcommandButton if (hiddenField.type == 'submit' || hiddenField.type == 'button') { var tmpField = document.createElement("input"); tmpField.type = "hidden"; tmpField.name = paramName; tmpField.value = parameters[paramName]; form.appendChild(tmpField); tempParams[paramName] = tmpField; hiddenFieldCreated = true; } else { hiddenField.value = paramValue; } } //VAC- added so that PDA's do not enter this flow. Since no PDA currently //supports createElement function on the document. Furthermore, if the //hidden field exists there should be no reason to create a new hidden field //with the same name and attach it to the form. else { if (isDOM) { if (! hiddenFieldCreated) { // as a convenience to the client, build a hidden field to hold // this parameter. var tmpField = document.createElement("input"); tmpField.type = "hidden"; tmpField.name = paramName; tmpField.value = parameters[paramName]; form.appendChild(tmpField); tempParams[paramName] = tmpField; } } } } } } } // IE BUG, see TRINIDAD-704 if(_agent.isIE) _autoCompleteForm(form); try { form.submit(); } catch (e) { if (TrPage.getInstance().getRequestQueue()._isMultipartForm(form)) { // IE will fail on an input file submission of a file that does not exist var facesMessage = _createFacesMessage( 'org.apache.myfaces.trinidad.component.core.input.CoreInputFile.INPUT_FILE_ERROR'); // if there's nowhere to display the message in either // summary or detail, then pop an alert to warn the page developer if (!TrMessageBox.isPresent()) alert(facesMessage.getDetail()); else // Add the message to the MessageBox TrMessageBox.addMessage(null, null, facesMessage); } else { throw e; } } if (_blockOnEverySubmit) _pprStartBlocking(window); // Remove any dynamically added form parameters. We do this for two // reasons: // 1. IE6 does not return dynamically-added form elements in the form map, // so we end up re-adding the same form elements again. // 2. If we don't remove them, then subsequent form submits behave like // they are PPR requests (because the dynamically added "partial" and // "partialTargets" parameters will be on the request). // (Bug #3623890. This seems to break on a few Apps pages with bad form // setups) if (isDOM) { for (var paramName in tempParams) form.removeChild(tempParams[paramName]); } } } return doSubmit; } /** * Internet Explorer has a bug, that the autocomplete does not work when * using JavaScript to submit a form. */ function _autoCompleteForm(form) { var theExternal = window.external; if (theExternal && (typeof theExternal.AutoCompleteSaveForm != "undefined")) { try { theExternal.AutoCompleteSaveForm(form); } catch (e) { // ignore } } } /** * This function is called when enter key is hit on any form input element. * @src if non-null, the ID of the object to fire */ function _submitOnEnter(e, frm, src, immediate, ppr) { if (window.event != null) e = window.event; var eventSource; if (e.srcElement == undefined) // Gecko browsers eventSource = e.target; else eventSource = e.srcElement; if (!eventSource) return true; // Only process for "INPUT": but not for submit and reset // buttons if(eventSource.tagName == 'A') return true; if ((eventSource.tagName == 'INPUT') && (eventSource.type != 'submit') && (eventSource.type != 'reset')) { if (_getKC(e)==13) { if (src != null) { var params = new Object(); params[src] = src; params['source'] = src; if(ppr != true) { submitForm(frm,immediate,params); } else { TrPage._autoSubmit(frm, src, e, immediate, params); } } return false; } } return true; } /** * In some cases we need to hold off on a submit for a while (waiting for the * page to complete rendering, waiting for another submit to complete, etc.). * This function will save off the state of the submit request for later * processing in _submitFormCheck(). */ function _saveFormForLaterSubmit(form, val, params) { // TODO: fix for PPR _saveForm = form; _saveDoValidate = val; _saveParameters = params; _submitRejected = true; } /** * Checks if _submitForm had been called before the form had completely * rendered, and if so, recall it. This function is rendered at the end of the * form, so it is guaranteed that the form is complete when this is called. */ function _submitFormCheck() { if (_submitRejected) { if (_inPartialSubmit) { _submitPartialChange(_saveForm, _saveDoValidate, _saveParameters); _inPartialSubmit = false; } else { submitForm(_saveForm, _saveDoValidate, _saveParameters); } _saveForm = null; _saveDoValidate = null; _saveParameters = null; } } /** * Attempts to reset the form, calling * any reset function calls registered on the form. * The form will be reloaded if any * reset function call returns true. * This function returns true if the page * had to be reloaded, and false otherwise. *

* @param form The form to submit. This can either be the name of the form * in the current document, the index of the form * in the current document or the form itself. */ function resetForm( form ) { var doReload = false; // if the form was passed as a form name, get the form object if ((typeof form) == "string") { form = document[form]; } // if the form was passed as a form index, get the form object else if ((typeof form) == "number") { form = document.forms[form]; } // we had better have a form now if (!form) return false; var doReload = TrPage.getInstance()._resetForm(form); if ( doReload ) { window.document.location.reload(); } else { form.reset(); } _lastDateReset = new Date(); return doReload; } // Create query string with the data from a given form function createNameValueString(form) { var datatosend = ""; try { var arr = form.elements; for (var i = 0; i < arr.length; i++) { try { var element = arr[i]; if(element.name) { if (element.type == "text" || element.type == "password" || element.type == "textarea" || element.type == "hidden") { datatosend += (element.name + "=" + escape(element.value) + "&"); } else if (element.type.indexOf("select") != -1) { //PH:selectdata must be initialized to "". Otherwise, results for //selectdata+="stringtoconcatenate" is "undefinedstringtoconcatenate" var selectdata ="" ; for (var j = 0; j < element.options.length; j++) { if (element.options[j].selected == true) selectdata += element.name + "=" + escape(element.options[j].value) + "&"; } if( !selectdata) { var val = _getValue(element); if (val) { selectdata += element.name + "=" + escape(val) + "&"; } } if (selectdata) { datatosend += selectdata; } } else if (element.type == "checkbox" && element.checked) datatosend += ( element.name + "=" + escape(element.value) + "&"); else if (element.type == "radio" && element.checked == true) datatosend += (element.name + "=" + escape(element.value) + "&"); } } catch (e) { } element = null; } } catch(e) { } return ( datatosend.substring(0, datatosend.length - 1)); } /** * Returns the value of a form element. */ function _getValue(formElement) { var shadowElem = formElement; var elementType = formElement.type; // When we're dealing with an array of elements, find the // real element type by looking inside the array. if (!elementType && formElement.length) { // See bug 3651045; IE can put "fieldsets" in with // form elements! for (var i = 0; i < formElement.length; i++) { elementType = formElement[i].type; if (elementType != (void 0)) { shadowElem = formElement[i]; break; } } } if (elementType == "checkbox") { if (formElement.length) { for (var i = 0; i < formElement.length; i++) { // See above for why we check each element's type if (formElement[i].type == "checkbox" && formElement[i].checked) { return formElement[i].value; } } } else { return formElement.checked; } } else if (elementType == "select-multiple") { var multiResult = new Array(); for (var i = 0; i < formElement.length; i++) { if(formElement.options[i].selected) { multiResult[multiResult.length] = formElement.options[i].value; } } return (multiResult.length > 0) ? multiResult : ""; } else if (elementType.substring(0,6) == "select") { formElement = shadowElem; var selectedIndex = formElement.selectedIndex; // selectedIndex exists and non-negative if (selectedIndex != (void 0) && selectedIndex != null && selectedIndex >= 0) { var opt = formElement.options[selectedIndex]; var value = opt.value; if (!value) { // If there's no value, it could be for two reasons: // (1) The user has only specified "text". // (2) The user explicitly wanted "value" to be empty. // We can't really tell the difference between the two, // unless we assume that users will be consistent with // all options of a choice. So, if _any_ option // has a value, assume this one was possibility (2) for (var i = 0; i < formElement.options.length; i++) { if (formElement.options[i].value) return value; } // OK, none had a value set - this is option (1) - default // the "value" to the "text" return opt.text; } return value; } // no selected value return ""; } else if (elementType == "radio") { if (formElement.length) { for (var i = 0; i < formElement.length; i++) { // See above for why we check each element's type if (formElement[i].type == "radio" && formElement[i].checked) { return formElement[i].value; } } } else { if (formElement.checked) { return formElement.value; } } // no selected value return ""; } else { return formElement.value; } } /** * Sets the selected index */ function _setSelectIndexById(id, index) { var element = _getElementById(document, id); if (element != null) element.selectedIndex = index; } /** * Synchronizes the index of a repeated choice. */ function _syncChoiceIndex(ch) { var form = ch.form; var name = ch.name; var comps = form.elements[name]; for (i=0; i= 46) && (e.keyCode < 112))) field.value=""; return true; } /** * If appropriate sets the focus on the input passed in */ function _setFocus(currInput) { // check if currInput is showing before setting focus, for example // ColorField has required validation on hidden field, // but cannot receive focus. if (_isShowing(currInput)) { if (currInput.focus) currInput.focus(); //PH:element["value"] is not supported for PIE,IEM and BB. Therefore //use element.value which is supported by all if ((currInput.type == "text") && (currInput.value != (void 0)) && (currInput.value != null) && (currInput.value.length > 0)) { // IE fails on this select if a timeout occurs to handle a // pending event. Don't do it if we've reset the delayed // events object. if (true != _delayedEventParams["reset"]) currInput.select(); } } } function _addValidators(formName, validators, validations, labels, formats) { var form = document.forms[formName]; var validatorMap = _getValidators(form); if (!validatorMap) validatorMap = new Object(); // Now, iterate through the array we've been given for (var i = 0; i < validators.length; i += 5) { var id = validators[i]; var descriptor = new Object(); // If the field is required, replace the format index with the // actual message if (validators[i + 1]) { var formatIndex = validators[i + 2]; descriptor.required = true; descriptor.requiredFormat = formats[formatIndex]; } // If the converter exists, change it from an index to a converter var converterIndex = validators[i + 3]; if (converterIndex != null) { descriptor.converter = validations[converterIndex]; } // If there's a validator array, reuse it after converting // the indices to validator objects var validatorArray = validators[i + 4]; if (validatorArray) { for (j = 0; j < validatorArray.length; j++) { validatorArray[j] = validations[validatorArray[j]]; } descriptor.validators = validatorArray; } // Store the label on the descriptor var label = labels[id]; if (label) descriptor.label = label; // Stash the descriptor on the validator map validatorMap[id] = descriptor; // If enabled, setup event based validation if (_TrEventBasedValidation) { var inputElem = _getElementById(document, id); if (inputElem) { _addEvent(inputElem, "change", _validateInput); } } } // And store the new validator map away window["_" + _getJavascriptId(_getFormName(form)) + "_Validators"] = validatorMap; } /** * Calls an array of validation functions and returns a map of validation * errors. Each map entry is keyed by an id of an input component * and contains an array of TrFacesMessage objects relating to the * component (i.e. ). */ function _multiValidate( form, source, validators ) { // Initialise the return map. var failureMap = new Object(); var subforms = window[_getFormName(form) + "_SF"]; var ignorePrefixes = new Array(); var foundUsedSubform = false; var key; if (source != (void 0)) { // Find if there's any prefix that matches for (key in subforms) { if (source.indexOf(key + ":") == 0) { foundUsedSubform = true; break; } } // Build up all prefixes that don't match for (key in subforms) { if (source.indexOf(key + ":") != 0) { if ((foundUsedSubform) || (subforms[key] == 1)) ignorePrefixes.push(key + ":"); } } } // We check for any relevent validation failures here, not just validations. // If a validation has been run on one field in the form (e.g. an onBlur), we // still need to run every other validation. However, if that one validation // failed, the user has seen one alert, don't bug them with a second til they // have fixed the first error. if (validators && !_recentValidation(true)) { for (var id in validators) { if(_getElementById(document, id) == null) { continue; } var isIgnored = false; // If this field is one that's specifically being ignored, // then don't validate here. for (var j = 0; j < ignorePrefixes.length; j++) { if (id.indexOf(ignorePrefixes[j]) == 0) { isIgnored = true; break; } } if (isIgnored) continue; // get the current form element to validate var currInput = _getFormElement(form, id); // Make sure we have a non-null input control. It is possible // that in rich client environments the DOM for the input // control may have been temporarily removed from the document. // If we don't find DOM for the current input, move on to the // next input. // todo: Should also check for visibility of currInput, since // rich client may have "hidden" the input, in which case // validation shouldn't fire. if (!currInput) continue; //Initialize the failure array for this input var inputFailures = new Array(); var descriptor = validators[id]; var label = descriptor.label; // if currInput is an array then multiple elements have the same name. // Only the first will be validated as subsequent values should be in sync var elementType = currInput.type; if (!elementType && currInput.length) { var firstType = currInput[0].type; if (firstType != "radio" && firstType != "checkbox") { currInput = currInput[0]; } } var value = _getValue(currInput); var required = descriptor.required; if ( required && ((value == "" ) || (value == null))) { // get the formatted error string for the current input and var requiredErrorString = _getErrorString(currInput, label, descriptor.requiredFormat); // Populate the failureMap with the current error inputFailures[inputFailures.length] = new TrFacesMessage(requiredErrorString, requiredErrorString); } else { var converterConstructor = descriptor.converter; // set the converterError var to false for each input, otherwise nothing // after the first conversion error is validated var converterError = false; if ( converterConstructor ) { // do the conversion if this element has a value if ((value != null) && !((typeof value == "string") && (value == ""))) { var converter = eval(converterConstructor); try { value = converter.getAsObject(value, label); } catch (e) { converterError = true; // Populate the failureMap with the current error if (_agent.isPIE || _agent.isNokiaPhone || _agent.isBlackBerry) { inputFailures[inputFailures.length] = e.message; } else { inputFailures[inputFailures.length] = e.getFacesMessage(); } } } } if ( converterError == false) { var validatorArray = descriptor.validators; if (validatorArray) { for ( var j = 0; j < validatorArray.length; j = j + 1) { // do the validation if this element has a value // Don't just compare against "", since the value has // already been converted to a non-string type if ((value !== null) && !((typeof value == "string") && value == "")) { // evaluate the validator var validatorConstructor = validatorArray[j]; if (validatorConstructor && value !== undefined) { var validator = eval(validatorConstructor); try { validator.validate(value, label, converter); } catch (e) { // Populate the failureMap with the current error if (_agent.isPIE || _agent.isNokiaPhone || _agent.isBlackBerry) { inputFailures[inputFailures.length] = e.message; } else { inputFailures[inputFailures.length] = e.getFacesMessage(); } } } } } } } } // if there were failures, then add the current input to the failuresMap if (inputFailures.length > 0) { // TRINIDAD-123: Use input 'name' from validators array rather than currInput.id // to avoid issues with radio buttons having numeric id suffixes failureMap[id] = inputFailures; } } } return failureMap; } function _getGlobalErrorString( input, errorFormat, errorString, label ) { var form = _getForm(input); if (errorFormat && label != null) { return _formatErrorString(errorFormat, { "0":label, "1":errorString }); } return errorString; } /** * Returns true if the element is visible such that it could * receive focus or have its value selected, otherwise false. */ function _isShowing( input) { //PH: removed !input.focus because firstly, focus() function is supported by //all browsers (PIE,IEM,BB,FF,IE) and secondly, _isShowing should be treated //as a function to test visibility only. If there is a case where one really //wants to test whether focus function exists or not, do it in an if //statement and call _isShowing within it. if (input.type == 'hidden') return false; // determine visibility from style information if (_agent.isIEGroup) { var node = input; // IE does not give a "computed" style, so we // need to walk up the DOM to get the styles while (node != (void 0)) { computedStyle = node.currentStyle; if ((computedStyle != (void 0)) && ( (computedStyle["visibility"] == "hidden") || (computedStyle["display"] == "none"))) { // node or one of its parents parents are NOT showing return false; } // consider parent style node = node.parentNode; } // node and all parents are showing return true; } if (_agent.isGecko || _agent.isSafari || _agent.BlackBerry) { // Radio buttons: it'll be an array if (!input.ownerDocument && input.length) input = input[0]; var computedStyle = input.ownerDocument.defaultView.getComputedStyle(input, null); // either of these styles will prevent focus from succeeding return ((computedStyle["visibility"] != "hidden") && (computedStyle["display"] != "none")); } return true; } /** * Returns the id of an input element on either IE or Netscape, dealing * with the fact that Netscape doesn't support IDs locally. */ function _getID( input ) { //VAC- bug 4205372 for PIE devices return the name of the input element if (_agent.isPIE) { return input.name; } // for non-Netscape return the ID directly var id = input.id; var inputType = input.type; if (!inputType && input.length) inputType = input[0].type; // for radio buttons, return ID of enclosing if (inputType == "radio") { var inputParent; if (input.length) { inputParent = input[0].parentNode; if (inputParent.tagName == 'FIELDSET') inputParent = inputParent.parentNode; } else { inputParent = input.parentNode; } id = inputParent.id; } return id; } /** * Returns the form of an input element on either IE or Netscape, dealing * with the fact that radio inputs do not directly support the form attribute. */ function _getForm( input ) { var form = input.form; if (form == (void 0)) { // Try the first item of the array if (input.length) { form = input[0].form; } } return form; } /** * Returns the element of name elementName for the given form */ function _getFormElement( form, elementName) { var formElement = null; if (_agent.isPIE) { formElement = form.elements[elementName]; } else { formElement = form[elementName]; // To support required validation on shuttle component if(formElement == undefined) { formElement = form.elements[elementName+":trailing:items"]; } } return formElement; } /** * Returns the name of an input element on either IE or Netscape, dealing * with the fact that radio inputs do not directly support the name attribute. */ function _getName( input ) { var name = input.name; if (name == (void 0)) { var inputType = input.type; if (!inputType && input.length) inputType = input[0].type; // for radio buttons, return ID of enclosing if (inputType == "radio" && input.length) { name = input[0].name; } } return name; } /** * Return true if the object or any of its prototypes' * are an instance of the specified object type. */ function _instanceof( obj, // the object instance type // the constructor function ) { if (type == (void 0)) return false; if (obj == (void 0)) return false; while (typeof(obj) == "object") { if (obj.constructor == type) return true; // walk up the prototype hierarchy obj = obj.prototype; } return false; } /** * Return the formatted error string for an input field * and an errorFormatIndex */ function _getErrorString( input, label, defaultErrorFormat, validationError ) { var errorFormat; var form = _getForm(input); var value = _getValue(input); // use the message embedded in the validationError, if any if (_instanceof(validationError, window["TrConverterException"])) { errorFormat = validationError.getFacesMessage().getDetail(); } // use the message embedded in the validationError, if any else if (_instanceof(validationError, window["TrValidatorException"])) { errorFormat = validationError.getFacesMessage().getDetail(); } else { errorFormat = defaultErrorFormat; } if (errorFormat) { // format the error string, replacing the following tokens // {0} the value of the label // {1} the value of the input element var errorString = _formatErrorString(errorFormat, { "0":label, "1":value }); // return the error return errorString; } } /** * Returns the array of form validators. */ function _getValidators( form ) { return window["_" + _getJavascriptId(_getFormName(form)) + "_Validators"]; } /** * Performs token replacement on the the error format, replacing each * token found in the token Object with the value for that token. */ function _formatErrorString( errorFormat, // error format string with embedded tokens to be replaced tokens // tokens Object containin token names and values to be replaced ) { var currString = errorFormat; // loop through all of the tokens, replacing them if they are present for (var currToken in tokens) { var currValue = tokens[currToken]; // if the token has no value if (!currValue) { currValue = ""; } // TRINIDAD-829: // we replace '{' and '}' to ensure, that tokens containing values // like {3} aren't parsed more than once... // Only do this if it is typeof string (see TRINIDAD-873) if (typeof currValue == "string") { currValue = currValue.replace("{","{'"); currValue = currValue.replace("}","'}"); } // the tokens are delimited by '{' before and '}' after the token var currRegExp = "{" + currToken + "}"; // support tokens of the form %token% as well as {token} currString = currString.replace(new RegExp('%' + currToken + '%', 'g'), currRegExp); // Replace the token. Don't use String.replace, as the value may // include dollar signs, which leads Netscape astray (bug 2242675) var indexOf = currString.indexOf(currRegExp); if (currValue.indexOf && currValue.indexOf(currRegExp) >= 0) { var b1 = ''; for (i=0; i= 0) { currString=(currString.substring(0,indexOf) + b1 + currString.substring(indexOf+currRegExp.length)); indexOf = currString.indexOf(currRegExp); } indexOf = currString.indexOf(b1); while (indexOf >= 0) { currString =(currString.substring(0,indexOf) + currValue + currString.substring(indexOf+b1.length)); indexOf = currString.indexOf(b1); } } else while (indexOf >= 0) { currString = (currString.substring(0, indexOf) + currValue + currString.substring(indexOf + currRegExp.length)); indexOf = currString.indexOf(currRegExp); } } // TRINIDAD-829: // we finally re-replace the '{' and '}'... while(currString.indexOf("{'")!=-1) { currString= currString.replace("{'","{"); currString= currString.replace("'}","}"); } // And now take any doubled-up single quotes down to one, // to handle escaping var twoSingleQuotes = /''/g; return currString.replace(twoSingleQuotes, "'"); } /** * Chain two functions together returning whether the default * event handling should occur */ function _chain( evh1, // event handler 1 string evh2, // event handler 2 string target, // target of event event, // the fired event shortCircuit // shortcircuit if handler 1 false ) { return _chainMultiple([evh1, evh2], target, event, shortCircuit); } /** * Chain two or more functions together returning whether the default * event handling should occur */ function _chainMultiple( eventHandlers, // Array of event handler JavaScript strings target, // target of event event, // the fired event (or null) shortCircuit // shortcircuit if handler 1 false ) { var overallResult = true; for (var i = 0, size = eventHandlers.length; i < size; ++i) { var result = _callChained(eventHandlers[i], target, event); if (result === false) { if (shortCircuit) { return false; } overallResult = false; } } return overallResult; } function _callChained( handler, target, event ) { if (handler && (handler.length > 0)) { // handle ie case, where we have no event parameter if( (typeof(event) == 'undefined') || (event == (void 0) ) ) { event = window.event; } // create function so that "return" is handled correctly, // use event parameter so that both ie and netscape // functions work var func = new Function("event", handler); var result; // WindowsMobile 5 doesn't support installing Funtion object // to "this", so just invoke the Function object instead. if (_agent.isPIE) { result = func(event); } else { // install the function on the object so that "this" is // handled correctly target._tempFunc = func; // evaluate the result result = target._tempFunc(event); // clear the temporary function target._tempFunc = (void 0); } // undefined results should be evaluated as true, return !(result == false); } else { return true; } } // Enforce the maximum length of a form element // Returns true if event processing should continue, false otherwise. function _checkLength(formElement, length, event) { elementLength = formElement.value.length; if (elementLength > length) { // Input is longer than max, truncate and return false. // This takes care of the case where the user has pasted in text // that's too long. Return true here because the onChange event can // continue (now that we've truncated the value). This allows chained // handlers to work. formElement.value = formElement.value.substr(0, length); return true; } // If less than max length (i.e. within acceptable range), return true if (elementLength < length) return true; // If we've made it to here, we know that elementLength == length if (_agent.isIE) { // in many forms there is a hidden field named "event" // Sometimes IE gets confused and sends us that instead of // the true event, so... if (event["type"] == "hidden") event = window.event; } // If this is a change event, the field has already been updated to a string // of the maximum allowable length. This is fine. Continue processing. if (event.type == 'change') return true; // If we've made it to here, we know that this is a keyPress event // If the input is something less than a space (e.g. tab, CR, etc.) // return true. // If key was CTRL-v, which will be used to paste some new text, // pass it along. if (event) { if ((event.which < 32) || ((event.which == 118) && (event["ctrlKey"]))) return true; } // Default return FALSE. If we're here, this is an onKeyPress event, it's a // printable character, and elementLength already equals the maximum allowed. // We need to return false here to cancel the event otherwise this last // character will end up in the input field in position MAX+1. return false; } /** * Cover for document.getElementById that works on IE 4.x */ function _getElementById( doc, id ) { //PH: Since BB supports getDocumentById use this to obtain the element. if(typeof(doc.getElementById) != 'undefined') { // // If we arent' on Internet Explorers before 5, // use the DOM way of doing this // //PH:exclude BlackBerry if (((_agent.kind != "ie") || (_agent.version >= 5)) && (!_agent.isBlackBerry)) { var element = doc.getElementById(id); // IE's implementation of getElementById() is buggy. If // the page contains an anchor which has the same name // as the requested id, IE will return the anchor, even // if the anchor's id attribute is not set. So, make // sure that we actually get back an element with the // correct id. if ((element == null) || (element.id == id)) return element; // If we get here, that means that IE has probably returned // an anchor instead of the desired element. Let's scan // the entire DOM tree to find the element we want. return _findElementById(doc, id); } return doc.getElementById(id); } else if (typeof(doc.all) == 'undefined') { // Browser does not support getElementById nor DOM documnet.all object. // One example of such browser today is BlackBerry 4.0 browser. //if element is not within a form if(doc.forms.length == 0) return window[id]; else //check to see if element is within the form, if so return the element else do nothing for(var i = 0; i= 0) ? '&' : '?'; } /** * Adds a parameter to an existing URL, replacing the parameter if * it already exists */ function _addParameter( baseURL, paramName, paramValue ) { // check if we have parameters var queryIndex = baseURL.indexOf('?'); if (queryIndex == -1) { // no parameters, so append to parameters return baseURL + '?' + paramName + '=' + paramValue; } else { // check if the parameter already exists var paramIndex = baseURL.indexOf('?' + paramName + '=', queryIndex); if (paramIndex == -1) paramIndex = baseURL.indexOf('&' + paramName + '=', queryIndex + 1); if (paramIndex == -1) { // parameter isn't in the URL return baseURL + '&' + paramName + '=' + paramValue; } else { // // replace the value of the parameter // // the +2 skips over the '&' or '?' and the '=' var valueIndex = paramIndex + paramName.length + 2; // get the URL + the parameter var newString = baseURL.substring(0, valueIndex); // append the new value newString += paramValue; var lastIndex = baseURL.indexOf('&', valueIndex); if (lastIndex != -1) { // append the rest of the string after the replaced value newString += baseURL.substring(lastIndex); } return newString; } } } /** * Adds a parameter to the parameters object for form submission */ function _addFormParameter( parameters, paramName, paramValue ) { // Always create a new object, since we don't want to mess with // the caller's parameters var newParameters = new Object(); // Copy over existing parameters if (parameters) { for (var name in parameters) newParameters[name] = parameters[name]; } // Now set the new parameter value newParameters[paramName] = paramValue; return newParameters; } // // _pprInstallBlockingHandlers: Helps implement blocking // This function just installs or de-installs the // event consuming handlers. // function _pprInstallBlockingHandlers(win, install) { var doc = win.document; if (doc == (void 0)) return; // Some mobile browser do not support attaching event listner // to document if (!doc.attachEvent && !doc.addEventListener) { return; } if (doc.attachEvent) // IE { var el = win._pprConsumeFirstClick; if (install) { // See comment in _pprConsumeFirstClick(). // If the event that started this PPR chain was an onChange or onBlur, // AND the event location is the element on which the change happened // (i.e. the user didn't click somewhere outside the element) // then we want to make sure that the blocking starts immediately. var ev = win.event; if (ev != (void 0)) { var destElt = document.elementFromPoint(ev.x, ev.y); if (!win._pprFirstClickPass // never attach unless passing first click || (((ev.type == 'change') || (ev.type == 'blur')) && (ev.srcElement == destElt)) || (!_isSubmittingElement(destElt))) { _pprControlCapture(win, true); return; } } // If we're here, we didn't set up a capture. // For an onClick, we have to pass on the first click, // then we'll capture every subsequent event. doc.attachEvent('onclick', el); } else { doc.detachEvent('onclick', el); _pprControlCapture(win, false); } } else // Gecko or other standards based browser { var el = win._pprConsumeBlockedEvent; // Set up the same handler on all these events. The handler will just eat // the event unless it's the first click and we're passing that. var handlers = { 'click':1, 'keyup':1, 'keydown':1, 'keypress':1}; for (var h in handlers) { if (install) doc.addEventListener(h, el, true); else doc.removeEventListener(h, el, true); } } } // // _pprConsumeClick: Helps implement blocking. This function just consumes // every click that falls within the body. // function _pprConsumeClick(event) { if (_agent.isIE) { var body = document.body; if ((event.x < body.offsetLeft) || (event.y < body.offsetTop) || (event.x > body.offsetWidth) || (event.y > body.offsetHeight)) { // OK, we've caught an event outside the body of the document. Assume // that the user is clicking somewhere on the menu bar, or another // window. At this point, we release the mouse and continue (that's // better than keeping the user in limbo). _pprStopBlocking(window); } } return false; } // // _pprStartBlocking: Starts consuming every click (to implement blocking) // function _pprStartBlocking(win) { // No blocking is performed on WM, Nokia, PPC and BlackBerry devices if (_agent.isPIE || _agent.isNokiaPhone || _agent.isBlackBerry) return; if (_agent.isIE) { // see TRINIDAD-952 - IE does not update the activeElement in time before // blocking starts. Use a timeout to allow the update. win._pprTimeoutFunc = win.setTimeout("_doPprStartBlocking(window);", 1); return; } else { _doPprStartBlocking (win); } } function _doPprStartBlocking (win) { // Clean up timeout set in _pprStartBlocking() if (win._pprTimeoutFunc) { win.clearTimeout(win._pprTimeoutFunc); win._pprTimeoutFunc = null; } // In order to force the user to allow a PPR update to complete, we // block all mouse clicks between the start of a PPR update, and the end. // We do this by building a dummy DIV element and having it grab all clicks. // On Mozilla, we just expand it to cover the entire body as a glass frame. // On IE, we leave the DIV at zero size, but route every click to it. if (!win._pprBlocking) { var body = win.document.body; win._pprBlockStartTime = new Date(); // XXXSafari: What to do for Safari? Safari will probably work like gecko, // but... need to check. if (_agent.isGecko) { // If the user clicks the stop button, then we'll be stuck blocking. // So we don't hang, this timeout will clear the block in eight // seconds whether we've finished or not, but first we clear any // previously existing timeout. if (win._pprBlockingTimeout != null) { win.clearTimeout(win._pprBlockingTimeout); } win._pprBlockingTimeout = win.setTimeout("_pprStopBlocking(window);", 8000); } else if (_agent.isIEGroup) { // save off the element we'll return focus to _pprEventElement = window.document.activeElement; } _pprInstallBlockingHandlers(win, true); win._pprBlocking = true; } } // // _pprStopBlocking: Finishes up the blocking, releases the page back // to normal processing // function _pprStopBlocking(win) { // see TRINIDAD-1833. If _pprStartBlocking() was delayed with setTimeout(), // we need to clear it here. Otherwise _pprStartBlocking() will be called later, // and will end up winning if (win._pprTimeoutFunc) { win.clearTimeout(win._pprTimeoutFunc); win._pprTimeoutFunc = null; } // No blocking is performed on Nokia, PPC and BlackBerry devices if (_agent.isPIE || _agent.isNokiaPhone || _agent.isBlackBerry) return; var doc = win.document; if (win._pprBlocking) { // XXXSafari: What to do for Safari? Safari will probably work like gecko, // but... need to check. if (_agent.isGecko) { // If we've set a timeout, clear it now. if (win._pprBlockingTimeout != null) { win.clearTimeout(win._pprBlockingTimeout); win._pprBlockingTimeout == null; } } // and turn off the event capture _pprInstallBlockingHandlers(win, false); win._pprEventElement = null; win._pprBlocking = false; } win._pprBlocking = false; } /* * After updates we often can't just set focus to a node, it has to be prepared * in a browser specific way (different idosyncracies cause poor focus * behavior). */ function _pprFocus(node, doc) { if (_agent.isIEGroup) { // If the node's parent has changed through a DOM update then // this node hasn't been fully added to the tree yet so we // can't set focus to it. if (node.parentNode == null) return; // On IE, if a node has focus and we update it, then setting focus to it // seems to have no effect. Setting the focus to another node, then back to // the target seems to work correctly. Here we set the focus to a hidden // field. var divnode = _getElementById(doc, _pprdivElementName); if ((divnode) && (divnode["focus"])) divnode.focus(); } node.focus(); } // // _pprConsumeBlockedEvent: Helps implement blocking. This function attached // as the event handler. It just consumes every event // it gets. // // This function is used on standards based browsers. // function _pprConsumeBlockedEvent(evt) { var rv = true; if (_pprBlocking) { var blockTheEvent = true; if (window._pprFirstClickPass) { var newDate = new Date(); var diff = newDate - _pprBlockStartTime; // If we've got a click on a button (or an image within a link that does // a submit), less than 150ms after the beginning of a PPR update, assume // the user has started an onChange type event with a click on a button. // This addresses the problems that people were seeing, but could cause // overlapping PPR events in rare cases. var delay = 150; if ((diff < delay) && (evt.type == 'click')) { // To try to further limit the overlaps, we only allow clicks on // buttons, or images that will cause a submit to go through. // get the target of the click var orig = evt.explicitOriginalTarget; // this function is never called on IE, but if it were, this would be: // var orig = (_agent.isIE // ? evt.srcElement // : evt.explicitOriginalTarget); blockTheEvent = ! _isSubmittingElement(orig); } } if (blockTheEvent) { // just swallow the event evt.stopPropagation(); evt.preventDefault(); rv = false; } } return rv; } // // _pprConsumeFirstClick: Helps implement blocking. // // On IE, the capture doesn't allow us to hand off the first click - we can // only eat it, but attachEvent only allows us to do something with the event // AFTER it's been delivered to the element. There's no way to make a decision // whether or not to deliver a particular event. Therefore, since we want to // deliver the first click, and block everything else, we attachEvent using // this handler. This handler then just immediately switches over the the // capture. This function is only used on IE. // function _pprConsumeFirstClick(event) { // This is an IE only function if (_agent.isIE) { // switch over to capture _pprControlCapture(window, true); // and remove this one-time function window.document.detachEvent('onclick', _pprConsumeFirstClick); } return false; } // // _pprControlCapture: Set up the pprDivElement to capture all // mouse events. It will then ignore them. // function _pprControlCapture(win, set) { // This is an IE only function if (_agent.isIE) { var doc = win.document; var body = doc.body; var divElement = _getElementById(doc, _pprdivElementName); if (divElement) { if (set) { divElement.setCapture(); // If we've got an element to return focus to, // then capture keyboard events also. if (win._pprEventElement) divElement.focus(); // save current cursor and display a wait cursor win._pprSavedCursor = body.style.cursor; body.style.cursor = "wait"; win._pprSavedCursorFlag = true; } else if (win._pprSavedCursorFlag) { divElement.releaseCapture(); // return focus to the post-PPR target element if (win._pprEventElement) win._pprEventElement.focus(); body.style.cursor = win._pprSavedCursor; win._pprSavedCursor = null; win._pprSavedCursorFlag = false; } } } return; } // handle the onClick or onBlur for an IE SELECT element // Returns true if the user has finally made a selection, and is ready to go. function _pprChoiceAction() { // this function is only needed to handle IE's weird select element if (!_agent.isIE) return true; var rv = false; // This gets called as both onClick and onBlur, but both really only want // to submit the event if a change has been made. if ((!window._pprBlocking) && (_pprChoiceChanged)) { // clear the choice tracker _pprChoiceChanged = false; rv = true; } return rv; } // handle the onChange for an IE SELECT element function _pprChoiceChangeEvent(event) { if (!_agent.isIE) return true; // Just remember the fact that a change has occurred. if (!window._pprBlocking) _pprChoiceChanged = true; return true; } // Tests whether a partial submit should be performed function _supportsPPR() { return !_agent.pprUnsupported; } // Fires a PPR request entirely as a GET operation function _firePartialChange(url) { // FIXME: shouldn't be using a private method on TrPage - this should // really be made into a public API on TrPage var page = TrPage.getInstance(); var queue = page.getRequestQueue(); queue.sendRequest( page, page._requestStatusChanged, url); } // Fires a partial page request via form submission. // The args are the same as submitForm(). The // partialTargets are passed in as parameters function _submitPartialChange( form, doValidate, parameters, event) { // If there's no PPR iframe, then just perform a normal, // full-page submission. if (!_supportsPPR()) return submitForm(form, doValidate, parameters); // Get the actual form object if ((typeof form) == "string") form = document[form]; if (!form) return false; // Tack on the "partial" event parameter parameter parameters = _addFormParameter(parameters, "partial", "true"); // block all mouse clicks until the submit is done _pprStartBlocking(window); // Submit the form var submitted = submitForm(form, doValidate, parameters, true, event); // If the form wasn't actually submitted, update the ref count if (!submitted) { _pprStopBlocking(window); } } /* If the Trinidad facility needs to set focus to a particular node after a PPR * update, calling this function saves off the data needed to find that node * * Args: * doc : The document that the node lives in * nodeid : The id attached to the desired node * next : If true, we'll try to focus on the node following the one above, * otherwise, we'll try to focus on the requested node. */ function _setRequestedFocusNode(doc, nodeid, next, win) { // degenerate case - default to something that won't cause an error if (!win) win = window; // we only allow one outstanding focus request win._TrFocusRequestDoc = doc; win._TrFocusRequestID = nodeid; win._TrFocusRequestNext = (next == true); } /* If a request was made to focus on a particular node, this function will * attempt to get that node. */ function _getRequestedFocusNode(win) { // degenerate case - default to something that won't cause an error if (win == (void 0)) win = window; if ((win._TrFocusRequestDoc != null) && (win._TrFocusRequestID != null)) { var element = _getElementById(win._TrFocusRequestDoc, win._TrFocusRequestID); if (!element) return null; if (win._TrFocusRequestNext) { // If "next" was set, the caller doesn't want this node, but the next // one. Try to find something that'll accept focus. for (var next = element.nextSibling; next != null; next = next.nextSibling) { if (_isFocusable(next) // we actually DO want to "tab" to links || ((_agent.isIE) && (next.nodeName.toLowerCase() == 'a'))) { element = next; break; } } } return element; } return null; } // Returns the first focusable node under the specified node function _getFirstFocusable(node) { if ((node == null) || _isFocusable(node)) return node; if (node.hasChildNodes) { var children = node.childNodes; for (var i = 0; i < children.length; i++) { var child = children[i]; var firstFocusable = _getFirstFocusable(child); if (firstFocusable != null) return firstFocusable; } } return null; } // Restores the focus to the specified node function _restoreFocus(node, isFirstFocusable, doc) { if (node == null) return; // If we are in a scrolled DIV, restoring the focus to the // first focusable node may cause the DIV to scroll back to 0,0. // So, for now we just avoid restoring the focus in this situation. // In the future we should see less cases where scrolling occurs, // since we should do a better job locating the correct node to // receive the focus. var divNode = _getAncestorByName(node, "DIV"); if (!divNode) { _pprFocus(node, doc); } else { var scrollTop = divNode.scrollTop; var scrollLeft = divNode.scrollLeft; // If we aren't scrolled at all, or if we are restoring the // focus to the correct focusable owner (and not just the // first focusable node), then restore the focus. Otherwise, // we do nothing, in order to avoid unnecessary scrolling. if (((scrollTop == 0) && (scrollLeft == 0)) || !isFirstFocusable) { _pprFocus(node, doc); } } // Bug #2753958: IE doesn't seem to want to re-set the focus when we're // done with a PPR update if the input element happens to be enclosed // within a table. However, if we make a second request, the focus is set // correctly. This is limited to the one interesting case. if ((_agent.isIE) && (node.tagName == 'INPUT') && (_getAncestorByName(node, 'TABLE'))) { _pprFocus(node, doc); } } // Returns an ancestor with the specified name function _getAncestorByName( node, ancestorName ) { ancestorName = ancestorName.toUpperCase(); while (node) { if (ancestorName == node.nodeName) return node; node = node.parentNode; } return null; } // Tests whether one node is a descendent of another function _isDescendent( node, ancestorNode ) { if (node == null) return false; while (node.parentNode) { if (node == ancestorNode) return true; node = node.parentNode; } return false; } // Tests whether the specified node is focusable function _isFocusable(node) { if (node == null) return false; var name = node.nodeName.toLowerCase(); // Links that have a destination are generally focusable if (('a' == name) && (node.href)) { // We need to be careful on IE - it seems that // IE has problems setting the focus to links // which contain a single image. We see this when // IE tries to set the focus to the link around the // previous icon in the table. Actually, this does // not seem to be a problem if the link has its // id set, so we first check for that. // If we're not on IE, or if the link has an id, // the link should be focusable if (!_agent.isIE || (node.id)) return true; // If we're on IE, we only consider the link to be // focusable if it has something other than a single // image for its contents. var children = node.childNodes; if ((children) && (children.length == 1)) { var childName = children[0].nodeName; if ('img' == childName.toLowerCase()) return false; } return true; } // Blow off any disabled elements if (node.disabled) return false; // Input elements are also usually focusable if ('input' == name) { // But don't set the focus to hidden fields return (node.type != 'hidden'); } // Catch everything else here... return (('select' == name) || ('button' == name) || ('textarea' == name)); } // Evaluates the specified code in the target window function _eval(targetWindow, code) { if (code == null) return; // For IE, we use window.execScript(). For Mozilla, we use // window.eval(). It would be nice if we could use eval() on // IE too, but IE's implementation of eval() always executes // the script in the current context, even if some other // window is specified. if (_agent.isIEGroup) { targetWindow.execScript(code); } else targetWindow.eval(code); } /** * Called to identify the input field from an event * This is called not only below, but also from LovInput.js. */ function _getInputField(event) { var input = (void 0); var src = (void 0); if (window.event) { kc = window.event.keyCode; src = window.event.srcElement; } else if (event) { kc = event.which; src = event.target; } if (src != (void 0) && (src.tagName == "INPUT" || src.tagName == "TEXTAREA" )) input = src; return input; } /** * Called when a field receives focus. * Prepares for a later reset of this field by saving its current value. */ function _enterField( event ) { var input; var src; var retv = true; var input = _getInputField(event); if (input != (void 0)) { input.form._mayResetByInput = false; // save the last valid value for later restoration input._validValue = input.value; retv = false; } return retv; } /** * Resets the form input to its last valid value. * This function is called from the onKeyDown for a form input. * If called twice in succession for the same form, with the * escape keycode both times, this function will reset the form. */ function _resetOnEscape(event) { var kc; var input = _getInputField(event); if (input != (void 0)) { var form = input.form; if (kc == 27) // escape keycode { // reset the form input to its last valid value // providing there is no selection (consistent with IE) var hasSelection = false; if ((input.selectionStart != (void 0)) && (input.selectionEnd != (void 0))) { hasSelection = (input.selectionStart != input.selectionEnd); } else if (document.selection) { hasSelection = (document.selection.createRange().text.length != 0); } if (!hasSelection) { // always reset the field input.value = input._validValue; // determine if a full form reset is required if (form._mayResetByInput == true) { // reset the form // unset the flag for form reset form.reset(); form._mayResetByInput = false; } else { // set the flag for form reset form._mayResetByInput = true; } } // consume this event to prevent any browser behavior from kicking in return false; } else // any keycode other than escape { // unset the flag for form reset // since some other key was pressed form._mayResetByInput = false; } } return true; } /**PH: Currently, if a browser supports PPR, the _checkLoad function * is set as the body onload to perform some initialization, both PPR related * and not (such as setting the initial focus). * Because this function was not called for non-PPR browsers (like BlackBerry * 4.0), the non-PPR initialization was not happening on those browsers. * Therefore, I created another function called _checkLoadNoPPR to handle * non-PPR related initialization, such as setting the initialFocus, and * set the body onload to this method for browsers that do not support PPR. */ function _checkLoadNoPPR() { if(_initialFocusID != null) _setFocus(_getElementById(document,_initialFocusID)); _agent.pprUnsupported = true; } /** * Called by the load handler of each document body to prepare event handlers * for forms, etc. */ function _checkLoad() { // set focus to the window if a dialog. This fixes the bug where our dialog // windows don't have focus, so the first keystroke is ignored. 3544304 // if I used window.focus(), I caused this bug 3876472 - // PAGES COME TO THE FOREGROUND WHEN THE PAGE LOADS // We are using _pprdivElementName cuz we need an empty div to set focus // to. If we get rid of this element, we'll need to set focus to // another element that we know is always on the page. // This was causing focus to go off and NEVER COME BACK in the shopping cart // demo. I think we can limit this to just a dialog if we can detect that // we're in one. For now, we'll have to live with the extra keystroke. /* if (_agent.isIE) { var divElement = _getElementById(document, _pprdivElementName); if (divElement && divElement.focus) divElement.focus(); } */ // IE has a document.activeElement property. Most other // browsers do not (though Firefox 3.0 will). if (!_agent.isIEGroup && document.addEventListener) { document.addEventListener("keyup", _trTrackActiveElement, false); document.addEventListener("mousedown", _trTrackActiveElement, false); } if (document.forms) { for (var i = 0; i < document.forms.length; i++) { var form = document.forms[i]; // Note: event listener functions must already be defined above // no forward references if (form.addEventListener) // DOM events { form.addEventListener('focus', _enterField, true); form.addEventListener('keydown', _resetOnEscape, true); } else if (form.attachEvent) // IE5 events { form.attachEvent('onfocusin', _enterField); form.attachEvent('onkeydown', _resetOnEscape); } } } // If we're inside a frameset, and the top frame wants // reloads blocked, install a _noReload handler. var topWindow = _getTop(self); if ((self != topWindow) && topWindow["_blockReload"]) { document.onkeydown = _noReload; } // Set initialFocus if necessary if ((!_agent.isNav) && (_initialFocusID != null)) { var myElement = _getElementById(document,_initialFocusID); //PH: Set Focus on element for all browsers. if(myElement) _setFocus(myElement); } // Initialize ourselves if we're in a PopupDialog except for Nokia if (!_agent.isNokiaPhone) { TrPopupDialog._initDialogPage(); } } function _getActiveElement() { if (document.activeElement) return document.activeElement; return window._trActiveElement; } function _trTrackActiveElement(e) { window._trActiveElement = e.target; } // // Event handle that blocks keys that lead to a page reloading. // function _noReload(e) { if (!e) e=window.event; var kc=e.keyCode; // F5 and Ctrl-R if ((kc==116)||(kc==82 && e.ctrlKey)) { if (e.preventDefault) e.preventDefault(); e.keyCode=0; return false; } } // // Deliver a client event with the specified type, source and parameters // to the handler body. // function _handleClientEvent(type, source, params, handlerBody) { var event = new Object(); event.type = type; event.source = source; event.params = params; var func = new Function("event", handlerBody); return func(event); } // // APIs dealing with cookies. We currently have no supported // public functions. _getCookie() and _setCookie() are good candidates. // function _getCookie(name) { var dc = document.cookie; var value = ""; var prefix = name + "="; if (dc) { // Look for the cookie name in in the middle. var begin = dc.indexOf("; " + prefix); if (begin < 0) { // Not there: look for it at the beginning begin = dc.indexOf(prefix); if (begin > 0) begin = -1; } else // Found it - now skip over the colon and space begin += 2; if (begin >= 0) { var end = dc.indexOf(";", begin); if (end < 0) end = dc.length; value = unescape(dc.substring(begin + name.length + 1, end)); } } return value; } // // Sets a cookie value. // This function isn't especially general (yet) as it doesn't // allow overriding the domain, path, or expiry. // function _setCookie(name, value) { // Compute the domain to scope as widely as is legit // by scoping off. // =-=AEW "localhost" just doesn't work. I don't know how to // deal with this... It'll confuse developers, even though // it will never have any real impact. var domain = window.location.host; /* =-=AEW The current Oracle Cookie design guidelines require cookies to _not_ be scoped widely. So don't! var periodIndex = domain.indexOf("."); if ((periodIndex >= 0) && (domain.lastIndexOf(".") != periodIndex)) { // But don't scope off anything that's entirely a number, // since then we're probably dealing with an IP address var startOfDomain = domain.substr(0, periodIndex); if (!(((startOfDomain * startOfDomain) == 0) || ((startOfDomain / startOfDomain) == 1))) domain = domain.substr(periodIndex); } */ var colonIndex = domain.indexOf(":"); if (colonIndex >= 0) domain = domain.substr(0, colonIndex); // Expire 10 years after today var expires = new Date(); expires.setFullYear(expires.getFullYear() + 10); // And here's the cookie: // (Reordering the parameters seemed to break some browsers) var curCookie = name + "=" + value + "; path=/;domain=" + domain + "; expires=" + expires.toGMTString(); document.cookie = curCookie; } // // Compute the time zone ID, of form GMT+-XX:YY // function _getTimeZoneID() { // Get the time zone offset, then flip the sign, as this // is opposite in meaning to the time zone ID var tzOffset = -(new Date()).getTimezoneOffset(); var newTZ; // Build up the name of the time zone if (tzOffset > 0) newTZ = "GMT+"; else { newTZ = "GMT-"; tzOffset = -tzOffset; } var minutes = "" + tzOffset % 60; if (minutes.length == 1) minutes = "0" + minutes; return (newTZ + (Math.floor(tzOffset / 60)) + ":" + minutes); } // // Returns true if the current document reads left to right. // function _isLTR() { return document.documentElement["dir"].toUpperCase() == "LTR"; } // // _isSubmittingElement : Is the given element likely to submit? // function _isSubmittingElement(element) { var isSub = false; var eltype = element.nodeName.toUpperCase(); // Assume any button click is wanted if (eltype == "BUTTON") { isSub = true; } else if (eltype == "IMG") { // If the click was on an image, check to see if the image // is inside a link element. var pnode = element.parentNode; var ptype = pnode.nodeName.toUpperCase(); if (('A' == ptype) && (pnode.href)) { // OK, it's a link, now check if the onClick goes to one of our // submit functions. var oc = "" + pnode["onclick"]; if ((oc != (void 0)) && (oc != null)) { isSub = ((oc.indexOf("submitForm") > 0) || (oc.indexOf("_uixspu") > 0) || (oc.indexOf("_adfspu") > 0) || (oc.indexOf("_addRowSubmit") > 0)); } } } return isSub; } // Get the keycode from an event function _getKC(event) { if (window.event) return window.event.keyCode; else if (event) return event.which; return -1; } // Returns true if a form has been submitted a "short" time before newDate function _recentSubmit(newDate) { if (_lastDateSubmitted) { var diff = newDate - _lastDateSubmitted; if ((diff >= 0) && (diff < 200)) return true; } return false; } // Returns true if a form has been reset a "short" time before newDate function _recentReset(newDate) { if (_lastDateReset) { var diff = newDate - _lastDateReset; if ((diff >= 0) && (diff < 200)) return true; } return false; } function _radioSet_uixspu(f,v,e,s,pt,p,o) { _radioSet_adfspu(f,v,e,s,o); } function _radioSet_adfspu(f,v,e,s,o) { if (window._pprBlocking) return; // Once again we've got timing issues. When the user clicks on the // text of a radio button, we get an onClick for the enclosing span before we // get the onClick for the button itself. This wouldn't be so bad if the // selected state was already changed, but it isn't. So we have to send the // second click if there is one, otherwise we have to send the first (only) // click. There's already code in submitForm to check for multiple submits // within 200ms, so we just send the first click after waiting 200ms. // // Of course the obvious answer to this is to use onChange instead of // onClick, but IE doesn't deliver onChange events to the container if (_pendingRadioButton) { // This is the second onClick call. We want to run the call to adfspu. // Eventually submitform will be called, do a submit, and set the // _lastDateSubmitted. // clear the pending flag for next time _pendingRadioButton = false; // and call _adfspu(f,v,e,s,o); } else { // This is the first click. // Remember that we've got a pending click. _pendingRadioButton = true; // Now build up a string representation of the call, // and put it into a timeout. // clear the pending flag for next time - in case there was no second click. var spucall = "_pendingRadioButton=false;_adfspu("; // Form if ((f != (void 0)) && (f != null)) spucall += "'" + f + "'"; spucall += ","; // Validation if (v != (void 0)) spucall += v; spucall += ","; // Event if ((e != (void 0)) && (e != null)) spucall += "'" + e + "'"; spucall += ","; // Source if ((s != (void 0)) && (s != null)) spucall += "'" + s + "'"; // RadioSet does not pass an object spucall += ");"; window.setTimeout(spucall, 200); } } /** This function is called from _spinboxRepeat. * This function increments or decrements the value that is in the * input field by the stepSize. If the max/min is reached, check circular. * If circular is true, then circle the number around. * we default circular for now, because we do not support it yet. * Else, stop at the max or min. */ function _stepSpinboxValue(id, increment, stepSize, min, max) { var circular = false; var input = _getElementById(document, id); if (input) { var value = input.value; if (isNaN(value) || isNaN(stepSize) || isNaN(min) || isNaN(max)) { alert("value, stepSize, min, and max must all be numbers. value: "+ value+", stepSize: "+stepSize+", min: "+min+", max: "+max); return false; } if (increment) { var incrementedValue = parseFloat(value) + parseFloat(stepSize); if (incrementedValue < max) input.value = incrementedValue; else if (circular) input.value = min; else input.value = max; } else { var decrementedValue = parseFloat(value) - parseFloat(stepSize); if (decrementedValue > min) input.value = decrementedValue; else if (circular) input.value = max; else input.value = min; } return true; } return false; } /* This function is called when the inputNumberSpinbox component's spinbox * buttons are released (onmouseup). * This function stops the spinboxTimer. * The spinboxTimer calls _stepSpinboxValue in one second increments. */ function _clearSpinbox() { window.clearTimeout(_spinboxRepeat.timer); _spinboxRepeat.functionString = null; } /** * This function is called when the inputNumberSpinbox component's * spinbox buttons are pressed. This is called onmousedown. * It calls the _stepSpinboxValue function to increment or decrement * the input element's value. We call this repeatedly every second. * onmouseup the component calls _clearSpinbox which clears the timeout. */ function _spinboxRepeat(id, increment, stepSize, min, max) { // increment/decrement var success = _stepSpinboxValue(id, increment, stepSize, min, max); // if not successful, then clear the timeout and return if (!success) { window.clearTimeout(_spinboxRepeat.timer); } else { if (_spinboxRepeat.functionString == null) { // setup the function to pass to the timeout. _spinboxRepeat.functionString = "_spinboxRepeat('"+id+"',"+increment+ ","+stepSize+","+min+","+max+");"; } _spinboxRepeat.timer = window.setTimeout(_spinboxRepeat.functionString, 1000); } } //PH:This method returns the 'event' object function _getEventObj() { if(typeof(event) == 'undefined') return window.event; else return event; return null; } //*********************************************************** // "Object Oriented" js below //*********************************************************** /** * User interfaces utility methods */ var TrUIUtils = new Object(); /** * Creates a function instance that will callback the passed in function * with "thisObj" as "this". This is extremely useful for creating callbacks */ TrUIUtils.createCallback = function(thisObj, func) { // create a function that sets up "this" and delegates all of the parameters // to the passed in function var proxyFunction = new Function( "var f=arguments.callee; return f._func.apply(f._owner, arguments);"); // attach ourselves as "this" to the created function proxyFunction._owner = thisObj; // attach function to delegate to proxyFunction._func = func; 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; if (doc.getBoxObjectFor === undefined) { var boundingRect = elem.getBoundingClientRect(); // top and bottom are not rounded off in Gecko1.9 // http://www.quirksmode.org/dom/w3c_cssom.html#elementviewm var elemTop = Math.round(boundingRect.top); var elemLeft = boundingRect.left; var docElement = doc.documentElement; // clientLeft and clientTop would be 0 for Gecko1.9 // https://bugzilla.mozilla.org/show_bug.cgi?id=174397#c34 elemLeft += docElement.scrollLeft; elemTop += docElement.scrollTop; return {x:elemLeft, y:elemTop}; } else { 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 ''; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy