mirror of
https://github.com/roytam1/UXP.git
synced 2026-05-26 05:46:58 +00:00
Issue #2548 - Part 5 - Implement the HTMLOrForeignElement mixin. https://bugzilla.mozilla.org/show_bug.cgi?id=1577660 Add 'preventScroll' option to HTMLElement's, SVGElement's and XULElement's 'focus' method. https://bugzilla.mozilla.org/show_bug.cgi?id=1374045
This commit is contained in:
@@ -308,12 +308,18 @@ Element::TabIndex()
|
||||
}
|
||||
|
||||
void
|
||||
Element::Focus(mozilla::ErrorResult& aError)
|
||||
Element::Focus(const FocusOptions& aOptions, ErrorResult& aError)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(this);
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
// Also other browsers seem to have the hack to not re-focus (and flush) when
|
||||
// the element is already focused.
|
||||
// Until https://github.com/whatwg/html/issues/4512 is clarified, we'll
|
||||
// maintain interoperatibility by not re-focusing, independent of aOptions.
|
||||
// I.e., `focus({ preventScroll: true})` followed by `focus( { preventScroll:
|
||||
// false })` won't re-focus.
|
||||
if (fm && domElement) {
|
||||
aError = fm->SetFocus(domElement, 0);
|
||||
aError = fm->SetFocus(domElement, nsFocusManager::FocusOptionsToFocusManagerFlags(aOptions));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -216,7 +216,7 @@ public:
|
||||
/**
|
||||
* Make focus on this element.
|
||||
*/
|
||||
virtual void Focus(mozilla::ErrorResult& aError);
|
||||
virtual void Focus(const FocusOptions& aOptions, ErrorResult& aError);
|
||||
|
||||
/**
|
||||
* Show blur and clear focus.
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
|
||||
#include "mozilla/ContentEvents.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ElementBinding.h"
|
||||
#include "mozilla/dom/ShadowRoot.h"
|
||||
#include "mozilla/dom/HTMLInputElement.h"
|
||||
#include "mozilla/dom/HTMLSlotElement.h"
|
||||
@@ -3005,6 +3006,11 @@ nsFocusManager::DetermineElementToMoveFocus(nsPIDOMWindowOuter* aWindow,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t nsFocusManager::FocusOptionsToFocusManagerFlags(
|
||||
const mozilla::dom::FocusOptions& aOptions) {
|
||||
return aOptions.mPreventScroll ? nsIFocusManager::FLAG_NOSCROLL : 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsHostOrSlot(nsIContent* aContent)
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@ class nsIMessageBroadcaster;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
struct FocusOptions;
|
||||
class TabParent;
|
||||
}
|
||||
}
|
||||
@@ -110,6 +111,9 @@ public:
|
||||
static nsIContent* GetFocusedDescendant(nsPIDOMWindowOuter* aWindow, bool aDeep,
|
||||
nsPIDOMWindowOuter** aFocusedWindow);
|
||||
|
||||
static uint32_t FocusOptionsToFocusManagerFlags(
|
||||
const mozilla::dom::FocusOptions& aOptions);
|
||||
|
||||
/**
|
||||
* Returns the content node that focus will be redirected to if aContent was
|
||||
* focused. This is used for the special case of certain XUL elements such
|
||||
|
||||
@@ -3590,7 +3590,7 @@ HTMLInputElement::Blur(ErrorResult& aError)
|
||||
}
|
||||
|
||||
void
|
||||
HTMLInputElement::Focus(ErrorResult& aError)
|
||||
HTMLInputElement::Focus(const FocusOptions& aOptions, ErrorResult& aError)
|
||||
{
|
||||
if (mType == NS_FORM_INPUT_NUMBER) {
|
||||
// Focus our anonymous text control, if we have one.
|
||||
@@ -3600,7 +3600,7 @@ HTMLInputElement::Focus(ErrorResult& aError)
|
||||
RefPtr<HTMLInputElement> textControl =
|
||||
numberControlFrame->GetAnonTextControl();
|
||||
if (textControl) {
|
||||
textControl->Focus(aError);
|
||||
textControl->Focus(aOptions, aError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -3616,7 +3616,7 @@ HTMLInputElement::Focus(ErrorResult& aError)
|
||||
}
|
||||
|
||||
if (mType != NS_FORM_INPUT_FILE) {
|
||||
nsGenericHTMLElement::Focus(aError);
|
||||
nsGenericHTMLElement::Focus(aOptions, aError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,8 @@ public:
|
||||
virtual int32_t TabIndexDefault() override;
|
||||
using nsGenericHTMLElement::Focus;
|
||||
virtual void Blur(ErrorResult& aError) override;
|
||||
virtual void Focus(ErrorResult& aError) override;
|
||||
virtual void Focus(const FocusOptions& aOptions,
|
||||
ErrorResult& aError) override;
|
||||
|
||||
// nsINode
|
||||
#if !defined(ANDROID) && !defined(XP_MACOSX)
|
||||
|
||||
@@ -93,14 +93,15 @@ HTMLLabelElement::GetForm() const
|
||||
}
|
||||
|
||||
void
|
||||
HTMLLabelElement::Focus(ErrorResult& aError)
|
||||
HTMLLabelElement::Focus(const FocusOptions& aOptions,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
// retarget the focus method at the for content
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
nsCOMPtr<nsIDOMElement> elem = do_QueryObject(GetLabeledElement());
|
||||
if (elem)
|
||||
fm->SetFocus(elem, 0);
|
||||
fm->SetFocus(elem, nsFocusManager::FocusOptionsToFocusManagerFlags(aOptions));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,8 @@ public:
|
||||
}
|
||||
|
||||
using nsGenericHTMLElement::Focus;
|
||||
virtual void Focus(mozilla::ErrorResult& aError) override;
|
||||
virtual void Focus(const FocusOptions& aOptions,
|
||||
ErrorResult& aError) override;
|
||||
|
||||
virtual bool IsDisabled() const override { return false; }
|
||||
|
||||
|
||||
@@ -86,7 +86,8 @@ HTMLLegendElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
}
|
||||
|
||||
void
|
||||
HTMLLegendElement::Focus(ErrorResult& aError)
|
||||
HTMLLegendElement::Focus(const FocusOptions& aOptions,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
nsIFrame* frame = GetPrimaryFrame();
|
||||
if (!frame) {
|
||||
@@ -95,7 +96,7 @@ HTMLLegendElement::Focus(ErrorResult& aError)
|
||||
|
||||
int32_t tabIndex;
|
||||
if (frame->IsFocusable(&tabIndex, false)) {
|
||||
nsGenericHTMLElement::Focus(aError);
|
||||
nsGenericHTMLElement::Focus(aOptions, aError);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -108,7 +109,8 @@ HTMLLegendElement::Focus(ErrorResult& aError)
|
||||
|
||||
nsCOMPtr<nsIDOMElement> result;
|
||||
aError = fm->MoveFocus(nullptr, this, nsIFocusManager::MOVEFOCUS_FORWARD,
|
||||
nsIFocusManager::FLAG_NOPARENTFRAME,
|
||||
nsIFocusManager::FLAG_NOPARENTFRAME |
|
||||
nsFocusManager::FocusOptionsToFocusManagerFlags(aOptions),
|
||||
getter_AddRefs(result));
|
||||
}
|
||||
|
||||
@@ -116,9 +118,10 @@ bool
|
||||
HTMLLegendElement::PerformAccesskey(bool aKeyCausesActivation,
|
||||
bool aIsTrustedEvent)
|
||||
{
|
||||
// just use the same behaviour as the focus method
|
||||
FocusOptions options;
|
||||
ErrorResult rv;
|
||||
Focus(rv);
|
||||
|
||||
Focus(options, rv);
|
||||
return NS_SUCCEEDED(rv.StealNSResult());
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ public:
|
||||
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLLegendElement, legend)
|
||||
|
||||
using nsGenericHTMLElement::Focus;
|
||||
virtual void Focus(ErrorResult& aError) override;
|
||||
virtual void Focus(const FocusOptions& aOptions,
|
||||
ErrorResult& aError) override;
|
||||
|
||||
virtual bool PerformAccesskey(bool aKeyCausesActivation,
|
||||
bool aIsTrustedEvent) override;
|
||||
|
||||
@@ -150,8 +150,9 @@ public:
|
||||
// If something is focused in the same document, ignore autofocus.
|
||||
if (!fm->GetFocusedContent() ||
|
||||
fm->GetFocusedContent()->OwnerDoc() != document) {
|
||||
mozilla::ErrorResult rv;
|
||||
mElement->Focus(rv);
|
||||
FocusOptions options;
|
||||
ErrorResult rv;
|
||||
mElement->Focus(options, rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
|
||||
@@ -434,8 +434,9 @@ public:
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
NS_IMETHOD Focus() final override {
|
||||
mozilla::dom::FocusOptions options;
|
||||
mozilla::ErrorResult rv;
|
||||
Focus(rv);
|
||||
Focus(options, rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
NS_IMETHOD GetDraggable(bool* aDraggable) final override {
|
||||
|
||||
@@ -435,8 +435,7 @@ MathMLElement::ParseNumericValue(const nsString& aString,
|
||||
number.Append(c);
|
||||
}
|
||||
|
||||
if (/*StaticPrefs::mathml_legacy_number_syntax_disabled() &&*/ gotDot &&
|
||||
str[i - 1] == '.') {
|
||||
if (gotDot && str[i - 1] == '.') {
|
||||
if (!(aFlags & PARSE_SUPPRESS_WARNINGS)) {
|
||||
ReportLengthParseError(aString, aDocument);
|
||||
}
|
||||
|
||||
@@ -169,6 +169,23 @@ interface mixin ElementCSSInlineStyle {
|
||||
readonly attribute CSSStyleDeclaration style;
|
||||
};
|
||||
|
||||
// https://html.spec.whatwg.org/#focus-management-apis
|
||||
dictionary FocusOptions {
|
||||
boolean preventScroll = false;
|
||||
};
|
||||
|
||||
interface mixin HTMLOrForeignElement {
|
||||
[SameObject] readonly attribute DOMStringMap dataset;
|
||||
// See bug 1389421
|
||||
// attribute DOMString nonce; // intentionally no [CEReactions]
|
||||
|
||||
// See bug 1575154
|
||||
// [CEReactions] attribute boolean autofocus;
|
||||
[CEReactions, SetterThrows, Pure] attribute long tabIndex;
|
||||
[Throws] void focus(optional FocusOptions options);
|
||||
[Throws] void blur();
|
||||
};
|
||||
|
||||
// http://dev.w3.org/csswg/cssom-view/
|
||||
enum ScrollLogicalPosition { "start", "center", "end", "nearest" };
|
||||
dictionary ScrollIntoViewOptions : ScrollOptions {
|
||||
|
||||
@@ -22,8 +22,6 @@ interface HTMLElement : Element {
|
||||
// attribute boolean translate;
|
||||
[CEReactions, SetterThrows, Pure]
|
||||
attribute DOMString dir;
|
||||
[Constant]
|
||||
readonly attribute DOMStringMap dataset;
|
||||
|
||||
[CEReactions, GetterThrows, Pure]
|
||||
attribute [TreatNullAs=EmptyString] DOMString innerText;
|
||||
@@ -32,12 +30,6 @@ interface HTMLElement : Element {
|
||||
[CEReactions, SetterThrows, Pure]
|
||||
attribute boolean hidden;
|
||||
void click();
|
||||
[CEReactions, SetterThrows, Pure]
|
||||
attribute long tabIndex;
|
||||
[Throws]
|
||||
void focus();
|
||||
[Throws]
|
||||
void blur();
|
||||
[CEReactions, SetterThrows, Pure]
|
||||
attribute DOMString accessKey;
|
||||
[Pure]
|
||||
@@ -92,6 +84,7 @@ interface mixin TouchEventHandlers {
|
||||
};
|
||||
|
||||
HTMLElement includes GlobalEventHandlers;
|
||||
HTMLElement includes HTMLOrForeignElement;
|
||||
HTMLElement includes DocumentAndElementEventHandlers;
|
||||
HTMLElement includes ElementCSSInlineStyle;
|
||||
HTMLElement includes TouchEventHandlers;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
[Exposed=Window]
|
||||
interface MathMLElement : Element { };
|
||||
MathMLElement includes GlobalEventHandlers;
|
||||
//MathMLElement includes HTMLOrForeignElement;
|
||||
MathMLElement includes HTMLOrForeignElement;
|
||||
MathMLElement includes DocumentAndElementEventHandlers;
|
||||
MathMLElement includes ElementCSSInlineStyle;
|
||||
MathMLElement includes TouchEventHandlers;
|
||||
@@ -15,18 +15,13 @@ interface SVGElement : Element {
|
||||
|
||||
[Constant]
|
||||
readonly attribute SVGAnimatedString className;
|
||||
[SameObject] readonly attribute DOMStringMap dataset;
|
||||
|
||||
readonly attribute SVGSVGElement? ownerSVGElement;
|
||||
readonly attribute SVGElement? viewportElement;
|
||||
|
||||
[SetterThrows, Pure]
|
||||
attribute long tabIndex;
|
||||
[Throws] void focus();
|
||||
[Throws] void blur();
|
||||
};
|
||||
|
||||
SVGElement includes GlobalEventHandlers;
|
||||
SVGElement includes HTMLOrForeignElement;
|
||||
SVGElement includes DocumentAndElementEventHandlers;
|
||||
SVGElement includes ElementCSSInlineStyle;
|
||||
SVGElement includes TouchEventHandlers;
|
||||
|
||||
@@ -96,10 +96,6 @@ interface XULElement : Element {
|
||||
[Throws]
|
||||
readonly attribute BoxObject? boxObject;
|
||||
|
||||
[Throws]
|
||||
void focus();
|
||||
[Throws]
|
||||
void blur();
|
||||
[Throws]
|
||||
void click();
|
||||
void doCommand();
|
||||
@@ -134,6 +130,7 @@ interface mixin MozFrameLoaderOwner {
|
||||
|
||||
XULElement includes GlobalEventHandlers;
|
||||
XULElement includes ElementCSSInlineStyle;
|
||||
XULElement includes HTMLOrForeignElement;
|
||||
XULElement includes TouchEventHandlers;
|
||||
XULElement includes MozFrameLoaderOwner;
|
||||
XULElement includes OnErrorEventHandlerForNodes;
|
||||
|
||||
@@ -1720,7 +1720,8 @@ NS_IMETHODIMP
|
||||
nsXULElement::Focus()
|
||||
{
|
||||
ErrorResult rv;
|
||||
Focus(rv);
|
||||
FocusOptions options;
|
||||
Focus(options, rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
|
||||
@@ -308,7 +308,11 @@ public:
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
if (mNumber->AsElement()->State().HasState(NS_EVENT_STATE_FOCUS)) {
|
||||
HTMLInputElement::FromContent(mTextField)->Focus();
|
||||
// This job shouldn't be triggered by a WebIDL interface, hence the
|
||||
// default options can be used.
|
||||
FocusOptions options;
|
||||
ErrorResult rv;
|
||||
HTMLInputElement::FromContent(mTextField)->Focus(options, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -595,7 +599,11 @@ nsNumberControlFrame::HandleFocusEvent(WidgetEvent* aEvent)
|
||||
if (aEvent->mOriginalTarget != mTextField) {
|
||||
// Move focus to our text field
|
||||
RefPtr<HTMLInputElement> textField = HTMLInputElement::FromContent(mTextField);
|
||||
textField->Focus();
|
||||
// Use default FocusOptions, because this method isn't supposed to be called
|
||||
// from a WebIDL interface.
|
||||
FocusOptions options;
|
||||
ErrorResult rv;
|
||||
textField->Focus(options, rv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user