Пример #1
0
bool
nsIConstraintValidation::ReportValidity()
{
  if (!IsCandidateForConstraintValidation() || IsValid()) {
    return true;
  }

  nsCOMPtr<nsIContent> content = do_QueryInterface(this);
  MOZ_ASSERT(content, "This class should be inherited by HTML elements only!");

  bool defaultAction = true;
  nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(), content,
                                       NS_LITERAL_STRING("invalid"),
                                       false, true, &defaultAction);
  if (!defaultAction) {
    return false;
  }

  nsCOMPtr<nsIObserverService> service =
    mozilla::services::GetObserverService();
  if (!service) {
    NS_WARNING("No observer service available!");
    return true;
  }

  nsCOMPtr<nsISimpleEnumerator> theEnum;
  nsresult rv = service->EnumerateObservers(NS_INVALIDFORMSUBMIT_SUBJECT,
                                            getter_AddRefs(theEnum));

  // Return true on error here because that's what we always did
  NS_ENSURE_SUCCESS(rv, true);

  bool hasObserver = false;
  rv = theEnum->HasMoreElements(&hasObserver);

  nsCOMPtr<nsIMutableArray> invalidElements =
    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
  invalidElements->AppendElement(content, false);

  NS_ENSURE_SUCCESS(rv, true);
  nsCOMPtr<nsISupports> inst;
  nsCOMPtr<nsIFormSubmitObserver> observer;
  bool more = true;
  while (NS_SUCCEEDED(theEnum->HasMoreElements(&more)) && more) {
    theEnum->GetNext(getter_AddRefs(inst));
    observer = do_QueryInterface(inst);

    if (observer) {
      observer->NotifyInvalidSubmit(nullptr, invalidElements);
    }
  }

  if (content->IsHTMLElement(nsGkAtoms::input) &&
      nsContentUtils::IsFocusedContent(content)) {
    HTMLInputElement* inputElement =
    HTMLInputElement::FromContentOrNull(content);

    inputElement->UpdateValidityUIBits(true);
  }

  dom::Element* element = content->AsElement();
  element->UpdateState(true);
  return false;
}
bool
nsIConstraintValidation::ReportValidity()
{
  if (!IsCandidateForConstraintValidation() || IsValid()) {
    return true;
  }

  nsCOMPtr<Element> element = do_QueryInterface(this);
  MOZ_ASSERT(element, "This class should be inherited by HTML elements only!");

  bool defaultAction = true;
  nsContentUtils::DispatchTrustedEvent(element->OwnerDoc(), element,
                                       NS_LITERAL_STRING("invalid"),
                                       CanBubble::eNo,
                                       Cancelable::eYes,
                                       &defaultAction);
  if (!defaultAction) {
    return false;
  }

  AutoTArray<RefPtr<Element>, 1> invalidElements;
  invalidElements.AppendElement(element);

  AutoJSAPI jsapi;
  if (!jsapi.Init(element->GetOwnerGlobal())) {
    return false;
  }
  JS::Rooted<JS::Value> detail(jsapi.cx());
  if (!ToJSValue(jsapi.cx(), invalidElements, &detail)) {
    return false;
  }

  RefPtr<CustomEvent> event = NS_NewDOMCustomEvent(element->OwnerDoc(),
                                                   nullptr, nullptr);
  event->InitCustomEvent(jsapi.cx(),
                         NS_LITERAL_STRING("MozInvalidForm"),
                         /* CanBubble */ true,
                         /* Cancelable */ true,
                         detail);
  event->SetTrusted(true);
  event->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true;

  element->DispatchEvent(*event);

  nsCOMPtr<nsIObserverService> service =
    mozilla::services::GetObserverService();
  if (!service) {
    NS_WARNING("No observer service available!");
    return true;
  }

  nsCOMPtr<nsISimpleEnumerator> theEnum;
  nsresult rv = service->EnumerateObservers(NS_INVALIDFORMSUBMIT_SUBJECT,
                                            getter_AddRefs(theEnum));

  // Return true on error here because that's what we always did
  NS_ENSURE_SUCCESS(rv, true);

  bool hasObserver = false;
  rv = theEnum->HasMoreElements(&hasObserver);

  NS_ENSURE_SUCCESS(rv, true);
  nsCOMPtr<nsISupports> inst;
  nsCOMPtr<nsIFormSubmitObserver> observer;
  bool more = true;
  while (NS_SUCCEEDED(theEnum->HasMoreElements(&more)) && more) {
    theEnum->GetNext(getter_AddRefs(inst));
    observer = do_QueryInterface(inst);

    if (observer) {
      observer->NotifyInvalidSubmit(nullptr, invalidElements);
    }
  }

  if (element->IsHTMLElement(nsGkAtoms::input) &&
      // We don't use nsContentUtils::IsFocusedContent here, because it doesn't
      // really do what we want for number controls: it's true for the
      // anonymous textnode inside, but not the number control itself.  We can
      // use the focus state, though, because that gets synced to the number
      // control by the anonymous text control.
      element->State().HasState(NS_EVENT_STATE_FOCUS)) {
    HTMLInputElement* inputElement = HTMLInputElement::FromNode(element);
    inputElement->UpdateValidityUIBits(true);
  }

  element->UpdateState(true);
  return false;
}