зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 4 changesets (bug 1733384) for causing failures at browser_windowPrompt.js. CLOSED TREE
Backed out changeset fa609fadac26 (bug 1733384) Backed out changeset dd1936d9fe17 (bug 1733384) Backed out changeset 1a073e40ab1a (bug 1733384) Backed out changeset 65708a4c708f (bug 1733384)
This commit is contained in:
Родитель
92b7c2a045
Коммит
4d927c1fb4
|
@ -39,6 +39,11 @@ add_task(async function test_check_window_modal_prompt_service() {
|
|||
dialogWin?.docShell?.chromeEventHandler,
|
||||
"Should have embedded the dialog."
|
||||
);
|
||||
is(
|
||||
window.getComputedStyle(document.body).getPropertyValue("-moz-user-input"),
|
||||
"none",
|
||||
"Browser window should be inert."
|
||||
);
|
||||
for (let menu of document.querySelectorAll("menubar > menu")) {
|
||||
ok(menu.disabled, `Menu ${menu.id} should be disabled.`);
|
||||
}
|
||||
|
@ -60,6 +65,11 @@ add_task(async function test_check_window_modal_prompt_service() {
|
|||
);
|
||||
|
||||
// Check we cleaned up:
|
||||
is(
|
||||
window.getComputedStyle(document.body).getPropertyValue("-moz-user-input"),
|
||||
"auto",
|
||||
"Browser window should no longer be inert."
|
||||
);
|
||||
for (let menu of document.querySelectorAll("menubar > menu")) {
|
||||
ok(!menu.disabled, `Menu ${menu.id} should not be disabled anymore.`);
|
||||
}
|
||||
|
|
|
@ -3371,6 +3371,7 @@ nsresult EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
bool suppressBlur = false;
|
||||
if (mCurrentTarget) {
|
||||
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(newFocus));
|
||||
const nsStyleUI* ui = mCurrentTarget->StyleUI();
|
||||
activeContent = mCurrentTarget->GetContent();
|
||||
|
||||
// In some cases, we do not want to even blur the current focused
|
||||
|
@ -3384,8 +3385,7 @@ nsresult EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
// we click on a non-focusable element like a <div>.
|
||||
// We have to use |aEvent->mTarget| to not make sure we do not check
|
||||
// an anonymous node of the targeted element.
|
||||
suppressBlur =
|
||||
mCurrentTarget->StyleUI()->UserFocus() == StyleUserFocus::Ignore;
|
||||
suppressBlur = (ui->mUserFocus == StyleUserFocus::Ignore);
|
||||
|
||||
nsCOMPtr<Element> element = do_QueryInterface(aEvent->mTarget);
|
||||
if (!suppressBlur && element) {
|
||||
|
@ -4071,7 +4071,7 @@ static CursorImage ComputeCustomCursor(nsPresContext* aPresContext,
|
|||
// If we are falling back because any cursor before us is loading, let the
|
||||
// consumer know.
|
||||
bool loading = false;
|
||||
for (const auto& image : style.StyleUI()->Cursor().images.AsSpan()) {
|
||||
for (const auto& image : style.StyleUI()->mCursor.images.AsSpan()) {
|
||||
MOZ_ASSERT(image.image.IsImageRequestType(),
|
||||
"Cursor image should only parse url() types");
|
||||
uint32_t status;
|
||||
|
@ -5606,9 +5606,11 @@ bool EventStateManager::SetContentState(nsIContent* aContent,
|
|||
|
||||
// check to see that this state is allowed by style. Check dragover too?
|
||||
// XXX Is this even what we want?
|
||||
if (mCurrentTarget &&
|
||||
mCurrentTarget->StyleUI()->UserInput() == StyleUserInput::None) {
|
||||
return false;
|
||||
if (mCurrentTarget) {
|
||||
const nsStyleUI* ui = mCurrentTarget->StyleUI();
|
||||
if (ui->mUserInput == StyleUserInput::None) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (aState == NS_EVENT_STATE_ACTIVE) {
|
||||
|
|
|
@ -39,7 +39,7 @@ void HTMLOptGroupElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
|
|||
if (nsIFrame* frame = GetPrimaryFrame()) {
|
||||
// FIXME(emilio): This poking at the style of the frame is broken unless we
|
||||
// flush before every event handling, which we don't really want to.
|
||||
if (frame->StyleUI()->UserInput() == StyleUserInput::None) {
|
||||
if (frame->StyleUI()->mUserInput == StyleUserInput::None) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1948,7 +1948,7 @@ bool nsGenericHTMLFormElement::IsElementDisabledForEvents(WidgetEvent* aEvent,
|
|||
|
||||
// FIXME(emilio): This poking at the style of the frame is slightly bogus
|
||||
// unless we flush before every event, which we don't really want to do.
|
||||
if (aFrame && aFrame->StyleUI()->UserInput() == StyleUserInput::None) {
|
||||
if (aFrame && aFrame->StyleUI()->mUserInput == StyleUserInput::None) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -185,8 +185,8 @@ nsresult nsXULPopupListener::FireFocusOnTargetContent(
|
|||
nsIFrame* targetFrame = aTargetContent->GetPrimaryFrame();
|
||||
if (!targetFrame) return NS_ERROR_FAILURE;
|
||||
|
||||
const bool suppressBlur =
|
||||
targetFrame->StyleUI()->UserFocus() == StyleUserFocus::Ignore;
|
||||
const nsStyleUI* ui = targetFrame->StyleUI();
|
||||
bool suppressBlur = (ui->mUserFocus == StyleUserFocus::Ignore);
|
||||
|
||||
RefPtr<Element> newFocusElement;
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ static nsIContent* GetClickableAncestor(
|
|||
// this check to any non-auto cursor. Such a change would also pick up things
|
||||
// like contenteditable or input fields, which can then be removed from the
|
||||
// loop below, and would have better performance.
|
||||
if (aFrame->StyleUI()->Cursor().keyword == StyleCursorKind::Pointer) {
|
||||
if (aFrame->StyleUI()->mCursor.keyword == StyleCursorKind::Pointer) {
|
||||
return aFrame->GetContent();
|
||||
}
|
||||
|
||||
|
|
|
@ -4010,8 +4010,7 @@ nsresult nsCSSFrameConstructor::GetAnonymousContent(
|
|||
StaticPrefs::layout_css_cached_scrollbar_styles_enabled() &&
|
||||
aParentFrame->StyleVisibility()->mVisible == StyleVisibility::Visible &&
|
||||
#ifndef ANDROID
|
||||
aParentFrame->StyleUI()->ComputedPointerEvents() ==
|
||||
StylePointerEvents::Auto &&
|
||||
aParentFrame->StyleUI()->mPointerEvents == StylePointerEvents::Auto &&
|
||||
#endif
|
||||
mPresShell->GetPresContext()->Medium() == nsGkAtoms::screen;
|
||||
|
||||
|
@ -4067,8 +4066,7 @@ nsresult nsCSSFrameConstructor::GetAnonymousContent(
|
|||
"cached anonymous content styles should be identical to those we "
|
||||
"would compute normally");
|
||||
# ifdef ANDROID
|
||||
MOZ_ASSERT(cs->StyleUI()->ComputedPointerEvents() ==
|
||||
StylePointerEvents::None);
|
||||
MOZ_ASSERT(cs->StyleUI()->mPointerEvents == StylePointerEvents::None);
|
||||
# endif
|
||||
#endif
|
||||
Servo_SetExplicitStyle(elements[i], cachedStyles[i]);
|
||||
|
|
|
@ -510,7 +510,7 @@ nsIFrame* nsCaret::GetPaintGeometry(nsRect* aCaretRect, nsRect* aHookRect,
|
|||
// since the <br> we're focused at is editable, but we do want to paint it at
|
||||
// the adjusted frame offset, so that we can see the collapsed whitespace.
|
||||
const nsStyleUI* ui = unadjustedFrame->StyleUI();
|
||||
if ((!mIgnoreUserModify && ui->UserModify() == StyleUserModify::ReadOnly) ||
|
||||
if ((!mIgnoreUserModify && ui->mUserModify == StyleUserModify::ReadOnly) ||
|
||||
unadjustedFrame->IsContentDisabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ nsresult nsImageControlFrame::HandleEvent(nsPresContext* aPresContext,
|
|||
void nsImageControlFrame::SetFocus(bool aOn, bool aRepaint) {}
|
||||
|
||||
Maybe<nsIFrame::Cursor> nsImageControlFrame::GetCursor(const nsPoint&) {
|
||||
StyleCursorKind kind = StyleUI()->Cursor().keyword;
|
||||
StyleCursorKind kind = StyleUI()->mCursor.keyword;
|
||||
if (kind == StyleCursorKind::Auto) {
|
||||
kind = StyleCursorKind::Pointer;
|
||||
}
|
||||
|
|
|
@ -3102,8 +3102,9 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
|||
this, nsCSSPropertyIDSet::OpacityProperties());
|
||||
// We can stop right away if this is a zero-opacity stacking context and
|
||||
// we're painting, and we're not animating opacity.
|
||||
bool needHitTestInfo = aBuilder->BuildCompositorHitTestInfo() &&
|
||||
Style()->PointerEvents() != StylePointerEvents::None;
|
||||
bool needHitTestInfo =
|
||||
aBuilder->BuildCompositorHitTestInfo() &&
|
||||
StyleUI()->GetEffectivePointerEvents(this) != StylePointerEvents::None;
|
||||
bool opacityItemForEventsOnly = false;
|
||||
if (effects->mOpacity == 0.0 && aBuilder->IsForPainting() &&
|
||||
!(disp->mWillChange.bits & StyleWillChangeBits::OPACITY) &&
|
||||
|
@ -4525,14 +4526,8 @@ static bool IsEditingHost(const nsIFrame* aFrame) {
|
|||
return element && element->IsEditableRoot();
|
||||
}
|
||||
|
||||
static bool IsTopmostModalDialog(const nsIFrame* aFrame) {
|
||||
auto* element = Element::FromNodeOrNull(aFrame->GetContent());
|
||||
return element &&
|
||||
element->State().HasState(NS_EVENT_STATE_TOPMOST_MODAL_DIALOG);
|
||||
}
|
||||
|
||||
static StyleUserSelect UsedUserSelect(const nsIFrame* aFrame) {
|
||||
if (aFrame->IsGeneratedContentFrame()) {
|
||||
if (aFrame->HasAnyStateBits(NS_FRAME_GENERATED_CONTENT)) {
|
||||
return StyleUserSelect::None;
|
||||
}
|
||||
|
||||
|
@ -4550,19 +4545,15 @@ static StyleUserSelect UsedUserSelect(const nsIFrame* aFrame) {
|
|||
//
|
||||
// Also, we check for auto first to allow explicitly overriding the value for
|
||||
// the editing host.
|
||||
auto style = aFrame->Style()->UserSelect();
|
||||
auto style = aFrame->StyleUIReset()->mUserSelect;
|
||||
if (style != StyleUserSelect::Auto) {
|
||||
return style;
|
||||
}
|
||||
|
||||
if (aFrame->IsTextInputFrame() || IsEditingHost(aFrame) ||
|
||||
IsTopmostModalDialog(aFrame)) {
|
||||
if (aFrame->IsTextInputFrame() || IsEditingHost(aFrame)) {
|
||||
// We don't implement 'contain' itself, but we make 'text' behave as
|
||||
// 'contain' for contenteditable and <input> / <textarea> elements anyway so
|
||||
// this is ok.
|
||||
//
|
||||
// Topmost modal dialogs need to behave like `text` too, because they're
|
||||
// supposed to be selectable even if their ancestors are inert.
|
||||
return StyleUserSelect::Text;
|
||||
}
|
||||
|
||||
|
@ -4842,7 +4833,7 @@ nsresult nsIFrame::MoveCaretToEventPoint(nsPresContext* aPresContext,
|
|||
(offsets.EndOffset() - offsets.StartOffset()) == 1) {
|
||||
// A single node is selected and we aren't extending an existing
|
||||
// selection, which means the user clicked directly on an object (either
|
||||
// user-select: all or a non-text node without children).
|
||||
// -moz-user-select: all or a non-text node without children).
|
||||
// Therefore, disable selection extension during mouse moves.
|
||||
// XXX This is a bit hacky; shouldn't editor be able to deal with this?
|
||||
fc->SetDragState(false);
|
||||
|
@ -5309,7 +5300,7 @@ static bool SelfIsSelectable(nsIFrame* aFrame, uint32_t aFlags) {
|
|||
return false;
|
||||
}
|
||||
return !aFrame->IsGeneratedContentFrame() &&
|
||||
aFrame->Style()->UserSelect() != StyleUserSelect::None;
|
||||
aFrame->StyleUIReset()->mUserSelect != StyleUserSelect::None;
|
||||
}
|
||||
|
||||
static bool SelectionDescendToKids(nsIFrame* aFrame) {
|
||||
|
@ -5337,7 +5328,7 @@ static bool SelectionDescendToKids(nsIFrame* aFrame) {
|
|||
return false;
|
||||
}
|
||||
|
||||
auto style = aFrame->Style()->UserSelect();
|
||||
auto style = aFrame->StyleUIReset()->mUserSelect;
|
||||
return style != StyleUserSelect::All && style != StyleUserSelect::None;
|
||||
}
|
||||
|
||||
|
@ -5601,7 +5592,7 @@ static nsIFrame* AdjustFrameForSelectionStyles(nsIFrame* aFrame) {
|
|||
for (nsIFrame* frame = aFrame; frame; frame = frame->GetParent()) {
|
||||
// These are the conditions that make all children not able to handle
|
||||
// a cursor.
|
||||
auto userSelect = frame->Style()->UserSelect();
|
||||
StyleUserSelect userSelect = frame->StyleUIReset()->mUserSelect;
|
||||
if (userSelect != StyleUserSelect::Auto &&
|
||||
userSelect != StyleUserSelect::All) {
|
||||
break;
|
||||
|
@ -5628,9 +5619,9 @@ nsIFrame::ContentOffsets nsIFrame::GetContentOffsetsFromPoint(
|
|||
|
||||
adjustedFrame = AdjustFrameForSelectionStyles(this);
|
||||
|
||||
// user-select: all needs special handling, because clicking on it
|
||||
// -moz-user-select: all needs special handling, because clicking on it
|
||||
// should lead to the whole frame being selected
|
||||
if (adjustedFrame->Style()->UserSelect() == StyleUserSelect::All) {
|
||||
if (adjustedFrame->StyleUIReset()->mUserSelect == StyleUserSelect::All) {
|
||||
nsPoint adjustedPoint = aPoint + this->GetOffsetTo(adjustedFrame);
|
||||
return OffsetsForSingleFrame(adjustedFrame, adjustedPoint);
|
||||
}
|
||||
|
@ -5721,7 +5712,7 @@ StyleImageRendering nsIFrame::UsedImageRendering() const {
|
|||
}
|
||||
|
||||
Maybe<nsIFrame::Cursor> nsIFrame::GetCursor(const nsPoint&) {
|
||||
StyleCursorKind kind = StyleUI()->Cursor().keyword;
|
||||
StyleCursorKind kind = StyleUI()->mCursor.keyword;
|
||||
if (kind == StyleCursorKind::Auto) {
|
||||
// If this is editable, I-beam cursor is better for most elements.
|
||||
kind = (mContent && mContent->IsEditable()) ? StyleCursorKind::Text
|
||||
|
@ -6776,7 +6767,7 @@ void nsIFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
|
|||
bool nsIFrame::IsContentDisabled() const {
|
||||
// FIXME(emilio): Doing this via CSS means callers must ensure the style is up
|
||||
// to date, and they don't!
|
||||
if (StyleUI()->UserInput() == StyleUserInput::None) {
|
||||
if (StyleUI()->mUserInput == StyleUserInput::None) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -10216,8 +10207,8 @@ nsIFrame::Focusable nsIFrame::IsFocusable(bool aWithMouse) {
|
|||
return {};
|
||||
}
|
||||
|
||||
const nsStyleUI& ui = *StyleUI();
|
||||
if (ui.IsInert()) {
|
||||
const nsStyleUI* ui = StyleUI();
|
||||
if (ui->mInert == StyleInert::Inert) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -10228,8 +10219,8 @@ nsIFrame::Focusable nsIFrame::IsFocusable(bool aWithMouse) {
|
|||
}
|
||||
|
||||
int32_t tabIndex = -1;
|
||||
if (ui.UserFocus() != StyleUserFocus::Ignore &&
|
||||
ui.UserFocus() != StyleUserFocus::None) {
|
||||
if (ui->mUserFocus != StyleUserFocus::Ignore &&
|
||||
ui->mUserFocus != StyleUserFocus::None) {
|
||||
// Pass in default tabindex of -1 for nonfocusable and 0 for focusable
|
||||
tabIndex = 0;
|
||||
}
|
||||
|
@ -11292,7 +11283,9 @@ CompositorHitTestInfo nsIFrame::GetCompositorHitTestInfo(
|
|||
// frames, are the event targets for any regions viewport frames may cover.
|
||||
return result;
|
||||
}
|
||||
if (Style()->PointerEvents() == StylePointerEvents::None) {
|
||||
const StylePointerEvents pointerEvents =
|
||||
StyleUI()->GetEffectivePointerEvents(this);
|
||||
if (pointerEvents == StylePointerEvents::None) {
|
||||
return result;
|
||||
}
|
||||
if (!StyleVisibility()->IsVisible()) {
|
||||
|
|
|
@ -4147,7 +4147,7 @@ class nsIFrame : public nsQueryFrame {
|
|||
* @return whether the frame correspods to generated content
|
||||
*/
|
||||
bool IsGeneratedContentFrame() const {
|
||||
return HasAnyStateBits(NS_FRAME_GENERATED_CONTENT);
|
||||
return (mState & NS_FRAME_GENERATED_CONTENT) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2531,7 +2531,7 @@ Maybe<nsIFrame::Cursor> nsImageFrame::GetCursor(const nsPoint& aPoint) {
|
|||
// get styles out of the blue and expect to trigger image loads for those.
|
||||
areaStyle->StartImageLoads(*PresContext()->Document());
|
||||
|
||||
StyleCursorKind kind = areaStyle->StyleUI()->Cursor().keyword;
|
||||
StyleCursorKind kind = areaStyle->StyleUI()->mCursor.keyword;
|
||||
if (kind == StyleCursorKind::Auto) {
|
||||
kind = StyleCursorKind::Default;
|
||||
}
|
||||
|
|
|
@ -334,8 +334,8 @@ void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
bool isRemoteFrame = frameLoader && frameLoader->IsRemoteFrame();
|
||||
|
||||
// If we are pointer-events:none then we don't need to HitTest background
|
||||
const bool pointerEventsNone =
|
||||
Style()->PointerEvents() == StylePointerEvents::None;
|
||||
bool pointerEventsNone =
|
||||
StyleUI()->mPointerEvents == StylePointerEvents::None;
|
||||
if (!aBuilder->IsForEventDelivery() || !pointerEventsNone) {
|
||||
nsDisplayListCollection decorations(aBuilder);
|
||||
DisplayBorderBackgroundOutline(aBuilder, decorations);
|
||||
|
@ -1265,8 +1265,8 @@ nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder,
|
|||
nsSubDocumentFrame* aFrame)
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame),
|
||||
mEventRegionsOverride(EventRegionsOverride::NoOverride) {
|
||||
const bool frameIsPointerEventsNone =
|
||||
aFrame->Style()->PointerEvents() == StylePointerEvents::None;
|
||||
bool frameIsPointerEventsNone = aFrame->StyleUI()->GetEffectivePointerEvents(
|
||||
aFrame) == StylePointerEvents::None;
|
||||
if (aBuilder->IsInsidePointerEventsNoneDoc() || frameIsPointerEventsNone) {
|
||||
mEventRegionsOverride |= EventRegionsOverride::ForceEmptyHitRegion;
|
||||
}
|
||||
|
|
|
@ -4692,7 +4692,7 @@ NS_IMPL_FRAMEARENA_HELPERS(nsContinuingTextFrame)
|
|||
nsTextFrame::~nsTextFrame() = default;
|
||||
|
||||
Maybe<nsIFrame::Cursor> nsTextFrame::GetCursor(const nsPoint& aPoint) {
|
||||
StyleCursorKind kind = StyleUI()->Cursor().keyword;
|
||||
StyleCursorKind kind = StyleUI()->mCursor.keyword;
|
||||
if (kind == StyleCursorKind::Auto) {
|
||||
if (!IsSelectable(nullptr)) {
|
||||
kind = StyleCursorKind::Default;
|
||||
|
|
|
@ -2295,7 +2295,8 @@ void nsDisplayList::DeleteAll(nsDisplayListBuilder* aBuilder) {
|
|||
}
|
||||
|
||||
static bool IsFrameReceivingPointerEvents(nsIFrame* aFrame) {
|
||||
return aFrame->Style()->PointerEvents() != StylePointerEvents::None;
|
||||
return StylePointerEvents::None !=
|
||||
aFrame->StyleUI()->GetEffectivePointerEvents(aFrame);
|
||||
}
|
||||
|
||||
// A list of frames, and their z depth. Used for sorting
|
||||
|
|
|
@ -222,9 +222,6 @@ class ComputedStyle {
|
|||
#include "nsStyleStructList.h"
|
||||
#undef STYLE_STRUCT
|
||||
|
||||
inline mozilla::StylePointerEvents PointerEvents() const;
|
||||
inline mozilla::StyleUserSelect UserSelect() const;
|
||||
|
||||
/**
|
||||
* Compute the style changes needed during restyling when this style
|
||||
* context is being replaced by aNewContext. (This is nonsymmetric since
|
||||
|
|
|
@ -49,25 +49,6 @@ void ComputedStyle::StartImageLoads(dom::Document& aDocument,
|
|||
#undef STYLE_STRUCT
|
||||
}
|
||||
|
||||
StylePointerEvents ComputedStyle::PointerEvents() const {
|
||||
if (IsRootElementStyle()) {
|
||||
// The root frame is not allowed to have pointer-events: none, or else no
|
||||
// frames could be hit test against and scrolling the viewport would not
|
||||
// work.
|
||||
return StylePointerEvents::Auto;
|
||||
}
|
||||
auto& ui = *StyleUI();
|
||||
if (ui.IsInert()) {
|
||||
return StylePointerEvents::None;
|
||||
}
|
||||
return ui.ComputedPointerEvents();
|
||||
}
|
||||
|
||||
StyleUserSelect ComputedStyle::UserSelect() const {
|
||||
return StyleUI()->IsInert() ? StyleUserSelect::None
|
||||
: StyleUIReset()->ComputedUserSelect();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // ComputedStyleInlines_h
|
||||
|
|
|
@ -666,7 +666,7 @@ static void CollectImageURLsForProperty(nsCSSPropertyID aProp,
|
|||
|
||||
switch (aProp) {
|
||||
case eCSSProperty_cursor:
|
||||
for (auto& image : aStyle.StyleUI()->Cursor().images.AsSpan()) {
|
||||
for (auto& image : aStyle.StyleUI()->mCursor.images.AsSpan()) {
|
||||
AddImageURL(image.image, aURLs);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1716,12 +1716,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset {
|
|||
|
||||
nsChangeHint CalcDifference(const nsStyleUIReset& aNewData) const;
|
||||
|
||||
private:
|
||||
mozilla::StyleUserSelect mUserSelect; // Use ComputedStyle::UserSelect()
|
||||
|
||||
public:
|
||||
mozilla::StyleUserSelect ComputedUserSelect() const { return mUserSelect; }
|
||||
|
||||
mozilla::StyleUserSelect mUserSelect; // [reset](selection-style)
|
||||
mozilla::StyleScrollbarWidth mScrollbarWidth;
|
||||
uint8_t mMozForceBrokenImageIcon; // (0 if not forcing, otherwise forcing)
|
||||
mozilla::StyleImeMode mIMEMode;
|
||||
|
@ -1743,45 +1738,21 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUI {
|
|||
nsChangeHint CalcDifference(const nsStyleUI& aNewData) const;
|
||||
|
||||
mozilla::StyleInert mInert;
|
||||
|
||||
private:
|
||||
mozilla::StyleUserInput mUserInput;
|
||||
mozilla::StyleUserModify mUserModify;
|
||||
mozilla::StyleUserFocus mUserFocus;
|
||||
mozilla::StyleUserModify mUserModify; // (modify-content)
|
||||
mozilla::StyleUserFocus mUserFocus; // (auto-select)
|
||||
mozilla::StylePointerEvents mPointerEvents;
|
||||
|
||||
mozilla::StyleCursor mCursor;
|
||||
|
||||
public:
|
||||
bool IsInert() const { return mInert == mozilla::StyleInert::Inert; }
|
||||
|
||||
mozilla::StyleUserInput UserInput() const {
|
||||
return IsInert() ? mozilla::StyleUserInput::None : mUserInput;
|
||||
}
|
||||
|
||||
mozilla::StyleUserModify UserModify() const {
|
||||
return IsInert() ? mozilla::StyleUserModify::ReadOnly : mUserModify;
|
||||
}
|
||||
|
||||
mozilla::StyleUserFocus UserFocus() const {
|
||||
return IsInert() ? mozilla::StyleUserFocus::None : mUserFocus;
|
||||
}
|
||||
|
||||
// This is likely not the getter you want (you probably want
|
||||
// ComputedStyle::PointerEvents().
|
||||
mozilla::StylePointerEvents ComputedPointerEvents() const {
|
||||
return mPointerEvents;
|
||||
}
|
||||
|
||||
const mozilla::StyleCursor& Cursor() const {
|
||||
static mozilla::StyleCursor sAuto{{}, mozilla::StyleCursorKind::Auto};
|
||||
return IsInert() ? sAuto : mCursor;
|
||||
}
|
||||
|
||||
mozilla::StyleColorOrAuto mAccentColor;
|
||||
mozilla::StyleCaretColor mCaretColor;
|
||||
mozilla::StyleScrollbarColor mScrollbarColor;
|
||||
mozilla::StyleColorScheme mColorScheme;
|
||||
|
||||
inline mozilla::StylePointerEvents GetEffectivePointerEvents(
|
||||
const nsIFrame*) const;
|
||||
|
||||
bool HasCustomScrollbars() const { return !mScrollbarColor.IsAuto(); }
|
||||
};
|
||||
|
||||
|
|
|
@ -178,6 +178,17 @@ bool nsStyleDisplay::IsAbsolutelyPositioned(
|
|||
!mozilla::SVGUtils::IsInSVGTextSubtree(aContextFrame);
|
||||
}
|
||||
|
||||
mozilla::StylePointerEvents nsStyleUI::GetEffectivePointerEvents(
|
||||
const nsIFrame* aFrame) const {
|
||||
if (aFrame->GetContent() && !aFrame->GetContent()->GetParent()) {
|
||||
// The root frame is not allowed to have pointer-events: none, or else
|
||||
// no frames could be hit test against and scrolling the viewport would
|
||||
// not work.
|
||||
return mozilla::StylePointerEvents::Auto;
|
||||
}
|
||||
return mPointerEvents;
|
||||
}
|
||||
|
||||
bool nsStyleBackground::HasLocalBackground() const {
|
||||
NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, mImage) {
|
||||
const nsStyleImageLayers::Layer& layer = mImage.mLayers[i];
|
||||
|
|
|
@ -828,12 +828,18 @@ dialog:not([open]) {
|
|||
display: none;
|
||||
}
|
||||
|
||||
/* This pseudo-class is used to remove the inertness for the topmost modal
|
||||
* dialog in top layer.
|
||||
*
|
||||
* Avoid doing this if the dialog is explicitly inert though. */
|
||||
dialog:not([inert]):-moz-topmost-modal-dialog {
|
||||
/* This pseudo-class is used to remove the inertness for
|
||||
the topmost modal dialog in top layer. This reverts
|
||||
what StyleAdjuster's adjust_for_inert does.
|
||||
*/
|
||||
dialog:-moz-topmost-modal-dialog {
|
||||
-moz-inert: none;
|
||||
-moz-user-focus: initial;
|
||||
-moz-user-input: initial;
|
||||
-moz-user-modify: initial;
|
||||
user-select: text;
|
||||
pointer-events: initial;
|
||||
cursor: initial;
|
||||
}
|
||||
|
||||
dialog:-moz-modal-dialog {
|
||||
|
|
|
@ -783,7 +783,7 @@ void SVGImageFrame::ReflowCallbackCanceled() { mReflowCallbackPosted = false; }
|
|||
uint16_t SVGImageFrame::GetHitTestFlags() {
|
||||
uint16_t flags = 0;
|
||||
|
||||
switch (Style()->PointerEvents()) {
|
||||
switch (StyleUI()->mPointerEvents) {
|
||||
case StylePointerEvents::None:
|
||||
break;
|
||||
case StylePointerEvents::Visiblepainted:
|
||||
|
|
|
@ -1539,7 +1539,7 @@ void SVGUtils::SetupStrokeGeometry(nsIFrame* aFrame, gfxContext* aContext,
|
|||
uint16_t SVGUtils::GetGeometryHitTestFlags(nsIFrame* aFrame) {
|
||||
uint16_t flags = 0;
|
||||
|
||||
switch (aFrame->Style()->PointerEvents()) {
|
||||
switch (aFrame->StyleUI()->mPointerEvents) {
|
||||
case StylePointerEvents::None:
|
||||
break;
|
||||
case StylePointerEvents::Auto:
|
||||
|
|
|
@ -200,7 +200,8 @@ void nsMenuPopupFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
|||
// If pointer-events: none; is set on the popup, then the widget should
|
||||
// ignore mouse events, passing them through to the content behind.
|
||||
bool nsMenuPopupFrame::IsMouseTransparent(const ComputedStyle& aStyle) const {
|
||||
return aStyle.PointerEvents() == StylePointerEvents::None;
|
||||
return aStyle.StyleUI()->GetEffectivePointerEvents(this) ==
|
||||
StylePointerEvents::None;
|
||||
}
|
||||
|
||||
bool nsMenuPopupFrame::HasRemoteContent() const {
|
||||
|
|
|
@ -2254,7 +2254,7 @@ Maybe<nsIFrame::Cursor> nsTreeBodyFrame::GetCursor(const nsPoint& aPoint) {
|
|||
if (child) {
|
||||
// Our scratch array is already prefilled.
|
||||
RefPtr<ComputedStyle> childContext = GetPseudoComputedStyle(child);
|
||||
StyleCursorKind kind = childContext->StyleUI()->Cursor().keyword;
|
||||
StyleCursorKind kind = childContext->StyleUI()->mCursor.keyword;
|
||||
if (kind == StyleCursorKind::Auto) {
|
||||
kind = StyleCursorKind::Default;
|
||||
}
|
||||
|
|
|
@ -153,6 +153,62 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/#inert-subtrees
|
||||
///
|
||||
/// If -moz-inert is applied then add:
|
||||
/// -moz-user-focus: none;
|
||||
/// -moz-user-input: none;
|
||||
/// -moz-user-modify: read-only;
|
||||
/// user-select: none;
|
||||
/// pointer-events: none;
|
||||
/// cursor: default;
|
||||
///
|
||||
/// NOTE: dialog:-moz-topmost-modal-dialog is used to override above
|
||||
/// rules to remove the inertness for the topmost modal dialog.
|
||||
///
|
||||
/// NOTE: If this or the pointer-events tweak is removed, then
|
||||
/// minimal-xul.css and the scrollbar style caching need to be tweaked.
|
||||
fn adjust_for_inert(&mut self) {
|
||||
use crate::values::specified::ui::CursorKind;
|
||||
use crate::values::specified::ui::UserSelect;
|
||||
use properties::longhands::_moz_inert::computed_value::T as Inert;
|
||||
use properties::longhands::_moz_user_focus::computed_value::T as UserFocus;
|
||||
use properties::longhands::_moz_user_input::computed_value::T as UserInput;
|
||||
use properties::longhands::_moz_user_modify::computed_value::T as UserModify;
|
||||
use properties::longhands::cursor::computed_value::T as Cursor;
|
||||
use properties::longhands::pointer_events::computed_value::T as PointerEvents;
|
||||
|
||||
let needs_update = {
|
||||
let ui = self.style.get_inherited_ui();
|
||||
if ui.clone__moz_inert() == Inert::None {
|
||||
return;
|
||||
}
|
||||
|
||||
ui.clone__moz_user_focus() != UserFocus::None ||
|
||||
ui.clone__moz_user_input() != UserInput::None ||
|
||||
ui.clone__moz_user_modify() != UserModify::ReadOnly ||
|
||||
ui.clone_pointer_events() != PointerEvents::None ||
|
||||
ui.clone_cursor().keyword != CursorKind::Default ||
|
||||
ui.clone_cursor().images != Default::default()
|
||||
};
|
||||
|
||||
if needs_update {
|
||||
let ui = self.style.mutate_inherited_ui();
|
||||
ui.set__moz_user_focus(UserFocus::None);
|
||||
ui.set__moz_user_input(UserInput::None);
|
||||
ui.set__moz_user_modify(UserModify::ReadOnly);
|
||||
ui.set_pointer_events(PointerEvents::None);
|
||||
ui.set_cursor(Cursor {
|
||||
images: Default::default(),
|
||||
keyword: CursorKind::Default,
|
||||
});
|
||||
}
|
||||
|
||||
if self.style.get_ui().clone_user_select() != UserSelect::None {
|
||||
self.style.mutate_ui().set_user_select(UserSelect::None);
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether we should skip any item-based display property blockification on
|
||||
/// this element.
|
||||
fn skip_item_display_fixup<E>(&self, element: Option<E>) -> bool
|
||||
|
@ -852,6 +908,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
|||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
self.adjust_for_appearance(element);
|
||||
self.adjust_for_inert();
|
||||
self.adjust_for_marker_pseudo();
|
||||
}
|
||||
self.set_bits();
|
||||
|
|
|
@ -532,7 +532,7 @@ renaming_overrides_prefixing = true
|
|||
"""
|
||||
|
||||
"OwnedSlice" = """
|
||||
constexpr StyleOwnedSlice() :
|
||||
StyleOwnedSlice() :
|
||||
ptr((T*)alignof(T)),
|
||||
len(0) {}
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[dialog-inert.tentative.html]
|
||||
prefs: [html5.inert.enabled:true]
|
|
@ -1,45 +0,0 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<link rel="author" title="Mozilla" href="https://mozilla.org">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
body { margin: 0 }
|
||||
dialog {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
dialog::backdrop {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<dialog id=dialog>Something</dialog>
|
||||
<script>
|
||||
test(function() {
|
||||
let dialog = document.getElementById("dialog");
|
||||
dialog.showModal();
|
||||
assert_equals(
|
||||
document.elementFromPoint(10, 10),
|
||||
dialog,
|
||||
"Dialog is hittable by default",
|
||||
);
|
||||
dialog.inert = true;
|
||||
assert_not_equals(
|
||||
document.elementFromPoint(10, 10),
|
||||
dialog,
|
||||
"Dialog becomes inert dynamically",
|
||||
);
|
||||
dialog.close();
|
||||
dialog.showModal();
|
||||
assert_not_equals(
|
||||
document.elementFromPoint(10, 10),
|
||||
dialog,
|
||||
"Dialog remains inert after open",
|
||||
);
|
||||
});
|
||||
</script>
|
|
@ -1,49 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>inert isn't hit-testable, but that isn't expose in the computed style</title>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<link rel="author" title="Mozilla" href="https://mozilla.org">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
body { margin: 0 }
|
||||
div {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: blue;
|
||||
}
|
||||
#non-inert {
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
<div id="non-inert"></div>
|
||||
<div id="inert"></div>
|
||||
<script>
|
||||
test(function() {
|
||||
let inert = document.getElementById("inert");
|
||||
assert_equals(
|
||||
document.elementFromPoint(50, 50),
|
||||
inert,
|
||||
"not-yet-inert node hit-test before non-inert node",
|
||||
);
|
||||
inert.inert = true;
|
||||
assert_equals(
|
||||
document.elementFromPoint(50, 50),
|
||||
document.getElementById("non-inert"),
|
||||
"inert node is transparent to events (as pointer-events: none)",
|
||||
);
|
||||
assert_equals(
|
||||
getComputedStyle(inert).pointerEvents,
|
||||
"auto",
|
||||
"inert node doesn't change pointer-events computed value",
|
||||
);
|
||||
assert_equals(
|
||||
getComputedStyle(inert).userSelect,
|
||||
"auto",
|
||||
"inert node doesn't change pointer-events computed value",
|
||||
);
|
||||
});
|
||||
</script>
|
|
@ -3005,8 +3005,9 @@ nsresult nsNativeThemeWin::ClassicGetThemePartAndState(
|
|||
if (contentState.HasAllStates(NS_EVENT_STATE_ACTIVE |
|
||||
NS_EVENT_STATE_HOVER)) {
|
||||
aState |= DFCS_PUSHED;
|
||||
const nsStyleUI* uiData = aFrame->StyleUI();
|
||||
// The down state is flat if the button is focusable
|
||||
if (aFrame->StyleUI()->UserFocus() == StyleUserFocus::Normal) {
|
||||
if (uiData->mUserFocus == StyleUserFocus::Normal) {
|
||||
if (!aFrame->GetContent()->IsHTMLElement()) aState |= DFCS_FLAT;
|
||||
|
||||
aFocused = true;
|
||||
|
|
Загрузка…
Ссылка в новой задаче