From 5b129b77c52004f246063086ab49870a3ffa6fa8 Mon Sep 17 00:00:00 2001 From: Cosmin Sabou Date: Tue, 29 Aug 2023 21:14:42 +0300 Subject: [PATCH] Backed out changeset f14569b8319b (bug 1850342) for causing dt failures on browser_rules_inactive_css_visited.js. CLOSED TREE --- dom/base/nsImageLoadingContent.cpp | 5 ++ dom/base/nsImageLoadingContent.h | 2 +- dom/base/nsObjectLoadingContent.cpp | 5 +- dom/base/rust/lib.rs | 68 ++++++++++--------- dom/html/HTMLEmbedElement.cpp | 3 + dom/html/HTMLImageElement.cpp | 3 +- dom/html/HTMLObjectElement.cpp | 3 + layout/base/RestyleManager.cpp | 10 ++- layout/style/test/test_selectors.html | 1 + .../style/gecko/non_ts_pseudo_class_list.rs | 1 + servo/components/style/gecko/wrapper.rs | 1 + 11 files changed, 63 insertions(+), 39 deletions(-) diff --git a/dom/base/nsImageLoadingContent.cpp b/dom/base/nsImageLoadingContent.cpp index b3f440e67a6e..0bcab995a44f 100644 --- a/dom/base/nsImageLoadingContent.cpp +++ b/dom/base/nsImageLoadingContent.cpp @@ -1348,9 +1348,14 @@ CSSIntSize nsImageLoadingContent::GetWidthHeightForImage() { ElementState nsImageLoadingContent::ImageState() const { ElementState states; + if (mBroken) { states |= ElementState::BROKEN; } + if (mLoading) { + states |= ElementState::LOADING; + } + return states; } diff --git a/dom/base/nsImageLoadingContent.h b/dom/base/nsImageLoadingContent.h index 5a16df36d8ec..34a7ff38fcfd 100644 --- a/dom/base/nsImageLoadingContent.h +++ b/dom/base/nsImageLoadingContent.h @@ -554,7 +554,6 @@ class nsImageLoadingContent : public nsIImageLoadingContent { bool mLoadingEnabled : 1; - protected: /** * The state we had the last time we checked whether we needed to notify the * document of a state change. These are maintained by UpdateImageState. @@ -562,6 +561,7 @@ class nsImageLoadingContent : public nsIImageLoadingContent { bool mLoading : 1; bool mBroken : 1; + protected: /** * A hack to get animations to reset, see bug 594771. On requests * that originate from setting .src, we mark them for needing their animation diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp index be5df0b4d94b..8d22662f5b5d 100644 --- a/dom/base/nsObjectLoadingContent.cpp +++ b/dom/base/nsObjectLoadingContent.cpp @@ -680,7 +680,7 @@ nsObjectLoadingContent::AsyncOnChannelRedirect( ElementState nsObjectLoadingContent::ObjectState() const { switch (mType) { case eType_Loading: - return {}; + return ElementState::LOADING; case eType_Image: return ImageState(); case eType_FakePlugin: @@ -690,6 +690,7 @@ ElementState nsObjectLoadingContent::ObjectState() const { // plugins. ElementState states = ElementState(); if (mLoadingSyntheticDocument) { + states |= ElementState::LOADING; states |= ImageState(); } return states; @@ -702,7 +703,7 @@ ElementState nsObjectLoadingContent::ObjectState() const { return ElementState::BROKEN; } MOZ_ASSERT_UNREACHABLE("unknown type?"); - return {}; + return ElementState::LOADING; } void nsObjectLoadingContent::MaybeRewriteYoutubeEmbed(nsIURI* aURI, diff --git a/dom/base/rust/lib.rs b/dom/base/rust/lib.rs index f3c13d40f77c..f9c94f97e4af 100644 --- a/dom/base/rust/lib.rs +++ b/dom/base/rust/lib.rs @@ -48,86 +48,88 @@ bitflags! { const USER_INVALID = 1 << 13; /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-broken const BROKEN = 1 << 14; + /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-loading + const LOADING = 1 << 15; /// - const REQUIRED = 1 << 15; + const REQUIRED = 1 << 16; /// /// We use an underscore to workaround a silly windows.h define. - const OPTIONAL_ = 1 << 16; + const OPTIONAL_ = 1 << 17; /// - const DEFINED = 1 << 17; + const DEFINED = 1 << 18; /// - const VISITED = 1 << 18; + const VISITED = 1 << 19; /// - const UNVISITED = 1 << 19; + const UNVISITED = 1 << 20; /// const VISITED_OR_UNVISITED = Self::VISITED.bits | Self::UNVISITED.bits; /// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-drag-over - const DRAGOVER = 1 << 20; + const DRAGOVER = 1 << 21; /// - const INRANGE = 1 << 21; + const INRANGE = 1 << 22; /// - const OUTOFRANGE = 1 << 22; + const OUTOFRANGE = 1 << 23; /// - const READONLY = 1 << 23; + const READONLY = 1 << 24; /// - const READWRITE = 1 << 24; + const READWRITE = 1 << 25; /// - const DEFAULT = 1 << 25; + const DEFAULT = 1 << 26; /// Non-standard & undocumented. - const OPTIMUM = 1 << 26; + const OPTIMUM = 1 << 28; /// Non-standard & undocumented. - const SUB_OPTIMUM = 1 << 27; + const SUB_OPTIMUM = 1 << 29; /// Non-standard & undocumented. - const SUB_SUB_OPTIMUM = 1 << 28; + const SUB_SUB_OPTIMUM = 1 << 30; /// All the above bits in one place. const METER_OPTIMUM_STATES = Self::OPTIMUM.bits | Self::SUB_OPTIMUM.bits | Self::SUB_SUB_OPTIMUM.bits; /// Non-standard & undocumented. - const INCREMENT_SCRIPT_LEVEL = 1 << 29; + const INCREMENT_SCRIPT_LEVEL = 1u64 << 31; /// - const FOCUSRING = 1 << 30; + const FOCUSRING = 1u64 << 32; /// - const FOCUS_WITHIN = 1u64 << 31; + const FOCUS_WITHIN = 1u64 << 33; /// :dir matching; the states are used for dynamic change detection. /// State that elements that match :dir(ltr) are in. - const LTR = 1u64 << 32; + const LTR = 1u64 << 34; /// State that elements that match :dir(rtl) are in. - const RTL = 1u64 << 33; + const RTL = 1u64 << 35; /// State that HTML elements that have a "dir" attr are in. - const HAS_DIR_ATTR = 1u64 << 34; + const HAS_DIR_ATTR = 1u64 << 36; /// State that HTML elements with dir="ltr" (or something /// case-insensitively equal to "ltr") are in. - const HAS_DIR_ATTR_LTR = 1u64 << 35; + const HAS_DIR_ATTR_LTR = 1u64 << 37; /// State that HTML elements with dir="rtl" (or something /// case-insensitively equal to "rtl") are in. - const HAS_DIR_ATTR_RTL = 1u64 << 36; + const HAS_DIR_ATTR_RTL = 1u64 << 38; /// State that HTML elements without a valid-valued "dir" attr or /// any HTML elements (including ) with dir="auto" (or something /// case-insensitively equal to "auto") are in. - const HAS_DIR_ATTR_LIKE_AUTO = 1u64 << 37; + const HAS_DIR_ATTR_LIKE_AUTO = 1u64 << 39; /// Non-standard & undocumented. - const AUTOFILL = 1u64 << 38; + const AUTOFILL = 1u64 << 40; /// Non-standard & undocumented. - const AUTOFILL_PREVIEW = 1u64 << 39; + const AUTOFILL_PREVIEW = 1u64 << 41; /// State for modal elements: /// - const MODAL = 1u64 << 40; + const MODAL = 1u64 << 42; /// - const INERT = 1u64 << 41; + const INERT = 1u64 << 43; /// State for the topmost modal element in top layer - const TOPMOST_MODAL = 1u64 << 42; + const TOPMOST_MODAL = 1u64 << 44; /// Initially used for the devtools highlighter, but now somehow only /// used for the devtools accessibility inspector. - const DEVTOOLS_HIGHLIGHTED = 1u64 << 43; + const DEVTOOLS_HIGHLIGHTED = 1u64 << 45; /// Used for the devtools style editor. Probably should go away. - const STYLEEDITOR_TRANSITIONING = 1u64 << 44; + const STYLEEDITOR_TRANSITIONING = 1u64 << 46; /// For :-moz-value-empty (to show widgets like the reveal password /// button or the clear button). - const VALUE_EMPTY = 1u64 << 45; + const VALUE_EMPTY = 1u64 << 47; /// For :-moz-revealed. - const REVEALED = 1u64 << 46; + const REVEALED = 1u64 << 48; /// https://html.spec.whatwg.org/#selector-popover-open /// Match element's popover visibility state of showing - const POPOVER_OPEN = 1u64 << 47; + const POPOVER_OPEN = 1u64 << 49; /// Some convenience unions. const DIR_STATES = Self::LTR.bits | Self::RTL.bits; diff --git a/dom/html/HTMLEmbedElement.cpp b/dom/html/HTMLEmbedElement.cpp index 859fe0e1dd30..af179a961377 100644 --- a/dom/html/HTMLEmbedElement.cpp +++ b/dom/html/HTMLEmbedElement.cpp @@ -30,6 +30,9 @@ HTMLEmbedElement::HTMLEmbedElement( : nsGenericHTMLElement(std::move(aNodeInfo)) { RegisterActivityObserver(); SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK); + + // By default we're in the loading state + AddStatesSilently(ElementState::LOADING); } HTMLEmbedElement::~HTMLEmbedElement() { diff --git a/dom/html/HTMLImageElement.cpp b/dom/html/HTMLImageElement.cpp index bca9d0df11b0..e9527af595cc 100644 --- a/dom/html/HTMLImageElement.cpp +++ b/dom/html/HTMLImageElement.cpp @@ -341,7 +341,8 @@ void HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName, bool forceReload = false; - if (aName == nsGkAtoms::loading && !mLoading) { + if (aName == nsGkAtoms::loading && + !ImageState().HasState(ElementState::LOADING)) { if (aValue && Loading(aValue->GetEnumValue()) == Loading::Lazy) { SetLazyLoading(); } else if (aOldValue && diff --git a/dom/html/HTMLObjectElement.cpp b/dom/html/HTMLObjectElement.cpp index 28ee786c314b..82c350c7a790 100644 --- a/dom/html/HTMLObjectElement.cpp +++ b/dom/html/HTMLObjectElement.cpp @@ -35,6 +35,9 @@ HTMLObjectElement::HTMLObjectElement( // is always barred from constraint validation. SetBarredFromConstraintValidation(true); + + // By default we're in the loading state + AddStatesSilently(ElementState::LOADING); } HTMLObjectElement::~HTMLObjectElement() { diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 6e463b4a1bf5..1c434dbb9833 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -513,11 +513,17 @@ static bool StateChangeMayAffectFrame(const Element& aElement, return false; } - if (!brokenChanged) { + const bool loadingChanged = aStates.HasState(ElementState::LOADING); + if (!brokenChanged && !loadingChanged) { return false; } if (aElement.IsHTMLElement(nsGkAtoms::img)) { + if (!brokenChanged) { + // Loading state doesn't affect , see + // `nsImageFrame::ImageFrameTypeForElement`. + return false; + } const bool needsImageFrame = nsImageFrame::ImageFrameTypeFor(aElement, *aFrame.Style()) != nsImageFrame::ImageFrameType::None; @@ -529,7 +535,7 @@ static bool StateChangeMayAffectFrame(const Element& aElement, return false; } - return brokenChanged; + return brokenChanged || loadingChanged; } /** diff --git a/layout/style/test/test_selectors.html b/layout/style/test/test_selectors.html index dd2b53bfe3e6..3c5b36c449a8 100644 --- a/layout/style/test/test_selectors.html +++ b/layout/style/test/test_selectors.html @@ -1309,6 +1309,7 @@ function runTests() { } test_parseable(":-moz-broken"); + test_parseable(":-moz-loading"); run_deferred_tests(); } diff --git a/servo/components/style/gecko/non_ts_pseudo_class_list.rs b/servo/components/style/gecko/non_ts_pseudo_class_list.rs index 38858893f315..37b66245d7ee 100644 --- a/servo/components/style/gecko/non_ts_pseudo_class_list.rs +++ b/servo/components/style/gecko/non_ts_pseudo_class_list.rs @@ -56,6 +56,7 @@ macro_rules! apply_non_ts_list { ("modal", Modal, MODAL, _), ("-moz-topmost-modal", MozTopmostModal, TOPMOST_MODAL, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS), ("-moz-broken", MozBroken, BROKEN, _), + ("-moz-loading", MozLoading, LOADING, _), ("-moz-has-dir-attr", MozHasDirAttr, HAS_DIR_ATTR, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS), ("-moz-dir-attr-ltr", MozDirAttrLTR, HAS_DIR_ATTR_LTR, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS), ("-moz-dir-attr-rtl", MozDirAttrRTL, HAS_DIR_ATTR_RTL, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS), diff --git a/servo/components/style/gecko/wrapper.rs b/servo/components/style/gecko/wrapper.rs index 9af99f4d9742..aab24f0522b1 100644 --- a/servo/components/style/gecko/wrapper.rs +++ b/servo/components/style/gecko/wrapper.rs @@ -1915,6 +1915,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { NonTSPseudoClass::Valid | NonTSPseudoClass::Invalid | NonTSPseudoClass::MozBroken | + NonTSPseudoClass::MozLoading | NonTSPseudoClass::Required | NonTSPseudoClass::Optional | NonTSPseudoClass::ReadOnly |