stance(tipElement) ||
          defView.HTMLButtonElement.isInstance(tipElement)) &&
        !tipElement.form?.noValidate
      ) {
        // If the element is barred from constraint validation or valid,
        // the validation message will be the empty string.
        titleText = tipElement.validationMessage || null;
      }

      // If the element is an <input type='file'> without a title, we should show
      // the current file selection.
      if (
        titleText == null &&
        defView.HTMLInputElement.isInstance(tipElement) &&
        tipElement.type == "file"
      ) {
        try {
          titleText = getFileInputTitleText(tipElement);
        } catch (ex) {}
      }

      if (
        lookingForSVGTitle &&
        tipElement.parentNode.nodeType != defView.Node.DOCUMENT_NODE
      ) {
        for (let childNode of tipElement.childNodes) {
          if (defView.SVGTitleElement.isInstance(childNode)) {
            titleText = childNode.textContent;
            break;
          }
        }
      }

      // Check texts against null so that title="" can be used to undefine a
      // title on a child element.
      if (titleText != null || XLinkTitleText != null) {
        break;
      }
    }

    return [titleText, XLinkTitleText].some(function (t) {
      if (t && /\S/.test(t)) {
        // Make CRLF and CR render one line break each.
        textOut.value = t.replace(/\r\n?/g, "\n");

        if (tipElement) {
          direction = defView
            .getComputedStyle(tipElement)
            .getPropertyValue("direction");
        }

        directionOut.value = direction;
        return true;
      }

      return false;
    });
  },

  classID: Components.ID("{f376627f-0bbc-47b8-887e-fc92574cc91f}"),
  QueryInterface: ChromeUtils.generateQI(["nsITooltipTextProvider"]),
};
PK