Quellcode-Bibliothek ElementInternals.cpp
Sprache: C
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/** * 1. Let element be this's target element. * 2. If element is not a form-associated custom element, then throw a * "NotSupportedError" DOMException.
*/ if (!mTarget->IsFormAssociatedElement()) {
aRv.ThrowNotSupportedError( "Target element is not a form-associated custom element"); return;
}
/** * 3. Set target element's submission value to value if value is not a * FormData object, or to a clone of the entry list associated with value * otherwise.
*/
mSubmissionValue.SetNull(); if (!aValue.IsNull()) { const FileOrUSVStringOrFormData& value = aValue.Value();
OwningFileOrUSVStringOrFormData& owningValue = mSubmissionValue.SetValue(); if (value.IsFormData()) {
owningValue.SetAsFormData() = value.GetAsFormData().Clone();
} elseif (value.IsFile()) {
owningValue.SetAsFile() = &value.GetAsFile();
} else {
owningValue.SetAsUSVString() = value.GetAsUSVString();
}
}
/** * 4. If the state argument of the function is omitted, set element's state to * its submission value.
*/ if (!aState.WasPassed()) {
mState = mSubmissionValue; return;
}
/** * 5. Otherwise, if state is a FormData object, set element's state to clone * of the entry list associated with state. * 6. Otherwise, set element's state to state.
*/
mState.SetNull(); if (!aState.Value().IsNull()) { const FileOrUSVStringOrFormData& state = aState.Value().Value();
OwningFileOrUSVStringOrFormData& owningState = mState.SetValue(); if (state.IsFormData()) {
owningState.SetAsFormData() = state.GetAsFormData().Clone();
} elseif (state.IsFile()) {
owningState.SetAsFile() = &state.GetAsFile();
} else {
owningState.SetAsUSVString() = state.GetAsUSVString();
}
}
}
if (!mTarget->IsFormAssociatedElement()) {
aRv.ThrowNotSupportedError( "Target element is not a form-associated custom element"); return nullptr;
} return GetForm();
}
/** * 1. Let element be this's target element. * 2. If element is not a form-associated custom element, then throw a * "NotSupportedError" DOMException.
*/ if (!mTarget->IsFormAssociatedElement()) {
aRv.ThrowNotSupportedError( "Target element is not a form-associated custom element"); return;
}
/** * 3. If flags contains one or more true values and message is not given or is * the empty string, then throw a TypeError.
*/ if ((aFlags.mBadInput || aFlags.mCustomError || aFlags.mPatternMismatch ||
aFlags.mRangeOverflow || aFlags.mRangeUnderflow ||
aFlags.mStepMismatch || aFlags.mTooLong || aFlags.mTooShort ||
aFlags.mTypeMismatch || aFlags.mValueMissing) &&
(!aMessage.WasPassed() || aMessage.Value().IsEmpty())) {
aRv.ThrowTypeError("Need to provide validation message"); return;
}
/** * 4. For each entry flag → value of flags, set element's validity flag with * the name flag to value.
*/
SetValidityState(VALIDITY_STATE_VALUE_MISSING, aFlags.mValueMissing);
SetValidityState(VALIDITY_STATE_TYPE_MISMATCH, aFlags.mTypeMismatch);
SetValidityState(VALIDITY_STATE_PATTERN_MISMATCH, aFlags.mPatternMismatch);
SetValidityState(VALIDITY_STATE_TOO_LONG, aFlags.mTooLong);
SetValidityState(VALIDITY_STATE_TOO_SHORT, aFlags.mTooShort);
SetValidityState(VALIDITY_STATE_RANGE_UNDERFLOW, aFlags.mRangeUnderflow);
SetValidityState(VALIDITY_STATE_RANGE_OVERFLOW, aFlags.mRangeOverflow);
SetValidityState(VALIDITY_STATE_STEP_MISMATCH, aFlags.mStepMismatch);
SetValidityState(VALIDITY_STATE_BAD_INPUT, aFlags.mBadInput);
SetValidityState(VALIDITY_STATE_CUSTOM_ERROR, aFlags.mCustomError);
mTarget->UpdateValidityElementStates(true);
/** * 5. Set element's validation message to the empty string if message is not * given or all of element's validity flags are false, or to message * otherwise. * 6. If element's customError validity flag is true, then set element's * custom validity error message to element's validation message. * Otherwise, set element's custom validity error message to the empty * string.
*/
mValidationMessage =
(!aMessage.WasPassed() || IsValid()) ? EmptyString() : aMessage.Value();
/** * 7. Set element's validation anchor to null if anchor is not given. * Otherwise, if anchor is not a shadow-including descendant of element, * then throw a "NotFoundError" DOMException. Otherwise, set element's * validation anchor to anchor.
*/
nsGenericHTMLElement* anchor =
aAnchor.WasPassed() ? &aAnchor.Value() : nullptr; // TODO: maybe create something like IsShadowIncludingDescendantOf if there // are other places also need such check. if (anchor && (anchor == mTarget ||
!anchor->IsShadowIncludingInclusiveDescendantOf(mTarget))) {
aRv.ThrowNotFoundError( "Validation anchor is not a shadow-including descendant of target" "element"); return;
}
mValidationAnchor = anchor;
}
if (!mTarget->IsFormAssociatedElement()) {
aRv.ThrowNotSupportedError( "Target element is not a form-associated custom element"); returnfalse;
} return WillValidate();
}
if (!mTarget->IsFormAssociatedElement()) {
aRv.ThrowNotSupportedError( "Target element is not a form-associated custom element"); return nullptr;
} return Validity();
}
if (!mTarget->IsFormAssociatedElement()) {
aRv.ThrowNotSupportedError( "Target element is not a form-associated custom element"); return;
}
aValidationMessage = mValidationMessage;
}
if (!mTarget->IsFormAssociatedElement()) {
aRv.ThrowNotSupportedError( "Target element is not a form-associated custom element"); returnfalse;
} return nsIConstraintValidation::CheckValidity(*mTarget);
}
if (!mTarget->IsFormAssociatedElement()) {
aRv.ThrowNotSupportedError( "Target element is not a form-associated custom element"); return nullptr;
} return mTarget->Labels();
}
if (!mTarget->IsFormAssociatedElement()) {
aRv.ThrowNotSupportedError( "Target element is not a form-associated custom element"); return nullptr;
} return mValidationAnchor;
}
CustomStateSet* ElementInternals::States() { if (!mCustomStateSet) {
mCustomStateSet = new CustomStateSet(mTarget);
} return mCustomStateSet;
}
void ElementInternals::Unlink() { if (mForm) { // Don't notify, since we're being destroyed in any case.
ClearForm(true, true);
MOZ_DIAGNOSTIC_ASSERT(!mForm);
} if (mFieldSet) {
mFieldSet->RemoveElement(mTarget);
mFieldSet = nullptr;
}
mAttrElementsMap.Clear();
}
void ElementInternals::InitializeControlNumber() {
MOZ_ASSERT(mControlNumber == -1, "FACE control number should only be initialized once!");
mControlNumber = mTarget->OwnerDoc()->GetNextControlNumber();
}
void ElementInternals::SetAttrElement(nsAtom* aAttr, Element* aElement) { // Accessibility requires that no other attribute changes occur between // AttrElementWillChange and AttrElementChanged. Scripts could cause // this, so don't let them run here. We do this even if accessibility isn't // running so that the JS behavior is consistent regardless of accessibility. // Otherwise, JS might be able to use this difference to determine whether // accessibility is running, which would be a privacy concern.
nsAutoScriptBlocker scriptBlocker;
#ifdef ACCESSIBILITY // If the target has this attribute defined then it overrides the defaults // defined here in the Internals instance. In that case we don't need to // notify the change to a11y since the attribute hasn't changed, just the // underlying default. We can set accService to null and not notify.
nsAccessibilityService* accService =
!mTarget->HasAttr(aAttr) ? GetAccService() : nullptr; if (accService) {
accService->NotifyAttrElementWillChange(mTarget, aAttr);
} #endif
void ElementInternals::SetAttrElements(
nsAtom* aAttr, const Nullable<Sequence<OwningNonNull<Element>>>& aElements) { #ifdef ACCESSIBILITY
nsAccessibilityService* accService = GetAccService(); #endif // Accessibility requires that no other attribute changes occur between // AttrElementWillChange and AttrElementChanged. Scripts could cause // this, so don't let them run here. We do this even if accessibility isn't // running so that the JS behavior is consistent regardless of accessibility. // Otherwise, JS might be able to use this difference to determine whether // accessibility is running, which would be a privacy concern.
nsAutoScriptBlocker scriptBlocker; #ifdef ACCESSIBILITY if (accService) {
accService->NotifyAttrElementWillChange(mTarget, aAttr);
} #endif
nsAttrValue emptyAttr; if (aElements.IsNull()) {
mAttrElementsMap.Remove(aAttr);
UnsetAttrInternal(aAttr);
} else { auto& [attrElements, cachedAttrElements] =
mAttrElementsMap.LookupOrInsert(aAttr);
attrElements.Clear(); for (Element* el : aElements.Value()) {
attrElements.AppendElement(do_GetWeakReference(el));
}
SetAttrInternal(aAttr, EmptyString());
}
#ifdef ACCESSIBILITY if (accService) {
accService->NotifyAttrElementChanged(mTarget, aAttr);
} #endif
}
auto getAttrAssociatedElements = [&, &attrElements = attrElements]() {
CopyableTArray<RefPtr<Element>> elements;
for (const nsWeakPtr& weakEl : attrElements) { // For each attrElement in reflectedTarget's explicitly set attr-elements: if (nsCOMPtr<Element> attrEl = do_QueryReferent(weakEl)) { // Append attrElement to elements.
elements.AppendElement(attrEl);
}
}
if (elements == cachedAttrElements) { // 2. If the contents of elements is equal to the contents of this's cached // attr-associated elements, then return this's cached attr-associated // elements object.
MOZ_ASSERT(!*aUseCachedValue);
*aUseCachedValue = true; return;
}
// 3. Let elementsAsFrozenArray be elements, converted to a FrozenArray<T>?. // (the binding code takes aElements and returns it as a FrozenArray) // 5. Set this's cached attr-associated elements object to // elementsAsFrozenArray. // (the binding code stores the attr-associated elements object in a slot) // 6. Return elementsAsFrozenArray.
aElements.SetValue(elements.Clone());
// 4. Set this's cached attr-associated elements to elements.
cachedAttrElements = std::move(elements);
}
bool ElementInternals::GetAttrElements(nsAtom* aAttr,
nsTArray<Element*>& aElements) {
aElements.Clear(); auto attrElementsMaybeEntry = mAttrElementsMap.Lookup(aAttr); if (!attrElementsMaybeEntry) { returnfalse;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.40Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.