Skip to content

Commit

Permalink
Bug 1729342 - Use delegatesFocus for <input type=date/time/datetime-l…
Browse files Browse the repository at this point in the history
…ocal> widget r=emilio

Currently datetimebox uses some hardcoded logic to find the edit
field inside the shadow tree and focus it.

Since we have delegatesFocus implemented, we could just use it without
these logic.

Differential Revision: https://phabricator.services.mozilla.com/D125440
  • Loading branch information
sefeng211 committed Sep 20, 2021
1 parent 42b741a commit c01f1a8
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 104 deletions.
10 changes: 6 additions & 4 deletions dom/base/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1182,12 +1182,13 @@ already_AddRefed<ShadowRoot> Element::AttachShadow(const ShadowRootInit& aInit,
OwnerDoc()->ReportShadowDOMUsage();
}

return AttachShadowWithoutNameChecks(aInit.mMode, aInit.mDelegatesFocus,
return AttachShadowWithoutNameChecks(aInit.mMode,
DelegatesFocus(aInit.mDelegatesFocus),
aInit.mSlotAssignment);
}

already_AddRefed<ShadowRoot> Element::AttachShadowWithoutNameChecks(
ShadowRootMode aMode, bool aDelegatesFocus,
ShadowRootMode aMode, DelegatesFocus aDelegatesFocus,
SlotAssignmentMode aSlotAssignment) {
nsAutoScriptBlocker scriptBlocker;

Expand Down Expand Up @@ -1252,7 +1253,8 @@ already_AddRefed<ShadowRoot> Element::AttachShadowWithoutNameChecks(
return shadowRoot.forget();
}

void Element::AttachAndSetUAShadowRoot(NotifyUAWidgetSetup aNotify) {
void Element::AttachAndSetUAShadowRoot(NotifyUAWidgetSetup aNotify,
DelegatesFocus aDelegatesFocus) {
MOZ_DIAGNOSTIC_ASSERT(!CanAttachShadowDOM(),
"Cannot be used to attach UI shadow DOM");
if (OwnerDoc()->IsStaticDocument()) {
Expand All @@ -1261,7 +1263,7 @@ void Element::AttachAndSetUAShadowRoot(NotifyUAWidgetSetup aNotify) {

if (!GetShadowRoot()) {
RefPtr<ShadowRoot> shadowRoot =
AttachShadowWithoutNameChecks(ShadowRootMode::Closed);
AttachShadowWithoutNameChecks(ShadowRootMode::Closed, aDelegatesFocus);
shadowRoot->SetIsUAWidget();
}

Expand Down
7 changes: 5 additions & 2 deletions dom/base/Element.h
Original file line number Diff line number Diff line change
Expand Up @@ -1270,13 +1270,16 @@ class Element : public FragmentOrElement {
ErrorResult& aError);
bool CanAttachShadowDOM() const;

enum class DelegatesFocus : bool { No, Yes };

already_AddRefed<ShadowRoot> AttachShadowWithoutNameChecks(
ShadowRootMode aMode, bool aDelegatesFocus = false,
ShadowRootMode aMode, DelegatesFocus = DelegatesFocus::No,
SlotAssignmentMode aSlotAssignmentMode = SlotAssignmentMode::Named);

// Attach UA Shadow Root if it is not attached.
enum class NotifyUAWidgetSetup : bool { No, Yes };
void AttachAndSetUAShadowRoot(NotifyUAWidgetSetup = NotifyUAWidgetSetup::Yes);
void AttachAndSetUAShadowRoot(NotifyUAWidgetSetup = NotifyUAWidgetSetup::Yes,
DelegatesFocus = DelegatesFocus::No);

// Dispatch an event to UAWidgetsChild, triggering construction
// or onchange callback on the existing widget.
Expand Down
3 changes: 2 additions & 1 deletion dom/base/ShadowRoot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ NS_IMPL_ADDREF_INHERITED(ShadowRoot, DocumentFragment)
NS_IMPL_RELEASE_INHERITED(ShadowRoot, DocumentFragment)

ShadowRoot::ShadowRoot(Element* aElement, ShadowRootMode aMode,
bool aDelegatesFocus, SlotAssignmentMode aSlotAssignment,
Element::DelegatesFocus aDelegatesFocus,
SlotAssignmentMode aSlotAssignment,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
: DocumentFragment(std::move(aNodeInfo)),
DocumentOrShadowRoot(this),
Expand Down
9 changes: 6 additions & 3 deletions dom/base/ShadowRoot.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ class ShadowRoot final : public DocumentFragment,
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRoot, DocumentFragment)
NS_DECL_ISUPPORTS_INHERITED

ShadowRoot(Element* aElement, ShadowRootMode aMode, bool aDelegatesFocus,
ShadowRoot(Element* aElement, ShadowRootMode aMode,
Element::DelegatesFocus aDelegatesFocus,
SlotAssignmentMode aSlotAssignment,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);

Expand Down Expand Up @@ -80,7 +81,9 @@ class ShadowRoot final : public DocumentFragment,
}

ShadowRootMode Mode() const { return mMode; }
bool DelegatesFocus() const { return mDelegatesFocus; }
bool DelegatesFocus() const {
return mDelegatesFocus == Element::DelegatesFocus::Yes;
}
SlotAssignmentMode SlotAssignment() const { return mSlotAssignment; }
bool IsClosed() const { return mMode == ShadowRootMode::Closed; }

Expand Down Expand Up @@ -278,7 +281,7 @@ class ShadowRoot final : public DocumentFragment,

const ShadowRootMode mMode;

bool mDelegatesFocus;
Element::DelegatesFocus mDelegatesFocus;

const SlotAssignmentMode mSlotAssignment;

Expand Down
51 changes: 3 additions & 48 deletions dom/html/HTMLInputElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2261,7 +2261,7 @@ void HTMLInputElement::SetUserInput(const nsAString& aValue,
// If this element is not currently focused, it won't receive a change event
// for this update through the normal channels. So fire a change event
// immediately, instead.
if (!ShouldBlur(this)) {
if (CreatesDateTimeWidget() || !ShouldBlur(this)) {
FireChangeEventIfNeeded();
}
}
Expand Down Expand Up @@ -2963,39 +2963,6 @@ void HTMLInputElement::SetCheckedInternal(bool aChecked, bool aNotify) {
}
}

void HTMLInputElement::Blur(ErrorResult& aError) {
if (CreatesDateTimeWidget()) {
if (Element* dateTimeBoxElement = GetDateTimeBoxElement()) {
// TODO(emilio, bug 1729342): This should probably use delegatesFocus
// instead.
AsyncEventDispatcher* dispatcher = new AsyncEventDispatcher(
dateTimeBoxElement, u"MozBlurInnerTextBox"_ns, CanBubble::eNo,
ChromeOnlyDispatch::eNo);
dispatcher->RunDOMEventWhenSafe();
return;
}
}

nsGenericHTMLElement::Blur(aError);
}

void HTMLInputElement::Focus(const FocusOptions& aOptions,
CallerType aCallerType, ErrorResult& aError) {
if (CreatesDateTimeWidget()) {
if (Element* dateTimeBoxElement = GetDateTimeBoxElement()) {
// TODO(emilio, bug 1729342): This should probably use delegatesFocus
// instead.
AsyncEventDispatcher* dispatcher = new AsyncEventDispatcher(
dateTimeBoxElement, u"MozFocusInnerTextBox"_ns, CanBubble::eNo,
ChromeOnlyDispatch::eNo);
dispatcher->RunDOMEventWhenSafe();
return;
}
}

nsGenericHTMLElement::Focus(aOptions, aCallerType, aError);
}

#if !defined(ANDROID) && !defined(XP_MACOSX)
bool HTMLInputElement::IsNodeApzAwareInternal() const {
// Tell APZC we may handle mouse wheel event and do preventDefault when input
Expand Down Expand Up @@ -3232,18 +3199,6 @@ void HTMLInputElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
}
}

if (CreatesDateTimeWidget() && aVisitor.mEvent->mMessage == eFocus &&
aVisitor.mEvent->mOriginalTarget == this) {
// If original target is this and not the inner text control, we should
// pass the focus to the inner text control.
if (Element* dateTimeBoxElement = GetDateTimeBoxElement()) {
AsyncEventDispatcher* dispatcher = new AsyncEventDispatcher(
dateTimeBoxElement, u"MozFocusInnerTextBox"_ns, CanBubble::eNo,
ChromeOnlyDispatch::eNo);
dispatcher->RunDOMEventWhenSafe();
}
}

if (mType == FormControlType::InputNumber && aVisitor.mEvent->IsTrusted()) {
if (mNumberControlSpinnerIsSpinning) {
// If the timer is running the user has depressed the mouse on one of the
Expand Down Expand Up @@ -4264,7 +4219,7 @@ nsresult HTMLInputElement::BindToTree(BindContext& aContext, nsINode& aParent) {

if (CreatesDateTimeWidget() && IsInComposedDoc()) {
// Construct Shadow Root so web content can be hidden in the DOM.
AttachAndSetUAShadowRoot();
AttachAndSetUAShadowRoot(NotifyUAWidgetSetup::Yes, DelegatesFocus::Yes);
}

if (mType == FormControlType::InputPassword) {
Expand Down Expand Up @@ -4536,7 +4491,7 @@ void HTMLInputElement::HandleTypeChange(FormControlType aNewType,
}
} else if (CreatesDateTimeWidget()) {
// Switch to date/time type.
AttachAndSetUAShadowRoot();
AttachAndSetUAShadowRoot(NotifyUAWidgetSetup::Yes, DelegatesFocus::Yes);
}
}
}
Expand Down
3 changes: 0 additions & 3 deletions dom/html/HTMLInputElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,6 @@ class HTMLInputElement final : public TextControlElement,

int32_t TabIndexDefault() override;
using nsGenericHTMLElement::Focus;
void Blur(ErrorResult& aError) override;
void Focus(const FocusOptions& aOptions, CallerType aCallerType,
ErrorResult& aError) override;

// nsINode
#if !defined(ANDROID) && !defined(XP_MACOSX)
Expand Down
44 changes: 1 addition & 43 deletions toolkit/content/widgets/datetimebox.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ this.DateTimeBoxWidget = class {
this.buildEditFields();

if (focused) {
this.focusInnerTextBox();
this.mInputElement.focus();
}
}

Expand Down Expand Up @@ -294,8 +294,6 @@ this.DateTimeBoxWidget = class {
return [
"MozDateTimeValueChanged",
"MozNotifyMinMaxStepAttrChanged",
"MozFocusInnerTextBox",
"MozBlurInnerTextBox",
"MozDateTimeAttributeChanged",
"MozPickerValueChanged",
"MozSetDateTimePickerState",
Expand Down Expand Up @@ -405,38 +403,6 @@ this.DateTimeBoxWidget = class {
}
}

focusInnerTextBox() {
this.log("Focus inner editable field.");

let editRoot = this.shadowRoot.getElementById("edit-wrapper");
for (let child of editRoot.querySelectorAll(
":scope > span.datetime-edit-field"
)) {
this.mLastFocusedField = child;
child.focus();
this.log("focused");
break;
}
}

blurInnerTextBox() {
this.log("Blur inner editable field.");

if (this.mLastFocusedField) {
this.mLastFocusedField.blur();
} else {
// If .mLastFocusedField hasn't been set, blur all editable fields,
// so that the bound element will actually be blurred. Note that
// blurring on a element that has no focus won't have any effect.
let editRoot = this.shadowRoot.getElementById("edit-wrapper");
for (let child of editRoot.querySelectorAll(
":scope > span.datetime-edit-field"
)) {
child.blur();
}
}
}

notifyInputElementValueChanged() {
this.log("inputElementValueChanged");
this.setFieldsFromInputValue();
Expand Down Expand Up @@ -582,14 +548,6 @@ this.DateTimeBoxWidget = class {
this.notifyMinMaxStepAttrChanged();
break;
}
case "MozFocusInnerTextBox": {
this.focusInnerTextBox();
break;
}
case "MozBlurInnerTextBox": {
this.blurInnerTextBox();
break;
}
case "MozDateTimeAttributeChanged": {
this.updateEditAttributes();
break;
Expand Down

0 comments on commit c01f1a8

Please sign in to comment.