forked from mirrors/gecko-dev
Bug 1888774 - make InvokeAction an enum, "auto" now implicit r=dom-core,sefeng
Only "custom" invoke actions (those with a dash) or well-defined built-in actions can be defined. Auto action is now implicit from empty/null atom. Differential Revision: https://phabricator.services.mozilla.com/D206182
This commit is contained in:
parent
d06779086a
commit
12abaca03f
10 changed files with 88 additions and 35 deletions
|
|
@ -253,6 +253,21 @@ class Grid;
|
|||
ExplicitlySetAttrElement(nsGkAtoms::attr, aElement); \
|
||||
}
|
||||
|
||||
// TODO(keithamus): Reference the spec link once merged.
|
||||
// https://github.com/whatwg/html/pull/9841/files#diff-41cf6794ba4200b839c53531555f0f3998df4cbb01a4d5cb0b94e3ca5e23947dR86024
|
||||
enum class InvokeAction : uint8_t {
|
||||
Invalid,
|
||||
Custom,
|
||||
Auto,
|
||||
TogglePopover,
|
||||
ShowPopover,
|
||||
HidePopover,
|
||||
ShowModal,
|
||||
Toggle,
|
||||
Close,
|
||||
Open,
|
||||
};
|
||||
|
||||
class Element : public FragmentOrElement {
|
||||
public:
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
|
|
@ -1113,7 +1128,7 @@ class Element : public FragmentOrElement {
|
|||
return FindAttributeDependence(aAttribute, aMaps, N);
|
||||
}
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT virtual void HandleInvokeInternal(nsAtom* aAction,
|
||||
MOZ_CAN_RUN_SCRIPT virtual void HandleInvokeInternal(InvokeAction aAction,
|
||||
ErrorResult& aRv) {}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -3658,6 +3658,23 @@ nsresult nsContentUtils::NewURIWithDocumentCharset(nsIURI** aResult,
|
|||
return NS_NewURI(aResult, aSpec, nullptr, aBaseURI);
|
||||
}
|
||||
|
||||
// static
|
||||
bool nsContentUtils::ContainsChar(nsAtom* aAtom, char aChar) {
|
||||
const uint32_t len = aAtom->GetLength();
|
||||
if (!len) {
|
||||
return false;
|
||||
}
|
||||
const char16_t* name = aAtom->GetUTF16String();
|
||||
uint32_t i = 0;
|
||||
while (i < len) {
|
||||
if (name[i] == aChar) {
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool nsContentUtils::IsNameWithDash(nsAtom* aName) {
|
||||
// A valid custom element name is a sequence of characters name which
|
||||
|
|
|
|||
|
|
@ -975,6 +975,11 @@ class nsContentUtils {
|
|||
Document* aDocument,
|
||||
nsIURI* aBaseURI);
|
||||
|
||||
/**
|
||||
* Returns true if |aAtom| contains at least one |aChar|.
|
||||
*/
|
||||
static bool ContainsChar(nsAtom* aAtom, char aChar);
|
||||
|
||||
/**
|
||||
* Returns true if |aName| is a name with dashes.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -144,16 +144,15 @@ JSObject* HTMLDetailsElement::WrapNode(JSContext* aCx,
|
|||
return HTMLDetailsElement_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void HTMLDetailsElement::HandleInvokeInternal(nsAtom* aAction,
|
||||
void HTMLDetailsElement::HandleInvokeInternal(InvokeAction aAction,
|
||||
ErrorResult& aRv) {
|
||||
if (nsContentUtils::EqualsIgnoreASCIICase(aAction, nsGkAtoms::_auto) ||
|
||||
nsContentUtils::EqualsIgnoreASCIICase(aAction, nsGkAtoms::toggle)) {
|
||||
if (aAction == InvokeAction::Auto || aAction == InvokeAction::Toggle) {
|
||||
ToggleOpen();
|
||||
} else if (nsContentUtils::EqualsIgnoreASCIICase(aAction, nsGkAtoms::close)) {
|
||||
} else if (aAction == InvokeAction::Close) {
|
||||
if (Open()) {
|
||||
SetOpen(false, IgnoreErrors());
|
||||
}
|
||||
} else if (nsContentUtils::EqualsIgnoreASCIICase(aAction, nsGkAtoms::open)) {
|
||||
} else if (aAction == InvokeAction::Open) {
|
||||
if (!Open()) {
|
||||
SetOpen(true, IgnoreErrors());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class HTMLDetailsElement final : public nsGenericHTMLElement {
|
|||
|
||||
void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
|
||||
|
||||
void HandleInvokeInternal(nsAtom* aAction, ErrorResult& aRv) override;
|
||||
void HandleInvokeInternal(InvokeAction aAction, ErrorResult& aRv) override;
|
||||
|
||||
protected:
|
||||
virtual ~HTMLDetailsElement();
|
||||
|
|
|
|||
|
|
@ -2897,15 +2897,42 @@ void nsGenericHTMLFormControlElementWithState::HandlePopoverTargetAction() {
|
|||
|
||||
void nsGenericHTMLFormControlElementWithState::GetInvokeAction(
|
||||
nsAString& aValue) const {
|
||||
GetInvokeAction()->ToString(aValue);
|
||||
const nsAttrValue* attr = GetParsedAttr(nsGkAtoms::invokeaction);
|
||||
if (attr) {
|
||||
attr->GetAtomValue()->ToString(aValue);
|
||||
}
|
||||
}
|
||||
|
||||
nsAtom* nsGenericHTMLFormControlElementWithState::GetInvokeAction() const {
|
||||
const nsAttrValue* attr = GetParsedAttr(nsGkAtoms::invokeaction);
|
||||
if (attr && attr->GetAtomValue() != nsGkAtoms::_empty) {
|
||||
return attr->GetAtomValue();
|
||||
InvokeAction nsGenericHTMLFormControlElementWithState::GetInvokeAction(
|
||||
nsAtom* aAtom) const {
|
||||
if (aAtom == nsGkAtoms::_empty) {
|
||||
return InvokeAction::Auto;
|
||||
}
|
||||
return nsGkAtoms::_auto;
|
||||
if (nsContentUtils::EqualsIgnoreASCIICase(aAtom, nsGkAtoms::showpopover)) {
|
||||
return InvokeAction::ShowPopover;
|
||||
}
|
||||
if (nsContentUtils::EqualsIgnoreASCIICase(aAtom, nsGkAtoms::hidepopover)) {
|
||||
return InvokeAction::HidePopover;
|
||||
}
|
||||
if (nsContentUtils::EqualsIgnoreASCIICase(aAtom, nsGkAtoms::togglepopover)) {
|
||||
return InvokeAction::TogglePopover;
|
||||
}
|
||||
if (nsContentUtils::EqualsIgnoreASCIICase(aAtom, nsGkAtoms::showmodal)) {
|
||||
return InvokeAction::ShowModal;
|
||||
}
|
||||
if (nsContentUtils::EqualsIgnoreASCIICase(aAtom, nsGkAtoms::toggle)) {
|
||||
return InvokeAction::Toggle;
|
||||
}
|
||||
if (nsContentUtils::EqualsIgnoreASCIICase(aAtom, nsGkAtoms::close)) {
|
||||
return InvokeAction::Close;
|
||||
}
|
||||
if (nsContentUtils::EqualsIgnoreASCIICase(aAtom, nsGkAtoms::open)) {
|
||||
return InvokeAction::Open;
|
||||
}
|
||||
if (nsContentUtils::ContainsChar(aAtom, '-')) {
|
||||
return InvokeAction::Custom;
|
||||
}
|
||||
return InvokeAction::Invalid;
|
||||
}
|
||||
|
||||
mozilla::dom::Element*
|
||||
|
|
@ -2930,16 +2957,15 @@ void nsGenericHTMLFormControlElementWithState::HandleInvokeTargetAction() {
|
|||
return;
|
||||
}
|
||||
|
||||
// 3. Let action be node's invokeaction attribute
|
||||
// 4. If action is null or empty, then let action be the string "auto".
|
||||
RefPtr<nsAtom> aAction = GetInvokeAction();
|
||||
MOZ_ASSERT(!aAction->IsEmpty(), "Action should not be empty");
|
||||
const nsAttrValue* attr = GetParsedAttr(nsGkAtoms::invokeaction);
|
||||
nsAtom* actionRaw = attr ? attr->GetAtomValue() : nsGkAtoms::_empty;
|
||||
InvokeAction action = GetInvokeAction(actionRaw);
|
||||
|
||||
// 5. Let notCancelled be the result of firing an event named invoke at
|
||||
// invokee with its action set to action, its invoker set to node,
|
||||
// and its cancelable attribute initialized to true.
|
||||
InvokeEventInit init;
|
||||
aAction->ToString(init.mAction);
|
||||
actionRaw->ToString(init.mAction);
|
||||
init.mInvoker = this;
|
||||
init.mCancelable = true;
|
||||
init.mComposed = true;
|
||||
|
|
@ -2955,7 +2981,7 @@ void nsGenericHTMLFormControlElementWithState::HandleInvokeTargetAction() {
|
|||
return;
|
||||
}
|
||||
|
||||
invokee->HandleInvokeInternal(aAction, IgnoreErrors());
|
||||
invokee->HandleInvokeInternal(action, IgnoreErrors());
|
||||
}
|
||||
|
||||
void nsGenericHTMLFormControlElementWithState::GenerateStateKey() {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase {
|
|||
public:
|
||||
using Element::Focus;
|
||||
using Element::SetTabIndex;
|
||||
using InvokeAction = mozilla::dom::InvokeAction;
|
||||
|
||||
explicit nsGenericHTMLElement(
|
||||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||
: nsGenericHTMLElementBase(std::move(aNodeInfo)) {
|
||||
|
|
@ -1260,7 +1262,7 @@ class nsGenericHTMLFormControlElementWithState
|
|||
mozilla::dom::Element* GetInvokeTargetElement() const;
|
||||
void SetInvokeTargetElement(mozilla::dom::Element*);
|
||||
void GetInvokeAction(nsAString& aValue) const;
|
||||
nsAtom* GetInvokeAction() const;
|
||||
InvokeAction GetInvokeAction(nsAtom* aAtom) const;
|
||||
void SetInvokeAction(const nsAString& aValue) {
|
||||
SetHTMLAttr(nsGkAtoms::invokeaction, aValue);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
[invokeelement-interface.tentative.html]
|
||||
[invokeAction reflects '' when attribute not present]
|
||||
expected: FAIL
|
||||
|
||||
[invokeAction reflects '' when attribute empty, setAttribute version]
|
||||
expected: FAIL
|
||||
|
||||
[invokeAction reflects '' when attribute empty, IDL version]
|
||||
expected: FAIL
|
||||
|
||||
[invokeAction reflects '' when attribute set to [\]]
|
||||
expected: FAIL
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
[invoketarget-button-event-dispatch.tentative.html]
|
||||
[event dispatches on click]
|
||||
expected: FAIL
|
||||
|
||||
[setting custom invokeAction property to foo (no dash) did not dispatch an event]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
|||
|
|
@ -520,6 +520,7 @@ STATIC_ATOMS = [
|
|||
Atom("hidden", "hidden"),
|
||||
Atom("hidechrome", "hidechrome"),
|
||||
Atom("hidecolumnpicker", "hidecolumnpicker"),
|
||||
Atom("hidepopover", "hidepopover"),
|
||||
Atom("high", "high"),
|
||||
Atom("highest", "highest"),
|
||||
Atom("horizontal", "horizontal"),
|
||||
|
|
@ -1155,6 +1156,8 @@ STATIC_ATOMS = [
|
|||
Atom("shape", "shape"),
|
||||
Atom("show", "show"),
|
||||
Atom("showcaret", "showcaret"),
|
||||
Atom("showmodal", "showmodal"),
|
||||
Atom("showpopover", "showpopover"),
|
||||
Atom("showservicesmenu", "showservicesmenu"),
|
||||
Atom("sibling", "sibling"),
|
||||
Atom("simple", "simple"),
|
||||
|
|
@ -1248,6 +1251,7 @@ STATIC_ATOMS = [
|
|||
Atom("title", "title"),
|
||||
Atom("titletip", "titletip"),
|
||||
Atom("toggle", "toggle"),
|
||||
Atom("togglepopover", "togglepopover"),
|
||||
Atom("token", "token"),
|
||||
Atom("tokenize", "tokenize"),
|
||||
Atom("toolbar", "toolbar"),
|
||||
|
|
|
|||
Loading…
Reference in a new issue