B2G/gecko/browser/base/content/browser.js
/**
 * Content area tooltip.
 * XXX - this must move into XBL binding/equiv! Do not want to pollute
 *       browser.js with functionality that can be encapsulated into
 *       browser widget. TEMPORARY!
 *
 * NOTE: Any changes to this routine need to be mirrored in DefaultTooltipTextProvider::GetNodeText()
 *       (located in mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp)
 *       which performs the same function, but for embedded clients that
 *       don't use a XUL/JS layer. It is important that the logic of
 *       these two routines be kept more or less in sync.
 *       (pinkerton)
 **/
Content area tooltip.
XXX - this must move into XBL binding/equiv. Do not want to pollute
browser.js with functionality that can be encapsulated into
browser widget. TEMPORARY!


Content area tooltip . XXX - this must move into XBL binding / equiv . Do not want to pollute browser . js with functionality that can be encapsulated into browser widget . TEMPORARY!
function FillInHTMLTooltip(tipElement)
{
  var retVal = false;
  if (!tipElement.ownerDocument ||
      (tipElement.ownerDocument.compareDocumentPosition(tipElement) & document.DOCUMENT_POSITION_DISCONNECTED))
    return retVal;
  const XLinkNS = "http://www.w3.org/1999/xlink";
  const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  var titleText = null;
  var XLinkTitleText = null;
  var SVGTitleText = null;
  var lookingForSVGTitle = true;
  var direction = tipElement.ownerDocument.dir;
  if ((tipElement instanceof HTMLInputElement ||
       tipElement instanceof HTMLTextAreaElement ||
       tipElement instanceof HTMLSelectElement ||
       tipElement instanceof HTMLButtonElement) &&
      !tipElement.hasAttribute('title') &&
      (!tipElement.form || !tipElement.form.noValidate)) {
    titleText = tipElement.validationMessage;
  }
  while (!titleText && !XLinkTitleText && !SVGTitleText && tipElement) {
    if (tipElement.nodeType == Node.ELEMENT_NODE &&
        tipElement.namespaceURI != XULNS) {
      titleText = tipElement.getAttribute("title");
      if ((tipElement instanceof HTMLAnchorElement ||
           tipElement instanceof HTMLAreaElement ||
           tipElement instanceof HTMLLinkElement ||
           tipElement instanceof SVGAElement) && tipElement.href) {
        XLinkTitleText = tipElement.getAttributeNS(XLinkNS, "title");
      }
      if (lookingForSVGTitle &&
          (!(tipElement instanceof SVGElement) ||
           tipElement.parentNode.nodeType == Node.DOCUMENT_NODE)) {
        lookingForSVGTitle = false;
      }
      if (lookingForSVGTitle) {
        for (let childNode of tipElement.childNodes) {
          if (childNode instanceof SVGTitleElement) {
            SVGTitleText = childNode.textContent;
            break;
          }
        }
      }
      var defView = tipElement.ownerDocument.defaultView;
      if (!defView)
        return retVal;
      direction = defView.getComputedStyle(tipElement, "")
        .getPropertyValue("direction");
    }
    tipElement = tipElement.parentNode;
  }
  var tipNode = document.getElementById("aHTMLTooltip");
  tipNode.style.direction = direction;
  [titleText, XLinkTitleText, SVGTitleText].forEach(function (t) {
    if (t && /\S/.test(t)) {
      t = t.replace(/\r\n?/g, '\n');
      tipNode.setAttribute("label", t);
      retVal = true;
    }
  });
  return retVal;
}
function FillInHTMLTooltip ( tipElement ) { var retVal = false ; if ( ! tipElement . ownerDocument || ( tipElement . ownerDocument . compareDocumentPosition ( tipElement ) & document . DOCUMENT_POSITION_DISCONNECTED ) ) return retVal ; const XLinkNS = "http://www.w3.org/1999/xlink" ; const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" ; var titleText = null ; var XLinkTitleText = null ; var SVGTitleText = null ; var lookingForSVGTitle = true ; var direction = tipElement . ownerDocument . dir ; if ( ( tipElement instanceof HTMLInputElement || tipElement instanceof HTMLTextAreaElement || tipElement instanceof HTMLSelectElement || tipElement instanceof HTMLButtonElement ) && ! tipElement . hasAttribute ( 'title' ) && ( ! tipElement . form || ! tipElement . form . noValidate ) ) { titleText = tipElement . validationMessage ; } while ( ! titleText && ! XLinkTitleText && ! SVGTitleText && tipElement ) { if ( tipElement . nodeType == Node . ELEMENT_NODE && tipElement . namespaceURI != XULNS ) { titleText = tipElement . getAttribute ( "title" ) ; if ( ( tipElement instanceof HTMLAnchorElement || tipElement instanceof HTMLAreaElement || tipElement instanceof HTMLLinkElement || tipElement instanceof SVGAElement ) && tipElement . href ) { XLinkTitleText = tipElement . getAttributeNS ( XLinkNS , "title" ) ; } if ( lookingForSVGTitle && ( ! ( tipElement instanceof SVGElement ) || tipElement . parentNode . nodeType == Node . DOCUMENT_NODE ) ) { lookingForSVGTitle = false ; } if ( lookingForSVGTitle ) { for ( let childNode of tipElement . childNodes ) { if ( childNode instanceof SVGTitleElement ) { SVGTitleText = childNode . textContent ; break ; } } } var defView = tipElement . ownerDocument . defaultView ; if ( ! defView ) return retVal ; direction = defView . getComputedStyle ( tipElement , "" ) . getPropertyValue ( "direction" ) ; } tipElement = tipElement . parentNode ; } var tipNode = document . getElementById ( "aHTMLTooltip" ) ; tipNode . style . direction = direction ; [ titleText , XLinkTitleText , SVGTitleText ] . forEach ( function ( t ) { if ( t && / \S / . test ( t ) ) { t = t . replace ( / \r\n? / g , '\n' ) ; tipNode . setAttribute ( "label" , t ) ; retVal = true ; } } ) ; return retVal ; }
Content area tooltip.
Content area tooltip .
// Don't show the tooltip if the tooltip node is a document or disconnected. // If the element is invalid per HTML5 Forms specifications and has no title, // show the constraint validation error message. // If the element is barred from constraint validation or valid, // the validation message will be the empty string. // XXX Work around bug 350679: // "Tooltips can be fired in documents with no view". // Make CRLF and CR render one line break each.