diff --git a/dom/base/test/test_find.html b/dom/base/test/test_find.html index 4b71bba4ff1b..eba3e53936a8 100644 --- a/dom/base/test/test_find.html +++ b/dom/base/test/test_find.html @@ -192,6 +192,12 @@ let runTests = t.step_func_done(function() { `, "ZWSP should be ignored"); testFindable(2, " ", "a b c", "Collapsed whitespace"); + + // TODO(emilio): This might be worth discussing in the spec. For now + // hard-coding our implementation. + testFindable(false, "find me", ` + Do you find not findable me? + `, "boundary-crossing user-find: none"); }); window.onload = function() { diff --git a/dom/base/use_counter_metrics.yaml b/dom/base/use_counter_metrics.yaml index 4f1030251807..1721720c699a 100644 --- a/dom/base/use_counter_metrics.yaml +++ b/dom/base/use_counter_metrics.yaml @@ -131,7 +131,7 @@ use.counter.error: send_in_pings: - use-counters -# Total of 2309 use counter metrics (excludes denominators). +# Total of 2311 use counter metrics (excludes denominators). # Total of 358 'page' use counters. use.counter.page: svgsvgelement_getelementbyid: @@ -15735,7 +15735,7 @@ use.counter.deprecated_ops.doc: send_in_pings: - use-counters -# Total of 696 'CSS (page)' use counters. +# Total of 697 'CSS (page)' use counters. use.counter.css.page: css_align_content: type: counter @@ -17794,6 +17794,23 @@ use.counter.css.page: send_in_pings: - use-counters + css_user_find: + type: counter + description: > + Whether a page used the CSS property user-find. + Compare against `use.counter.top_level_content_documents_destroyed` + to calculate the rate. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852098 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852098 + notification_emails: + - dom-core@mozilla.com + - emilio@mozilla.com + expires: never + send_in_pings: + - use-counters + css_user_select: type: counter description: > @@ -27569,7 +27586,7 @@ use.counter.css.page: send_in_pings: - use-counters -# Total of 696 'CSS (document)' use counters. +# Total of 697 'CSS (document)' use counters. use.counter.css.doc: css_align_content: type: counter @@ -29628,6 +29645,23 @@ use.counter.css.doc: send_in_pings: - use-counters + css_user_find: + type: counter + description: > + Whether a document used the CSS property user-find. + Compare against `use.counter.content_documents_destroyed` + to calculate the rate. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852098 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1852098 + notification_emails: + - dom-core@mozilla.com + - emilio@mozilla.com + expires: never + send_in_pings: + - use-counters + css_user_select: type: counter description: > diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml index 6c02c4c59a2e..cc6d13fb5e34 100644 --- a/layout/style/ServoBindings.toml +++ b/layout/style/ServoBindings.toml @@ -105,6 +105,7 @@ rusty-enums = [ "mozilla::StyleInert", "mozilla::StyleUserModify", "mozilla::StyleUserInput", + "mozilla::StyleUserFind", "mozilla::StyleBoxDirection", "mozilla::StyleRubyAlign", "mozilla::StyleTextSecurity", diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h index 99433c902730..4ce1bb19c387 100644 --- a/layout/style/nsStyleConsts.h +++ b/layout/style/nsStyleConsts.h @@ -153,6 +153,12 @@ enum class StyleUserInput : uint8_t { Auto, }; +// user-find +enum class StyleUserFind : uint8_t { + Auto, + None, +}; + // user-modify enum class StyleUserModify : uint8_t { ReadOnly, diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 123a1b3304cc..12ffc531ca42 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -2969,6 +2969,7 @@ nsStyleUI::nsStyleUI() : mInert(StyleInert::None), mMozTheme(StyleMozTheme::Auto), mUserInput(StyleUserInput::Auto), + mUserFind(StyleUserFind::Auto), mUserModify(StyleUserModify::ReadOnly), mUserFocus(StyleUserFocus::Normal), mPointerEvents(StylePointerEvents::Auto), @@ -2984,6 +2985,7 @@ nsStyleUI::nsStyleUI(const nsStyleUI& aSource) : mInert(aSource.mInert), mMozTheme(aSource.mMozTheme), mUserInput(aSource.mUserInput), + mUserFind(aSource.mUserFind), mUserModify(aSource.mUserModify), mUserFocus(aSource.mUserFocus), mPointerEvents(aSource.mPointerEvents), @@ -3041,7 +3043,8 @@ nsChangeHint nsStyleUI::CalcDifference(const nsStyleUI& aNewData) const { hint |= NS_STYLE_HINT_VISUAL | kPointerEventsHint; } - if (mUserFocus != aNewData.mUserFocus || mUserInput != aNewData.mUserInput) { + if (mUserFocus != aNewData.mUserFocus || mUserInput != aNewData.mUserInput || + mUserFind != aNewData.mUserFind) { hint |= nsChangeHint_NeutralChange; } diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index c2354290ab86..234c21055a70 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1734,6 +1734,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUI { private: mozilla::StyleUserInput mUserInput; + mozilla::StyleUserFind mUserFind; mozilla::StyleUserModify mUserModify; mozilla::StyleUserFocus mUserFocus; mozilla::StylePointerEvents mPointerEvents; @@ -1746,6 +1747,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUI { return IsInert() ? mozilla::StyleUserInput::None : mUserInput; } + mozilla::StyleUserFind UserFind() const { return mUserFind; } + mozilla::StyleUserModify UserModify() const { return IsInert() ? mozilla::StyleUserModify::ReadOnly : mUserModify; } diff --git a/layout/style/test/mochitest.toml b/layout/style/test/mochitest.toml index 3eee71f2e048..7a379c3c99a1 100644 --- a/layout/style/test/mochitest.toml +++ b/layout/style/test/mochitest.toml @@ -19,6 +19,7 @@ prefs = [ "layout.css.basic-shape-rect.enabled=true", "layout.css.basic-shape-xywh.enabled=true", "layout.css.transform-box-content-stroke.enabled=true", + "layout.css.user-find.enabled=true", ] support-files = [ "animation_utils.js", diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 913d6906971e..977bc206ed61 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -3928,6 +3928,14 @@ var gCSSProperties = { alias_for: "user-select", subproperties: ["user-select"], }, + "user-find": { + domProp: "userFind", + inherited: true, + type: CSS_TYPE_LONGHAND, + initial_values: ["auto"], + other_values: ["none"], + invalid_values: [], + }, "user-select": { domProp: "userSelect", inherited: false, diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 611e22237867..1036a00073d1 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -8793,6 +8793,13 @@ mirror: always rust: true +# Whether user-find CSS property is enabled. +- name: layout.css.user-find.enabled + type: RelaxedAtomicBool + value: @IS_NIGHTLY_BUILD@ + mirror: always + rust: true + # Should the :visited selector ever match (otherwise :link matches instead)? - name: layout.css.visited_links_enabled type: bool diff --git a/servo/components/style/properties/longhands/inherited_ui.mako.rs b/servo/components/style/properties/longhands/inherited_ui.mako.rs index 8eb6f1dc9997..04605f81ff79 100644 --- a/servo/components/style/properties/longhands/inherited_ui.mako.rs +++ b/servo/components/style/properties/longhands/inherited_ui.mako.rs @@ -78,6 +78,19 @@ ${helpers.single_keyword( affects="", )} +${helpers.single_keyword( + "user-find", + "auto none", + engines="gecko", + gecko_ffi_name="mUserFind", + gecko_enum_prefix="StyleUserFind", + animation_value_type="discrete", + gecko_pref="layout.css.user-find.enabled", + spec="Prototype of solution proposed in https://github.com/w3c/csswg-drafts/issues/3460", + has_effect_on_gecko_scrollbars=False, + affects="", +)} + ${helpers.predefined_type( "caret-color", "color::CaretColor", diff --git a/testing/web-platform/tests/css/css-ui/inheritance.html b/testing/web-platform/tests/css/css-ui/inheritance.html index 9a2efdd049ee..1eaa901aa0a1 100644 --- a/testing/web-platform/tests/css/css-ui/inheritance.html +++ b/testing/web-platform/tests/css/css-ui/inheritance.html @@ -37,6 +37,9 @@ assert_not_inherited('appearance', 'none', 'auto'); assert_inherited('caret-color', currentColor, 'rgba(42, 53, 64, 0.75)'); assert_inherited('caret-shape', 'auto', 'bar'); assert_inherited('cursor', 'auto', 'pointer'); +if (CSS.supports('user-find', 'auto')) { + assert_inherited('user-find', 'auto', 'none'); +} assert_not_inherited('nav-down', 'auto', '#foo'); assert_not_inherited('nav-left', 'auto', '#foo'); assert_not_inherited('nav-right', 'auto', '#foo'); diff --git a/testing/web-platform/tests/css/css-ui/parsing/user-find-computed.tentative.html b/testing/web-platform/tests/css/css-ui/parsing/user-find-computed.tentative.html new file mode 100644 index 000000000000..91c0d3f73979 --- /dev/null +++ b/testing/web-platform/tests/css/css-ui/parsing/user-find-computed.tentative.html @@ -0,0 +1,19 @@ + + + + +CSS UI Level 4: getComputedStyle().userFind + + + + + + + +
+ + + diff --git a/testing/web-platform/tests/css/css-ui/parsing/user-find-invalid.tentative.html b/testing/web-platform/tests/css/css-ui/parsing/user-find-invalid.tentative.html new file mode 100644 index 000000000000..1d85f2849561 --- /dev/null +++ b/testing/web-platform/tests/css/css-ui/parsing/user-find-invalid.tentative.html @@ -0,0 +1,20 @@ + + + + +CSS UI Level 4: parsing user-find with invalid values + + + + + + + + + + diff --git a/testing/web-platform/tests/css/css-ui/parsing/user-find-valid.tentative.html b/testing/web-platform/tests/css/css-ui/parsing/user-find-valid.tentative.html new file mode 100644 index 000000000000..ab963c296a69 --- /dev/null +++ b/testing/web-platform/tests/css/css-ui/parsing/user-find-valid.tentative.html @@ -0,0 +1,18 @@ + + + + +CSS UI Level 4: parsing user-find with valid values + + + + + + + + + + diff --git a/testing/web-platform/tests/css/css-ui/user-find.tentative.html b/testing/web-platform/tests/css/css-ui/user-find.tentative.html new file mode 100644 index 000000000000..b15d813d11d8 --- /dev/null +++ b/testing/web-platform/tests/css/css-ui/user-find.tentative.html @@ -0,0 +1,57 @@ + + + + + +Basic test for the user-find property + + + diff --git a/toolkit/components/find/nsFind.cpp b/toolkit/components/find/nsFind.cpp index 8a5c291fdfd0..8342732e9c5e 100644 --- a/toolkit/components/find/nsFind.cpp +++ b/toolkit/components/find/nsFind.cpp @@ -140,7 +140,7 @@ static bool IsRubyAnnotationNode(const nsINode* aNode) { StyleDisplay::RubyTextContainer == display; } -static bool IsVisibleNode(const nsINode* aNode) { +static bool IsFindableNode(const nsINode* aNode) { if (!IsDisplayedNode(aNode)) { return false; } @@ -151,7 +151,8 @@ static bool IsVisibleNode(const nsINode* aNode) { return true; } - if (frame->HidesContent(nsIFrame::IncludeContentVisibility::Hidden) || + if (frame->StyleUI()->UserFind() == StyleUserFind::None || + frame->HidesContent(nsIFrame::IncludeContentVisibility::Hidden) || frame->IsHiddenByContentVisibilityOnAnyAncestor( nsIFrame::IncludeContentVisibility::Hidden)) { return false; @@ -953,8 +954,8 @@ nsFind::Find(const nsAString& aPatText, nsRange* aSearchRange, } RefPtr range = nsRange::Create(current); - if (startParent && endParent && IsVisibleNode(startParent) && - IsVisibleNode(endParent)) { + if (startParent && endParent && IsFindableNode(startParent) && + IsFindableNode(endParent)) { IgnoredErrorResult rv; range->SetStart(*startParent, matchStartOffset, rv); if (!rv.Failed()) {