Bug 1470545: Add chromeonly "shadowrootattached" event for devtools. r=smaug
Summary:
document.addEventListener("shadowrootattached", e => {
// Do stuff with composedTarget.
});
I didn't bother to add tests for the event itself since this is going to get
tested in bug 1449333, but I can look into writing a chrome mochitest if you
want.
Test Plan: See above.
Reviewers: smaug
Bug #: 1470545
Differential Revision: https://phabricator.services.mozilla.com/D1777
MozReview-Commit-ID: 55cVMSsznMS

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* vim: set ts=8 sts=2 et sw=2 tw=80: *//* 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/. */#ifndef mozilla_dom_HTMLFormElement_h#define mozilla_dom_HTMLFormElement_h#include"mozilla/AsyncEventDispatcher.h"#include"mozilla/Attributes.h"#include"mozilla/dom/HTMLFormSubmission.h"#include"nsAutoPtr.h"#include"nsCOMPtr.h"#include"nsIForm.h"#include"nsIFormControl.h"#include"nsGenericHTMLElement.h"#include"nsIWebProgressListener.h"#include"nsIRadioGroupContainer.h"#include"nsIWeakReferenceUtils.h"#include"nsThreadUtils.h"#include"nsInterfaceHashtable.h"#include"nsRefPtrHashtable.h"#include"nsDataHashtable.h"#include"jsfriendapi.h" // For js::ExpandoAndGenerationclassnsIMutableArray;classnsIURI;namespacemozilla{classEventChainPostVisitor;classEventChainPreVisitor;namespacedom{classHTMLFormControlsCollection;classHTMLImageElement;classHTMLFormElementfinal:publicnsGenericHTMLElement,publicnsIWebProgressListener,publicnsIForm,publicnsIRadioGroupContainer{friendclassHTMLFormControlsCollection;public:NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLFormElement,form)explicitHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>&aNodeInfo);enum{FORM_CONTROL_LIST_HASHTABLE_LENGTH=8};// nsISupportsNS_DECL_ISUPPORTS_INHERITED// nsIWebProgressListenerNS_DECL_NSIWEBPROGRESSLISTENER// nsIFormNS_IMETHOD_(nsIFormControl*)GetElementAt(int32_taIndex)constoverride;NS_IMETHOD_(uint32_t)GetElementCount()constoverride;NS_IMETHOD_(int32_t)IndexOfControl(nsIFormControl*aControl)override;NS_IMETHOD_(nsIFormControl*)GetDefaultSubmitElement()constoverride;// nsIRadioGroupContainervoidSetCurrentRadioButton(constnsAString&aName,HTMLInputElement*aRadio)override;HTMLInputElement*GetCurrentRadioButton(constnsAString&aName)override;NS_IMETHODGetNextRadioButton(constnsAString&aName,constboolaPrevious,HTMLInputElement*aFocusedRadio,HTMLInputElement**aRadioOut)override;NS_IMETHODWalkRadioGroup(constnsAString&aName,nsIRadioVisitor*aVisitor,boolaFlushContent)override;voidAddToRadioGroup(constnsAString&aName,HTMLInputElement*aRadio)override;voidRemoveFromRadioGroup(constnsAString&aName,HTMLInputElement*aRadio)override;virtualuint32_tGetRequiredRadioCount(constnsAString&aName)constoverride;virtualvoidRadioRequiredWillChange(constnsAString&aName,boolaRequiredAdded)override;virtualboolGetValueMissingState(constnsAString&aName)constoverride;virtualvoidSetValueMissingState(constnsAString&aName,boolaValue)override;virtualEventStatesIntrinsicState()constoverride;// EventTargetvirtualvoidAsyncEventRunning(AsyncEventDispatcher*aEvent)override;// nsIContentvirtualboolParseAttribute(int32_taNamespaceID,nsAtom*aAttribute,constnsAString&aValue,nsIPrincipal*aMaybeScriptedPrincipal,nsAttrValue&aResult)override;voidGetEventTargetParent(EventChainPreVisitor&aVisitor)override;voidWillHandleEvent(EventChainPostVisitor&aVisitor)override;virtualnsresultPostHandleEvent(EventChainPostVisitor&aVisitor)override;virtualnsresultBindToTree(nsIDocument*aDocument,nsIContent*aParent,nsIContent*aBindingParent,boolaCompileEventHandlers)override;virtualvoidUnbindFromTree(boolaDeep=true,boolaNullParent=true)override;virtualnsresultBeforeSetAttr(int32_taNamespaceID,nsAtom*aName,constnsAttrValueOrString*aValue,boolaNotify)override;virtualnsresultAfterSetAttr(int32_taNameSpaceID,nsAtom*aName,constnsAttrValue*aValue,constnsAttrValue*aOldValue,nsIPrincipal*aSubjectPrincipal,boolaNotify)override;/** * Forget all information about the current submission (and the fact that we * are currently submitting at all). */voidForgetCurrentSubmission();virtualnsresultClone(mozilla::dom::NodeInfo*aNodeInfo,nsINode**aResult,boolaPreallocateChildren)constoverride;NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLFormElement,nsGenericHTMLElement)/** * Remove an element from this form's list of elements * * @param aElement the element to remove * @param aUpdateValidity If true, updates the form validity. * @return NS_OK if the element was successfully removed. */nsresultRemoveElement(nsGenericHTMLFormElement*aElement,boolaUpdateValidity);/** * Remove an element from the lookup table maintained by the form. * We can't fold this method into RemoveElement() because when * RemoveElement() is called it doesn't know if the element is * removed because the id attribute has changed, or because the * name attribute has changed. * * @param aElement the element to remove * @param aName the name or id of the element to remove * @return NS_OK if the element was successfully removed. */nsresultRemoveElementFromTable(nsGenericHTMLFormElement*aElement,constnsAString&aName);/** * Add an element to end of this form's list of elements * * @param aElement the element to add * @param aUpdateValidity If true, the form validity will be updated. * @param aNotify If true, send nsIDocumentObserver notifications as needed. * @return NS_OK if the element was successfully added */nsresultAddElement(nsGenericHTMLFormElement*aElement,boolaUpdateValidity,boolaNotify);/** * Add an element to the lookup table maintained by the form. * * We can't fold this method into AddElement() because when * AddElement() is called, the form control has no * attributes. The name or id attributes of the form control * are used as a key into the table. */nsresultAddElementToTable(nsGenericHTMLFormElement*aChild,constnsAString&aName);/** * Remove an image element from this form's list of image elements * * @param aElement the image element to remove * @return NS_OK if the element was successfully removed. */nsresultRemoveImageElement(HTMLImageElement*aElement);/** * Remove an image element from the lookup table maintained by the form. * We can't fold this method into RemoveImageElement() because when * RemoveImageElement() is called it doesn't know if the element is * removed because the id attribute has changed, or because the * name attribute has changed. * * @param aElement the image element to remove * @param aName the name or id of the element to remove * @return NS_OK if the element was successfully removed. */nsresultRemoveImageElementFromTable(HTMLImageElement*aElement,constnsAString&aName);/** * Add an image element to the end of this form's list of image elements * * @param aElement the element to add * @return NS_OK if the element was successfully added */nsresultAddImageElement(HTMLImageElement*aElement);/** * Add an image element to the lookup table maintained by the form. * * We can't fold this method into AddImageElement() because when * AddImageElement() is called, the image attributes can change. * The name or id attributes of the image are used as a key into the table. */nsresultAddImageElementToTable(HTMLImageElement*aChild,constnsAString&aName);/** * Returns true if implicit submission of this form is disabled. For more * on implicit submission see: * * http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#implicit-submission */boolImplicitSubmissionIsDisabled()const;/** * Check whether a given nsIFormControl is the last single line input control * that is not disabled. aControl is expected to not be null. */boolIsLastActiveElement(constnsIFormControl*aControl)const;/** * Check whether a given nsIFormControl is the default submit * element. This is different from just comparing to * GetDefaultSubmitElement() in certain situations inside an update * when GetDefaultSubmitElement() might not be up to date. aControl * is expected to not be null. */boolIsDefaultSubmitElement(constnsIFormControl*aControl)const;/** * Flag the form to know that a button or image triggered scripted form * submission. In that case the form will defer the submission until the * script handler returns and the return value is known. */voidOnSubmitClickBegin(Element*aOriginatingElement);voidOnSubmitClickEnd();/** * This method will update the form validity so the submit controls states * will be updated (for -moz-submit-invalid pseudo-class). * This method has to be called by form elements whenever their validity state * or status regarding constraint validation changes. * * @note This method isn't used for CheckValidity(). * @note If an element becomes barred from constraint validation, it has to be * considered as valid. * * @param aElementValidityState the new validity state of the element */voidUpdateValidity(boolaElementValidityState);/** * Returns the form validity based on the last UpdateValidity() call. * * @return Whether the form was valid the last time UpdateValidity() was called. * * @note This method may not return the *current* validity state! */boolGetValidity()const{return!mInvalidElementsCount;}/** * This method check the form validity and make invalid form elements send * invalid event if needed. * * @return Whether the form is valid. * * @note Do not call this method if novalidate/formnovalidate is used. * @note This method might disappear with bug 592124, hopefuly. */boolCheckValidFormSubmission();/** * Check whether submission can proceed for this form. This basically * implements steps 1-4 (more or less) of * <https://html.spec.whatwg.org/multipage/forms.html#concept-form-submit>. * aSubmitter, if not null, is the "submitter" from that algorithm. Therefore * it must be a valid submit control. */boolSubmissionCanProceed(Element*aSubmitter);/** * Walk over the form elements and call SubmitNamesValues() on them to get * their data pumped into the FormSubmitter. * * @param aFormSubmission the form submission object */nsresultWalkFormElements(HTMLFormSubmission*aFormSubmission);/** * Whether the submission of this form has been ever prevented because of * being invalid. * * @return Whether the submission of this form has been prevented because of * being invalid. */boolHasEverTriedInvalidSubmit()const{returnmEverTriedInvalidSubmit;}/** * Implements form[name]. Returns form controls in this form with the correct * value of the name attribute. */already_AddRefed<nsISupports>FindNamedItem(constnsAString&aName,nsWrapperCache**aCache);// WebIDLvoidGetAcceptCharset(DOMString&aValue){GetHTMLAttr(nsGkAtoms::acceptcharset,aValue);}voidSetAcceptCharset(constnsAString&aValue,ErrorResult&aRv){SetHTMLAttr(nsGkAtoms::acceptcharset,aValue,aRv);}voidGetAction(nsString&aValue);voidSetAction(constnsAString&aValue,ErrorResult&aRv){SetHTMLAttr(nsGkAtoms::action,aValue,aRv);}voidGetAutocomplete(nsAString&aValue);voidSetAutocomplete(constnsAString&aValue,ErrorResult&aRv){SetHTMLAttr(nsGkAtoms::autocomplete,aValue,aRv);}voidGetEnctype(nsAString&aValue);voidSetEnctype(constnsAString&aValue,ErrorResult&aRv){SetHTMLAttr(nsGkAtoms::enctype,aValue,aRv);}voidGetEncoding(nsAString&aValue){GetEnctype(aValue);}voidSetEncoding(constnsAString&aValue,ErrorResult&aRv){SetEnctype(aValue,aRv);}voidGetMethod(nsAString&aValue);voidSetMethod(constnsAString&aValue,ErrorResult&aRv){SetHTMLAttr(nsGkAtoms::method,aValue,aRv);}voidGetName(DOMString&aValue){GetHTMLAttr(nsGkAtoms::name,aValue);}voidSetName(constnsAString&aValue,ErrorResult&aRv){SetHTMLAttr(nsGkAtoms::name,aValue,aRv);}boolNoValidate()const{returnGetBoolAttr(nsGkAtoms::novalidate);}voidSetNoValidate(boolaValue,ErrorResult&aRv){SetHTMLBoolAttr(nsGkAtoms::novalidate,aValue,aRv);}voidGetTarget(DOMString&aValue){GetHTMLAttr(nsGkAtoms::target,aValue);}voidSetTarget(constnsAString&aValue,ErrorResult&aRv){SetHTMLAttr(nsGkAtoms::target,aValue,aRv);}// it's only out-of-line because the class definition is not available in the// headernsIHTMLCollection*Elements();int32_tLength();voidSubmit(ErrorResult&aRv);voidReset();boolCheckValidity(){returnCheckFormValidity(nullptr);}boolReportValidity(){returnCheckValidFormSubmission();}Element*IndexedGetter(uint32_taIndex,bool&aFound);already_AddRefed<nsISupports>NamedGetter(constnsAString&aName,bool&aFound);voidGetSupportedNames(nsTArray<nsString>&aRetval);staticint32_tCompareFormControlPosition(Element*aElement1,Element*aElement2,constnsIContent*aForm);#ifdef DEBUGstaticvoidAssertDocumentOrder(constnsTArray<nsGenericHTMLFormElement*>&aControls,nsIContent*aForm);staticvoidAssertDocumentOrder(constnsTArray<RefPtr<nsGenericHTMLFormElement>>&aControls,nsIContent*aForm);#endifjs::ExpandoAndGenerationmExpandoAndGeneration;protected:virtualJSObject*WrapNode(JSContext*aCx,JS::Handle<JSObject*>aGivenProto)override;voidPostPasswordEvent();RefPtr<AsyncEventDispatcher>mFormPasswordEventDispatcher;classRemoveElementRunnable;friendclassRemoveElementRunnable;classRemoveElementRunnable:publicRunnable{public:explicitRemoveElementRunnable(HTMLFormElement*aForm):Runnable("dom::HTMLFormElement::RemoveElementRunnable"),mForm(aForm){}NS_IMETHODRun()override{mForm->HandleDefaultSubmitRemoval();returnNS_OK;}private:RefPtr<HTMLFormElement>mForm;};nsresultDoSubmitOrReset(WidgetEvent*aEvent,EventMessageaMessage);nsresultDoReset();// Async callback to handle removal of our default submitvoidHandleDefaultSubmitRemoval();//// Submit Helpers/////** * Attempt to submit (submission might be deferred) * (called by DoSubmitOrReset) * * @param aPresContext the presentation context * @param aEvent the DOM event that was passed to us for the submit */nsresultDoSubmit(WidgetEvent*aEvent);/** * Prepare the submission object (called by DoSubmit) * * @param aFormSubmission the submission object * @param aEvent the DOM event that was passed to us for the submit */nsresultBuildSubmission(HTMLFormSubmission**aFormSubmission,WidgetEvent*aEvent);/** * Perform the submission (called by DoSubmit and FlushPendingSubmission) * * @param aFormSubmission the submission object */nsresultSubmitSubmission(HTMLFormSubmission*aFormSubmission);/** * Notify any submit observers of the submit. * * @param aActionURL the URL being submitted to * @param aCancelSubmit out param where submit observers can specify that the * submit should be cancelled. */nsresultNotifySubmitObservers(nsIURI*aActionURL,bool*aCancelSubmit,boolaEarlyNotify);/** * If this form submission is secure -> insecure, ask the user if they want * to continue. * * @param aActionURL the URL being submitted to * @param aCancelSubmit out param: will be true if the user wants to cancel */nsresultDoSecureToInsecureSubmitCheck(nsIURI*aActionURL,bool*aCancelSubmit);/** * Find form controls in this form with the correct value in the name * attribute. */already_AddRefed<nsISupports>DoResolveName(constnsAString&aName,boolaFlushContent);/** * Get the full URL to submit to. Do not submit if the returned URL is null. * * @param aActionURL the full, unadulterated URL you'll be submitting to [OUT] * @param aOriginatingElement the originating element of the form submission [IN] */nsresultGetActionURL(nsIURI**aActionURL,Element*aOriginatingElement);/** * Check the form validity following this algorithm: * http://www.whatwg.org/specs/web-apps/current-work/#statically-validate-the-constraints * * @param aInvalidElements [out] parameter containing the list of unhandled * invalid controls. * * @return Whether the form is currently valid. */boolCheckFormValidity(nsIMutableArray*aInvalidElements)const;// Clear the mImageNameLookupTable and mImageElements.voidClear();// Insert a element into the past names map.voidAddToPastNamesMap(constnsAString&aName,nsISupports*aChild);// Remove the given element from the past names map. The element must be an// nsGenericHTMLFormElement or HTMLImageElement.voidRemoveElementFromPastNamesMap(Element*aElement);nsresultAddElementToTableInternal(nsInterfaceHashtable<nsStringHashKey,nsISupports>&aTable,nsIContent*aChild,constnsAString&aName);nsresultRemoveElementFromTableInternal(nsInterfaceHashtable<nsStringHashKey,nsISupports>&aTable,nsIContent*aChild,constnsAString&aName);public:/** * Flush a possible pending submission. If there was a scripted submission * triggered by a button or image, the submission was defered. This method * forces the pending submission to be submitted. (happens when the handler * returns false or there is an action/target change in the script) */voidFlushPendingSubmission();protected://// Data members///** The list of controls (form.elements as well as stuff not in elements) */RefPtr<HTMLFormControlsCollection>mControls;/** The currently selected radio button of each group */nsRefPtrHashtable<nsStringHashKey,HTMLInputElement>mSelectedRadioButtons;/** The number of required radio button of each group */nsDataHashtable<nsStringCaseInsensitiveHashKey,uint32_t>mRequiredRadioButtonCounts;/** The value missing state of each group */nsDataHashtable<nsStringCaseInsensitiveHashKey,bool>mValueMissingRadioGroups;/** The pending submission object */nsAutoPtr<HTMLFormSubmission>mPendingSubmission;/** The request currently being submitted */nsCOMPtr<nsIRequest>mSubmittingRequest;/** The web progress object we are currently listening to */nsWeakPtrmWebProgress;/** The default submit element -- WEAK */nsGenericHTMLFormElement*mDefaultSubmitElement;/** The first submit element in mElements -- WEAK */nsGenericHTMLFormElement*mFirstSubmitInElements;/** The first submit element in mNotInElements -- WEAK */nsGenericHTMLFormElement*mFirstSubmitNotInElements;// This array holds on to all HTMLImageElement(s).// This is needed to properly clean up the bi-directional references// (both weak and strong) between the form and its HTMLImageElements.nsTArray<HTMLImageElement*>mImageElements;// Holds WEAK references// A map from an ID or NAME attribute to the HTMLImageElement(s), this// hash holds strong references either to the named HTMLImageElement, or// to a list of named HTMLImageElement(s), in the case where this hash// holds on to a list of named HTMLImageElement(s) the list has weak// references to the HTMLImageElement.nsInterfaceHashtable<nsStringHashKey,nsISupports>mImageNameLookupTable;// A map from names to elements that were gotten by those names from this// form in that past. See "past names map" in the HTML5 specification.nsInterfaceHashtable<nsStringHashKey,nsISupports>mPastNameLookupTable;/** Keep track of what the popup state was when the submit was initiated */PopupControlStatemSubmitPopupState;/** * Number of invalid and candidate for constraint validation elements in the * form the last time UpdateValidity has been called. * @note Should only be used by UpdateValidity() and GetValidity()! */int32_tmInvalidElementsCount;/** Whether we are currently processing a submit event or not */boolmGeneratingSubmit;/** Whether we are currently processing a reset event or not */boolmGeneratingReset;/** Whether we are submitting currently */boolmIsSubmitting;/** Whether the submission is to be deferred in case a script triggers it */boolmDeferSubmission;/** Whether we notified NS_FORMSUBMIT_SUBJECT listeners already */boolmNotifiedObservers;/** If we notified the listeners early, what was the result? */boolmNotifiedObserversResult;/** Keep track of whether a submission was user-initiated or not */boolmSubmitInitiatedFromUserInput;/** * Whether the submission of this form has been ever prevented because of * being invalid. */boolmEverTriedInvalidSubmit;protected:/** Detection of first form to notify observers */staticboolgFirstFormSubmitted;/** Detection of first password input to initialize the password manager */staticboolgPasswordManagerInitialized;private:~HTMLFormElement();};}// namespace dom}// namespace mozilla#endif // mozilla_dom_HTMLFormElement_h