From def92d1b8e9d373e2f6f27c366d578d97d8960c6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:34:50 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- layout/base/AccessibleCaretManager.cpp | 30 +- layout/base/MotionPathUtils.cpp | 35 +- layout/base/PresShell.cpp | 156 ++- layout/base/PresShell.h | 18 + layout/base/RestyleManager.cpp | 96 +- layout/base/RestyleManager.h | 17 +- layout/base/crashtests/crashtests.list | 4 +- layout/base/nsCSSFrameConstructor.cpp | 18 +- layout/base/nsCSSFrameConstructor.h | 14 +- layout/base/nsCaret.cpp | 275 ++--- layout/base/nsCaret.h | 143 ++- layout/base/nsCounterManager.cpp | 6 +- layout/base/nsDocumentViewer.cpp | 42 +- layout/base/nsLayoutUtils.cpp | 59 +- layout/base/nsLayoutUtils.h | 2 +- layout/base/nsPresContext.cpp | 9 +- layout/base/nsRefreshDriver.cpp | 23 +- layout/base/nsRefreshDriver.h | 5 + layout/base/tests/chrome/chrome.toml | 6 + layout/base/tests/chrome/printpreview_helper.xhtml | 243 ++++ .../tests/chrome/printpreview_scale_test_001.html | 21 + .../chrome/printpreview_scale_test_001_ref.html | 20 + .../tests/chrome/printpreview_scale_test_002.html | 21 + .../chrome/printpreview_scale_test_002_ref.html | 26 + .../tests/chrome/printpreview_scale_test_003.html | 21 + .../chrome/printpreview_scale_test_003_ref.html | 21 + layout/base/tests/chrome/test_bug420499.xhtml | 2 +- layout/build/nsLayoutStatics.cpp | 6 - layout/forms/nsCheckboxRadioFrame.cpp | 26 +- layout/forms/nsComboboxControlFrame.cpp | 2 - layout/forms/nsDateTimeControlFrame.cpp | 29 +- layout/forms/nsFieldSetFrame.cpp | 15 +- layout/forms/nsHTMLButtonControlFrame.cpp | 26 +- layout/forms/nsImageControlFrame.cpp | 1 - layout/forms/nsListControlFrame.cpp | 16 +- layout/forms/nsMeterFrame.cpp | 64 +- layout/forms/nsMeterFrame.h | 39 +- layout/forms/nsProgressFrame.cpp | 71 +- layout/forms/nsProgressFrame.h | 38 +- layout/forms/nsRangeFrame.cpp | 280 ++--- layout/forms/nsRangeFrame.h | 46 +- layout/forms/nsTextControlFrame.cpp | 104 +- layout/forms/nsTextControlFrame.h | 14 +- layout/generic/AspectRatio.cpp | 2 +- layout/generic/AspectRatio.h | 2 +- layout/generic/BRFrame.cpp | 13 +- layout/generic/CSSAlignUtils.cpp | 4 +- layout/generic/ColumnSetWrapperFrame.cpp | 2 - layout/generic/MiddleCroppingBlockFrame.cpp | 11 +- layout/generic/PrintedSheetFrame.cpp | 1 - layout/generic/ReflowInput.cpp | 139 ++- layout/generic/ReflowInput.h | 39 +- layout/generic/ScrollGeneration.h | 5 +- layout/generic/ScrollSnapTargetId.h | 1 + layout/generic/ViewportFrame.cpp | 23 +- layout/generic/WritingModes.h | 216 ++-- layout/generic/crashtests/1410243-1.html | 26 + layout/generic/crashtests/1741488-1.html | 23 + layout/generic/crashtests/1881375-1-helper.html | 38 + layout/generic/crashtests/1881375-1.html | 25 + layout/generic/crashtests/481921.ogg | Bin 42852 -> 0 bytes layout/generic/crashtests/crashtests.list | 3 + layout/generic/nsAbsoluteContainingBlock.cpp | 6 +- layout/generic/nsBackdropFrame.cpp | 1 - layout/generic/nsBlockFrame.cpp | 33 +- layout/generic/nsCanvasFrame.cpp | 21 +- layout/generic/nsColumnSetFrame.cpp | 7 +- layout/generic/nsContainerFrame.cpp | 44 +- layout/generic/nsContainerFrame.h | 122 -- layout/generic/nsFirstLetterFrame.cpp | 1 - layout/generic/nsFlexContainerFrame.cpp | 205 ++-- layout/generic/nsFlexContainerFrame.h | 6 - layout/generic/nsFloatManager.cpp | 2 +- layout/generic/nsFrameSelection.cpp | 30 +- layout/generic/nsFrameSelection.h | 32 +- layout/generic/nsFrameSetFrame.cpp | 2 - layout/generic/nsGfxScrollFrame.cpp | 40 +- layout/generic/nsGfxScrollFrame.h | 2 +- layout/generic/nsGridContainerFrame.cpp | 502 +++++---- layout/generic/nsGridContainerFrame.h | 12 +- layout/generic/nsHTMLCanvasFrame.cpp | 3 - layout/generic/nsIFrame.cpp | 1167 ++------------------ layout/generic/nsIFrame.h | 29 +- layout/generic/nsIFrameInlines.h | 2 +- layout/generic/nsImageFrame.cpp | 5 - layout/generic/nsInlineFrame.cpp | 1 - layout/generic/nsLeafFrame.cpp | 10 +- layout/generic/nsLineBox.cpp | 2 +- layout/generic/nsLineBox.h | 48 +- layout/generic/nsLineLayout.cpp | 6 +- layout/generic/nsPageContentFrame.cpp | 1 - layout/generic/nsPageFrame.cpp | 84 +- layout/generic/nsPageSequenceFrame.cpp | 1 - layout/generic/nsPlaceholderFrame.cpp | 1 - layout/generic/nsRubyBaseContainerFrame.cpp | 1 - layout/generic/nsRubyFrame.cpp | 5 +- layout/generic/nsRubyTextContainerFrame.cpp | 1 - layout/generic/nsSubDocumentFrame.cpp | 9 +- layout/generic/nsTextFrame.cpp | 66 +- layout/generic/nsTextPaintStyle.cpp | 18 + layout/generic/nsTextPaintStyle.h | 1 + layout/generic/nsTextRunTransformations.cpp | 20 + layout/generic/nsTextRunTransformations.h | 3 + layout/generic/nsVideoFrame.cpp | 8 +- layout/generic/test/mochitest.toml | 37 + .../test/selection_cross_shadow_boundary_helper.js | 28 + ...ion_cross_shadow_boundary_1_backward_click.html | 36 + ...tion_cross_shadow_boundary_1_backward_drag.html | 40 + ...tion_cross_shadow_boundary_1_forward_click.html | 35 + ...ction_cross_shadow_boundary_1_forward_drag.html | 39 + ...ion_cross_shadow_boundary_2_backward_click.html | 47 + ...tion_cross_shadow_boundary_2_backward_drag.html | 48 + ...tion_cross_shadow_boundary_2_forward_click.html | 46 + ...ction_cross_shadow_boundary_2_forward_drag.html | 48 + ...hadow_boundary_multi_ranges_backward_click.html | 61 + ...shadow_boundary_multi_ranges_backward_drag.html | 65 ++ ...shadow_boundary_multi_ranges_forward_click.html | 59 + ..._shadow_boundary_multi_ranges_forward_drag.html | 65 ++ layout/inspector/InspectorUtils.cpp | 31 +- layout/inspector/InspectorUtils.h | 15 +- layout/inspector/ServoStyleRuleMap.cpp | 8 +- layout/inspector/tests/mochitest.toml | 3 + layout/inspector/tests/test_bug877690.html | 7 +- .../tests/test_getCSSPseudoElementNames.html | 1 + .../test_replaceBlockRuleBodyTextInStylesheet.html | 209 ++++ layout/mathml/nsMathMLContainerFrame.cpp | 22 +- layout/mathml/nsMathMLContainerFrame.h | 15 +- layout/mathml/nsMathMLmoFrame.cpp | 33 +- layout/mathml/nsMathMLmtableFrame.h | 3 +- layout/painting/RetainedDisplayListBuilder.cpp | 19 +- layout/painting/RetainedDisplayListBuilder.h | 6 - layout/painting/crashtests/crashtests.list | 2 +- layout/painting/nsCSSRenderingGradients.cpp | 30 +- layout/painting/nsCSSRenderingGradients.h | 37 +- layout/painting/nsDisplayList.cpp | 111 +- layout/painting/nsDisplayList.h | 24 +- layout/reftests/bidi/dirAuto/reftest.list | 2 +- .../1888941-text-transform-emergency-wrap-ref.html | 2 + .../1888941-text-transform-emergency-wrap.html | 2 + layout/reftests/bugs/307102-2-ref.html | 8 - layout/reftests/bugs/307102-2.html | 8 - layout/reftests/bugs/385870-1-ref.html | 51 - layout/reftests/bugs/385870-1.html | 55 - layout/reftests/bugs/385870-2-ref.html | 51 - layout/reftests/bugs/385870-2.html | 55 - layout/reftests/bugs/404553-1-ref.html | 2 +- layout/reftests/bugs/404553-1.html | 2 +- layout/reftests/bugs/reftest.list | 6 +- .../counters/counter-hebrew-reference.html | 5 +- .../counters/counters-hebrew-reference.html | 93 +- .../counters/t1202-counter-06-b-reference.html | 4 +- .../counters/t1202-counter-07-b-reference.html | 8 +- .../counters/t1202-counter-08-b-reference.html | 8 +- .../counters/t1202-counters-06-b-reference.html | 28 +- .../counters/t1202-counters-07-b-reference.html | 36 +- .../counters/t1202-counters-08-b-reference.html | 36 +- .../counters/t1202-counters-09-b-reference.html | 78 +- .../counters/t1202-counters-10-b-reference.html | 76 +- .../counters/t1204-reset-00-c-o-reference.html | 2 +- .../counters/t120401-scope-01-c-reference.html | 2 +- .../counters/t120401-scope-02-c-reference.html | 2 +- layout/reftests/dom/reftest.list | 2 +- layout/reftests/flexbox/reftest.list | 1 - layout/reftests/forms/input/range/1887539-ref.html | 30 + layout/reftests/forms/input/range/1887539.html | 35 + layout/reftests/forms/input/range/reftest.list | 2 + layout/reftests/marquee/336736-1-ref.html | 5 - layout/reftests/marquee/336736-1a-ref.html | 5 + layout/reftests/marquee/336736-1b-ref.html | 5 + layout/reftests/marquee/reftest.list | 4 +- layout/reftests/moz.build | 2 - layout/reftests/ogg-video/444-1-ref.html | 20 - layout/reftests/ogg-video/444-1.html | 20 - layout/reftests/ogg-video/aspect-ratio-1-ref.html | 6 - layout/reftests/ogg-video/aspect-ratio-1a.xhtml | 14 - layout/reftests/ogg-video/aspect-ratio-1b.xhtml | 14 - layout/reftests/ogg-video/aspect-ratio-2-ref.html | 6 - layout/reftests/ogg-video/aspect-ratio-2a.xhtml | 14 - layout/reftests/ogg-video/aspect-ratio-2b.xhtml | 14 - layout/reftests/ogg-video/aspect-ratio-3-ref.xhtml | 14 - layout/reftests/ogg-video/aspect-ratio-3a.xhtml | 14 - layout/reftests/ogg-video/aspect-ratio-3b.xhtml | 14 - layout/reftests/ogg-video/basic-1-ref.html | 6 - layout/reftests/ogg-video/basic-1.xhtml | 14 - .../reftests/ogg-video/black100x100-aspect3to2.ogv | Bin 3428 -> 0 bytes layout/reftests/ogg-video/black140x100.ogv | Bin 2871 -> 0 bytes layout/reftests/ogg-video/black29x19offset.ogv | Bin 3988 -> 0 bytes layout/reftests/ogg-video/blue140x100.png | Bin 277 -> 0 bytes layout/reftests/ogg-video/blue250x200.png | Bin 1157 -> 0 bytes layout/reftests/ogg-video/canvas-1a.xhtml | 29 - layout/reftests/ogg-video/canvas-1b.xhtml | 27 - layout/reftests/ogg-video/clipping-1-ref.html | 9 - layout/reftests/ogg-video/clipping-1a.html | 8 - layout/reftests/ogg-video/empty-1-ref.html | 5 - layout/reftests/ogg-video/empty-1a.html | 6 - layout/reftests/ogg-video/empty-1b.html | 6 - .../ogg-video/encoded-aspect-ratio-1-ref.html | 19 - .../reftests/ogg-video/encoded-aspect-ratio-1.html | 29 - layout/reftests/ogg-video/green70x30.png | Bin 224 -> 0 bytes .../ogg-video/object-aspect-ratio-1a.xhtml | 14 - .../ogg-video/object-aspect-ratio-1b.xhtml | 14 - .../ogg-video/object-aspect-ratio-2a.xhtml | 14 - .../ogg-video/object-aspect-ratio-2b.xhtml | 14 - layout/reftests/ogg-video/offset-1-ref.html | 6 - layout/reftests/ogg-video/offset-1.xhtml | 14 - layout/reftests/ogg-video/poster-1.html | 7 - layout/reftests/ogg-video/poster-10.html | 18 - layout/reftests/ogg-video/poster-11.html | 29 - layout/reftests/ogg-video/poster-12.html | 38 - layout/reftests/ogg-video/poster-13.html | 8 - layout/reftests/ogg-video/poster-15.html | 13 - layout/reftests/ogg-video/poster-2.html | 7 - layout/reftests/ogg-video/poster-3.html | 11 - layout/reftests/ogg-video/poster-4.html | 14 - layout/reftests/ogg-video/poster-5.html | 13 - layout/reftests/ogg-video/poster-6.html | 12 - layout/reftests/ogg-video/poster-7.html | 14 - layout/reftests/ogg-video/poster-8.html | 12 - .../ogg-video/poster-ref-black140x100.html | 6 - .../reftests/ogg-video/poster-ref-blue125x100.html | 6 - .../reftests/ogg-video/poster-ref-blue140x100.html | 6 - .../reftests/ogg-video/poster-ref-blue250x200.html | 6 - .../reftests/ogg-video/poster-ref-blue400x300.html | 8 - .../reftests/ogg-video/poster-ref-green70x30.html | 6 - .../reftests/ogg-video/poster-ref-red140x100.html | 6 - layout/reftests/ogg-video/red140x100.png | Bin 274 -> 0 bytes layout/reftests/ogg-video/red160x120.png | Bin 720 -> 0 bytes layout/reftests/ogg-video/reftest.list | 35 - layout/reftests/ogg-video/seek420.ogv | Bin 30163 -> 0 bytes layout/reftests/ogg-video/seek444.ogv | Bin 30408 -> 0 bytes layout/reftests/ogg-video/zoomed-1-ref.html | 6 - layout/reftests/ogg-video/zoomed-1.xhtml | 15 - layout/reftests/reftest.list | 3 - layout/reftests/transform-3d/reftest.list | 1 - layout/style/CSSPageRule.cpp | 22 +- layout/style/CSSPageRule.h | 9 +- layout/style/CSSScopeRule.cpp | 66 ++ layout/style/CSSScopeRule.h | 49 + layout/style/CSSStartingStyleRule.cpp | 47 + layout/style/CSSStartingStyleRule.h | 54 + layout/style/FontFaceImpl.cpp | 47 +- layout/style/FontFaceImpl.h | 20 +- layout/style/FontFaceSetDocumentImpl.cpp | 2 +- layout/style/FontFaceSetImpl.cpp | 5 +- layout/style/FontFaceSetImpl.h | 7 +- layout/style/FontFaceSetWorkerImpl.cpp | 2 +- layout/style/GenerateServoCSSPropList.py | 2 +- layout/style/ImageLoader.cpp | 10 + layout/style/PreferenceSheet.cpp | 2 +- layout/style/Rule.cpp | 4 +- layout/style/ServoBindingTypes.h | 2 + layout/style/ServoBindings.h | 4 +- layout/style/ServoBindings.toml | 3 + layout/style/ServoCSSRuleList.cpp | 19 +- layout/style/ServoElementSnapshot.cpp | 7 + layout/style/ServoElementSnapshot.h | 7 + layout/style/ServoStyleConstsForwards.h | 4 +- layout/style/ServoStyleConstsInlines.h | 43 +- layout/style/ServoStyleSet.cpp | 17 + layout/style/ServoStyleSet.h | 14 + layout/style/SharedSubResourceCache.h | 3 + layout/style/moz.build | 5 + layout/style/nsCSSPseudoElementList.h | 1 + layout/style/nsCSSPseudoElements.h | 2 + layout/style/nsComputedDOMStyle.cpp | 147 +-- layout/style/nsComputedDOMStyle.h | 4 + layout/style/nsMediaFeatures.cpp | 12 +- layout/style/nsROCSSPrimitiveValue.cpp | 8 - layout/style/nsROCSSPrimitiveValue.h | 2 - layout/style/nsStyleStruct.cpp | 6 +- layout/style/res/forms.css | 4 + layout/style/res/html.css | 12 +- .../style/test/chrome/chrome-only-media-queries.js | 1 + layout/style/test/mochitest.toml | 5 +- layout/style/test/property_database.js | 306 ++--- layout/style/test/test_hover_quirk.html | 32 + .../test/test_non_content_accessible_pseudos.html | 1 - layout/style/test/test_selectors.html | 1 - .../test/test_style_struct_copy_constructors.html | 14 +- layout/svg/CSSClipPathInstance.cpp | 43 +- layout/svg/CSSClipPathInstance.h | 3 + layout/svg/SVGAFrame.cpp | 14 - layout/svg/SVGContextPaint.cpp | 2 +- layout/svg/SVGFEImageFrame.cpp | 18 - layout/svg/SVGGradientFrame.cpp | 9 +- layout/svg/SVGImageFrame.cpp | 20 - layout/svg/SVGOuterSVGFrame.cpp | 9 +- layout/svg/SVGUseFrame.cpp | 13 - layout/svg/SVGUseFrame.h | 2 - layout/tables/BasicTableLayoutStrategy.cpp | 14 +- layout/tables/FixedTableLayoutStrategy.cpp | 5 +- layout/tables/celldata.h | 4 +- layout/tables/nsCellMap.cpp | 34 +- layout/tables/nsTableCellFrame.cpp | 52 +- layout/tables/nsTableCellFrame.h | 90 +- layout/tables/nsTableColFrame.cpp | 1 - layout/tables/nsTableColGroupFrame.cpp | 1 - layout/tables/nsTableFrame.cpp | 162 +-- layout/tables/nsTableRowFrame.cpp | 22 +- layout/tables/nsTableRowFrame.h | 14 +- layout/tables/nsTableRowGroupFrame.cpp | 3 +- layout/tables/nsTableWrapperFrame.cpp | 9 +- layout/tools/reftest/mach_commands.py | 4 - layout/tools/reftest/manifest.sys.mjs | 3 + layout/tools/reftest/reftest.sys.mjs | 4 +- layout/tools/reftest/runreftest.py | 19 +- layout/xul/nsMenuPopupFrame.cpp | 20 +- layout/xul/nsXULPopupManager.cpp | 1 + layout/xul/tree/nsTreeBodyFrame.cpp | 2 +- 309 files changed, 4606 insertions(+), 4895 deletions(-) create mode 100644 layout/base/tests/chrome/printpreview_scale_test_001.html create mode 100644 layout/base/tests/chrome/printpreview_scale_test_001_ref.html create mode 100644 layout/base/tests/chrome/printpreview_scale_test_002.html create mode 100644 layout/base/tests/chrome/printpreview_scale_test_002_ref.html create mode 100644 layout/base/tests/chrome/printpreview_scale_test_003.html create mode 100644 layout/base/tests/chrome/printpreview_scale_test_003_ref.html create mode 100644 layout/generic/crashtests/1410243-1.html create mode 100644 layout/generic/crashtests/1741488-1.html create mode 100644 layout/generic/crashtests/1881375-1-helper.html create mode 100644 layout/generic/crashtests/1881375-1.html delete mode 100644 layout/generic/crashtests/481921.ogg create mode 100644 layout/generic/test/selection_cross_shadow_boundary_helper.js create mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_1_backward_click.html create mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_1_backward_drag.html create mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_1_forward_click.html create mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_1_forward_drag.html create mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_2_backward_click.html create mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_2_backward_drag.html create mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_2_forward_click.html create mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_2_forward_drag.html create mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_backward_click.html create mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_backward_drag.html create mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_forward_click.html create mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_forward_drag.html create mode 100644 layout/inspector/tests/test_replaceBlockRuleBodyTextInStylesheet.html create mode 100644 layout/reftests/bugs/1888941-text-transform-emergency-wrap-ref.html create mode 100644 layout/reftests/bugs/1888941-text-transform-emergency-wrap.html delete mode 100644 layout/reftests/bugs/307102-2-ref.html delete mode 100644 layout/reftests/bugs/307102-2.html delete mode 100644 layout/reftests/bugs/385870-1-ref.html delete mode 100644 layout/reftests/bugs/385870-1.html delete mode 100644 layout/reftests/bugs/385870-2-ref.html delete mode 100644 layout/reftests/bugs/385870-2.html create mode 100644 layout/reftests/forms/input/range/1887539-ref.html create mode 100644 layout/reftests/forms/input/range/1887539.html delete mode 100644 layout/reftests/marquee/336736-1-ref.html create mode 100644 layout/reftests/marquee/336736-1a-ref.html create mode 100644 layout/reftests/marquee/336736-1b-ref.html delete mode 100644 layout/reftests/ogg-video/444-1-ref.html delete mode 100644 layout/reftests/ogg-video/444-1.html delete mode 100644 layout/reftests/ogg-video/aspect-ratio-1-ref.html delete mode 100644 layout/reftests/ogg-video/aspect-ratio-1a.xhtml delete mode 100644 layout/reftests/ogg-video/aspect-ratio-1b.xhtml delete mode 100644 layout/reftests/ogg-video/aspect-ratio-2-ref.html delete mode 100644 layout/reftests/ogg-video/aspect-ratio-2a.xhtml delete mode 100644 layout/reftests/ogg-video/aspect-ratio-2b.xhtml delete mode 100644 layout/reftests/ogg-video/aspect-ratio-3-ref.xhtml delete mode 100644 layout/reftests/ogg-video/aspect-ratio-3a.xhtml delete mode 100644 layout/reftests/ogg-video/aspect-ratio-3b.xhtml delete mode 100644 layout/reftests/ogg-video/basic-1-ref.html delete mode 100644 layout/reftests/ogg-video/basic-1.xhtml delete mode 100644 layout/reftests/ogg-video/black100x100-aspect3to2.ogv delete mode 100644 layout/reftests/ogg-video/black140x100.ogv delete mode 100644 layout/reftests/ogg-video/black29x19offset.ogv delete mode 100644 layout/reftests/ogg-video/blue140x100.png delete mode 100644 layout/reftests/ogg-video/blue250x200.png delete mode 100644 layout/reftests/ogg-video/canvas-1a.xhtml delete mode 100644 layout/reftests/ogg-video/canvas-1b.xhtml delete mode 100644 layout/reftests/ogg-video/clipping-1-ref.html delete mode 100644 layout/reftests/ogg-video/clipping-1a.html delete mode 100644 layout/reftests/ogg-video/empty-1-ref.html delete mode 100644 layout/reftests/ogg-video/empty-1a.html delete mode 100644 layout/reftests/ogg-video/empty-1b.html delete mode 100644 layout/reftests/ogg-video/encoded-aspect-ratio-1-ref.html delete mode 100644 layout/reftests/ogg-video/encoded-aspect-ratio-1.html delete mode 100644 layout/reftests/ogg-video/green70x30.png delete mode 100644 layout/reftests/ogg-video/object-aspect-ratio-1a.xhtml delete mode 100644 layout/reftests/ogg-video/object-aspect-ratio-1b.xhtml delete mode 100644 layout/reftests/ogg-video/object-aspect-ratio-2a.xhtml delete mode 100644 layout/reftests/ogg-video/object-aspect-ratio-2b.xhtml delete mode 100644 layout/reftests/ogg-video/offset-1-ref.html delete mode 100644 layout/reftests/ogg-video/offset-1.xhtml delete mode 100644 layout/reftests/ogg-video/poster-1.html delete mode 100644 layout/reftests/ogg-video/poster-10.html delete mode 100644 layout/reftests/ogg-video/poster-11.html delete mode 100644 layout/reftests/ogg-video/poster-12.html delete mode 100644 layout/reftests/ogg-video/poster-13.html delete mode 100644 layout/reftests/ogg-video/poster-15.html delete mode 100644 layout/reftests/ogg-video/poster-2.html delete mode 100644 layout/reftests/ogg-video/poster-3.html delete mode 100644 layout/reftests/ogg-video/poster-4.html delete mode 100644 layout/reftests/ogg-video/poster-5.html delete mode 100644 layout/reftests/ogg-video/poster-6.html delete mode 100644 layout/reftests/ogg-video/poster-7.html delete mode 100644 layout/reftests/ogg-video/poster-8.html delete mode 100644 layout/reftests/ogg-video/poster-ref-black140x100.html delete mode 100644 layout/reftests/ogg-video/poster-ref-blue125x100.html delete mode 100644 layout/reftests/ogg-video/poster-ref-blue140x100.html delete mode 100644 layout/reftests/ogg-video/poster-ref-blue250x200.html delete mode 100644 layout/reftests/ogg-video/poster-ref-blue400x300.html delete mode 100644 layout/reftests/ogg-video/poster-ref-green70x30.html delete mode 100644 layout/reftests/ogg-video/poster-ref-red140x100.html delete mode 100644 layout/reftests/ogg-video/red140x100.png delete mode 100644 layout/reftests/ogg-video/red160x120.png delete mode 100644 layout/reftests/ogg-video/reftest.list delete mode 100644 layout/reftests/ogg-video/seek420.ogv delete mode 100644 layout/reftests/ogg-video/seek444.ogv delete mode 100644 layout/reftests/ogg-video/zoomed-1-ref.html delete mode 100644 layout/reftests/ogg-video/zoomed-1.xhtml create mode 100644 layout/style/CSSScopeRule.cpp create mode 100644 layout/style/CSSScopeRule.h create mode 100644 layout/style/CSSStartingStyleRule.cpp create mode 100644 layout/style/CSSStartingStyleRule.h (limited to 'layout') diff --git a/layout/base/AccessibleCaretManager.cpp b/layout/base/AccessibleCaretManager.cpp index 17597d287d..99155133cd 100644 --- a/layout/base/AccessibleCaretManager.cpp +++ b/layout/base/AccessibleCaretManager.cpp @@ -222,27 +222,17 @@ bool AccessibleCaretManager::IsCaretDisplayableInCursorMode( if (!caret || !caret->IsVisible()) { return false; } - - int32_t offset = 0; - nsIFrame* frame = - nsCaret::GetFrameAndOffset(GetSelection(), nullptr, 0, &offset); - - if (!frame) { - return false; - } - - if (!GetEditingHostForFrame(frame)) { + auto frameData = + nsCaret::GetFrameAndOffset(nsCaret::CaretPositionFor(GetSelection())); + if (!GetEditingHostForFrame(frameData.mFrame)) { return false; } - if (aOutFrame) { - *aOutFrame = frame; + *aOutFrame = frameData.mFrame; } - if (aOutOffset) { - *aOutOffset = offset; + *aOutOffset = frameData.mOffsetInFrameContent; } - return true; } @@ -1333,10 +1323,9 @@ nsPoint AccessibleCaretManager::AdjustDragBoundary( const nsPoint& aPoint) const { nsPoint adjustedPoint = aPoint; - int32_t focusOffset = 0; - nsIFrame* focusFrame = - nsCaret::GetFrameAndOffset(GetSelection(), nullptr, 0, &focusOffset); - Element* editingHost = GetEditingHostForFrame(focusFrame); + auto frameData = + nsCaret::GetFrameAndOffset(nsCaret::CaretPositionFor(GetSelection())); + Element* editingHost = GetEditingHostForFrame(frameData.mFrame); if (editingHost) { nsIFrame* editingHostFrame = editingHost->GetPrimaryFrame(); @@ -1471,8 +1460,7 @@ void AccessibleCaretManager::DispatchCaretStateChangedEvent( // Send isEditable info w/ event detail. This info can help determine // whether to show cut command on selection dialog or not. - init.mSelectionEditable = - commonAncestorFrame && GetEditingHostForFrame(commonAncestorFrame); + init.mSelectionEditable = GetEditingHostForFrame(commonAncestorFrame); init.mBoundingClientRect = domRect; init.mReason = aReason; diff --git a/layout/base/MotionPathUtils.cpp b/layout/base/MotionPathUtils.cpp index 4045f2304a..d620064b73 100644 --- a/layout/base/MotionPathUtils.cpp +++ b/layout/base/MotionPathUtils.cpp @@ -434,7 +434,7 @@ Maybe MotionPathUtils::ResolveMotionPath( static inline bool IsClosedLoop(const StyleSVGPathData& aPathData) { return !aPathData._0.AsSpan().empty() && - aPathData._0.AsSpan().rbegin()->IsClosePath(); + aPathData._0.AsSpan().rbegin()->IsClose(); } // Create a path for "inset(0 round X)", where X is the value of border-radius @@ -466,8 +466,8 @@ static already_AddRefed BuildDefaultPathForURL( return nullptr; } - Array array(StylePathCommand::MoveTo( - StyleCoordPair(gfx::Point{0.0, 0.0}), StyleIsAbsolute::No)); + Array array(StylePathCommand::Move( + StyleByTo::By, StyleCoordinatePair{0.0, 0.0})); return SVGPathData::BuildPath(array, aBuilder, StyleStrokeLinecap::Butt, 0.0); } @@ -695,6 +695,21 @@ already_AddRefed MotionPathUtils::BuildSVGPath( 0.0); } +static already_AddRefed BuildShape( + const Span& aShape, gfx::PathBuilder* aPathBuilder, + const nsRect& aCoordBox) { + if (!aPathBuilder) { + return nullptr; + } + + // For motion path, we always use CSSPixel unit to compute the offset + // transform (i.e. motion path transform). + const auto rect = CSSRect::FromAppUnits(aCoordBox); + return SVGPathData::BuildPath(aShape, aPathBuilder, StyleStrokeLinecap::Butt, + 0.0, rect.Size(), + rect.TopLeft().ToUnknownPoint()); +} + /* static */ already_AddRefed MotionPathUtils::BuildPath( const StyleBasicShape& aBasicShape, @@ -725,12 +740,22 @@ already_AddRefed MotionPathUtils::BuildPath( case StyleBasicShape::Tag::Polygon: return ShapeUtils::BuildPolygonPath(aBasicShape, aCoordBox, AppUnitsPerCSSPixel(), aPathBuilder); - case StyleBasicShape::Tag::Path: + case StyleBasicShape::Tag::PathOrShape: { // FIXME: Bug 1836847. Once we support "at " for path(), we have // to also check its containing block as well. For now, we are still // building its gfx::Path directly by its SVGPathData without other // reference. https://github.com/w3c/fxtf-drafts/issues/504 - return BuildSVGPath(aBasicShape.AsPath().path, aPathBuilder); + const auto& pathOrShape = aBasicShape.AsPathOrShape(); + if (pathOrShape.IsPath()) { + return BuildSVGPath(pathOrShape.AsPath().path, aPathBuilder); + } + + // Note that shape() always defines the initial position, i.e. "from x y", + // by its first move command, so |aOffsetPosition|, i.e. offset-position + // property, is ignored. + return BuildShape(pathOrShape.AsShape().commands.AsSpan(), aPathBuilder, + aCoordBox); + } } return nullptr; diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index 31c21c3377..7674abb3d0 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -14,6 +14,7 @@ #include "mozilla/dom/AncestorIterator.h" #include "mozilla/dom/FontFaceSet.h" #include "mozilla/dom/ElementBinding.h" +#include "mozilla/dom/FragmentDirective.h" #include "mozilla/dom/LargestContentfulPaint.h" #include "mozilla/dom/MouseEventBinding.h" #include "mozilla/dom/PerformanceMainThread.h" @@ -1281,10 +1282,13 @@ void PresShell::Destroy() { ClearApproximatelyVisibleFramesList(Some(OnNonvisible::DiscardImages)); - if (mCaret) { + if (mOriginalCaret) { + mOriginalCaret->Terminate(); + } + if (mCaret && mCaret != mOriginalCaret) { mCaret->Terminate(); - mCaret = nullptr; } + mCaret = mOriginalCaret = nullptr; mFocusedFrameSelection = nullptr; @@ -2238,9 +2242,20 @@ PresShell::GetAccessibleCaretEventHub() const { return eventHub.forget(); } -void PresShell::SetCaret(nsCaret* aNewCaret) { mCaret = aNewCaret; } +void PresShell::SetCaret(nsCaret* aNewCaret) { + if (mCaret == aNewCaret) { + return; + } + if (mCaret) { + mCaret->SchedulePaint(); + } + mCaret = aNewCaret; + if (aNewCaret) { + aNewCaret->SchedulePaint(); + } +} -void PresShell::RestoreCaret() { mCaret = mOriginalCaret; } +void PresShell::RestoreCaret() { SetCaret(mOriginalCaret); } NS_IMETHODIMP PresShell::SetCaretEnabled(bool aInEnable) { bool oldEnabled = mCaretEnabled; @@ -3277,6 +3292,46 @@ nsresult PresShell::ScrollToAnchor() { ScrollAxis(), ScrollFlags::AnchorScrollFlags); } +bool PresShell::HighlightAndGoToTextFragment(bool aScrollToTextFragment) { + MOZ_ASSERT(mDocument); + if (!StaticPrefs::dom_text_fragments_enabled()) { + return false; + } + const RefPtr fragmentDirective = + mDocument->FragmentDirective(); + + nsTArray> textDirectiveRanges = + fragmentDirective->FindTextFragmentsInDocument(); + if (textDirectiveRanges.IsEmpty()) { + return false; + } + + const RefPtr targetTextSelection = + GetCurrentSelection(SelectionType::eTargetText); + if (!targetTextSelection) { + return false; + } + for (RefPtr range : textDirectiveRanges) { + targetTextSelection->AddRangeAndSelectFramesAndNotifyListeners( + *range, IgnoreErrors()); + } + if (!aScrollToTextFragment) { + return false; + } + + // Scroll the last text directive into view. + nsRange* lastRange = textDirectiveRanges.LastElement(); + MOZ_ASSERT(lastRange); + if (RefPtr lastRangeStartContent = + nsIContent::FromNode(lastRange->GetStartContainer())) { + return ScrollContentIntoView( + lastRangeStartContent, + ScrollAxis(WhereToScroll::Center, WhenToScroll::Always), + ScrollAxis(), ScrollFlags::AnchorScrollFlags) == NS_OK; + } + return false; +} + /* * Helper (per-continuation) for ScrollContentIntoView. * @@ -4473,6 +4528,26 @@ MOZ_CAN_RUN_SCRIPT_BOUNDARY void PresShell::ElementStateChanged( } } +MOZ_CAN_RUN_SCRIPT_BOUNDARY void PresShell::CustomStatesWillChange( + Element& aElement) { + if (MOZ_UNLIKELY(!mDidInitialize)) { + return; + } + + mPresContext->RestyleManager()->CustomStatesWillChange(aElement); +} + +MOZ_CAN_RUN_SCRIPT_BOUNDARY void PresShell::CustomStateChanged( + Element& aElement, nsAtom* aState) { + MOZ_ASSERT(!mIsDocumentGone, "Unexpected CustomStateChanged"); + MOZ_ASSERT(aState, "Unexpected empty state"); + + if (mDidInitialize) { + nsAutoCauseReflowNotifier crNotifier(this); + mPresContext->RestyleManager()->CustomStateChanged(aElement, aState); + } +} + void PresShell::DocumentStatesChanged(DocumentState aStateMask) { MOZ_ASSERT(!mIsDocumentGone, "Unexpected DocumentStatesChanged"); MOZ_ASSERT(mDocument); @@ -5582,7 +5657,7 @@ nsresult PresShell::SetResolutionAndScaleTo(float aResolution, // GetResolution handles mResolution being nothing by returning 1 so this // is checking that the resolution is actually changing. - bool resolutionUpdated = (aResolution != GetResolution()); + bool resolutionUpdated = aResolution != GetResolution(); mLastResolutionChangeOrigin = aOrigin; @@ -5647,7 +5722,9 @@ void PresShell::SetRenderingState(const RenderingState& aState) { } void PresShell::SynthesizeMouseMove(bool aFromScroll) { - if (!StaticPrefs::layout_reflow_synthMouseMove()) return; + if (!StaticPrefs::layout_reflow_synthMouseMove()) { + return; + } if (mPaintingSuppressed || !mIsActive || !mPresContext) { return; @@ -5660,8 +5737,9 @@ void PresShell::SynthesizeMouseMove(bool aFromScroll) { return; } - if (mMouseLocation == nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)) + if (mMouseLocation == nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)) { return; + } if (!mSynthMouseMoveEvent.IsPending()) { RefPtr ev = @@ -11220,8 +11298,7 @@ Maybe UseMobileViewportManager( if (nsLayoutUtils::ShouldHandleMetaViewport(aDocument)) { return Some(MobileViewportManager::ManagerType::VisualAndMetaViewport); } - if (StaticPrefs::apz_mvm_force_enabled() || - nsLayoutUtils::AllowZoomingForDocument(aDocument)) { + if (nsLayoutUtils::AllowZoomingForDocument(aDocument)) { return Some(MobileViewportManager::ManagerType::VisualViewportOnly); } return Nothing(); @@ -11244,6 +11321,11 @@ void PresShell::MaybeRecreateMobileViewportManager(bool aAfterInitialization) { return; } + if (!mPresContext->IsRootContentDocumentCrossProcess()) { + MOZ_ASSERT(!mMobileViewportManager, "We never create MVMs for subframes"); + return; + } + if (mMobileViewportManager) { // We have one, but we need to either destroy it completely to replace it // with another one of the correct type. So either way, let's destroy the @@ -11253,16 +11335,6 @@ void PresShell::MaybeRecreateMobileViewportManager(bool aAfterInitialization) { mMVMContext = nullptr; ResetVisualViewportSize(); - - // After we clear out the MVM and the MVMContext, also reset the - // resolution to its pre-MVM value. - SetResolutionAndScaleTo(mDocument->GetSavedResolutionBeforeMVM(), - ResolutionChangeOrigin::MainThreadRestore); - - if (aAfterInitialization) { - // Force a reflow to our correct view manager size. - ForceResizeReflowWithCurrentDimensions(); - } } if (mvmType) { @@ -11270,32 +11342,33 @@ void PresShell::MaybeRecreateMobileViewportManager(bool aAfterInitialization) { // have one. MOZ_ASSERT(!mMobileViewportManager); - if (mPresContext->IsRootContentDocumentCrossProcess()) { - // Store the resolution so we can restore to this resolution when - // the MVM is destroyed. - mDocument->SetSavedResolutionBeforeMVM(mResolution.valueOr(1.0f)); - - mMVMContext = new GeckoMVMContext(mDocument, this); - mMobileViewportManager = new MobileViewportManager(mMVMContext, *mvmType); - if (MOZ_UNLIKELY( - MOZ_LOG_TEST(MobileViewportManager::gLog, LogLevel::Debug))) { - nsIURI* uri = mDocument->GetDocumentURI(); - MOZ_LOG(MobileViewportManager::gLog, LogLevel::Debug, - ("Created MVM %p (type %d) for URI %s", - mMobileViewportManager.get(), (int)*mvmType, - uri ? uri->GetSpecOrDefault().get() : "(null)")); - } - - if (aAfterInitialization) { - // Setting the initial viewport will trigger a reflow. - mMobileViewportManager->SetInitialViewport(); - } + mMVMContext = new GeckoMVMContext(mDocument, this); + mMobileViewportManager = new MobileViewportManager(mMVMContext, *mvmType); + if (MOZ_UNLIKELY( + MOZ_LOG_TEST(MobileViewportManager::gLog, LogLevel::Debug))) { + nsIURI* uri = mDocument->GetDocumentURI(); + MOZ_LOG( + MobileViewportManager::gLog, LogLevel::Debug, + ("Created MVM %p (type %d) for URI %s", mMobileViewportManager.get(), + (int)*mvmType, uri ? uri->GetSpecOrDefault().get() : "(null)")); } } + if (aAfterInitialization) { + // Setting the initial viewport will trigger a reflow. + if (mMobileViewportManager) { + mMobileViewportManager->SetInitialViewport(); + } else { + // Force a reflow to our correct view manager size. + ForceResizeReflowWithCurrentDimensions(); + } + // After we clear out the MVM and the MVMContext, also reset the + // resolution to 1. + SetResolutionAndScaleTo(1.0f, ResolutionChangeOrigin::MainThreadRestore); + } } bool PresShell::UsesMobileViewportSizing() const { - return mMobileViewportManager != nullptr && + return mMobileViewportManager && nsLayoutUtils::ShouldHandleMetaViewport(mDocument); } @@ -11708,8 +11781,7 @@ static bool IsTopLevelWidget(nsIWidget* aWidget) { auto windowType = aWidget->GetWindowType(); return windowType == WindowType::TopLevel || - windowType == WindowType::Dialog || windowType == WindowType::Popup || - windowType == WindowType::Sheet; + windowType == WindowType::Dialog || windowType == WindowType::Popup; } PresShell::WindowSizeConstraints PresShell::GetWindowSizeConstraints() { diff --git a/layout/base/PresShell.h b/layout/base/PresShell.h index 482ace1421..2b43b3c492 100644 --- a/layout/base/PresShell.h +++ b/layout/base/PresShell.h @@ -531,6 +531,12 @@ class PresShell final : public nsStubDocumentObserver, dom::HTMLSlotElement* aOldSlot, dom::HTMLSlotElement* aNewSlot); + /** + * Handles when a CustomStateSet state is about to be removed or added. + */ + void CustomStatesWillChange(Element& aElement); + void CustomStateChanged(Element& aElement, nsAtom* aState); + void PostRecreateFramesFor(Element*); void RestyleForAnimation(Element*, RestyleHint); @@ -1603,6 +1609,18 @@ class PresShell final : public nsStubDocumentObserver, */ MOZ_CAN_RUN_SCRIPT nsresult ScrollToAnchor(); + /** + * Finds text fragments ranes in the document, highlights the ranges and + * scrolls to the last text fragment range on the page if + * `aScrollToTextFragment` is true. + * + * @param aScrollToTextFragment If true, scrolls the view to the last text + * fragment. + * @return True if scrolling happened. + */ + MOZ_CAN_RUN_SCRIPT bool HighlightAndGoToTextFragment( + bool aScrollToTextFragment); + /** * When scroll anchoring adjusts positions in the root frame during page load, * it may move our scroll position in the root frame. diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 8c07512093..81ffebf89a 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -2087,6 +2087,28 @@ void RestyleManager::AnimationsWithDestroyedFrame ::StopAnimationsWithoutFrame( } } +// When using handled hints by an ancestor, we need to make sure that our +// ancestor in the DOM tree is actually our ancestor in the flat tree. +// Otherwise, we can't guarantee that e.g. a repaint from an ancestor in the DOM +// will really end up repainting us. +static bool CanUseHandledHintsFromAncestors(const nsIFrame* aFrame) { + if (aFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)) { + // An out of flow can be parented in other part of the tree. + return false; + } + if (aFrame->IsColumnSpanInMulticolSubtree()) { + // Any column-spanner's parent frame is not its DOM parent's primary frame. + return false; + } + if (aFrame->IsTableCaption()) { + // This one is more subtle. captions are in-flow children of the table + // frame. But they are parented to the table wrapper. So hints handled for + // the inner table might not be applicable to us. + return false; + } + return true; +} + #ifdef DEBUG static bool IsAnonBox(const nsIFrame* aFrame) { return aFrame->Style()->IsAnonBox(); @@ -2185,8 +2207,7 @@ static bool IsInReplicatedFixedPosTree(const nsIFrame* aFrame) { void ServoRestyleState::AssertOwner(const ServoRestyleState& aParent) const { MOZ_ASSERT(mOwner); - MOZ_ASSERT(!mOwner->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)); - MOZ_ASSERT(!mOwner->IsColumnSpanInMulticolSubtree()); + MOZ_ASSERT(CanUseHandledHintsFromAncestors(mOwner)); // We allow aParent.mOwner to be null, for cases when we're not starting at // the root of the tree. We also allow aParent.mOwner to be somewhere up our // expected owner chain not our immediate owner, which allows us creating long @@ -2309,7 +2330,7 @@ size_t ServoRestyleState::ProcessMaybeNestedWrapperRestyle(nsIFrame* aParent, nsLayoutUtils::FirstContinuationOrIBSplitSibling(parent); if (parentForRestyle != aParent) { parentRestyleState.emplace(*parentForRestyle, *this, nsChangeHint_Empty, - Type::InFlow); + CanUseHandledHints::Yes); } ServoRestyleState& curRestyleState = parentRestyleState ? *parentRestyleState : *this; @@ -2332,7 +2353,7 @@ size_t ServoRestyleState::ProcessMaybeNestedWrapperRestyle(nsIFrame* aParent, // the other hand, presumably our mChangesHandled already has the bits // we really want here so in practice it doesn't matter. ServoRestyleState childState(*cur, curRestyleState, nsChangeHint_Empty, - Type::InFlow, + CanUseHandledHints::Yes, /* aAssertWrapperRestyleLength = */ false); numProcessed += childState.ProcessMaybeNestedWrapperRestyle(cur, aIndex + 1); @@ -2652,8 +2673,7 @@ static void UpdateOneAdditionalComputedStyle(nsIFrame* aFrame, uint32_t aIndex, uint32_t equalStructs; // Not used, actually. nsChangeHint childHint = aOldContext.CalcStyleDifference(*newStyle, &equalStructs); - if (!aFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW) && - !aFrame->IsColumnSpanInMulticolSubtree()) { + if (CanUseHandledHintsFromAncestors(aFrame)) { childHint = NS_RemoveSubsumedHints(childHint, aRestyleState.ChangesHandledFor(aFrame)); } @@ -2812,11 +2832,8 @@ bool RestyleManager::ProcessPostTraversal(Element* aElement, const bool isOutOfFlow = primaryFrame && primaryFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW); - // We need this because any column-spanner's parent frame is not its DOM - // parent's primary frame. We need some special check similar to out-of-flow - // frames. - const bool isColumnSpan = - primaryFrame && primaryFrame->IsColumnSpanInMulticolSubtree(); + const bool canUseHandledHints = + primaryFrame && CanUseHandledHintsFromAncestors(primaryFrame); // Grab the change hint from Servo. bool wasRestyled = false; @@ -2848,11 +2865,12 @@ bool RestyleManager::ProcessPostTraversal(Element* aElement, maybeAnonBoxChild = primaryFrame->GetPlaceholderFrame(); } else { maybeAnonBoxChild = primaryFrame; - // Do not subsume change hints for the column-spanner. - if (!isColumnSpan) { - changeHint = NS_RemoveSubsumedHints( - changeHint, aRestyleState.ChangesHandledFor(styleFrame)); - } + } + + // Do not subsume change hints for the column-spanner. + if (canUseHandledHints) { + changeHint = NS_RemoveSubsumedHints( + changeHint, aRestyleState.ChangesHandledFor(styleFrame)); } // If the parent wasn't restyled, the styles of our anon box parents won't @@ -2944,10 +2962,9 @@ bool RestyleManager::ProcessPostTraversal(Element* aElement, Maybe thisFrameRestyleState; if (styleFrame) { - auto type = isOutOfFlow || isColumnSpan ? ServoRestyleState::Type::OutOfFlow - : ServoRestyleState::Type::InFlow; - - thisFrameRestyleState.emplace(*styleFrame, aRestyleState, changeHint, type); + thisFrameRestyleState.emplace( + *styleFrame, aRestyleState, changeHint, + ServoRestyleState::CanUseHandledHints(canUseHandledHints)); } // We can't really assume as used changes from display: contents elements (or @@ -3435,6 +3452,45 @@ void RestyleManager::ElementStateChanged(Element* aElement, MaybeRestyleForRelativeSelectorState(styleSet, aElement, aChangedBits); } +void RestyleManager::CustomStatesWillChange(Element& aElement) { + MOZ_DIAGNOSTIC_ASSERT(!mInStyleRefresh); + + IncrementUndisplayedRestyleGeneration(); + + // Relative selector invalidation travels ancestor and earlier sibling + // direction, so it's very possible that it invalidates a styled element. + if (!aElement.HasServoData() && + !(aElement.GetSelectorFlags() & + NodeSelectorFlags::RelativeSelectorSearchDirectionAncestorSibling)) { + return; + } + + ServoElementSnapshot& snapshot = SnapshotFor(aElement); + snapshot.AddCustomStates(aElement); +} + +void RestyleManager::CustomStateChanged(Element& aElement, nsAtom* aState) { + ServoStyleSet& styleSet = *StyleSet(); + MaybeRestyleForNthOfCustomState(styleSet, aElement, aState); + styleSet.MaybeInvalidateRelativeSelectorCustomStateDependency( + aElement, aState, Snapshots()); +} + +void RestyleManager::MaybeRestyleForNthOfCustomState(ServoStyleSet& aStyleSet, + Element& aChild, + nsAtom* aState) { + const auto* parentNode = aChild.GetParentNode(); + MOZ_ASSERT(parentNode); + const auto parentFlags = parentNode->GetSelectorFlags(); + if (!(parentFlags & NodeSelectorFlags::HasSlowSelectorNthOf)) { + return; + } + + if (aStyleSet.HasNthOfCustomStateDependency(aChild, aState)) { + RestyleSiblingsForNthOf(&aChild, parentFlags); + } +} + void RestyleManager::MaybeRestyleForNthOfState(ServoStyleSet& aStyleSet, Element* aChild, ElementState aChangedBits) { diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 62fef15a16..8485fe18a0 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -66,13 +66,11 @@ class ServoRestyleState { // our children too if we're out of flow since they aren't necessarily // parented in DOM order, and thus a change handled by a DOM ancestor doesn't // necessarily mean that it's handled for an ancestor frame. - enum class Type { - InFlow, - OutOfFlow, - }; + enum class CanUseHandledHints : bool { No = false, Yes }; ServoRestyleState(const nsIFrame& aOwner, ServoRestyleState& aParentState, - nsChangeHint aHintForThisFrame, Type aType, + nsChangeHint aHintForThisFrame, + CanUseHandledHints aCanUseHandledHints, bool aAssertWrapperRestyleLength = true) : mStyleSet(aParentState.mStyleSet), mChangeList(aParentState.mChangeList), @@ -81,7 +79,7 @@ class ServoRestyleState { aParentState.mPendingScrollAnchorSuppressions), mPendingWrapperRestyleOffset( aParentState.mPendingWrapperRestyles.Length()), - mChangesHandled(aType == Type::InFlow + mChangesHandled(bool(aCanUseHandledHints) ? aParentState.mChangesHandled | aHintForThisFrame : aHintForThisFrame) #ifdef DEBUG @@ -90,7 +88,7 @@ class ServoRestyleState { mAssertWrapperRestyleLength(aAssertWrapperRestyleLength) #endif { - if (aType == Type::InFlow) { + if (bool(aCanUseHandledHints)) { AssertOwner(aParentState); } } @@ -361,6 +359,11 @@ class RestyleManager { void ElementStateChanged(Element*, dom::ElementState); + void CustomStatesWillChange(Element&); + void CustomStateChanged(Element&, nsAtom* aState); + void MaybeRestyleForNthOfCustomState(ServoStyleSet&, Element&, + nsAtom* aState); + /** * Posts restyle hints for siblings of an element and their descendants if the * element's parent has NODE_HAS_SLOW_SELECTOR_NTH_OF and the element has a diff --git a/layout/base/crashtests/crashtests.list b/layout/base/crashtests/crashtests.list index d9cf87f4d2..3b1ed1e3d4 100644 --- a/layout/base/crashtests/crashtests.list +++ b/layout/base/crashtests/crashtests.list @@ -494,7 +494,7 @@ load 1463940.html HTTP load 1464641.html load 1464737.html load 1466638.html -pref(layout.css.motion-path-ray.enabled,true) asserts(1-1) load 1467519.html # bogus size +asserts(1-1) load 1467519.html # bogus size load 1467688.html load 1467964.html load 1469354.html @@ -547,7 +547,7 @@ load 1599532.html pref(layout.accessiblecaret.enabled,true) load 1606492.html load 1654315.html load 1676301-1.html -pref(apz.mvm.force-enabled,false) pref(dom.meta-viewport.enabled,false) pref(apz.allow_zooming,false) pref(layout.dynamic-toolbar-max-height,100) load 1689371.html +pref(dom.meta-viewport.enabled,false) pref(apz.allow_zooming,false) pref(layout.dynamic-toolbar-max-height,100) load 1689371.html load 1685146.html load 1689912.html load 1690163.html diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 149f2f24bf..c0f35c278d 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -4985,9 +4985,8 @@ nsCSSFrameConstructor::FindSVGData(const Element& aElement, return data; } -void nsCSSFrameConstructor::InsertPageBreakItem( - nsIContent* aContent, FrameConstructionItemList& aItems, - InsertPageBreakLocation location) { +void nsCSSFrameConstructor::AppendPageBreakItem( + nsIContent* aContent, FrameConstructionItemList& aItems) { RefPtr pseudoStyle = mPresShell->StyleSet()->ResolveNonInheritingAnonymousBoxStyle( PseudoStyleType::pageBreak); @@ -4997,13 +4996,8 @@ void nsCSSFrameConstructor::InsertPageBreakItem( static constexpr FrameConstructionData sPageBreakData(NS_NewPageBreakFrame, FCDATA_SKIP_FRAMESET); - if (location == InsertPageBreakLocation::eBefore) { - aItems.PrependItem(this, &sPageBreakData, aContent, pseudoStyle.forget(), - true); - } else { - aItems.AppendItem(this, &sPageBreakData, aContent, pseudoStyle.forget(), - true); - } + aItems.AppendItem(this, &sPageBreakData, aContent, pseudoStyle.forget(), + true); } bool nsCSSFrameConstructor::ShouldCreateItemsForChild( @@ -6012,7 +6006,7 @@ nsIFrame* nsCSSFrameConstructor::GetInsertionPrevSibling( // Find the frame that precedes the insertion point. FlattenedChildIterator iter(aInsertion->mContainer); - if (iter.ShadowDOMInvolved() || !aChild->IsRootOfNativeAnonymousSubtree()) { + if (!aChild->IsRootOfNativeAnonymousSubtree()) { // The check for IsRootOfNativeAnonymousSubtree() is because editor is // severely broken and calls us directly for native anonymous // nodes that it creates. @@ -8390,7 +8384,7 @@ void nsCSSFrameConstructor::RecreateFramesForContent( } // TODO(emilio): We technically can find the right insertion point nowadays - // using StyleChildrenIterator rather than FlattenedTreeIterator. But we'd + // using StyleChildrenIterator rather than FlattenedChildIterator. But we'd // need to tweak the setup to insert into replaced elements to filter which // anonymous roots can be allowed, and which can't. // diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index 283d1385ce..51d5fe32d0 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -1423,18 +1423,8 @@ class nsCSSFrameConstructor final : public nsFrameManager { // for it. void ReframeTextIfNeeded(nsIContent* aContent); - enum InsertPageBreakLocation { eBefore, eAfter }; - inline void AppendPageBreakItem(nsIContent* aContent, - FrameConstructionItemList& aItems) { - InsertPageBreakItem(aContent, aItems, InsertPageBreakLocation::eAfter); - } - inline void PrependPageBreakItem(nsIContent* aContent, - FrameConstructionItemList& aItems) { - InsertPageBreakItem(aContent, aItems, InsertPageBreakLocation::eBefore); - } - void InsertPageBreakItem(nsIContent* aContent, - FrameConstructionItemList& aItems, - InsertPageBreakLocation location); + void AppendPageBreakItem(nsIContent* aContent, + FrameConstructionItemList& aItems); // Function to find FrameConstructionData for aElement. Will return // null if aElement is not HTML. diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index d66d55d6bb..8707dcba5f 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -50,16 +50,7 @@ using BidiEmbeddingLevel = mozilla::intl::BidiEmbeddingLevel; // like an insignificant dot static const int32_t kMinBidiIndicatorPixels = 2; -nsCaret::nsCaret() - : mOverrideOffset(0), - mBlinkCount(-1), - mBlinkRate(0), - mHideCount(0), - mIsBlinkOn(false), - mVisible(false), - mReadOnly(false), - mShowDuringSelection(false), - mIgnoreUserModify(true) {} +nsCaret::nsCaret() = default; nsCaret::~nsCaret() { StopBlinking(); } @@ -70,10 +61,6 @@ nsresult nsCaret::Init(PresShell* aPresShell) { do_GetWeakReference(aPresShell); // the presshell owns us, so no addref NS_ASSERTION(mPresShell, "Hey, pres shell should support weak refs"); - mShowDuringSelection = - LookAndFeel::GetInt(LookAndFeel::IntID::ShowCaretDuringSelection, - mShowDuringSelection ? 1 : 0) != 0; - RefPtr selection = aPresShell->GetSelection(nsISelectionController::SELECTION_NORMAL); if (!selection) { @@ -82,6 +69,7 @@ nsresult nsCaret::Init(PresShell* aPresShell) { selection->AddSelectionListener(this); mDomSelectionWeak = selection; + UpdateCaretPositionFromSelectionIfNeeded(); return NS_OK; } @@ -137,8 +125,7 @@ void nsCaret::Terminate() { } mDomSelectionWeak = nullptr; mPresShell = nullptr; - - mOverrideContent = nullptr; + mCaretPosition = {}; } NS_IMPL_ISUPPORTS(nsCaret, nsISelectionListener) @@ -148,15 +135,30 @@ Selection* nsCaret::GetSelection() { return mDomSelectionWeak; } void nsCaret::SetSelection(Selection* aDOMSel) { MOZ_ASSERT(aDOMSel); mDomSelectionWeak = aDOMSel; + UpdateCaretPositionFromSelectionIfNeeded(); ResetBlinking(); - SchedulePaint(aDOMSel); + SchedulePaint(); } -void nsCaret::SetVisible(bool inMakeVisible) { - mVisible = inMakeVisible; - mIgnoreUserModify = mVisible; +void nsCaret::SetVisible(bool aVisible) { + const bool wasVisible = mVisible; + mVisible = aVisible; + mIgnoreUserModify = aVisible; + if (mVisible != wasVisible) { + CaretVisibilityMaybeChanged(); + } +} + +bool nsCaret::IsVisible() const { return mVisible && !mHideCount; } + +void nsCaret::CaretVisibilityMaybeChanged() { ResetBlinking(); SchedulePaint(); + if (IsVisible()) { + // We ignore caret position updates when the caret is not visible, so we + // update the caret position here if needed. + UpdateCaretPositionFromSelectionIfNeeded(); + } } void nsCaret::AddForceHide() { @@ -164,20 +166,18 @@ void nsCaret::AddForceHide() { if (++mHideCount > 1) { return; } - ResetBlinking(); - SchedulePaint(); + CaretVisibilityMaybeChanged(); } void nsCaret::RemoveForceHide() { if (!mHideCount || --mHideCount) { return; } - ResetBlinking(); - SchedulePaint(); + CaretVisibilityMaybeChanged(); } -void nsCaret::SetCaretReadOnly(bool inMakeReadonly) { - mReadOnly = inMakeReadonly; +void nsCaret::SetCaretReadOnly(bool aReadOnly) { + mReadOnly = aReadOnly; ResetBlinking(); SchedulePaint(); } @@ -333,61 +333,48 @@ nsRect nsCaret::GetGeometryForFrame(nsIFrame* aFrame, int32_t aFrameOffset, return rect; } -nsIFrame* nsCaret::GetFrameAndOffset(const Selection* aSelection, - nsINode* aOverrideNode, - int32_t aOverrideOffset, - int32_t* aFrameOffset, - nsIFrame** aUnadjustedFrame) { - if (aUnadjustedFrame) { - *aUnadjustedFrame = nullptr; +auto nsCaret::CaretPositionFor(const Selection* aSelection) -> CaretPosition { + if (!aSelection) { + return {}; } - - nsINode* focusNode; - int32_t focusOffset; - - if (aOverrideNode) { - focusNode = aOverrideNode; - focusOffset = aOverrideOffset; - } else if (aSelection) { - focusNode = aSelection->GetFocusNode(); - focusOffset = aSelection->FocusOffset(); - } else { - return nullptr; + const nsFrameSelection* frameSelection = aSelection->GetFrameSelection(); + if (!frameSelection) { + return {}; } + nsINode* node = aSelection->GetFocusNode(); + if (!node) { + return {}; + } + return { + node, + int32_t(aSelection->FocusOffset()), + frameSelection->GetHint(), + frameSelection->GetCaretBidiLevel(), + }; +} - if (!focusNode || !focusNode->IsContent() || !aSelection) { - return nullptr; +CaretFrameData nsCaret::GetFrameAndOffset(const CaretPosition& aPosition) { + nsINode* focusNode = aPosition.mContent; + int32_t focusOffset = aPosition.mOffset; + + if (!focusNode || !focusNode->IsContent()) { + return {}; } nsIContent* contentNode = focusNode->AsContent(); - nsFrameSelection* frameSelection = aSelection->GetFrameSelection(); - BidiEmbeddingLevel bidiLevel = frameSelection->GetCaretBidiLevel(); - const CaretFrameData result = - SelectionMovementUtils::GetCaretFrameForNodeOffset( - frameSelection, contentNode, focusOffset, frameSelection->GetHint(), - bidiLevel, ForceEditableRegion::No); - // FIXME: It's odd to update nsFrameSelection within this method which is - // named as a getter. - if (result.mFrame) { - frameSelection->SetHint(result.mHint); - } - if (aUnadjustedFrame) { - *aUnadjustedFrame = result.mUnadjustedFrame; - } - if (aFrameOffset) { - *aFrameOffset = result.mOffsetInFrameContent; - } - return result.mFrame; + return SelectionMovementUtils::GetCaretFrameForNodeOffset( + nullptr, contentNode, focusOffset, aPosition.mHint, aPosition.mBidiLevel, + ForceEditableRegion::No); } /* static */ nsIFrame* nsCaret::GetGeometry(const Selection* aSelection, nsRect* aRect) { - int32_t frameOffset; - nsIFrame* frame = GetFrameAndOffset(aSelection, nullptr, 0, &frameOffset); - if (frame) { - *aRect = GetGeometryForFrame(frame, frameOffset, nullptr); + auto data = GetFrameAndOffset(CaretPositionFor(aSelection)); + if (data.mFrame) { + *aRect = + GetGeometryForFrame(data.mFrame, data.mOffsetInFrameContent, nullptr); } - return frame; + return data.mFrame; } [[nodiscard]] static nsIFrame* GetContainingBlockIfNeeded(nsIFrame* aFrame) { @@ -397,39 +384,56 @@ nsIFrame* nsCaret::GetGeometry(const Selection* aSelection, nsRect* aRect) { return aFrame->GetContainingBlock(); } -void nsCaret::SchedulePaint(Selection* aSelection) { - Selection* selection; - if (aSelection) { - selection = aSelection; - } else { - selection = GetSelection(); +void nsCaret::SchedulePaint() { + if (mLastPaintedFrame) { + mLastPaintedFrame->SchedulePaint(); + mLastPaintedFrame = nullptr; } - - int32_t frameOffset; - nsIFrame* frame = GetFrameAndOffset(selection, mOverrideContent, - mOverrideOffset, &frameOffset); - if (!frame) { + auto data = GetFrameAndOffset(mCaretPosition); + if (!data.mFrame) { return; } - + nsIFrame* frame = data.mFrame; if (nsIFrame* cb = GetContainingBlockIfNeeded(frame)) { - cb->SchedulePaint(); - } else { - frame->SchedulePaint(); + frame = cb; } + frame->SchedulePaint(); } void nsCaret::SetVisibilityDuringSelection(bool aVisibility) { + if (mShowDuringSelection == aVisibility) { + return; + } mShowDuringSelection = aVisibility; + if (mHiddenDuringSelection && aVisibility) { + RemoveForceHide(); + mHiddenDuringSelection = false; + } SchedulePaint(); } -void nsCaret::SetCaretPosition(nsINode* aNode, int32_t aOffset) { - mOverrideContent = aNode; - mOverrideOffset = aOffset; +void nsCaret::UpdateCaretPositionFromSelectionIfNeeded() { + if (mFixedCaretPosition) { + return; + } + CaretPosition newPos = CaretPositionFor(GetSelection()); + if (newPos == mCaretPosition) { + return; + } + mCaretPosition = newPos; + SchedulePaint(); +} +void nsCaret::SetCaretPosition(nsINode* aNode, int32_t aOffset) { + // Schedule a paint with the old position to invalidate. + mFixedCaretPosition = !!aNode; + if (mFixedCaretPosition) { + mCaretPosition = {aNode, aOffset}; + SchedulePaint(); + } else { + UpdateCaretPositionFromSelectionIfNeeded(); + } ResetBlinking(); - SchedulePaint(); } void nsCaret::CheckSelectionLanguageChange() { @@ -478,16 +482,15 @@ nsIFrame* nsCaret::GetPaintGeometry(nsRect* aCaretRect, nsRect* aHookRect, // taken into account when computing the caret position below. CheckSelectionLanguageChange(); - int32_t frameOffset; - nsIFrame* unadjustedFrame = nullptr; - nsIFrame* frame = - GetFrameAndOffset(GetSelection(), mOverrideContent, mOverrideOffset, - &frameOffset, &unadjustedFrame); - MOZ_ASSERT(!!frame == !!unadjustedFrame); - if (!frame) { + auto data = GetFrameAndOffset(mCaretPosition); + MOZ_ASSERT(!!data.mFrame == !!data.mUnadjustedFrame); + if (!data.mFrame) { return nullptr; } + nsIFrame* frame = data.mFrame; + nsIFrame* unadjustedFrame = data.mUnadjustedFrame; + int32_t frameOffset(data.mOffsetInFrameContent); // Now we have a frame, check whether it's appropriate to show the caret here. // Note we need to check the unadjusted frame, otherwise consider the // following case: @@ -555,26 +558,35 @@ void nsCaret::PaintCaret(DrawTarget& aDrawTarget, nsIFrame* aForFrame, NS_IMETHODIMP nsCaret::NotifySelectionChanged(Document*, Selection* aDomSel, int16_t aReason, int32_t aAmount) { - // Note that aDomSel, per the comment below may not be the same as our - // selection, but that's OK since if that is the case, it wouldn't have - // mattered what IsVisible() returns here, so we just opt for checking - // the selection later down below. - if ((aReason & nsISelectionListener::MOUSEUP_REASON) || - !IsVisible(aDomSel)) // this wont do - return NS_OK; - // The same caret is shared amongst the document and any text widgets it // may contain. This means that the caret could get notifications from // multiple selections. // // If this notification is for a selection that is not the one the - // the caret is currently interested in (mDomSelectionWeak), then there - // is nothing to do! + // the caret is currently interested in (mDomSelectionWeak), or the caret + // position is fixed, then there is nothing to do! + if (mDomSelectionWeak != aDomSel) { + return NS_OK; + } - if (mDomSelectionWeak != aDomSel) return NS_OK; + // Check if we need to hide / un-hide the caret due to the selection being + // collapsed. + if (!mShowDuringSelection && + !aDomSel->IsCollapsed() != mHiddenDuringSelection) { + if (mHiddenDuringSelection) { + RemoveForceHide(); + } else { + AddForceHide(); + } + mHiddenDuringSelection = !mHiddenDuringSelection; + } - ResetBlinking(); - SchedulePaint(aDomSel); + // We don't bother computing the caret position when invisible. We'll do it if + // we become visible in CaretVisibilityMaybeChanged(). + if (IsVisible()) { + UpdateCaretPositionFromSelectionIfNeeded(); + ResetBlinking(); + } return NS_OK; } @@ -589,7 +601,7 @@ void nsCaret::ResetBlinking() { mIsBlinkOn = true; - if (mReadOnly || !mVisible || mHideCount) { + if (mReadOnly || !IsVisible()) { StopBlinking(); return; } @@ -647,49 +659,6 @@ size_t nsCaret::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { return total; } -bool nsCaret::IsMenuPopupHidingCaret() { - // Check if there are open popups. - nsXULPopupManager* popMgr = nsXULPopupManager::GetInstance(); - nsTArray popups; - popMgr->GetVisiblePopups(popups); - - if (popups.Length() == 0) - return false; // No popups, so caret can't be hidden by them. - - // Get the selection focus content, that's where the caret would - // go if it was drawn. - if (!mDomSelectionWeak) { - return true; // No selection/caret to draw. - } - nsCOMPtr caretContent = - nsIContent::FromNodeOrNull(mDomSelectionWeak->GetFocusNode()); - if (!caretContent) return true; // No selection/caret to draw. - - // If there's a menu popup open before the popup with - // the caret, don't show the caret. - for (uint32_t i = 0; i < popups.Length(); i++) { - nsMenuPopupFrame* popupFrame = static_cast(popups[i]); - nsIContent* popupContent = popupFrame->GetContent(); - - if (caretContent->IsInclusiveDescendantOf(popupContent)) { - // The caret is in this popup. There were no menu popups before this - // popup, so don't hide the caret. - return false; - } - - if (popupFrame->GetPopupType() == widget::PopupType::Menu && - !popupFrame->IsContextMenu()) { - // This is an open menu popup. It does not contain the caret (else we'd - // have returned above). Even if the caret is in a subsequent popup, - // or another document/frame, it should be hidden. - return true; - } - } - - // There are no open menu popups, no need to hide the caret. - return false; -} - void nsCaret::ComputeCaretRects(nsIFrame* aFrame, int32_t aFrameOffset, nsRect* aCaretRect, nsRect* aHookRect) { NS_ASSERTION(aFrame, "Should have a frame here"); diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index 43329c827f..cba719962c 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -10,10 +10,10 @@ #define nsCaret_h__ #include "mozilla/MemoryReporting.h" -#include "mozilla/dom/Selection.h" +#include "mozilla/SelectionMovementUtils.h" #include "nsCoord.h" +#include "nsIFrame.h" #include "nsISelectionListener.h" -#include "nsIWeakReferenceUtils.h" #include "nsPoint.h" #include "nsRect.h" @@ -46,10 +46,10 @@ class nsCaret final : public nsISelectionListener { using CaretAssociationHint = mozilla::CaretAssociationHint; - nsresult Init(mozilla::PresShell* aPresShell); + nsresult Init(mozilla::PresShell*); void Terminate(); - void SetSelection(mozilla::dom::Selection* aDOMSel); + void SetSelection(mozilla::dom::Selection*); mozilla::dom::Selection* GetSelection(); /** @@ -61,40 +61,18 @@ class nsCaret final : public nsISelectionListener { * those with user-modify: read-only */ void SetIgnoreUserModify(bool aIgnoreUserModify); - /** SetVisible will set the visibility of the caret - * @param inMakeVisible true to show the caret, false to hide it + /** + * SetVisible will set the visibility of the caret + * @param aVisible true to show the caret, false to hide it */ - void SetVisible(bool intMakeVisible); - /** IsVisible will get the visibility of the caret. - * This returns false if the caret is hidden because it was set - * to not be visible, or because the selection is not collapsed, or - * because an open popup is hiding the caret. - * It does not take account of blinking or the caret being hidden - * because we're in non-editable/disabled content. + void SetVisible(bool aVisible); + /** + * IsVisible will get the visibility of the caret. + * It does not take account of blinking or the caret being hidden because + * we're in non-editable/disabled content. */ - bool IsVisible(mozilla::dom::Selection* aSelection = nullptr) { - if (!mVisible || mHideCount) { - return false; - } - - if (!mShowDuringSelection) { - mozilla::dom::Selection* selection; - if (aSelection) { - selection = aSelection; - } else { - selection = GetSelection(); - } - if (!selection || !selection->IsCollapsed()) { - return false; - } - } - - if (IsMenuPopupHidingCaret()) { - return false; - } + bool IsVisible() const; - return true; - } /** * AddForceHide() increases mHideCount and hide the caret even if * SetVisible(true) has been or will be called. This is useful when the @@ -114,7 +92,7 @@ class nsCaret final : public nsISelectionListener { * @param inMakeReadonly true to show the caret in a 'read only' state, * false to show the caret in normal, editing state */ - void SetCaretReadOnly(bool inMakeReadonly); + void SetCaretReadOnly(bool aReadOnly); /** * @param aVisibility true if the caret should be visible even when the * selection is not collapsed. @@ -132,7 +110,10 @@ class nsCaret final : public nsISelectionListener { * Schedule a repaint for the frame where the caret would appear. * Does not check visibility etc. */ - void SchedulePaint(mozilla::dom::Selection* aSelection = nullptr); + void SchedulePaint(); + + nsIFrame* GetLastPaintedFrame() { return mLastPaintedFrame; } + void SetLastPaintedFrame(nsIFrame* aFrame) { mLastPaintedFrame = aFrame; } /** * Returns a frame to paint in, and the bounds of the painted caret @@ -142,6 +123,7 @@ class nsCaret final : public nsISelectionListener { * off). */ nsIFrame* GetPaintGeometry(nsRect* aRect); + /** * Same as the overload above, but returns the caret and hook rects * separately, and also computes the color if requested. @@ -165,6 +147,22 @@ class nsCaret final : public nsISelectionListener { // nsISelectionListener interface NS_DECL_NSISELECTIONLISTENER + /** The current caret position. */ + struct CaretPosition { + nsCOMPtr mContent; + int32_t mOffset = 0; + CaretAssociationHint mHint{0}; + mozilla::intl::BidiEmbeddingLevel mBidiLevel; + + bool operator==(const CaretPosition& aOther) const { + return mContent == aOther.mContent && mOffset == aOther.mOffset && + mHint == aOther.mHint && mBidiLevel == aOther.mBidiLevel; + } + explicit operator bool() const { return !!mContent; } + }; + + static CaretPosition CaretPositionFor(const mozilla::dom::Selection*); + /** * Gets the position and size of the caret that would be drawn for * the focus node/offset of aSelection (assuming it would be drawn, @@ -181,18 +179,9 @@ class nsCaret final : public nsISelectionListener { static nsRect GetGeometryForFrame(nsIFrame* aFrame, int32_t aFrameOffset, nscoord* aBidiIndicatorSize); - // Get the frame and frame offset based on the focus node and focus offset - // of aSelection. If aOverrideNode and aOverride are provided, use them - // instead. - // @param aFrameOffset return the frame offset if non-null. - // @param aUnadjustedFrame return the original frame that the selection is - // targeting, without any adjustment for painting. - // @return the frame of the focus node. - static nsIFrame* GetFrameAndOffset(const mozilla::dom::Selection* aSelection, - nsINode* aOverrideNode, - int32_t aOverrideOffset, - int32_t* aFrameOffset, - nsIFrame** aUnadjustedFrame = nullptr); + // Get the frame and frame offset based on aPosition. + static mozilla::CaretFrameData GetFrameAndOffset( + const CaretPosition& aPosition); size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; @@ -200,6 +189,7 @@ class nsCaret final : public nsISelectionListener { static void CaretBlinkCallback(nsITimer* aTimer, void* aClosure); void CheckSelectionLanguageChange(); + void CaretVisibilityMaybeChanged(); void ResetBlinking(); void StopBlinking(); @@ -213,72 +203,73 @@ class nsCaret final : public nsISelectionListener { void ComputeCaretRects(nsIFrame* aFrame, int32_t aFrameOffset, nsRect* aCaretRect, nsRect* aHookRect); - // Returns true if we should not draw the caret because of XUL menu popups. - // The caret should be hidden if: - // 1. An open popup contains the caret, but a menu popup exists before the - // caret-owning popup in the popup list (i.e. a menu is in front of the - // popup with the caret). If the menu itself contains the caret we don't - // hide it. - // 2. A menu popup is open, but there is no caret present in any popup. - // 3. The caret selection is empty. - bool IsMenuPopupHidingCaret(); + // If we're tracking the selection, this updates the caret position and + // invalidates paint as needed. + void UpdateCaretPositionFromSelectionIfNeeded(); nsWeakPtr mPresShell; mozilla::WeakPtr mDomSelectionWeak; nsCOMPtr mBlinkTimer; - /** - * The content to draw the caret at. If null, we use mDomSelectionWeak's - * focus node instead. - */ - nsCOMPtr mOverrideContent; - /** - * The character offset to draw the caret at. - * Ignored if mOverrideContent is null. - */ - int32_t mOverrideOffset; + CaretPosition mCaretPosition; + + // The last frame we painted the caret in. + WeakFrame mLastPaintedFrame; + /** * mBlinkCount is used to control the number of times to blink the caret * before stopping the blink. This is reset each time we reset the * blinking. */ - int32_t mBlinkCount; + int32_t mBlinkCount = -1; /** * mBlinkRate is the rate of the caret blinking the last time we read it. * It is used as a way to optimize whether we need to reset the blinking * timer. 0 or a negative value means no blinking. */ - int32_t mBlinkRate; + int32_t mBlinkRate = 0; /** * mHideCount is not 0, it means that somebody doesn't want the caret * to be visible. See AddForceHide() and RemoveForceHide(). */ - uint32_t mHideCount; + uint32_t mHideCount = 0; /** * mIsBlinkOn is true when we're in a blink cycle where the caret is on. */ - bool mIsBlinkOn; + bool mIsBlinkOn = false; /** * mIsVisible is true when SetVisible was last called with 'true'. */ - bool mVisible; + bool mVisible = false; /** * mReadOnly is true when the caret is set to "read only" mode (i.e., * it doesn't blink). */ - bool mReadOnly; + bool mReadOnly = false; /** * mShowDuringSelection is true when the caret should be shown even when * the selection is not collapsed. */ - bool mShowDuringSelection; + bool mShowDuringSelection = false; /** * mIgnoreUserModify is true when the caret should be shown even when * it's in non-user-modifiable content. */ - bool mIgnoreUserModify; + bool mIgnoreUserModify = true; + + /** + * If the caret position is fixed, it's been overridden externally and it + * will not track the selection. + */ + bool mFixedCaretPosition = false; + + /** + * If we're currently hiding the caret due to the selection not being + * collapsed. Can only be true if mShowDuringSelection is false. + */ + bool mHiddenDuringSelection = false; }; #endif // nsCaret_h__ diff --git a/layout/base/nsCounterManager.cpp b/layout/base/nsCounterManager.cpp index 7c2e9bb776..f2bbb5e50e 100644 --- a/layout/base/nsCounterManager.cpp +++ b/layout/base/nsCounterManager.cpp @@ -203,7 +203,11 @@ void nsCounterList::SetScope(nsCounterNode* aNode) { // the element itself, then we use that scope. // Otherwise, fall through to consider scopes created by siblings (and // their descendants) in reverse document order. - if (aNode->mType != nsCounterNode::USE && + // Do this only for the list-item counter, while the CSSWG discusses what the + // right thing to do here is, see bug 1548753 and + // https://github.com/w3c/csswg-drafts/issues/5477. + if (mCounterName == nsGkAtoms::list_item && + aNode->mType != nsCounterNode::USE && StaticPrefs::layout_css_counter_ancestor_scope_enabled()) { for (auto* p = aNode->mPseudoFrame; p; p = p->GetParent()) { // This relies on the fact that a RESET node is always the first diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index d1cf9bf237..8ae0e001b8 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -449,6 +449,7 @@ class nsDocumentViewer final : public nsIDocumentViewer, #ifdef NS_PRINTING unsigned mClosingWhilePrinting : 1; + unsigned mCloseWindowAfterPrint : 1; # if NS_PRINT_PREVIEW RefPtr mPrintJob; @@ -520,6 +521,7 @@ nsDocumentViewer::nsDocumentViewer() mInPermitUnloadPrompt(false), #ifdef NS_PRINTING mClosingWhilePrinting(false), + mCloseWindowAfterPrint(false), #endif // NS_PRINTING mReloadEncodingSource(kCharsetUninitialized), mReloadEncoding(nullptr), @@ -3139,6 +3141,20 @@ nsDocumentViewer::GetDoingPrintPreview(bool* aDoingPrintPreview) { return NS_OK; } +NS_IMETHODIMP +nsDocumentViewer::GetCloseWindowAfterPrint(bool* aCloseWindowAfterPrint) { + NS_ENSURE_ARG_POINTER(aCloseWindowAfterPrint); + + *aCloseWindowAfterPrint = mCloseWindowAfterPrint; + return NS_OK; +} + +NS_IMETHODIMP +nsDocumentViewer::SetCloseWindowAfterPrint(bool aCloseWindowAfterPrint) { + mCloseWindowAfterPrint = aCloseWindowAfterPrint; + return NS_OK; +} + NS_IMETHODIMP nsDocumentViewer::ExitPrintPreview() { NS_ENSURE_TRUE(mPrintJob, NS_ERROR_FAILURE); @@ -3301,15 +3317,23 @@ void nsDocumentViewer::OnDonePrinting() { printJob->Destroy(); } - // We are done printing, now clean up. - // - // For non-print-preview jobs, we are actually responsible for cleaning up - // our whole or window (see the OPEN_PRINT_BROWSER code), so gotta - // run window.close(), which will take care of this. - // - // For print preview jobs the front-end code is responsible for cleaning the - // UI. - if (!printJob->CreatedForPrintPreview()) { +// We are done printing, now clean up. +// +// If the original document to print was not a static clone, we opened a new +// window and are responsible for cleaning up the whole or window +// (see the OPEN_PRINT_BROWSER code, specifically +// handleStaticCloneCreatedForPrint()), so gotta run window.close(), which +// will take care of this. +// +// Otherwise the front-end code is responsible for cleaning the UI. +# ifdef ANDROID + // Android doesn't support Content Analysis and prints in a different way, + // so use different logic to clean up. + bool closeWindowAfterPrint = !printJob->CreatedForPrintPreview(); +# else + bool closeWindowAfterPrint = GetCloseWindowAfterPrint(); +# endif + if (closeWindowAfterPrint) { if (mContainer) { if (nsCOMPtr win = mContainer->GetWindow()) { win->Close(); diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index db766f6603..429ad335cc 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -714,12 +714,9 @@ bool nsLayoutUtils::AllowZoomingForDocument( return false; } // True if we allow zooming for all documents on this platform, or if we are - // in RDM and handling meta viewports, which force zoom under some - // circumstances. - BrowsingContext* bc = aDocument ? aDocument->GetBrowsingContext() : nullptr; - return StaticPrefs::apz_allow_zooming() || - (bc && bc->InRDMPane() && - nsLayoutUtils::ShouldHandleMetaViewport(aDocument)); + // in RDM. + BrowsingContext* bc = aDocument->GetBrowsingContext(); + return StaticPrefs::apz_allow_zooming() || (bc && bc->InRDMPane()); } static bool HasVisibleAnonymousContents(Document* aDoc) { @@ -4676,7 +4673,7 @@ nscoord nsLayoutUtils::IntrinsicForAxis( horizontalAxis ? stylePos->mMaxWidth : stylePos->mMaxHeight; PhysicalAxis ourInlineAxis = - aFrame->GetWritingMode().PhysicalAxis(eLogicalAxisInline); + aFrame->GetWritingMode().PhysicalAxis(LogicalAxis::Inline); const bool isInlineAxis = aAxis == ourInlineAxis; auto resetIfKeywords = [](StyleSize& aSize, StyleSize& aMinSize, @@ -4897,8 +4894,8 @@ nscoord nsLayoutUtils::IntrinsicForAxis( // We are computing the size of |aFrame|, so we use the inline & block // dimensions of |aFrame|. result = ratio.ComputeRatioDependentSize( - isInlineAxis ? eLogicalAxisInline : eLogicalAxisBlock, childWM, h, - *contentBoxSizeToBoxSizingAdjust); + isInlineAxis ? LogicalAxis::Inline : LogicalAxis::Block, childWM, + h, *contentBoxSizeToBoxSizingAdjust); // We have get the inlineSizeForAspectRatio value, so we don't have to // recompute this again below. inlineSizeFromAspectRatio.emplace(result); @@ -4910,8 +4907,8 @@ nscoord nsLayoutUtils::IntrinsicForAxis( GetPercentBSize(styleMaxBSize, aFrame, horizontalAxis, h))) { h = std::max(0, h - bSizeTakenByBoxSizing); nscoord maxISize = ratio.ComputeRatioDependentSize( - isInlineAxis ? eLogicalAxisInline : eLogicalAxisBlock, childWM, h, - *contentBoxSizeToBoxSizingAdjust); + isInlineAxis ? LogicalAxis::Inline : LogicalAxis::Block, childWM, + h, *contentBoxSizeToBoxSizingAdjust); if (maxISize < result) { result = maxISize; } @@ -4926,8 +4923,8 @@ nscoord nsLayoutUtils::IntrinsicForAxis( GetPercentBSize(styleMinBSize, aFrame, horizontalAxis, h))) { h = std::max(0, h - bSizeTakenByBoxSizing); nscoord minISize = ratio.ComputeRatioDependentSize( - isInlineAxis ? eLogicalAxisInline : eLogicalAxisBlock, childWM, h, - *contentBoxSizeToBoxSizingAdjust); + isInlineAxis ? LogicalAxis::Inline : LogicalAxis::Block, childWM, + h, *contentBoxSizeToBoxSizingAdjust); if (minISize > result) { result = minISize; } @@ -4990,9 +4987,9 @@ nscoord nsLayoutUtils::IntrinsicForAxis( GetDefiniteSizeTakenByBoxSizing(boxSizingForAR, aFrame, !isInlineAxis, ignorePadding, aPercentageBasis); bSize -= bSizeTakenByBoxSizing; - inlineSizeFromAspectRatio.emplace(ar.ComputeRatioDependentSize( - LogicalAxis::eLogicalAxisInline, childWM, bSize, - *contentBoxSizeToBoxSizingAdjust)); + inlineSizeFromAspectRatio.emplace( + ar.ComputeRatioDependentSize(LogicalAxis::Inline, childWM, bSize, + *contentBoxSizeToBoxSizingAdjust)); } } @@ -5027,7 +5024,7 @@ nscoord nsLayoutUtils::IntrinsicForContainer(gfxContext* aRenderingContext, MOZ_ASSERT(aFrame && aFrame->GetParent()); // We want the size aFrame will contribute to its parent's inline-size. PhysicalAxis axis = - aFrame->GetParent()->GetWritingMode().PhysicalAxis(eLogicalAxisInline); + aFrame->GetParent()->GetWritingMode().PhysicalAxis(LogicalAxis::Inline); return IntrinsicForAxis(axis, aRenderingContext, aFrame, aType, Nothing(), aFlags); } @@ -5056,7 +5053,7 @@ nscoord nsLayoutUtils::MinSizeContributionForAxis( StyleMaxSize maxSize = aAxis == eAxisHorizontal ? stylePos->mMaxWidth : stylePos->mMaxHeight; auto childWM = aFrame->GetWritingMode(); - PhysicalAxis ourInlineAxis = childWM.PhysicalAxis(eLogicalAxisInline); + PhysicalAxis ourInlineAxis = childWM.PhysicalAxis(LogicalAxis::Inline); // According to the spec, max-content and min-content should behave as the // property's initial values in block axis. // It also make senses to use the initial values for -moz-fit-content and @@ -5323,7 +5320,6 @@ nscoord nsLayoutUtils::MinISizeFromInline(nsIFrame* aFrame, "should not be container for font size inflation"); nsIFrame::InlineMinISizeData data; - DISPLAY_MIN_INLINE_SIZE(aFrame, data.mPrevLines); aFrame->AddInlineMinISize(aRenderingContext, &data); data.ForceBreak(); return data.mPrevLines; @@ -5336,7 +5332,6 @@ nscoord nsLayoutUtils::PrefISizeFromInline(nsIFrame* aFrame, "should not be container for font size inflation"); nsIFrame::InlinePrefISizeData data; - DISPLAY_PREF_INLINE_SIZE(aFrame, data.mPrevLines); aFrame->AddInlinePrefISize(aRenderingContext, &data); data.ForceBreak(); return data.mPrevLines; @@ -7449,7 +7444,7 @@ SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement( SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement( HTMLVideoElement* aElement, uint32_t aSurfaceFlags, - RefPtr& aTarget) { + RefPtr& aTarget, bool aOptimizeSourceSurface) { SurfaceFromElementResult result; result.mAlphaType = gfxAlphaType::Opaque; // Assume opaque. @@ -7484,7 +7479,7 @@ SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement( result.mIsWriteOnly = CanvasUtils::CheckWriteOnlySecurity( result.mCORSUsed, result.mPrincipal, result.mHadCrossOriginRedirects); - if (aTarget) { + if (aTarget && aOptimizeSourceSurface) { // They gave us a DrawTarget to optimize for, so even though we have a // layers::Image, we should unconditionally try to grab a SourceSurface and // try to optimize it. @@ -9769,24 +9764,8 @@ void nsLayoutUtils::ComputeSystemFont(nsFont* aSystemFont, /* static */ bool nsLayoutUtils::ShouldHandleMetaViewport(const Document* aDocument) { - auto metaViewportOverride = nsIDocShell::META_VIEWPORT_OVERRIDE_NONE; - if (aDocument) { - if (nsIDocShell* docShell = aDocument->GetDocShell()) { - metaViewportOverride = docShell->GetMetaViewportOverride(); - } - } - switch (metaViewportOverride) { - case nsIDocShell::META_VIEWPORT_OVERRIDE_ENABLED: - return true; - case nsIDocShell::META_VIEWPORT_OVERRIDE_DISABLED: - return false; - default: - MOZ_ASSERT(metaViewportOverride == - nsIDocShell::META_VIEWPORT_OVERRIDE_NONE); - // The META_VIEWPORT_OVERRIDE_NONE case means that there is no override - // and we rely solely on the StaticPrefs. - return StaticPrefs::dom_meta_viewport_enabled(); - } + BrowsingContext* bc = aDocument->GetBrowsingContext(); + return StaticPrefs::dom_meta_viewport_enabled() || (bc && bc->InRDMPane()); } /* static */ diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 697b139ed9..135a9ad9ab 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2230,7 +2230,7 @@ class nsLayoutUtils { } static mozilla::SurfaceFromElementResult SurfaceFromElement( mozilla::dom::HTMLVideoElement* aElement, uint32_t aSurfaceFlags, - RefPtr& aTarget); + RefPtr& aTarget, bool aOptimizeSourceSurface = true); /** * When the document is editable by contenteditable attribute of its root diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index 7d9515c495..0786ec25d9 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -336,6 +336,7 @@ static const char* gExactCallbackPrefs[] = { "intl.accept_languages", "layout.css.devPixelsPerPx", "layout.css.dpi", + "layout.css.letter-spacing.model", "layout.css.text-transform.uppercase-eszett.enabled", "privacy.trackingprotection.enabled", "ui.use_standins_for_native_colors", @@ -608,7 +609,8 @@ void nsPresContext::PreferenceChanged(const char* aPrefName) { } if (prefName.EqualsLiteral( - "layout.css.text-transform.uppercase-eszett.enabled")) { + "layout.css.text-transform.uppercase-eszett.enabled") || + prefName.EqualsLiteral("layout.css.letter-spacing.model")) { changeHint |= NS_STYLE_HINT_REFLOW; } @@ -1410,6 +1412,11 @@ void nsPresContext::SetInRDMPane(bool aInRDMPane) { } mInRDMPane = aInRDMPane; RecomputeTheme(); + if (mPresShell) { + nsContentUtils::AddScriptRunner(NewRunnableMethod( + "PresShell::MaybeRecreateMobileViewportManager", mPresShell, + &PresShell::MaybeRecreateMobileViewportManager, true)); + } } float nsPresContext::GetDeviceFullZoom() { diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index a5c2b1ded9..7885d6b8db 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -1528,6 +1528,16 @@ void nsRefreshDriver::PostScrollEvent(mozilla::Runnable* aScrollEvent, } } +void nsRefreshDriver::PostScrollEndEvent(mozilla::Runnable* aScrollEndEvent, + bool aDelayed) { + if (aDelayed) { + mDelayedScrollEndEvents.AppendElement(aScrollEndEvent); + } else { + mScrollEndEvents.AppendElement(aScrollEndEvent); + EnsureTimerStarted(); + } +} + void nsRefreshDriver::DispatchScrollEvents() { // Scroll events are one-shot, so after running them we can drop them. // However, dispatching a scroll event can potentially cause more scroll @@ -1539,6 +1549,13 @@ void nsRefreshDriver::DispatchScrollEvents() { } } +void nsRefreshDriver::DispatchScrollEndEvents() { + ScrollEventArray events = std::move(mScrollEndEvents); + for (auto& event : events) { + event->Run(); + } +} + void nsRefreshDriver::PostVisualViewportScrollEvent( VVPScrollEvent* aScrollEvent) { mVisualViewportScrollEvents.AppendElement(aScrollEvent); @@ -1673,6 +1690,9 @@ void nsRefreshDriver::RunDelayedEventsSoon() { mScrollEvents.AppendElements(mDelayedScrollEvents); mDelayedScrollEvents.Clear(); + mScrollEndEvents.AppendElements(mDelayedScrollEvents); + mDelayedScrollEndEvents.Clear(); + mResizeEventFlushObservers.AppendElements(mDelayedResizeEventFlushObservers); mDelayedResizeEventFlushObservers.Clear(); @@ -2008,7 +2028,7 @@ auto nsRefreshDriver::GetReasonsToTick() const -> TickReasons { if (!mVisualViewportResizeEvents.IsEmpty()) { reasons |= TickReasons::eHasVisualViewportResizeEvents; } - if (!mScrollEvents.IsEmpty()) { + if (!mScrollEvents.IsEmpty() || !mScrollEndEvents.IsEmpty()) { reasons |= TickReasons::eHasScrollEvents; } if (!mVisualViewportScrollEvents.IsEmpty()) { @@ -2476,6 +2496,7 @@ bool nsRefreshDriver::TickObserverArray(uint32_t aIdx, TimeStamp aNowTime) { FlushAutoFocusDocuments(); DispatchScrollEvents(); DispatchVisualViewportScrollEvents(); + DispatchScrollEndEvents(); EvaluateMediaQueriesAndReportChanges(); DispatchAnimationEvents(); RunFullscreenSteps(); diff --git a/layout/base/nsRefreshDriver.h b/layout/base/nsRefreshDriver.h index cd050f7431..7bd0f883f4 100644 --- a/layout/base/nsRefreshDriver.h +++ b/layout/base/nsRefreshDriver.h @@ -114,7 +114,10 @@ class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator, void DispatchVisualViewportResizeEvents(); void PostScrollEvent(mozilla::Runnable* aScrollEvent, bool aDelayed = false); + void PostScrollEndEvent(mozilla::Runnable* aScrollEndEvent, + bool aDelayed = false); void DispatchScrollEvents(); + void DispatchScrollEndEvents(); void PostVisualViewportScrollEvent(VVPScrollEvent* aScrollEvent); void DispatchVisualViewportScrollEvents(); @@ -694,10 +697,12 @@ class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator, AutoTArray, 16> mEarlyRunners; VisualViewportResizeEventArray mVisualViewportResizeEvents; ScrollEventArray mScrollEvents; + ScrollEventArray mScrollEndEvents; VisualViewportScrollEventArray mVisualViewportScrollEvents; // Scroll events on documents that might have events suppressed. ScrollEventArray mDelayedScrollEvents; + ScrollEventArray mDelayedScrollEndEvents; AutoTArray mResizeEventFlushObservers; AutoTArray mDelayedResizeEventFlushObservers; diff --git a/layout/base/tests/chrome/chrome.toml b/layout/base/tests/chrome/chrome.toml index 6636b224e6..63e3da9609 100644 --- a/layout/base/tests/chrome/chrome.toml +++ b/layout/base/tests/chrome/chrome.toml @@ -66,6 +66,12 @@ support-files = [ "printpreview_pps16_ref.html", "printpreview_prettyprint.xml", "printpreview_prettyprint_ref.xhtml", + "printpreview_scale_test_001.html", + "printpreview_scale_test_001_ref.html", + "printpreview_scale_test_002.html", + "printpreview_scale_test_002_ref.html", + "printpreview_scale_test_003.html", + "printpreview_scale_test_003_ref.html", "printpreview_mask.html", "print_page_size1.html", "print_page_size1_ref.html", diff --git a/layout/base/tests/chrome/printpreview_helper.xhtml b/layout/base/tests/chrome/printpreview_helper.xhtml index e40d2e4d5b..119c55d777 100644 --- a/layout/base/tests/chrome/printpreview_helper.xhtml +++ b/layout/base/tests/chrome/printpreview_helper.xhtml @@ -1708,9 +1708,252 @@ async function runTest58() { let test = "printpreview_mixed_page_size_002.html"; // The params are just to give the file unique URLs. await compareFiles(test + "?test", test + "?ref"); + requestAnimationFrame(() => setTimeout(runTest59)); +} + +// Creates a data URL that has a single div of |divSize| em square, on a page +// of size |pageSize| inches square. +// |center| determines if the div should be centered horizontally. +function createScalingTestSource(pageSize, center, name) { + // Styling always used. + let baseStyle = 'background: blue;'; + if (center) { + baseStyle += 'margin: auto;'; + } + const div = '
'; + const style = ''; + // Add the name as a comment, to ensure every test has a unique source even + // if the parameters are identical. + const comment = ''; + return 'data:text/html,' + style + div + comment; +} + +async function runScalingCenteredTest(refPageSize, testPageSize, paperSize, + name, center = true, fuzz = null) { + const printSettings = { + settings: { + paperWidth: paperSize, + paperHeight: paperSize, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + } + }; + let settings = Object.create(fuzz, { + ref: {value: printSettings}, + test: {value: printSettings} + }); + const testSrc = createScalingTestSource(testPageSize, center, name); + const refSrc = createScalingTestSource(refPageSize, center, name); + return compareFiles(testSrc, refSrc, settings); +} + +// Tests that auto-detection and use of page centering. +// Has a smaller page on a larger sheet, where the difference is within the +// tolerance for auto-detection. +async function runTest59() { + await SpecialPowers.pushPrefEnv({ + set: [["print.center_page_on_sheet", 2]] + }); + // See bug 1680838 + const fuzz = navigator.platform.includes("Win") ? + { maxDifferent: 180, maxDifference: 255 } : + null; + await runScalingCenteredTest(10, 9.5, 10, "runTest59", true, fuzz); + await SpecialPowers.popPrefEnv(); + requestAnimationFrame(() => setTimeout(runTest60)); +} + +// Tests that centering won't occur when the pref disables it, using the same +// values as runTest59. +async function runTest60() { + await SpecialPowers.pushPrefEnv({ + set: [["print.center_page_on_sheet", 0]] + }); + // See bug 1680838 + const fuzz = navigator.platform.includes("Win") ? + { maxDifferent: 180, maxDifference: 255 } : + null; + await runScalingCenteredTest(10, 9.5, 10, "runTest60", false, fuzz); + await SpecialPowers.popPrefEnv(); + requestAnimationFrame(() => setTimeout(runTest61)); +} + +// Tests that auto-detection will reject too big a difference for page +// centering. Has a much smaller page on a larger sheet, where the difference +// is outside the threshold for auto-detection. +async function runTest61() { + await SpecialPowers.pushPrefEnv({ + set: [["print.center_page_on_sheet", 2]] + }); + // See bug 1680838 + const fuzz = navigator.platform.includes("Win") ? + { maxDifferent: 450, maxDifference: 255 } : + null; + await runScalingCenteredTest(10, 8.9, 10, "runTest61", false, fuzz); + await SpecialPowers.popPrefEnv(); + requestAnimationFrame(() => setTimeout(runTest62)); +} + +// Tests that we can force page centering with the pref, using the same values +// as runTest61. +async function runTest62() { + await SpecialPowers.pushPrefEnv({ + set: [["print.center_page_on_sheet", 1]] + }); + // See bug 1680838 + const fuzz = navigator.platform.includes("Win") ? + { maxDifferent: 450, maxDifference: 255 } : + null; + await runScalingCenteredTest(10, 8.9, 10, "runTest62", true, fuzz); + await SpecialPowers.popPrefEnv(); + requestAnimationFrame(() => setTimeout(runTest63)); +} + +// Tests that centering will always happen if the pref forces it. +// The sizes used in these files are very large and the scale factor very high +// here to ensure that any errors in the calculation for centering will be +// magnified. +async function runTest63() { + let test = "printpreview_scale_test_001.html"; + let ref = "printpreview_scale_test_001_ref.html"; + + await SpecialPowers.pushPrefEnv({ + set: [["print.center_page_on_sheet", 1]] + }); + await compareFiles(test, ref, { + test: { + settings: { + paperWidth: 8.5, + paperHeight: 11, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + ref: { + settings: { + paperWidth: 8.5, + paperHeight: 11, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + }); + await SpecialPowers.popPrefEnv(); + requestAnimationFrame(() => setTimeout(runTest64)); +} + +// Tests that printing A4 pages on US Letter will be a close enough fit +// that we will automatically center the page. +async function runTest64() { + let test = "printpreview_scale_test_002.html"; + let ref = "printpreview_scale_test_002_ref.html"; + + await SpecialPowers.pushPrefEnv({ + set: [["print.center_page_on_sheet", 2]] + }); + await compareFiles(test, ref, { + test: { + settings: { + paperWidth: 8.5, + paperHeight: 11, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + ref: { + settings: { + paperWidth: 8.5, + paperHeight: 11, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + }); + await SpecialPowers.popPrefEnv(); + requestAnimationFrame(() => setTimeout(runTest65)); +} + +// Tests that auto-detection will reject a large enough difference in width +// when downscaling is used to make the page fit on the paper. +async function runTest65() { + let test = "printpreview_scale_test_003.html"; + let ref = "printpreview_scale_test_003_ref.html"; + + await SpecialPowers.pushPrefEnv({ + set: [["print.center_page_on_sheet", 2]] + }); + await compareFiles(test, ref, { + test: { + settings: { + paperWidth: 8.5, + paperHeight: 11, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + ref: { + settings: { + paperWidth: 8.5, + paperHeight: 11, + paperSizeUnit: Ci.nsIPrintSettings.kPaperSizeInches, + marginTop: 0, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + unwriteableMarginTop: 0, + unwriteableMarginRight: 0, + unwriteableMarginBottom: 0, + unwriteableMarginLeft: 0, + }, + }, + }); + await SpecialPowers.popPrefEnv(); finish(); } + ]]> diff --git a/layout/base/tests/chrome/printpreview_scale_test_001.html b/layout/base/tests/chrome/printpreview_scale_test_001.html new file mode 100644 index 0000000000..e9d3122b6b --- /dev/null +++ b/layout/base/tests/chrome/printpreview_scale_test_001.html @@ -0,0 +1,21 @@ + + + + + +
+ diff --git a/layout/base/tests/chrome/printpreview_scale_test_001_ref.html b/layout/base/tests/chrome/printpreview_scale_test_001_ref.html new file mode 100644 index 0000000000..2ed4571ef1 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_scale_test_001_ref.html @@ -0,0 +1,20 @@ + + + + + +
+ diff --git a/layout/base/tests/chrome/printpreview_scale_test_002.html b/layout/base/tests/chrome/printpreview_scale_test_002.html new file mode 100644 index 0000000000..94c35ab3c3 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_scale_test_002.html @@ -0,0 +1,21 @@ + + + + + +
+ diff --git a/layout/base/tests/chrome/printpreview_scale_test_002_ref.html b/layout/base/tests/chrome/printpreview_scale_test_002_ref.html new file mode 100644 index 0000000000..d73de86fe5 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_scale_test_002_ref.html @@ -0,0 +1,26 @@ + + + + + +
+ diff --git a/layout/base/tests/chrome/printpreview_scale_test_003.html b/layout/base/tests/chrome/printpreview_scale_test_003.html new file mode 100644 index 0000000000..2b1d68ff60 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_scale_test_003.html @@ -0,0 +1,21 @@ + + + + + +
+ diff --git a/layout/base/tests/chrome/printpreview_scale_test_003_ref.html b/layout/base/tests/chrome/printpreview_scale_test_003_ref.html new file mode 100644 index 0000000000..41a3f87889 --- /dev/null +++ b/layout/base/tests/chrome/printpreview_scale_test_003_ref.html @@ -0,0 +1,21 @@ + + + + + +
+ diff --git a/layout/base/tests/chrome/test_bug420499.xhtml b/layout/base/tests/chrome/test_bug420499.xhtml index 22fefd7987..8db69ff6c1 100644 --- a/layout/base/tests/chrome/test_bug420499.xhtml +++ b/layout/base/tests/chrome/test_bug420499.xhtml @@ -84,7 +84,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=420499 function popupMenuShownHandler() { window.removeEventListener("popupshown", popupMenuShownHandler); - ok(!isCaretVisible(), "Caret shouldn't be visible when menu open"); + ok(isCaretVisible(), "Caret shouldn't be visible when menu open"); window.addEventListener("popuphidden", ensureParagraphFocused); $("menu").open = false; } diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp index 1738098ed2..ecc84ad286 100644 --- a/layout/build/nsLayoutStatics.cpp +++ b/layout/build/nsLayoutStatics.cpp @@ -183,9 +183,6 @@ nsresult nsLayoutStatics::Initialize() { nsMathMLOperators::AddRefTable(); -#ifdef DEBUG - nsIFrame::DisplayReflowStartup(); -#endif Attr::Initialize(); PopupBlocker::Initialize(); @@ -320,9 +317,6 @@ void nsLayoutStatics::Shutdown() { HTMLDNSPrefetch::Shutdown(); nsCSSRendering::Shutdown(); StaticPresData::Shutdown(); -#ifdef DEBUG - nsIFrame::DisplayReflowShutdown(); -#endif nsCellMap::Shutdown(); ActiveLayerTracker::Shutdown(); diff --git a/layout/forms/nsCheckboxRadioFrame.cpp b/layout/forms/nsCheckboxRadioFrame.cpp index e2b8541613..4bf15099aa 100644 --- a/layout/forms/nsCheckboxRadioFrame.cpp +++ b/layout/forms/nsCheckboxRadioFrame.cpp @@ -52,18 +52,12 @@ void nsCheckboxRadioFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, /* virtual */ nscoord nsCheckboxRadioFrame::GetMinISize(gfxContext* aRenderingContext) { - nscoord result; - DISPLAY_MIN_INLINE_SIZE(this, result); - result = StyleDisplay()->HasAppearance() ? DefaultSize() : 0; - return result; + return StyleDisplay()->HasAppearance() ? DefaultSize() : 0; } /* virtual */ nscoord nsCheckboxRadioFrame::GetPrefISize(gfxContext* aRenderingContext) { - nscoord result; - DISPLAY_PREF_INLINE_SIZE(this, result); - result = StyleDisplay()->HasAppearance() ? DefaultSize() : 0; - return result; + return StyleDisplay()->HasAppearance() ? DefaultSize() : 0; } /* virtual */ @@ -76,13 +70,9 @@ LogicalSize nsCheckboxRadioFrame::ComputeAutoSize( if (!StyleDisplay()->HasAppearance()) { return size; } - - // Note: this call always set the BSize to NS_UNCONSTRAINEDSIZE. - size = nsAtomicContainerFrame::ComputeAutoSize( + return nsAtomicContainerFrame::ComputeAutoSize( aRC, aWM, aCBSize, aAvailableISize, aMargin, aBorderPadding, aSizeOverrides, aFlags); - size.BSize(aWM) = DefaultSize(); - return size; } Maybe nsCheckboxRadioFrame::GetNaturalBaselineBOffset( @@ -125,7 +115,6 @@ void nsCheckboxRadioFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsCheckboxRadioFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); NS_FRAME_TRACE( NS_FRAME_TRACE_CALLS, @@ -133,10 +122,13 @@ void nsCheckboxRadioFrame::Reflow(nsPresContext* aPresContext, aReflowInput.AvailableWidth(), aReflowInput.AvailableHeight())); const auto wm = aReflowInput.GetWritingMode(); - aDesiredSize.SetSize(wm, aReflowInput.ComputedSizeWithBorderPadding(wm)); - + const auto contentBoxSize = + aReflowInput.ComputedSizeWithBSizeFallback([&] { return DefaultSize(); }); + aDesiredSize.SetSize( + wm, + contentBoxSize + aReflowInput.ComputedLogicalBorderPadding(wm).Size(wm)); if (nsLayoutUtils::FontSizeInflationEnabled(aPresContext)) { - float inflation = nsLayoutUtils::FontSizeInflationFor(this); + const float inflation = nsLayoutUtils::FontSizeInflationFor(this); aDesiredSize.Width() *= inflation; aDesiredSize.Height() *= inflation; } diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 1d4ff15b4f..98486255d0 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -190,14 +190,12 @@ nscoord nsComboboxControlFrame::GetIntrinsicISize(gfxContext* aRenderingContext, nscoord nsComboboxControlFrame::GetMinISize(gfxContext* aRenderingContext) { nscoord minISize; - DISPLAY_MIN_INLINE_SIZE(this, minISize); minISize = GetIntrinsicISize(aRenderingContext, IntrinsicISizeType::MinISize); return minISize; } nscoord nsComboboxControlFrame::GetPrefISize(gfxContext* aRenderingContext) { nscoord prefISize; - DISPLAY_PREF_INLINE_SIZE(this, prefISize); prefISize = GetIntrinsicISize(aRenderingContext, IntrinsicISizeType::PrefISize); return prefISize; diff --git a/layout/forms/nsDateTimeControlFrame.cpp b/layout/forms/nsDateTimeControlFrame.cpp index b19f787dbc..d8cdf5f277 100644 --- a/layout/forms/nsDateTimeControlFrame.cpp +++ b/layout/forms/nsDateTimeControlFrame.cpp @@ -35,33 +35,21 @@ nsDateTimeControlFrame::nsDateTimeControlFrame(ComputedStyle* aStyle, : nsContainerFrame(aStyle, aPresContext, kClassID) {} nscoord nsDateTimeControlFrame::GetMinISize(gfxContext* aRenderingContext) { - nscoord result; - DISPLAY_MIN_INLINE_SIZE(this, result); - nsIFrame* kid = mFrames.FirstChild(); - if (kid) { // display:none? - result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, kid, - IntrinsicISizeType::MinISize); - } else { - result = 0; + if (!kid) { + return 0; } - - return result; + return nsLayoutUtils::IntrinsicForContainer(aRenderingContext, kid, + IntrinsicISizeType::MinISize); } nscoord nsDateTimeControlFrame::GetPrefISize(gfxContext* aRenderingContext) { - nscoord result; - DISPLAY_PREF_INLINE_SIZE(this, result); - nsIFrame* kid = mFrames.FirstChild(); - if (kid) { // display:none? - result = nsLayoutUtils::IntrinsicForContainer( - aRenderingContext, kid, IntrinsicISizeType::PrefISize); - } else { - result = 0; + if (!kid) { + return 0; } - - return result; + return nsLayoutUtils::IntrinsicForContainer(aRenderingContext, kid, + IntrinsicISizeType::PrefISize); } Maybe nsDateTimeControlFrame::GetNaturalBaselineBOffset( @@ -78,7 +66,6 @@ void nsDateTimeControlFrame::Reflow(nsPresContext* aPresContext, MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsDateTimeControlFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); NS_FRAME_TRACE( NS_FRAME_TRACE_CALLS, diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index c96b293e82..2648cb4dd3 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -58,7 +58,7 @@ nsRect nsFieldSetFrame::VisualBorderRectRelativeToSelf() const { auto legendMargin = legend->GetLogicalUsedMargin(wm); nscoord legendStartMargin = legendMargin.BStart(wm); nscoord legendEndMargin = legendMargin.BEnd(wm); - nscoord border = GetUsedBorder().Side(wm.PhysicalSide(eLogicalSideBStart)); + nscoord border = GetUsedBorder().Side(wm.PhysicalSide(LogicalSide::BStart)); // Calculate the offset from the border area block-axis start edge needed to // center-align our border with the legend's border-box (in the block-axis). nscoord off = (legendStartMargin + legendSize / 2) - border / 2; @@ -348,19 +348,11 @@ nscoord nsFieldSetFrame::GetIntrinsicISize(gfxContext* aRenderingContext, } nscoord nsFieldSetFrame::GetMinISize(gfxContext* aRenderingContext) { - nscoord result = 0; - DISPLAY_MIN_INLINE_SIZE(this, result); - - result = GetIntrinsicISize(aRenderingContext, IntrinsicISizeType::MinISize); - return result; + return GetIntrinsicISize(aRenderingContext, IntrinsicISizeType::MinISize); } nscoord nsFieldSetFrame::GetPrefISize(gfxContext* aRenderingContext) { - nscoord result = 0; - DISPLAY_PREF_INLINE_SIZE(this, result); - - result = GetIntrinsicISize(aRenderingContext, IntrinsicISizeType::PrefISize); - return result; + return GetIntrinsicISize(aRenderingContext, IntrinsicISizeType::PrefISize); } /* virtual */ @@ -372,7 +364,6 @@ void nsFieldSetFrame::Reflow(nsPresContext* aPresContext, MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsFieldSetFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); NS_WARNING_ASSERTION(aReflowInput.ComputedISize() != NS_UNCONSTRAINEDSIZE, "Should have a precomputed inline-size!"); diff --git a/layout/forms/nsHTMLButtonControlFrame.cpp b/layout/forms/nsHTMLButtonControlFrame.cpp index cb24ccbfb9..5201e420e2 100644 --- a/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/layout/forms/nsHTMLButtonControlFrame.cpp @@ -51,6 +51,7 @@ void nsHTMLButtonControlFrame::Init(nsIContent* aContent, } NS_QUERYFRAME_HEAD(nsHTMLButtonControlFrame) + NS_QUERYFRAME_ENTRY(nsHTMLButtonControlFrame) NS_QUERYFRAME_ENTRY(nsIFormControlFrame) NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) @@ -238,29 +239,21 @@ void nsHTMLButtonControlFrame::BuildDisplayList( } nscoord nsHTMLButtonControlFrame::GetMinISize(gfxContext* aRenderingContext) { - nscoord result; - DISPLAY_MIN_INLINE_SIZE(this, result); if (Maybe containISize = ContainIntrinsicISize()) { - result = *containISize; - } else { - nsIFrame* kid = mFrames.FirstChild(); - result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, kid, - IntrinsicISizeType::MinISize); + return *containISize; } - return result; + nsIFrame* kid = mFrames.FirstChild(); + return nsLayoutUtils::IntrinsicForContainer(aRenderingContext, kid, + IntrinsicISizeType::MinISize); } nscoord nsHTMLButtonControlFrame::GetPrefISize(gfxContext* aRenderingContext) { - nscoord result; - DISPLAY_PREF_INLINE_SIZE(this, result); if (Maybe containISize = ContainIntrinsicISize()) { - result = *containISize; - } else { - nsIFrame* kid = mFrames.FirstChild(); - result = nsLayoutUtils::IntrinsicForContainer( - aRenderingContext, kid, IntrinsicISizeType::PrefISize); + return *containISize; } - return result; + nsIFrame* kid = mFrames.FirstChild(); + return nsLayoutUtils::IntrinsicForContainer(aRenderingContext, kid, + IntrinsicISizeType::PrefISize); } void nsHTMLButtonControlFrame::Reflow(nsPresContext* aPresContext, @@ -269,7 +262,6 @@ void nsHTMLButtonControlFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsHTMLButtonControlFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); // Reflow the child diff --git a/layout/forms/nsImageControlFrame.cpp b/layout/forms/nsImageControlFrame.cpp index 17e3893a2f..8207a427f1 100644 --- a/layout/forms/nsImageControlFrame.cpp +++ b/layout/forms/nsImageControlFrame.cpp @@ -97,7 +97,6 @@ void nsImageControlFrame::Reflow(nsPresContext* aPresContext, const ReflowInput& aReflowInput, nsReflowStatus& aStatus) { DO_GLOBAL_REFLOW_COUNT("nsImageControlFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); return nsImageFrame::Reflow(aPresContext, aDesiredSize, aReflowInput, aStatus); diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index 44ce9fde13..3020e99888 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -230,34 +230,30 @@ nscoord nsListControlFrame::CalcBSizeOfARow() { } nscoord nsListControlFrame::GetPrefISize(gfxContext* aRenderingContext) { - nscoord result; - DISPLAY_PREF_INLINE_SIZE(this, result); - // Always add scrollbar inline sizes to the pref-inline-size of the // scrolled content. Combobox frames depend on this happening in the // dropdown, and standalone listboxes are overflow:scroll so they need // it too. WritingMode wm = GetWritingMode(); Maybe containISize = ContainIntrinsicISize(); - result = containISize ? *containISize - : GetScrolledFrame()->GetPrefISize(aRenderingContext); + nscoord result = containISize + ? *containISize + : GetScrolledFrame()->GetPrefISize(aRenderingContext); LogicalMargin scrollbarSize(wm, GetDesiredScrollbarSizes()); result = NSCoordSaturatingAdd(result, scrollbarSize.IStartEnd(wm)); return result; } nscoord nsListControlFrame::GetMinISize(gfxContext* aRenderingContext) { - nscoord result; - DISPLAY_MIN_INLINE_SIZE(this, result); - // Always add scrollbar inline sizes to the min-inline-size of the // scrolled content. Combobox frames depend on this happening in the // dropdown, and standalone listboxes are overflow:scroll so they need // it too. WritingMode wm = GetWritingMode(); Maybe containISize = ContainIntrinsicISize(); - result = containISize ? *containISize - : GetScrolledFrame()->GetMinISize(aRenderingContext); + nscoord result = containISize + ? *containISize + : GetScrolledFrame()->GetMinISize(aRenderingContext); LogicalMargin scrollbarSize(wm, GetDesiredScrollbarSizes()); result += scrollbarSize.IStartEnd(wm); diff --git a/layout/forms/nsMeterFrame.cpp b/layout/forms/nsMeterFrame.cpp index a72a6816d5..31ef52a000 100644 --- a/layout/forms/nsMeterFrame.cpp +++ b/layout/forms/nsMeterFrame.cpp @@ -82,7 +82,6 @@ void nsMeterFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsMeterFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); NS_ASSERTION(mBarDiv, "Meter bar div must exist!"); @@ -93,13 +92,19 @@ void nsMeterFrame::Reflow(nsPresContext* aPresContext, nsIFrame* barFrame = mBarDiv->GetPrimaryFrame(); NS_ASSERTION(barFrame, "The meter frame should have a child with a frame!"); - ReflowBarFrame(barFrame, aPresContext, aReflowInput, aStatus); - const auto wm = aReflowInput.GetWritingMode(); - aDesiredSize.SetSize(wm, aReflowInput.ComputedSizeWithBorderPadding(wm)); - + const auto contentBoxSize = aReflowInput.ComputedSizeWithBSizeFallback([&] { + nscoord em = OneEmInAppUnits(); + return ResolvedOrientationIsVertical() == wm.IsVertical() ? em : 5 * em; + }); + aDesiredSize.SetSize( + wm, + contentBoxSize + aReflowInput.ComputedLogicalBorderPadding(wm).Size(wm)); aDesiredSize.SetOverflowAreasToDesiredBounds(); + + ReflowBarFrame(barFrame, aPresContext, aReflowInput, contentBoxSize, aStatus); ConsiderChildOverflow(aDesiredSize.mOverflowAreas, barFrame); + FinishAndStoreOverflow(&aDesiredSize); aStatus.Reset(); // This type of frame can't be split. @@ -108,14 +113,19 @@ void nsMeterFrame::Reflow(nsPresContext* aPresContext, void nsMeterFrame::ReflowBarFrame(nsIFrame* aBarFrame, nsPresContext* aPresContext, const ReflowInput& aReflowInput, + const LogicalSize& aParentContentBoxSize, nsReflowStatus& aStatus) { bool vertical = ResolvedOrientationIsVertical(); - WritingMode wm = aBarFrame->GetWritingMode(); - LogicalSize availSize = aReflowInput.ComputedSize(wm); + const WritingMode wm = aBarFrame->GetWritingMode(); + const LogicalSize parentSizeInChildWM = + aParentContentBoxSize.ConvertTo(wm, aReflowInput.GetWritingMode()); + const nsSize parentPhysicalSize = parentSizeInChildWM.GetPhysicalSize(wm); + LogicalSize availSize = parentSizeInChildWM; availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE; - ReflowInput reflowInput(aPresContext, aReflowInput, aBarFrame, availSize); + ReflowInput reflowInput(aPresContext, aReflowInput, aBarFrame, availSize, + Some(parentSizeInChildWM)); nscoord size = - vertical ? aReflowInput.ComputedHeight() : aReflowInput.ComputedWidth(); + vertical ? parentPhysicalSize.Height() : parentPhysicalSize.Width(); nscoord xoffset = aReflowInput.ComputedPhysicalBorderPadding().left; nscoord yoffset = aReflowInput.ComputedPhysicalBorderPadding().top; @@ -123,14 +133,13 @@ void nsMeterFrame::ReflowBarFrame(nsIFrame* aBarFrame, size = NSToCoordRound(size * meterElement->Position()); if (!vertical && wm.IsPhysicalRTL()) { - xoffset += aReflowInput.ComputedWidth() - size; + xoffset += parentPhysicalSize.Width() - size; } // The bar position is *always* constrained. if (vertical) { // We want the bar to begin at the bottom. - yoffset += aReflowInput.ComputedHeight() - size; - + yoffset += parentPhysicalSize.Height() - size; size -= reflowInput.ComputedPhysicalMargin().TopBottom() + reflowInput.ComputedPhysicalBorderPadding().TopBottom(); size = std::max(size, 0); @@ -169,39 +178,12 @@ nsresult nsMeterFrame::AttributeChanged(int32_t aNameSpaceID, return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType); } -LogicalSize nsMeterFrame::ComputeAutoSize( - gfxContext* aRenderingContext, WritingMode aWM, const LogicalSize& aCBSize, - nscoord aAvailableISize, const LogicalSize& aMargin, - const LogicalSize& aBorderPadding, const StyleSizeOverrides& aSizeOverrides, - ComputeSizeFlags aFlags) { - RefPtr fontMet = - nsLayoutUtils::GetFontMetricsForFrame(this, 1.0f); - - const WritingMode wm = GetWritingMode(); - LogicalSize autoSize(wm); - autoSize.BSize(wm) = autoSize.ISize(wm) = - fontMet->Font().size.ToAppUnits(); // 1em - - if (ResolvedOrientationIsVertical() == wm.IsVertical()) { - autoSize.ISize(wm) *= 5; // 5em - } else { - autoSize.BSize(wm) *= 5; // 5em - } - - return autoSize.ConvertTo(aWM, wm); -} - nscoord nsMeterFrame::GetMinISize(gfxContext* aRenderingContext) { - RefPtr fontMet = - nsLayoutUtils::GetFontMetricsForFrame(this, 1.0f); - - nscoord minISize = fontMet->Font().size.ToAppUnits(); // 1em - + nscoord minISize = OneEmInAppUnits(); if (ResolvedOrientationIsVertical() == GetWritingMode().IsVertical()) { // The orientation is inline - minISize *= 5; // 5em + minISize *= 5; } - return minISize; } diff --git a/layout/forms/nsMeterFrame.h b/layout/forms/nsMeterFrame.h index 4aa82c1384..7a15878beb 100644 --- a/layout/forms/nsMeterFrame.h +++ b/layout/forms/nsMeterFrame.h @@ -7,17 +7,15 @@ #ifndef nsMeterFrame_h___ #define nsMeterFrame_h___ -#include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsIAnonymousContentCreator.h" #include "nsCOMPtr.h" -#include "nsCSSPseudoElements.h" class nsMeterFrame final : public nsContainerFrame, public nsIAnonymousContentCreator { - typedef mozilla::dom::Element Element; + using Element = mozilla::dom::Element; public: NS_DECL_QUERYFRAME @@ -27,36 +25,25 @@ class nsMeterFrame final : public nsContainerFrame, virtual ~nsMeterFrame(); void Destroy(DestroyContext&) override; - - virtual void Reflow(nsPresContext* aCX, ReflowOutput& aDesiredSize, - const ReflowInput& aReflowInput, - nsReflowStatus& aStatus) override; + void Reflow(nsPresContext*, ReflowOutput&, const ReflowInput&, + nsReflowStatus&) override; #ifdef DEBUG_FRAME_DUMP - virtual nsresult GetFrameName(nsAString& aResult) const override { + nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(u"Meter"_ns, aResult); } #endif // nsIAnonymousContentCreator - virtual nsresult CreateAnonymousContent( - nsTArray& aElements) override; - virtual void AppendAnonymousContentTo(nsTArray& aElements, - uint32_t aFilter) override; + nsresult CreateAnonymousContent(nsTArray& aElements) override; + void AppendAnonymousContentTo(nsTArray& aElements, + uint32_t aFilter) override; - virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, - int32_t aModType) override; + nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, + int32_t aModType) override; - virtual mozilla::LogicalSize ComputeAutoSize( - gfxContext* aRenderingContext, mozilla::WritingMode aWM, - const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize, - const mozilla::LogicalSize& aMargin, - const mozilla::LogicalSize& aBorderPadding, - const mozilla::StyleSizeOverrides& aSizeOverrides, - mozilla::ComputeSizeFlags aFlags) override; - - virtual nscoord GetMinISize(gfxContext* aRenderingContext) override; - virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override; + nscoord GetMinISize(gfxContext* aRenderingContext) override; + nscoord GetPrefISize(gfxContext* aRenderingContext) override; /** * Returns whether the frame and its child should use the native style. @@ -66,7 +53,9 @@ class nsMeterFrame final : public nsContainerFrame, protected: // Helper function which reflow the anonymous div frame. void ReflowBarFrame(nsIFrame* aBarFrame, nsPresContext* aPresContext, - const ReflowInput& aReflowInput, nsReflowStatus& aStatus); + const ReflowInput& aReflowInput, + const mozilla::LogicalSize& aParentContentBoxSize, + nsReflowStatus& aStatus); /** * The div used to show the meter bar. * @see nsMeterFrame::CreateAnonymousContent diff --git a/layout/forms/nsProgressFrame.cpp b/layout/forms/nsProgressFrame.cpp index 2f0d727473..1cf6bf1447 100644 --- a/layout/forms/nsProgressFrame.cpp +++ b/layout/forms/nsProgressFrame.cpp @@ -86,7 +86,6 @@ void nsProgressFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsProgressFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); NS_ASSERTION(mBarDiv, "Progress bar div must exist!"); @@ -99,11 +98,18 @@ void nsProgressFrame::Reflow(nsPresContext* aPresContext, "need to call RegUnregAccessKey only for the first."); const auto wm = aReflowInput.GetWritingMode(); - aDesiredSize.SetSize(wm, aReflowInput.ComputedSizeWithBorderPadding(wm)); + const auto contentBoxSize = aReflowInput.ComputedSizeWithBSizeFallback([&] { + nscoord em = OneEmInAppUnits(); + return ResolvedOrientationIsVertical() == wm.IsVertical() ? em : 10 * em; + }); + aDesiredSize.SetSize( + wm, + contentBoxSize + aReflowInput.ComputedLogicalBorderPadding(wm).Size(wm)); aDesiredSize.SetOverflowAreasToDesiredBounds(); - for (auto childFrame : PrincipalChildList()) { - ReflowChildFrame(childFrame, aPresContext, aReflowInput, aStatus); + for (nsIFrame* childFrame : PrincipalChildList()) { + ReflowChildFrame(childFrame, aPresContext, aReflowInput, contentBoxSize, + aStatus); ConsiderChildOverflow(aDesiredSize.mOverflowAreas, childFrame); } @@ -115,14 +121,19 @@ void nsProgressFrame::Reflow(nsPresContext* aPresContext, void nsProgressFrame::ReflowChildFrame(nsIFrame* aChild, nsPresContext* aPresContext, const ReflowInput& aReflowInput, + const LogicalSize& aParentContentBoxSize, nsReflowStatus& aStatus) { bool vertical = ResolvedOrientationIsVertical(); - WritingMode wm = aChild->GetWritingMode(); - LogicalSize availSize = aReflowInput.ComputedSize(wm); + const WritingMode wm = aChild->GetWritingMode(); + const LogicalSize parentSizeInChildWM = + aParentContentBoxSize.ConvertTo(wm, aReflowInput.GetWritingMode()); + const nsSize parentPhysicalSize = parentSizeInChildWM.GetPhysicalSize(wm); + LogicalSize availSize = parentSizeInChildWM; availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE; - ReflowInput reflowInput(aPresContext, aReflowInput, aChild, availSize); + ReflowInput reflowInput(aPresContext, aReflowInput, aChild, availSize, + Some(parentSizeInChildWM)); nscoord size = - vertical ? aReflowInput.ComputedHeight() : aReflowInput.ComputedWidth(); + vertical ? parentPhysicalSize.Height() : parentPhysicalSize.Width(); nscoord xoffset = aReflowInput.ComputedPhysicalBorderPadding().left; nscoord yoffset = aReflowInput.ComputedPhysicalBorderPadding().top; @@ -135,7 +146,7 @@ void nsProgressFrame::ReflowChildFrame(nsIFrame* aChild, } if (!vertical && wm.IsPhysicalRTL()) { - xoffset += aReflowInput.ComputedWidth() - size; + xoffset += parentPhysicalSize.Width() - size; } // The bar size is fixed in these cases: @@ -148,8 +159,7 @@ void nsProgressFrame::ReflowChildFrame(nsIFrame* aChild, if (position != -1 || ShouldUseNativeStyle()) { if (vertical) { // We want the bar to begin at the bottom. - yoffset += aReflowInput.ComputedHeight() - size; - + yoffset += parentPhysicalSize.Height() - size; size -= reflowInput.ComputedPhysicalMargin().TopBottom() + reflowInput.ComputedPhysicalBorderPadding().TopBottom(); size = std::max(size, 0); @@ -161,10 +171,12 @@ void nsProgressFrame::ReflowChildFrame(nsIFrame* aChild, reflowInput.SetComputedWidth(size); } } else if (vertical) { - // For vertical progress bars, we need to position the bar specificly when + // For vertical progress bars, we need to position the bar specifically when // the width isn't constrained (position == -1 and !ShouldUseNativeStyle()) - // because aReflowInput.ComputedHeight() - size == 0. - yoffset += aReflowInput.ComputedHeight() - reflowInput.ComputedHeight(); + // because parentPhysiscalSize.Height() - size == 0. + // FIXME(emilio): This assumes that the bar's height is constrained, which + // seems like a wrong assumption? + yoffset += parentPhysicalSize.Height() - reflowInput.ComputedHeight(); } xoffset += reflowInput.ComputedPhysicalMargin().left; @@ -195,38 +207,11 @@ nsresult nsProgressFrame::AttributeChanged(int32_t aNameSpaceID, return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType); } -LogicalSize nsProgressFrame::ComputeAutoSize( - gfxContext* aRenderingContext, WritingMode aWM, const LogicalSize& aCBSize, - nscoord aAvailableISize, const LogicalSize& aMargin, - const LogicalSize& aBorderPadding, const StyleSizeOverrides& aSizeOverrides, - ComputeSizeFlags aFlags) { - const WritingMode wm = GetWritingMode(); - LogicalSize autoSize(wm); - autoSize.BSize(wm) = autoSize.ISize(wm) = - StyleFont() - ->mFont.size.ScaledBy(nsLayoutUtils::FontSizeInflationFor(this)) - .ToAppUnits(); // 1em - - if (ResolvedOrientationIsVertical() == wm.IsVertical()) { - autoSize.ISize(wm) *= 10; // 10em - } else { - autoSize.BSize(wm) *= 10; // 10em - } - - return autoSize.ConvertTo(aWM, wm); -} - nscoord nsProgressFrame::GetMinISize(gfxContext* aRenderingContext) { - RefPtr fontMet = - nsLayoutUtils::GetFontMetricsForFrame(this, 1.0f); - - nscoord minISize = fontMet->Font().size.ToAppUnits(); // 1em - + nscoord minISize = OneEmInAppUnits(); if (ResolvedOrientationIsVertical() == GetWritingMode().IsVertical()) { - // The orientation is inline - minISize *= 10; // 10em + minISize *= 10; } - return minISize; } diff --git a/layout/forms/nsProgressFrame.h b/layout/forms/nsProgressFrame.h index 7d3618ee96..f8917ba4f2 100644 --- a/layout/forms/nsProgressFrame.h +++ b/layout/forms/nsProgressFrame.h @@ -18,8 +18,7 @@ enum class PseudoStyleType : uint8_t; class nsProgressFrame final : public nsContainerFrame, public nsIAnonymousContentCreator { - typedef mozilla::PseudoStyleType PseudoStyleType; - typedef mozilla::dom::Element Element; + using Element = mozilla::dom::Element; public: NS_DECL_QUERYFRAME @@ -30,38 +29,28 @@ class nsProgressFrame final : public nsContainerFrame, void Destroy(DestroyContext&) override; - virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsDisplayListSet& aLists) override; + void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsDisplayListSet& aLists) override; - virtual void Reflow(nsPresContext* aCX, ReflowOutput& aDesiredSize, - const ReflowInput& aReflowInput, - nsReflowStatus& aStatus) override; + void Reflow(nsPresContext*, ReflowOutput&, const ReflowInput&, + nsReflowStatus&) override; #ifdef DEBUG_FRAME_DUMP - virtual nsresult GetFrameName(nsAString& aResult) const override { + nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(u"Progress"_ns, aResult); } #endif // nsIAnonymousContentCreator - virtual nsresult CreateAnonymousContent( - nsTArray& aElements) override; - virtual void AppendAnonymousContentTo(nsTArray& aElements, - uint32_t aFilter) override; + nsresult CreateAnonymousContent(nsTArray& aElements) override; + void AppendAnonymousContentTo(nsTArray& aElements, + uint32_t aFilter) override; - virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, - int32_t aModType) override; + nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, + int32_t aModType) override; - virtual mozilla::LogicalSize ComputeAutoSize( - gfxContext* aRenderingContext, mozilla::WritingMode aWM, - const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize, - const mozilla::LogicalSize& aMargin, - const mozilla::LogicalSize& aBorderPadding, - const mozilla::StyleSizeOverrides& aSizeOverrides, - mozilla::ComputeSizeFlags aFlags) override; - - virtual nscoord GetMinISize(gfxContext* aRenderingContext) override; - virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override; + nscoord GetMinISize(gfxContext* aRenderingContext) override; + nscoord GetPrefISize(gfxContext* aRenderingContext) override; /** * Returns whether the frame and its child should use the native style. @@ -72,6 +61,7 @@ class nsProgressFrame final : public nsContainerFrame, // Helper function to reflow a child frame. void ReflowChildFrame(nsIFrame* aChild, nsPresContext* aPresContext, const ReflowInput& aReflowInput, + const mozilla::LogicalSize& aParentContentBoxSize, nsReflowStatus& aStatus); /** diff --git a/layout/forms/nsRangeFrame.cpp b/layout/forms/nsRangeFrame.cpp index 2cccff715a..3238d0372f 100644 --- a/layout/forms/nsRangeFrame.cpp +++ b/layout/forms/nsRangeFrame.cpp @@ -155,7 +155,6 @@ void nsRangeFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsRangeFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); NS_ASSERTION(mTrackDiv, "::-moz-range-track div must exist!"); @@ -166,35 +165,17 @@ void nsRangeFrame::Reflow(nsPresContext* aPresContext, "need to call RegUnregAccessKey only for the first."); WritingMode wm = aReflowInput.GetWritingMode(); - nscoord computedBSize = aReflowInput.ComputedBSize(); - if (computedBSize == NS_UNCONSTRAINEDSIZE) { - computedBSize = 0; - } - const auto borderPadding = aReflowInput.ComputedLogicalBorderPadding(wm); - LogicalSize finalSize( - wm, aReflowInput.ComputedISize() + borderPadding.IStartEnd(wm), - computedBSize + borderPadding.BStartEnd(wm)); - aDesiredSize.SetSize(wm, finalSize); - - ReflowAnonymousContent(aPresContext, aDesiredSize, aReflowInput); - + const auto contentBoxSize = aReflowInput.ComputedSizeWithBSizeFallback([&] { + return IsInlineOriented() ? AutoCrossSize() + : OneEmInAppUnits() * MAIN_AXIS_EM_SIZE; + }); + aDesiredSize.SetSize( + wm, + contentBoxSize + aReflowInput.ComputedLogicalBorderPadding(wm).Size(wm)); aDesiredSize.SetOverflowAreasToDesiredBounds(); - nsIFrame* trackFrame = mTrackDiv->GetPrimaryFrame(); - if (trackFrame) { - ConsiderChildOverflow(aDesiredSize.mOverflowAreas, trackFrame); - } - - nsIFrame* rangeProgressFrame = mProgressDiv->GetPrimaryFrame(); - if (rangeProgressFrame) { - ConsiderChildOverflow(aDesiredSize.mOverflowAreas, rangeProgressFrame); - } - - nsIFrame* thumbFrame = mThumbDiv->GetPrimaryFrame(); - if (thumbFrame) { - ConsiderChildOverflow(aDesiredSize.mOverflowAreas, thumbFrame); - } - + ReflowAnonymousContent(aPresContext, aDesiredSize, contentBoxSize, + aReflowInput); FinishAndStoreOverflow(&aDesiredSize); MOZ_ASSERT(aStatus.IsEmpty(), "This type of frame can't be split."); @@ -202,111 +183,71 @@ void nsRangeFrame::Reflow(nsPresContext* aPresContext, void nsRangeFrame::ReflowAnonymousContent(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, + const LogicalSize& aContentBoxSize, const ReflowInput& aReflowInput) { + const auto parentWM = aReflowInput.GetWritingMode(); // The width/height of our content box, which is the available width/height - // for our anonymous content: - nscoord rangeFrameContentBoxWidth = aReflowInput.ComputedWidth(); - nscoord rangeFrameContentBoxHeight = aReflowInput.ComputedHeight(); - if (rangeFrameContentBoxHeight == NS_UNCONSTRAINEDSIZE) { - rangeFrameContentBoxHeight = 0; - } - - nsIFrame* trackFrame = mTrackDiv->GetPrimaryFrame(); - - if (trackFrame) { // display:none? - - // Position the track: - // The idea here is that we allow content authors to style the width, - // height, border and padding of the track, but we ignore margin and - // positioning properties and do the positioning ourself to keep the center - // of the track's border box on the center of the nsRangeFrame's content - // box. - - WritingMode wm = trackFrame->GetWritingMode(); - LogicalSize availSize = aReflowInput.ComputedSize(wm); - availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE; - ReflowInput trackReflowInput(aPresContext, aReflowInput, trackFrame, - availSize); - - // Find the x/y position of the track frame such that it will be positioned - // as described above. These coordinates are with respect to the - // nsRangeFrame's border-box. - nscoord trackX = rangeFrameContentBoxWidth / 2; - nscoord trackY = rangeFrameContentBoxHeight / 2; - - // Account for the track's border and padding (we ignore its margin): - trackX -= trackReflowInput.ComputedPhysicalBorderPadding().left + - trackReflowInput.ComputedWidth() / 2; - trackY -= trackReflowInput.ComputedPhysicalBorderPadding().top + - trackReflowInput.ComputedHeight() / 2; - - // Make relative to our border box instead of our content box: - trackX += aReflowInput.ComputedPhysicalBorderPadding().left; - trackY += aReflowInput.ComputedPhysicalBorderPadding().top; - - nsReflowStatus frameStatus; - ReflowOutput trackDesiredSize(aReflowInput); - ReflowChild(trackFrame, aPresContext, trackDesiredSize, trackReflowInput, - trackX, trackY, ReflowChildFlags::Default, frameStatus); - MOZ_ASSERT( - frameStatus.IsFullyComplete(), - "We gave our child unconstrained height, so it should be complete"); - FinishReflowChild(trackFrame, aPresContext, trackDesiredSize, - &trackReflowInput, trackX, trackY, - ReflowChildFlags::Default); - } - - nsIFrame* thumbFrame = mThumbDiv->GetPrimaryFrame(); - - if (thumbFrame) { // display:none? - WritingMode wm = thumbFrame->GetWritingMode(); - LogicalSize availSize = aReflowInput.ComputedSize(wm); - availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE; - ReflowInput thumbReflowInput(aPresContext, aReflowInput, thumbFrame, - availSize); - - // Where we position the thumb depends on its size, so we first reflow - // the thumb at {0,0} to obtain its size, then position it afterwards. - - nsReflowStatus frameStatus; - ReflowOutput thumbDesiredSize(aReflowInput); - ReflowChild(thumbFrame, aPresContext, thumbDesiredSize, thumbReflowInput, 0, - 0, ReflowChildFlags::Default, frameStatus); - MOZ_ASSERT( - frameStatus.IsFullyComplete(), - "We gave our child unconstrained height, so it should be complete"); - FinishReflowChild(thumbFrame, aPresContext, thumbDesiredSize, - &thumbReflowInput, 0, 0, ReflowChildFlags::Default); - DoUpdateThumbPosition(thumbFrame, - nsSize(aDesiredSize.Width(), aDesiredSize.Height())); - } - - nsIFrame* rangeProgressFrame = mProgressDiv->GetPrimaryFrame(); - - if (rangeProgressFrame) { // display:none? - WritingMode wm = rangeProgressFrame->GetWritingMode(); - LogicalSize availSize = aReflowInput.ComputedSize(wm); + // for our anonymous content. + const nsSize rangeFrameContentBoxSize = + aContentBoxSize.GetPhysicalSize(parentWM); + for (auto* div : {mTrackDiv.get(), mThumbDiv.get(), mProgressDiv.get()}) { + nsIFrame* child = div->GetPrimaryFrame(); + if (!child) { + continue; + } + const WritingMode wm = child->GetWritingMode(); + const LogicalSize parentSizeInChildWM = + aContentBoxSize.ConvertTo(wm, parentWM); + LogicalSize availSize = parentSizeInChildWM; availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE; - ReflowInput progressReflowInput(aPresContext, aReflowInput, - rangeProgressFrame, availSize); - - // We first reflow the range-progress frame at {0,0} to obtain its - // unadjusted dimensions, then we adjust it to so that the appropriate edge - // ends at the thumb. + ReflowInput childReflowInput(aPresContext, aReflowInput, child, availSize, + Some(parentSizeInChildWM)); + + const nsPoint pos = [&] { + if (div != mTrackDiv) { + // Where we position the thumb and range-progress depends on its size, + // so we first reflow them at {0,0} to obtain the size, then position + // them afterwards. + return nsPoint(); + } + // Find the x/y position of the track. The idea here is that we allow + // content authors to style the width, height, border and padding of the + // track, but we ignore margin and positioning properties and do the + // positioning ourself to keep the center of the track's border box on the + // center of the nsRangeFrame's content. These coordinates are with + // respect to the nsRangeFrame's border-box. + nscoord trackX = rangeFrameContentBoxSize.Width() / 2; + nscoord trackY = rangeFrameContentBoxSize.Height() / 2; + + // Account for the track's border and padding (we ignore its margin): + // FIXME(emilio): Assumes the track height is constrained, which might not + // be true if authors override it. + trackX -= childReflowInput.ComputedPhysicalBorderPadding().left + + childReflowInput.ComputedWidth() / 2; + trackY -= childReflowInput.ComputedPhysicalBorderPadding().top + + childReflowInput.ComputedHeight() / 2; + + // Make relative to our border box instead of our content box: + trackX += aReflowInput.ComputedPhysicalBorderPadding().left; + trackY += aReflowInput.ComputedPhysicalBorderPadding().top; + return nsPoint(trackX, trackY); + }(); nsReflowStatus frameStatus; - ReflowOutput progressDesiredSize(aReflowInput); - ReflowChild(rangeProgressFrame, aPresContext, progressDesiredSize, - progressReflowInput, 0, 0, ReflowChildFlags::Default, - frameStatus); + ReflowOutput childDesiredSize(aReflowInput); + ReflowChild(child, aPresContext, childDesiredSize, childReflowInput, pos.x, + pos.y, ReflowChildFlags::Default, frameStatus); MOZ_ASSERT( frameStatus.IsFullyComplete(), "We gave our child unconstrained height, so it should be complete"); - FinishReflowChild(rangeProgressFrame, aPresContext, progressDesiredSize, - &progressReflowInput, 0, 0, ReflowChildFlags::Default); - DoUpdateRangeProgressFrame( - rangeProgressFrame, - nsSize(aDesiredSize.Width(), aDesiredSize.Height())); + FinishReflowChild(child, aPresContext, childDesiredSize, &childReflowInput, + pos.x, pos.y, ReflowChildFlags::Default); + if (div == mThumbDiv) { + DoUpdateThumbPosition(child, rangeFrameContentBoxSize); + } else if (div == mProgressDiv) { + DoUpdateRangeProgressFrame(child, rangeFrameContentBoxSize); + } + ConsiderChildOverflow(aDesiredSize.mOverflowAreas, child); } } @@ -388,7 +329,7 @@ Decimal nsRangeFrame::GetValueAtEventPoint(WidgetGUIEvent* aEvent) { ->GetValueAsDecimal(); } - nsRect rangeContentRect = GetContentRectRelativeToSelf(); + const nsRect rangeContentRect = GetContentRectRelativeToSelf(); nsSize thumbSize; if (IsThemed()) { @@ -455,11 +396,12 @@ void nsRangeFrame::UpdateForValueChange() { if (!rangeProgressFrame && !thumbFrame) { return; // diplay:none? } + const nsSize contentBoxSize = GetContentRect().Size(); if (rangeProgressFrame) { - DoUpdateRangeProgressFrame(rangeProgressFrame, GetSize()); + DoUpdateRangeProgressFrame(rangeProgressFrame, contentBoxSize); } if (thumbFrame) { - DoUpdateThumbPosition(thumbFrame, GetSize()); + DoUpdateThumbPosition(thumbFrame, contentBoxSize); } if (IsThemed()) { // We don't know the exact dimensions or location of the thumb when native @@ -539,7 +481,7 @@ mozilla::dom::HTMLInputElement& nsRangeFrame::InputElement() const { } void nsRangeFrame::DoUpdateThumbPosition(nsIFrame* aThumbFrame, - const nsSize& aRangeSize) { + const nsSize& aRangeContentBoxSize) { MOZ_ASSERT(aThumbFrame); // The idea here is that we want to position the thumb so that the center @@ -553,29 +495,26 @@ void nsRangeFrame::DoUpdateThumbPosition(nsIFrame* aThumbFrame, nsMargin borderAndPadding = GetUsedBorderAndPadding(); nsPoint newPosition(borderAndPadding.left, borderAndPadding.top); - nsSize rangeContentBoxSize(aRangeSize); - rangeContentBoxSize.width -= borderAndPadding.LeftRight(); - rangeContentBoxSize.height -= borderAndPadding.TopBottom(); - nsSize thumbSize = aThumbFrame->GetSize(); double fraction = GetValueAsFractionOfRange(); MOZ_ASSERT(fraction >= 0.0 && fraction <= 1.0); if (IsHorizontal()) { - if (thumbSize.width < rangeContentBoxSize.width) { - nscoord traversableDistance = rangeContentBoxSize.width - thumbSize.width; + if (thumbSize.width < aRangeContentBoxSize.width) { + nscoord traversableDistance = + aRangeContentBoxSize.width - thumbSize.width; if (IsRightToLeft()) { newPosition.x += NSToCoordRound((1.0 - fraction) * traversableDistance); } else { newPosition.x += NSToCoordRound(fraction * traversableDistance); } - newPosition.y += (rangeContentBoxSize.height - thumbSize.height) / 2; + newPosition.y += (aRangeContentBoxSize.height - thumbSize.height) / 2; } } else { - if (thumbSize.height < rangeContentBoxSize.height) { + if (thumbSize.height < aRangeContentBoxSize.height) { nscoord traversableDistance = - rangeContentBoxSize.height - thumbSize.height; - newPosition.x += (rangeContentBoxSize.width - thumbSize.width) / 2; + aRangeContentBoxSize.height - thumbSize.height; + newPosition.x += (aRangeContentBoxSize.width - thumbSize.width) / 2; if (IsUpwards()) { newPosition.y += NSToCoordRound((1.0 - fraction) * traversableDistance); } else { @@ -586,9 +525,9 @@ void nsRangeFrame::DoUpdateThumbPosition(nsIFrame* aThumbFrame, aThumbFrame->SetPosition(newPosition); } -void nsRangeFrame::DoUpdateRangeProgressFrame(nsIFrame* aRangeProgressFrame, - const nsSize& aRangeSize) { - MOZ_ASSERT(aRangeProgressFrame); +void nsRangeFrame::DoUpdateRangeProgressFrame( + nsIFrame* aProgressFrame, const nsSize& aRangeContentBoxSize) { + MOZ_ASSERT(aProgressFrame); // The idea here is that we want to position the ::-moz-range-progress // pseudo-element so that the center line running along its length is on the @@ -598,35 +537,30 @@ void nsRangeFrame::DoUpdateRangeProgressFrame(nsIFrame* aRangeProgressFrame, // nsRangeFrame's content box, and we size the progress element's border-box // to have a length of GetValueAsFractionOfRange() times the nsRangeFrame's // content-box size. - nsMargin borderAndPadding = GetUsedBorderAndPadding(); - nsSize progSize = aRangeProgressFrame->GetSize(); + nsSize progSize = aProgressFrame->GetSize(); nsRect progRect(borderAndPadding.left, borderAndPadding.top, progSize.width, progSize.height); - nsSize rangeContentBoxSize(aRangeSize); - rangeContentBoxSize.width -= borderAndPadding.LeftRight(); - rangeContentBoxSize.height -= borderAndPadding.TopBottom(); - double fraction = GetValueAsFractionOfRange(); MOZ_ASSERT(fraction >= 0.0 && fraction <= 1.0); if (IsHorizontal()) { - nscoord progLength = NSToCoordRound(fraction * rangeContentBoxSize.width); + nscoord progLength = NSToCoordRound(fraction * aRangeContentBoxSize.width); if (IsRightToLeft()) { - progRect.x += rangeContentBoxSize.width - progLength; + progRect.x += aRangeContentBoxSize.width - progLength; } - progRect.y += (rangeContentBoxSize.height - progSize.height) / 2; + progRect.y += (aRangeContentBoxSize.height - progSize.height) / 2; progRect.width = progLength; } else { - nscoord progLength = NSToCoordRound(fraction * rangeContentBoxSize.height); - progRect.x += (rangeContentBoxSize.width - progSize.width) / 2; + nscoord progLength = NSToCoordRound(fraction * aRangeContentBoxSize.height); + progRect.x += (aRangeContentBoxSize.width - progSize.width) / 2; if (IsUpwards()) { - progRect.y += rangeContentBoxSize.height - progLength; + progRect.y += aRangeContentBoxSize.height - progLength; } progRect.height = progLength; } - aRangeProgressFrame->SetRect(progRect); + aProgressFrame->SetRect(progRect); } nsresult nsRangeFrame::AttributeChanged(int32_t aNameSpaceID, @@ -677,7 +611,7 @@ nsresult nsRangeFrame::AttributeChanged(int32_t aNameSpaceID, return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType); } -nscoord nsRangeFrame::AutoCrossSize(Length aEm) { +nscoord nsRangeFrame::AutoCrossSize() { nscoord minCrossSize(0); if (IsThemed()) { nsPresContext* pc = PresContext(); @@ -686,33 +620,8 @@ nscoord nsRangeFrame::AutoCrossSize(Length aEm) { minCrossSize = pc->DevPixelsToAppUnits(IsHorizontal() ? size.height : size.width); } - return std::max(minCrossSize, aEm.ScaledBy(CROSS_AXIS_EM_SIZE).ToAppUnits()); -} - -static mozilla::Length OneEm(nsRangeFrame* aFrame) { - return aFrame->StyleFont()->mFont.size.ScaledBy( - nsLayoutUtils::FontSizeInflationFor(aFrame)); -} - -LogicalSize nsRangeFrame::ComputeAutoSize( - gfxContext* aRenderingContext, WritingMode aWM, const LogicalSize& aCBSize, - nscoord aAvailableISize, const LogicalSize& aMargin, - const LogicalSize& aBorderPadding, const StyleSizeOverrides& aSizeOverrides, - ComputeSizeFlags aFlags) { - bool isInlineOriented = IsInlineOriented(); - auto em = OneEm(this); - - const WritingMode wm = GetWritingMode(); - LogicalSize autoSize(wm); - if (isInlineOriented) { - autoSize.ISize(wm) = em.ScaledBy(MAIN_AXIS_EM_SIZE).ToAppUnits(); - autoSize.BSize(wm) = AutoCrossSize(em); - } else { - autoSize.ISize(wm) = AutoCrossSize(em); - autoSize.BSize(wm) = em.ScaledBy(MAIN_AXIS_EM_SIZE).ToAppUnits(); - } - - return autoSize.ConvertTo(aWM, wm); + return std::max(minCrossSize, + NSToCoordRound(OneEmInAppUnits() * CROSS_AXIS_EM_SIZE)); } nscoord nsRangeFrame::GetMinISize(gfxContext* aRenderingContext) { @@ -728,11 +637,10 @@ nscoord nsRangeFrame::GetMinISize(gfxContext* aRenderingContext) { } nscoord nsRangeFrame::GetPrefISize(gfxContext* aRenderingContext) { - auto em = OneEm(this); if (IsInlineOriented()) { - return em.ScaledBy(MAIN_AXIS_EM_SIZE).ToAppUnits(); + return OneEmInAppUnits() * MAIN_AXIS_EM_SIZE; } - return AutoCrossSize(em); + return AutoCrossSize(); } bool nsRangeFrame::IsHorizontal() const { diff --git a/layout/forms/nsRangeFrame.h b/layout/forms/nsRangeFrame.h index 4d2073aa50..10d0fc0095 100644 --- a/layout/forms/nsRangeFrame.h +++ b/layout/forms/nsRangeFrame.h @@ -7,12 +7,10 @@ #ifndef nsRangeFrame_h___ #define nsRangeFrame_h___ -#include "mozilla/Attributes.h" #include "mozilla/Decimal.h" #include "mozilla/EventForwards.h" #include "nsContainerFrame.h" #include "nsIAnonymousContentCreator.h" -#include "nsIDOMEventListener.h" #include "nsCOMPtr.h" #include "nsTArray.h" @@ -40,8 +38,7 @@ class nsRangeFrame final : public nsContainerFrame, explicit nsRangeFrame(ComputedStyle* aStyle, nsPresContext* aPresContext); virtual ~nsRangeFrame(); - typedef mozilla::PseudoStyleType PseudoStyleType; - typedef mozilla::dom::Element Element; + using Element = mozilla::dom::Element; public: NS_DECL_QUERYFRAME @@ -53,39 +50,30 @@ class nsRangeFrame final : public nsContainerFrame, void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) override; - virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, - const ReflowInput& aReflowInput, - nsReflowStatus& aStatus) override; + void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, + const ReflowInput& aReflowInput, + nsReflowStatus& aStatus) override; #ifdef DEBUG_FRAME_DUMP - virtual nsresult GetFrameName(nsAString& aResult) const override { + nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(u"Range"_ns, aResult); } #endif #ifdef ACCESSIBILITY - virtual mozilla::a11y::AccType AccessibleType() override; + mozilla::a11y::AccType AccessibleType() override; #endif // nsIAnonymousContentCreator - virtual nsresult CreateAnonymousContent( - nsTArray& aElements) override; - virtual void AppendAnonymousContentTo(nsTArray& aElements, - uint32_t aFilter) override; + nsresult CreateAnonymousContent(nsTArray& aElements) override; + void AppendAnonymousContentTo(nsTArray& aElements, + uint32_t aFilter) override; - virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, - int32_t aModType) override; + nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, + int32_t aModType) override; - mozilla::LogicalSize ComputeAutoSize( - gfxContext* aRenderingContext, mozilla::WritingMode aWM, - const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize, - const mozilla::LogicalSize& aMargin, - const mozilla::LogicalSize& aBorderPadding, - const mozilla::StyleSizeOverrides& aSizeOverrides, - mozilla::ComputeSizeFlags aFlags) override; - - virtual nscoord GetMinISize(gfxContext* aRenderingContext) override; - virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override; + nscoord GetMinISize(gfxContext* aRenderingContext) override; + nscoord GetPrefISize(gfxContext* aRenderingContext) override; /** * Returns true if the slider's thumb moves horizontally, or else false if it @@ -171,17 +159,19 @@ class nsRangeFrame final : public nsContainerFrame, private: // Return our preferred size in the cross-axis (the axis perpendicular // to the direction of movement of the thumb). - nscoord AutoCrossSize(mozilla::Length aEm); + nscoord AutoCrossSize(); // Helper function which reflows the anonymous div frames. void ReflowAnonymousContent(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, + const mozilla::LogicalSize& aContentBoxSize, const ReflowInput& aReflowInput); - void DoUpdateThumbPosition(nsIFrame* aThumbFrame, const nsSize& aRangeSize); + void DoUpdateThumbPosition(nsIFrame* aThumbFrame, + const nsSize& aRangeContentBoxSize); void DoUpdateRangeProgressFrame(nsIFrame* aProgressFrame, - const nsSize& aRangeSize); + const nsSize& aRangeContentBoxSize); /** * The div used to show the ::-moz-range-track pseudo-element. diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index c51b94c56a..32e817be8a 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -173,15 +173,14 @@ void nsTextControlFrame::Destroy(DestroyContext& aContext) { nsContainerFrame::Destroy(aContext); } -LogicalSize nsTextControlFrame::CalcIntrinsicSize( - gfxContext* aRenderingContext, WritingMode aWM, - float aFontSizeInflation) const { +LogicalSize nsTextControlFrame::CalcIntrinsicSize(gfxContext* aRenderingContext, + WritingMode aWM) const { LogicalSize intrinsicSize(aWM); + const float inflation = nsLayoutUtils::FontSizeInflationFor(this); RefPtr fontMet = - nsLayoutUtils::GetFontMetricsForFrame(this, aFontSizeInflation); - const nscoord lineHeight = - ReflowInput::CalcLineHeight(*Style(), PresContext(), GetContent(), - NS_UNCONSTRAINEDSIZE, aFontSizeInflation); + nsLayoutUtils::GetFontMetricsForFrame(this, inflation); + const nscoord lineHeight = ReflowInput::CalcLineHeight( + *Style(), PresContext(), GetContent(), NS_UNCONSTRAINEDSIZE, inflation); // Use the larger of the font's "average" char width or the width of the // zero glyph (if present) as the basis for resolving the size attribute. const nscoord charWidth = @@ -554,58 +553,14 @@ void nsTextControlFrame::AppendAnonymousContentTo( } nscoord nsTextControlFrame::GetPrefISize(gfxContext* aRenderingContext) { - nscoord result = 0; - DISPLAY_PREF_INLINE_SIZE(this, result); - float inflation = nsLayoutUtils::FontSizeInflationFor(this); WritingMode wm = GetWritingMode(); - result = CalcIntrinsicSize(aRenderingContext, wm, inflation).ISize(wm); - return result; + return CalcIntrinsicSize(aRenderingContext, wm).ISize(wm); } nscoord nsTextControlFrame::GetMinISize(gfxContext* aRenderingContext) { - // Our min inline size is just our preferred width if we have auto inline size - nscoord result; - DISPLAY_MIN_INLINE_SIZE(this, result); - result = GetPrefISize(aRenderingContext); - return result; -} - -LogicalSize nsTextControlFrame::ComputeAutoSize( - gfxContext* aRenderingContext, WritingMode aWM, const LogicalSize& aCBSize, - nscoord aAvailableISize, const LogicalSize& aMargin, - const LogicalSize& aBorderPadding, const StyleSizeOverrides& aSizeOverrides, - ComputeSizeFlags aFlags) { - float inflation = nsLayoutUtils::FontSizeInflationFor(this); - LogicalSize autoSize = CalcIntrinsicSize(aRenderingContext, aWM, inflation); - - // Note: nsContainerFrame::ComputeAutoSize only computes the inline-size (and - // only for 'auto'), the block-size it returns is always NS_UNCONSTRAINEDSIZE. - const auto& styleISize = aSizeOverrides.mStyleISize - ? *aSizeOverrides.mStyleISize - : StylePosition()->ISize(aWM); - if (styleISize.IsAuto()) { - if (aFlags.contains(ComputeSizeFlag::IClampMarginBoxMinSize)) { - // CalcIntrinsicSize isn't aware of grid-item margin-box clamping, so we - // fall back to nsContainerFrame's ComputeAutoSize to handle that. - // XXX maybe a font-inflation issue here? (per the assertion below). - autoSize.ISize(aWM) = - nsContainerFrame::ComputeAutoSize( - aRenderingContext, aWM, aCBSize, aAvailableISize, aMargin, - aBorderPadding, aSizeOverrides, aFlags) - .ISize(aWM); - } -#ifdef DEBUG - else { - LogicalSize ancestorAutoSize = nsContainerFrame::ComputeAutoSize( - aRenderingContext, aWM, aCBSize, aAvailableISize, aMargin, - aBorderPadding, aSizeOverrides, aFlags); - MOZ_ASSERT(inflation != 1.0f || - ancestorAutoSize.ISize(aWM) == autoSize.ISize(aWM), - "Incorrect size computed by ComputeAutoSize?"); - } -#endif - } - return autoSize; + // Our min inline size is just our preferred inline-size if we have auto + // inline size. + return GetPrefISize(aRenderingContext); } Maybe nsTextControlFrame::ComputeBaseline( @@ -641,12 +596,16 @@ void nsTextControlFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsTextControlFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); // set values of reflow's out parameters WritingMode wm = aReflowInput.GetWritingMode(); - aDesiredSize.SetSize(wm, aReflowInput.ComputedSizeWithBorderPadding(wm)); + const auto contentBoxSize = aReflowInput.ComputedSizeWithBSizeFallback([&] { + return CalcIntrinsicSize(aReflowInput.mRenderingContext, wm).BSize(wm); + }); + aDesiredSize.SetSize( + wm, + contentBoxSize + aReflowInput.ComputedLogicalBorderPadding(wm).Size(wm)); { // Calculate the baseline and store it in mFirstBaseline. @@ -674,7 +633,7 @@ void nsTextControlFrame::Reflow(nsPresContext* aPresContext, nscoord buttonBoxISize = 0; if (buttonBox) { ReflowTextControlChild(buttonBox, aPresContext, aReflowInput, aStatus, - aDesiredSize, buttonBoxISize); + aDesiredSize, contentBoxSize, buttonBoxISize); } // perform reflow on all kids @@ -684,7 +643,7 @@ void nsTextControlFrame::Reflow(nsPresContext* aPresContext, MOZ_ASSERT(!IsButtonBox(kid), "Should only have one button box, and should be last"); ReflowTextControlChild(kid, aPresContext, aReflowInput, aStatus, - aDesiredSize, buttonBoxISize); + aDesiredSize, contentBoxSize, buttonBoxISize); } kid = kid->GetNextSibling(); } @@ -698,22 +657,28 @@ void nsTextControlFrame::Reflow(nsPresContext* aPresContext, void nsTextControlFrame::ReflowTextControlChild( nsIFrame* aKid, nsPresContext* aPresContext, const ReflowInput& aReflowInput, nsReflowStatus& aStatus, - ReflowOutput& aParentDesiredSize, nscoord& aButtonBoxISize) { + ReflowOutput& aParentDesiredSize, const LogicalSize& aParentContentBoxSize, + nscoord& aButtonBoxISize) { const WritingMode outerWM = aReflowInput.GetWritingMode(); // compute available size and frame offsets for child const WritingMode wm = aKid->GetWritingMode(); - LogicalSize availSize = aReflowInput.ComputedSizeWithPadding(wm); + const auto parentPadding = aReflowInput.ComputedLogicalPadding(wm); + const LogicalSize contentBoxSize = + aParentContentBoxSize.ConvertTo(wm, outerWM); + const LogicalSize paddingBoxSize = contentBoxSize + parentPadding.Size(wm); + const LogicalSize borderBoxSize = + paddingBoxSize + aReflowInput.ComputedLogicalBorder(wm).Size(wm); + LogicalSize availSize = paddingBoxSize; availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE; - bool isButtonBox = IsButtonBox(aKid); + const bool isButtonBox = IsButtonBox(aKid); ReflowInput kidReflowInput(aPresContext, aReflowInput, aKid, availSize, Nothing(), ReflowInput::InitFlag::CallerWillInit); // Override padding with our computed padding in case we got it from theming // or percentage, if we're not the button box. - auto overridePadding = - isButtonBox ? Nothing() : Some(aReflowInput.ComputedLogicalPadding(wm)); + auto overridePadding = isButtonBox ? Nothing() : Some(parentPadding); if (!isButtonBox && aButtonBoxISize) { // Button box respects inline-end-padding, so we don't need to. overridePadding->IEnd(outerWM) = 0; @@ -722,8 +687,7 @@ void nsTextControlFrame::ReflowTextControlChild( // We want to let our button box fill the frame in the block axis, up to the // edge of the control's border. So, we use the control's padding-box as the // containing block size for our button box. - auto overrideCBSize = - isButtonBox ? Some(aReflowInput.ComputedSizeWithPadding(wm)) : Nothing(); + auto overrideCBSize = isButtonBox ? Some(paddingBoxSize) : Nothing(); kidReflowInput.Init(aPresContext, overrideCBSize, Nothing(), overridePadding); LogicalPoint position(wm); @@ -746,14 +710,12 @@ void nsTextControlFrame::ReflowTextControlChild( // the only exception, which has an auto size). kidReflowInput.SetComputedISize( std::max(0, aReflowInput.ComputedISize() - aButtonBoxISize)); - kidReflowInput.SetComputedBSize(aReflowInput.ComputedBSize()); + kidReflowInput.SetComputedBSize(contentBoxSize.BSize(wm)); } // reflow the child ReflowOutput desiredSize(aReflowInput); - const nsSize containerSize = - aReflowInput.ComputedSizeWithBorderPadding(outerWM).GetPhysicalSize( - outerWM); + const nsSize containerSize = borderBoxSize.GetPhysicalSize(wm); ReflowChild(aKid, aPresContext, desiredSize, kidReflowInput, wm, position, containerSize, ReflowChildFlags::Default, aStatus); @@ -767,7 +729,7 @@ void nsTextControlFrame::ReflowTextControlChild( buttonRect.ISize(outerWM) = size.ISize(outerWM); buttonRect.BStart(outerWM) = bp.BStart(outerWM) + - (aReflowInput.ComputedBSize() - size.BSize(outerWM)) / 2; + (aParentContentBoxSize.BSize(outerWM) - size.BSize(outerWM)) / 2; // Align to the inline-end of the content box. buttonRect.IStart(outerWM) = bp.IStart(outerWM) + aReflowInput.ComputedISize() - size.ISize(outerWM); diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index 0d52e5849f..2eb6f18d15 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -63,14 +63,6 @@ class nsTextControlFrame : public nsContainerFrame, nscoord GetMinISize(gfxContext* aRenderingContext) override; nscoord GetPrefISize(gfxContext* aRenderingContext) override; - mozilla::LogicalSize ComputeAutoSize( - gfxContext* aRenderingContext, mozilla::WritingMode aWM, - const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize, - const mozilla::LogicalSize& aMargin, - const mozilla::LogicalSize& aBorderPadding, - const mozilla::StyleSizeOverrides& aSizeOverrides, - mozilla::ComputeSizeFlags aFlags) override; - void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; @@ -180,10 +172,11 @@ class nsTextControlFrame : public nsContainerFrame, /** * Launch the reflow on the child frames - see nsTextControlFrame::Reflow() */ - void ReflowTextControlChild(nsIFrame* aFrame, nsPresContext* aPresContext, + void ReflowTextControlChild(nsIFrame* aKid, nsPresContext* aPresContext, const ReflowInput& aReflowInput, nsReflowStatus& aStatus, ReflowOutput& aParentDesiredSize, + const mozilla::LogicalSize& aParentContentBoxSize, nscoord& aButtonBoxISize); public: @@ -278,8 +271,7 @@ class nsTextControlFrame : public nsContainerFrame, // etc. Just the size of our actual area for the text (and the scrollbars, // for - - - - - - diff --git a/layout/reftests/bugs/385870-1.html b/layout/reftests/bugs/385870-1.html deleted file mode 100644 index 4d292e1c20..0000000000 --- a/layout/reftests/bugs/385870-1.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/layout/reftests/bugs/385870-2-ref.html b/layout/reftests/bugs/385870-2-ref.html deleted file mode 100644 index eebef3805e..0000000000 --- a/layout/reftests/bugs/385870-2-ref.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/layout/reftests/bugs/385870-2.html b/layout/reftests/bugs/385870-2.html deleted file mode 100644 index c641abb796..0000000000 --- a/layout/reftests/bugs/385870-2.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/layout/reftests/bugs/404553-1-ref.html b/layout/reftests/bugs/404553-1-ref.html index cfa0dc8147..ac35a9e4b5 100644 --- a/layout/reftests/bugs/404553-1-ref.html +++ b/layout/reftests/bugs/404553-1-ref.html @@ -1 +1 @@ -
 
\ No newline at end of file +
 
diff --git a/layout/reftests/bugs/404553-1.html b/layout/reftests/bugs/404553-1.html index 692c63c67c..ab63f1396e 100644 --- a/layout/reftests/bugs/404553-1.html +++ b/layout/reftests/bugs/404553-1.html @@ -1 +1 @@ -
Print preview canvas 1Print preview canvas 2
 
\ No newline at end of file +<table><marquee behavior="alternate" scrollamount="0" style="background-color: lime; height: 50px;"><div style="background: green; width: 50px"> </div></marquee><span><title> diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index d85d5e7310..28e96a51da 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -342,8 +342,7 @@ skip-if(useDrawSnapshot) == 306660-2.html 306660-2-ref.html == 306660-3.html 306660-3-ref.html == 307076-1.html 307076-1-ref.html == 307102-1.html 307102-1-ref.html -== 307102-2.html 307102-2-ref.html -== 307102-3.html 307102-3-ref.html +random == 307102-3.html 307102-3-ref.html == 307102-4.html 307102-4-ref.html == 308406-1.html 308406-1-ref.html == 308406-2.html 308406-2-ref.html @@ -725,8 +724,6 @@ fuzzy(0-2,0-5) == 381507-1.html 381507-1-ref.html fuzzy(0-1,0-600) == 385823-2a.html 385823-2-ref.html fails == 385823-2b.html 385823-2-ref.html fuzzy(0-1,0-600) == 385823-2c.html 385823-2-ref.html -fuzzy(0-2,0-11) == 385870-1.html 385870-1-ref.html -fuzzy(0-2,0-3) == 385870-2.html 385870-2-ref.html == 386014-1a.html 386014-1-ref.html == 386014-1b.html 386014-1-ref.html == 386014-1c.html 386014-1-ref.html @@ -2165,3 +2162,4 @@ fuzzy-if(!useDrawSnapshot,18-19,294-322) == 1840747-1.html about:blank # here. That's tracked in bug 1840747. fuzzy-if(!useDrawSnapshot&&!swgl,254-255,110-121) fuzzy-if(useDrawSnapshot,18-18,93-93) fuzzy-if(swgl,19-19,58-58) == 1841355-1.html about:blank skip-if(((AddressSanitizer||ThreadSanitizer)&>kWidget)||(isDebugBuild&&Android)) fuzzy(0-123,0-1425) == 1878294-1.html 1878294-1-ref.html +== 1888941-text-transform-emergency-wrap.html 1888941-text-transform-emergency-wrap-ref.html diff --git a/layout/reftests/counters/counter-hebrew-reference.html b/layout/reftests/counters/counter-hebrew-reference.html index f2c1326056..0d08f6d49b 100644 --- a/layout/reftests/counters/counter-hebrew-reference.html +++ b/layout/reftests/counters/counter-hebrew-reference.html @@ -55,10 +55,7 @@ <span>ט׳</span> <span>ט׳תתקצט</span> <span>תתקצט׳תתקצט</span> - <style> - #c18:before { counter-set: c 18; content: counter(c, hebrew); } - </style> - <span id="c18"></span> + <span>1000000</span> </div> </body> diff --git a/layout/reftests/counters/counters-hebrew-reference.html b/layout/reftests/counters/counters-hebrew-reference.html index 7e725760e8..9ae6b5e011 100644 --- a/layout/reftests/counters/counters-hebrew-reference.html +++ b/layout/reftests/counters/counters-hebrew-reference.html @@ -12,54 +12,51 @@ <p></p> <div> <span>א.א</span> - <span>ב</span> - <span>ג</span> - <span>ד</span> - <span>ה</span> - <span>ו</span> - <span>ז</span> - <span>ח</span> - <span>ט</span> - <span>י</span> - <span>יא</span> - <span>יב</span> - <span>יג</span> - <span>יד</span> - <span>טו</span> - <span>טז</span> - <span>יז</span> - <span>יז.כ</span> - <span>יז.ל</span> - <span>יז.מ</span> - <span>יז.נ</span> - <span>יז.ס</span> - <span>יז.ע</span> - <span>יז.פ</span> - <span>יז.צ</span> - <span>יז.ק</span> - <span>יז.ר</span> - <span>יז.ש</span> - <span>יז.ת</span> - <span>יז.תק</span> - <span>יז.תר</span> - <span>יז.תש</span> - <span>יז.תת</span> - <span>יז.תתק</span> - <span>יז.א׳</span> - <span>יז.ב׳</span> - <span>יז.ג׳</span> - <span>יז.ד׳</span> - <span>יז.ה׳</span> - <span>יז.ו׳</span> - <span>יז.ז׳</span> - <span>יז.ח׳</span> - <span>יז.ט׳</span> - <span>יז.ט׳תתקצט</span> - <span>יז.תתקצט׳תתקצט</span> - <style> - #c18:before { counter-set: c 18; content: counter(c, hebrew); } - </style> - <span id="c18"></span> + <span>א.ב</span> + <span>א.ג</span> + <span>א.ד</span> + <span>א.ה</span> + <span>א.ו</span> + <span>א.ז</span> + <span>א.ח</span> + <span>א.ט</span> + <span>א.י</span> + <span>א.יא</span> + <span>א.יב</span> + <span>א.יג</span> + <span>א.יד</span> + <span>א.טו</span> + <span>א.טז</span> + <span>א.יז</span> + <span>א.כ</span> + <span>א.ל</span> + <span>א.מ</span> + <span>א.נ</span> + <span>א.ס</span> + <span>א.ע</span> + <span>א.פ</span> + <span>א.צ</span> + <span>א.ק</span> + <span>א.ר</span> + <span>א.ש</span> + <span>א.ת</span> + <span>א.תק</span> + <span>א.תר</span> + <span>א.תש</span> + <span>א.תת</span> + <span>א.תתק</span> + <span>א.א׳</span> + <span>א.ב׳</span> + <span>א.ג׳</span> + <span>א.ד׳</span> + <span>א.ה׳</span> + <span>א.ו׳</span> + <span>א.ז׳</span> + <span>א.ח׳</span> + <span>א.ט׳</span> + <span>א.ט׳תתקצט</span> + <span>א.תתקצט׳תתקצט</span> + <span>א.1000000</span> </div> </body> diff --git a/layout/reftests/counters/t1202-counter-06-b-reference.html b/layout/reftests/counters/t1202-counter-06-b-reference.html index 78c9300a8b..0fdc2905e2 100644 --- a/layout/reftests/counters/t1202-counter-06-b-reference.html +++ b/layout/reftests/counters/t1202-counter-06-b-reference.html @@ -24,8 +24,8 @@ <span>11</span> <span>12</span> <span>99</span> - <span>13</span> - <span>14</span> + <span>100</span> + <span>101</span> </div> </body> diff --git a/layout/reftests/counters/t1202-counter-07-b-reference.html b/layout/reftests/counters/t1202-counter-07-b-reference.html index b0da1fa597..f6429c211a 100644 --- a/layout/reftests/counters/t1202-counter-07-b-reference.html +++ b/layout/reftests/counters/t1202-counter-07-b-reference.html @@ -23,12 +23,12 @@ <span>xi</span> <span>xii</span> <span>xlix</span> - <span>xiii</span> + <span>l</span> <span>ccclxxxix</span> - <span>xiv</span> + <span>cccxc</span> <span>mmmcdlxxxix</span> - <span>xv</span> - <span>xvi</span> + <span>mmmcdxc</span> + <span>mmmcdxci</span> </div> </body> diff --git a/layout/reftests/counters/t1202-counter-08-b-reference.html b/layout/reftests/counters/t1202-counter-08-b-reference.html index 40a8bf8d53..16be49dcbc 100644 --- a/layout/reftests/counters/t1202-counter-08-b-reference.html +++ b/layout/reftests/counters/t1202-counter-08-b-reference.html @@ -23,12 +23,12 @@ <span>XI</span> <span>XII</span> <span>XLIX</span> - <span>XIII</span> + <span>L</span> <span>CCCLXXXIX</span> - <span>XIV</span> + <span>CCCXC</span> <span>MMMCDLXXXIX</span> - <span>XV</span> - <span>XVI</span> + <span>MMMCDXC</span> + <span>MMMCDXCI</span> </div> </body> diff --git a/layout/reftests/counters/t1202-counters-06-b-reference.html b/layout/reftests/counters/t1202-counters-06-b-reference.html index 7b3af2409f..b2b5ca1a07 100644 --- a/layout/reftests/counters/t1202-counters-06-b-reference.html +++ b/layout/reftests/counters/t1202-counters-06-b-reference.html @@ -13,20 +13,20 @@ <div> <span>01.01</span> - <span>02</span> - <span>03</span> - <span>04</span> - <span>05</span> - <span>06</span> - <span>07</span> - <span>08</span> - <span>09</span> - <span>10</span> - <span>11</span> - <span>12</span> - <span>12.99</span> - <span>13</span> - <span>14</span> + <span>01.02</span> + <span>01.03</span> + <span>01.04</span> + <span>01.05</span> + <span>01.06</span> + <span>01.07</span> + <span>01.08</span> + <span>01.09</span> + <span>01.10</span> + <span>01.11</span> + <span>01.12</span> + <span>01.99</span> + <span>01.100</span> + <span>01.101</span> </div> </body> diff --git a/layout/reftests/counters/t1202-counters-07-b-reference.html b/layout/reftests/counters/t1202-counters-07-b-reference.html index 49713c7344..ef08cfbefc 100644 --- a/layout/reftests/counters/t1202-counters-07-b-reference.html +++ b/layout/reftests/counters/t1202-counters-07-b-reference.html @@ -13,24 +13,24 @@ <div> <span>i.i</span> - <span>ii</span> - <span>iii</span> - <span>iv</span> - <span>v</span> - <span>vi</span> - <span>vii</span> - <span>viii</span> - <span>ix</span> - <span>x</span> - <span>xi</span> - <span>xii</span> - <span>xii.xlix</span> - <span>xiii</span> - <span>xiii.ccclxxxix</span> - <span>xiv</span> - <span>xiv.mmmcdlxxxix</span> - <span>xv</span> - <span>xvi</span> + <span>i.ii</span> + <span>i.iii</span> + <span>i.iv</span> + <span>i.v</span> + <span>i.vi</span> + <span>i.vii</span> + <span>i.viii</span> + <span>i.ix</span> + <span>i.x</span> + <span>i.xi</span> + <span>i.xii</span> + <span>i.xlix</span> + <span>i.l</span> + <span>i.ccclxxxix</span> + <span>i.cccxc</span> + <span>i.mmmcdlxxxix</span> + <span>i.mmmcdxc</span> + <span>i.mmmcdxci</span> </div> </body> diff --git a/layout/reftests/counters/t1202-counters-08-b-reference.html b/layout/reftests/counters/t1202-counters-08-b-reference.html index 92a6429164..7838d10fbb 100644 --- a/layout/reftests/counters/t1202-counters-08-b-reference.html +++ b/layout/reftests/counters/t1202-counters-08-b-reference.html @@ -13,24 +13,24 @@ <div> <span>I.I</span> - <span>II</span> - <span>III</span> - <span>IV</span> - <span>V</span> - <span>VI</span> - <span>VII</span> - <span>VIII</span> - <span>IX</span> - <span>X</span> - <span>XI</span> - <span>XII</span> - <span>XII.XLIX</span> - <span>XIII</span> - <span>XIII.CCCLXXXIX</span> - <span>XIV</span> - <span>XIV.MMMCDLXXXIX</span> - <span>XV</span> - <span>XVI</span> + <span>I.II</span> + <span>I.III</span> + <span>I.IV</span> + <span>I.V</span> + <span>I.VI</span> + <span>I.VII</span> + <span>I.VIII</span> + <span>I.IX</span> + <span>I.X</span> + <span>I.XI</span> + <span>I.XII</span> + <span>I.XLIX</span> + <span>I.L</span> + <span>I.CCCLXXXIX</span> + <span>I.CCCXC</span> + <span>I.MMMCDLXXXIX</span> + <span>I.MMMCDXC</span> + <span>I.MMMCDXCI</span> </div> </body> diff --git a/layout/reftests/counters/t1202-counters-09-b-reference.html b/layout/reftests/counters/t1202-counters-09-b-reference.html index 928e440ae1..0511df55e4 100644 --- a/layout/reftests/counters/t1202-counters-09-b-reference.html +++ b/layout/reftests/counters/t1202-counters-09-b-reference.html @@ -13,45 +13,45 @@ <div> <span>ა.ა</span> - <span>ბ</span> - <span>გ</span> - <span>დ</span> - <span>ე</span> - <span>ვ</span> - <span>ზ</span> - <span>ჱ</span> - <span>თ</span> - <span>ი</span> - <span>ია</span> - <span>იბ</span> - <span>იბ.კ</span> - <span>იბ.ლ</span> - <span>იბ.მ</span> - <span>იბ.ნ</span> - <span>იბ.ჲ</span> - <span>იბ.ო</span> - <span>იბ.პ</span> - <span>იბ.ჟ</span> - <span>იბ.რ</span> - <span>იბ.ს</span> - <span>იბ.ტ</span> - <span>იბ.ჳ</span> - <span>იბ.ფ</span> - <span>იბ.ქ</span> - <span>იბ.ღ</span> - <span>იბ.ყ</span> - <span>იბ.შ</span> - <span>იბ.ჩ</span> - <span>იბ.ც</span> - <span>იბ.ძ</span> - <span>იბ.წ</span> - <span>იბ.ჭ</span> - <span>იბ.ხ</span> - <span>იბ.ჴ</span> - <span>იბ.ჯ</span> - <span>იბ.ჰ</span> - <span>იბ.ჵ</span> - <span>იბ.ჵჰშჟთ</span> + <span>ა.ბ</span> + <span>ა.გ</span> + <span>ა.დ</span> + <span>ა.ე</span> + <span>ა.ვ</span> + <span>ა.ზ</span> + <span>ა.ჱ</span> + <span>ა.თ</span> + <span>ა.ი</span> + <span>ა.ია</span> + <span>ა.იბ</span> + <span>ა.კ</span> + <span>ა.ლ</span> + <span>ა.მ</span> + <span>ა.ნ</span> + <span>ა.ჲ</span> + <span>ა.ო</span> + <span>ა.პ</span> + <span>ა.ჟ</span> + <span>ა.რ</span> + <span>ა.ს</span> + <span>ა.ტ</span> + <span>ა.ჳ</span> + <span>ა.ფ</span> + <span>ა.ქ</span> + <span>ა.ღ</span> + <span>ა.ყ</span> + <span>ა.შ</span> + <span>ა.ჩ</span> + <span>ა.ც</span> + <span>ა.ძ</span> + <span>ა.წ</span> + <span>ა.ჭ</span> + <span>ა.ხ</span> + <span>ა.ჴ</span> + <span>ა.ჯ</span> + <span>ა.ჰ</span> + <span>ა.ჵ</span> + <span>ა.ჵჰშჟთ</span> </div> </body> diff --git a/layout/reftests/counters/t1202-counters-10-b-reference.html b/layout/reftests/counters/t1202-counters-10-b-reference.html index f3a3fa6dfa..af593dab5c 100644 --- a/layout/reftests/counters/t1202-counters-10-b-reference.html +++ b/layout/reftests/counters/t1202-counters-10-b-reference.html @@ -13,44 +13,44 @@ <div> <span>Ա.Ա</span> - <span>Բ</span> - <span>Գ</span> - <span>Դ</span> - <span>Ե</span> - <span>Զ</span> - <span>Է</span> - <span>Ը</span> - <span>Թ</span> - <span>Ժ</span> - <span>ԺԱ</span> - <span>ԺԲ</span> - <span>ԺԲ.Ի</span> - <span>ԺԲ.Լ</span> - <span>ԺԲ.Խ</span> - <span>ԺԲ.Ծ</span> - <span>ԺԲ.Կ</span> - <span>ԺԲ.Հ</span> - <span>ԺԲ.Ձ</span> - <span>ԺԲ.Ղ</span> - <span>ԺԲ.Ճ</span> - <span>ԺԲ.Մ</span> - <span>ԺԲ.Յ</span> - <span>ԺԲ.Ն</span> - <span>ԺԲ.Շ</span> - <span>ԺԲ.Ո</span> - <span>ԺԲ.Չ</span> - <span>ԺԲ.Պ</span> - <span>ԺԲ.Ջ</span> - <span>ԺԲ.Ռ</span> - <span>ԺԲ.Ս</span> - <span>ԺԲ.Վ</span> - <span>ԺԲ.Տ</span> - <span>ԺԲ.Ր</span> - <span>ԺԲ.Ց</span> - <span>ԺԲ.Ւ</span> - <span>ԺԲ.Փ</span> - <span>ԺԲ.Ք</span> - <span>ԺԲ.ՔՋՂԹ</span> + <span>Ա.Բ</span> + <span>Ա.Գ</span> + <span>Ա.Դ</span> + <span>Ա.Ե</span> + <span>Ա.Զ</span> + <span>Ա.Է</span> + <span>Ա.Ը</span> + <span>Ա.Թ</span> + <span>Ա.Ժ</span> + <span>Ա.ԺԱ</span> + <span>Ա.ԺԲ</span> + <span>Ա.Ի</span> + <span>Ա.Լ</span> + <span>Ա.Խ</span> + <span>Ա.Ծ</span> + <span>Ա.Կ</span> + <span>Ա.Հ</span> + <span>Ա.Ձ</span> + <span>Ա.Ղ</span> + <span>Ա.Ճ</span> + <span>Ա.Մ</span> + <span>Ա.Յ</span> + <span>Ա.Ն</span> + <span>Ա.Շ</span> + <span>Ա.Ո</span> + <span>Ա.Չ</span> + <span>Ա.Պ</span> + <span>Ա.Ջ</span> + <span>Ա.Ռ</span> + <span>Ա.Ս</span> + <span>Ա.Վ</span> + <span>Ա.Տ</span> + <span>Ա.Ր</span> + <span>Ա.Ց</span> + <span>Ա.Ւ</span> + <span>Ա.Փ</span> + <span>Ա.Ք</span> + <span>Ա.ՔՋՂԹ</span> </div> </body> diff --git a/layout/reftests/counters/t1204-reset-00-c-o-reference.html b/layout/reftests/counters/t1204-reset-00-c-o-reference.html index 3be209b7e8..e9afee0b67 100644 --- a/layout/reftests/counters/t1204-reset-00-c-o-reference.html +++ b/layout/reftests/counters/t1204-reset-00-c-o-reference.html @@ -9,7 +9,7 @@ </head> <body> - <div id="reference"><span>1-</span><span>2-</span><span>3-</span></div> + <div id="reference"><span>1-</span><span>1.1-</span><span>1.2-</span></div> </body> </html> diff --git a/layout/reftests/counters/t120401-scope-01-c-reference.html b/layout/reftests/counters/t120401-scope-01-c-reference.html index 021366aaed..c7488ce4b3 100644 --- a/layout/reftests/counters/t120401-scope-01-c-reference.html +++ b/layout/reftests/counters/t120401-scope-01-c-reference.html @@ -10,7 +10,7 @@ <body> - <div><span>B</span><span>1</span><span>-</span><span>B</span><span>2</span><span>-</span><span>B</span><span>2.1</span><span>-</span><span>B</span><span>2.2</span><span>-</span><span>A</span><span>2.3</span><span>-</span><span>B</span><span>2.4</span><span>-</span><span>A</span><span>2.5</span><span>-</span><span>A</span><span>2.6</span><span>-</span><span>B</span><span>3</span><span>-</span><span>B</span><span>4</span><span>-</span><span>A</span><span>5</span><span>-</span><span>A</span><span>6</span><span>-</span><span>A</span><span>7</span><span>-</span><span>A</span><span>8</span><span>-</span></div> + <div><span>B</span><span>1</span><span>-</span><span>B</span><span>2</span><span>-</span><span>B</span><span>2.1</span><span>-</span><span>B</span><span>2.2</span><span>-</span><span>A</span><span>2.3</span><span>-</span><span>B</span><span>2.4</span><span>-</span><span>A</span><span>2.5</span><span>-</span><span>A</span><span>2.6</span><span>-</span><span>B</span><span>2.7</span><span>-</span><span>B</span><span>2.8</span><span>-</span><span>A</span><span>2.9</span><span>-</span><span>A</span><span>2.10</span><span>-</span><span>A</span><span>2.11</span><span>-</span><span>A</span><span>3</span><span>-</span></div> </body> </html> diff --git a/layout/reftests/counters/t120401-scope-02-c-reference.html b/layout/reftests/counters/t120401-scope-02-c-reference.html index 41fc79875a..ff2281a8cf 100644 --- a/layout/reftests/counters/t120401-scope-02-c-reference.html +++ b/layout/reftests/counters/t120401-scope-02-c-reference.html @@ -10,7 +10,7 @@ <body> - <div><span>B</span><span>1</span><span>-</span><span>B</span><span>1.1</span><span>-</span><span>B</span><span>2</span><span>-</span><span>A</span><span>3</span><span>-</span><span>A</span><span>4</span><span>-</span><span>A</span><span>5</span><span>-</span></div> + <div><span>B</span><span>1</span><span>-</span><span>B</span><span>1.1</span><span>-</span><span>B</span><span>1.2</span><span>-</span><span>A</span><span>1.3</span><span>-</span><span>A</span><span>1.4</span><span>-</span><span>A</span><span>2</span><span>-</span></div> </body> </html> diff --git a/layout/reftests/dom/reftest.list b/layout/reftests/dom/reftest.list index 64ac914010..897af84d11 100644 --- a/layout/reftests/dom/reftest.list +++ b/layout/reftests/dom/reftest.list @@ -28,7 +28,7 @@ # a range insert and an append == insertmultiplemultiple-2.html insertmultiplemultiple-ref.html # multiple range inserts and an append -== insertmultiplemultiple-2.html insertmultiplemultiple-ref.html +== insertmultiplemultiple-3.html insertmultiplemultiple-ref.html # testing bindings that have multiple insertion points == multipleinsertionpoints-ref2-shadow.xhtml multipleinsertionpoints-ref.xhtml diff --git a/layout/reftests/flexbox/reftest.list b/layout/reftests/flexbox/reftest.list index dbd6c705cd..b96dbf4fce 100644 --- a/layout/reftests/flexbox/reftest.list +++ b/layout/reftests/flexbox/reftest.list @@ -75,7 +75,6 @@ fuzzy(0-3,0-10) == flexbox-dyn-insertAroundSpan-3.xhtml flexbox-dyn-insertAround == flexbox-position-absolute-2.xhtml flexbox-position-absolute-2-ref.xhtml == flexbox-position-absolute-3.xhtml flexbox-position-absolute-3-ref.xhtml == flexbox-position-absolute-4.xhtml flexbox-position-absolute-4-ref.xhtml -== flexbox-position-fixed-3.xhtml flexbox-position-fixed-3-ref.xhtml fuzzy-if(Android,0-16,0-400) == flexbox-position-fixed-1.xhtml flexbox-position-fixed-1-ref.xhtml fuzzy-if(Android,0-16,0-400) == flexbox-position-fixed-2.xhtml flexbox-position-fixed-2-ref.xhtml == flexbox-position-fixed-3.xhtml flexbox-position-fixed-3-ref.xhtml diff --git a/layout/reftests/forms/input/range/1887539-ref.html b/layout/reftests/forms/input/range/1887539-ref.html new file mode 100644 index 0000000000..b539a1b5c2 --- /dev/null +++ b/layout/reftests/forms/input/range/1887539-ref.html @@ -0,0 +1,30 @@ +<!doctype html> +<style> +#scrubber { + height: 100px; + width: 100%; + appearance: none; + background-color: black; + box-sizing: border-box; + padding: 6px 2px; + margin: 0; + + &::-moz-range-thumb { + border-radius: 14px; + background-color: #BFBFC9; + width: 8px; + height: 8px; + border: 3px solid white; + padding: 0; + } + + &::-moz-range-track { + background-color: #969696; + } + + &::-moz-range-progress { + background-color: white; + } +} +</style> +<input type="range" id="scrubber" value="0.5" min="0" max="1" step=".001"> diff --git a/layout/reftests/forms/input/range/1887539.html b/layout/reftests/forms/input/range/1887539.html new file mode 100644 index 0000000000..9472af203e --- /dev/null +++ b/layout/reftests/forms/input/range/1887539.html @@ -0,0 +1,35 @@ +<!doctype html> +<style> +#scrubber { + height: 100px; + width: 100%; + appearance: none; + background-color: black; + box-sizing: border-box; + padding: 6px 2px; + margin: 0; + + &::-moz-range-thumb { + border-radius: 14px; + background-color: #BFBFC9; + width: 8px; + height: 8px; + border: 3px solid white; + padding: 0; + } + + &::-moz-range-track { + background-color: #969696; + } + + &::-moz-range-progress { + background-color: white; + } +} +</style> +<input type="range" id="scrubber" value="0" min="0" max="1" step=".001"> +<script> +let scrubber = document.getElementById('scrubber'); +scrubber.getBoundingClientRect(); +scrubber.value = 0.5; +</script> diff --git a/layout/reftests/forms/input/range/reftest.list b/layout/reftests/forms/input/range/reftest.list index 181097dc15..f98f345b95 100644 --- a/layout/reftests/forms/input/range/reftest.list +++ b/layout/reftests/forms/input/range/reftest.list @@ -59,3 +59,5 @@ skip-if(Android) == range-border-background.html range-border-background-ref.htm fails-if(Android) fuzzy(0-2,0-80) == auto-size.html auto-size-ref.html # Snapping, bug 1621141 == range-track-bg.html range-track-bg-ref.html != track-default-rendering.html track-default-rendering-ref.html + +== 1887539.html 1887539-ref.html diff --git a/layout/reftests/marquee/336736-1-ref.html b/layout/reftests/marquee/336736-1-ref.html deleted file mode 100644 index 116e5ade28..0000000000 --- a/layout/reftests/marquee/336736-1-ref.html +++ /dev/null @@ -1,5 +0,0 @@ -<html> -<body> -<div style="background: green; width: 50px"> </div> -</body> -</html> diff --git a/layout/reftests/marquee/336736-1a-ref.html b/layout/reftests/marquee/336736-1a-ref.html new file mode 100644 index 0000000000..690992b8a5 --- /dev/null +++ b/layout/reftests/marquee/336736-1a-ref.html @@ -0,0 +1,5 @@ +<html> +<body dir="rtl"> +<div style="background: green; width: 50px"> </div> +</body> +</html> diff --git a/layout/reftests/marquee/336736-1b-ref.html b/layout/reftests/marquee/336736-1b-ref.html new file mode 100644 index 0000000000..116e5ade28 --- /dev/null +++ b/layout/reftests/marquee/336736-1b-ref.html @@ -0,0 +1,5 @@ +<html> +<body> +<div style="background: green; width: 50px"> </div> +</body> +</html> diff --git a/layout/reftests/marquee/reftest.list b/layout/reftests/marquee/reftest.list index ac6772f6c9..c7d2fafd30 100644 --- a/layout/reftests/marquee/reftest.list +++ b/layout/reftests/marquee/reftest.list @@ -1,6 +1,6 @@ == 166591-dynamic-1.html 166591-dynamic-1-ref.html -fuzzy-if(Android,0-8,0-50) == 336736-1a.html 336736-1-ref.html -fuzzy-if(Android,0-8,0-50) == 336736-1b.html 336736-1-ref.html +fuzzy-if(Android,0-8,0-50) == 336736-1a.html 336736-1a-ref.html +fuzzy-if(Android,0-8,0-50) == 336736-1b.html 336736-1b-ref.html == 406073-1.html 406073-1-ref.html == 407016-2.html 407016-2-ref.html fuzzy-if(Android,0-8,0-220) == 413027-4.html 413027-4-ref.html diff --git a/layout/reftests/moz.build b/layout/reftests/moz.build index 14b30d92a3..261ea6db09 100644 --- a/layout/reftests/moz.build +++ b/layout/reftests/moz.build @@ -171,8 +171,6 @@ with Files("native-theme/**"): BUG_COMPONENT = ("Core", "Layout") with Files("object/**"): BUG_COMPONENT = ("Core", "DOM: Core & HTML") -with Files("ogg-video/**"): - BUG_COMPONENT = ("Core", "Audio/Video") with Files("outline/**"): BUG_COMPONENT = ("Core", "Layout") with Files("pagination/**"): diff --git a/layout/reftests/ogg-video/444-1-ref.html b/layout/reftests/ogg-video/444-1-ref.html deleted file mode 100644 index 08e4df28ee..0000000000 --- a/layout/reftests/ogg-video/444-1-ref.html +++ /dev/null @@ -1,20 +0,0 @@ -<!DOCTYPE HTML> -<html class="reftest-wait"> -<body> -<video id="v1" style="position:absolute; left:0; top:0"></video> -<!-- hide bottom of video --> -<div style="position:absolute; top:120px; left:0; right:0; bottom:0; background:black"></div> -<script> -function doTest() { - // Set source now so that the loadeddata event can't fire before - // this function runs. - v1.src = "seek420.ogv"; - v1.play(); - v1.addEventListener("loadeddata", function() { - setTimeout(function() { - document.documentElement.removeAttribute('class'); - }, 50); - }); -} -document.addEventListener("MozReftestInvalidate", doTest); -</script> diff --git a/layout/reftests/ogg-video/444-1.html b/layout/reftests/ogg-video/444-1.html deleted file mode 100644 index 02e7b3ddb8..0000000000 --- a/layout/reftests/ogg-video/444-1.html +++ /dev/null @@ -1,20 +0,0 @@ -<!DOCTYPE HTML> -<html class="reftest-wait"> -<body> -<video id="v1" style="position:absolute; left:0; top:0"></video> -<!-- hide bottom of video --> -<div style="position:absolute; top:120px; left:0; right:0; bottom:0; background:black"></div> -<script> -function doTest() { - // Set source now so that the loadeddata event can't fire before - // this function runs. - v1.src = "seek444.ogv"; - v1.play(); - v1.addEventListener("loadeddata", function() { - setTimeout(function() { - document.documentElement.removeAttribute('class'); - }, 50); - }); -} -document.addEventListener("MozReftestInvalidate", doTest); -</script> diff --git a/layout/reftests/ogg-video/aspect-ratio-1-ref.html b/layout/reftests/ogg-video/aspect-ratio-1-ref.html deleted file mode 100644 index 93391ed83c..0000000000 --- a/layout/reftests/ogg-video/aspect-ratio-1-ref.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<div style="width:140px; height:100px; position:relative; left:100px; top:100px; background:black;"></div> -</body> -</html> diff --git a/layout/reftests/ogg-video/aspect-ratio-1a.xhtml b/layout/reftests/ogg-video/aspect-ratio-1a.xhtml deleted file mode 100644 index c70d3248f5..0000000000 --- a/layout/reftests/ogg-video/aspect-ratio-1a.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<video src="black140x100.ogv" style="width:340px; height:100px; position:relative; top:100px;"></video> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/aspect-ratio-1b.xhtml b/layout/reftests/ogg-video/aspect-ratio-1b.xhtml deleted file mode 100644 index b59352b516..0000000000 --- a/layout/reftests/ogg-video/aspect-ratio-1b.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<video src="black140x100.ogv" style="width:140px; height:300px; position:relative; left:100px;"></video> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/aspect-ratio-2-ref.html b/layout/reftests/ogg-video/aspect-ratio-2-ref.html deleted file mode 100644 index 4f78ab4d2f..0000000000 --- a/layout/reftests/ogg-video/aspect-ratio-2-ref.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<div style="width:280px; height:200px; position:relative; left:200px; top:200px; background:black;"></div> -</body> -</html> diff --git a/layout/reftests/ogg-video/aspect-ratio-2a.xhtml b/layout/reftests/ogg-video/aspect-ratio-2a.xhtml deleted file mode 100644 index f708ec90af..0000000000 --- a/layout/reftests/ogg-video/aspect-ratio-2a.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<video src="black140x100.ogv" style="width:680px; height:200px; position:relative; top:200px;"></video> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/aspect-ratio-2b.xhtml b/layout/reftests/ogg-video/aspect-ratio-2b.xhtml deleted file mode 100644 index e7469031a8..0000000000 --- a/layout/reftests/ogg-video/aspect-ratio-2b.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<video src="black140x100.ogv" style="width:280px; height:600px; position:relative; left:200px;"></video> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/aspect-ratio-3-ref.xhtml b/layout/reftests/ogg-video/aspect-ratio-3-ref.xhtml deleted file mode 100644 index 73662654f8..0000000000 --- a/layout/reftests/ogg-video/aspect-ratio-3-ref.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<video src="black140x100.ogv" style="width:280px; height:200px;"></video> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/aspect-ratio-3a.xhtml b/layout/reftests/ogg-video/aspect-ratio-3a.xhtml deleted file mode 100644 index 3c253e8f81..0000000000 --- a/layout/reftests/ogg-video/aspect-ratio-3a.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<video src="black140x100.ogv" width="280"></video> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/aspect-ratio-3b.xhtml b/layout/reftests/ogg-video/aspect-ratio-3b.xhtml deleted file mode 100644 index cc6ec4c750..0000000000 --- a/layout/reftests/ogg-video/aspect-ratio-3b.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<video src="black140x100.ogv" height="200"></video> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/basic-1-ref.html b/layout/reftests/ogg-video/basic-1-ref.html deleted file mode 100644 index aca3dcb9ca..0000000000 --- a/layout/reftests/ogg-video/basic-1-ref.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<div style="width:140px; height:100px; background:black;"></div> -</body> -</html> diff --git a/layout/reftests/ogg-video/basic-1.xhtml b/layout/reftests/ogg-video/basic-1.xhtml deleted file mode 100644 index 4899dc29f7..0000000000 --- a/layout/reftests/ogg-video/basic-1.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<video src="black140x100.ogv"></video> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/black100x100-aspect3to2.ogv b/layout/reftests/ogg-video/black100x100-aspect3to2.ogv deleted file mode 100644 index 81fe51ffb3..0000000000 Binary files a/layout/reftests/ogg-video/black100x100-aspect3to2.ogv and /dev/null differ diff --git a/layout/reftests/ogg-video/black140x100.ogv b/layout/reftests/ogg-video/black140x100.ogv deleted file mode 100644 index ab146ebe28..0000000000 Binary files a/layout/reftests/ogg-video/black140x100.ogv and /dev/null differ diff --git a/layout/reftests/ogg-video/black29x19offset.ogv b/layout/reftests/ogg-video/black29x19offset.ogv deleted file mode 100644 index b515ebd1f3..0000000000 Binary files a/layout/reftests/ogg-video/black29x19offset.ogv and /dev/null differ diff --git a/layout/reftests/ogg-video/blue140x100.png b/layout/reftests/ogg-video/blue140x100.png deleted file mode 100644 index f4c3973fcc..0000000000 Binary files a/layout/reftests/ogg-video/blue140x100.png and /dev/null differ diff --git a/layout/reftests/ogg-video/blue250x200.png b/layout/reftests/ogg-video/blue250x200.png deleted file mode 100644 index 5eb0b52511..0000000000 Binary files a/layout/reftests/ogg-video/blue250x200.png and /dev/null differ diff --git a/layout/reftests/ogg-video/canvas-1a.xhtml b/layout/reftests/ogg-video/canvas-1a.xhtml deleted file mode 100644 index 9f115e785f..0000000000 --- a/layout/reftests/ogg-video/canvas-1a.xhtml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1" class="reftest-wait"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body> -<canvas id="canvas" width="200" height="200"></canvas> -<script> -var video = document.createElement("video"); -video.src = "black140x100.ogv"; -video.load(); -function draw() { - var canvas = document.getElementById("canvas"); - var ctx = canvas.getContext("2d"); - try { - ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); - } catch (e) { - } - document.documentElement.removeAttribute("class"); -} -video.addEventListener("loadeddata", draw, false); -</script> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/canvas-1b.xhtml b/layout/reftests/ogg-video/canvas-1b.xhtml deleted file mode 100644 index 4524593e9e..0000000000 --- a/layout/reftests/ogg-video/canvas-1b.xhtml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body> -<canvas id="canvas" width="200" height="200"></canvas> -<script> -function draw() { - var video = document.getElementById("video"); - var canvas = document.getElementById("canvas"); - var ctx = canvas.getContext("2d"); - try { - ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); - } catch (e) { - } - document.documentElement.removeAttribute("class"); -} -</script> -<video id="video" src="black140x100.ogv" onloadeddata="draw()" style="opacity:0"></video> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/clipping-1-ref.html b/layout/reftests/ogg-video/clipping-1-ref.html deleted file mode 100644 index 67782811c5..0000000000 --- a/layout/reftests/ogg-video/clipping-1-ref.html +++ /dev/null @@ -1,9 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white"> -<div style="position:absolute; left:0; top:0; width:200px; height:600px;"> - <video src="black140x100.ogv" style="width:400px; margin-left:-100px;"></video> -</div> -<div style="position:absolute; left:200px; top:0; background:white; width:200px; height:600px;"></div> -</body> -</html> diff --git a/layout/reftests/ogg-video/clipping-1a.html b/layout/reftests/ogg-video/clipping-1a.html deleted file mode 100644 index cfae72cedd..0000000000 --- a/layout/reftests/ogg-video/clipping-1a.html +++ /dev/null @@ -1,8 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white"> -<div style="overflow:hidden; position:absolute; left:0; top:0; width:200px; height:600px;"> - <video src="black140x100.ogv" style="width:400px; margin-left:-100px;"></video> -</div> -</body> -</html> diff --git a/layout/reftests/ogg-video/empty-1-ref.html b/layout/reftests/ogg-video/empty-1-ref.html deleted file mode 100644 index fcc7693202..0000000000 --- a/layout/reftests/ogg-video/empty-1-ref.html +++ /dev/null @@ -1,5 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -</body> -</html> diff --git a/layout/reftests/ogg-video/empty-1a.html b/layout/reftests/ogg-video/empty-1a.html deleted file mode 100644 index fc1421a810..0000000000 --- a/layout/reftests/ogg-video/empty-1a.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<video src="black140x100.ogv" style="width:0"></video> -</body> -</html> diff --git a/layout/reftests/ogg-video/empty-1b.html b/layout/reftests/ogg-video/empty-1b.html deleted file mode 100644 index 9dd17dbbaa..0000000000 --- a/layout/reftests/ogg-video/empty-1b.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<video src="black140x100.ogv" style="height:0"></video> -</body> -</html> diff --git a/layout/reftests/ogg-video/encoded-aspect-ratio-1-ref.html b/layout/reftests/ogg-video/encoded-aspect-ratio-1-ref.html deleted file mode 100644 index d9c0054eb5..0000000000 --- a/layout/reftests/ogg-video/encoded-aspect-ratio-1-ref.html +++ /dev/null @@ -1,19 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<div style="background-color: black; width: 150px; height: 100px; position: absolute; left: 10px; top: 10px;"></div> - -<!-- Left side vertical. --> -<div style="position: absolute; left: 9px; top: 9px; width: 2px; height: 102px; z-index: 2; background: red;"></div> - -<!-- Right side vertical. --> -<div style="position: absolute; left: 159px; top: 9px; width: 2px; height: 102px; z-index: 2; background: red;"></div> - -<!-- Top horizontal bar. --> -<div style="position: absolute; left: 9px; top: 9px; width: 152px; height: 2px; z-index: 2; background: red;"></div> - -<!-- Bottom horizontal bar. --> -<div style="position: absolute; left: 9px; top: 109px; width: 152px; height: 2px; z-index: 2; background: red;"></div> - -</body> -</html> diff --git a/layout/reftests/ogg-video/encoded-aspect-ratio-1.html b/layout/reftests/ogg-video/encoded-aspect-ratio-1.html deleted file mode 100644 index 238fdbfe8d..0000000000 --- a/layout/reftests/ogg-video/encoded-aspect-ratio-1.html +++ /dev/null @@ -1,29 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<!-- - Test if video displays correctly with a 3:2 aspect ratio. - It should display at w=150 h=100. - On some Linux systems, the scaling to preserve the aspect ratio can sample - the pixels outside visible region. This results in a thin grey line down - some sides of the scaled picture. We add red bars over the edges to - overwrite such happenings, to make the test reliable. ---> -<video src="black100x100-aspect3to2.ogv" - style="position:absolute; left: 10px; top: 10px; z-index: 1;"> -</video> - -<!-- Left side vertical. --> -<div style="position: absolute; left: 9px; top: 9px; width: 2px; height: 102px; z-index: 2; background: red;"></div> - -<!-- Right side vertical. --> -<div style="position: absolute; left: 159px; top: 9px; width: 2px; height: 102px; z-index: 2; background: red;"></div> - -<!-- Top horizontal bar. --> -<div style="position: absolute; left: 9px; top: 9px; width: 152px; height: 2px; z-index: 2; background: red;"></div> - -<!-- Bottom horizontal bar. --> -<div style="position: absolute; left: 9px; top: 109px; width: 152px; height: 2px; z-index: 2; background: red;"></div> - -</body> -</html> diff --git a/layout/reftests/ogg-video/green70x30.png b/layout/reftests/ogg-video/green70x30.png deleted file mode 100644 index b2bf32762d..0000000000 Binary files a/layout/reftests/ogg-video/green70x30.png and /dev/null differ diff --git a/layout/reftests/ogg-video/object-aspect-ratio-1a.xhtml b/layout/reftests/ogg-video/object-aspect-ratio-1a.xhtml deleted file mode 100644 index 29fd619fd7..0000000000 --- a/layout/reftests/ogg-video/object-aspect-ratio-1a.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<object data="black140x100.ogv" style="width:340px; height:100px; position:relative; top:100px;"></object> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/object-aspect-ratio-1b.xhtml b/layout/reftests/ogg-video/object-aspect-ratio-1b.xhtml deleted file mode 100644 index ea1f02ff74..0000000000 --- a/layout/reftests/ogg-video/object-aspect-ratio-1b.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<object data="black140x100.ogv" style="width:140px; height:300px; position:relative; left:100px;"></object> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/object-aspect-ratio-2a.xhtml b/layout/reftests/ogg-video/object-aspect-ratio-2a.xhtml deleted file mode 100644 index 36b4cc0c1e..0000000000 --- a/layout/reftests/ogg-video/object-aspect-ratio-2a.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<object data="black140x100.ogv" style="width:680px; height:200px; position:relative; top:200px;"></object> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/object-aspect-ratio-2b.xhtml b/layout/reftests/ogg-video/object-aspect-ratio-2b.xhtml deleted file mode 100644 index d557921d2f..0000000000 --- a/layout/reftests/ogg-video/object-aspect-ratio-2b.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<object data="black140x100.ogv" style="width:280px; height:600px; position:relative; left:200px;"></object> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/offset-1-ref.html b/layout/reftests/ogg-video/offset-1-ref.html deleted file mode 100644 index 61a1dc83a7..0000000000 --- a/layout/reftests/ogg-video/offset-1-ref.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<div style="width:29px; height:29px; background:black;"></div> -</body> -</html> diff --git a/layout/reftests/ogg-video/offset-1.xhtml b/layout/reftests/ogg-video/offset-1.xhtml deleted file mode 100644 index 3504734907..0000000000 --- a/layout/reftests/ogg-video/offset-1.xhtml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject filter="url(../filters.svg#ThresholdRGB)" x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white;"> -<video src="black29x19offset.ogv"></video> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/ogg-video/poster-1.html b/layout/reftests/ogg-video/poster-1.html deleted file mode 100644 index 15e3cb5462..0000000000 --- a/layout/reftests/ogg-video/poster-1.html +++ /dev/null @@ -1,7 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<!-- Ensure video element displays at poster size when video's intrinsic size isn't available. --> -<video preload="none" src="black140x100.ogv" poster="blue250x200.png"></video> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-10.html b/layout/reftests/ogg-video/poster-10.html deleted file mode 100644 index 546b96a46f..0000000000 --- a/layout/reftests/ogg-video/poster-10.html +++ /dev/null @@ -1,18 +0,0 @@ -<!DOCTYPE HTML> -<html class="reftest-wait"> -<!-- Test: Create video, add poster, load. Should display poster. --> -<script> -function runTest() { - var v = document.createElement('video'); - v.addEventListener('loadeddata', function(){setTimeout(function(){document.documentElement.className = '';}, 0);}); - v.id = 'v'; - v.src = "black140x100.ogv"; - v.poster = "blue250x200.png"; - v.preload = "auto"; - document.body.appendChild(v); -} - -</script> -<body style="background:white;" onload="runTest();"> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-11.html b/layout/reftests/ogg-video/poster-11.html deleted file mode 100644 index a2f186a4bb..0000000000 --- a/layout/reftests/ogg-video/poster-11.html +++ /dev/null @@ -1,29 +0,0 @@ -<!DOCTYPE HTML> -<html class="reftest-wait"> -<!-- Test: Create video, load. Add poster frame, load again, poster should show. --> -<script> -function runTest() { - var v = document.createElement('video'); - - var endTest = function() { - setTimeout(function(){document.documentElement.className = '';}, 0); - }; - - var addPoster = function() { - v.removeEventListener('loadeddata', addPoster); - v.poster = "blue140x100.png"; - v.addEventListener('loadeddata', endTest); - v.load(); - }; - - v.addEventListener('loadeddata', addPoster); - v.id = 'v'; - v.src = "black140x100.ogv"; - v.preload = "auto"; - document.body.appendChild(v); -} - -</script> -<body style="background:white;" onload="runTest();"> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-12.html b/layout/reftests/ogg-video/poster-12.html deleted file mode 100644 index 49b6dbfebf..0000000000 --- a/layout/reftests/ogg-video/poster-12.html +++ /dev/null @@ -1,38 +0,0 @@ -<!DOCTYPE HTML> -<html class="reftest-wait"> -<!-- Test: Create video, load, play. Add poster frame, load again, poster should show. --> -<script> -function runTest() { - var v = document.createElement('video'); - - var endTest = function() { - setTimeout(function(){document.documentElement.className = '';}, 0); - }; - - var play = - function() { - v.removeEventListener('loadeddata', play); - v.play(); - } - - var addPoster = function() { - v.removeEventListener('playing', addPoster); - v.poster = "blue140x100.png"; - v.addEventListener('loadeddata', endTest); - v.load(); - }; - - v.addEventListener('loadeddata', - play); - v.addEventListener('playing', - addPoster); - v.id = 'v'; - v.src = "black140x100.ogv"; - v.preload = "auto"; - document.body.appendChild(v); -} - -</script> -<body style="background:white;" onload="runTest();"> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-13.html b/layout/reftests/ogg-video/poster-13.html deleted file mode 100644 index 79c3b8c582..0000000000 --- a/layout/reftests/ogg-video/poster-13.html +++ /dev/null @@ -1,8 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<!-- Test that poster is resized, maintaining its aspect ratio. --> -<video src="black140x100.ogv" poster="blue250x200.png" style="width: 288px; height: 216px;"></video> - -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-15.html b/layout/reftests/ogg-video/poster-15.html deleted file mode 100644 index 01c25b660e..0000000000 --- a/layout/reftests/ogg-video/poster-15.html +++ /dev/null @@ -1,13 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- Test that poster is correctly laid out inside borders. Also test that - poster frames smaller than video don't have the video frame drawn behind - them etc. --> -<body style="background:white;"> -<video src="black140x100.ogv" - poster="green70x30.png" - preload="none" - style="border: solid blue 2px;"> -</video> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-2.html b/layout/reftests/ogg-video/poster-2.html deleted file mode 100644 index 28b38f398c..0000000000 --- a/layout/reftests/ogg-video/poster-2.html +++ /dev/null @@ -1,7 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<!-- Test if poster frame with invalid poster displays video frame. --> -<video src="black140x100.ogv" poster="not-a-valid-file"></video> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-3.html b/layout/reftests/ogg-video/poster-3.html deleted file mode 100644 index ae12c1b65d..0000000000 --- a/layout/reftests/ogg-video/poster-3.html +++ /dev/null @@ -1,11 +0,0 @@ -<!DOCTYPE HTML> -<html class="reftest-wait"> -<body style="background:white;"> -<!-- Test if poster hides after playing with autoplay. --> -<video src="black140x100.ogv" - poster="blue250x200.png" - preload="auto" - autoplay - onplaying="setTimeout(function(){document.documentElement.className = '';},0);"></video> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-4.html b/layout/reftests/ogg-video/poster-4.html deleted file mode 100644 index 85453638c8..0000000000 --- a/layout/reftests/ogg-video/poster-4.html +++ /dev/null @@ -1,14 +0,0 @@ -<!DOCTYPE HTML> -<html class="reftest-wait"> -<body style="background:white;" - onload="setTimeout(function(){document.documentElement.className = '';}, 0);"> -<!-- Test if we show video frame after removing valid poster. --> -<video src="black140x100.ogv" - preload="auto" - id="v" - poster="blue250x200.png"></video> -<script type="text/javascript"> - document.getElementById('v').poster = ''; -</script> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-5.html b/layout/reftests/ogg-video/poster-5.html deleted file mode 100644 index 94049c92d7..0000000000 --- a/layout/reftests/ogg-video/poster-5.html +++ /dev/null @@ -1,13 +0,0 @@ -<!DOCTYPE HTML> -<html class="reftest-wait"> -<body style="background:white;"> -<!-- Test to ensure that changing the poster after video has painted its first - frame doesn't render the poster. The video frame should not change to the - poster, since it's already painted its first video frame. --> -<video src="black140x100.ogv" - preload="auto" - id="v" - autoplay - onended="document.getElementById('v').poster = 'blue250x200.png'; setTimeout(function(){document.documentElement.className = '';},0);"></video> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-6.html b/layout/reftests/ogg-video/poster-6.html deleted file mode 100644 index c9ae5b88f5..0000000000 --- a/layout/reftests/ogg-video/poster-6.html +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE HTML> -<html class="reftest-wait"> -<body style="background:white;"> -<!-- Test that poster frame should hide after completing a seek. --> -<video src="black140x100.ogv" - preload="auto" - id="v" - onloadeddata="var v = document.getElementById('v'); v.currentTime = v.duration;" - onseeked="setTimeout(function(){document.documentElement.className = '';}, 0);" - poster="blue250x200.png"></video> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-7.html b/layout/reftests/ogg-video/poster-7.html deleted file mode 100644 index 4c3e002d37..0000000000 --- a/layout/reftests/ogg-video/poster-7.html +++ /dev/null @@ -1,14 +0,0 @@ -<!DOCTYPE HTML> -<html class="reftest-wait"> -<body style="background:white;" - onload="setTimeout(function(){document.documentElement.className = '';}, 0);"> -<!-- Test that poster frame changes when you change the poster attribute. --> -<video src="black140x100.ogv" - preload="none" - id="v" - poster="blue250x200.png"></video> -<script type="text/javascript"> - document.getElementById('v').poster = 'red140x100.png'; -</script> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-8.html b/layout/reftests/ogg-video/poster-8.html deleted file mode 100644 index c9e1fa37a0..0000000000 --- a/layout/reftests/ogg-video/poster-8.html +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE HTML> -<html class="reftest-wait"> -<body style="background:white;"> -<!-- Test if poster hides after playing with play() call. --> -<video src="black140x100.ogv" - poster="blue250x200.png" - id="v" - preload="auto" - onloadeddata="document.getElementById('v').play();" - onplaying="setTimeout(function(){document.documentElement.className = '';}, 0);"></video> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-ref-black140x100.html b/layout/reftests/ogg-video/poster-ref-black140x100.html deleted file mode 100644 index 98f1a4cba7..0000000000 --- a/layout/reftests/ogg-video/poster-ref-black140x100.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<video src="black140x100.ogv" preload="auto"></video> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-ref-blue125x100.html b/layout/reftests/ogg-video/poster-ref-blue125x100.html deleted file mode 100644 index 90795ae911..0000000000 --- a/layout/reftests/ogg-video/poster-ref-blue125x100.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<img src="blue140x100.png" alt="poster" style="position: absolute; height: 100px; width: 125px; left: 16px"> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-ref-blue140x100.html b/layout/reftests/ogg-video/poster-ref-blue140x100.html deleted file mode 100644 index 66540b8e85..0000000000 --- a/layout/reftests/ogg-video/poster-ref-blue140x100.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<img src="blue140x100.png" alt="poster"> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-ref-blue250x200.html b/layout/reftests/ogg-video/poster-ref-blue250x200.html deleted file mode 100644 index 050d53dfb3..0000000000 --- a/layout/reftests/ogg-video/poster-ref-blue250x200.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<img src="blue250x200.png" alt="poster"> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-ref-blue400x300.html b/layout/reftests/ogg-video/poster-ref-blue400x300.html deleted file mode 100644 index 8c32ff715d..0000000000 --- a/layout/reftests/ogg-video/poster-ref-blue400x300.html +++ /dev/null @@ -1,8 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<img src="blue250x200.png" style="position: relative; width: 270px; height: 216px; left: 9px;"> -</body> -</html> - - diff --git a/layout/reftests/ogg-video/poster-ref-green70x30.html b/layout/reftests/ogg-video/poster-ref-green70x30.html deleted file mode 100644 index f979220a6a..0000000000 --- a/layout/reftests/ogg-video/poster-ref-green70x30.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<img src="green70x30.png" alt="poster" style="border: solid blue 2px;"> -</body> -</html> diff --git a/layout/reftests/ogg-video/poster-ref-red140x100.html b/layout/reftests/ogg-video/poster-ref-red140x100.html deleted file mode 100644 index 3ac08d29e2..0000000000 --- a/layout/reftests/ogg-video/poster-ref-red140x100.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white;"> -<img src="red140x100.png" alt="poster"> -</body> -</html> diff --git a/layout/reftests/ogg-video/red140x100.png b/layout/reftests/ogg-video/red140x100.png deleted file mode 100644 index 20250771f3..0000000000 Binary files a/layout/reftests/ogg-video/red140x100.png and /dev/null differ diff --git a/layout/reftests/ogg-video/red160x120.png b/layout/reftests/ogg-video/red160x120.png deleted file mode 100644 index 21737a0e8e..0000000000 Binary files a/layout/reftests/ogg-video/red160x120.png and /dev/null differ diff --git a/layout/reftests/ogg-video/reftest.list b/layout/reftests/ogg-video/reftest.list deleted file mode 100644 index 2c9a96f8ee..0000000000 --- a/layout/reftests/ogg-video/reftest.list +++ /dev/null @@ -1,35 +0,0 @@ -# NOTE: bug 1084564 covers "fails"/"skip" annotations for android below: -fuzzy(0-255,0-5000) == 444-1.html 444-1-ref.html -fails-if(Android) == aspect-ratio-1a.xhtml aspect-ratio-1-ref.html -fails-if(Android) == aspect-ratio-1b.xhtml aspect-ratio-1-ref.html -fails-if(Android) skip-if(gtkWidget) == aspect-ratio-2a.xhtml aspect-ratio-2-ref.html -fails-if(Android) skip-if(gtkWidget) == aspect-ratio-2b.xhtml aspect-ratio-2-ref.html -== aspect-ratio-3a.xhtml aspect-ratio-3-ref.xhtml -== aspect-ratio-3b.xhtml aspect-ratio-3-ref.xhtml -fails-if(Android) random == encoded-aspect-ratio-1.html encoded-aspect-ratio-1-ref.html -fails-if(Android) == basic-1.xhtml basic-1-ref.html -== canvas-1a.xhtml basic-1-ref.html -fails-if(Android) == canvas-1b.xhtml basic-1-ref.html -== clipping-1a.html clipping-1-ref.html -== empty-1a.html empty-1-ref.html -== empty-1b.html empty-1-ref.html -#these is skipped because we hang on the htmlparser tests when this is ran -random == object-aspect-ratio-1a.xhtml aspect-ratio-1-ref.html -random == object-aspect-ratio-1b.xhtml aspect-ratio-1-ref.html -== offset-1.xhtml offset-1-ref.html -random == object-aspect-ratio-2a.xhtml aspect-ratio-2-ref.html -random == object-aspect-ratio-2b.xhtml aspect-ratio-2-ref.html -fuzzy-if(winWidget,0-1,0-56000) fuzzy-if(cocoaWidget,0-1,0-56000) == zoomed-1.xhtml zoomed-1-ref.html # bug 778995 for fuzzy -== poster-1.html poster-ref-blue250x200.html -== poster-2.html poster-ref-black140x100.html -== poster-3.html poster-ref-black140x100.html -== poster-4.html poster-ref-black140x100.html -== poster-5.html poster-ref-black140x100.html -== poster-6.html poster-ref-black140x100.html -== poster-7.html poster-ref-red140x100.html -== poster-8.html poster-ref-black140x100.html -random == poster-10.html poster-ref-blue125x100.html -random == poster-11.html poster-ref-blue140x100.html -random == poster-12.html poster-ref-blue140x100.html -== poster-13.html poster-ref-blue400x300.html -== poster-15.html poster-ref-green70x30.html diff --git a/layout/reftests/ogg-video/seek420.ogv b/layout/reftests/ogg-video/seek420.ogv deleted file mode 100644 index 2221cfef42..0000000000 Binary files a/layout/reftests/ogg-video/seek420.ogv and /dev/null differ diff --git a/layout/reftests/ogg-video/seek444.ogv b/layout/reftests/ogg-video/seek444.ogv deleted file mode 100644 index a2453afeae..0000000000 Binary files a/layout/reftests/ogg-video/seek444.ogv and /dev/null differ diff --git a/layout/reftests/ogg-video/zoomed-1-ref.html b/layout/reftests/ogg-video/zoomed-1-ref.html deleted file mode 100644 index 01929db7e7..0000000000 --- a/layout/reftests/ogg-video/zoomed-1-ref.html +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE HTML> -<html> -<body style="background:white; margin:0;"> -<div style="width:280px; height:200px; background:#010101;"></div> -</body> -</html> diff --git a/layout/reftests/ogg-video/zoomed-1.xhtml b/layout/reftests/ogg-video/zoomed-1.xhtml deleted file mode 100644 index e68e1290f4..0000000000 --- a/layout/reftests/ogg-video/zoomed-1.xhtml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.1" reftest-zoom="2" - width="50%" height="50%"> -<!-- use an empty g to force filters.svg to load before onload --> -<use xlink:href="../filters.svg#empty" /> -<foreignObject x="0" y="0" height="100%" width="100%"> -<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> -<body style="background:white; margin:0"> -<video src="black140x100.ogv"></video> -</body> -</html> -</foreignObject> -</svg> diff --git a/layout/reftests/reftest.list b/layout/reftests/reftest.list index 9587c70798..97f04542ff 100644 --- a/layout/reftests/reftest.list +++ b/layout/reftests/reftest.list @@ -273,9 +273,6 @@ include outline/reftest.list # object/ include object/reftest.list -# ogg-video/ -skip include ogg-video/reftest.list - # webm-video/ skip include webm-video/reftest.list diff --git a/layout/reftests/transform-3d/reftest.list b/layout/reftests/transform-3d/reftest.list index affea05d0b..1f865ac3a7 100644 --- a/layout/reftests/transform-3d/reftest.list +++ b/layout/reftests/transform-3d/reftest.list @@ -10,7 +10,6 @@ fuzzy(0-1,0-6) == rotatey-1a.html rotatey-1-ref.html # perspective should only apply to child elements == rotatex-perspective-1c.html rotatex-1-ref.html == rotatex-perspective-3a.html rotatex-perspective-3-ref.html -== scalez-1a.html scalez-1-ref.html fuzzy(0-16,0-346) fuzzy-if(cocoaWidget,0-200,0-310) fuzzy-if(winWidget,0-175,0-250) == preserve3d-1a.html preserve3d-1-ref.html == preserve3d-1b.html about:blank == preserve3d-clipped.html about:blank diff --git a/layout/style/CSSPageRule.cpp b/layout/style/CSSPageRule.cpp index 04d064b362..fb7dcbc38b 100644 --- a/layout/style/CSSPageRule.cpp +++ b/layout/style/CSSPageRule.cpp @@ -94,20 +94,20 @@ CSSPageRuleDeclaration::GetParsingEnvironment( CSSPageRule::CSSPageRule(RefPtr<StyleLockedPageRule> aRawRule, StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn) - : css::Rule(aSheet, aParentRule, aLine, aColumn), + : css::GroupRule(aSheet, aParentRule, aLine, aColumn), mRawRule(std::move(aRawRule)), mDecls(Servo_PageRule_GetStyle(mRawRule).Consume()) {} -NS_IMPL_ADDREF_INHERITED(CSSPageRule, css::Rule) -NS_IMPL_RELEASE_INHERITED(CSSPageRule, css::Rule) +NS_IMPL_ADDREF_INHERITED(CSSPageRule, css::GroupRule) +NS_IMPL_RELEASE_INHERITED(CSSPageRule, css::GroupRule) // QueryInterface implementation for PageRule NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSPageRule) -NS_INTERFACE_MAP_END_INHERITING(css::Rule) +NS_INTERFACE_MAP_END_INHERITING(css::GroupRule) NS_IMPL_CYCLE_COLLECTION_CLASS(CSSPageRule) -NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSPageRule, css::Rule) +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSPageRule, css::GroupRule) // Keep this in sync with IsCCLeaf. // Trace the wrapper for our declaration. This just expands out @@ -124,14 +124,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSPageRule) // Note that this has to happen before unlinking css::Rule. tmp->UnlinkDeclarationWrapper(tmp->mDecls); tmp->mDecls.mDecls->SetOwningRule(nullptr); -NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(css::Rule) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(css::GroupRule) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSPageRule, css::Rule) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSPageRule, css::GroupRule) // Keep this in sync with IsCCLeaf. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END bool CSSPageRule::IsCCLeaf() const { - if (!Rule::IsCCLeaf()) { + if (!GroupRule::IsCCLeaf()) { return false; } @@ -147,7 +147,7 @@ StyleCssRuleType CSSPageRule::Type() const { return StyleCssRuleType::Page; } size_t CSSPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { // TODO Implement this! - return aMallocSizeOf(this); + return GroupRule::SizeOfExcludingThis(aMallocSizeOf) + aMallocSizeOf(this); } #ifdef DEBUG @@ -188,6 +188,10 @@ void CSSPageRule::SetSelectorText(const nsACString& aSelectorText) { } } +already_AddRefed<StyleLockedCssRules> CSSPageRule::GetOrCreateRawRules() { + return Servo_PageRule_GetRules(mRawRule).Consume(); +} + nsICSSDeclaration* CSSPageRule::Style() { return &mDecls; } JSObject* CSSPageRule::WrapObject(JSContext* aCx, diff --git a/layout/style/CSSPageRule.h b/layout/style/CSSPageRule.h index 705d526bdf..904f94d2c0 100644 --- a/layout/style/CSSPageRule.h +++ b/layout/style/CSSPageRule.h @@ -7,7 +7,7 @@ #ifndef mozilla_dom_CSSPageRule_h #define mozilla_dom_CSSPageRule_h -#include "mozilla/css/Rule.h" +#include "mozilla/css/GroupRule.h" #include "mozilla/ServoBindingTypes.h" #include "nsDOMCSSDeclaration.h" @@ -53,13 +53,14 @@ class CSSPageRuleDeclaration final : public nsDOMCSSDeclaration { RefPtr<DeclarationBlock> mDecls; }; -class CSSPageRule final : public css::Rule { +class CSSPageRule final : public css::GroupRule { public: CSSPageRule(RefPtr<StyleLockedPageRule> aRawRule, StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn); NS_DECL_ISUPPORTS_INHERITED - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(CSSPageRule, css::Rule) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(CSSPageRule, + css::GroupRule) bool IsCCLeaf() const final; @@ -76,6 +77,8 @@ class CSSPageRule final : public css::Rule { size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final; + already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final; + #ifdef DEBUG void List(FILE* out = stdout, int32_t aIndent = 0) const final; #endif diff --git a/layout/style/CSSScopeRule.cpp b/layout/style/CSSScopeRule.cpp new file mode 100644 index 0000000000..18047a582b --- /dev/null +++ b/layout/style/CSSScopeRule.cpp @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/CSSScopeRule.h" +#include "mozilla/dom/CSSScopeRuleBinding.h" +#include "mozilla/ServoBindings.h" + +namespace mozilla::dom { + +CSSScopeRule::CSSScopeRule(RefPtr<StyleScopeRule> aRawRule, StyleSheet* aSheet, + css::Rule* aParentRule, uint32_t aLine, + uint32_t aColumn) + : css::GroupRule(aSheet, aParentRule, aLine, aColumn), + mRawRule(std::move(aRawRule)) {} + +NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSScopeRule, css::GroupRule) + +// QueryInterface implementation for SupportsRule + +#ifdef DEBUG +void CSSScopeRule::List(FILE* out, int32_t aIndent) const { + nsAutoCString str; + for (int32_t i = 0; i < aIndent; i++) { + str.AppendLiteral(" "); + } + Servo_ScopeRule_Debug(mRawRule, &str); + fprintf_stderr(out, "%s\n", str.get()); +} +#endif + +StyleCssRuleType CSSScopeRule::Type() const { return StyleCssRuleType::Scope; } + +already_AddRefed<StyleLockedCssRules> CSSScopeRule::GetOrCreateRawRules() { + return Servo_ScopeRule_GetRules(mRawRule).Consume(); +} + +void CSSScopeRule::SetRawAfterClone(RefPtr<StyleScopeRule> aRaw) { + mRawRule = std::move(aRaw); + css::GroupRule::DidSetRawAfterClone(); +} + +void CSSScopeRule::GetCssText(nsACString& aCssText) const { + Servo_ScopeRule_GetCssText(mRawRule.get(), &aCssText); +} + +void CSSScopeRule::GetStart(nsACString& aStart) const { + Servo_ScopeRule_GetStart(mRawRule.get(), &aStart); +} + +void CSSScopeRule::GetEnd(nsACString& aEnd) const { + Servo_ScopeRule_GetEnd(mRawRule.get(), &aEnd); +} + +size_t CSSScopeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { + return aMallocSizeOf(this); +} + +JSObject* CSSScopeRule::WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) { + return CSSScopeRule_Binding::Wrap(aCx, this, aGivenProto); +} + +} // namespace mozilla::dom diff --git a/layout/style/CSSScopeRule.h b/layout/style/CSSScopeRule.h new file mode 100644 index 0000000000..2cb1fa7e40 --- /dev/null +++ b/layout/style/CSSScopeRule.h @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef CSSScopeRule_h___ +#define CSSScopeRule_h___ + +#include "mozilla/css/GroupRule.h" +#include "mozilla/ServoBindingTypes.h" + +namespace mozilla::dom { + +class CSSScopeRule final : public css::GroupRule { + public: + CSSScopeRule(RefPtr<StyleScopeRule> aRawRule, StyleSheet* aSheet, + css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn); + + NS_DECL_ISUPPORTS_INHERITED + +#ifdef DEBUG + void List(FILE* out = stdout, int32_t aIndent = 0) const final; +#endif + + StyleScopeRule* Raw() const { return mRawRule; } + void SetRawAfterClone(RefPtr<StyleScopeRule>); + + already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final; + + // WebIDL interface + StyleCssRuleType Type() const final; + void GetCssText(nsACString& aCssText) const final; + + void GetStart(nsACString& aStart) const; + void GetEnd(nsACString& aEnd) const; + + size_t SizeOfIncludingThis(MallocSizeOf) const override; + JSObject* WrapObject(JSContext*, JS::Handle<JSObject*>) override; + + private: + ~CSSScopeRule() = default; + + RefPtr<StyleScopeRule> mRawRule; +}; + +} // namespace mozilla::dom + +#endif diff --git a/layout/style/CSSStartingStyleRule.cpp b/layout/style/CSSStartingStyleRule.cpp new file mode 100644 index 0000000000..5c5ec311c9 --- /dev/null +++ b/layout/style/CSSStartingStyleRule.cpp @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/CSSStartingStyleRule.h" +#include "mozilla/dom/CSSStartingStyleRuleBinding.h" +#include "mozilla/ServoBindings.h" + +namespace mozilla::dom { + +NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSStartingStyleRule, + css::GroupRule) + +// QueryInterface implementation for SupportsRule + +#ifdef DEBUG +void CSSStartingStyleRule::List(FILE* out, int32_t aIndent) const { + nsAutoCString str; + for (int32_t i = 0; i < aIndent; i++) { + str.AppendLiteral(" "); + } + Servo_StartingStyleRule_Debug(mRawRule, &str); + fprintf_stderr(out, "%s\n", str.get()); +} +#endif + +StyleCssRuleType CSSStartingStyleRule::Type() const { + return StyleCssRuleType::StartingStyle; +} + +already_AddRefed<StyleLockedCssRules> +CSSStartingStyleRule::GetOrCreateRawRules() { + return Servo_StartingStyleRule_GetRules(mRawRule).Consume(); +} + +void CSSStartingStyleRule::GetCssText(nsACString& aCssText) const { + Servo_StartingStyleRule_GetCssText(mRawRule.get(), &aCssText); +} + +JSObject* CSSStartingStyleRule::WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) { + return CSSStartingStyleRule_Binding::Wrap(aCx, this, aGivenProto); +} + +} // namespace mozilla::dom diff --git a/layout/style/CSSStartingStyleRule.h b/layout/style/CSSStartingStyleRule.h new file mode 100644 index 0000000000..9ecccf505c --- /dev/null +++ b/layout/style/CSSStartingStyleRule.h @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef CSSStaringStyleRule_h___ +#define CSSStaringStyleRule_h___ + +#include "mozilla/css/GroupRule.h" +#include "mozilla/ServoBindingTypes.h" + +namespace mozilla::dom { + +class CSSStartingStyleRule final : public css::GroupRule { + public: + CSSStartingStyleRule(RefPtr<StyleStartingStyleRule> aRawRule, + StyleSheet* aSheet, css::Rule* aParentRule, + uint32_t aLine, uint32_t aColumn) + : css::GroupRule(aSheet, aParentRule, aLine, aColumn), + mRawRule(std::move(aRawRule)) {} + + NS_DECL_ISUPPORTS_INHERITED + +#ifdef DEBUG + void List(FILE* out = stdout, int32_t aIndent = 0) const final; +#endif + + StyleStartingStyleRule* Raw() const { return mRawRule; } + void SetRawAfterClone(RefPtr<StyleStartingStyleRule> aRaw) { + mRawRule = std::move(aRaw); + css::GroupRule::DidSetRawAfterClone(); + } + + already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final; + + // WebIDL interface + StyleCssRuleType Type() const final; + void GetCssText(nsACString& aCssText) const final; + + size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override { + return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); + } + JSObject* WrapObject(JSContext*, JS::Handle<JSObject*>) override; + + private: + ~CSSStartingStyleRule() = default; + + RefPtr<StyleStartingStyleRule> mRawRule; +}; + +} // namespace mozilla::dom + +#endif diff --git a/layout/style/FontFaceImpl.cpp b/layout/style/FontFaceImpl.cpp index 9d1f7c8c5b..5650b62afd 100644 --- a/layout/style/FontFaceImpl.cpp +++ b/layout/style/FontFaceImpl.cpp @@ -675,25 +675,40 @@ bool FontFaceImpl::IsInFontFaceSet(FontFaceSetImpl* aFontFaceSet) const { void FontFaceImpl::AddFontFaceSet(FontFaceSetImpl* aFontFaceSet) { MOZ_ASSERT(!IsInFontFaceSet(aFontFaceSet)); - if (mFontFaceSet == aFontFaceSet) { - mInFontFaceSet = true; + auto doAddFontFaceSet = [&]() { + if (mFontFaceSet == aFontFaceSet) { + mInFontFaceSet = true; + } else { + mOtherFontFaceSets.AppendElement(aFontFaceSet); + } + }; + + if (mUserFontEntry) { + AutoWriteLock lock(mUserFontEntry->Lock()); + doAddFontFaceSet(); } else { - mOtherFontFaceSets.AppendElement(aFontFaceSet); + doAddFontFaceSet(); } } void FontFaceImpl::RemoveFontFaceSet(FontFaceSetImpl* aFontFaceSet) { MOZ_ASSERT(IsInFontFaceSet(aFontFaceSet)); - if (mFontFaceSet == aFontFaceSet) { - mInFontFaceSet = false; - } else { - mOtherFontFaceSets.RemoveElement(aFontFaceSet); - } + auto doRemoveFontFaceSet = [&]() { + if (mFontFaceSet == aFontFaceSet) { + mInFontFaceSet = false; + } else { + mOtherFontFaceSets.RemoveElement(aFontFaceSet); + } + }; - // The caller should be holding a strong reference to the FontFaceSetImpl. if (mUserFontEntry) { - mUserFontEntry->CheckUserFontSet(); + AutoWriteLock lock(mUserFontEntry->Lock()); + doRemoveFontFaceSet(); + // The caller should be holding a strong reference to the FontFaceSetImpl. + mUserFontEntry->CheckUserFontSetLocked(); + } else { + doRemoveFontFaceSet(); } } @@ -736,7 +751,7 @@ void FontFaceImpl::Entry::SetLoadState(UserFontLoadState aLoadState) { nsTArray<RefPtr<FontFaceImpl>> fontFaces; { - MutexAutoLock lock(mMutex); + AutoReadLock lock(mLock); fontFaces.SetCapacity(mFontFaces.Length()); for (FontFaceImpl* f : mFontFaces) { fontFaces.AppendElement(f); @@ -758,7 +773,7 @@ void FontFaceImpl::Entry::SetLoadState(UserFontLoadState aLoadState) { /* virtual */ void FontFaceImpl::Entry::GetUserFontSets( nsTArray<RefPtr<gfxUserFontSet>>& aResult) { - MutexAutoLock lock(mMutex); + AutoReadLock lock(mLock); aResult.Clear(); @@ -783,7 +798,7 @@ void FontFaceImpl::Entry::GetUserFontSets( /* virtual */ already_AddRefed<gfxUserFontSet> FontFaceImpl::Entry::GetUserFontSet() const { - MutexAutoLock lock(mMutex); + AutoReadLock lock(mLock); if (mFontSet) { return do_AddRef(mFontSet); } @@ -816,7 +831,7 @@ void FontFaceImpl::Entry::CheckUserFontSetLocked() { } void FontFaceImpl::Entry::FindFontFaceOwners(nsTHashSet<FontFace*>& aOwners) { - MutexAutoLock lock(mMutex); + AutoReadLock lock(mLock); for (FontFaceImpl* f : mFontFaces) { if (FontFace* owner = f->GetOwner()) { aOwners.Insert(owner); @@ -825,13 +840,13 @@ void FontFaceImpl::Entry::FindFontFaceOwners(nsTHashSet<FontFace*>& aOwners) { } void FontFaceImpl::Entry::AddFontFace(FontFaceImpl* aFontFace) { - MutexAutoLock lock(mMutex); + AutoWriteLock lock(mLock); mFontFaces.AppendElement(aFontFace); CheckUserFontSetLocked(); } void FontFaceImpl::Entry::RemoveFontFace(FontFaceImpl* aFontFace) { - MutexAutoLock lock(mMutex); + AutoWriteLock lock(mLock); mFontFaces.RemoveElement(aFontFace); CheckUserFontSetLocked(); } diff --git a/layout/style/FontFaceImpl.h b/layout/style/FontFaceImpl.h index 70c06609e9..7f1279a248 100644 --- a/layout/style/FontFaceImpl.h +++ b/layout/style/FontFaceImpl.h @@ -10,7 +10,7 @@ #include "mozilla/dom/FontFaceBinding.h" #include "mozilla/FontPropertyTypes.h" #include "mozilla/Maybe.h" -#include "mozilla/Mutex.h" +#include "mozilla/RWLock.h" #include "mozilla/ServoStyleConsts.h" #include "gfxUserFontSet.h" #include "nsCSSPropertyID.h" @@ -50,21 +50,15 @@ class FontFaceImpl final { Entry(gfxUserFontSet* aFontSet, nsTArray<gfxFontFaceSrc>&& aFontFaceSrcList, gfxUserFontAttributes&& aAttr) : gfxUserFontEntry(std::move(aFontFaceSrcList), std::move(aAttr)), - mMutex("FontFaceImpl::Entry::mMutex"), mFontSet(aFontSet) {} void SetLoadState(UserFontLoadState aLoadState) override; void GetUserFontSets(nsTArray<RefPtr<gfxUserFontSet>>& aResult) override; already_AddRefed<gfxUserFontSet> GetUserFontSet() const override; - void CheckUserFontSet() { - MutexAutoLock lock(mMutex); - CheckUserFontSetLocked(); - } - #ifdef DEBUG bool HasUserFontSet(gfxUserFontSet* aFontSet) const { - MutexAutoLock lock(mMutex); + AutoReadLock lock(mLock); return mFontSet == aFontSet; } #endif @@ -73,19 +67,19 @@ class FontFaceImpl final { void RemoveFontFace(FontFaceImpl* aOwner); void FindFontFaceOwners(nsTHashSet<FontFace*>& aOwners); - protected: - void CheckUserFontSetLocked() MOZ_REQUIRES(mMutex); + RWLock& Lock() const MOZ_RETURN_CAPABILITY(mLock) { return mLock; } - mutable Mutex mMutex; + protected: + void CheckUserFontSetLocked() MOZ_REQUIRES(mLock); // Font set which owns this entry; - gfxUserFontSet* MOZ_NON_OWNING_REF mFontSet MOZ_GUARDED_BY(mMutex); + gfxUserFontSet* MOZ_NON_OWNING_REF mFontSet MOZ_GUARDED_BY(mLock); // The FontFace objects that use this user font entry. We need to store // an array of these, not just a single pointer, since the user font // cache can return the same entry for different FontFaces that have // the same descriptor values and come from the same origin. - AutoTArray<FontFaceImpl*, 1> mFontFaces MOZ_GUARDED_BY(mMutex); + AutoTArray<FontFaceImpl*, 1> mFontFaces MOZ_GUARDED_BY(mLock); }; #ifdef DEBUG diff --git a/layout/style/FontFaceSetDocumentImpl.cpp b/layout/style/FontFaceSetDocumentImpl.cpp index 33f7404c7c..cd1d5959d2 100644 --- a/layout/style/FontFaceSetDocumentImpl.cpp +++ b/layout/style/FontFaceSetDocumentImpl.cpp @@ -496,7 +496,7 @@ bool FontFaceSetDocumentImpl::UpdateRules( } if (modified) { - IncrementGeneration(true); + IncrementGenerationLocked(true); mHasLoadingFontFacesIsDirty = true; CheckLoadingStarted(); CheckLoadingFinished(); diff --git a/layout/style/FontFaceSetImpl.cpp b/layout/style/FontFaceSetImpl.cpp index 7383842a41..5dabf25d38 100644 --- a/layout/style/FontFaceSetImpl.cpp +++ b/layout/style/FontFaceSetImpl.cpp @@ -70,8 +70,7 @@ using namespace mozilla::dom; NS_IMPL_ISUPPORTS0(FontFaceSetImpl) FontFaceSetImpl::FontFaceSetImpl(FontFaceSet* aOwner) - : mMutex("mozilla::dom::FontFaceSetImpl"), - mOwner(aOwner), + : mOwner(aOwner), mStatus(FontFaceSetLoadStatus::Loaded), mNonRuleFacesDirty(false), mHasLoadingFontFaces(false), @@ -891,7 +890,7 @@ void FontFaceSetImpl::OnLoadingFinished() { void FontFaceSetImpl::RefreshStandardFontLoadPrincipal() { RecursiveMutexAutoLock lock(mMutex); mAllowedFontLoads.Clear(); - IncrementGeneration(false); + IncrementGenerationLocked(false); } // -- gfxUserFontSet diff --git a/layout/style/FontFaceSetImpl.h b/layout/style/FontFaceSetImpl.h index 6f245c6599..dd412dd721 100644 --- a/layout/style/FontFaceSetImpl.h +++ b/layout/style/FontFaceSetImpl.h @@ -92,9 +92,10 @@ class FontFaceSetImpl : public nsISupports, public gfxUserFontSet { virtual void DispatchToOwningThread(const char* aName, std::function<void()>&& aFunc) = 0; - // Called by nsFontFaceLoader when the loader has completed normally. + // Called by nsFontFaceLoader when the loader has completed normally, + // or by gfxUserFontSet if it cancels the loader. // It's removed from the mLoaders set. - virtual void RemoveLoader(nsFontFaceLoader* aLoader); + void RemoveLoader(nsFontFaceLoader* aLoader) override; virtual bool UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules) { MOZ_ASSERT_UNREACHABLE("Not implemented!"); @@ -247,8 +248,6 @@ class FontFaceSetImpl : public nsISupports, public gfxUserFontSet { virtual TimeStamp GetNavigationStartTimeStamp() = 0; - mutable RecursiveMutex mMutex; - FontFaceSet* MOZ_NON_OWNING_REF mOwner MOZ_GUARDED_BY(mMutex); // The document's node principal, which is the principal font loads for diff --git a/layout/style/FontFaceSetWorkerImpl.cpp b/layout/style/FontFaceSetWorkerImpl.cpp index 015c9e5b18..7fbfbf0d95 100644 --- a/layout/style/FontFaceSetWorkerImpl.cpp +++ b/layout/style/FontFaceSetWorkerImpl.cpp @@ -227,7 +227,7 @@ void FontFaceSetWorkerImpl::FlushUserFontSet() { } if (modified) { - IncrementGeneration(true); + IncrementGenerationLocked(true); mHasLoadingFontFacesIsDirty = true; CheckLoadingStarted(); CheckLoadingFinished(); diff --git a/layout/style/GenerateServoCSSPropList.py b/layout/style/GenerateServoCSSPropList.py index 0e9678ac5c..4dba1f0a8f 100644 --- a/layout/style/GenerateServoCSSPropList.py +++ b/layout/style/GenerateServoCSSPropList.py @@ -30,7 +30,7 @@ def generate_data(output, template): ) # Add all relevant files into the dependencies of the generated file. - DEP_EXTS = [".py", ".rs", ".zip"] + DEP_EXTS = [".py", ".rs"] deps = set() for path, dirs, files in os.walk(SERVO_PROP_BASE): for file in files: diff --git a/layout/style/ImageLoader.cpp b/layout/style/ImageLoader.cpp index 2ae1822b02..1a59a5bcf3 100644 --- a/layout/style/ImageLoader.cpp +++ b/layout/style/ImageLoader.cpp @@ -565,6 +565,16 @@ static void InvalidateImages(nsIFrame* aFrame, imgIRequest* aRequest, } } } +#ifdef XP_MACOSX + else if (aFrame->HasAnyStateBits(NS_FRAME_IN_POPUP)) { + // On macOS popups are painted with fallback rendering so they don't have + // webrender user data to tell us if the frame was painted last time, so we + // just have to invalidate always. Bug 1754796 tracks making popups on macOS + // use webrender. (On other platforms tooltips type popups are still + // rendered with fallback, but we don't expect them to have images.) + invalidateFrame = true; + } +#endif // Update ancestor rendering observers (-moz-element etc) // diff --git a/layout/style/PreferenceSheet.cpp b/layout/style/PreferenceSheet.cpp index a206209885..eb752b2789 100644 --- a/layout/style/PreferenceSheet.cpp +++ b/layout/style/PreferenceSheet.cpp @@ -205,7 +205,7 @@ void PreferenceSheet::Prefs::Load(bool aIsChrome) { // as those are the colors exposed to the user in the colors dialog. mMustUseLightColorSet = mUsePrefColors && !mUseDocumentColors; #ifdef XP_WIN - if (mUseAccessibilityTheme) { + if (mUseAccessibilityTheme && (mIsChrome || !mUseDocumentColors)) { // Windows overrides the light colors with the HCM colors when HCM is // active, so make sure to always use the light system colors in that case, // and also make sure that we always use the light color set for the same diff --git a/layout/style/Rule.cpp b/layout/style/Rule.cpp index 0a7de42789..4b0f783bd9 100644 --- a/layout/style/Rule.cpp +++ b/layout/style/Rule.cpp @@ -106,7 +106,9 @@ void Rule::AssertParentRuleType() { type == StyleCssRuleType::Supports || type == StyleCssRuleType::Keyframes || type == StyleCssRuleType::LayerBlock || - type == StyleCssRuleType::Container); + type == StyleCssRuleType::Container || + type == StyleCssRuleType::Scope || + type == StyleCssRuleType::StartingStyle); } } #endif diff --git a/layout/style/ServoBindingTypes.h b/layout/style/ServoBindingTypes.h index fe4f96cf0b..b081a4981b 100644 --- a/layout/style/ServoBindingTypes.h +++ b/layout/style/ServoBindingTypes.h @@ -129,6 +129,8 @@ UNLOCKED_RULE_TYPE(Supports) UNLOCKED_RULE_TYPE(Document) UNLOCKED_RULE_TYPE(FontFeatureValues) UNLOCKED_RULE_TYPE(FontPaletteValues) +UNLOCKED_RULE_TYPE(Scope) +UNLOCKED_RULE_TYPE(StartingStyle) SERVO_ARC_TYPE(AnimationValue, mozilla::StyleAnimationValue) SERVO_ARC_TYPE(ComputedStyle, mozilla::ComputedStyle) diff --git a/layout/style/ServoBindings.h b/layout/style/ServoBindings.h index 6f19006512..52538cafb8 100644 --- a/layout/style/ServoBindings.h +++ b/layout/style/ServoBindings.h @@ -77,7 +77,7 @@ BASIC_RULE_FUNCS_LOCKED(Keyframes) GROUP_RULE_FUNCS_UNLOCKED(Media) GROUP_RULE_FUNCS_UNLOCKED(Document) BASIC_RULE_FUNCS_UNLOCKED(Namespace) -BASIC_RULE_FUNCS_LOCKED(Page) +GROUP_RULE_FUNCS_LOCKED(Page) BASIC_RULE_FUNCS_UNLOCKED(Property) GROUP_RULE_FUNCS_UNLOCKED(Supports) GROUP_RULE_FUNCS_UNLOCKED(LayerBlock) @@ -87,6 +87,8 @@ BASIC_RULE_FUNCS_UNLOCKED(FontPaletteValues) BASIC_RULE_FUNCS_LOCKED(FontFace) BASIC_RULE_FUNCS_LOCKED(CounterStyle) GROUP_RULE_FUNCS_UNLOCKED(Container) +GROUP_RULE_FUNCS_UNLOCKED(Scope) +GROUP_RULE_FUNCS_UNLOCKED(StartingStyle) #undef GROUP_RULE_FUNCS_LOCKED #undef GROUP_RULE_FUNCS_UNLOCKED diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml index 20e1ca4116..67fd902e2b 100644 --- a/layout/style/ServoBindings.toml +++ b/layout/style/ServoBindings.toml @@ -515,6 +515,9 @@ cbindgen-types = [ { gecko = "StyleBasicShape", servo = "crate::values::computed::basic_shape::BasicShape" }, { gecko = "StyleGenericInsetRect", servo = "crate::values::generics::basic_shape::InsetRect" }, { gecko = "StyleInsetRect", servo = "crate::values::computed::basic_shape::InsetRect" }, + { gecko = "StyleShape", servo = "crate::values::computed::basic_shape::Shape" }, + { gecko = "StyleShapeCommand", servo = "crate::values::computed::basic_shape::ShapeCommand" }, + { gecko = "StyleGenericShapeCommand", servo = "crate::values::generics::basic_shape::ShapeCommand" }, { gecko = "StyleArcSlice", servo = "style_traits::arc_slice::ArcSlice" }, { gecko = "StyleForgottenArcSlicePtr", servo = "style_traits::arc_slice::ForgottenArcSlicePtr" }, { gecko = "StyleOwnedSlice", servo = "style_traits::owned_slice::OwnedSlice" }, diff --git a/layout/style/ServoCSSRuleList.cpp b/layout/style/ServoCSSRuleList.cpp index 6fcdfdd4b5..133a962256 100644 --- a/layout/style/ServoCSSRuleList.cpp +++ b/layout/style/ServoCSSRuleList.cpp @@ -22,6 +22,8 @@ #include "mozilla/dom/CSSNamespaceRule.h" #include "mozilla/dom/CSSPageRule.h" #include "mozilla/dom/CSSPropertyRule.h" +#include "mozilla/dom/CSSScopeRule.h" +#include "mozilla/dom/CSSStartingStyleRule.h" #include "mozilla/dom/CSSStyleRule.h" #include "mozilla/dom/CSSSupportsRule.h" #include "mozilla/IntegerRange.h" @@ -98,6 +100,8 @@ css::Rule* ServoCSSRuleList::GetRule(uint32_t aIndex) { CASE_RULE_UNLOCKED(LayerBlock, LayerBlock) CASE_RULE_UNLOCKED(LayerStatement, LayerStatement) CASE_RULE_UNLOCKED(Container, Container) + CASE_RULE_UNLOCKED(Scope, Scope) + CASE_RULE_UNLOCKED(StartingStyle, StartingStyle) #undef CASE_RULE_LOCKED #undef CASE_RULE_UNLOCKED #undef CASE_RULE_WITH_PREFIX @@ -208,12 +212,21 @@ nsresult ServoCSSRuleList::InsertRule(const nsACString& aRule, } StyleCssRuleType type; uint32_t containingTypes = 0; + Maybe<StyleCssRuleType> parseRelativeRuleType; for (css::Rule* rule = mParentRule; rule; rule = rule->GetParentRule()) { - containingTypes |= (1 << uint32_t(rule->Type())); + const auto ruleType = rule->Type(); + containingTypes |= (1 << uint32_t(ruleType)); + if (parseRelativeRuleType.isNothing() && + (ruleType == StyleCssRuleType::Style || + ruleType == StyleCssRuleType::Scope)) { + // Only the closest applicable type to this rule matters. + parseRelativeRuleType = Some(ruleType); + } } nsresult rv = Servo_CssRules_InsertRule( mRawRules, mStyleSheet->RawContents(), &aRule, aIndex, containingTypes, - loader, allowImportRules, mStyleSheet, &type); + parseRelativeRuleType.ptrOr(nullptr), loader, allowImportRules, + mStyleSheet, &type); NS_ENSURE_SUCCESS(rv, rv); mRules.InsertElementAt(aIndex, uintptr_t(type)); return rv; @@ -276,6 +289,8 @@ void ServoCSSRuleList::SetRawContents(RefPtr<StyleLockedCssRules> aNewRules, RULE_CASE_UNLOCKED(LayerBlock, LayerBlock) RULE_CASE_UNLOCKED(LayerStatement, LayerStatement) RULE_CASE_UNLOCKED(Container, Container) + RULE_CASE_UNLOCKED(Scope, Scope) + RULE_CASE_UNLOCKED(StartingStyle, StartingStyle) case StyleCssRuleType::Keyframe: MOZ_ASSERT_UNREACHABLE("keyframe rule cannot be here"); break; diff --git a/layout/style/ServoElementSnapshot.cpp b/layout/style/ServoElementSnapshot.cpp index e0ef2849f9..a5251d9349 100644 --- a/layout/style/ServoElementSnapshot.cpp +++ b/layout/style/ServoElementSnapshot.cpp @@ -82,4 +82,11 @@ void ServoElementSnapshot::AddAttrs(const Element& aElement, } } +void ServoElementSnapshot::AddCustomStates(Element& aElement) { + if (mContains & Flags::CustomState) { + return; + } + mCustomStates = aElement.EnsureCustomStates().Clone(); + mContains |= Flags::CustomState; +} } // namespace mozilla diff --git a/layout/style/ServoElementSnapshot.h b/layout/style/ServoElementSnapshot.h index b702975c4b..5a86b4c13d 100644 --- a/layout/style/ServoElementSnapshot.h +++ b/layout/style/ServoElementSnapshot.h @@ -33,6 +33,7 @@ enum class ServoElementSnapshotFlags : uint8_t { Id = 1 << 2, MaybeClass = 1 << 3, OtherPseudoClassState = 1 << 4, + CustomState = 1 << 5, }; MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoElementSnapshotFlags) @@ -88,6 +89,11 @@ class ServoElementSnapshot { */ void AddAttrs(const Element&, int32_t aNameSpaceID, nsAtom* aAttribute); + /** + * Captures the given element custom states. + */ + void AddCustomStates(Element&); + /** * Captures some other pseudo-class matching state not included in * ElementState. @@ -155,6 +161,7 @@ class ServoElementSnapshot { // snapshots. nsTArray<AttrArray::InternalAttr> mAttrs; nsTArray<RefPtr<nsAtom>> mChangedAttrNames; + nsTArray<RefPtr<nsAtom>> mCustomStates; nsAttrValue mClass; ServoStateType mState; Flags mContains; diff --git a/layout/style/ServoStyleConstsForwards.h b/layout/style/ServoStyleConstsForwards.h index 65128e1377..5bf87d8330 100644 --- a/layout/style/ServoStyleConstsForwards.h +++ b/layout/style/ServoStyleConstsForwards.h @@ -83,7 +83,7 @@ struct PropertyStyleAnimationValuePair; using ComputedKeyframeValues = nsTArray<PropertyStyleAnimationValuePair>; class ComputedStyle; -enum LogicalAxis : uint8_t; +enum class LogicalAxis : uint8_t; class SeenPtrs; class SharedFontList; class StyleSheet; @@ -100,7 +100,7 @@ struct ComputedTiming; struct URLExtraData; enum HalfCorner : uint8_t; -enum LogicalSide : uint8_t; +enum class LogicalSide : uint8_t; enum class PseudoStyleType : uint8_t; enum class OriginFlags : uint8_t; enum class UseBoxSizing : uint8_t; diff --git a/layout/style/ServoStyleConstsInlines.h b/layout/style/ServoStyleConstsInlines.h index 1985e8fbeb..5a86e4ccd0 100644 --- a/layout/style/ServoStyleConstsInlines.h +++ b/layout/style/ServoStyleConstsInlines.h @@ -53,6 +53,8 @@ template struct StyleStrong<StyleFontPaletteValuesRule>; template struct StyleStrong<StyleLockedFontFaceRule>; template struct StyleStrong<StyleLockedCounterStyleRule>; template struct StyleStrong<StyleContainerRule>; +template struct StyleStrong<StyleScopeRule>; +template struct StyleStrong<StyleStartingStyleRule>; template <typename T> inline void StyleOwnedSlice<T>::Clear() { @@ -697,9 +699,12 @@ CSSCoord StyleCalcLengthPercentage::ResolveToCSSPixels(CSSCoord aBasis) const { return Servo_ResolveCalcLengthPercentage(this, aBasis); } -nscoord StyleCalcLengthPercentage::Resolve(nscoord aBasis) const { - return detail::DefaultLengthToAppUnits( - ResolveToCSSPixels(CSSPixel::FromAppUnits(aBasis))); +template <typename Rounder> +nscoord StyleCalcLengthPercentage::Resolve(nscoord aBasis, + Rounder aRounder) const { + static_assert(std::is_same_v<decltype(aRounder(1.0f)), nscoord>); + CSSCoord result = ResolveToCSSPixels(CSSPixel::FromAppUnits(aBasis)); + return aRounder(result * AppUnitsPerCSSPixel()); } template <> @@ -724,11 +729,10 @@ CSSCoord LengthPercentage::ResolveToCSSPixelsWith(T aPercentageGetter) const { return ResolveToCSSPixels(aPercentageGetter()); } -template <typename T, typename PercentRounder> -nscoord LengthPercentage::Resolve(T aPercentageGetter, - PercentRounder aPercentRounder) const { +template <typename T, typename Rounder> +nscoord LengthPercentage::Resolve(T aPercentageGetter, Rounder aRounder) const { static_assert(std::is_same_v<decltype(aPercentageGetter()), nscoord>); - static_assert(std::is_same_v<decltype(aPercentRounder(1.0f)), nscoord>); + static_assert(std::is_same_v<decltype(aRounder(1.0f)), nscoord>); if (ConvertsToLength()) { return ToLength(); } @@ -737,9 +741,9 @@ nscoord LengthPercentage::Resolve(T aPercentageGetter, } nscoord basis = aPercentageGetter(); if (IsPercentage()) { - return aPercentRounder(basis * AsPercentage()._0); + return aRounder(basis * AsPercentage()._0); } - return AsCalc().Resolve(basis); + return AsCalc().Resolve(basis, aRounder); } nscoord LengthPercentage::Resolve(nscoord aPercentageBasis) const { @@ -752,11 +756,10 @@ nscoord LengthPercentage::Resolve(T aPercentageGetter) const { return Resolve(aPercentageGetter, detail::DefaultPercentLengthToAppUnits); } -template <typename PercentRounder> +template <typename Rounder> nscoord LengthPercentage::Resolve(nscoord aPercentageBasis, - PercentRounder aPercentRounder) const { - return Resolve([aPercentageBasis] { return aPercentageBasis; }, - aPercentRounder); + Rounder aRounder) const { + return Resolve([aPercentageBasis] { return aPercentageBasis; }, aRounder); } void LengthPercentage::ScaleLengthsBy(float aScale) { @@ -1201,6 +1204,20 @@ inline nsRect StyleZoom::Unzoom(const nsRect& aValue) const { UnzoomCoord(aValue.Width()), UnzoomCoord(aValue.Height())); } +template <> +inline gfx::Point StyleCoordinatePair<StyleCSSFloat>::ToGfxPoint( + const CSSSize* aBasis) const { + return gfx::Point(x, y); +} + +template <> +inline gfx::Point StyleCoordinatePair<LengthPercentage>::ToGfxPoint( + const CSSSize* aBasis) const { + MOZ_ASSERT(aBasis); + return gfx::Point(x.ResolveToCSSPixels(aBasis->Width()), + y.ResolveToCSSPixels(aBasis->Height())); +} + } // namespace mozilla #endif diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp index cfc38849b8..91231af2b0 100644 --- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -41,7 +41,9 @@ #include "mozilla/dom/CSSNamespaceRule.h" #include "mozilla/dom/CSSPageRule.h" #include "mozilla/dom/CSSPropertyRule.h" +#include "mozilla/dom/CSSScopeRule.h" #include "mozilla/dom/CSSSupportsRule.h" +#include "mozilla/dom/CSSStartingStyleRule.h" #include "mozilla/dom/FontFaceSet.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/ElementInlines.h" @@ -1002,6 +1004,8 @@ void ServoStyleSet::RuleChangedInternal(StyleSheet& aSheet, css::Rule& aRule, CASE_FOR(LayerBlock, LayerBlock) CASE_FOR(LayerStatement, LayerStatement) CASE_FOR(Container, Container) + CASE_FOR(Scope, Scope) + CASE_FOR(StartingStyle, StartingStyle) // @namespace can only be inserted / removed when there are only other // @namespace and @import rules, and can't be mutated. case StyleCssRuleType::Namespace: @@ -1394,6 +1398,13 @@ void ServoStyleSet::MaybeInvalidateRelativeSelectorClassDependency( mRawData.get(), &aElement, &aSnapshots); } +void ServoStyleSet::MaybeInvalidateRelativeSelectorCustomStateDependency( + const Element& aElement, nsAtom* state, + const ServoElementSnapshotTable& aSnapshots) { + Servo_StyleSet_MaybeInvalidateRelativeSelectorCustomStateDependency( + mRawData.get(), &aElement, state, &aSnapshots); +} + void ServoStyleSet::MaybeInvalidateRelativeSelectorAttributeDependency( const Element& aElement, nsAtom* aAttribute, const ServoElementSnapshotTable& aSnapshots) { @@ -1465,6 +1476,12 @@ bool ServoStyleSet::HasNthOfStateDependency(const Element& aElement, aState.GetInternalValue()); } +bool ServoStyleSet::HasNthOfCustomStateDependency(const Element& aElement, + nsAtom* aState) const { + return Servo_StyleSet_HasNthOfCustomStateDependency(mRawData.get(), &aElement, + aState); +} + void ServoStyleSet::RestyleSiblingsForNthOf(const Element& aElement, uint32_t aFlags) const { Servo_StyleSet_RestyleSiblingsForNthOf(&aElement, aFlags); diff --git a/layout/style/ServoStyleSet.h b/layout/style/ServoStyleSet.h index eee6cba0f7..f3159c97ec 100644 --- a/layout/style/ServoStyleSet.h +++ b/layout/style/ServoStyleSet.h @@ -476,6 +476,14 @@ class ServoStyleSet { void MaybeInvalidateRelativeSelectorClassDependency( const dom::Element&, const ServoElementSnapshotTable& aSnapshots); + /** + * Maybe invalidate if a modification to a Custom State might require us to + * restyle the relative selector it refers to. + */ + void MaybeInvalidateRelativeSelectorCustomStateDependency( + const dom::Element&, nsAtom* state, + const ServoElementSnapshotTable& aSnapshots); + /** * Maybe invalidate if a modification to an ID might require us to restyle * the relative selector it refers to. @@ -549,6 +557,12 @@ class ServoStyleSet { */ bool HasNthOfStateDependency(const dom::Element&, dom::ElementState) const; + /** + * Returns true if a change in Custom State on an element might require + * us to restyle the element's siblings. + */ + bool HasNthOfCustomStateDependency(const dom::Element&, nsAtom*) const; + /** * Restyle this element's siblings in order to propagate any potential change * in :nth-child(of) styling. diff --git a/layout/style/SharedSubResourceCache.h b/layout/style/SharedSubResourceCache.h index 32919b8863..896eacbcb5 100644 --- a/layout/style/SharedSubResourceCache.h +++ b/layout/style/SharedSubResourceCache.h @@ -58,6 +58,9 @@ struct SharedSubResourceCacheLoadingValueBase { virtual void SetLoadCompleted() = 0; virtual void Cancel() = 0; + // Return the next sub-resource which has the same key. + Derived* GetNextSubResource() { return mNext; } + ~SharedSubResourceCacheLoadingValueBase() { // Do this iteratively to avoid blowing up the stack. RefPtr<Derived> next = std::move(mNext); diff --git a/layout/style/moz.build b/layout/style/moz.build index a14ab6a7ac..b77fa34983 100644 --- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -56,6 +56,7 @@ EXPORTS += [ "nsCSSValue.h", "nsDOMCSSAttrDeclaration.h", "nsDOMCSSDeclaration.h", + "nsFontFaceLoader.h", "nsICSSDeclaration.h", "nsICSSLoaderObserver.h", "nsStyleAutoArray.h", @@ -143,6 +144,8 @@ EXPORTS.mozilla.dom += [ "CSSPageRule.h", "CSSPropertyRule.h", "CSSRuleList.h", + "CSSScopeRule.h", + "CSSStartingStyleRule.h", "CSSStyleRule.h", "CSSSupportsRule.h", "CSSValue.h", @@ -194,6 +197,8 @@ UNIFIED_SOURCES += [ "CSSPageRule.cpp", "CSSPropertyRule.cpp", "CSSRuleList.cpp", + "CSSScopeRule.cpp", + "CSSStartingStyleRule.cpp", "CSSStyleRule.cpp", "CSSSupportsRule.cpp", "DeclarationBlock.cpp", diff --git a/layout/style/nsCSSPseudoElementList.h b/layout/style/nsCSSPseudoElementList.h index 9514dd6c4b..7492523c58 100644 --- a/layout/style/nsCSSPseudoElementList.h +++ b/layout/style/nsCSSPseudoElementList.h @@ -51,6 +51,7 @@ CSS_PSEUDO_ELEMENT(highlight, ":highlight", 0) CSS_PSEUDO_ELEMENT(selection, ":selection", CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS) +CSS_PSEUDO_ELEMENT(targetText, ":target-text", 0) // XXXbz should we really allow random content to style these? Maybe // use our flags to prevent that? CSS_PSEUDO_ELEMENT(mozFocusInner, ":-moz-focus-inner", 0) diff --git a/layout/style/nsCSSPseudoElements.h b/layout/style/nsCSSPseudoElements.h index 9866fbfb7e..baeee9d4de 100644 --- a/layout/style/nsCSSPseudoElements.h +++ b/layout/style/nsCSSPseudoElements.h @@ -130,6 +130,8 @@ class nsCSSPseudoElements { switch (aType) { case Type::highlight: return mozilla::StaticPrefs::dom_customHighlightAPI_enabled(); + case Type::targetText: + return mozilla::StaticPrefs::dom_text_fragments_enabled(); case Type::sliderTrack: case Type::sliderThumb: case Type::sliderFill: diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index d40d4bc801..5b71ec54bf 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -1358,11 +1358,28 @@ already_AddRefed<nsROCSSPrimitiveValue> nsComputedDOMStyle::MatrixToCSSValue( /* Create a value to hold our result. */ RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetString(resultString); return val.forget(); } +already_AddRefed<nsROCSSPrimitiveValue> nsComputedDOMStyle::AppUnitsToCSSValue( + nscoord aAppUnits) { + return PixelsToCSSValue(CSSPixel::FromAppUnits(aAppUnits)); +} + +already_AddRefed<nsROCSSPrimitiveValue> nsComputedDOMStyle::PixelsToCSSValue( + float aPixels) { + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; + SetValueToPixels(val, aPixels); + return val.forget(); +} + +void nsComputedDOMStyle::SetValueToPixels(nsROCSSPrimitiveValue* aValue, + float aPixels) { + MOZ_ASSERT(mComputedStyle); + aValue->SetPixels(mComputedStyle->EffectiveZoom().Unzoom(aPixels)); +} + already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMozOsxFontSmoothing() { if (nsContentUtils::ShouldResistFingerprinting( mPresShell->GetPresContext()->GetDocShell(), @@ -1614,9 +1631,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows( // Add any leading implicit tracks. if (serializeImplicit) { for (uint32_t i = 0; i < numLeadingImplicitTracks; ++i) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(trackSizes[i]); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(trackSizes[i])); } } @@ -1652,8 +1667,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows( for (uint32_t i = 0; i < repeatStart; i++) { AppendGridLineNames(valueList, aTrackInfo.mResolvedLineNames[i]); RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(*trackSizeIter++); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(*trackSizeIter++)); } auto lineNameIter = aTrackInfo.mResolvedLineNames.cbegin() + repeatStart; // Write the track names at the start of the repeat, including the names @@ -1666,9 +1680,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows( // track). const nscoord firstRepeatTrackSize = (!aTrackInfo.mRemovedRepeatTracks[0]) ? *trackSizeIter++ : 0; - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(firstRepeatTrackSize); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(firstRepeatTrackSize)); } // Write the line names and track sizes inside the repeat, checking for // removed tracks (size 0). @@ -1688,9 +1700,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows( trackSizeIter != explicitTrackSizeEnd); const nscoord repeatTrackSize = (!aTrackInfo.mRemovedRepeatTracks[i]) ? *trackSizeIter++ : 0; - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(repeatTrackSize); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(repeatTrackSize)); } // The resolved line names include a single repetition of the auto-repeat // line names. Skip over those. @@ -1698,9 +1708,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows( // Write out any more tracks after the repeat. while (trackSizeIter != explicitTrackSizeEnd) { AppendGridLineNames(valueList, *lineNameIter++); - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(*trackSizeIter++); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(*trackSizeIter++)); } // Write the final trailing line name. AppendGridLineNames(valueList, *lineNameIter++); @@ -1711,18 +1719,15 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridTemplateColumnsRows( if (i == numExplicitTracks) { break; } - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(trackSizes[i + numLeadingImplicitTracks]); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue( + AppUnitsToCSSValue(trackSizes[i + numLeadingImplicitTracks])); } } // Add any trailing implicit tracks. if (serializeImplicit) { for (uint32_t i = numLeadingImplicitTracks + numExplicitTracks; i < numSizes; ++i) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(trackSizes[i]); - valueList->AppendCSSValue(val.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(trackSizes[i])); } } @@ -1787,15 +1792,9 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPaddingRight() { already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetBorderSpacing() { RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false); - RefPtr<nsROCSSPrimitiveValue> xSpacing = new nsROCSSPrimitiveValue; - RefPtr<nsROCSSPrimitiveValue> ySpacing = new nsROCSSPrimitiveValue; - const nsStyleTableBorder* border = StyleTableBorder(); - xSpacing->SetAppUnits(border->mBorderSpacingCol); - ySpacing->SetAppUnits(border->mBorderSpacingRow); - - valueList->AppendCSSValue(xSpacing.forget()); - valueList->AppendCSSValue(ySpacing.forget()); + valueList->AppendCSSValue(AppUnitsToCSSValue(border->mBorderSpacingCol)); + valueList->AppendCSSValue(AppUnitsToCSSValue(border->mBorderSpacingRow)); return valueList.forget(); } @@ -1833,32 +1832,26 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetMarginRight() { } already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetHeight() { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - if (mInnerFrame && !IsNonReplacedInline(mInnerFrame)) { AssertFlushedPendingReflows(); - nsMargin adjustedValues = GetAdjustedValuesForBoxSizing(); - val->SetAppUnits(mInnerFrame->GetContentRect().height + - adjustedValues.TopBottom()); - } else { - SetValueToSize(val, StylePosition()->mHeight); + const nsMargin adjustedValues = GetAdjustedValuesForBoxSizing(); + return AppUnitsToCSSValue(mInnerFrame->GetContentRect().height + + adjustedValues.TopBottom()); } - + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; + SetValueToSize(val, StylePosition()->mHeight); return val.forget(); } already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetWidth() { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - if (mInnerFrame && !IsNonReplacedInline(mInnerFrame)) { AssertFlushedPendingReflows(); nsMargin adjustedValues = GetAdjustedValuesForBoxSizing(); - val->SetAppUnits(mInnerFrame->GetContentRect().width + - adjustedValues.LeftRight()); - } else { - SetValueToSize(val, StylePosition()->mWidth); + return AppUnitsToCSSValue(mInnerFrame->GetContentRect().width + + adjustedValues.LeftRight()); } - + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; + SetValueToSize(val, StylePosition()->mWidth); return val.forget(); } @@ -1968,14 +1961,13 @@ static_assert(eSideTop == 0 && eSideRight == 1 && eSideBottom == 2 && already_AddRefed<CSSValue> nsComputedDOMStyle::GetNonStaticPositionOffset( mozilla::Side aSide, bool aResolveAuto, PercentageBaseGetter aWidthGetter, PercentageBaseGetter aHeightGetter) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - const nsStylePosition* positionData = StylePosition(); int32_t sign = 1; LengthPercentageOrAuto coord = positionData->mOffset.Get(aSide); if (coord.IsAuto()) { if (!aResolveAuto) { + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; val->SetString("auto"); return val.forget(); } @@ -1983,14 +1975,12 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetNonStaticPositionOffset( sign = -1; } if (!coord.IsLengthPercentage()) { - val->SetPixels(0.0f); - return val.forget(); + return PixelsToCSSValue(0.0f); } - auto& lp = coord.AsLengthPercentage(); + const auto& lp = coord.AsLengthPercentage(); if (lp.ConvertsToLength()) { - val->SetPixels(sign * lp.ToLengthInCSSPixels()); - return val.forget(); + return PixelsToCSSValue(sign * lp.ToLengthInCSSPixels()); } PercentageBaseGetter baseGetter = (aSide == eSideLeft || aSide == eSideRight) @@ -1998,12 +1988,10 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetNonStaticPositionOffset( : aHeightGetter; nscoord percentageBase; if (!(this->*baseGetter)(percentageBase)) { - val->SetPixels(0.0f); - return val.forget(); + return PixelsToCSSValue(0.0f); } nscoord result = lp.Resolve(percentageBase); - val->SetAppUnits(sign * result); - return val.forget(); + return AppUnitsToCSSValue(sign * result); } already_AddRefed<CSSValue> nsComputedDOMStyle::GetAbsoluteOffset( @@ -2013,9 +2001,7 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetAbsoluteOffset( const auto& oppositeCoord = offset.Get(NS_OPPOSITE_SIDE(aSide)); if (coord.IsAuto() || oppositeCoord.IsAuto()) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - val->SetAppUnits(GetUsedAbsoluteOffset(aSide)); - return val.forget(); + return AppUnitsToCSSValue(GetUsedAbsoluteOffset(aSide)); } return GetNonStaticPositionOffset( @@ -2096,23 +2082,18 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetStaticOffset( already_AddRefed<CSSValue> nsComputedDOMStyle::GetPaddingWidthFor( mozilla::Side aSide) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - - auto& padding = StylePadding()->mPadding.Get(aSide); + const auto& padding = StylePadding()->mPadding.Get(aSide); if (!mInnerFrame || !PaddingNeedsUsedValue(padding, *mComputedStyle)) { + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToLengthPercentage(val, padding, true); - } else { - AssertFlushedPendingReflows(); - val->SetAppUnits(mInnerFrame->GetUsedPadding().Side(aSide)); + return val.forget(); } - - return val.forget(); + AssertFlushedPendingReflows(); + return AppUnitsToCSSValue(mInnerFrame->GetUsedPadding().Side(aSide)); } already_AddRefed<CSSValue> nsComputedDOMStyle::GetBorderWidthFor( mozilla::Side aSide) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - nscoord width; if (mInnerFrame && mComputedStyle->StyleDisplay()->HasAppearance()) { AssertFlushedPendingReflows(); @@ -2120,29 +2101,23 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetBorderWidthFor( } else { width = StyleBorder()->GetComputedBorderWidth(aSide); } - val->SetAppUnits(width); - - return val.forget(); + return AppUnitsToCSSValue(width); } already_AddRefed<CSSValue> nsComputedDOMStyle::GetMarginFor(Side aSide) { - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - - auto& margin = StyleMargin()->mMargin.Get(aSide); + const auto& margin = StyleMargin()->mMargin.Get(aSide); if (!mInnerFrame || margin.ConvertsToLength()) { + RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; SetValueToLengthPercentageOrAuto(val, margin, false); - } else { - AssertFlushedPendingReflows(); - - // For tables, GetUsedMargin always returns an empty margin, so we - // should read the margin from the table wrapper frame instead. - val->SetAppUnits(mOuterFrame->GetUsedMargin().Side(aSide)); - NS_ASSERTION(mOuterFrame == mInnerFrame || - mInnerFrame->GetUsedMargin() == nsMargin(0, 0, 0, 0), - "Inner tables must have zero margins"); + return val.forget(); } - - return val.forget(); + AssertFlushedPendingReflows(); + // For tables, GetUsedMargin always returns an empty margin, so we + // should read the margin from the table wrapper frame instead. + NS_ASSERTION( + mOuterFrame == mInnerFrame || mInnerFrame->GetUsedMargin() == nsMargin(), + "Inner tables must have zero margins"); + return AppUnitsToCSSValue(mOuterFrame->GetUsedMargin().Side(aSide)); } static void SetValueToExtremumLength(nsROCSSPrimitiveValue* aValue, @@ -2223,7 +2198,7 @@ void nsComputedDOMStyle::SetValueToLengthPercentage( if (aClampNegativeCalc) { length = std::max(float(length), 0.0f); } - return aValue->SetPixels(length); + return SetValueToPixels(aValue, length); } if (aLength.ConvertsToPercentage()) { float result = aLength.ToPercentage(); diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index 4f135a3aca..d1f3458030 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -148,6 +148,10 @@ class nsComputedDOMStyle final : public nsDOMCSSDeclaration, NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED private: + already_AddRefed<nsROCSSPrimitiveValue> AppUnitsToCSSValue(nscoord); + already_AddRefed<nsROCSSPrimitiveValue> PixelsToCSSValue(float); + void SetValueToPixels(nsROCSSPrimitiveValue*, float); + void GetPropertyValue(const nsCSSPropertyID aPropID, const nsACString& aMaybeCustomPropertyNme, nsACString& aValue); diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp index f888c127d4..fbdde4102d 100644 --- a/layout/style/nsMediaFeatures.cpp +++ b/layout/style/nsMediaFeatures.cpp @@ -336,18 +336,20 @@ StyleDynamicRange Gecko_MediaFeatures_DynamicRange(const Document* aDocument) { StyleDynamicRange Gecko_MediaFeatures_VideoDynamicRange( const Document* aDocument) { - if (aDocument->ShouldResistFingerprinting(RFPTarget::CSSVideoDynamicRange)) { + if (aDocument->ShouldResistFingerprinting(RFPTarget::CSSVideoDynamicRange) || + !StaticPrefs::layout_css_video_dynamic_range_allows_high()) { return StyleDynamicRange::Standard; } // video-dynamic-range: high has 3 requirements: // 1) high peak brightness // 2) high contrast ratio // 3) color depth > 24 - // We check the color depth requirement before asking the LookAndFeel - // if it is HDR capable. + + // As a proxy for those requirements, return 'High' if the screen associated + // with the device context claims to be HDR capable. if (nsDeviceContext* dx = GetDeviceContextFor(aDocument)) { - if (dx->GetDepth() > 24 && - LookAndFeel::GetInt(LookAndFeel::IntID::VideoDynamicRange)) { + if (dx->GetScreenIsHDR()) { + // bjw return StyleDynamicRange::High; } } diff --git a/layout/style/nsROCSSPrimitiveValue.cpp b/layout/style/nsROCSSPrimitiveValue.cpp index 84911d209b..3b31a14dd2 100644 --- a/layout/style/nsROCSSPrimitiveValue.cpp +++ b/layout/style/nsROCSSPrimitiveValue.cpp @@ -102,20 +102,12 @@ void nsROCSSPrimitiveValue::SetDegree(float aValue) { mType = CSS_DEG; } -void nsROCSSPrimitiveValue::SetAppUnits(nscoord aValue) { - SetPixels(nsPresContext::AppUnitsToFloatCSSPixels(aValue)); -} - void nsROCSSPrimitiveValue::SetPixels(float aValue) { Reset(); mValue.mFloat = aValue; mType = CSS_PX; } -void nsROCSSPrimitiveValue::SetAppUnits(float aValue) { - SetAppUnits(NSToCoordRound(aValue)); -} - void nsROCSSPrimitiveValue::SetString(const nsACString& aString) { Reset(); mValue.mString = ToNewUnicode(aString, mozilla::fallible); diff --git a/layout/style/nsROCSSPrimitiveValue.h b/layout/style/nsROCSSPrimitiveValue.h index d782a23469..79e6fd6a10 100644 --- a/layout/style/nsROCSSPrimitiveValue.h +++ b/layout/style/nsROCSSPrimitiveValue.h @@ -48,8 +48,6 @@ class nsROCSSPrimitiveValue final : public mozilla::dom::CSSValue { void SetPercent(float aValue); void SetDegree(float aValue); void SetPixels(float aValue); - void SetAppUnits(nscoord aValue); - void SetAppUnits(float aValue); void SetString(const nsACString& aString); void SetString(const nsAString& aString); diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 39f5b1a760..e46566d471 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -3536,7 +3536,7 @@ static nscoord Resolve(const StyleContainIntrinsicSize& aSize, } MOZ_ASSERT(aSize.HasAuto()); if (const auto* element = Element::FromNodeOrNull(aFrame.GetContent())) { - Maybe<float> lastSize = aAxis == eLogicalAxisBlock + Maybe<float> lastSize = aAxis == LogicalAxis::Block ? element->GetLastRememberedBSize() : element->GetLastRememberedISize(); if (lastSize && aFrame.HidesContent()) { @@ -3556,7 +3556,7 @@ Maybe<nscoord> ContainSizeAxes::ContainIntrinsicBSize( } const StyleContainIntrinsicSize& bSize = aFrame.StylePosition()->ContainIntrinsicBSize(aFrame.GetWritingMode()); - return Some(Resolve(bSize, aNoneValue, aFrame, eLogicalAxisBlock)); + return Some(Resolve(bSize, aNoneValue, aFrame, LogicalAxis::Block)); } Maybe<nscoord> ContainSizeAxes::ContainIntrinsicISize( @@ -3566,7 +3566,7 @@ Maybe<nscoord> ContainSizeAxes::ContainIntrinsicISize( } const StyleContainIntrinsicSize& iSize = aFrame.StylePosition()->ContainIntrinsicISize(aFrame.GetWritingMode()); - return Some(Resolve(iSize, aNoneValue, aFrame, eLogicalAxisInline)); + return Some(Resolve(iSize, aNoneValue, aFrame, LogicalAxis::Inline)); } nsSize ContainSizeAxes::ContainSize(const nsSize& aUncontainedSize, diff --git a/layout/style/res/forms.css b/layout/style/res/forms.css index 587534e9f3..044d460ad4 100644 --- a/layout/style/res/forms.css +++ b/layout/style/res/forms.css @@ -73,6 +73,8 @@ fieldset { label { cursor: default; + /* If you add declarations here, consider whether the select > label and file + * input label need them as well. */ } /* Default inputs, text inputs, and selects */ @@ -281,6 +283,7 @@ select > button { select > label { display: inline-block; overflow: clip; + cursor: unset; } option[label]::before { @@ -627,6 +630,7 @@ input[type=file] > label { min-inline-size: 12em; text-align: match-parent; + cursor: unset; color: unset; font-size: unset; letter-spacing: unset; diff --git a/layout/style/res/html.css b/layout/style/res/html.css index ff58ecd4d1..18dd1c4855 100644 --- a/layout/style/res/html.css +++ b/layout/style/res/html.css @@ -765,7 +765,7 @@ video > .caption-box { * The pseudo element won't inherit CSS styles from its direct parent, `::cue` * would actually inherit styles from video because it's video's pseudo element. * Therefore, we have to explicitly set some styles which are already defined - * in its parent element in vtt.jsm. + * in its parent element in vtt.sys.mjs. */ ::cue { color: rgba(255, 255, 255, 1); @@ -816,15 +816,21 @@ dialog::backdrop { background: rgba(0, 0, 0, 0.1); } +/* https://html.spec.whatwg.org/#the-marquee-element-2 */ marquee { - inline-size: -moz-available; display: inline-block; + text-align: initial; + overflow: hidden !important; + + /* See https://github.com/whatwg/html/issues/10249 */ + inline-size: -moz-available; vertical-align: text-bottom; - text-align: start; + white-space: nowrap; } marquee:is([direction="up"], [direction="down"]) { block-size: 200px; + white-space: unset; } /* Ruby */ diff --git a/layout/style/test/chrome/chrome-only-media-queries.js b/layout/style/test/chrome/chrome-only-media-queries.js index aaf313a526..d17976149b 100644 --- a/layout/style/test/chrome/chrome-only-media-queries.js +++ b/layout/style/test/chrome/chrome-only-media-queries.js @@ -31,4 +31,5 @@ const CHROME_ONLY_QUERIES = [ "(-moz-gtk-theme-family: adwaita)", "(-moz-gtk-theme-family: breeze)", "(-moz-gtk-theme-family: yaru)", + "(forced-colors: requested)", ]; diff --git a/layout/style/test/mochitest.toml b/layout/style/test/mochitest.toml index 54ad9736f2..cc5f26708f 100644 --- a/layout/style/test/mochitest.toml +++ b/layout/style/test/mochitest.toml @@ -6,16 +6,13 @@ prefs = [ "gfx.font_loader.delay=0", "layout.css.container-queries.enabled=true", "layout.css.individual-transform.enabled=true", - "layout.css.motion-path-ray.enabled=true", - "layout.css.motion-path-basic-shapes.enabled=true", - "layout.css.motion-path-coord-box.enabled=true", - "layout.css.motion-path-offset-position.enabled=true", "layout.css.motion-path-url.enabled=true", "layout.css.backdrop-filter.enabled=true", "layout.css.fit-content-function.enabled=true", "layout.css.scroll-driven-animations.enabled=true", "layout.css.animation-composition.enabled=true", "layout.css.basic-shape-rect.enabled=true", + "layout.css.basic-shape-shape.enabled=true", "layout.css.basic-shape-xywh.enabled=true", "layout.css.transform-box-content-stroke.enabled=true", "layout.css.transition-behavior.enabled=true", diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 2e8b4c71a3..c63d65926e 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -1035,6 +1035,36 @@ if (IsCSSPropertyPrefEnabled("layout.css.basic-shape-rect.enabled")) { ); } +var basicShapeShapeValues = []; +var basicShapeShapeValuesWithFillRule = []; +if (IsCSSPropertyPrefEnabled("layout.css.basic-shape-shape.enabled")) { + basicShapeShapeValuesWithFillRule.push( + "shape(evenodd from 0px 0px, line to 10px 10px)", + "shape(nonzero from 0px 0px, line to 10px 10px)" + ); + + basicShapeShapeValues.push( + "shape(from 0px 0%, line to 10px 10%)", + "shape(from 10px 10px, move by 10px 5px, line by 20px 40%, close)", + "shape(from 10px 10px, hline by 10px, vline to 5rem)", + "shape(from 10px 10px, vline by 5%, hline to 1vw)", + "shape(from 10px 10px, curve to 50px 20px via 10rem 1%)", + "shape(from 10px 10px, smooth to 50px 20px via 10rem 1%)", + "shape(from 10% 1rem, arc to 50px 1pt of 20% cw large rotate 25deg)" + ); + + // It's fine to include this for properties which don't support shape(), + // e.g. shape-outside, because they must reject these values. + basicShapeInvalidValues.push( + "shape()", + "shape(evenodd, from 0px 0px)", + "shape(from 0px 0px line to 10px 10px)", + "shape(from 0px 0px)", + "shape(close)", + "shape(nonzero, close)" + ); +} + if (/* mozGradientsEnabled */ true) { // Maybe one day :( // Extend gradient lists with valid/invalid moz-prefixed expressions: @@ -6841,6 +6871,130 @@ var gCSSProperties = { "left 10px top", ], }, + offset: { + domProp: "offset", + inherited: false, + type: CSS_TYPE_TRUE_SHORTHAND, + subproperties: [ + "offset-path", + "offset-distance", + "offset-rotate", + "offset-anchor", + "offset-position", + ], + initial_values: ["none"], + other_values: [ + "none 30deg reverse", + "none 50px reverse 30deg", + "none calc(10px + 20%) auto", + "none reverse", + "none / left center", + "path('M 0 0 H 1') -200% auto", + "path('M 0 0 H 1') -200%", + "path('M 0 0 H 1') 50px", + "path('M 0 0 H 1') auto", + "path('M 0 0 H 1') reverse 30deg 50px", + "path('M 0 0 H 1')", + "path('m 20 0 h 100') -7rad 8px / auto", + "path('m 0 30 v 100') -7rad 8px / left top", + "path('m 0 0 h 100') -7rad 8px", + "path('M 0 0 H 100') 100px 0deg", + "top right / top left", + "top right ray(45deg closest-side)", + "50% 50% ray(0rad farthest-side)", + ], + invalid_values: [ + "100px 0deg path('m 0 0 h 100')", + "30deg", + "auto 30deg 100px", + "auto / none", + "none /", + "none / 100px 20px 30deg", + "path('M 20 30 A 60 70 80') bottom", + "path('M 20 30 A 60 70 80') bottom top", + "path('M 20 30 A 60 70 80') 100px 200px", + "path('M 20 30 A 60 70 80') reverse auto", + "path('M 20 30 A 60 70 80') reverse 10px 30deg", + "path('M 20 30 A 60 70 80') /", + ], + }, + "offset-anchor": { + domProp: "offsetAnchor", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: ["auto"], + other_values: [ + "left bottom", + "center center", + "calc(20% + 10px) center", + "right 30em", + "10px 20%", + "left -10px top -20%", + "right 10% bottom 20em", + ], + invalid_values: ["none", "10deg", "left 10% top"], + }, + "offset-distance": { + domProp: "offsetDistance", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: ["0"], + other_values: ["10px", "10%", "190%", "-280%", "calc(30px + 40%)"], + invalid_values: ["none", "45deg"], + }, + "offset-path": { + domProp: "offsetPath", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: ["none"], + other_values: [ + "ray(0deg)", + "ray(45deg closest-side)", + "ray(0rad farthest-side)", + "ray(0.5turn closest-corner contain)", + "ray(200grad farthest-corner)", + "ray(sides 180deg)", + "ray(contain farthest-side 180deg)", + "ray(calc(180deg - 45deg) farthest-side)", + "ray(0deg at center center)", + "ray(at 10% 10% 1rad)", + ] + .concat(pathValues.other_values) + .concat(basicShapeOtherValues) + .concat(basicShapeXywhRectValues) + .concat(basicShapeShapeValues), + invalid_values: [ + "path('')", + "ray(closest-side)", + "ray(0deg, closest-side)", + "ray(contain 0deg closest-side contain)", + ].concat(pathValues.invalid_values), + }, + "offset-position": { + domProp: "offsetPosition", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: ["normal"], + other_values: [ + "auto", + "left bottom", + "center center", + "calc(20% + 10px) center", + "right 30em", + "10px 20%", + "left -10px top -20%", + "right 10% bottom 20em", + ], + invalid_values: ["none", "10deg", "left 10% top"], + }, + "offset-rotate": { + domProp: "offsetRotate", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: ["auto"], + other_values: ["reverse", "0deg", "0rad reverse", "-45deg", "5turn auto"], + invalid_values: ["none", "10px", "reverse 0deg reverse", "reverse auto"], + }, opacity: { domProp: "opacity", inherited: false, @@ -8827,7 +8981,9 @@ var gCSSProperties = { .concat(basicShapeSVGBoxValues) .concat(basicShapeOtherValues) .concat(basicShapeOtherValuesWithFillRule) - .concat(basicShapeXywhRectValues), + .concat(basicShapeXywhRectValues) + .concat(basicShapeShapeValues) + .concat(basicShapeShapeValuesWithFillRule), invalid_values: [ "path(nonzero)", "path(abs, 'M 10 10 L 10 10 z')", @@ -13409,158 +13565,10 @@ gCSSProperties["scrollbar-width"] = { invalid_values: ["1px"], }; -gCSSProperties["offset"] = { - domProp: "offset", - inherited: false, - type: CSS_TYPE_TRUE_SHORTHAND, - subproperties: [ - "offset-path", - "offset-distance", - "offset-rotate", - "offset-anchor", - ], - initial_values: ["none"], - other_values: [ - "none 30deg reverse", - "none 50px reverse 30deg", - "none calc(10px + 20%) auto", - "none reverse", - "none / left center", - "path('M 0 0 H 1') -200% auto", - "path('M 0 0 H 1') -200%", - "path('M 0 0 H 1') 50px", - "path('M 0 0 H 1') auto", - "path('M 0 0 H 1') reverse 30deg 50px", - "path('M 0 0 H 1')", - "path('m 20 0 h 100') -7rad 8px / auto", - "path('m 0 30 v 100') -7rad 8px / left top", - "path('m 0 0 h 100') -7rad 8px", - "path('M 0 0 H 100') 100px 0deg", - ], - invalid_values: [ - "100px 0deg path('m 0 0 h 100')", - "30deg", - "auto 30deg 100px", - "auto / none", - "none /", - "none / 100px 20px 30deg", - "path('M 20 30 A 60 70 80') bottom", - "path('M 20 30 A 60 70 80') bottom top", - "path('M 20 30 A 60 70 80') 100px 200px", - "path('M 20 30 A 60 70 80') reverse auto", - "path('M 20 30 A 60 70 80') reverse 10px 30deg", - "path('M 20 30 A 60 70 80') /", - ], -}; - -gCSSProperties["offset-path"] = { - domProp: "offsetPath", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: ["none"], - other_values: [...pathValues.other_values], - invalid_values: ["path('')"].concat(pathValues.invalid_values), -}; - -if (IsCSSPropertyPrefEnabled("layout.css.motion-path-ray.enabled")) { - gCSSProperties["offset-path"]["other_values"].push( - "ray(0deg)", - "ray(45deg closest-side)", - "ray(0rad farthest-side)", - "ray(0.5turn closest-corner contain)", - "ray(200grad farthest-corner)", - "ray(sides 180deg)", - "ray(contain farthest-side 180deg)", - "ray(calc(180deg - 45deg) farthest-side)", - "ray(0deg at center center)", - "ray(at 10% 10% 1rad)" - ); - - gCSSProperties["offset-path"]["invalid_values"].push( - "ray(closest-side)", - "ray(0deg, closest-side)", - "ray(contain 0deg closest-side contain)" - ); -} - -if (IsCSSPropertyPrefEnabled("layout.css.motion-path-basic-shapes.enabled")) { - gCSSProperties["offset-path"]["other_values"].push( - ...basicShapeOtherValues, - ...basicShapeXywhRectValues - ); -} - if (IsCSSPropertyPrefEnabled("layout.css.motion-path-url.enabled")) { gCSSProperties["offset-path"]["other_values"].push("url(#svgPath)"); } -gCSSProperties["offset-distance"] = { - domProp: "offsetDistance", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: ["0"], - other_values: ["10px", "10%", "190%", "-280%", "calc(30px + 40%)"], - invalid_values: ["none", "45deg"], -}; - -gCSSProperties["offset-rotate"] = { - domProp: "offsetRotate", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: ["auto"], - other_values: ["reverse", "0deg", "0rad reverse", "-45deg", "5turn auto"], - invalid_values: ["none", "10px", "reverse 0deg reverse", "reverse auto"], -}; - -gCSSProperties["offset-anchor"] = { - domProp: "offsetAnchor", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: ["auto"], - other_values: [ - "left bottom", - "center center", - "calc(20% + 10px) center", - "right 30em", - "10px 20%", - "left -10px top -20%", - "right 10% bottom 20em", - ], - invalid_values: ["none", "10deg", "left 10% top"], -}; - -if ( - IsCSSPropertyPrefEnabled("layout.css.motion-path-offset-position.enabled") -) { - gCSSProperties["offset"]["subproperties"].push("offset-position"); - gCSSProperties["offset"]["other_values"].push("top right / top left"); - - if (IsCSSPropertyPrefEnabled("layout.css.motion-path-ray.enabled")) { - gCSSProperties["offset"]["other_values"].push( - "top right ray(45deg closest-side)", - "50% 50% ray(0rad farthest-side)" - ); - } - - gCSSProperties["offset-position"] = { - domProp: "offsetPosition", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: ["normal"], - other_values: [ - "auto", - "left bottom", - "center center", - "calc(20% + 10px) center", - "right 30em", - "10px 20%", - "left -10px top -20%", - "right 10% bottom 20em", - ], - invalid_values: ["none", "10deg", "left 10% top"], - }; -} - { let linear_function_other_values = [ "linear(0, 1)", diff --git a/layout/style/test/test_hover_quirk.html b/layout/style/test/test_hover_quirk.html index 61e19f2a60..7a78185178 100644 --- a/layout/style/test/test_hover_quirk.html +++ b/layout/style/test/test_hover_quirk.html @@ -54,6 +54,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=783213 #dynamic-test:hover > * { background: rgb(0, 255, 0); } + + #dynamic-test-2 :is(button,input,a){ + background-color:yellow !important; + } + + #dynamic-test-2 :is(button,input,a):hover{ + background-color:lime !important; + } + + #dynamic-test-2 :is(button,input):focus{ + background-color:skyblue !important; + } </style> <script src="/tests/SimpleTest/SimpleTest.js"></script> <script src="/tests/SimpleTest/EventUtils.js"></script> @@ -97,6 +109,21 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=783213 is(getComputedStyle(document.getElementById('should-be-green-on-hover')).backgroundColor, "rgb(0, 255, 0)", "Dynamic change should invalidate properly"); + + synthesizeMouseAtCenter(document.getElementById('button'), {type: "mousemove"}); + is(getComputedStyle(document.getElementById('button')).backgroundColor, + "rgb(0, 255, 0)", + "Button hover should be green"); + + synthesizeMouseAtCenter(document.getElementById('input'), {type: "mousemove"}); + is(getComputedStyle(document.getElementById('input')).backgroundColor, + "rgb(0, 255, 0)", + "Input hover should be green"); + + synthesizeMouseAtCenter(document.getElementById('link-2'), {type: "mousemove"}); + is(getComputedStyle(document.getElementById('link-2')).backgroundColor, + "rgb(0, 255, 0)", + "Link hover should be green"); SimpleTest.finish(); }); </script> @@ -113,6 +140,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=783213 <a id="link" href="#">Link<span class="child"></span></a><br> <div id="div" class="parent">Div <span><span class="child"></span></span></div><br> </div> + <div id="dynamic-test-2"> + <button id="button">Button</button> + <input id="input" value="Input"> + <a id="link-2"href="">Link</a> + </div> <pre id="test"></pre> </body> </html> diff --git a/layout/style/test/test_non_content_accessible_pseudos.html b/layout/style/test/test_non_content_accessible_pseudos.html index 81493b1a4a..5f2d15d6a2 100644 --- a/layout/style/test/test_non_content_accessible_pseudos.html +++ b/layout/style/test/test_non_content_accessible_pseudos.html @@ -30,7 +30,6 @@ const NON_CONTENT_ACCESIBLE_PSEUDOS = [ ":-moz-dir-attr-rtl", ":-moz-dir-attr-like-auto", ":-moz-autofill-preview", - ":-moz-lwtheme", ":-moz-is-html", ":-moz-locale-dir(rtl)", ":-moz-locale-dir(ltr)", diff --git a/layout/style/test/test_selectors.html b/layout/style/test/test_selectors.html index d688139d3c..684e9d6524 100644 --- a/layout/style/test/test_selectors.html +++ b/layout/style/test/test_selectors.html @@ -1077,7 +1077,6 @@ function runTests() { test_balanced_unparseable(":dir"); // Test chrome-only -moz-lwtheme - test_balanced_unparseable(":-moz-lwtheme"); test_balanced_unparseable(":-moz-broken"); test_balanced_unparseable(":-moz-tree-row(selected)"); diff --git a/layout/style/test/test_style_struct_copy_constructors.html b/layout/style/test/test_style_struct_copy_constructors.html index 95f727a58d..bce5a4e32c 100644 --- a/layout/style/test/test_style_struct_copy_constructors.html +++ b/layout/style/test/test_style_struct_copy_constructors.html @@ -64,6 +64,12 @@ for (var prop in gCSSProperties) { } /** Test using inheritance **/ + +// TODO(bug 1887221): Zoom right now doesn't apply to explicitly inherited +// values, so remove it to get consistent results. +gRule1.style.removeProperty("zoom"); +gRule2.style.removeProperty("zoom"); + for (var prop in gCSSProperties) { var info = gCSSProperties[prop]; if (info.inherited && !("subproperties" in info)) { @@ -79,14 +85,6 @@ for (var prop in gCSSProperties) { } } -for (var prop in gCSSProperties) { - var info = gCSSProperties[prop]; - if (!("subproperties" in info)) { - gRule1.style.removeProperty(prop); - gRule2.style.removeProperty(prop); - } -} - </script> </pre> </body> diff --git a/layout/svg/CSSClipPathInstance.cpp b/layout/svg/CSSClipPathInstance.cpp index 77bde2bb54..a8e0306d3e 100644 --- a/layout/svg/CSSClipPathInstance.cpp +++ b/layout/svg/CSSClipPathInstance.cpp @@ -66,7 +66,7 @@ bool CSSClipPathInstance::HitTestBasicShapeOrPathClip(nsIFrame* aFrame, RefPtr<Path> path = instance.CreateClipPath( drawTarget, SVGUtils::GetCSSPxToDevPxMatrix(aFrame)); float pixelRatio = float(AppUnitsPerCSSPixel()) / - aFrame->PresContext()->AppUnitsPerDevPixel(); + float(aFrame->PresContext()->AppUnitsPerDevPixel()); return path && path->ContainsPoint(ToPoint(aPoint) * pixelRatio, Matrix()); } @@ -121,8 +121,10 @@ already_AddRefed<Path> CSSClipPathInstance::CreateClipPath( return CreateClipPathPolygon(aDrawTarget, r); case StyleBasicShape::Tag::Rect: return CreateClipPathInset(aDrawTarget, r); - case StyleBasicShape::Tag::Path: - return CreateClipPathPath(aDrawTarget, r); + case StyleBasicShape::Tag::PathOrShape: + return basicShape.AsPathOrShape().IsPath() + ? CreateClipPathPath(aDrawTarget, r) + : CreateClipPathShape(aDrawTarget, r); default: MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected shape type"); } @@ -175,18 +177,41 @@ already_AddRefed<Path> CSSClipPathInstance::CreateClipPathInset( already_AddRefed<Path> CSSClipPathInstance::CreateClipPathPath( DrawTarget* aDrawTarget, const nsRect& aRefBox) { - const auto& path = mClipPathStyle.AsShape()._0->AsPath(); + const auto& path = mClipPathStyle.AsShape()._0->AsPathOrShape().AsPath(); RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder( path.fill == StyleFillRule::Nonzero ? FillRule::FILL_WINDING : FillRule::FILL_EVEN_ODD); - nscoord appUnitsPerDevPixel = + const nscoord appUnitsPerDevPixel = mTargetFrame->PresContext()->AppUnitsPerDevPixel(); - float scale = float(AppUnitsPerCSSPixel()) / appUnitsPerDevPixel; - Point offset = Point(aRefBox.x, aRefBox.y) / appUnitsPerDevPixel; - + const Point offset = + LayoutDevicePoint::FromAppUnits(aRefBox.TopLeft(), appUnitsPerDevPixel) + .ToUnknownPoint(); + const float scale = mTargetFrame->Style()->EffectiveZoom().Zoom( + float(AppUnitsPerCSSPixel()) / float(appUnitsPerDevPixel)); return SVGPathData::BuildPath(path.path._0.AsSpan(), builder, - StyleStrokeLinecap::Butt, 0.0, offset, scale); + StyleStrokeLinecap::Butt, 0.0, {}, offset, + scale); +} + +already_AddRefed<Path> CSSClipPathInstance::CreateClipPathShape( + DrawTarget* aDrawTarget, const nsRect& aRefBox) { + const auto& shape = mClipPathStyle.AsShape()._0->AsPathOrShape().AsShape(); + + RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder( + shape.fill == StyleFillRule::Nonzero ? FillRule::FILL_WINDING + : FillRule::FILL_EVEN_ODD); + const nscoord appUnitsPerDevPixel = + mTargetFrame->PresContext()->AppUnitsPerDevPixel(); + const CSSSize basis = CSSSize::FromAppUnits(aRefBox.Size()); + const Point offset = + LayoutDevicePoint::FromAppUnits(aRefBox.TopLeft(), appUnitsPerDevPixel) + .ToUnknownPoint(); + const float scale = mTargetFrame->Style()->EffectiveZoom().Zoom( + float(AppUnitsPerCSSPixel()) / float(appUnitsPerDevPixel)); + return SVGPathData::BuildPath(shape.commands.AsSpan(), builder, + StyleStrokeLinecap::Butt, 0.0, basis, offset, + scale); } } // namespace mozilla diff --git a/layout/svg/CSSClipPathInstance.h b/layout/svg/CSSClipPathInstance.h index 2d1e16c62f..2cec8c125f 100644 --- a/layout/svg/CSSClipPathInstance.h +++ b/layout/svg/CSSClipPathInstance.h @@ -58,6 +58,9 @@ class MOZ_STACK_CLASS CSSClipPathInstance { already_AddRefed<Path> CreateClipPathPath(DrawTarget* aDrawTarget, const nsRect& aRefBox); + already_AddRefed<Path> CreateClipPathShape(DrawTarget* aDrawTarget, + const nsRect& aRefBox); + /** * The frame for the element that is currently being clipped. */ diff --git a/layout/svg/SVGAFrame.cpp b/layout/svg/SVGAFrame.cpp index 02ff68d7e7..3d09cdc3f5 100644 --- a/layout/svg/SVGAFrame.cpp +++ b/layout/svg/SVGAFrame.cpp @@ -82,20 +82,6 @@ nsresult SVGAFrame::AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, NotifySVGChanged(TRANSFORM_CHANGED); } - // Currently our SMIL implementation does not modify the DOM attributes. Once - // we implement the SVG 2 SMIL behaviour this can be removed - // SVGAElement::SetAttr/UnsetAttr's ResetLinkState() call will be sufficient. - if (aModType == dom::MutationEvent_Binding::SMIL && - aAttribute == nsGkAtoms::href && - (aNameSpaceID == kNameSpaceID_None || - aNameSpaceID == kNameSpaceID_XLink)) { - auto* content = static_cast<dom::SVGAElement*>(GetContent()); - - // SMIL may change whether an <a> element is a link, in which case we will - // need to update the link state. - content->ResetLinkState(true, content->ElementHasHref()); - } - return NS_OK; } diff --git a/layout/svg/SVGContextPaint.cpp b/layout/svg/SVGContextPaint.cpp index 0d7a610df9..e135ea2db3 100644 --- a/layout/svg/SVGContextPaint.cpp +++ b/layout/svg/SVGContextPaint.cpp @@ -80,7 +80,7 @@ bool SVGContextPaint::IsAllowedForImageFromURI(nsIURI* aURI) { // Only allowed for extensions that have the // internal:svgContextPropertiesAllowed permission (added internally from // to Mozilla-owned extensions, see `isMozillaExtension` function - // defined in Extension.jsm for the exact criteria). + // defined in Extension.sys.mjs for the exact criteria). return addonPolicy->HasPermission( nsGkAtoms::svgContextPropertiesAllowedPermission); } diff --git a/layout/svg/SVGFEImageFrame.cpp b/layout/svg/SVGFEImageFrame.cpp index 50fb42cd68..d89ed566f1 100644 --- a/layout/svg/SVGFEImageFrame.cpp +++ b/layout/svg/SVGFEImageFrame.cpp @@ -121,24 +121,6 @@ nsresult SVGFEImageFrame::AttributeChanged(int32_t aNameSpaceID, SVGObserverUtils::InvalidateRenderingObservers(GetParent()); } - // Currently our SMIL implementation does not modify the DOM attributes. Once - // we implement the SVG 2 SMIL behaviour this can be removed - // SVGFEImageElement::AfterSetAttr's implementation will be sufficient. - if (aModType == MutationEvent_Binding::SMIL && - aAttribute == nsGkAtoms::href && - (aNameSpaceID == kNameSpaceID_XLink || - aNameSpaceID == kNameSpaceID_None)) { - bool hrefIsSet = - element->mStringAttributes[SVGFEImageElement::HREF].IsExplicitlySet() || - element->mStringAttributes[SVGFEImageElement::XLINK_HREF] - .IsExplicitlySet(); - if (hrefIsSet) { - element->LoadSVGImage(true, true); - } else { - element->CancelImageRequests(true); - } - } - return nsIFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType); } diff --git a/layout/svg/SVGGradientFrame.cpp b/layout/svg/SVGGradientFrame.cpp index 92558cefcd..be6f395cda 100644 --- a/layout/svg/SVGGradientFrame.cpp +++ b/layout/svg/SVGGradientFrame.cpp @@ -244,8 +244,10 @@ class MOZ_STACK_CLASS SVGColorStopInterpolator public: SVGColorStopInterpolator( gfxPattern* aGradient, const nsTArray<ColorStop>& aStops, - const StyleColorInterpolationMethod& aStyleColorInterpolationMethod) - : ColorStopInterpolator(aStops, aStyleColorInterpolationMethod), + const StyleColorInterpolationMethod& aStyleColorInterpolationMethod, + bool aExtendLastStop) + : ColorStopInterpolator(aStops, aStyleColorInterpolationMethod, + aExtendLastStop), mGradient(aGradient) {} void CreateStop(float aPosition, DeviceColor aColor) { @@ -327,7 +329,8 @@ already_AddRefed<gfxPattern> SVGGradientFrame::GetPaintServerPattern( if (StyleSVG()->mColorInterpolation == StyleColorInterpolation::Linearrgb) { static constexpr auto interpolationMethod = StyleColorInterpolationMethod{ StyleColorSpace::SrgbLinear, StyleHueInterpolationMethod::Shorter}; - SVGColorStopInterpolator interpolator(gradient, stops, interpolationMethod); + SVGColorStopInterpolator interpolator(gradient, stops, interpolationMethod, + false); interpolator.CreateStops(); } else { // setup standard sRGB stops diff --git a/layout/svg/SVGImageFrame.cpp b/layout/svg/SVGImageFrame.cpp index 242ee6e25e..35693e87c0 100644 --- a/layout/svg/SVGImageFrame.cpp +++ b/layout/svg/SVGImageFrame.cpp @@ -191,26 +191,6 @@ nsresult SVGImageFrame::AttributeChanged(int32_t aNameSpaceID, } } - // Currently our SMIL implementation does not modify the DOM attributes. Once - // we implement the SVG 2 SMIL behaviour this can be removed - // SVGImageElement::AfterSetAttr's implementation will be sufficient. - if (aModType == MutationEvent_Binding::SMIL && - aAttribute == nsGkAtoms::href && - (aNameSpaceID == kNameSpaceID_XLink || - aNameSpaceID == kNameSpaceID_None)) { - SVGImageElement* element = static_cast<SVGImageElement*>(GetContent()); - - bool hrefIsSet = - element->mStringAttributes[SVGImageElement::HREF].IsExplicitlySet() || - element->mStringAttributes[SVGImageElement::XLINK_HREF] - .IsExplicitlySet(); - if (hrefIsSet) { - element->LoadSVGImage(true, true); - } else { - element->CancelImageRequests(true); - } - } - return NS_OK; } diff --git a/layout/svg/SVGOuterSVGFrame.cpp b/layout/svg/SVGOuterSVGFrame.cpp index ea0879c0c2..d88327f059 100644 --- a/layout/svg/SVGOuterSVGFrame.cpp +++ b/layout/svg/SVGOuterSVGFrame.cpp @@ -126,20 +126,14 @@ NS_QUERYFRAME_TAIL_INHERITING(SVGDisplayContainerFrame) /* virtual */ nscoord SVGOuterSVGFrame::GetMinISize(gfxContext* aRenderingContext) { - nscoord result; - DISPLAY_MIN_INLINE_SIZE(this, result); - // If this ever changes to return something other than zero, then // nsSubDocumentFrame::GetMinISize will also need to change. - result = nscoord(0); - - return result; + return 0; } /* virtual */ nscoord SVGOuterSVGFrame::GetPrefISize(gfxContext* aRenderingContext) { nscoord result; - DISPLAY_PREF_INLINE_SIZE(this, result); SVGSVGElement* svg = static_cast<SVGSVGElement*>(GetContent()); WritingMode wm = GetWritingMode(); @@ -325,7 +319,6 @@ void SVGOuterSVGFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("SVGOuterSVGFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); NS_FRAME_TRACE( NS_FRAME_TRACE_CALLS, diff --git a/layout/svg/SVGUseFrame.cpp b/layout/svg/SVGUseFrame.cpp index c655f7b24f..e356895208 100644 --- a/layout/svg/SVGUseFrame.cpp +++ b/layout/svg/SVGUseFrame.cpp @@ -42,19 +42,6 @@ void SVGUseFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, SVGGFrame::Init(aContent, aParent, aPrevInFlow); } -nsresult SVGUseFrame::AttributeChanged(int32_t aNamespaceID, nsAtom* aAttribute, - int32_t aModType) { - // Currently our SMIL implementation does not modify the DOM attributes. Once - // we implement the SVG 2 SMIL behaviour this can be removed - // SVGUseElement::AfterSetAttr's implementation will be sufficient. - if (aModType == MutationEvent_Binding::SMIL) { - auto* content = SVGUseElement::FromNode(GetContent()); - content->ProcessAttributeChange(aNamespaceID, aAttribute); - } - - return SVGGFrame::AttributeChanged(aNamespaceID, aAttribute, aModType); -} - void SVGUseFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) { SVGGFrame::DidSetComputedStyle(aOldComputedStyle); diff --git a/layout/svg/SVGUseFrame.h b/layout/svg/SVGUseFrame.h index b72d29247a..a528522991 100644 --- a/layout/svg/SVGUseFrame.h +++ b/layout/svg/SVGUseFrame.h @@ -41,8 +41,6 @@ class SVGUseFrame final : public SVGGFrame { void DimensionAttributeChanged(bool aHadValidDimensions, bool aAttributeIsUsed); - nsresult AttributeChanged(int32_t aNamespaceID, nsAtom* aAttribute, - int32_t aModType) override; void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override; #ifdef DEBUG_FRAME_DUMP diff --git a/layout/tables/BasicTableLayoutStrategy.cpp b/layout/tables/BasicTableLayoutStrategy.cpp index 5cb890c234..b6fe51db59 100644 --- a/layout/tables/BasicTableLayoutStrategy.cpp +++ b/layout/tables/BasicTableLayoutStrategy.cpp @@ -37,7 +37,6 @@ BasicTableLayoutStrategy::~BasicTableLayoutStrategy() = default; /* virtual */ nscoord BasicTableLayoutStrategy::GetMinISize(gfxContext* aRenderingContext) { - DISPLAY_MIN_INLINE_SIZE(mTableFrame, mMinISize); if (mMinISize == NS_INTRINSIC_ISIZE_UNKNOWN) { ComputeIntrinsicISizes(aRenderingContext); } @@ -47,7 +46,6 @@ nscoord BasicTableLayoutStrategy::GetMinISize(gfxContext* aRenderingContext) { /* virtual */ nscoord BasicTableLayoutStrategy::GetPrefISize(gfxContext* aRenderingContext, bool aComputingSize) { - DISPLAY_PREF_INLINE_SIZE(mTableFrame, mPrefISize); NS_ASSERTION((mPrefISize == NS_INTRINSIC_ISIZE_UNKNOWN) == (mPrefISizePctExpand == NS_INTRINSIC_ISIZE_UNKNOWN), "dirtyness out of sync"); @@ -97,18 +95,10 @@ static CellISizeInfo GetISizeInfo(gfxContext* aRenderingContext, // XXX Should we ignore percentage padding? nsIFrame::IntrinsicSizeOffsetData offsets = aFrame->IntrinsicISizeOffsets(); - - // In quirks mode, table cell isize should be content-box, - // but bsize should be border box. - // Because of this historic anomaly, we do not use quirk.css. - // (We can't specify one value of box-sizing for isize and another - // for bsize). - // For this reason, we also do not use box-sizing for just one of - // them, as this may be confusing. - if (isQuirks || stylePos->mBoxSizing == StyleBoxSizing::Content) { + if (stylePos->mBoxSizing == StyleBoxSizing::Content) { boxSizingToBorderEdge = offsets.padding + offsets.border; } else { - // StyleBoxSizing::Border and standards-mode + // StyleBoxSizing::Border minCoord += offsets.padding + offsets.border; prefCoord += offsets.padding + offsets.border; } diff --git a/layout/tables/FixedTableLayoutStrategy.cpp b/layout/tables/FixedTableLayoutStrategy.cpp index 8d74e3ba12..5eda3b001e 100644 --- a/layout/tables/FixedTableLayoutStrategy.cpp +++ b/layout/tables/FixedTableLayoutStrategy.cpp @@ -32,7 +32,6 @@ FixedTableLayoutStrategy::~FixedTableLayoutStrategy() = default; /* virtual */ nscoord FixedTableLayoutStrategy::GetMinISize(gfxContext* aRenderingContext) { - DISPLAY_MIN_INLINE_SIZE(mTableFrame, mMinISize); if (mMinISize != NS_INTRINSIC_ISIZE_UNKNOWN) { return mMinISize; } @@ -119,9 +118,7 @@ nscoord FixedTableLayoutStrategy::GetPrefISize(gfxContext* aRenderingContext, // algorithm to find the narrowest inline size that would hold all of // those intrinsic inline sizes), but it wouldn't be compatible with // other browsers. - nscoord result = nscoord_MAX; - DISPLAY_PREF_INLINE_SIZE(mTableFrame, result); - return result; + return nscoord_MAX; } /* virtual */ diff --git a/layout/tables/celldata.h b/layout/tables/celldata.h index 681f0e9f28..22cdb4217d 100644 --- a/layout/tables/celldata.h +++ b/layout/tables/celldata.h @@ -347,7 +347,7 @@ inline BCData::BCData() { SetBStartStart(true); SetIStartStart(true); mIStartSize = mCornerSubSize = mBStartSize = 0; - mCornerSide = mozilla::eLogicalSideBStart; + mCornerSide = static_cast<uint8_t>(mozilla::LogicalSide::BStart); mCornerBevel = false; } @@ -393,7 +393,7 @@ inline BCPixelSize BCData::GetCorner(mozilla::LogicalSide& aOwnerSide, inline void BCData::SetCorner(BCPixelSize aSubSize, mozilla::LogicalSide aOwnerSide, bool aBevel) { mCornerSubSize = aSubSize; - mCornerSide = aOwnerSide; + mCornerSide = static_cast<uint8_t>(aOwnerSide); mCornerBevel = aBevel; } diff --git a/layout/tables/nsCellMap.cpp b/layout/tables/nsCellMap.cpp index 7c29baa5b0..60496d3ae0 100644 --- a/layout/tables/nsCellMap.cpp +++ b/layout/tables/nsCellMap.cpp @@ -678,7 +678,8 @@ void nsTableCellMap::Dump(char* aString) const { printf("l=%d%X%d ", int32_t(size), owner, segStart); } else { size = cd.GetCorner(side, bevel); - printf("c=%d%X%d ", int32_t(size), side, bevel); + printf("c=%d%hhX%d ", int32_t(size), static_cast<uint8_t>(side), + bevel); } } BCData& cd = mBCInfo->mBEndIEndCorner; @@ -690,7 +691,7 @@ void nsTableCellMap::Dump(char* aString) const { printf("l=%d%X%d ", int32_t(size), owner, segStart); } else { size = cd.GetCorner(side, bevel); - printf("c=%d%X%d ", int32_t(size), side, bevel); + printf("c=%d%hhX%d ", int32_t(size), static_cast<uint8_t>(side), bevel); } } printf("\n"); @@ -818,7 +819,7 @@ bool nsTableCellMap::RowHasSpanningCells(int32_t aRowIndex, return false; } -// FIXME: The only value callers pass for aSide is eLogicalSideBEnd. +// FIXME: The only value callers pass for aSide is LogicalSide::BEnd. // Consider removing support for the other three values. void nsTableCellMap::ResetBStartStart(LogicalSide aSide, nsCellMap& aCellMap, uint32_t aRowGroupStart, @@ -829,16 +830,16 @@ void nsTableCellMap::ResetBStartStart(LogicalSide aSide, nsCellMap& aCellMap, BCData* bcData = nullptr; switch (aSide) { - case eLogicalSideBEnd: + case LogicalSide::BEnd: aRowIndex++; [[fallthrough]]; - case eLogicalSideBStart: + case LogicalSide::BStart: cellData = (BCCellData*)aCellMap.GetDataAt(aRowIndex - aRowGroupStart, aColIndex); if (cellData) { bcData = &cellData->mData; } else { - NS_ASSERTION(aSide == eLogicalSideBEnd, "program error"); + NS_ASSERTION(aSide == LogicalSide::BEnd, "program error"); // try the next row group nsCellMap* cellMap = aCellMap.GetNextSibling(); if (cellMap) { @@ -851,16 +852,16 @@ void nsTableCellMap::ResetBStartStart(LogicalSide aSide, nsCellMap& aCellMap, } } break; - case eLogicalSideIEnd: + case LogicalSide::IEnd: aColIndex++; [[fallthrough]]; - case eLogicalSideIStart: + case LogicalSide::IStart: cellData = (BCCellData*)aCellMap.GetDataAt(aRowIndex - aRowGroupStart, aColIndex); if (cellData) { bcData = &cellData->mData; } else { - NS_ASSERTION(aSide == eLogicalSideIEnd, "program error"); + NS_ASSERTION(aSide == LogicalSide::IEnd, "program error"); bcData = GetIEndMostBorder(aRowIndex); } break; @@ -890,11 +891,11 @@ void nsTableCellMap::SetBCBorderEdge(LogicalSide aSide, nsCellMap& aCellMap, bool changed; switch (aSide) { - case eLogicalSideBEnd: + case LogicalSide::BEnd: rgYPos++; yPos++; [[fallthrough]]; - case eLogicalSideBStart: + case LogicalSide::BStart: lastIndex = xPos + aLength - 1; for (xIndex = xPos; xIndex <= lastIndex; xIndex++) { changed = aChanged && (xIndex == xPos); @@ -908,7 +909,7 @@ void nsTableCellMap::SetBCBorderEdge(LogicalSide aSide, nsCellMap& aCellMap, false, 0, damageArea); if (!cellData) ABORT0(); } else { - NS_ASSERTION(aSide == eLogicalSideBEnd, "program error"); + NS_ASSERTION(aSide == LogicalSide::BEnd, "program error"); // try the next non empty row group nsCellMap* cellMap = aCellMap.GetNextSibling(); while (cellMap && (0 == cellMap->GetRowCount())) { @@ -935,10 +936,10 @@ void nsTableCellMap::SetBCBorderEdge(LogicalSide aSide, nsCellMap& aCellMap, NS_ERROR("Cellmap: BStart edge not found"); } break; - case eLogicalSideIEnd: + case LogicalSide::IEnd: xPos++; [[fallthrough]]; - case eLogicalSideIStart: + case LogicalSide::IStart: // since bStart, bEnd borders were set, there should already be a cellData // entry lastIndex = rgYPos + aLength - 1; @@ -948,7 +949,7 @@ void nsTableCellMap::SetBCBorderEdge(LogicalSide aSide, nsCellMap& aCellMap, if (cellData) { cellData->mData.SetIStartEdge(aOwner, aSize, changed); } else { - NS_ASSERTION(aSide == eLogicalSideIEnd, "program error"); + NS_ASSERTION(aSide == LogicalSide::IEnd, "program error"); BCData* bcData = GetIEndMostBorder(yIndex + aCellMapStart); if (bcData) { bcData->SetIStartEdge(aOwner, aSize, changed); @@ -2225,7 +2226,8 @@ void nsCellMap::Dump(bool aIsBorderCollapse) const { printf("l=%d%d%d ", int32_t(size), owner, segStart); } else { size = cd->mData.GetCorner(side, bevel); - printf("c=%d%d%d ", int32_t(size), side, bevel); + printf("c=%d%hhu%d ", int32_t(size), static_cast<uint8_t>(side), + bevel); } } } diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index 6eb1c3146a..fdfa5e305e 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -48,9 +48,6 @@ nsTableCellFrame::nsTableCellFrame(ComputedStyle* aStyle, nsTableFrame* aTableFrame, ClassID aID) : nsContainerFrame(aStyle, aTableFrame->PresContext(), aID), mDesiredSize(aTableFrame->GetWritingMode()) { - mColIndex = 0; - mPriorAvailISize = 0; - SetContentEmpty(false); } @@ -392,9 +389,14 @@ LogicalSides nsTableCellFrame::GetLogicalSkipSides() const { /* virtual */ nsMargin nsTableCellFrame::GetBorderOverflow() { return nsMargin(0, 0, 0, 0); } -// Align the cell's child frame within the cell +void nsTableCellFrame::BlockDirAlignChild( + WritingMode aWM, nscoord aMaxAscent, + ForceAlignTopForTableCell aForceAlignTop) { + MOZ_ASSERT(aForceAlignTop != ForceAlignTopForTableCell::Yes || + PresContext()->IsPaginated(), + "We shouldn't force table-cells to do 'vertical-align:top' if " + "we're not in printing!"); -void nsTableCellFrame::BlockDirAlignChild(WritingMode aWM, nscoord aMaxAscent) { /* It's the 'border-collapse' on the table that matters */ const LogicalMargin border = GetLogicalUsedBorder(GetWritingMode()) .ApplySkipSides(GetLogicalSkipSides()) @@ -413,8 +415,11 @@ void nsTableCellFrame::BlockDirAlignChild(WritingMode aWM, nscoord aMaxAscent) { nscoord childBSize = kidRect.BSize(aWM); // Vertically align the child + const auto verticalAlign = aForceAlignTop == ForceAlignTopForTableCell::Yes + ? StyleVerticalAlignKeyword::Top + : GetVerticalAlign(); nscoord kidBStart = 0; - switch (GetVerticalAlign()) { + switch (verticalAlign) { case StyleVerticalAlignKeyword::Baseline: if (!GetContentEmpty()) { // Align the baselines of the child frame with the baselines of @@ -590,26 +595,18 @@ nsIScrollableFrame* nsTableCellFrame::GetScrollTargetFrame() const { /* virtual */ nscoord nsTableCellFrame::GetMinISize(gfxContext* aRenderingContext) { - nscoord result = 0; - DISPLAY_MIN_INLINE_SIZE(this, result); - nsIFrame* inner = mFrames.FirstChild(); - result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, inner, - IntrinsicISizeType::MinISize, - nsLayoutUtils::IGNORE_PADDING); - return result; + return nsLayoutUtils::IntrinsicForContainer(aRenderingContext, inner, + IntrinsicISizeType::MinISize, + nsLayoutUtils::IGNORE_PADDING); } /* virtual */ nscoord nsTableCellFrame::GetPrefISize(gfxContext* aRenderingContext) { - nscoord result = 0; - DISPLAY_PREF_INLINE_SIZE(this, result); - nsIFrame* inner = mFrames.FirstChild(); - result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, inner, - IntrinsicISizeType::PrefISize, - nsLayoutUtils::IGNORE_PADDING); - return result; + return nsLayoutUtils::IntrinsicForContainer(aRenderingContext, inner, + IntrinsicISizeType::PrefISize, + nsLayoutUtils::IGNORE_PADDING); } /* virtual */ nsIFrame::IntrinsicSizeOffsetData @@ -675,7 +672,6 @@ void nsTableCellFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsTableCellFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); if (aReflowInput.mFlags.mSpecialBSizeReflow) { @@ -708,14 +704,12 @@ void nsTableCellFrame::Reflow(nsPresContext* aPresContext, if (aReflowInput.mFlags.mSpecialBSizeReflow) { const_cast<ReflowInput&>(aReflowInput) .SetComputedBSize(BSize(wm) - bp.BStartEnd(wm)); - DISPLAY_REFLOW_CHANGE(); } else { const nscoord computedUnpaginatedBSize = CalcUnpaginatedBSize(*this, *tableFrame, bp.BStartEnd(wm)); if (computedUnpaginatedBSize > 0) { const_cast<ReflowInput&>(aReflowInput) .SetComputedBSize(computedUnpaginatedBSize); - DISPLAY_REFLOW_CHANGE(); } } } @@ -977,11 +971,11 @@ LogicalMargin nsBCTableCellFrame::GetBorderWidth(WritingMode aWM) const { BCPixelSize nsBCTableCellFrame::GetBorderWidth(LogicalSide aSide) const { switch (aSide) { - case eLogicalSideBStart: + case LogicalSide::BStart: return BC_BORDER_END_HALF(mBStartBorder); - case eLogicalSideIEnd: + case LogicalSide::IEnd: return BC_BORDER_START_HALF(mIEndBorder); - case eLogicalSideBEnd: + case LogicalSide::BEnd: return BC_BORDER_START_HALF(mBEndBorder); default: return BC_BORDER_END_HALF(mIStartBorder); @@ -990,13 +984,13 @@ BCPixelSize nsBCTableCellFrame::GetBorderWidth(LogicalSide aSide) const { void nsBCTableCellFrame::SetBorderWidth(LogicalSide aSide, BCPixelSize aValue) { switch (aSide) { - case eLogicalSideBStart: + case LogicalSide::BStart: mBStartBorder = aValue; break; - case eLogicalSideIEnd: + case LogicalSide::IEnd: mIEndBorder = aValue; break; - case eLogicalSideBEnd: + case LogicalSide::BEnd: mBEndBorder = aValue; break; default: diff --git a/layout/tables/nsTableCellFrame.h b/layout/tables/nsTableCellFrame.h index f9b6f3ccac..ae1a881819 100644 --- a/layout/tables/nsTableCellFrame.h +++ b/layout/tables/nsTableCellFrame.h @@ -34,9 +34,6 @@ class PresShell; class nsTableCellFrame : public nsContainerFrame, public nsITableCellLayout, public nsIPercentBSizeObserver { - typedef mozilla::gfx::DrawTarget DrawTarget; - typedef mozilla::image::ImgDrawResult ImgDrawResult; - friend nsTableCellFrame* NS_NewTableCellFrame(mozilla::PresShell* aPresShell, ComputedStyle* aStyle, nsTableFrame* aTableFrame); @@ -44,11 +41,6 @@ class nsTableCellFrame : public nsContainerFrame, nsTableCellFrame(ComputedStyle* aStyle, nsTableFrame* aTableFrame) : nsTableCellFrame(aStyle, aTableFrame, kClassID) {} - protected: - typedef mozilla::WritingMode WritingMode; - typedef mozilla::LogicalSide LogicalSide; - typedef mozilla::LogicalMargin LogicalMargin; - public: NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS(nsTableCellFrame) @@ -122,7 +114,9 @@ class nsTableCellFrame : public nsContainerFrame, nsresult GetFrameName(nsAString& aResult) const override; #endif - void BlockDirAlignChild(mozilla::WritingMode aWM, nscoord aMaxAscent); + // Align the cell's child frame within the cell. + void BlockDirAlignChild(mozilla::WritingMode aWM, nscoord aMaxAscent, + mozilla::ForceAlignTopForTableCell aForceAlignTop); /* * Get the value of vertical-align adjusted for CSS 2's rules for a @@ -193,20 +187,24 @@ class nsTableCellFrame : public nsContainerFrame, void SetColIndex(int32_t aColIndex); - /** return the available isize given to this frame during its last reflow */ - inline nscoord GetPriorAvailISize(); - - /** set the available isize given to this frame during its last reflow */ - inline void SetPriorAvailISize(nscoord aPriorAvailISize); - - /** return the desired size returned by this frame during its last reflow */ - inline mozilla::LogicalSize GetDesiredSize(); + // Get or set the available isize given to this frame during its last reflow. + nscoord GetPriorAvailISize() const { return mPriorAvailISize; } + void SetPriorAvailISize(nscoord aPriorAvailISize) { + mPriorAvailISize = aPriorAvailISize; + } - /** set the desired size returned by this frame during its last reflow */ - inline void SetDesiredSize(const ReflowOutput& aDesiredSize); + // Get or set the desired size returned by this frame during its last reflow. + mozilla::LogicalSize GetDesiredSize() const { return mDesiredSize; } + void SetDesiredSize(const ReflowOutput& aDesiredSize) { + mDesiredSize = aDesiredSize.Size(GetWritingMode()); + } - bool GetContentEmpty() const; - void SetContentEmpty(bool aContentEmpty); + bool GetContentEmpty() const { + return HasAnyStateBits(NS_TABLE_CELL_CONTENT_EMPTY); + } + void SetContentEmpty(bool aContentEmpty) { + AddOrRemoveStateBits(NS_TABLE_CELL_CONTENT_EMPTY, aContentEmpty); + } nsTableCellFrame* GetNextCell() const { nsIFrame* sibling = GetNextSibling(); @@ -216,7 +214,7 @@ class nsTableCellFrame : public nsContainerFrame, return static_cast<nsTableCellFrame*>(sibling); } - virtual LogicalMargin GetBorderWidth(WritingMode aWM) const; + virtual mozilla::LogicalMargin GetBorderWidth(mozilla::WritingMode aWM) const; void DecorateForSelection(DrawTarget* aDrawTarget, nsPoint aPt); @@ -251,44 +249,17 @@ class nsTableCellFrame : public nsContainerFrame, friend class nsTableRowFrame; - uint32_t mColIndex; // the starting column for this cell - - nscoord mPriorAvailISize; // the avail isize during the last reflow - mozilla::LogicalSize mDesiredSize; // the last desired inline and block size -}; - -inline nscoord nsTableCellFrame::GetPriorAvailISize() { - return mPriorAvailISize; -} - -inline void nsTableCellFrame::SetPriorAvailISize(nscoord aPriorAvailISize) { - mPriorAvailISize = aPriorAvailISize; -} - -inline mozilla::LogicalSize nsTableCellFrame::GetDesiredSize() { - return mDesiredSize; -} - -inline void nsTableCellFrame::SetDesiredSize(const ReflowOutput& aDesiredSize) { - mDesiredSize = aDesiredSize.Size(GetWritingMode()); -} + // The starting column for this cell + uint32_t mColIndex = 0; -inline bool nsTableCellFrame::GetContentEmpty() const { - return HasAnyStateBits(NS_TABLE_CELL_CONTENT_EMPTY); -} + // The avail isize during the last reflow + nscoord mPriorAvailISize = 0; -inline void nsTableCellFrame::SetContentEmpty(bool aContentEmpty) { - if (aContentEmpty) { - AddStateBits(NS_TABLE_CELL_CONTENT_EMPTY); - } else { - RemoveStateBits(NS_TABLE_CELL_CONTENT_EMPTY); - } -} + // The last desired inline and block size + mozilla::LogicalSize mDesiredSize; +}; -// nsBCTableCellFrame class nsBCTableCellFrame final : public nsTableCellFrame { - typedef mozilla::image::ImgDrawResult ImgDrawResult; - public: NS_DECL_FRAMEARENA_HELPERS(nsBCTableCellFrame) @@ -299,13 +270,14 @@ class nsBCTableCellFrame final : public nsTableCellFrame { nsMargin GetUsedBorder() const override; // Get the *inner half of the border only*, in twips. - LogicalMargin GetBorderWidth(WritingMode aWM) const override; + mozilla::LogicalMargin GetBorderWidth( + mozilla::WritingMode aWM) const override; // Get the *inner half of the border only*, in pixels. - BCPixelSize GetBorderWidth(LogicalSide aSide) const; + BCPixelSize GetBorderWidth(mozilla::LogicalSide aSide) const; // Set the full (both halves) width of the border - void SetBorderWidth(LogicalSide aSide, BCPixelSize aPixelValue); + void SetBorderWidth(mozilla::LogicalSide aSide, BCPixelSize aPixelValue); nsMargin GetBorderOverflow() override; diff --git a/layout/tables/nsTableColFrame.cpp b/layout/tables/nsTableColFrame.cpp index 16eab74cab..8031d4c47c 100644 --- a/layout/tables/nsTableColFrame.cpp +++ b/layout/tables/nsTableColFrame.cpp @@ -82,7 +82,6 @@ void nsTableColFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsTableColFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); aDesiredSize.ClearSize(); const nsStyleVisibility* colVis = StyleVisibility(); diff --git a/layout/tables/nsTableColGroupFrame.cpp b/layout/tables/nsTableColGroupFrame.cpp index 54fe53a5c4..bf0200e27c 100644 --- a/layout/tables/nsTableColGroupFrame.cpp +++ b/layout/tables/nsTableColGroupFrame.cpp @@ -329,7 +329,6 @@ void nsTableColGroupFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsTableColGroupFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); NS_ASSERTION(nullptr != mContent, "bad state -- null content for frame"); diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index e7fd7340bf..84bdbc48af 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1615,7 +1615,6 @@ void nsTableFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsTableFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); MOZ_ASSERT(!HasAnyStateBits(NS_FRAME_OUT_OF_FLOW), "The nsTableWrapperFrame should be the out-of-flow if needed"); @@ -4537,7 +4536,7 @@ struct BCCornerInfo { ownerColor = 0; ownerWidth = subWidth = ownerElem = subSide = subElem = hasDashDot = numSegs = bevel = 0; - ownerSide = eLogicalSideBStart; + ownerSide = static_cast<uint16_t>(LogicalSide::BStart); ownerStyle = BORDER_STYLE_UNSET; subStyle = StyleBorderStyle::Solid; } @@ -4552,7 +4551,7 @@ struct BCCornerInfo { // border perpendicular to ownerSide StyleBorderStyle subStyle; // border style of subElem StyleBorderStyle ownerStyle; // border style of ownerElem - uint16_t ownerSide : 2; // LogicalSide (e.g eLogicalSideBStart, etc) of the + uint16_t ownerSide : 2; // LogicalSide (e.g LogicalSide::BStart, etc) of the // border owning the corner relative to the corner uint16_t ownerElem : 4; // elem type (e.g. eTable, eGroup, etc) owning the corner @@ -4575,7 +4574,7 @@ void BCCornerInfo::Set(mozilla::LogicalSide aSide, BCCellBorder aBorder) { ownerStyle = aBorder.style; ownerWidth = aBorder.width; ownerColor = aBorder.color; - ownerSide = aSide; + ownerSide = static_cast<uint16_t>(aSide); hasDashDot = 0; numSegs = 0; if (aBorder.width > 0) { @@ -4586,7 +4585,8 @@ void BCCornerInfo::Set(mozilla::LogicalSide aSide, BCCellBorder aBorder) { bevel = 0; subWidth = 0; // the following will get set later - subSide = IsInline(aSide) ? eLogicalSideBStart : eLogicalSideIStart; + subSide = static_cast<uint16_t>(IsInline(aSide) ? LogicalSide::BStart + : LogicalSide::IStart); subElem = eTableOwner; subStyle = StyleBorderStyle::Solid; } @@ -4631,16 +4631,16 @@ void BCCornerInfo::Update(mozilla::LogicalSide aSide, BCCellBorder aBorder) { subStyle = tempBorder.style; subWidth = tempBorder.width; if (!firstWins) { - subSide = aSide; + subSide = static_cast<uint16_t>(aSide); } } } else { // input args are dominant - ownerSide = aSide; + ownerSide = static_cast<uint16_t>(aSide); if (::Perpendicular(oldSide, LogicalSide(ownerSide))) { subElem = oldBorder.owner; subStyle = oldBorder.style; subWidth = oldBorder.width; - subSide = oldSide; + subSide = static_cast<uint16_t>(oldSide); } } if (aBorder.width > 0) { @@ -4886,8 +4886,8 @@ void BCMapCellInfo::SetIEndBorderWidths(BCPixelSize aWidth) { // update the borders of the cells and cols affected if (mCell) { mCell->SetBorderWidth( - eLogicalSideIEnd, - std::max(aWidth, mCell->GetBorderWidth(eLogicalSideIEnd))); + LogicalSide::IEnd, + std::max(aWidth, mCell->GetBorderWidth(LogicalSide::IEnd))); } if (mEndCol) { BCPixelSize half = BC_BORDER_START_HALF(aWidth); @@ -4899,8 +4899,8 @@ void BCMapCellInfo::SetBEndBorderWidths(BCPixelSize aWidth) { // update the borders of the affected cells and rows if (mCell) { mCell->SetBorderWidth( - eLogicalSideBEnd, - std::max(aWidth, mCell->GetBorderWidth(eLogicalSideBEnd))); + LogicalSide::BEnd, + std::max(aWidth, mCell->GetBorderWidth(LogicalSide::BEnd))); } if (mEndRow) { BCPixelSize half = BC_BORDER_START_HALF(aWidth); @@ -4912,8 +4912,8 @@ void BCMapCellInfo::SetBEndBorderWidths(BCPixelSize aWidth) { void BCMapCellInfo::SetBStartBorderWidths(BCPixelSize aWidth) { if (mCell) { mCell->SetBorderWidth( - eLogicalSideBStart, - std::max(aWidth, mCell->GetBorderWidth(eLogicalSideBStart))); + LogicalSide::BStart, + std::max(aWidth, mCell->GetBorderWidth(LogicalSide::BStart))); } if (mStartRow) { BCPixelSize half = BC_BORDER_END_HALF(aWidth); @@ -4925,8 +4925,8 @@ void BCMapCellInfo::SetBStartBorderWidths(BCPixelSize aWidth) { void BCMapCellInfo::SetIStartBorderWidths(BCPixelSize aWidth) { if (mCell) { mCell->SetBorderWidth( - eLogicalSideIStart, - std::max(aWidth, mCell->GetBorderWidth(eLogicalSideIStart))); + LogicalSide::IStart, + std::max(aWidth, mCell->GetBorderWidth(LogicalSide::IStart))); } if (mStartCol) { BCPixelSize half = BC_BORDER_END_HALF(aWidth); @@ -4957,46 +4957,46 @@ void BCMapCellInfo::IncrementRow(bool aResetToBStartRowOfCell) { BCCellBorder BCMapCellInfo::GetBStartEdgeBorder() { return CompareBorders(mTableFrame, mCurrentColGroupFrame, mCurrentColFrame, mRowGroup, mStartRow, mCell, mTableWM, - eLogicalSideBStart, !ADJACENT); + LogicalSide::BStart, !ADJACENT); } BCCellBorder BCMapCellInfo::GetBEndEdgeBorder() { return CompareBorders(mTableFrame, mCurrentColGroupFrame, mCurrentColFrame, - mRowGroup, mEndRow, mCell, mTableWM, eLogicalSideBEnd, + mRowGroup, mEndRow, mCell, mTableWM, LogicalSide::BEnd, ADJACENT); } BCCellBorder BCMapCellInfo::GetIStartEdgeBorder() { return CompareBorders(mTableFrame, mColGroup, mStartCol, mRowGroup, - mCurrentRowFrame, mCell, mTableWM, eLogicalSideIStart, + mCurrentRowFrame, mCell, mTableWM, LogicalSide::IStart, !ADJACENT); } BCCellBorder BCMapCellInfo::GetIEndEdgeBorder() { return CompareBorders(mTableFrame, mColGroup, mEndCol, mRowGroup, - mCurrentRowFrame, mCell, mTableWM, eLogicalSideIEnd, + mCurrentRowFrame, mCell, mTableWM, LogicalSide::IEnd, ADJACENT); } BCCellBorder BCMapCellInfo::GetIEndInternalBorder() { const nsIFrame* cg = mCgAtEnd ? mColGroup : nullptr; return CompareBorders(nullptr, cg, mEndCol, nullptr, nullptr, mCell, mTableWM, - eLogicalSideIEnd, ADJACENT); + LogicalSide::IEnd, ADJACENT); } BCCellBorder BCMapCellInfo::GetIStartInternalBorder() { const nsIFrame* cg = mCgAtStart ? mColGroup : nullptr; return CompareBorders(nullptr, cg, mStartCol, nullptr, nullptr, mCell, - mTableWM, eLogicalSideIStart, !ADJACENT); + mTableWM, LogicalSide::IStart, !ADJACENT); } BCCellBorder BCMapCellInfo::GetBEndInternalBorder() { const nsIFrame* rg = mRgAtEnd ? mRowGroup : nullptr; return CompareBorders(nullptr, nullptr, nullptr, rg, mEndRow, mCell, mTableWM, - eLogicalSideBEnd, ADJACENT); + LogicalSide::BEnd, ADJACENT); } BCCellBorder BCMapCellInfo::GetBStartInternalBorder() { const nsIFrame* rg = mRgAtStart ? mRowGroup : nullptr; return CompareBorders(nullptr, nullptr, nullptr, rg, mStartRow, mCell, - mTableWM, eLogicalSideBStart, !ADJACENT); + mTableWM, LogicalSide::BStart, !ADJACENT); } // Calculate border information for border-collapsed tables. @@ -5164,9 +5164,10 @@ void nsTableFrame::CalcBCBorders() { // table, row group, row if the border is at the bStart of the table, // otherwise it was processed in a previous row if (0 == info.mRowIndex) { - if (!tableBorderReset[eLogicalSideBStart]) { + uint8_t idxBStart = static_cast<uint8_t>(LogicalSide::BStart); + if (!tableBorderReset[idxBStart]) { propData->mBStartBorderWidth = 0; - tableBorderReset[eLogicalSideBStart] = true; + tableBorderReset[idxBStart] = true; } for (int32_t colIdx = info.mColIndex; colIdx <= info.GetCellEndColIndex(); colIdx++) { @@ -5175,9 +5176,9 @@ void nsTableFrame::CalcBCBorders() { BCCornerInfo& bStartIStartCorner = bStartCorners[colIdx]; // Mark inline-end direction border from this corner. if (0 == colIdx) { - bStartIStartCorner.Set(eLogicalSideIEnd, currentBorder); + bStartIStartCorner.Set(LogicalSide::IEnd, currentBorder); } else { - bStartIStartCorner.Update(eLogicalSideIEnd, currentBorder); + bStartIStartCorner.Update(LogicalSide::IEnd, currentBorder); tableCellMap->SetBCBorderCorner( LogicalCorner::BStartIStart, *iter.mCellMap, 0, 0, colIdx, LogicalSide(bStartIStartCorner.ownerSide), @@ -5186,7 +5187,7 @@ void nsTableFrame::CalcBCBorders() { // Above, we set the corner `colIndex` column as having a border towards // inline-end, heading towards the next column. Vice versa is also true, // where the next column has a border heading towards this column. - bStartCorners[colIdx + 1].Set(eLogicalSideIStart, currentBorder); + bStartCorners[colIdx + 1].Set(LogicalSide::IStart, currentBorder); MOZ_ASSERT(firstRowBStartEdgeBorder, "Inline start border tracking not set?"); // update firstRowBStartEdgeBorder and see if a new segment starts @@ -5196,7 +5197,7 @@ void nsTableFrame::CalcBCBorders() { firstRowBStartEdgeBorder.ref()) : true; // store the border segment in the cell map - tableCellMap->SetBCBorderEdge(eLogicalSideBStart, *iter.mCellMap, 0, 0, + tableCellMap->SetBCBorderEdge(LogicalSide::BStart, *iter.mCellMap, 0, 0, colIdx, 1, currentBorder.owner, currentBorder.width, startSeg); @@ -5225,9 +5226,10 @@ void nsTableFrame::CalcBCBorders() { // table, col group, col if the border is at the iStart of the table, // otherwise it was processed in a previous col if (0 == info.mColIndex) { - if (!tableBorderReset[eLogicalSideIStart]) { + uint8_t idxIStart = static_cast<uint8_t>(LogicalSide::IStart); + if (!tableBorderReset[idxIStart]) { propData->mIStartBorderWidth = 0; - tableBorderReset[eLogicalSideIStart] = true; + tableBorderReset[idxIStart] = true; } info.mCurrentRowFrame = nullptr; for (int32_t rowB = info.mRowIndex; rowB <= info.GetCellEndRowIndex(); @@ -5236,17 +5238,17 @@ void nsTableFrame::CalcBCBorders() { BCCellBorder currentBorder = info.GetIStartEdgeBorder(); BCCornerInfo& bStartIStartCorner = (0 == rowB) ? bStartCorners[0] : bEndCorners[0]; - bStartIStartCorner.Update(eLogicalSideBEnd, currentBorder); + bStartIStartCorner.Update(LogicalSide::BEnd, currentBorder); tableCellMap->SetBCBorderCorner( LogicalCorner::BStartIStart, *iter.mCellMap, iter.mRowGroupStart, rowB, 0, LogicalSide(bStartIStartCorner.ownerSide), bStartIStartCorner.subWidth, bStartIStartCorner.bevel); - bEndCorners[0].Set(eLogicalSideBStart, currentBorder); + bEndCorners[0].Set(LogicalSide::BStart, currentBorder); // update lastBlockDirBorders and see if a new segment starts bool startSeg = SetBorder(currentBorder, lastBlockDirBorders[0]); // store the border segment in the cell map - tableCellMap->SetBCBorderEdge(eLogicalSideIStart, *iter.mCellMap, + tableCellMap->SetBCBorderEdge(LogicalSide::IStart, *iter.mCellMap, iter.mRowGroupStart, rowB, info.mColIndex, 1, currentBorder.owner, currentBorder.width, startSeg); @@ -5261,9 +5263,10 @@ void nsTableFrame::CalcBCBorders() { // cells and the table, row group, row if (info.mNumTableCols == info.GetCellEndColIndex() + 1) { // touches iEnd edge of table - if (!tableBorderReset[eLogicalSideIEnd]) { + uint8_t idxIEnd = static_cast<uint8_t>(LogicalSide::IEnd); + if (!tableBorderReset[idxIEnd]) { propData->mIEndBorderWidth = 0; - tableBorderReset[eLogicalSideIEnd] = true; + tableBorderReset[idxIEnd] = true; } info.mCurrentRowFrame = nullptr; for (int32_t rowB = info.mRowIndex; rowB <= info.GetCellEndRowIndex(); @@ -5275,7 +5278,7 @@ void nsTableFrame::CalcBCBorders() { BCCornerInfo& bStartIEndCorner = (0 == rowB) ? bStartCorners[info.GetCellEndColIndex() + 1] : bEndCorners[info.GetCellEndColIndex() + 1]; - bStartIEndCorner.Update(eLogicalSideBEnd, currentBorder); + bStartIEndCorner.Update(LogicalSide::BEnd, currentBorder); tableCellMap->SetBCBorderCorner( LogicalCorner::BStartIEnd, *iter.mCellMap, iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), @@ -5283,7 +5286,7 @@ void nsTableFrame::CalcBCBorders() { bStartIEndCorner.bevel); BCCornerInfo& bEndIEndCorner = bEndCorners[info.GetCellEndColIndex() + 1]; - bEndIEndCorner.Set(eLogicalSideBStart, currentBorder); + bEndIEndCorner.Set(LogicalSide::BStart, currentBorder); tableCellMap->SetBCBorderCorner( LogicalCorner::BEndIEnd, *iter.mCellMap, iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), LogicalSide(bEndIEndCorner.ownerSide), @@ -5293,7 +5296,7 @@ void nsTableFrame::CalcBCBorders() { currentBorder, lastBlockDirBorders[info.GetCellEndColIndex() + 1]); // store the border segment in the cell map and update cellBorders tableCellMap->SetBCBorderEdge( - eLogicalSideIEnd, *iter.mCellMap, iter.mRowGroupStart, rowB, + LogicalSide::IEnd, *iter.mCellMap, iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), 1, currentBorder.owner, currentBorder.width, startSeg); // Set border width at inline-end (table-wide and for the cell), but @@ -5325,7 +5328,7 @@ void nsTableFrame::CalcBCBorders() { if (info.GetCellEndColIndex() < damageArea.EndCol() && rowB >= damageArea.StartRow() && rowB < damageArea.EndRow()) { tableCellMap->SetBCBorderEdge( - eLogicalSideIEnd, *iter.mCellMap, iter.mRowGroupStart, rowB, + LogicalSide::IEnd, *iter.mCellMap, iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), segLength, currentBorder.owner, currentBorder.width, startSeg); info.SetIEndBorderWidths(currentBorder.width); @@ -5346,7 +5349,7 @@ void nsTableFrame::CalcBCBorders() { ? &bStartCorners[info.GetCellEndColIndex() + 1] : &bEndCorners[info.GetCellEndColIndex() + 1]; // From previous row. - bStartIEndCorner->Update(eLogicalSideBEnd, currentBorder); + bStartIEndCorner->Update(LogicalSide::BEnd, currentBorder); // If this is a rowspan, need to consider if this "corner" is generating // an inline segment for the adjacent cell. e.g. // @@ -5360,7 +5363,7 @@ void nsTableFrame::CalcBCBorders() { BCCellBorder adjacentBorder = ajaInfo.GetBStartInternalBorder(); currentBorder = CompareBorders(!CELL_CORNER, currentBorder, adjacentBorder, INLINE_DIR); - bStartIEndCorner->Update(eLogicalSideIEnd, currentBorder); + bStartIEndCorner->Update(LogicalSide::IEnd, currentBorder); } // Check that the spanned area is inside of the invalidation area if (info.GetCellEndColIndex() < damageArea.EndCol() && @@ -5387,7 +5390,7 @@ void nsTableFrame::CalcBCBorders() { BCCornerInfo& bEndIEndCorner = (hitsSpanOnIEnd) ? bStartCorners[info.GetCellEndColIndex() + 1] : bEndCorners[info.GetCellEndColIndex() + 1]; - bEndIEndCorner.Set(eLogicalSideBStart, currentBorder); + bEndIEndCorner.Set(LogicalSide::BStart, currentBorder); priorAjaInfo = ajaInfo; } } @@ -5400,23 +5403,24 @@ void nsTableFrame::CalcBCBorders() { // cells and the table, row group, row if (info.mNumTableRows == info.GetCellEndRowIndex() + 1) { // touches bEnd edge of table - if (!tableBorderReset[eLogicalSideBEnd]) { + uint8_t idxBEnd = static_cast<uint8_t>(LogicalSide::BEnd); + if (!tableBorderReset[idxBEnd]) { propData->mBEndBorderWidth = 0; - tableBorderReset[eLogicalSideBEnd] = true; + tableBorderReset[idxBEnd] = true; } for (int32_t colIdx = info.mColIndex; colIdx <= info.GetCellEndColIndex(); colIdx++) { info.SetColumn(colIdx); BCCellBorder currentBorder = info.GetBEndEdgeBorder(); BCCornerInfo& bEndIStartCorner = bEndCorners[colIdx]; - bEndIStartCorner.Update(eLogicalSideIEnd, currentBorder); + bEndIStartCorner.Update(LogicalSide::IEnd, currentBorder); tableCellMap->SetBCBorderCorner( LogicalCorner::BEndIStart, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), colIdx, LogicalSide(bEndIStartCorner.ownerSide), bEndIStartCorner.subWidth, bEndIStartCorner.bevel); BCCornerInfo& bEndIEndCorner = bEndCorners[colIdx + 1]; - bEndIEndCorner.Update(eLogicalSideIStart, currentBorder); + bEndIEndCorner.Update(LogicalSide::IStart, currentBorder); // Store the block-end inline-end corner if it also is the block-end // inline-end of the overall table. if (info.mNumTableCols == colIdx + 1) { @@ -5439,7 +5443,7 @@ void nsTableFrame::CalcBCBorders() { } // store the border segment in the cell map and update cellBorders tableCellMap->SetBCBorderEdge( - eLogicalSideBEnd, *iter.mCellMap, iter.mRowGroupStart, + LogicalSide::BEnd, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), colIdx, 1, currentBorder.owner, currentBorder.width, startSeg); // update lastBEndBorders @@ -5486,12 +5490,12 @@ void nsTableFrame::CalcBCBorders() { } else if (prevRowIndex < info.GetCellEndRowIndex() + 1) { // spans below the cell to the iStart side bStartCorners[colIdx] = bEndIStartCorner; - bEndIStartCorner.Set(eLogicalSideIEnd, currentBorder); + bEndIStartCorner.Set(LogicalSide::IEnd, currentBorder); update = false; } } if (update) { - bEndIStartCorner.Update(eLogicalSideIEnd, currentBorder); + bEndIStartCorner.Update(LogicalSide::IEnd, currentBorder); } // Check that the spanned area is inside of the invalidation area if (info.GetCellEndRowIndex() < damageArea.EndRow() && @@ -5506,7 +5510,7 @@ void nsTableFrame::CalcBCBorders() { // Propagate this segment down the colspan for (int32_t c = colIdx + 1; c < colIdx + segLength; c++) { BCCornerInfo& corner = bEndCorners[c]; - corner.Set(eLogicalSideIEnd, currentBorder); + corner.Set(LogicalSide::IEnd, currentBorder); tableCellMap->SetBCBorderCorner( LogicalCorner::BEndIStart, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), c, LogicalSide(corner.ownerSide), @@ -5533,7 +5537,7 @@ void nsTableFrame::CalcBCBorders() { if (info.GetCellEndRowIndex() < damageArea.EndRow() && colIdx >= damageArea.StartCol() && colIdx < damageArea.EndCol()) { tableCellMap->SetBCBorderEdge( - eLogicalSideBEnd, *iter.mCellMap, iter.mRowGroupStart, + LogicalSide::BEnd, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), colIdx, segLength, currentBorder.owner, currentBorder.width, startSeg); info.SetBEndBorderWidths(currentBorder.width); @@ -5541,7 +5545,7 @@ void nsTableFrame::CalcBCBorders() { } // update bEnd-iEnd corner BCCornerInfo& bEndIEndCorner = bEndCorners[colIdx + segLength]; - bEndIEndCorner.Update(eLogicalSideIStart, currentBorder); + bEndIEndCorner.Update(LogicalSide::IStart, currentBorder); } } // o------o------o @@ -5570,7 +5574,7 @@ void nsTableFrame::CalcBCBorders() { // new segment if (iter.mCellMap) { tableCellMap->ResetBStartStart( - eLogicalSideBEnd, *iter.mCellMap, iter.mRowGroupStart, + LogicalSide::BEnd, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), nextColIndex); } } @@ -6248,7 +6252,7 @@ static nscoord CalcVerCornerOffset(nsPresContext* aPresContext, offset = (aIsStartOfSeg) ? -largeHalf : smallHalf; } else { offset = - (eLogicalSideBStart == aCornerOwnerSide) ? smallHalf : -largeHalf; + (LogicalSide::BStart == aCornerOwnerSide) ? smallHalf : -largeHalf; } } else { DivideBCBorderSize(aHorWidth, smallHalf, largeHalf); @@ -6283,7 +6287,7 @@ static nscoord CalcHorCornerOffset(nsPresContext* aPresContext, offset = (aIsStartOfSeg) ? -largeHalf : smallHalf; } else { offset = - (eLogicalSideIStart == aCornerOwnerSide) ? smallHalf : -largeHalf; + (LogicalSide::IStart == aCornerOwnerSide) ? smallHalf : -largeHalf; } } else { DivideBCBorderSize(aVerWidth, smallHalf, largeHalf); @@ -6305,7 +6309,7 @@ BCBlockDirSeg::BCBlockDirSeg() mCol = nullptr; mFirstCell = mLastCell = mAjaCell = nullptr; mOffsetI = mOffsetB = mLength = mWidth = mBStartBevelOffset = 0; - mBStartBevelSide = eLogicalSideBStart; + mBStartBevelSide = LogicalSide::BStart; mOwner = eCellOwner; } @@ -6322,7 +6326,7 @@ void BCBlockDirSeg::Start(BCPaintBorderIterator& aIter, BCPixelSize aBlockSegISize, BCPixelSize aInlineSegBSize, Maybe<nscoord> aEmptyRowEndBSize) { - LogicalSide ownerSide = eLogicalSideBStart; + LogicalSide ownerSide = LogicalSide::BStart; bool bevel = false; nscoord cornerSubWidth = @@ -6339,7 +6343,7 @@ void BCBlockDirSeg::Start(BCPaintBorderIterator& aIter, bStartBevel ? presContext->DevPixelsToAppUnits(maxInlineSegBSize) : 0; // XXX this assumes that only corners where 2 segments join can be beveled mBStartBevelSide = - (aInlineSegBSize > 0) ? eLogicalSideIEnd : eLogicalSideIStart; + (aInlineSegBSize > 0) ? LogicalSide::IEnd : LogicalSide::IStart; if (aEmptyRowEndBSize && *aEmptyRowEndBSize < offset) { // This segment is starting from an empty row. This will require the the // starting segment to overlap with the previously drawn segment, unless the @@ -6390,7 +6394,7 @@ void BCBlockDirSeg::Initialize(BCPaintBorderIterator& aIter) { */ void BCBlockDirSeg::GetBEndCorner(BCPaintBorderIterator& aIter, BCPixelSize aInlineSegBSize) { - LogicalSide ownerSide = eLogicalSideBStart; + LogicalSide ownerSide = LogicalSide::BStart; nscoord cornerSubWidth = 0; bool bevel = false; if (aIter.mBCData) { @@ -6410,7 +6414,7 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters( // get the border style, color and paint the segment LogicalSide side = - aIter.IsDamageAreaIEndMost() ? eLogicalSideIEnd : eLogicalSideIStart; + aIter.IsDamageAreaIEndMost() ? LogicalSide::IEnd : LogicalSide::IStart; int32_t relColIndex = aIter.GetRelativeColIndex(); nsTableColFrame* col = mCol; if (!col) ABORT1(Nothing()); @@ -6430,7 +6434,7 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters( owner = aIter.mTable; break; case eAjaColGroupOwner: - side = eLogicalSideIEnd; + side = LogicalSide::IEnd; if (!aIter.IsTableIEndMost() && (relColIndex > 0)) { col = aIter.mBlockDirInfo[relColIndex - 1].mCol; } @@ -6441,7 +6445,7 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters( } break; case eAjaColOwner: - side = eLogicalSideIEnd; + side = LogicalSide::IEnd; if (!aIter.IsTableIEndMost() && (relColIndex > 0)) { col = aIter.mBlockDirInfo[relColIndex - 1].mCol; } @@ -6466,7 +6470,7 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters( owner = mFirstRow; break; case eAjaCellOwner: - side = eLogicalSideIEnd; + side = LogicalSide::IEnd; cell = mAjaCell; [[fallthrough]]; case eCellOwner: @@ -6487,7 +6491,7 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters( (mIsBEndBevel) ? presContext->DevPixelsToAppUnits(mBEndInlineSegBSize) : 0; LogicalSide bEndBevelSide = - (aInlineSegBSize > 0) ? eLogicalSideIEnd : eLogicalSideIStart; + (aInlineSegBSize > 0) ? LogicalSide::IEnd : LogicalSide::IStart; // Convert logical to physical sides/coordinates for DrawTableBorderSegment. @@ -6733,11 +6737,11 @@ void BCBlockDirSeg::IncludeCurrentBorder(BCPaintBorderIterator& aIter) { BCInlineDirSeg::BCInlineDirSeg() : mIsIEndBevel(false), mIEndBevelOffset(0), - mIEndBevelSide(eLogicalSideBStart), + mIEndBevelSide(LogicalSide::BStart), mEndOffset(0), mOwner(eTableOwner) { mOffsetI = mOffsetB = mLength = mWidth = mIStartBevelOffset = 0; - mIStartBevelSide = eLogicalSideBStart; + mIStartBevelSide = LogicalSide::BStart; mFirstCell = mAjaCell = nullptr; } @@ -6751,7 +6755,7 @@ void BCInlineDirSeg::Start(BCPaintBorderIterator& aIter, BCBorderOwner aBorderOwner, BCPixelSize aBEndBlockSegISize, BCPixelSize aInlineSegBSize) { - LogicalSide cornerOwnerSide = eLogicalSideBStart; + LogicalSide cornerOwnerSide = LogicalSide::BStart; bool bevel = false; mOwner = aBorderOwner; @@ -6769,7 +6773,7 @@ void BCInlineDirSeg::Start(BCPaintBorderIterator& aIter, (iStartBevel && (aInlineSegBSize > 0)) ? maxBlockSegISize : 0; // XXX this assumes that only corners where 2 segments join can be beveled mIStartBevelSide = - (aBEndBlockSegISize > 0) ? eLogicalSideBEnd : eLogicalSideBStart; + (aBEndBlockSegISize > 0) ? LogicalSide::BEnd : LogicalSide::BStart; mOffsetI += offset; mLength = -offset; mWidth = aInlineSegBSize; @@ -6787,7 +6791,7 @@ void BCInlineDirSeg::Start(BCPaintBorderIterator& aIter, */ void BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter, BCPixelSize aIStartSegISize) { - LogicalSide ownerSide = eLogicalSideBStart; + LogicalSide ownerSide = LogicalSide::BStart; nscoord cornerSubWidth = 0; bool bevel = false; if (aIter.mBCData) { @@ -6805,7 +6809,7 @@ void BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter, mIEndBevelOffset = (mIsIEndBevel) ? presContext->DevPixelsToAppUnits(verWidth) : 0; mIEndBevelSide = - (aIStartSegISize > 0) ? eLogicalSideBEnd : eLogicalSideBStart; + (aIStartSegISize > 0) ? LogicalSide::BEnd : LogicalSide::BStart; } Maybe<BCBorderParameters> BCInlineDirSeg::BuildBorderParameters( @@ -6814,7 +6818,7 @@ Maybe<BCBorderParameters> BCInlineDirSeg::BuildBorderParameters( // get the border style, color and paint the segment LogicalSide side = - aIter.IsDamageAreaBEndMost() ? eLogicalSideBEnd : eLogicalSideBStart; + aIter.IsDamageAreaBEndMost() ? LogicalSide::BEnd : LogicalSide::BStart; nsIFrame* rg = aIter.mRg; if (!rg) ABORT1(Nothing()); nsIFrame* row = aIter.mRow; @@ -6855,21 +6859,21 @@ Maybe<BCBorderParameters> BCInlineDirSeg::BuildBorderParameters( owner = aIter.mTableFirstInFlow->GetColFrame(aIter.mColIndex - 1); break; case eAjaRowGroupOwner: - side = eLogicalSideBEnd; + side = LogicalSide::BEnd; rg = (aIter.IsTableBEndMost()) ? aIter.mRg : aIter.mPrevRg; [[fallthrough]]; case eRowGroupOwner: owner = rg; break; case eAjaRowOwner: - side = eLogicalSideBEnd; + side = LogicalSide::BEnd; row = (aIter.IsTableBEndMost()) ? aIter.mRow : aIter.mPrevRow; [[fallthrough]]; case eRowOwner: owner = row; break; case eAjaCellOwner: - side = eLogicalSideBEnd; + side = LogicalSide::BEnd; // if this is null due to the damage area origin-y > 0, then the border // won't show up anyway cell = mAjaCell; @@ -6974,14 +6978,14 @@ void BCPaintBorderIterator::StoreColumnWidth(int32_t aIndex) { * Determine if a block-dir segment owns the corner */ bool BCPaintBorderIterator::BlockDirSegmentOwnsCorner() { - LogicalSide cornerOwnerSide = eLogicalSideBStart; + LogicalSide cornerOwnerSide = LogicalSide::BStart; bool bevel = false; if (mBCData) { mBCData->GetCorner(cornerOwnerSide, bevel); } // unitialized ownerside, bevel - return (eLogicalSideBStart == cornerOwnerSide) || - (eLogicalSideBEnd == cornerOwnerSide); + return (LogicalSide::BStart == cornerOwnerSide) || + (LogicalSide::BEnd == cornerOwnerSide); } /** diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index 1190561ee8..a6f4647429 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -305,7 +305,7 @@ static nscoord GetBSizeOfRowsSpannedBelowFirst( /** * Post-reflow hook. This is where the table row does its post-processing */ -void nsTableRowFrame::DidResize() { +void nsTableRowFrame::DidResize(ForceAlignTopForTableCell aForceAlignTop) { // Resize and re-align the cell frames based on our row bsize nsTableFrame* tableFrame = GetTableFrame(); @@ -369,7 +369,7 @@ void nsTableRowFrame::DidResize() { // realign cell content based on the new bsize. We might be able to // skip this if the bsize didn't change... maybe. Hard to tell. - cellFrame->BlockDirAlignChild(wm, mMaxCellAscent); + cellFrame->BlockDirAlignChild(wm, mMaxCellAscent, aForceAlignTop); // Always store the overflow, even if the height didn't change, since // we'll lose part of our overflow area otherwise. @@ -581,11 +581,8 @@ nscoord nsTableRowFrame::CalcCellActualBSize(nsTableCellFrame* aCellFrame, const auto& bsizeStyleCoord = position->BSize(aWM); if (bsizeStyleCoord.ConvertsToLength()) { - // In quirks mode, table cell isize should be content-box, but bsize - // should be border-box. - // Because of this historic anomaly, we do not use quirk.css - // (since we can't specify one value of box-sizing for isize and another - // for bsize) + // In quirks mode, table cell bsize should always be border-box. + // https://quirks.spec.whatwg.org/#the-table-cell-height-box-sizing-quirk specifiedBSize = bsizeStyleCoord.ToLength(); if (PresContext()->CompatibilityMode() != eCompatibility_NavQuirks && position->mBoxSizing == StyleBoxSizing::Content) { @@ -956,7 +953,6 @@ void nsTableRowFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsTableRowFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); WritingMode wm = aReflowInput.GetWritingMode(); @@ -999,17 +995,14 @@ void nsTableRowFrame::Reflow(nsPresContext* aPresContext, PushDirtyBitToAbsoluteFrames(); } -/** - * This function is called by the row group frame's SplitRowGroup() code when - * pushing a row frame that has cell frames that span into it. The cell frame - * should be reflowed with the specified height - */ nscoord nsTableRowFrame::ReflowCellFrame(nsPresContext* aPresContext, const ReflowInput& aReflowInput, bool aIsTopOfPage, nsTableCellFrame* aCellFrame, nscoord aAvailableBSize, nsReflowStatus& aStatus) { + MOZ_ASSERT(aPresContext->IsPaginated(), + "ReflowCellFrame currently supports only paged media!"); MOZ_ASSERT(aAvailableBSize != NS_UNCONSTRAINEDSIZE, "Why split cell frame if available bsize is unconstrained?"); WritingMode wm = aReflowInput.GetWritingMode(); @@ -1049,7 +1042,8 @@ nscoord nsTableRowFrame::ReflowCellFrame(nsPresContext* aPresContext, // XXX What happens if this cell has 'vertical-align: baseline' ? // XXX Why is it assumed that the cell's ascent hasn't changed ? if (isCompleteAndNotTruncated) { - aCellFrame->BlockDirAlignChild(wm, mMaxCellAscent); + aCellFrame->BlockDirAlignChild(wm, mMaxCellAscent, + ForceAlignTopForTableCell::Yes); } nsTableFrame::InvalidateTableFrame( diff --git a/layout/tables/nsTableRowFrame.h b/layout/tables/nsTableRowFrame.h index 1d68a534c3..e24be1ea23 100644 --- a/layout/tables/nsTableRowFrame.h +++ b/layout/tables/nsTableRowFrame.h @@ -15,6 +15,11 @@ class nsTableCellFrame; namespace mozilla { class PresShell; struct TableCellReflowInput; + +// Yes if table-cells should use 'vertical-align:top' in +// nsTableCellFrame::BlockDirAlignChild(). This is a hack to workaround our +// current table row group fragmentation to avoid data loss. +enum class ForceAlignTopForTableCell : uint8_t { No, Yes }; } // namespace mozilla /** @@ -104,7 +109,8 @@ class nsTableRowFrame : public nsContainerFrame { const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; - void DidResize(); + void DidResize(mozilla::ForceAlignTopForTableCell aForceAlignTop = + mozilla::ForceAlignTopForTableCell::No); #ifdef DEBUG_FRAME_DUMP nsresult GetFrameName(nsAString& aResult) const override; @@ -145,7 +151,11 @@ class nsTableRowFrame : public nsContainerFrame { // See nsTableFrame.h void AddDeletedRowIndex(); - /** used by row group frame code */ + /** + * This function is called by the row group frame's SplitRowGroup() code when + * pushing a row frame that has cell frames that span into it. The cell frame + * should be reflowed with the specified available block-size. + */ nscoord ReflowCellFrame(nsPresContext* aPresContext, const ReflowInput& aReflowInput, bool aIsTopOfPage, nsTableCellFrame* aCellFrame, nscoord aAvailableBSize, diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index f8dac61386..9ae8a59a90 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1122,7 +1122,7 @@ void nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, FinishReflowChild(rowFrame, aPresContext, rowMetrics, &rowReflowInput, wm, dummyPos, dummyContainerSize, ReflowChildFlags::NoMoveFrame); - rowFrame->DidResize(); + rowFrame->DidResize(ForceAlignTopForTableCell::Yes); if (!aRowForcedPageBreak && !aStatus.IsFullyComplete() && ShouldAvoidBreakInside(aReflowInput)) { @@ -1324,7 +1324,6 @@ void nsTableRowGroupFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsTableRowGroupFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); // Row geometry may be going to change so we need to invalidate any row diff --git a/layout/tables/nsTableWrapperFrame.cpp b/layout/tables/nsTableWrapperFrame.cpp index a3e957c4fd..aa898ddf6f 100644 --- a/layout/tables/nsTableWrapperFrame.cpp +++ b/layout/tables/nsTableWrapperFrame.cpp @@ -242,7 +242,6 @@ ComputedStyle* nsTableWrapperFrame::GetParentComputedStyle( nscoord nsTableWrapperFrame::GetMinISize(gfxContext* aRenderingContext) { nscoord iSize = nsLayoutUtils::IntrinsicForContainer( aRenderingContext, InnerTableFrame(), IntrinsicISizeType::MinISize); - DISPLAY_MIN_INLINE_SIZE(this, iSize); if (mCaptionFrames.NotEmpty()) { nscoord capISize = nsLayoutUtils::IntrinsicForContainer( aRenderingContext, mCaptionFrames.FirstChild(), @@ -256,10 +255,7 @@ nscoord nsTableWrapperFrame::GetMinISize(gfxContext* aRenderingContext) { /* virtual */ nscoord nsTableWrapperFrame::GetPrefISize(gfxContext* aRenderingContext) { - nscoord maxISize; - DISPLAY_PREF_INLINE_SIZE(this, maxISize); - - maxISize = nsLayoutUtils::IntrinsicForContainer( + nscoord maxISize = nsLayoutUtils::IntrinsicForContainer( aRenderingContext, InnerTableFrame(), IntrinsicISizeType::PrefISize); if (mCaptionFrames.NotEmpty()) { // Don't let the caption's pref isize expand the table's pref isize. @@ -547,7 +543,7 @@ ComputeSizeFlags nsTableWrapperFrame::CreateComputeSizeFlagsForChild() const { // Shrink-wrap child frames by default, except if we're a stretched grid item. if (MOZ_UNLIKELY(IsGridItem())) { auto* gridContainer = static_cast<nsGridContainerFrame*>(GetParent()); - if (gridContainer->GridItemShouldStretch(this, eLogicalAxisInline)) { + if (gridContainer->GridItemShouldStretch(this, LogicalAxis::Inline)) { return {}; } } @@ -691,7 +687,6 @@ void nsTableWrapperFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsTableWrapperFrame"); - DISPLAY_REFLOW(aPresContext, this, aOuterRI, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); // Initialize out parameters diff --git a/layout/tools/reftest/mach_commands.py b/layout/tools/reftest/mach_commands.py index 8cb1164332..dd4c8ea63a 100644 --- a/layout/tools/reftest/mach_commands.py +++ b/layout/tools/reftest/mach_commands.py @@ -160,10 +160,6 @@ class ReftestRunner(MozbuildObject): args.e10s = False print("using e10s=False for non-geckoview app") - # Disable fission until geckoview supports fission by default. - # Need fission on Android? Use '--setpref fission.autostart=true' - args.disableFission = True - # A symlink and some path manipulations are required so that test # manifests can be found both locally and remotely (via a url) # using the same relative path. diff --git a/layout/tools/reftest/manifest.sys.mjs b/layout/tools/reftest/manifest.sys.mjs index 4be0afde57..a4a8ed126f 100644 --- a/layout/tools/reftest/manifest.sys.mjs +++ b/layout/tools/reftest/manifest.sys.mjs @@ -677,6 +677,9 @@ function BuildConditionSandbox(aURL) { sandbox.d2d && sandbox.gpuProcess; + sandbox.mozinfo = Services.prefs.getStringPref("sandbox.mozinfo", null); + sandbox.os_version = sandbox.mozinfo.os_version; + sandbox.layersGPUAccelerated = g.windowUtils.layerManagerType != "Basic"; sandbox.d3d11 = g.windowUtils.layerManagerType == "Direct3D 11"; sandbox.d3d9 = g.windowUtils.layerManagerType == "Direct3D 9"; diff --git a/layout/tools/reftest/reftest.sys.mjs b/layout/tools/reftest/reftest.sys.mjs index 1040470967..0f103c5816 100644 --- a/layout/tools/reftest/reftest.sys.mjs +++ b/layout/tools/reftest/reftest.sys.mjs @@ -1423,7 +1423,9 @@ function RecordResult(testRunTime, errorMsg, typeSpecificResults) { // branch, 'equal' must be false so let's assert that to guard // against logic errors. if (equal) { - throw new Error("Logic error in reftest.jsm fuzzy test handling!"); + throw new Error( + "Logic error in reftest.sys.mjs fuzzy test handling!" + ); } output = { s: ["PASS", "FAIL"], n: "UnexpectedPass" }; } else { diff --git a/layout/tools/reftest/runreftest.py b/layout/tools/reftest/runreftest.py index cf314c99b5..e97a6de5d7 100644 --- a/layout/tools/reftest/runreftest.py +++ b/layout/tools/reftest/runreftest.py @@ -462,6 +462,9 @@ class RefTest(object): # config specific flags prefs["sandbox.apple_silicon"] = mozinfo.info.get("apple_silicon", False) + prefs["sandbox.mozinfo"] = json.dumps(mozinfo.info) + prefs["sandbox.os_version"] = mozinfo.info.get("os_version", "") + # Set tests to run or manifests to parse. if tests: testlist = os.path.join(profile.profile, "reftests.json") @@ -482,22 +485,6 @@ class RefTest(object): if options.thisChunk: prefs["reftest.thisChunk"] = options.thisChunk - # Bug 1262954: For winXP + e10s disable acceleration - if ( - platform.system() in ("Windows", "Microsoft") - and "5.1" in platform.version() - and options.e10s - ): - prefs["layers.acceleration.disabled"] = True - - # Bug 1300355: Disable canvas cache for win7 as it uses - # too much memory and causes OOMs. - if ( - platform.system() in ("Windows", "Microsoft") - and "6.1" in platform.version() - ): - prefs["reftest.nocache"] = True - if options.marionette: # options.marionette can specify host:port port = options.marionette.split(":")[1] diff --git a/layout/xul/nsMenuPopupFrame.cpp b/layout/xul/nsMenuPopupFrame.cpp index 8ebb8b01d5..17993c8466 100644 --- a/layout/xul/nsMenuPopupFrame.cpp +++ b/layout/xul/nsMenuPopupFrame.cpp @@ -491,19 +491,13 @@ void nsMenuPopupFrame::TweakMinPrefISize(nscoord& aSize) { } nscoord nsMenuPopupFrame::GetMinISize(gfxContext* aRC) { - nscoord result; - DISPLAY_PREF_INLINE_SIZE(this, result); - - result = nsBlockFrame::GetMinISize(aRC); + nscoord result = nsBlockFrame::GetMinISize(aRC); TweakMinPrefISize(result); return result; } nscoord nsMenuPopupFrame::GetPrefISize(gfxContext* aRC) { - nscoord result; - DISPLAY_PREF_INLINE_SIZE(this, result); - - result = nsBlockFrame::GetPrefISize(aRC); + nscoord result = nsBlockFrame::GetPrefISize(aRC); TweakMinPrefISize(result); return result; } @@ -514,7 +508,6 @@ void nsMenuPopupFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsMenuPopupFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); const auto wm = GetWritingMode(); @@ -2186,6 +2179,12 @@ nsMargin nsMenuPopupFrame::GetMargin() const { margin.left += auOffset.x; margin.right += auOffset.x; } + if (mPopupType == PopupType::Tooltip && !IsAnchored()) { + const auto auOffset = + CSSPixel::ToAppUnits(LookAndFeel::TooltipOffsetVertical()); + margin.top += auOffset; + margin.bottom += auOffset; + } return margin; } @@ -2246,7 +2245,8 @@ void nsMenuPopupFrame::MoveTo(const CSSPoint& aPos, bool aUpdateAttrs, void nsMenuPopupFrame::MoveToAnchor(nsIContent* aAnchorContent, const nsAString& aPosition, int32_t aXPos, int32_t aYPos, bool aAttributesOverride) { - NS_ASSERTION(IsVisible(), "popup must be visible to move it"); + NS_ASSERTION(IsVisibleOrShowing(), + "popup must be visible or showing to move it"); nsPopupState oldstate = mPopupState; InitializePopup(aAnchorContent, mTriggerContent, aPosition, aXPos, aYPos, diff --git a/layout/xul/nsXULPopupManager.cpp b/layout/xul/nsXULPopupManager.cpp index 332d60d363..a6dbeadca7 100644 --- a/layout/xul/nsXULPopupManager.cpp +++ b/layout/xul/nsXULPopupManager.cpp @@ -49,6 +49,7 @@ #include "mozilla/dom/XULMenuElement.h" #include "mozilla/dom/XULMenuBarElement.h" #include "mozilla/dom/XULPopupElement.h" +#include "mozilla/AutoRestore.h" #include "mozilla/EventDispatcher.h" #include "mozilla/EventStateManager.h" #include "mozilla/LookAndFeel.h" diff --git a/layout/xul/tree/nsTreeBodyFrame.cpp b/layout/xul/tree/nsTreeBodyFrame.cpp index 5ccc1468cc..f585009600 100644 --- a/layout/xul/tree/nsTreeBodyFrame.cpp +++ b/layout/xul/tree/nsTreeBodyFrame.cpp @@ -3895,7 +3895,7 @@ void nsTreeBodyFrame::RemoveImageCacheEntry(int32_t aRowIndex, nsTreeColumn* aCol) { nsAutoString imageSrc; nsCOMPtr<nsITreeView> view = GetExistingView(); - if (NS_FAILED(view->GetImageSrc(aRowIndex, aCol, imageSrc))) { + if (!view || NS_FAILED(view->GetImageSrc(aRowIndex, aCol, imageSrc))) { return; } nsTreeImageCacheEntry entry; -- cgit v1.2.3