From 086c044dc34dfc0f74fbe41f4ecb402b2cd34884 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:13:33 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- layout/base/LayoutTelemetryTools.h | 4 +- layout/base/MotionPathUtils.cpp | 8 +- layout/base/PositionedEventTargeting.cpp | 12 - layout/base/PresShell.cpp | 204 +++++-- layout/base/PresShell.h | 12 +- layout/base/RestyleManager.cpp | 9 +- layout/base/TouchManager.cpp | 130 ++++- layout/base/TouchManager.h | 16 + layout/base/crashtests/1435015.html | 9 - layout/base/crashtests/243159-2.xhtml | 26 - layout/base/crashtests/355993-1.xhtml | 26 - layout/base/crashtests/384649-1.xhtml | 31 -- layout/base/crashtests/394150-1.xhtml | 27 - layout/base/crashtests/399676-1.xhtml | 7 - layout/base/crashtests/400445-1.xhtml | 22 - layout/base/crashtests/400904-1.xhtml | 20 - layout/base/crashtests/crashtests.list | 12 +- layout/base/nsBidiPresUtils.cpp | 247 +++++---- layout/base/nsBidiPresUtils.h | 6 +- layout/base/nsCSSFrameConstructor.cpp | 240 +++------ layout/base/nsCSSFrameConstructor.h | 51 +- layout/base/nsDocumentViewer.cpp | 6 +- layout/base/nsLayoutUtils.cpp | 14 +- layout/base/nsLayoutUtils.h | 8 +- layout/base/nsPresContext.cpp | 1 - layout/base/nsPresContext.h | 3 +- layout/base/nsRefreshDriver.cpp | 3 +- layout/base/tests/mochitest.toml | 2 + layout/base/tests/test_bug1836801.html | 59 ++ .../base/tests/test_event_target_iframe_oop.html | 177 ------ layout/build/components.conf | 10 - layout/build/moz.build | 1 - layout/build/nsContentDLF.cpp | 1 - layout/build/nsLayoutCID.h | 105 ---- layout/build/nsLayoutModule.cpp | 2 - layout/forms/HTMLSelectEventListener.cpp | 2 +- layout/forms/crashtests/crashtests.list | 2 +- layout/forms/moz.build | 1 - layout/forms/nsButtonFrameRenderer.cpp | 471 ---------------- layout/forms/nsButtonFrameRenderer.h | 83 --- layout/forms/nsComboboxControlFrame.cpp | 600 +++------------------ layout/forms/nsComboboxControlFrame.h | 128 +---- layout/forms/nsFieldSetFrame.cpp | 10 - layout/forms/nsGfxButtonControlFrame.cpp | 4 - layout/forms/nsGfxButtonControlFrame.h | 23 +- layout/forms/nsHTMLButtonControlFrame.cpp | 175 +++++- layout/forms/nsHTMLButtonControlFrame.h | 15 +- layout/forms/nsNumberControlFrame.cpp | 25 +- layout/forms/test/test_bug536567_perwindowpb.html | 2 +- layout/forms/test/test_bug935876.html | 14 +- layout/generic/BlockReflowState.cpp | 31 +- layout/generic/BlockReflowState.h | 20 +- layout/generic/FrameClasses.py | 18 +- layout/generic/ScrollAnchorContainer.cpp | 7 +- layout/generic/ScrollAnimationMSDPhysics.cpp | 14 +- layout/generic/ScrollOrigin.h | 2 - layout/generic/ScrollPositionUpdate.cpp | 15 - layout/generic/ScrollPositionUpdate.h | 6 - layout/generic/StickyScrollContainer.cpp | 11 +- layout/generic/TextOverflow.cpp | 16 +- layout/generic/ViewportFrame.cpp | 1 - layout/generic/WritingModes.h | 10 +- layout/generic/crashtests/1140268-1.html | 18 - layout/generic/crashtests/364686-1.xhtml | 12 - layout/generic/crashtests/368461-1.xhtml | 11 - layout/generic/crashtests/370884-1.xhtml | 14 - layout/generic/crashtests/382208-1.xhtml | 7 - layout/generic/crashtests/382396-1.xhtml | 7 - layout/generic/crashtests/385265-1.xhtml | 13 - layout/generic/crashtests/395450-1.xhtml | 28 - layout/generic/crashtests/467914-1.html | 3 - layout/generic/crashtests/547843-1.xhtml | 1 - layout/generic/crashtests/700031.xhtml | 9 - layout/generic/crashtests/crashtests.list | 17 +- layout/generic/nsBlockFrame.cpp | 506 +++++++++-------- layout/generic/nsBlockFrame.h | 31 +- layout/generic/nsBlockReflowContext.cpp | 2 +- layout/generic/nsContainerFrame.cpp | 52 +- layout/generic/nsFloatManager.h | 4 +- layout/generic/nsFrameSelection.cpp | 2 - layout/generic/nsFrameStateBits.h | 31 +- layout/generic/nsGfxScrollFrame.cpp | 91 ++-- layout/generic/nsGfxScrollFrame.h | 8 +- layout/generic/nsGridContainerFrame.cpp | 87 +-- layout/generic/nsGridContainerFrame.h | 6 +- layout/generic/nsHTMLParts.h | 4 - layout/generic/nsIFrame.cpp | 108 +++- layout/generic/nsIFrame.h | 15 +- layout/generic/nsImageFrame.cpp | 14 +- layout/generic/nsLineLayout.cpp | 5 +- layout/generic/nsTextFrame.cpp | 22 +- layout/generic/nsTextFrame.h | 8 +- layout/generic/nsTextPaintStyle.cpp | 4 +- layout/generic/nsTextPaintStyle.h | 5 +- layout/inspector/InspectorUtils.cpp | 93 +++- layout/inspector/InspectorUtils.h | 16 +- layout/inspector/tests/mochitest.toml | 3 + layout/inspector/tests/test_bug877690.html | 2 +- layout/inspector/tests/test_color_to.html | 116 ++++ layout/mathml/nsIMathMLFrame.h | 8 - layout/mathml/nsMathMLContainerFrame.cpp | 57 +- layout/mathml/nsMathMLTokenFrame.cpp | 2 - layout/mathml/nsMathMLmencloseFrame.cpp | 4 +- layout/mathml/nsMathMLmoFrame.cpp | 2 +- layout/mathml/nsMathMLmpaddedFrame.cpp | 3 +- layout/mathml/nsMathMLmrootFrame.cpp | 19 +- layout/mathml/nsMathMLmspaceFrame.cpp | 1 - layout/mathml/tests/chrome.toml | 9 + layout/painting/ActiveLayerTracker.cpp | 50 +- layout/painting/RetainedDisplayListBuilder.cpp | 11 + layout/painting/nsDisplayItemTypesList.h | 4 - layout/painting/nsDisplayList.cpp | 31 +- layout/painting/nsDisplayList.h | 16 +- layout/reftests/abs-pos/reftest.list | 2 +- layout/reftests/async-scrolling/reftest.list | 174 +++--- layout/reftests/backgrounds/reftest.list | 2 +- layout/reftests/bidi/dirAuto/1103348-1-ref.html | 19 - layout/reftests/bidi/dirAuto/1103348-1.html | 36 -- layout/reftests/bidi/dirAuto/reftest.list | 1 - layout/reftests/bidi/numeral/reftest.list | 6 +- layout/reftests/bidi/reftest.list | 6 +- layout/reftests/border-image/reftest.list | 22 +- layout/reftests/border-radius/reftest.list | 8 +- layout/reftests/box-shadow/reftest.list | 16 +- layout/reftests/bugs/1553571-1.html | 16 +- layout/reftests/bugs/1553571-2.html | 16 +- layout/reftests/bugs/1878294-1-ref.html | 8 + layout/reftests/bugs/1878294-1.html | 41 ++ layout/reftests/bugs/reftest.list | 129 ++--- layout/reftests/canvas/reftest.list | 12 +- layout/reftests/columns/reftest.list | 4 +- layout/reftests/css-animations/reftest.list | 2 +- layout/reftests/css-blending/reftest.list | 24 +- layout/reftests/css-gradients/reftest.list | 22 +- layout/reftests/css-grid/reftest.list | 2 +- layout/reftests/display-list/reftest.list | 42 +- layout/reftests/first-letter/reftest.list | 4 +- layout/reftests/floats/reftest.list | 4 +- layout/reftests/font-face/reftest.list | 10 +- layout/reftests/font-inflation/reftest.list | 2 +- layout/reftests/font-matching/reftest.list | 16 +- layout/reftests/forms/fieldset/reftest.list | 2 +- layout/reftests/forms/input/file/reftest.list | 2 +- layout/reftests/forms/input/number/number.html | 2 + layout/reftests/forms/input/number/reftest.list | 6 +- layout/reftests/forms/input/radio/reftest.list | 2 +- .../input/text/autofill-author-background.html | 9 + layout/reftests/forms/input/text/reftest.list | 3 +- layout/reftests/forms/placeholder/reftest.list | 4 +- layout/reftests/forms/textarea/reftest.list | 2 +- layout/reftests/forms/textbox/reftest.list | 1 - layout/reftests/forms/textbox/setsize-ref.xhtml | 9 - layout/reftests/forms/textbox/setsize.xhtml | 8 - layout/reftests/high-contrast/reftest.list | 1 + .../high-contrast/transparent-textarea-ref.html | 4 + .../high-contrast/transparent-textarea.html | 17 + layout/reftests/image-element/reftest.list | 12 +- layout/reftests/image/reftest.list | 2 +- layout/reftests/invalidation/reftest.list | 2 +- layout/reftests/layers/reftest.list | 16 +- layout/reftests/list-item/reftest.list | 6 +- layout/reftests/mathml/largeop-1-ref.html | 0 layout/reftests/mathml/largeop-1.html | 0 .../mathml/mathml-mmultiscript-base-ref.html | 14 - .../reftests/mathml/mathml-mmultiscript-base.html | 16 - .../mathml/mathml-mmultiscript-mprescript-ref.html | 15 - .../mathml/mathml-mmultiscript-mprescript.html | 18 - layout/reftests/mathml/mirror-op-1-ref.html | 19 - layout/reftests/mathml/mirror-op-1.html | 14 - layout/reftests/mathml/mirror-op-2-ref.html | 9 - layout/reftests/mathml/mirror-op-2.html | 9 - layout/reftests/mathml/mirror-op-3-ref.html | 9 - layout/reftests/mathml/mirror-op-3.html | 9 - layout/reftests/mathml/mirror-op-4-ref.html | 9 - layout/reftests/mathml/mirror-op-4.html | 9 - layout/reftests/mathml/mmultiscript-align-ref.html | 42 -- layout/reftests/mathml/mmultiscript-align.html | 38 -- layout/reftests/mathml/mo-glyph-size-ref.html | 14 - layout/reftests/mathml/mo-glyph-size.html | 50 -- layout/reftests/mathml/mpadded-7-ref.html | 15 - layout/reftests/mathml/mpadded-7.html | 16 - layout/reftests/mathml/mpadded-8-ref.html | 15 - layout/reftests/mathml/mpadded-8.html | 16 - layout/reftests/mathml/mpadded-9-ref.html | 15 - layout/reftests/mathml/mpadded-9.html | 16 - layout/reftests/mathml/mstyle-2-ref.xhtml | 110 ---- layout/reftests/mathml/mstyle-2.xhtml | 113 ---- layout/reftests/mathml/mstyle-3-ref.xhtml | 133 ----- layout/reftests/mathml/mstyle-3.xhtml | 136 ----- layout/reftests/mathml/mstyle-4-ref.xhtml | 75 --- layout/reftests/mathml/mstyle-4.xhtml | 78 --- layout/reftests/mathml/multiscripts-1-ref.html | 71 --- layout/reftests/mathml/multiscripts-1.html | 71 --- .../munder-mover-align-accent-false-ref.html | 114 ---- .../mathml/munder-mover-align-accent-false.html | 98 ---- .../mathml/munder-mover-align-accent-true-ref.html | 114 ---- .../mathml/munder-mover-align-accent-true.html | 98 ---- .../mathml/munderover-align-accent-false-ref.html | 132 ----- .../mathml/munderover-align-accent-false.html | 104 ---- .../mathml/munderover-align-accent-true-ref.html | 132 ----- .../mathml/munderover-align-accent-true.html | 104 ---- .../mathml/munderover-empty-scripts-ref.html | 35 -- .../reftests/mathml/munderover-empty-scripts.html | 32 -- layout/reftests/mathml/overbar-width-1-ref.xhtml | 26 - layout/reftests/mathml/overbar-width-1.xhtml | 25 - layout/reftests/mathml/radicalbar-1.html | 48 -- layout/reftests/mathml/radicalbar-1a.html | 48 -- layout/reftests/mathml/radicalbar-1b.html | 48 -- layout/reftests/mathml/radicalbar-1c.html | 48 -- layout/reftests/mathml/radicalbar-1d.html | 48 -- layout/reftests/mathml/radicalbar-2.html | 47 -- layout/reftests/mathml/radicalbar-2a.html | 47 -- layout/reftests/mathml/radicalbar-2b.html | 47 -- layout/reftests/mathml/radicalbar-2c.html | 47 -- layout/reftests/mathml/radicalbar-2d.html | 47 -- layout/reftests/mathml/radicalbar-3.html | 47 -- layout/reftests/mathml/radicalbar-3a.html | 47 -- layout/reftests/mathml/radicalbar-3b.html | 47 -- layout/reftests/mathml/radicalbar-3c.html | 47 -- layout/reftests/mathml/radicalbar-3d.html | 47 -- layout/reftests/mathml/reftest.list | 55 -- layout/reftests/mathml/scale-stretchy-1-ref.xhtml | 26 - layout/reftests/mathml/scale-stretchy-1.xhtml | 41 -- layout/reftests/mathml/scale-stretchy-2-ref.xhtml | 26 - layout/reftests/mathml/scale-stretchy-2.xhtml | 41 -- layout/reftests/mathml/scale-stretchy-3-ref.xhtml | 27 - layout/reftests/mathml/scale-stretchy-3.xhtml | 43 -- layout/reftests/mathml/scale-stretchy-4-ref.xhtml | 27 - layout/reftests/mathml/scale-stretchy-4.xhtml | 43 -- layout/reftests/mathml/scale-stretchy-5-ref.xhtml | 14 - layout/reftests/mathml/scale-stretchy-5.xhtml | 14 - .../mathml/scriptlevel-movablelimits-1-ref.html | 25 - .../mathml/scriptlevel-movablelimits-1.html | 25 - layout/reftests/mathml/semantics-1-ref.xhtml | 66 --- layout/reftests/mathml/semantics-1.xhtml | 66 --- layout/reftests/mathml/semantics-2-ref.html | 19 - layout/reftests/mathml/semantics-2.html | 19 - layout/reftests/mathml/semantics-3-ref.html | 21 - layout/reftests/mathml/semantics-3.html | 21 - layout/reftests/mathml/semantics-5-ref.html | 17 - layout/reftests/mathml/semantics-5.html | 17 - layout/reftests/mathml/stretchy-1-ref.html | 14 - layout/reftests/mathml/stretchy-1.html | 14 - layout/reftests/mathml/stretchy-largeop-1-ref.html | 56 -- layout/reftests/mathml/stretchy-largeop-1.html | 81 --- layout/reftests/mathml/stretchy-largeop-2-ref.html | 111 ---- layout/reftests/mathml/stretchy-largeop-2.html | 137 ----- layout/reftests/mathml/stretchy-largeop-3-ref.html | 123 ----- layout/reftests/mathml/stretchy-largeop-3.html | 156 ------ .../mathml/subscript-italic-correction-ref.html | 36 -- .../mathml/subscript-italic-correction.html | 61 --- layout/reftests/mathml/underbar-width-1-ref.xhtml | 26 - layout/reftests/mathml/underbar-width-1.xhtml | 25 - layout/reftests/mp4-video/reftest.list | 6 +- layout/reftests/native-theme/reftest.list | 2 +- layout/reftests/ogg-video/reftest.list | 2 +- layout/reftests/outline/reftest.list | 2 +- layout/reftests/pagination/reftest.list | 12 +- .../rowgroup-page-break-after-always-1-ref.html | 18 + .../rowgroup-page-break-after-always-2-ref.html | 24 + .../table-caption-splitaftercaption-5-ref.html | 6 +- .../pagination/table-nested-1308876-1-ref.html | 11 +- .../pagination/table-nested-1308876-1.xhtml | 6 +- .../table-page-break-before-auto-3-ref.html | 24 - .../pagination/table-tfoot-thead-1-ref.html | 2 +- .../reftests/percent-overflow-sizing/reftest.list | 34 +- .../reftests/position-dynamic-changes/reftest.list | 2 +- .../position-dynamic-changes/relative/reftest.list | 8 +- layout/reftests/position-sticky/reftest.list | 14 +- layout/reftests/reftest-sanity/reftest.list | 20 +- layout/reftests/reftest.list | 12 +- layout/reftests/scrolling/reftest.list | 12 +- layout/reftests/selection/reftest.list | 4 +- layout/reftests/svg/as-image/reftest.list | 18 +- .../reftests/svg/filters/css-filters/reftest.list | 32 +- layout/reftests/svg/filters/reftest.list | 8 +- .../svg/filters/svg-filter-chains/reftest.list | 2 +- layout/reftests/svg/moz-only/reftest.list | 4 +- layout/reftests/svg/reftest.list | 24 +- layout/reftests/svg/sizing/reftest.list | 36 +- layout/reftests/svg/smil/container/reftest.list | 8 +- layout/reftests/svg/smil/reftest.list | 2 +- .../svg/svg-integration/clip-path/reftest.list | 2 +- layout/reftests/svg/text/reftest.list | 12 +- layout/reftests/table-anonymous-boxes/reftest.list | 2 +- .../reftests/table-overflow/bug785684-x-ref.html | 1 - .../reftests/table-overflow/bug785684-y-ref.html | 1 - layout/reftests/table-overflow/reftest.list | 5 +- layout/reftests/text-overflow/reftest.list | 2 +- layout/reftests/text/reftest.list | 4 +- layout/reftests/text/webkit-text-security-1.html | 2 +- layout/reftests/transform-3d/reftest.list | 16 +- layout/reftests/transform/reftest.list | 2 +- layout/reftests/webm-video/reftest.list | 26 +- layout/reftests/writing-mode/reftest.list | 2 +- layout/reftests/xul/reftest.list | 2 +- layout/reftests/z-index/reftest.list | 6 +- layout/style/FontFaceSet.cpp | 1 - layout/style/GeckoBindings.cpp | 2 +- layout/style/Loader.cpp | 208 ++++--- layout/style/Loader.h | 5 +- layout/style/PseudoStyleType.h | 1 + layout/style/ServoBindings.toml | 60 +-- layout/style/ServoCSSParser.cpp | 10 + layout/style/ServoCSSParser.h | 21 + layout/style/ServoStyleConstsInlines.h | 68 +-- layout/style/ServoStyleSet.h | 4 +- layout/style/SheetLoadData.h | 6 +- layout/style/StreamLoader.cpp | 114 +++- layout/style/StreamLoader.h | 10 +- layout/style/StyleSheet.cpp | 47 +- layout/style/StyleSheet.h | 31 +- layout/style/contenteditable.css | 4 - layout/style/crashtests/1397439-1.html | 6 - layout/style/crashtests/1403465.html | 24 - layout/style/crashtests/411603-1.html | 7 - layout/style/crashtests/413274-1.xhtml | 18 - layout/style/crashtests/418007-1.xhtml | 24 - layout/style/crashtests/crashtests.list | 5 - layout/style/nsCSSAnonBoxList.h | 1 - layout/style/nsComputedDOMStyle.cpp | 28 +- layout/style/nsComputedDOMStyle.h | 6 + layout/style/nsICSSDeclaration.h | 5 + layout/style/nsMediaFeatures.cpp | 3 + layout/style/nsStyleStruct.cpp | 11 +- layout/style/nsStyleStruct.h | 7 + layout/style/nsStyleTransformMatrix.cpp | 3 +- layout/style/nsTransitionManager.cpp | 12 +- layout/style/nsTransitionManager.h | 1 + layout/style/res/forms.css | 63 +-- layout/style/res/html.css | 133 ++--- layout/style/test/ParseCSS.cpp | 1 - layout/style/test/animation_utils.js | 2 + layout/style/test/chrome/bug418986-2.js | 2 + layout/style/test/mochitest.toml | 1 + layout/style/test/property_database.js | 84 ++- .../test/test_shorthand_property_getters.html | 14 +- layout/svg/SVGGeometryFrame.cpp | 32 +- layout/svg/SVGGradientFrame.cpp | 3 +- layout/svg/SVGPatternFrame.cpp | 2 +- layout/svg/SVGTextFrame.cpp | 169 ++++-- layout/svg/SVGUtils.h | 6 + layout/svg/crashtests/1882921-1.html | 7 + layout/svg/crashtests/crashtests.list | 1 + layout/tables/crashtests/1555757-1.html | 16 - layout/tables/crashtests/1555757-2.html | 27 - layout/tables/crashtests/1881157.html | 26 + layout/tables/crashtests/347506-1.xhtml | 23 - layout/tables/crashtests/crashtests.list | 6 +- layout/tables/nsCellMap.cpp | 6 +- layout/tables/nsTableCellFrame.cpp | 19 +- layout/tables/nsTableFrame.cpp | 245 ++++++--- layout/tables/nsTableFrame.h | 3 +- layout/tables/nsTableRowFrame.cpp | 72 ++- .../layout-debug/src/nsLayoutDebuggingTools.cpp | 2 - .../tools/layout-debug/ui/content/layoutdebug.js | 2 +- layout/tools/reftest/api.js | 2 +- layout/tools/reftest/reftest-content.js | 20 +- layout/tools/reftest/reftest.sys.mjs | 14 +- layout/tools/reftest/runreftest.py | 2 +- layout/xul/nsMenuPopupFrame.cpp | 33 +- layout/xul/nsSplitterFrame.cpp | 1 - layout/xul/nsXULTooltipListener.cpp | 64 +-- layout/xul/reftest/reftest.list | 2 +- layout/xul/test/browser_bug685470.js | 4 +- layout/xul/test/browser_bug703210.js | 4 +- layout/xul/test/browser_bug706743.js | 4 +- layout/xul/test/chrome.toml | 1 - layout/xul/test/test_windowminmaxsize.xhtml | 62 +-- layout/xul/test/titledpanelwindow.xhtml | 5 - 370 files changed, 3629 insertions(+), 8705 deletions(-) delete mode 100644 layout/base/crashtests/1435015.html delete mode 100644 layout/base/crashtests/243159-2.xhtml delete mode 100644 layout/base/crashtests/355993-1.xhtml delete mode 100644 layout/base/crashtests/384649-1.xhtml delete mode 100644 layout/base/crashtests/394150-1.xhtml delete mode 100644 layout/base/crashtests/399676-1.xhtml delete mode 100644 layout/base/crashtests/400445-1.xhtml delete mode 100644 layout/base/crashtests/400904-1.xhtml create mode 100644 layout/base/tests/test_bug1836801.html delete mode 100644 layout/base/tests/test_event_target_iframe_oop.html delete mode 100644 layout/build/nsLayoutCID.h delete mode 100644 layout/forms/nsButtonFrameRenderer.cpp delete mode 100644 layout/forms/nsButtonFrameRenderer.h delete mode 100644 layout/generic/crashtests/1140268-1.html delete mode 100644 layout/generic/crashtests/364686-1.xhtml delete mode 100644 layout/generic/crashtests/368461-1.xhtml delete mode 100644 layout/generic/crashtests/370884-1.xhtml delete mode 100644 layout/generic/crashtests/382208-1.xhtml delete mode 100644 layout/generic/crashtests/382396-1.xhtml delete mode 100644 layout/generic/crashtests/385265-1.xhtml delete mode 100644 layout/generic/crashtests/395450-1.xhtml delete mode 100644 layout/generic/crashtests/467914-1.html delete mode 100644 layout/generic/crashtests/547843-1.xhtml delete mode 100644 layout/generic/crashtests/700031.xhtml create mode 100644 layout/inspector/tests/test_color_to.html delete mode 100644 layout/reftests/bidi/dirAuto/1103348-1-ref.html delete mode 100644 layout/reftests/bidi/dirAuto/1103348-1.html create mode 100644 layout/reftests/bugs/1878294-1-ref.html create mode 100644 layout/reftests/bugs/1878294-1.html create mode 100644 layout/reftests/forms/input/number/number.html create mode 100644 layout/reftests/forms/input/text/autofill-author-background.html delete mode 100644 layout/reftests/forms/textbox/setsize-ref.xhtml delete mode 100644 layout/reftests/forms/textbox/setsize.xhtml create mode 100644 layout/reftests/high-contrast/transparent-textarea-ref.html create mode 100644 layout/reftests/high-contrast/transparent-textarea.html delete mode 100644 layout/reftests/mathml/largeop-1-ref.html delete mode 100644 layout/reftests/mathml/largeop-1.html delete mode 100644 layout/reftests/mathml/mathml-mmultiscript-base-ref.html delete mode 100644 layout/reftests/mathml/mathml-mmultiscript-base.html delete mode 100644 layout/reftests/mathml/mathml-mmultiscript-mprescript-ref.html delete mode 100644 layout/reftests/mathml/mathml-mmultiscript-mprescript.html delete mode 100644 layout/reftests/mathml/mirror-op-1-ref.html delete mode 100644 layout/reftests/mathml/mirror-op-1.html delete mode 100644 layout/reftests/mathml/mirror-op-2-ref.html delete mode 100644 layout/reftests/mathml/mirror-op-2.html delete mode 100644 layout/reftests/mathml/mirror-op-3-ref.html delete mode 100644 layout/reftests/mathml/mirror-op-3.html delete mode 100644 layout/reftests/mathml/mirror-op-4-ref.html delete mode 100644 layout/reftests/mathml/mirror-op-4.html delete mode 100644 layout/reftests/mathml/mmultiscript-align-ref.html delete mode 100644 layout/reftests/mathml/mmultiscript-align.html delete mode 100644 layout/reftests/mathml/mo-glyph-size-ref.html delete mode 100644 layout/reftests/mathml/mo-glyph-size.html delete mode 100644 layout/reftests/mathml/mpadded-7-ref.html delete mode 100644 layout/reftests/mathml/mpadded-7.html delete mode 100644 layout/reftests/mathml/mpadded-8-ref.html delete mode 100644 layout/reftests/mathml/mpadded-8.html delete mode 100644 layout/reftests/mathml/mpadded-9-ref.html delete mode 100644 layout/reftests/mathml/mpadded-9.html delete mode 100644 layout/reftests/mathml/mstyle-2-ref.xhtml delete mode 100644 layout/reftests/mathml/mstyle-2.xhtml delete mode 100644 layout/reftests/mathml/mstyle-3-ref.xhtml delete mode 100644 layout/reftests/mathml/mstyle-3.xhtml delete mode 100644 layout/reftests/mathml/mstyle-4-ref.xhtml delete mode 100644 layout/reftests/mathml/mstyle-4.xhtml delete mode 100644 layout/reftests/mathml/multiscripts-1-ref.html delete mode 100644 layout/reftests/mathml/multiscripts-1.html delete mode 100644 layout/reftests/mathml/munder-mover-align-accent-false-ref.html delete mode 100644 layout/reftests/mathml/munder-mover-align-accent-false.html delete mode 100644 layout/reftests/mathml/munder-mover-align-accent-true-ref.html delete mode 100644 layout/reftests/mathml/munder-mover-align-accent-true.html delete mode 100644 layout/reftests/mathml/munderover-align-accent-false-ref.html delete mode 100644 layout/reftests/mathml/munderover-align-accent-false.html delete mode 100644 layout/reftests/mathml/munderover-align-accent-true-ref.html delete mode 100644 layout/reftests/mathml/munderover-align-accent-true.html delete mode 100644 layout/reftests/mathml/munderover-empty-scripts-ref.html delete mode 100644 layout/reftests/mathml/munderover-empty-scripts.html delete mode 100644 layout/reftests/mathml/overbar-width-1-ref.xhtml delete mode 100644 layout/reftests/mathml/overbar-width-1.xhtml delete mode 100644 layout/reftests/mathml/radicalbar-1.html delete mode 100644 layout/reftests/mathml/radicalbar-1a.html delete mode 100644 layout/reftests/mathml/radicalbar-1b.html delete mode 100644 layout/reftests/mathml/radicalbar-1c.html delete mode 100644 layout/reftests/mathml/radicalbar-1d.html delete mode 100644 layout/reftests/mathml/radicalbar-2.html delete mode 100644 layout/reftests/mathml/radicalbar-2a.html delete mode 100644 layout/reftests/mathml/radicalbar-2b.html delete mode 100644 layout/reftests/mathml/radicalbar-2c.html delete mode 100644 layout/reftests/mathml/radicalbar-2d.html delete mode 100644 layout/reftests/mathml/radicalbar-3.html delete mode 100644 layout/reftests/mathml/radicalbar-3a.html delete mode 100644 layout/reftests/mathml/radicalbar-3b.html delete mode 100644 layout/reftests/mathml/radicalbar-3c.html delete mode 100644 layout/reftests/mathml/radicalbar-3d.html delete mode 100644 layout/reftests/mathml/reftest.list delete mode 100644 layout/reftests/mathml/scale-stretchy-1-ref.xhtml delete mode 100644 layout/reftests/mathml/scale-stretchy-1.xhtml delete mode 100644 layout/reftests/mathml/scale-stretchy-2-ref.xhtml delete mode 100644 layout/reftests/mathml/scale-stretchy-2.xhtml delete mode 100644 layout/reftests/mathml/scale-stretchy-3-ref.xhtml delete mode 100644 layout/reftests/mathml/scale-stretchy-3.xhtml delete mode 100644 layout/reftests/mathml/scale-stretchy-4-ref.xhtml delete mode 100644 layout/reftests/mathml/scale-stretchy-4.xhtml delete mode 100644 layout/reftests/mathml/scale-stretchy-5-ref.xhtml delete mode 100644 layout/reftests/mathml/scale-stretchy-5.xhtml delete mode 100644 layout/reftests/mathml/scriptlevel-movablelimits-1-ref.html delete mode 100644 layout/reftests/mathml/scriptlevel-movablelimits-1.html delete mode 100644 layout/reftests/mathml/semantics-1-ref.xhtml delete mode 100644 layout/reftests/mathml/semantics-1.xhtml delete mode 100644 layout/reftests/mathml/semantics-2-ref.html delete mode 100644 layout/reftests/mathml/semantics-2.html delete mode 100644 layout/reftests/mathml/semantics-3-ref.html delete mode 100644 layout/reftests/mathml/semantics-3.html delete mode 100644 layout/reftests/mathml/semantics-5-ref.html delete mode 100644 layout/reftests/mathml/semantics-5.html delete mode 100644 layout/reftests/mathml/stretchy-1-ref.html delete mode 100644 layout/reftests/mathml/stretchy-1.html delete mode 100644 layout/reftests/mathml/stretchy-largeop-1-ref.html delete mode 100644 layout/reftests/mathml/stretchy-largeop-1.html delete mode 100644 layout/reftests/mathml/stretchy-largeop-2-ref.html delete mode 100644 layout/reftests/mathml/stretchy-largeop-2.html delete mode 100644 layout/reftests/mathml/stretchy-largeop-3-ref.html delete mode 100644 layout/reftests/mathml/stretchy-largeop-3.html delete mode 100644 layout/reftests/mathml/subscript-italic-correction-ref.html delete mode 100644 layout/reftests/mathml/subscript-italic-correction.html delete mode 100644 layout/reftests/mathml/underbar-width-1-ref.xhtml delete mode 100644 layout/reftests/mathml/underbar-width-1.xhtml create mode 100644 layout/reftests/pagination/rowgroup-page-break-after-always-1-ref.html create mode 100644 layout/reftests/pagination/rowgroup-page-break-after-always-2-ref.html delete mode 100644 layout/reftests/pagination/table-page-break-before-auto-3-ref.html delete mode 100644 layout/style/crashtests/1397439-1.html delete mode 100644 layout/style/crashtests/1403465.html delete mode 100644 layout/style/crashtests/411603-1.html delete mode 100644 layout/style/crashtests/413274-1.xhtml delete mode 100644 layout/style/crashtests/418007-1.xhtml create mode 100644 layout/svg/crashtests/1882921-1.html delete mode 100644 layout/tables/crashtests/1555757-1.html delete mode 100644 layout/tables/crashtests/1555757-2.html create mode 100644 layout/tables/crashtests/1881157.html delete mode 100644 layout/tables/crashtests/347506-1.xhtml delete mode 100644 layout/xul/test/titledpanelwindow.xhtml (limited to 'layout') diff --git a/layout/base/LayoutTelemetryTools.h b/layout/base/LayoutTelemetryTools.h index 25c80dcc2c..43eee79923 100644 --- a/layout/base/LayoutTelemetryTools.h +++ b/layout/base/LayoutTelemetryTools.h @@ -38,9 +38,9 @@ enum class LayoutSubsystem : uint8_t { }; using LayoutSubsystemDurations = - EnumeratedArray; + EnumeratedArray; using LayoutFlushCount = - EnumeratedArray; + EnumeratedArray; struct Data { Data(); diff --git a/layout/base/MotionPathUtils.cpp b/layout/base/MotionPathUtils.cpp index c81020645d..4045f2304a 100644 --- a/layout/base/MotionPathUtils.cpp +++ b/layout/base/MotionPathUtils.cpp @@ -111,9 +111,11 @@ CSSCoord MotionPathUtils::GetRayContainReferenceSize(nsIFrame* aFrame) { const auto size = CSSSize::FromAppUnits( (aFrame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT) ? nsLayoutUtils::ComputeSVGReferenceRect( - aFrame, aFrame->StyleSVGReset()->HasNonScalingStroke() - ? StyleGeometryBox::FillBox - : StyleGeometryBox::StrokeBox) + aFrame, + aFrame->StyleSVGReset()->HasNonScalingStroke() + ? StyleGeometryBox::FillBox + : StyleGeometryBox::StrokeBox, + nsLayoutUtils::MayHaveNonScalingStrokeCyclicDependency::Yes) : nsLayoutUtils::ComputeHTMLReferenceRect( aFrame, StyleGeometryBox::BorderBox)) .Size()); diff --git a/layout/base/PositionedEventTargeting.cpp b/layout/base/PositionedEventTargeting.cpp index e159239f16..a975372dea 100644 --- a/layout/base/PositionedEventTargeting.cpp +++ b/layout/base/PositionedEventTargeting.cpp @@ -249,18 +249,6 @@ static nsIContent* GetClickableAncestor( return content; } - // Bug 921928: we don't have access to the content of remote iframe. - // So fluffing won't go there. We do an optimistic assumption here: - // that the content of the remote iframe needs to be a target. - if (content->IsHTMLElement(nsGkAtoms::iframe) && - content->AsElement()->AttrValueIs(kNameSpaceID_None, - nsGkAtoms::mozbrowser, - nsGkAtoms::_true, eIgnoreCase) && - content->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::remote, - nsGkAtoms::_true, eIgnoreCase)) { - return content; - } - // See nsCSSFrameConstructor::FindXULTagData. This code is not // really intended to be used with XUL, though. if (content->IsAnyOfXULElements( diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index 90a9eee411..31c21c3377 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -9,11 +9,13 @@ #include "mozilla/PresShell.h" #include "Units.h" +#include "mozilla/EventForwards.h" #include "mozilla/RefPtr.h" #include "mozilla/dom/AncestorIterator.h" #include "mozilla/dom/FontFaceSet.h" #include "mozilla/dom/ElementBinding.h" #include "mozilla/dom/LargestContentfulPaint.h" +#include "mozilla/dom/MouseEventBinding.h" #include "mozilla/dom/PerformanceMainThread.h" #include "mozilla/dom/HTMLAreaElement.h" #include "mozilla/ArrayUtils.h" @@ -45,6 +47,7 @@ #include "mozilla/StaticPrefs_font.h" #include "mozilla/StaticPrefs_image.h" #include "mozilla/StaticPrefs_layout.h" +#include "mozilla/StaticPrefs_test.h" #include "mozilla/StaticPrefs_toolkit.h" #include "mozilla/Try.h" #include "mozilla/TextEvents.h" @@ -562,35 +565,52 @@ class nsBeforeFirstPaintDispatcher : public Runnable { class MOZ_STACK_CLASS AutoPointerEventTargetUpdater final { public: AutoPointerEventTargetUpdater(PresShell* aShell, WidgetEvent* aEvent, - nsIFrame* aFrame, nsIContent** aTargetContent) { + nsIFrame* aFrame, nsIContent* aTargetContent, + nsIContent** aOutTargetContent) { MOZ_ASSERT(aEvent); - if (!aTargetContent || aEvent->mClass != ePointerEventClass) { + if (!aOutTargetContent || aEvent->mClass != ePointerEventClass) { // Make the destructor happy. - mTargetContent = nullptr; + mOutTargetContent = nullptr; return; } MOZ_ASSERT(aShell); - MOZ_ASSERT(aFrame); - MOZ_ASSERT(!aFrame->GetContent() || - aShell->GetDocument() == aFrame->GetContent()->OwnerDoc()); + MOZ_ASSERT_IF(aFrame && aFrame->GetContent(), + aShell->GetDocument() == aFrame->GetContent()->OwnerDoc()); mShell = aShell; mWeakFrame = aFrame; - mTargetContent = aTargetContent; - aShell->mPointerEventTarget = aFrame->GetContent(); + mOutTargetContent = aOutTargetContent; + mFromTouch = aEvent->AsPointerEvent()->mFromTouchEvent; + // Touch event target may have no frame, e.g., removed from the DOM + MOZ_ASSERT_IF(!mFromTouch, aFrame); + mOriginalPointerEventTarget = aShell->mPointerEventTarget = + aFrame ? aFrame->GetContent() : aTargetContent; } ~AutoPointerEventTargetUpdater() { - if (!mTargetContent || !mShell || mWeakFrame.IsAlive()) { + if (!mOutTargetContent || !mShell || mWeakFrame.IsAlive()) { return; } - mShell->mPointerEventTarget.swap(*mTargetContent); + if (mFromTouch) { + // If the source event is a touch event, the touch event target should + // always be same target as preceding ePointerDown. Therefore, we should + // always set it back to the original event target. + mOriginalPointerEventTarget.swap(*mOutTargetContent); + } else { + // If the source event is not a touch event (must be a mouse event in + // this case), the event should be fired on the closest inclusive ancestor + // of the pointer event target which is still connected. The mutations + // are tracked by PresShell::ContentRemoved. Therefore, we should set it. + mShell->mPointerEventTarget.swap(*mOutTargetContent); + } } private: RefPtr mShell; + nsCOMPtr mOriginalPointerEventTarget; AutoWeakFrame mWeakFrame; - nsIContent** mTargetContent; + nsIContent** mOutTargetContent; + bool mFromTouch = false; }; bool PresShell::sDisableNonTestMouseEvents = false; @@ -5421,7 +5441,6 @@ bool PresShell::IsTransparentContainerElement() const { case dom::PrefersColorSchemeOverride::Dark: return pc->DefaultBackgroundColorScheme() == ColorScheme::Dark; case dom::PrefersColorSchemeOverride::None: - case dom::PrefersColorSchemeOverride::EndGuard_: break; } } @@ -6888,18 +6907,13 @@ PresShell* PresShell::GetShellForTouchEvent(WidgetGUIEvent* aEvent) { return nullptr; } - nsCOMPtr content = do_QueryInterface(oldTouch->GetTarget()); + nsIContent* const content = + nsIContent::FromEventTargetOrNull(oldTouch->GetTarget()); if (!content) { return nullptr; } - nsIFrame* contentFrame = content->GetPrimaryFrame(); - if (!contentFrame) { - return nullptr; - } - - PresShell* presShell = contentFrame->PresContext()->GetPresShell(); - if (presShell) { + if (PresShell* const presShell = content->OwnerDoc()->GetPresShell()) { return presShell; } } @@ -7249,12 +7263,6 @@ nsresult PresShell::EventHandler::HandleEventUsingCoordinates( return NS_OK; } - // frame could be null after dispatching pointer events. - // XXX Despite of this comment, we update the event target data outside - // DispatchPrecedingPointerEvent(). Can we make it call - // UpdateTouchEventTarget()? - eventTargetData.UpdateTouchEventTarget(aGUIEvent); - // Handle the event in the correct shell. // We pass the subshell's root frame as the frame to start from. This is // the only correct alternative; if the event was captured then it @@ -7267,7 +7275,17 @@ nsresult PresShell::EventHandler::HandleEventUsingCoordinates( nsresult rv = eventHandler.HandleEventWithCurrentEventInfo( aGUIEvent, aEventStatus, true, MOZ_KnownLive(eventTargetData.mOverrideClickTarget)); - return rv; + if (NS_FAILED(rv) || + MOZ_UNLIKELY(eventTargetData.mPresShell->IsDestroying())) { + return rv; + } + + if (aGUIEvent->mMessage == eTouchEnd) { + MaybeSynthesizeCompatMouseEventsForTouchEnd(aGUIEvent->AsTouchEvent(), + aEventStatus); + } + + return NS_OK; } bool PresShell::EventHandler::MaybeFlushPendingNotifications( @@ -7436,41 +7454,58 @@ bool PresShell::EventHandler::DispatchPrecedingPointerEvent( AutoWeakFrame weakTargetFrame(targetFrame); AutoWeakFrame weakFrame(aEventTargetData->GetFrame()); - nsCOMPtr content(aEventTargetData->GetContent()); + nsCOMPtr pointerEventTargetContent( + aEventTargetData->GetContent()); RefPtr presShell(aEventTargetData->mPresShell); - nsCOMPtr targetContent; + nsCOMPtr mouseOrTouchEventTargetContent; PointerEventHandler::DispatchPointerFromMouseOrTouch( - presShell, aEventTargetData->GetFrame(), content, aGUIEvent, - aDontRetargetEvents, aEventStatus, getter_AddRefs(targetContent)); + presShell, aEventTargetData->GetFrame(), pointerEventTargetContent, + aGUIEvent, aDontRetargetEvents, aEventStatus, + getter_AddRefs(mouseOrTouchEventTargetContent)); // If the target frame is alive, the caller should keep handling the event // unless event target frame is destroyed. - if (weakTargetFrame.IsAlive()) { - return weakFrame.IsAlive(); + if (weakTargetFrame.IsAlive() && weakFrame.IsAlive()) { + aEventTargetData->UpdateTouchEventTarget(aGUIEvent); + return true; } - // If the event is not a mouse event, the caller should keep handling the - // event unless event target frame is destroyed. Note that this case is - // not defined by the spec. - if (aGUIEvent->mClass != eMouseEventClass) { - return weakFrame.IsAlive(); + presShell->FlushPendingNotifications(FlushType::Layout); + if (MOZ_UNLIKELY(mPresShell->IsDestroying())) { + return false; } - // Spec defines that mouse events must be dispatched to the same target as - // the pointer event. If the target is no longer participating in its - // ownerDocument's tree, fire the event at the original target's nearest - // ancestor node - if (!targetContent) { + // The spec defines that mouse events must be dispatched to the same target as + // the pointer event. + // The Touch Events spec defines that touch events must be dispatched to the + // same target as touch start and the other browsers dispatch touch events + // even if the touch event target is not connected to the document. + // Retargetting the event is handled by AutoPointerEventTargetUpdater and + // mouseOrTouchEventTargetContent stores the result. + + // If the target is no longer participating in its ownerDocument's tree, + // fire the event at the original target's nearest ancestor node. + if (!mouseOrTouchEventTargetContent) { + MOZ_ASSERT(aGUIEvent->mClass == eMouseEventClass); return false; } - aEventTargetData->SetFrameAndContent(targetContent->GetPrimaryFrame(), - targetContent); - aEventTargetData->mPresShell = PresShell::GetShellForEventTarget( - aEventTargetData->GetFrame(), aEventTargetData->GetContent()); + aEventTargetData->SetFrameAndContent( + mouseOrTouchEventTargetContent->GetPrimaryFrame(), + mouseOrTouchEventTargetContent); + aEventTargetData->mPresShell = + mouseOrTouchEventTargetContent->IsInComposedDoc() + ? PresShell::GetShellForEventTarget(aEventTargetData->GetFrame(), + aEventTargetData->GetContent()) + : mouseOrTouchEventTargetContent->OwnerDoc()->GetPresShell(); // If new target PresShel is not found, we cannot keep handling the event. - return !!aEventTargetData->mPresShell; + if (!aEventTargetData->mPresShell) { + return false; + } + + aEventTargetData->UpdateTouchEventTarget(aGUIEvent); + return true; } /** @@ -7586,6 +7621,60 @@ bool PresShell::EventHandler::MaybeHandleEventWithAccessibleCaret( return true; } +void PresShell::EventHandler::MaybeSynthesizeCompatMouseEventsForTouchEnd( + const WidgetTouchEvent* aTouchEndEvent, + const nsEventStatus* aStatus) const { + MOZ_ASSERT(aTouchEndEvent->mMessage == eTouchEnd); + + // If the eTouchEnd event is dispatched via APZ, APZCCallbackHelper dispatches + // a set of mouse events with better handling. Therefore, we don't need to + // handle that here. + if (!aTouchEndEvent->mFlags.mIsSynthesizedForTests || + StaticPrefs::test_events_async_enabled()) { + return; + } + + // If the tap was consumed or 2 or more touches occurred, we don't need the + // compatibility mouse events. + if (*aStatus == nsEventStatus_eConsumeNoDefault || + !TouchManager::IsSingleTapEndToDoDefault(aTouchEndEvent)) { + return; + } + + if (NS_WARN_IF(!aTouchEndEvent->mWidget)) { + return; + } + + nsCOMPtr widget = aTouchEndEvent->mWidget; + + // NOTE: I think that we don't need to implement a double click here becase + // WebDriver does not support a way to synthesize a double click and Chrome + // does not fire "dblclick" even if doing `pointerDown().pointerUp()` twice. + // FIXME: Currently we don't support long tap. + RefPtr presShell = mPresShell; + for (const EventMessage message : {eMouseMove, eMouseDown, eMouseUp}) { + if (MOZ_UNLIKELY(presShell->IsDestroying())) { + break; + } + nsIFrame* frameForPresShell = GetNearestFrameContainingPresShell(presShell); + if (!frameForPresShell) { + break; + } + WidgetMouseEvent event(true, message, widget, WidgetMouseEvent::eReal, + WidgetMouseEvent::eNormal); + event.mRefPoint = aTouchEndEvent->mTouches[0]->mRefPoint; + event.mButton = MouseButton::ePrimary; + event.mButtons = message == eMouseDown ? MouseButtonsFlag::ePrimaryFlag + : MouseButtonsFlag::eNoButtons; + event.mInputSource = MouseEvent_Binding::MOZ_SOURCE_TOUCH; + event.mClickCount = message == eMouseMove ? 0 : 1; + event.mModifiers = aTouchEndEvent->mModifiers; + event.convertToPointer = false; + nsEventStatus mouseEventStatus = nsEventStatus_eIgnore; + presShell->HandleEvent(frameForPresShell, &event, false, &mouseEventStatus); + } +} + bool PresShell::EventHandler::MaybeDiscardEvent(WidgetGUIEvent* aGUIEvent) { MOZ_ASSERT(aGUIEvent); @@ -8252,7 +8341,7 @@ nsresult PresShell::EventHandler::HandleEventWithTarget( mPresShell->RecordPointerLocation(aEvent->AsMouseEvent()); } AutoPointerEventTargetUpdater updater(mPresShell, aEvent, aNewEventFrame, - aTargetContent); + aNewEventContent, aTargetContent); AutoCurrentEventInfoSetter eventInfoSetter(*this, aNewEventFrame, aNewEventContent); nsresult rv = HandleEventWithCurrentEventInfo(aEvent, aEventStatus, false, @@ -8360,7 +8449,7 @@ nsresult PresShell::EventHandler::HandleEventWithCurrentEventInfo( manager->TryToFlushPendingNotificationsToIME(); } - FinalizeHandlingEvent(aEvent); + FinalizeHandlingEvent(aEvent, aEventStatus); RecordEventHandlingResponsePerformance(aEvent); @@ -8512,7 +8601,8 @@ bool PresShell::EventHandler::PrepareToDispatchEvent( } } -void PresShell::EventHandler::FinalizeHandlingEvent(WidgetEvent* aEvent) { +void PresShell::EventHandler::FinalizeHandlingEvent( + WidgetEvent* aEvent, const nsEventStatus* aStatus) { switch (aEvent->mMessage) { case eKeyPress: case eKeyDown: @@ -8562,6 +8652,16 @@ void PresShell::EventHandler::FinalizeHandlingEvent(WidgetEvent* aEvent) { } return; } + case eTouchStart: + case eTouchMove: + case eTouchEnd: + case eTouchCancel: + case eTouchPointerCancel: + case eMouseLongTap: + case eContextMenu: { + mPresShell->mTouchManager.PostHandleEvent(aEvent, aStatus); + break; + } default: return; } @@ -11955,7 +12055,7 @@ void PresShell::EventHandler::EventTargetData::UpdateTouchEventTarget( nsIFrame* newFrame = TouchManager::SuppressInvalidPointsAndGetTargetedFrame(touchEvent); if (!newFrame) { - return; // XXX Why don't we stop handling the event in this case? + return; } SetFrameAndComputePresShellAndContent(newFrame, aGUIEvent); return; diff --git a/layout/base/PresShell.h b/layout/base/PresShell.h index c6a965e81e..482ace1421 100644 --- a/layout/base/PresShell.h +++ b/layout/base/PresShell.h @@ -2439,6 +2439,14 @@ class PresShell final : public nsStubDocumentObserver, WidgetGUIEvent* aGUIEvent, nsEventStatus* aEventStatus); + /** + * Maybe dispatch mouse events for aTouchEnd. This should be called after + * aTouchEndEvent is dispatched into the DOM. + */ + MOZ_CAN_RUN_SCRIPT void MaybeSynthesizeCompatMouseEventsForTouchEnd( + const WidgetTouchEvent* aTouchEndEvent, + const nsEventStatus* aStatus) const; + /** * MaybeDiscardOrDelayKeyboardEvent() may discared or put aGUIEvent into * the delayed event queue if it's a keyboard event and if we should do so. @@ -2821,8 +2829,10 @@ class PresShell final : public nsStubDocumentObserver, * and then, this cleans up the state of mPresShell and aEvent. * * @param aEvent The handled event. + * @param aStatus The status of aEvent. Must not be nullptr. */ - MOZ_CAN_RUN_SCRIPT void FinalizeHandlingEvent(WidgetEvent* aEvent); + MOZ_CAN_RUN_SCRIPT void FinalizeHandlingEvent(WidgetEvent* aEvent, + const nsEventStatus* aStatus); /** * AutoCurrentEventInfoSetter() pushes and pops current event info of diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 9c313a254c..8c07512093 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -2709,6 +2709,7 @@ enum class ServoPostTraversalFlags : uint32_t { MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoPostTraversalFlags) +#ifdef ACCESSIBILITY static bool IsVisibleForA11y(const ComputedStyle& aStyle) { return aStyle.StyleVisibility()->IsVisible() && !aStyle.StyleUI()->IsInert(); } @@ -2717,6 +2718,7 @@ static bool IsSubtreeVisibleForA11y(const ComputedStyle& aStyle) { return aStyle.StyleDisplay()->mContentVisibility != StyleContentVisibility::Hidden; } +#endif // Send proper accessibility notifications and return post traversal // flags for kids. @@ -3450,11 +3452,8 @@ void RestyleManager::MaybeRestyleForNthOfState(ServoStyleSet& aStyleSet, static inline bool AttributeInfluencesOtherPseudoClassState( const Element& aElement, const nsAtom* aAttribute) { - // We must record some state for :-moz-browser-frame, - // :-moz-table-border-nonzero, and :-moz-select-list-box. - if (aAttribute == nsGkAtoms::mozbrowser) { - return aElement.IsAnyOfHTMLElements(nsGkAtoms::iframe, nsGkAtoms::frame); - } + // We must record some state for :-moz-table-border-nonzero and + // :-moz-select-list-box. if (aAttribute == nsGkAtoms::border) { return aElement.IsHTMLElement(nsGkAtoms::table); diff --git a/layout/base/TouchManager.cpp b/layout/base/TouchManager.cpp index 0c34567b65..42ea78eb2e 100644 --- a/layout/base/TouchManager.cpp +++ b/layout/base/TouchManager.cpp @@ -7,9 +7,13 @@ #include "TouchManager.h" +#include "Units.h" +#include "mozilla/EventForwards.h" +#include "mozilla/PresShell.h" +#include "mozilla/StaticPrefs_test.h" +#include "mozilla/TimeStamp.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/EventTarget.h" -#include "mozilla/PresShell.h" #include "mozilla/layers/InputAPZContext.h" #include "nsIContent.h" #include "nsIFrame.h" @@ -24,6 +28,8 @@ namespace mozilla { StaticAutoPtr> TouchManager::sCaptureTouchList; layers::LayersId TouchManager::sCaptureTouchLayersId; +TimeStamp TouchManager::sSingleTouchStartTimeStamp; +LayoutDeviceIntPoint TouchManager::sSingleTouchStartPoint; /*static*/ void TouchManager::InitializeStatics() { @@ -168,7 +174,7 @@ nsIFrame* TouchManager::SuppressInvalidPointsAndGetTargetedFrame( } nsIFrame* frame = nullptr; - for (int32_t i = aEvent->mTouches.Length(); i;) { + for (uint32_t i = aEvent->mTouches.Length(); i;) { --i; dom::Touch* touch = aEvent->mTouches[i]; if (TouchManager::HasCapturedTouch(touch->Identifier())) { @@ -176,9 +182,35 @@ nsIFrame* TouchManager::SuppressInvalidPointsAndGetTargetedFrame( } MOZ_ASSERT(touch->mOriginalTarget); - nsCOMPtr targetContent = do_QueryInterface(touch->GetTarget()); - nsIFrame* targetFrame = - targetContent ? targetContent->GetPrimaryFrame() : nullptr; + nsIContent* const targetContent = + nsIContent::FromEventTargetOrNull(touch->GetTarget()); + if (MOZ_UNLIKELY(!targetContent)) { + touch->mIsTouchEventSuppressed = true; + continue; + } + + // Even if the target content is not connected, we should dispatch the touch + // start event except when the target content is owned by different + // document. + if (MOZ_UNLIKELY(!targetContent->IsInComposedDoc())) { + if (anyTarget && anyTarget->OwnerDoc() != targetContent->OwnerDoc()) { + touch->mIsTouchEventSuppressed = true; + continue; + } + if (!anyTarget) { + anyTarget = targetContent; + } + touch->SetTouchTarget(targetContent->GetAsElementOrParentElement()); + if (PresShell* const presShell = + targetContent->OwnerDoc()->GetPresShell()) { + if (nsIFrame* rootFrame = presShell->GetRootFrame()) { + frame = rootFrame; + } + } + continue; + } + + nsIFrame* targetFrame = targetContent->GetPrimaryFrame(); if (targetFrame && !anyTarget) { anyTarget = targetContent; } else { @@ -202,10 +234,12 @@ nsIFrame* TouchManager::SuppressInvalidPointsAndGetTargetedFrame( touch->mIsTouchEventSuppressed = true; } else { targetFrame = newTargetFrame; - targetFrame->GetContentForEvent(aEvent, getter_AddRefs(targetContent)); - touch->SetTouchTarget(targetContent - ? targetContent->GetAsElementOrParentElement() - : nullptr); + nsCOMPtr newTargetContent; + targetFrame->GetContentForEvent(aEvent, + getter_AddRefs(newTargetContent)); + touch->SetTouchTarget( + newTargetContent ? newTargetContent->GetAsElementOrParentElement() + : nullptr); } } if (targetFrame) { @@ -236,8 +270,11 @@ bool TouchManager::PreHandleEvent(WidgetEvent* aEvent, nsEventStatus* aStatus, // touch event associated to. We cache layers id of the first touchstart // event, all subsequent touch events will use the same layers id. sCaptureTouchLayersId = aEvent->mLayersId; + sSingleTouchStartTimeStamp = aEvent->mTimeStamp; + sSingleTouchStartPoint = aEvent->AsTouchEvent()->mTouches[0]->mRefPoint; } else { touchEvent->mLayersId = sCaptureTouchLayersId; + sSingleTouchStartTimeStamp = TimeStamp(); } // Add any new touches to the queue WidgetTouchEvent::TouchArray& touches = touchEvent->mTouches; @@ -404,6 +441,60 @@ bool TouchManager::PreHandleEvent(WidgetEvent* aEvent, nsEventStatus* aStatus, return true; } +void TouchManager::PostHandleEvent(const WidgetEvent* aEvent, + const nsEventStatus* aStatus) { + switch (aEvent->mMessage) { + case eTouchMove: { + if (sSingleTouchStartTimeStamp.IsNull()) { + break; + } + if (*aStatus == nsEventStatus_eConsumeNoDefault) { + sSingleTouchStartTimeStamp = TimeStamp(); + break; + } + const WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent(); + if (touchEvent->mTouches.Length() > 1) { + sSingleTouchStartTimeStamp = TimeStamp(); + break; + } + if (touchEvent->mTouches.Length() == 1) { + // If the touch moved too far from the start point, don't treat the + // touch as a tap. + const float distance = + static_cast((sSingleTouchStartPoint - + aEvent->AsTouchEvent()->mTouches[0]->mRefPoint) + .Length()); + const float maxDistance = + StaticPrefs::apz_touch_start_tolerance() * + (MOZ_LIKELY(touchEvent->mWidget) ? touchEvent->mWidget->GetDPI() + : 96.0f); + if (distance > maxDistance) { + sSingleTouchStartTimeStamp = TimeStamp(); + } + } + break; + } + case eTouchStart: + case eTouchEnd: + if (*aStatus == nsEventStatus_eConsumeNoDefault && + !sSingleTouchStartTimeStamp.IsNull()) { + sSingleTouchStartTimeStamp = TimeStamp(); + } + break; + case eTouchCancel: + case eTouchPointerCancel: + case eMouseLongTap: + case eContextMenu: { + if (!sSingleTouchStartTimeStamp.IsNull()) { + sSingleTouchStartTimeStamp = TimeStamp(); + } + break; + } + default: + break; + } +} + /*static*/ already_AddRefed TouchManager::GetAnyCapturedTouchTarget() { nsCOMPtr result = nullptr; @@ -473,4 +564,25 @@ bool TouchManager::ShouldConvertTouchToPointer(const Touch* aTouch, return true; } +/* static */ +bool TouchManager::IsSingleTapEndToDoDefault( + const WidgetTouchEvent* aTouchEndEvent) { + MOZ_ASSERT(aTouchEndEvent); + MOZ_ASSERT(aTouchEndEvent->mFlags.mIsSynthesizedForTests); + MOZ_ASSERT(!StaticPrefs::test_events_async_enabled()); + if (sSingleTouchStartTimeStamp.IsNull() || + aTouchEndEvent->mTouches.Length() != 1) { + return false; + } + // If it's pressed long time, we should not treat it as a single tap because + // a long press should cause opening context menu by default. + if ((aTouchEndEvent->mTimeStamp - sSingleTouchStartTimeStamp) + .ToMilliseconds() > StaticPrefs::apz_max_tap_time()) { + return false; + } + NS_WARNING_ASSERTION(aTouchEndEvent->mTouches[0]->mChanged, + "The single tap end should be changed"); + return true; +} + } // namespace mozilla diff --git a/layout/base/TouchManager.h b/layout/base/TouchManager.h index 0e12c25c7d..40b9083bdb 100644 --- a/layout/base/TouchManager.h +++ b/layout/base/TouchManager.h @@ -12,6 +12,7 @@ #ifndef TouchManager_h_ #define TouchManager_h_ +#include "Units.h" #include "mozilla/BasicEvents.h" #include "mozilla/dom/Touch.h" #include "mozilla/StaticPtr.h" @@ -20,6 +21,7 @@ namespace mozilla { class PresShell; +class TimeStamp; class TouchManager { public: @@ -52,6 +54,8 @@ class TouchManager { bool PreHandleEvent(mozilla::WidgetEvent* aEvent, nsEventStatus* aStatus, bool& aTouchIsNew, nsCOMPtr& aCurrentEventContent); + void PostHandleEvent(const mozilla::WidgetEvent* aEvent, + const nsEventStatus* aStatus); static already_AddRefed GetAnyCapturedTouchTarget(); static bool HasCapturedTouch(int32_t aId); @@ -59,6 +63,12 @@ class TouchManager { static bool ShouldConvertTouchToPointer(const dom::Touch* aTouch, const WidgetTouchEvent* aEvent); + // This should be called after PostHandleEvent() is called. Note that this + // cannot check touches outside this process. So, this should not be used for + // actual user input handling. This is designed for a fallback path to + // dispatch mouse events for touch events synthesized without APZ. + static bool IsSingleTapEndToDoDefault(const WidgetTouchEvent* aTouchEndEvent); + private: void EvictTouches(dom::Document* aLimitToDocument = nullptr); static void EvictTouchPoint(RefPtr& aTouch, @@ -77,6 +87,12 @@ class TouchManager { static StaticAutoPtr> sCaptureTouchList; static layers::LayersId sCaptureTouchLayersId; + // The last start of a single tap. This will be set to "Null" if the tap is + // consumed or becomes not a single tap. + static TimeStamp sSingleTouchStartTimeStamp; + // The last start point of the single tap tracked with + // sSingleTouchStartTimeStamp. + static LayoutDeviceIntPoint sSingleTouchStartPoint; }; } // namespace mozilla diff --git a/layout/base/crashtests/1435015.html b/layout/base/crashtests/1435015.html deleted file mode 100644 index 329aaca22f..0000000000 --- a/layout/base/crashtests/1435015.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - diff --git a/layout/base/crashtests/243159-2.xhtml b/layout/base/crashtests/243159-2.xhtml deleted file mode 100644 index 79d9bcd90a..0000000000 --- a/layout/base/crashtests/243159-2.xhtml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - diff --git a/layout/base/crashtests/355993-1.xhtml b/layout/base/crashtests/355993-1.xhtml deleted file mode 100644 index e902ee550e..0000000000 --- a/layout/base/crashtests/355993-1.xhtml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - -
- - - - - - 1 - - - - -
- - - \ No newline at end of file diff --git a/layout/base/crashtests/384649-1.xhtml b/layout/base/crashtests/384649-1.xhtml deleted file mode 100644 index e2ba50cdee..0000000000 --- a/layout/base/crashtests/384649-1.xhtml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -
- - - - x - - - y - - - -
- - - - diff --git a/layout/base/crashtests/394150-1.xhtml b/layout/base/crashtests/394150-1.xhtml deleted file mode 100644 index b2349c9f8b..0000000000 --- a/layout/base/crashtests/394150-1.xhtml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/layout/base/crashtests/399676-1.xhtml b/layout/base/crashtests/399676-1.xhtml deleted file mode 100644 index 82b547e5ea..0000000000 --- a/layout/base/crashtests/399676-1.xhtml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/layout/base/crashtests/400445-1.xhtml b/layout/base/crashtests/400445-1.xhtml deleted file mode 100644 index 9cb71dbbd6..0000000000 --- a/layout/base/crashtests/400445-1.xhtml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - diff --git a/layout/base/crashtests/400904-1.xhtml b/layout/base/crashtests/400904-1.xhtml deleted file mode 100644 index a00f42fd02..0000000000 --- a/layout/base/crashtests/400904-1.xhtml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - diff --git a/layout/base/crashtests/crashtests.list b/layout/base/crashtests/crashtests.list index 44572dad53..d9cf87f4d2 100644 --- a/layout/base/crashtests/crashtests.list +++ b/layout/base/crashtests/crashtests.list @@ -7,7 +7,7 @@ load 56746-1.html load 89101-1.html load 89358-1.html load 90205-1.html -skip-if(cocoaWidget&&browserIsRemote) load 99776-1.html # Bug 849747 +skip-if(cocoaWidget) load 99776-1.html # Bug 849747 load 118931-1.html load 121533-1.html load 123049-1.html @@ -31,7 +31,6 @@ load 234851-1.html load 234851-2.html load 241300-1.html load 243159-1.html -load 243159-2.xhtml load 243519-1.html load 244490-1.html load 254367-1.html @@ -116,7 +115,6 @@ load 350267-1.html load 354133-1.html load 354766-1.xhtml load 355989-1.xhtml -load 355993-1.xhtml load chrome://reftest/content/crashtests/layout/base/crashtests/356325-1.xhtml load 358729-1.xhtml skip-if(Android) load chrome://reftest/content/crashtests/layout/base/crashtests/360339-1.xhtml @@ -151,7 +149,6 @@ load 383129-1.html load 384344-1.html load 384392-1.xhtml load 384392-2.svg -load 384649-1.xhtml load 385354.html load 385866-1.xhtml load 385880-1.xhtml @@ -163,7 +160,6 @@ load 388715-1.html load 390976-1.html load 393661-1.html load 393801-1.html -load 394150-1.xhtml load 397011-1.xhtml load 398510-1.xhtml load 398733-1.html @@ -171,13 +167,10 @@ load 398733-2.html load 399132-1.xhtml load 399219-1.xhtml load 399365-1.html -load 399676-1.xhtml load 399687-1.html load 399940-1.xhtml load 399951-1.html load 399994-1.html -load 400445-1.xhtml -load 400904-1.xhtml load 401734-1.html load 401734-2.html needs-focus pref(accessibility.browsewithcaret,true) load 403048.html @@ -258,7 +251,7 @@ load 468645-3.xhtml load 469861-1.xhtml load 469861-2.xhtml load 470851-1.xhtml -asserts-if(Android&&!asyncPan,1-2) load 473042.xhtml # bug 1034369 (may also cause a few assertions to be registered on the next test) +load 473042.xhtml # bug 1034369 (may also cause a few assertions to be registered on the next test) asserts(1) load 474075.html # bug 1775003 load 477333-1.xhtml load 477731-1.html @@ -483,7 +476,6 @@ load 1428892.html load 1429088.html load 1429961.html load 1429962.html -load 1435015.html load 1437155.html load 1439016.html load 1442018-1.html diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp index b1215972c2..0331a7e5a0 100644 --- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -47,9 +47,10 @@ using BidiClass = intl::BidiClass; using BidiDirection = intl::BidiDirection; using BidiEmbeddingLevel = intl::BidiEmbeddingLevel; -static const char16_t kSpace = 0x0020; +static const char16_t kNextLine = 0x0085; static const char16_t kZWSP = 0x200B; static const char16_t kLineSeparator = 0x2028; +static const char16_t kParagraphSeparator = 0x2029; static const char16_t kObjectSubstitute = 0xFFFC; static const char16_t kLRE = 0x202A; static const char16_t kRLE = 0x202B; @@ -60,11 +61,12 @@ static const char16_t kLRI = 0x2066; static const char16_t kRLI = 0x2067; static const char16_t kFSI = 0x2068; static const char16_t kPDI = 0x2069; -// All characters with Bidi type Segment Separator or Block Separator +// All characters with Bidi type Segment Separator or Block Separator. +// This should be kept in sync with the table in ReplaceSeparators. static const char16_t kSeparators[] = { - char16_t('\t'), char16_t('\r'), char16_t('\n'), char16_t(0xb), - char16_t(0x1c), char16_t(0x1d), char16_t(0x1e), char16_t(0x1f), - char16_t(0x85), char16_t(0x2029), char16_t(0)}; + char16_t('\t'), char16_t('\r'), char16_t('\n'), char16_t(0xb), + char16_t(0x1c), char16_t(0x1d), char16_t(0x1e), char16_t(0x1f), + kNextLine, kParagraphSeparator, char16_t(0)}; #define NS_BIDI_CONTROL_FRAME ((nsIFrame*)0xfffb1d1) @@ -478,115 +480,99 @@ struct MOZ_STACK_CLASS BidiParagraphData { } }; -struct MOZ_STACK_CLASS BidiLineData { - AutoTArray mLogicalFrames; - AutoTArray mVisualFrames; - AutoTArray mIndexMap; - AutoTArray mLevels; - bool mIsReordered; - +class MOZ_STACK_CLASS BidiLineData { + public: BidiLineData(nsIFrame* aFirstFrameOnLine, int32_t aNumFramesOnLine) { - /** - * Initialize the logically-ordered array of frames using the top-level - * frames of a single line - */ - bool isReordered = false; - bool hasRTLFrames = false; - bool hasVirtualControls = false; - + // Initialize the logically-ordered array of frames using the top-level + // frames of a single line auto appendFrame = [&](nsIFrame* frame, BidiEmbeddingLevel level) { mLogicalFrames.AppendElement(frame); mLevels.AppendElement(level); mIndexMap.AppendElement(0); - if (level.IsRTL()) { - hasRTLFrames = true; - } }; - bool firstFrame = true; for (nsIFrame* frame = aFirstFrameOnLine; frame && aNumFramesOnLine--; frame = frame->GetNextSibling()) { FrameBidiData bidiData = nsBidiPresUtils::GetFrameBidiData(frame); - // Ignore virtual control before the first frame. Doing so should - // not affect the visual result, but could avoid running into the - // stripping code below for many cases. - if (!firstFrame && bidiData.precedingControl != kBidiLevelNone) { + if (bidiData.precedingControl != kBidiLevelNone) { appendFrame(NS_BIDI_CONTROL_FRAME, bidiData.precedingControl); - hasVirtualControls = true; } appendFrame(frame, bidiData.embeddingLevel); - firstFrame = false; } // Reorder the line - BidiEngine::ReorderVisual(mLevels.Elements(), FrameCount(), + BidiEngine::ReorderVisual(mLevels.Elements(), mLevels.Length(), mIndexMap.Elements()); - // Strip virtual frames - if (hasVirtualControls) { - auto originalCount = mLogicalFrames.Length(); - AutoTArray realFrameMap; - realFrameMap.SetCapacity(originalCount); - size_t count = 0; - for (auto i : IntegerRange(originalCount)) { - if (mLogicalFrames[i] == NS_BIDI_CONTROL_FRAME) { - realFrameMap.AppendElement(-1); - } else { - mLogicalFrames[count] = mLogicalFrames[i]; - mLevels[count] = mLevels[i]; - realFrameMap.AppendElement(count); - count++; - } + // Collect the frames in visual order, omitting virtual controls + // and noting whether frames are reordered. + for (uint32_t i = 0; i < mIndexMap.Length(); i++) { + nsIFrame* frame = mLogicalFrames[mIndexMap[i]]; + if (frame == NS_BIDI_CONTROL_FRAME) { + continue; } - // Only keep index map for real frames. - for (size_t i = 0, j = 0; i < originalCount; ++i) { - auto newIndex = realFrameMap[mIndexMap[i]]; - if (newIndex != -1) { - mIndexMap[j] = newIndex; - j++; - } + mVisualFrameIndex.AppendElement(mIndexMap[i]); + if (int32_t(i) != mIndexMap[i]) { + mIsReordered = true; } - mLogicalFrames.TruncateLength(count); - mLevels.TruncateLength(count); - mIndexMap.TruncateLength(count); } + } - for (int32_t i = 0; i < FrameCount(); i++) { - mVisualFrames.AppendElement(LogicalFrameAt(mIndexMap[i])); - if (i != mIndexMap[i]) { - isReordered = true; - } - } + uint32_t LogicalFrameCount() const { return mLogicalFrames.Length(); } + uint32_t VisualFrameCount() const { return mVisualFrameIndex.Length(); } - // If there's an RTL frame, assume the line is reordered - mIsReordered = isReordered || hasRTLFrames; + nsIFrame* LogicalFrameAt(uint32_t aIndex) const { + return mLogicalFrames[aIndex]; } - int32_t FrameCount() const { return mLogicalFrames.Length(); } + nsIFrame* VisualFrameAt(uint32_t aIndex) const { + return mLogicalFrames[mVisualFrameIndex[aIndex]]; + } - nsIFrame* LogicalFrameAt(int32_t aIndex) const { - return mLogicalFrames[aIndex]; + std::pair VisualFrameAndLevelAt( + uint32_t aIndex) const { + int32_t index = mVisualFrameIndex[aIndex]; + return std::pair(mLogicalFrames[index], mLevels[index]); } - nsIFrame* VisualFrameAt(int32_t aIndex) const { - return mVisualFrames[aIndex]; + bool IsReordered() const { return mIsReordered; } + + void InitContinuationStates(nsContinuationStates* aContinuationStates) const { + for (auto* frame : mLogicalFrames) { + if (frame != NS_BIDI_CONTROL_FRAME) { + nsBidiPresUtils::InitContinuationStates(frame, aContinuationStates); + } + } } + + private: + AutoTArray mLogicalFrames; + AutoTArray mVisualFrameIndex; + AutoTArray mIndexMap; + AutoTArray mLevels; + bool mIsReordered = false; }; #ifdef DEBUG extern "C" { -void MOZ_EXPORT DumpFrameArray(const nsTArray& aFrames) { - for (nsIFrame* frame : aFrames) { +void MOZ_EXPORT DumpBidiLine(BidiLineData* aData, bool aVisualOrder) { + auto dump = [](nsIFrame* frame) { if (frame == NS_BIDI_CONTROL_FRAME) { fprintf_stderr(stderr, "(Bidi control frame)\n"); } else { frame->List(); } - } -} + }; -void MOZ_EXPORT DumpBidiLine(BidiLineData* aData, bool aVisualOrder) { - DumpFrameArray(aVisualOrder ? aData->mVisualFrames : aData->mLogicalFrames); + if (aVisualOrder) { + for (uint32_t i = 0; i < aData->VisualFrameCount(); i++) { + dump(aData->VisualFrameAt(i)); + } + } else { + for (uint32_t i = 0; i < aData->LogicalFrameCount(); i++) { + dump(aData->LogicalFrameAt(i)); + } + } } } #endif @@ -870,11 +856,32 @@ nsresult nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame) { return ResolveParagraph(&bpd); } +// In ResolveParagraph, we previously used ReplaceChar(kSeparators, kSpace) +// to convert separators to spaces, but this hard-coded implementation is +// substantially faster than the general-purpose ReplaceChar function. +// This must be kept in sync with the definition of kSeparators. +static inline void ReplaceSeparators(nsString& aText, size_t aStartIndex = 0) { + for (char16_t* cp = aText.BeginWriting() + aStartIndex; + cp < aText.EndWriting(); cp++) { + if (MOZ_UNLIKELY(*cp < char16_t(' '))) { + static constexpr char16_t SeparatorToSpace[32] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, ' ', ' ', + ' ', 0x0c, ' ', 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, ' ', ' ', ' ', ' ', + }; + *cp = SeparatorToSpace[*cp]; + } else if (MOZ_UNLIKELY(*cp == kNextLine || *cp == kParagraphSeparator)) { + *cp = ' '; + } + } +} + nsresult nsBidiPresUtils::ResolveParagraph(BidiParagraphData* aBpd) { if (aBpd->BufferLength() < 1) { return NS_OK; } - aBpd->mBuffer.ReplaceChar(kSeparators, kSpace); + + ReplaceSeparators(aBpd->mBuffer); int32_t runCount; @@ -1506,8 +1513,19 @@ nscoord nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine, aStart = 0; } + // No need to bidi-reorder the line if there's only a single frame. + if (aNumFramesOnLine == 1) { + auto bidiData = nsBidiPresUtils::GetFrameBidiData(aFirstFrameOnLine); + nsContinuationStates continuationStates; + InitContinuationStates(aFirstFrameOnLine, &continuationStates); + return aStart + RepositionFrame(aFirstFrameOnLine, + bidiData.embeddingLevel.IsLTR(), aStart, + &continuationStates, aLineWM, false, + containerSize); + } + BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine); - return RepositionInlineFrames(&bld, aLineWM, containerSize, aStart); + return RepositionInlineFrames(bld, aLineWM, containerSize, aStart); } nsIFrame* nsBidiPresUtils::GetFirstLeaf(nsIFrame* aFrame) { @@ -1857,40 +1875,30 @@ void nsBidiPresUtils::InitContinuationStates( } /* static */ -nscoord nsBidiPresUtils::RepositionInlineFrames(BidiLineData* aBld, +nscoord nsBidiPresUtils::RepositionInlineFrames(const BidiLineData& aBld, WritingMode aLineWM, const nsSize& aContainerSize, nscoord aStart) { - nscoord start = aStart; - nsIFrame* frame; - int32_t count = aBld->mVisualFrames.Length(); - int32_t index; nsContinuationStates continuationStates; + aBld.InitContinuationStates(&continuationStates); - // Initialize continuation states to (nullptr, 0) for - // each frame on the line. - for (index = 0; index < count; index++) { - InitContinuationStates(aBld->VisualFrameAt(index), &continuationStates); - } - - // Reposition frames in visual order - int32_t step, limit; if (aLineWM.IsBidiLTR()) { - index = 0; - step = 1; - limit = count; + for (auto index : IntegerRange(aBld.VisualFrameCount())) { + auto [frame, level] = aBld.VisualFrameAndLevelAt(index); + aStart += + RepositionFrame(frame, level.IsLTR(), aStart, &continuationStates, + aLineWM, false, aContainerSize); + } } else { - index = count - 1; - step = -1; - limit = -1; - } - for (; index != limit; index += step) { - frame = aBld->VisualFrameAt(index); - start += RepositionFrame( - frame, !(aBld->mLevels[aBld->mIndexMap[index]].IsRTL()), start, - &continuationStates, aLineWM, false, aContainerSize); + for (auto index : Reversed(IntegerRange(aBld.VisualFrameCount()))) { + auto [frame, level] = aBld.VisualFrameAndLevelAt(index); + aStart += + RepositionFrame(frame, level.IsLTR(), aStart, &continuationStates, + aLineWM, false, aContainerSize); + } } - return start; + + return aStart; } bool nsBidiPresUtils::CheckLineOrder(nsIFrame* aFirstFrameOnLine, @@ -1898,16 +1906,15 @@ bool nsBidiPresUtils::CheckLineOrder(nsIFrame* aFirstFrameOnLine, nsIFrame** aFirstVisual, nsIFrame** aLastVisual) { BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine); - int32_t count = bld.FrameCount(); if (aFirstVisual) { *aFirstVisual = bld.VisualFrameAt(0); } if (aLastVisual) { - *aLastVisual = bld.VisualFrameAt(count - 1); + *aLastVisual = bld.VisualFrameAt(bld.VisualFrameCount() - 1); } - return bld.mIsReordered; + return bld.IsReordered(); } nsIFrame* nsBidiPresUtils::GetFrameToRightOf(const nsIFrame* aFrame, @@ -1915,9 +1922,11 @@ nsIFrame* nsBidiPresUtils::GetFrameToRightOf(const nsIFrame* aFrame, int32_t aNumFramesOnLine) { BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine); - int32_t count = bld.mVisualFrames.Length(); + int32_t count = bld.VisualFrameCount(); - if (aFrame == nullptr && count) return bld.VisualFrameAt(0); + if (!aFrame && count) { + return bld.VisualFrameAt(0); + } for (int32_t i = 0; i < count - 1; i++) { if (bld.VisualFrameAt(i) == aFrame) { @@ -1933,9 +1942,11 @@ nsIFrame* nsBidiPresUtils::GetFrameToLeftOf(const nsIFrame* aFrame, int32_t aNumFramesOnLine) { BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine); - int32_t count = bld.mVisualFrames.Length(); + int32_t count = bld.VisualFrameCount(); - if (aFrame == nullptr && count) return bld.VisualFrameAt(count - 1); + if (!aFrame && count) { + return bld.VisualFrameAt(count - 1); + } for (int32_t i = 1; i < count; i++) { if (bld.VisualFrameAt(i) == aFrame) { @@ -2476,9 +2487,19 @@ nsresult nsBidiPresUtils::ProcessTextForRenderingContext( nsIRenderingContextBidiProcessor processor(&aRenderingContext, aTextRunConstructionDrawTarget, &aFontMetrics, nsPoint(aX, aY)); - nsAutoString text(aText, aLength); - text.ReplaceChar(kSeparators, ' '); - return ProcessText(text.BeginReading(), text.Length(), aBaseLevel, + nsDependentSubstring text(aText, aLength); + auto separatorIndex = text.FindCharInSet(kSeparators); + if (separatorIndex == kNotFound) { + return ProcessText(text.BeginReading(), text.Length(), aBaseLevel, + aPresContext, processor, aMode, aPosResolve, + aPosResolveCount, aWidth, aPresContext->BidiEngine()); + } + + // We need to replace any block or segment separators with space for bidi + // processing, so make a local copy. + nsAutoString localText(text); + ReplaceSeparators(localText, separatorIndex); + return ProcessText(localText.BeginReading(), localText.Length(), aBaseLevel, aPresContext, processor, aMode, aPosResolve, aPosResolveCount, aWidth, aPresContext->BidiEngine()); } diff --git a/layout/base/nsBidiPresUtils.h b/layout/base/nsBidiPresUtils.h index c369a06f2d..80cf8fbc41 100644 --- a/layout/base/nsBidiPresUtils.h +++ b/layout/base/nsBidiPresUtils.h @@ -21,7 +21,7 @@ #endif struct BidiParagraphData; -struct BidiLineData; +class BidiLineData; class gfxContext; class nsFontMetrics; class nsIFrame; @@ -398,6 +398,8 @@ class nsBidiPresUtils { mozilla::ComputedStyle* aComputedStyle); private: + friend class BidiLineData; + static nsresult ProcessTextForRenderingContext( const char16_t* aText, int32_t aLength, mozilla::intl::BidiEmbeddingLevel aBaseLevel, nsPresContext* aPresContext, @@ -536,7 +538,7 @@ class nsBidiPresUtils { * * @lina 04/11/2000 */ - static nscoord RepositionInlineFrames(BidiLineData* aBld, + static nscoord RepositionInlineFrames(const BidiLineData& aBld, mozilla::WritingMode aLineWM, const nsSize& aContainerSize, nscoord aStart); diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 3c1896c162..149f2f24bf 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -170,6 +170,7 @@ nsIFrame* NS_NewSVGFEImageFrame(PresShell* aPresShell, ComputedStyle* aStyle); nsIFrame* NS_NewSVGFEUnstyledLeafFrame(PresShell* aPresShell, ComputedStyle* aStyle); nsIFrame* NS_NewFileControlLabelFrame(PresShell*, ComputedStyle*); +nsIFrame* NS_NewComboboxLabelFrame(PresShell*, ComputedStyle*); nsIFrame* NS_NewMiddleCroppingLabelFrame(PresShell*, ComputedStyle*); #include "mozilla/dom/NodeInfo.h" @@ -320,7 +321,7 @@ static bool ShouldSuppressColumnSpanDescendants(nsIFrame* aFrame) { } if (!aFrame->IsBlockFrameOrSubclass() || - aFrame->HasAnyStateBits(NS_BLOCK_BFC_STATE_BITS | NS_FRAME_OUT_OF_FLOW) || + aFrame->HasAnyStateBits(NS_BLOCK_BFC | NS_FRAME_OUT_OF_FLOW) || aFrame->IsFixedPosContainingBlock()) { // Need to suppress column-span if we: // - Are a different block formatting context, @@ -2286,7 +2287,7 @@ nsIFrame* nsCSSFrameConstructor::ConstructTableCell( aState, content, innerPseudoStyle, cellFrame, PseudoStyleType::scrolledContent, false, scrollFrame); } - cellInnerFrame = NS_NewBlockFormattingContext(mPresShell, innerPseudoStyle); + cellInnerFrame = NS_NewBlockFrame(mPresShell, innerPseudoStyle); } auto* parent = scrollFrame ? scrollFrame : cellFrame; InitAndRestoreFrame(aState, content, parent, cellInnerFrame); @@ -2566,7 +2567,7 @@ nsIFrame* nsCSSFrameConstructor::ConstructDocElementFrame( MOZ_ASSERT(display->mDisplay == StyleDisplay::Block || display->mDisplay == StyleDisplay::FlowRoot, "Unhandled display type for root element"); - contentFrame = NS_NewBlockFormattingContext(mPresShell, computedStyle); + contentFrame = NS_NewBlockFrame(mPresShell, computedStyle); ConstructBlock( state, aDocElement, state.GetGeometricParent(*display, mDocElementContainingBlock), @@ -3012,91 +3013,33 @@ static inline void ClearLazyBits(nsIContent* aStartContent, } } -nsIFrame* nsCSSFrameConstructor::ConstructSelectFrame( +/* static */ +const nsCSSFrameConstructor::FrameConstructionData* +nsCSSFrameConstructor::FindSelectData(const Element& aElement, + ComputedStyle& aStyle) { + // Construct a frame-based listbox or combobox + const auto* sel = dom::HTMLSelectElement::FromNode(aElement); + MOZ_ASSERT(sel); + if (sel->IsCombobox()) { + static constexpr FrameConstructionData sComboboxData{ + ToCreationFunc(NS_NewComboboxControlFrame), 0, + PseudoStyleType::buttonContent}; + return &sComboboxData; + } + // FIXME: Can we simplify this to avoid needing ConstructListboxSelectFrame, + // and reuse ConstructScrollableBlock or so? + static constexpr FrameConstructionData sListBoxData{ + &nsCSSFrameConstructor::ConstructListBoxSelectFrame}; + return &sListBoxData; +} + +nsIFrame* nsCSSFrameConstructor::ConstructListBoxSelectFrame( nsFrameConstructorState& aState, FrameConstructionItem& aItem, nsContainerFrame* aParentFrame, const nsStyleDisplay* aStyleDisplay, nsFrameList& aFrameList) { nsIContent* const content = aItem.mContent; ComputedStyle* const computedStyle = aItem.mComputedStyle; - // Construct a frame-based listbox or combobox - dom::HTMLSelectElement* sel = dom::HTMLSelectElement::FromNode(content); - MOZ_ASSERT(sel); - if (sel->IsCombobox()) { - // Construct a frame-based combo box. - // The frame-based combo box is built out of three parts. A display area, a - // button and a dropdown list. The display area and button are created - // through anonymous content. The drop-down list's frame is created - // explicitly. The combobox frame shares its content with the drop-down - // list. - nsComboboxControlFrame* comboboxFrame = - NS_NewComboboxControlFrame(mPresShell, computedStyle); - - // Save the history state so we don't restore during construction - // since the complete tree is required before we restore. - nsILayoutHistoryState* historyState = aState.mFrameState; - aState.mFrameState = nullptr; - // Initialize the combobox frame - InitAndRestoreFrame(aState, content, - aState.GetGeometricParent(*aStyleDisplay, aParentFrame), - comboboxFrame); - - comboboxFrame->AddStateBits(NS_FRAME_OWNS_ANON_BOXES); - - aState.AddChild(comboboxFrame, aFrameList, content, aParentFrame); - - // Resolve pseudo element style for the dropdown list - RefPtr listStyle = - mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle( - PseudoStyleType::dropDownList, computedStyle); - - // child frames of combobox frame - nsFrameList childList; - - // Create display and button frames from the combobox's anonymous content. - // The anonymous content is appended to existing anonymous content for this - // element (the scrollbars). - // - // nsComboboxControlFrame needs special frame creation behavior for its - // first piece of anonymous content, which means that we can't take the - // normal ProcessChildren path. - AutoTArray newAnonymousItems; - DebugOnly rv = - GetAnonymousContent(content, comboboxFrame, newAnonymousItems); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - MOZ_ASSERT(!newAnonymousItems.IsEmpty()); - - // Manually create a frame for the special NAC. - MOZ_ASSERT(newAnonymousItems[0].mContent == - comboboxFrame->GetDisplayNode()); - newAnonymousItems.RemoveElementAt(0); - nsIFrame* customFrame = comboboxFrame->CreateFrameForDisplayNode(); - MOZ_ASSERT(customFrame); - childList.AppendFrame(nullptr, customFrame); - - nsFrameConstructorSaveState floatSaveState; - aState.MaybePushFloatContainingBlock(comboboxFrame, floatSaveState); - - // The other piece of NAC can take the normal path. - AutoFrameConstructionItemList fcItems(this); - AutoFrameConstructionPageName pageNameTracker(aState, comboboxFrame); - AddFCItemsForAnonymousContent(aState, comboboxFrame, newAnonymousItems, - fcItems, pageNameTracker); - ConstructFramesFromItemList(aState, fcItems, comboboxFrame, - /* aParentIsWrapperAnonBox = */ false, - childList); - - comboboxFrame->SetInitialChildList(FrameChildListID::Principal, - std::move(childList)); - - aState.mFrameState = historyState; - if (aState.mFrameState) { - // Restore frame state for the entire subtree of |comboboxFrame|. - RestoreFrameState(comboboxFrame, aState.mFrameState); - } - return comboboxFrame; - } - // Listbox, not combobox nsContainerFrame* listFrame = NS_NewListControlFrame(mPresShell, computedStyle); @@ -3175,7 +3118,7 @@ nsIFrame* nsCSSFrameConstructor::ConstructFieldSetFrame( const nsStyleDisplay* fieldsetContentDisplay = fieldsetContentStyle->StyleDisplay(); - bool isScrollable = fieldsetContentDisplay->IsScrollableOverflow(); + const bool isScrollable = fieldsetContentDisplay->IsScrollableOverflow(); nsContainerFrame* scrollFrame = nullptr; if (isScrollable) { fieldsetContentStyle = BeginBuildingScrollFrame( @@ -3204,8 +3147,7 @@ nsIFrame* nsCSSFrameConstructor::ConstructFieldSetFrame( MOZ_ASSERT(fieldsetContentDisplay->mDisplay == StyleDisplay::Block, "bug in StyleAdjuster::adjust_for_fieldset_content?"); - contentFrame = - NS_NewBlockFormattingContext(mPresShell, fieldsetContentStyle); + contentFrame = NS_NewBlockFrame(mPresShell, fieldsetContentStyle); if (fieldsetContentStyle->StyleColumn()->IsColumnContainerStyle()) { contentFrameTop = BeginBuildingColumns( aState, content, parent, contentFrame, fieldsetContentStyle); @@ -3499,11 +3441,18 @@ nsCSSFrameConstructor::FindHTMLData(const Element& aElement, "Unexpected parent for fieldset content anon box"); if (aElement.IsInNativeAnonymousSubtree() && - aElement.NodeInfo()->NameAtom() == nsGkAtoms::label && - static_cast(do_QueryFrame(aParentFrame))) { - static constexpr FrameConstructionData sFileLabelData( - NS_NewFileControlLabelFrame); - return &sFileLabelData; + aElement.NodeInfo()->NameAtom() == nsGkAtoms::label && aParentFrame) { + if (static_cast(do_QueryFrame(aParentFrame))) { + static constexpr FrameConstructionData sFileLabelData( + NS_NewFileControlLabelFrame); + return &sFileLabelData; + } + if (aParentFrame->GetParent() && + aParentFrame->GetParent()->IsComboboxControlFrame()) { + static constexpr FrameConstructionData sComboboxLabelData( + NS_NewComboboxLabelFrame); + return &sComboboxLabelData; + } } static constexpr FrameConstructionDataByTag sHTMLData[] = { @@ -3515,7 +3464,7 @@ nsCSSFrameConstructor::FindHTMLData(const Element& aElement, SIMPLE_TAG_CREATE(wbr, NS_NewWBRFrame), SIMPLE_TAG_CHAIN(input, nsCSSFrameConstructor::FindInputData), SIMPLE_TAG_CREATE(textarea, NS_NewTextControlFrame), - COMPLEX_TAG_CREATE(select, &nsCSSFrameConstructor::ConstructSelectFrame), + SIMPLE_TAG_CHAIN(select, nsCSSFrameConstructor::FindSelectData), SIMPLE_TAG_CHAIN(object, nsCSSFrameConstructor::FindObjectData), SIMPLE_TAG_CHAIN(embed, nsCSSFrameConstructor::FindObjectData), COMPLEX_TAG_CREATE(fieldset, @@ -3741,11 +3690,6 @@ void nsCSSFrameConstructor::ConstructFrameFromItemInternal( CHECK_ONLY_ONE_BIT(FCDATA_WRAP_KIDS_IN_BLOCKS, FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS); #undef CHECK_ONLY_ONE_BIT - NS_ASSERTION(!(bits & FCDATA_FORCED_NON_SCROLLABLE_BLOCK) || - ((bits & FCDATA_FUNC_IS_FULL_CTOR) && - data->mFunc.mFullConstructor == - &nsCSSFrameConstructor::ConstructNonScrollableBlock), - "Unexpected FCDATA_FORCED_NON_SCROLLABLE_BLOCK flag"); MOZ_ASSERT( !(bits & FCDATA_IS_WRAPPER_ANON_BOX) || (bits & FCDATA_USE_CHILD_ITEMS), "Wrapper anon boxes should always have FCDATA_USE_CHILD_ITEMS"); @@ -3823,7 +3767,7 @@ void nsCSSFrameConstructor::ConstructFrameFromItemInternal( innerFrame = outerFrame; break; default: { - innerFrame = NS_NewBlockFormattingContext(mPresShell, outerStyle); + innerFrame = NS_NewBlockFrame(mPresShell, outerStyle); if (outerStyle->StyleColumn()->IsColumnContainerStyle()) { outerFrame = BeginBuildingColumns(aState, content, container, innerFrame, outerStyle); @@ -3836,7 +3780,7 @@ void nsCSSFrameConstructor::ConstructFrameFromItemInternal( } } } else { - innerFrame = NS_NewBlockFormattingContext(mPresShell, outerStyle); + innerFrame = NS_NewBlockFrame(mPresShell, outerStyle); InitAndRestoreFrame(aState, content, container, innerFrame); outerFrame = innerFrame; } @@ -4386,14 +4330,14 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay& aDisplay, // XXX Ignore tables for the time being (except caption) const uint32_t kCaptionCtorFlags = FCDATA_IS_TABLE_PART | FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable); - bool caption = aDisplay.mDisplay == StyleDisplay::TableCaption; - bool suppressScrollFrame = false; - bool needScrollFrame = + const bool caption = aDisplay.mDisplay == StyleDisplay::TableCaption; + const bool needScrollFrame = aDisplay.IsScrollableOverflow() && !propagatedScrollToViewport; if (needScrollFrame) { - suppressScrollFrame = mPresShell->GetPresContext()->IsPaginated() && - aDisplay.IsBlockOutsideStyle() && - !aElement.IsInNativeAnonymousSubtree(); + const bool suppressScrollFrame = + mPresShell->GetPresContext()->IsPaginated() && + aDisplay.IsBlockOutsideStyle() && + !aElement.IsInNativeAnonymousSubtree(); if (!suppressScrollFrame) { static constexpr FrameConstructionData sScrollableBlockData[2] = { {&nsCSSFrameConstructor::ConstructScrollableBlock}, @@ -4401,27 +4345,14 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay& aDisplay, kCaptionCtorFlags}}; return &sScrollableBlockData[caption]; } - - // If the scrollable frame would have propagated its scrolling to the - // viewport, we still want to construct a regular block rather than a - // scrollframe so that it paginates correctly, but we don't want to set - // the bit on the block that tells it to clip at paint time. - if (mPresShell->GetPresContext()->ElementWouldPropagateScrollStyles( - aElement)) { - suppressScrollFrame = false; - } } // Handle various non-scrollable blocks. - static constexpr FrameConstructionData sNonScrollableBlockData[2][2] = { - {{&nsCSSFrameConstructor::ConstructNonScrollableBlock}, - {&nsCSSFrameConstructor::ConstructNonScrollableBlock, - kCaptionCtorFlags}}, - {{&nsCSSFrameConstructor::ConstructNonScrollableBlock, - FCDATA_FORCED_NON_SCROLLABLE_BLOCK}, - {&nsCSSFrameConstructor::ConstructNonScrollableBlock, - FCDATA_FORCED_NON_SCROLLABLE_BLOCK | kCaptionCtorFlags}}}; - return &sNonScrollableBlockData[suppressScrollFrame][caption]; + static constexpr FrameConstructionData sNonScrollableBlockData[2] = { + {&nsCSSFrameConstructor::ConstructNonScrollableBlock}, + {&nsCSSFrameConstructor::ConstructNonScrollableBlock, + kCaptionCtorFlags}}; + return &sNonScrollableBlockData[caption]; } case StyleDisplayInside::Table: { static constexpr FrameConstructionData data( @@ -4555,8 +4486,7 @@ nsIFrame* nsCSSFrameConstructor::ConstructScrollableBlock( // Create our block frame // pass a temporary stylecontext, the correct one will be set later - nsContainerFrame* scrolledFrame = - NS_NewBlockFormattingContext(mPresShell, computedStyle); + nsContainerFrame* scrolledFrame = NS_NewBlockFrame(mPresShell, computedStyle); // Make sure to AddChild before we call ConstructBlock so that we // end up before our descendants in fixed-pos lists as needed. @@ -4579,26 +4509,7 @@ nsIFrame* nsCSSFrameConstructor::ConstructNonScrollableBlock( nsContainerFrame* aParentFrame, const nsStyleDisplay* aDisplay, nsFrameList& aFrameList) { ComputedStyle* const computedStyle = aItem.mComputedStyle; - - // We want a block formatting context root in paginated contexts for - // every block that would be scrollable in a non-paginated context. - // We mark our blocks with a bit here if this condition is true, so - // we can check it later in nsIFrame::ApplyPaginatedOverflowClipping. - bool clipPaginatedOverflow = - (aItem.mFCData->mBits & FCDATA_FORCED_NON_SCROLLABLE_BLOCK) != 0; - nsFrameState flags = nsFrameState(0); - if ((aDisplay->IsAbsolutelyPositionedStyle() || aDisplay->IsFloatingStyle() || - aDisplay->DisplayInside() == StyleDisplayInside::FlowRoot || - clipPaginatedOverflow) && - !aParentFrame->IsInSVGTextSubtree()) { - flags = NS_BLOCK_STATIC_BFC; - if (clipPaginatedOverflow) { - flags |= NS_BLOCK_CLIP_PAGINATED_OVERFLOW; - } - } - nsContainerFrame* newFrame = NS_NewBlockFrame(mPresShell, computedStyle); - newFrame->AddStateBits(flags); ConstructBlock(aState, aItem.mContent, aState.GetGeometricParent(*aDisplay, aParentFrame), aParentFrame, computedStyle, &newFrame, aFrameList, @@ -5165,10 +5076,14 @@ static bool ShouldSuppressFrameInSelect(const nsIContent* aParent, return false; } + // Allow native anonymous content no matter what. + if (aChild.IsRootOfNativeAnonymousSubtree()) { + return false; + } + // Options with labels have their label text added in ::before by forms.css. // Suppress frames for their child text. - if (aParent->IsHTMLElement(nsGkAtoms::option) && - !aChild.IsRootOfNativeAnonymousSubtree()) { + if (aParent->IsHTMLElement(nsGkAtoms::option)) { return aParent->AsElement()->HasNonEmptyAttr(nsGkAtoms::label); } @@ -5191,11 +5106,7 @@ static bool ShouldSuppressFrameInSelect(const nsIContent* aParent, return false; } - // Allow native anonymous content no matter what. - if (aChild.IsRootOfNativeAnonymousSubtree()) { - return false; - } - + // Anything else is not ok. return true; } @@ -8042,6 +7953,20 @@ nsIFrame* nsCSSFrameConstructor::CreateContinuingFrame( return newFrame; } +void nsCSSFrameConstructor::MaybeSetNextPageContentFramePageName( + const nsIFrame* aFrame) { + MOZ_ASSERT(aFrame, "Frame should not be null"); + // No parent means the root frame, which isn't what this funciton is for. + MOZ_ASSERT(aFrame->GetParent(), + "Frame should be the first child placed on a new page, not the " + "root frame."); + if (mNextPageContentFramePageName) { + return; + } + const nsAtom* const autoValue = aFrame->GetParent()->GetAutoPageValue(); + mNextPageContentFramePageName = aFrame->ComputePageValue(autoValue); +} + nsresult nsCSSFrameConstructor::ReplicateFixedFrames( nsPageContentFrame* aParentFrame) { // Now deal with fixed-pos things.... They should appear on all pages, @@ -8743,15 +8668,14 @@ void nsCSSFrameConstructor::CreateNeededAnonFlexOrGridItems( mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle( PseudoStyleType::anonymousItem, aParentFrame->Style()); - static constexpr FrameConstructionData sBlockFormattingContextFCData( - ToCreationFunc(NS_NewBlockFormattingContext), - FCDATA_SKIP_FRAMESET | FCDATA_USE_CHILD_ITEMS | - FCDATA_IS_WRAPPER_ANON_BOX); + static constexpr FrameConstructionData sBlockFCData( + ToCreationFunc(NS_NewBlockFrame), FCDATA_SKIP_FRAMESET | + FCDATA_USE_CHILD_ITEMS | + FCDATA_IS_WRAPPER_ANON_BOX); - FrameConstructionItem* newItem = new (this) - FrameConstructionItem(&sBlockFormattingContextFCData, - // Use the content of our parent frame - parentContent, wrapperStyle.forget(), true); + // Use the content of our parent frame + auto* newItem = new (this) FrameConstructionItem( + &sBlockFCData, parentContent, wrapperStyle.forget(), true); newItem->mIsAllInline = newItem->mComputedStyle->StyleDisplay()->IsInlineOutsideStyle(); diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index 1b48fd15dc..283d1385ce 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -297,12 +297,39 @@ class nsCSSFrameConstructor final : public nsFrameManager { nsContainerFrame* aParentFrame, bool aIsFluid = true); - void SetNextPageContentFramePageName(const nsAtom* aAtom) { + /** + * Sets the page name when a page break is being generated due to a change + * in page name. + * + * Should only be used during paginated reflow, to signal what page value + * the next page content frame should have. + * + * It is an error to set this if a new page name has already been set, either + * through SetNextPageContentFramePageName or + * MaybeSetNextPageContentFramePageName. + */ + void SetNextPageContentFramePageName(const nsAtom* aPageName) { + MOZ_ASSERT(aPageName, "New page name should never be null"); MOZ_ASSERT(!mNextPageContentFramePageName, "PageContentFrame page name was already set"); - mNextPageContentFramePageName = aAtom; + mNextPageContentFramePageName = aPageName; } + /** + * If a new page name has not been set for the next page, sets the value + * using the given frame. + * + * |aFrame| should be a frame to be placed on the new page. + * + * This function handles the work of resolving an atom for the frame, and + * avoids doing this extra work when not necessary. + * + * This is used during block reflow when a page break has occurred but it was + * not caused by a change in page name. It should only be used during + * paginated reflow. + */ + void MaybeSetNextPageContentFramePageName(const nsIFrame* aFrame); + // Copy over fixed frames from aParentFrame's prev-in-flow nsresult ReplicateFixedFrames(nsPageContentFrame* aParentFrame); @@ -696,10 +723,6 @@ class nsCSSFrameConstructor final : public nsFrameManager { This can be used with or without FCDATA_FUNC_IS_FULL_CTOR. The child items might still need table pseudo processing. */ #define FCDATA_USE_CHILD_ITEMS 0x10000 - /* If FCDATA_FORCED_NON_SCROLLABLE_BLOCK is set, then this block - would have been scrollable but has been forced to be - non-scrollable due to being in a paginated context. */ -#define FCDATA_FORCED_NON_SCROLLABLE_BLOCK 0x20000 /* If FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, then create a block formatting context wrapper around the kids of this frame using the FrameConstructionData's mPseudoAtom for its anonymous @@ -1361,14 +1384,6 @@ class nsCSSFrameConstructor final : public nsFrameManager { nsFrameState aTypeBit); private: - // ConstructSelectFrame puts the new frame in aFrameList and - // handles the kids of the select. - nsIFrame* ConstructSelectFrame(nsFrameConstructorState& aState, - FrameConstructionItem& aItem, - nsContainerFrame* aParentFrame, - const nsStyleDisplay* aStyleDisplay, - nsFrameList& aFrameList); - // ConstructFieldSetFrame puts the new frame in aFrameList and // handles the kids of the fieldset nsIFrame* ConstructFieldSetFrame(nsFrameConstructorState& aState, @@ -1377,6 +1392,12 @@ class nsCSSFrameConstructor final : public nsFrameManager { const nsStyleDisplay* aStyleDisplay, nsFrameList& aFrameList); + nsIFrame* ConstructListBoxSelectFrame(nsFrameConstructorState& aState, + FrameConstructionItem& aItem, + nsContainerFrame* aParentFrame, + const nsStyleDisplay* aStyleDisplay, + nsFrameList& aFrameList); + // Creates a block frame wrapping an anonymous ruby frame. nsIFrame* ConstructBlockRubyFrame(nsFrameConstructorState& aState, FrameConstructionItem& aItem, @@ -1423,6 +1444,8 @@ class nsCSSFrameConstructor final : public nsFrameManager { nsIFrame* aParentFrame, ComputedStyle&); // HTML data-finding helper functions + static const FrameConstructionData* FindSelectData(const Element&, + ComputedStyle&); static const FrameConstructionData* FindImgData(const Element&, ComputedStyle&); static const FrameConstructionData* FindGeneratedImageData(const Element&, diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index ab61daae87..d1cf9bf237 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -1143,6 +1143,8 @@ nsDocumentViewer::PermitUnload(PermitUnloadAction aAction, *aPermitUnload = true; + NS_ENSURE_STATE(mContainer); + RefPtr bc = mContainer->GetBrowsingContext(); if (!bc) { return NS_OK; @@ -1224,7 +1226,7 @@ MOZ_CAN_RUN_SCRIPT_BOUNDARY PermitUnloadResult nsDocumentViewer::DispatchBeforeUnload() { AutoDontWarnAboutSyncXHR disableSyncXHRWarning; - if (!mDocument || mInPermitUnload || mInPermitUnloadPrompt) { + if (!mDocument || mInPermitUnload || mInPermitUnloadPrompt || !mContainer) { return eAllowNavigation; } @@ -2546,6 +2548,8 @@ nsDocumentViewer::ForgetReloadEncoding() { MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP nsDocumentViewer::GetContentSize( int32_t aMaxWidth, int32_t aMaxHeight, int32_t aPrefWidth, int32_t* aWidth, int32_t* aHeight) { + NS_ENSURE_STATE(mContainer); + RefPtr bc = mContainer->GetBrowsingContext(); NS_ENSURE_TRUE(bc, NS_ERROR_NOT_AVAILABLE); diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 28230421d5..db766f6603 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -9492,8 +9492,9 @@ nsRect nsLayoutUtils::ComputeSVGOriginBox(SVGViewportElement* aElement) { } /* static */ -nsRect nsLayoutUtils::ComputeSVGReferenceRect(nsIFrame* aFrame, - StyleGeometryBox aGeometryBox) { +nsRect nsLayoutUtils::ComputeSVGReferenceRect( + nsIFrame* aFrame, StyleGeometryBox aGeometryBox, + MayHaveNonScalingStrokeCyclicDependency aMayHaveCyclicDependency) { MOZ_ASSERT(aFrame->GetContent()->IsSVGElement()); nsRect r; @@ -9502,9 +9503,12 @@ nsRect nsLayoutUtils::ComputeSVGReferenceRect(nsIFrame* aFrame, // XXX Bug 1299876 // The size of stroke-box is not correct if this graphic element has // specific stroke-linejoin or stroke-linecap. - gfxRect bbox = - SVGUtils::GetBBox(aFrame, SVGUtils::eBBoxIncludeFillGeometry | - SVGUtils::eBBoxIncludeStroke); + const uint32_t flags = SVGUtils::eBBoxIncludeFillGeometry | + SVGUtils::eBBoxIncludeStroke | + (bool(aMayHaveCyclicDependency) + ? SVGUtils::eAvoidCycleIfNonScalingStroke + : 0); + gfxRect bbox = SVGUtils::GetBBox(aFrame, flags); r = nsLayoutUtils::RoundGfxRectToAppRect(bbox, AppUnitsPerCSSPixel()); break; } diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 3cd01dce9f..697b139ed9 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2913,7 +2913,13 @@ class nsLayoutUtils { // Compute the geometry box for SVG layout. The caller should map the CSS box // into the proper SVG box. - static nsRect ComputeSVGReferenceRect(nsIFrame*, StyleGeometryBox); + // |aMayHaveCyclicDependency| is used for stroke-box to avoid the cyclic + // dependency if any of its descendants uses non-scaling-stroke. + enum class MayHaveNonScalingStrokeCyclicDependency : bool { No, Yes }; + static nsRect ComputeSVGReferenceRect( + nsIFrame*, StyleGeometryBox, + MayHaveNonScalingStrokeCyclicDependency = + MayHaveNonScalingStrokeCyclicDependency::No); // Compute the geometry box for CSS layout. The caller should map the SVG box // into the proper CSS box. diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index c1b03aebf4..7d9515c495 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -906,7 +906,6 @@ Maybe nsPresContext::GetOverriddenOrEmbedderColorScheme() const { case dom::PrefersColorSchemeOverride::Light: return Some(ColorScheme::Light); case dom::PrefersColorSchemeOverride::None: - case dom::PrefersColorSchemeOverride::EndGuard_: break; } diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index bc4e70dbcf..563dac0eae 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -1397,7 +1397,8 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr { #ifdef DEBUG private: friend struct nsAutoLayoutPhase; - mozilla::EnumeratedArray + mozilla::EnumeratedArray mLayoutPhaseCount; public: diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index af780bb192..a5c2b1ded9 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -2264,7 +2264,8 @@ void nsRefreshDriver::DetermineProximityToViewportAndNotifyResizeObservers() { return false; } return ps->HasContentVisibilityAutoFrames() || - aDocument->HasResizeObservers(); + aDocument->HasResizeObservers() || + aDocument->HasElementsWithLastRememberedSize(); }; AutoTArray, 32> documents; diff --git a/layout/base/tests/mochitest.toml b/layout/base/tests/mochitest.toml index d4b7932cfc..24924809c0 100644 --- a/layout/base/tests/mochitest.toml +++ b/layout/base/tests/mochitest.toml @@ -234,6 +234,8 @@ support-files = ["bug1448730.html"] ["test_bug1756118.html"] +["test_bug1836801.html"] + ["test_caret_browsing_around_form_controls.html"] skip-if = ["os == 'android'"] diff --git a/layout/base/tests/test_bug1836801.html b/layout/base/tests/test_bug1836801.html new file mode 100644 index 0000000000..4584394600 --- /dev/null +++ b/layout/base/tests/test_bug1836801.html @@ -0,0 +1,59 @@ + + + + + + + + + + diff --git a/layout/base/tests/test_event_target_iframe_oop.html b/layout/base/tests/test_event_target_iframe_oop.html deleted file mode 100644 index 562433c955..0000000000 --- a/layout/base/tests/test_event_target_iframe_oop.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - - Test for bug 921928 - - - - - - - - - diff --git a/layout/build/components.conf b/layout/build/components.conf index 0239a7c85c..eb834a20a1 100644 --- a/layout/build/components.conf +++ b/layout/build/components.conf @@ -149,16 +149,6 @@ Classes = [ 'type': 'nsStructuredCloneContainer', 'headers': ['nsStructuredCloneContainer.h'], }, - { - 'js_name': 'DOMRequest', - 'cid': '{3160e271-138d-4cc7-9d63-6429f16957c7}', - 'contract_ids': ['@mozilla.org/dom/dom-request-service;1'], - 'interfaces': ['nsIDOMRequestService'], - 'singleton': True, - 'type': 'mozilla::dom::DOMRequestService', - 'headers': ['mozilla/dom/DOMRequest.h'], - 'constructor': 'mozilla::dom::DOMRequestService::FactoryCreate', - }, { 'js_name': 'domStorageManager', 'cid': '{656db07c-aa80-49e4-bce8-e431baae697d}', diff --git a/layout/build/moz.build b/layout/build/moz.build index b2059e396e..9135208edb 100644 --- a/layout/build/moz.build +++ b/layout/build/moz.build @@ -6,7 +6,6 @@ EXPORTS += [ "nsContentDLF.h", - "nsLayoutCID.h", "nsLayoutStatics.h", ] diff --git a/layout/build/nsContentDLF.cpp b/layout/build/nsContentDLF.cpp index a9234099b0..fac598b68a 100644 --- a/layout/build/nsContentDLF.cpp +++ b/layout/build/nsContentDLF.cpp @@ -16,7 +16,6 @@ #include "mozilla/dom/Document.h" #include "nsNodeInfoManager.h" #include "nsString.h" -#include "nsContentCID.h" #include "nsNetUtil.h" #include "nsCRT.h" #include "nsIViewSourceChannel.h" diff --git a/layout/build/nsLayoutCID.h b/layout/build/nsLayoutCID.h deleted file mode 100644 index 9805225fd2..0000000000 --- a/layout/build/nsLayoutCID.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- 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 nsLayoutCID_h__ -#define nsLayoutCID_h__ - -// {1691E1F4-EE41-11d4-9885-00C04FA0CF4B} -#define NS_FRAMETRAVERSAL_CID \ - { \ - 0x1691e1f4, 0xee41, 0x11d4, { \ - 0x98, 0x85, 0x0, 0xc0, 0x4f, 0xa0, 0xcf, 0x4b \ - } \ - } - -/* a6cf90f9-15b3-11d2-932e-00805f8add32 */ -#define NS_LAYOUT_DEBUGGER_CID \ - { \ - 0xa6cf90f9, 0x15b3, 0x11d2, { \ - 0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32 \ - } \ - } - -// {2fe88332-31c6-4829-b247-a07d8a73e80f} -#define NS_CANVASRENDERINGCONTEXTWEBGL_CID \ - { \ - 0x2fe88332, 0x31c6, 0x4829, { \ - 0xb2, 0x47, 0xa0, 0x7d, 0x8a, 0x7e, 0xe8, 0x0fe \ - } \ - } - -// {ae2793c0-2ba3-4adb-9c5e-c23525812c64} -#define NS_SDBCONNECTION_CID \ - { \ - 0xae2793c0, 0x2ba3, 0x4adb, { \ - 0x9c, 0x5e, 0xc2, 0x35, 0x25, 0x81, 0x2c, 0x64 \ - } \ - } - -// {656DB07C-AA80-49e4-BCE8-E431BAAE697D} -#define NS_DOMLOCALSTORAGEMANAGER_CID \ - { \ - 0x656db07c, 0xaa80, 0x49e4, { \ - 0xbc, 0xe8, 0xe4, 0x31, 0xba, 0xae, 0x69, 0x7d \ - } \ - } - -// {93ad72a6-02cd-4716-9626-d47d5ec275ec} -#define NS_DOMJSON_CID \ - { \ - 0x93ad72a6, 0x02cd, 0x4716, { \ - 0x96, 0x26, 0xd4, 0x7d, 0x5e, 0xc2, 0x75, 0xec \ - } \ - } - -// {CF7FD51F-ABA2-44C1-9FF0-11F7508EFCD4} -#define NS_FOCUSMANAGER_CID \ - { \ - 0xcf7fd51f, 0xaba2, 0x44c1, { \ - 0x9f, 0xf0, 0x11, 0xf7, 0x50, 0x8e, 0xfc, 0xd4 \ - } \ - } - -// {3160e271-138d-4cc7-9d63-6429f16957c7} -#define DOMREQUEST_SERVICE_CID \ - { \ - 0x3160e271, 0x138d, 0x4cc7, { \ - 0x9d, 0x63, 0x64, 0x29, 0xf1, 0x69, 0x57, 0xc7 \ - } \ - } - -// {5a75c25a-5e7e-4d90-8f7c-07eb15cc0aa8} -#define QUOTAMANAGER_SERVICE_CID \ - { \ - 0x5a75c25a, 0x5e7e, 0x4d90, { \ - 0x8f, 0x7c, 0x07, 0xeb, 0x15, 0xcc, 0x0a, 0xa8 \ - } \ - } - -// {c74bde32-bcc7-4840-8430-c733351b212a} -#define SERVICEWORKERMANAGER_CID \ - { \ - 0xc74bde32, 0xbcc7, 0x4840, { \ - 0x84, 0x30, 0xc7, 0x33, 0x35, 0x1b, 0x21, 0x2a \ - } \ - } - -// {69da374a-fda3-4a93-9fbc-d9304f66a7fe} -#define STORAGEACTIVITYSERVICE_CID \ - { \ - 0x69da374a, 0xfda3, 0x4a93, { \ - 0x9f, 0xbc, 0xd9, 0x30, 0x4f, 0x66, 0xa7, 0xfe \ - } \ - } - -#define NOTIFICATIONTELEMETRYSERVICE_CID \ - { \ - 0x5995b782, 0x6a0e, 0x4066, { \ - 0xaa, 0xc5, 0x27, 0x6f, 0x0a, 0x9a, 0xd8, 0xcf \ - } \ - } - -#endif /* nsLayoutCID_h__ */ diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index 542785f156..93a1c1a329 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -13,7 +13,6 @@ #include "mozilla/ModuleUtils.h" #include "nsImageModule.h" #include "nsLayoutStatics.h" -#include "nsContentCID.h" #include "nsContentDLF.h" #include "nsContentPolicyUtils.h" #include "nsDataDocumentContentPolicy.h" @@ -27,7 +26,6 @@ #include "nsPlainTextSerializer.h" #include "nsXMLContentSerializer.h" #include "nsXHTMLContentSerializer.h" -#include "nsLayoutCID.h" #include "nsFocusManager.h" #include "ThirdPartyUtil.h" #include "gfxPlatform.h" diff --git a/layout/forms/HTMLSelectEventListener.cpp b/layout/forms/HTMLSelectEventListener.cpp index 4f6b1e3561..8c74c57cc0 100644 --- a/layout/forms/HTMLSelectEventListener.cpp +++ b/layout/forms/HTMLSelectEventListener.cpp @@ -40,7 +40,7 @@ static bool IsOptionInteractivelySelectable(HTMLSelectElement& aSelect, // options in a display: contents subtree interactively. // test_select_key_navigation_bug1498769.html tests for this and should // probably be changed (and this loop removed) or alternatively - // SelectChild.jsm should be changed to match it. + // SelectChild.sys.mjs should be changed to match it. for (Element* el = &aOption; el && el != &aSelect; el = el->GetParentElement()) { if (Servo_Element_IsDisplayContents(el)) { diff --git a/layout/forms/crashtests/crashtests.list b/layout/forms/crashtests/crashtests.list index da43270ba6..5bc0fa7746 100644 --- a/layout/forms/crashtests/crashtests.list +++ b/layout/forms/crashtests/crashtests.list @@ -68,7 +68,7 @@ load 1405830.html load 1418477.html load 1432853.html asserts(1-4) load 1460787-1.html -load 1464165-1.html +asserts(1-4) load 1464165-1.html # Big sizes. load 1471157.html load 1488219.html load 1600207.html diff --git a/layout/forms/moz.build b/layout/forms/moz.build index 838a17bf92..93ec0a430c 100644 --- a/layout/forms/moz.build +++ b/layout/forms/moz.build @@ -19,7 +19,6 @@ EXPORTS += [ UNIFIED_SOURCES += [ "HTMLSelectEventListener.cpp", "ListMutationObserver.cpp", - "nsButtonFrameRenderer.cpp", "nsCheckboxRadioFrame.cpp", "nsColorControlFrame.cpp", "nsComboboxControlFrame.cpp", diff --git a/layout/forms/nsButtonFrameRenderer.cpp b/layout/forms/nsButtonFrameRenderer.cpp deleted file mode 100644 index 598610cf72..0000000000 --- a/layout/forms/nsButtonFrameRenderer.cpp +++ /dev/null @@ -1,471 +0,0 @@ -/* -*- 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 "nsButtonFrameRenderer.h" -#include "nsCSSRendering.h" -#include "nsPresContext.h" -#include "nsPresContextInlines.h" -#include "nsGkAtoms.h" -#include "nsCSSPseudoElements.h" -#include "nsNameSpaceManager.h" -#include "mozilla/ServoStyleSet.h" -#include "mozilla/Unused.h" -#include "nsDisplayList.h" -#include "nsITheme.h" -#include "nsIFrame.h" -#include "mozilla/dom/Element.h" - -#include "gfxUtils.h" -#include "mozilla/layers/RenderRootStateManager.h" - -using namespace mozilla; -using namespace mozilla::image; -using namespace mozilla::layers; - -namespace mozilla { -class nsDisplayButtonBoxShadowOuter; -class nsDisplayButtonBorder; -class nsDisplayButtonForeground; -} // namespace mozilla - -nsButtonFrameRenderer::nsButtonFrameRenderer() : mFrame(nullptr) { - MOZ_COUNT_CTOR(nsButtonFrameRenderer); -} - -nsButtonFrameRenderer::~nsButtonFrameRenderer() { - MOZ_COUNT_DTOR(nsButtonFrameRenderer); -} - -void nsButtonFrameRenderer::SetFrame(nsIFrame* aFrame, - nsPresContext* aPresContext) { - mFrame = aFrame; - ReResolveStyles(aPresContext); -} - -nsIFrame* nsButtonFrameRenderer::GetFrame() { return mFrame; } - -void nsButtonFrameRenderer::SetDisabled(bool aDisabled, bool aNotify) { - dom::Element* element = mFrame->GetContent()->AsElement(); - if (aDisabled) - element->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled, u""_ns, aNotify); - else - element->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, aNotify); -} - -bool nsButtonFrameRenderer::isDisabled() { - return mFrame->GetContent()->AsElement()->IsDisabled(); -} - -nsresult nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder, - nsDisplayList* aBackground, - nsDisplayList* aForeground) { - if (!mFrame->StyleEffects()->mBoxShadow.IsEmpty()) { - aBackground->AppendNewToTop(aBuilder, - GetFrame()); - } - - nsRect buttonRect = - mFrame->GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(mFrame); - - const AppendedBackgroundType result = - nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, mFrame, buttonRect, aBackground); - if (result == AppendedBackgroundType::None) { - aBuilder->BuildCompositorHitTestInfoIfNeeded(GetFrame(), aBackground); - } - - aBackground->AppendNewToTop(aBuilder, GetFrame(), - this); - - // Only display focus rings if we actually have them. Since at most one - // button would normally display a focus ring, most buttons won't have them. - if (mInnerFocusStyle && mInnerFocusStyle->StyleBorder()->HasBorder() && - mFrame->IsThemed() && - mFrame->PresContext()->Theme()->ThemeWantsButtonInnerFocusRing()) { - aForeground->AppendNewToTop(aBuilder, GetFrame(), - this); - } - return NS_OK; -} - -void nsButtonFrameRenderer::GetButtonInnerFocusRect(const nsRect& aRect, - nsRect& aResult) { - aResult = aRect; - aResult.Deflate(mFrame->GetUsedBorderAndPadding()); - - if (mInnerFocusStyle) { - nsMargin innerFocusPadding(0, 0, 0, 0); - mInnerFocusStyle->StylePadding()->GetPadding(innerFocusPadding); - - nsMargin framePadding = mFrame->GetUsedPadding(); - - innerFocusPadding.top = std::min(innerFocusPadding.top, framePadding.top); - innerFocusPadding.right = - std::min(innerFocusPadding.right, framePadding.right); - innerFocusPadding.bottom = - std::min(innerFocusPadding.bottom, framePadding.bottom); - innerFocusPadding.left = - std::min(innerFocusPadding.left, framePadding.left); - - aResult.Inflate(innerFocusPadding); - } -} - -ImgDrawResult nsButtonFrameRenderer::PaintInnerFocusBorder( - nsDisplayListBuilder* aBuilder, nsPresContext* aPresContext, - gfxContext& aRenderingContext, const nsRect& aDirtyRect, - const nsRect& aRect) { - // we draw the -moz-focus-inner border just inside the button's - // normal border and padding, to match Windows themes. - - nsRect rect; - - PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages() - ? PaintBorderFlags::SyncDecodeImages - : PaintBorderFlags(); - - ImgDrawResult result = ImgDrawResult::SUCCESS; - - if (mInnerFocusStyle) { - GetButtonInnerFocusRect(aRect, rect); - - result &= - nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame, - aDirtyRect, rect, mInnerFocusStyle, flags); - } - - return result; -} - -Maybe -nsButtonFrameRenderer::CreateInnerFocusBorderRenderer( - nsDisplayListBuilder* aBuilder, nsPresContext* aPresContext, - gfxContext* aRenderingContext, const nsRect& aDirtyRect, - const nsRect& aRect, bool* aBorderIsEmpty) { - if (mInnerFocusStyle) { - nsRect rect; - GetButtonInnerFocusRect(aRect, rect); - - gfx::DrawTarget* dt = - aRenderingContext ? aRenderingContext->GetDrawTarget() : nullptr; - return nsCSSRendering::CreateBorderRenderer( - aPresContext, dt, mFrame, aDirtyRect, rect, mInnerFocusStyle, - aBorderIsEmpty); - } - - return Nothing(); -} - -ImgDrawResult nsButtonFrameRenderer::PaintBorder(nsDisplayListBuilder* aBuilder, - nsPresContext* aPresContext, - gfxContext& aRenderingContext, - const nsRect& aDirtyRect, - const nsRect& aRect) { - // get the button rect this is inside the focus and outline rects - nsRect buttonRect = aRect; - ComputedStyle* context = mFrame->Style(); - - PaintBorderFlags borderFlags = aBuilder->ShouldSyncDecodeImages() - ? PaintBorderFlags::SyncDecodeImages - : PaintBorderFlags(); - - nsCSSRendering::PaintBoxShadowInner(aPresContext, aRenderingContext, mFrame, - buttonRect); - - ImgDrawResult result = - nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame, - aDirtyRect, buttonRect, context, borderFlags); - - return result; -} - -/** - * Call this when styles change - */ -void nsButtonFrameRenderer::ReResolveStyles(nsPresContext* aPresContext) { - // get all the styles - ServoStyleSet* styleSet = aPresContext->StyleSet(); - - // get styles assigned to -moz-focus-inner (ie dotted border on Windows) - mInnerFocusStyle = styleSet->ProbePseudoElementStyle( - *mFrame->GetContent()->AsElement(), PseudoStyleType::mozFocusInner, - nullptr, mFrame->Style()); -} - -ComputedStyle* nsButtonFrameRenderer::GetComputedStyle(int32_t aIndex) const { - switch (aIndex) { - case NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX: - return mInnerFocusStyle; - default: - return nullptr; - } -} - -void nsButtonFrameRenderer::SetComputedStyle(int32_t aIndex, - ComputedStyle* aComputedStyle) { - switch (aIndex) { - case NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX: - mInnerFocusStyle = aComputedStyle; - break; - } -} - -namespace mozilla { - -class nsDisplayButtonBoxShadowOuter : public nsPaintedDisplayItem { - public: - nsDisplayButtonBoxShadowOuter(nsDisplayListBuilder* aBuilder, - nsIFrame* aFrame) - : nsPaintedDisplayItem(aBuilder, aFrame) { - MOZ_COUNT_CTOR(nsDisplayButtonBoxShadowOuter); - } - MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayButtonBoxShadowOuter) - - virtual bool CreateWebRenderCommands( - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - mozilla::layers::RenderRootStateManager* aManager, - nsDisplayListBuilder* aDisplayListBuilder) override; - - bool CanBuildWebRenderDisplayItems(); - - virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, - bool* aSnap) const override; - NS_DISPLAY_DECL_NAME("ButtonBoxShadowOuter", TYPE_BUTTON_BOX_SHADOW_OUTER) -}; - -nsRect nsDisplayButtonBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder, - bool* aSnap) const { - *aSnap = false; - return mFrame->InkOverflowRectRelativeToSelf() + ToReferenceFrame(); -} - -void nsDisplayButtonBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder, - gfxContext* aCtx) { - nsRect frameRect = nsRect(ToReferenceFrame(), mFrame->GetSize()); - - nsCSSRendering::PaintBoxShadowOuter(mFrame->PresContext(), *aCtx, mFrame, - frameRect, GetPaintRect(aBuilder, aCtx)); -} - -bool nsDisplayButtonBoxShadowOuter::CanBuildWebRenderDisplayItems() { - // FIXME(emilio): Is this right? That doesn't make much sense. - if (mFrame->StyleEffects()->mBoxShadow.IsEmpty()) { - return false; - } - - bool hasBorderRadius; - bool nativeTheme = - nsCSSRendering::HasBoxShadowNativeTheme(mFrame, hasBorderRadius); - - // We don't support native themed things yet like box shadows around - // input buttons. - return !nativeTheme; -} - -bool nsDisplayButtonBoxShadowOuter::CreateWebRenderCommands( - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - mozilla::layers::RenderRootStateManager* aManager, - nsDisplayListBuilder* aDisplayListBuilder) { - if (!CanBuildWebRenderDisplayItems()) { - return false; - } - int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel(); - nsRect shadowRect = nsRect(ToReferenceFrame(), mFrame->GetSize()); - LayoutDeviceRect deviceBox = - LayoutDeviceRect::FromAppUnits(shadowRect, appUnitsPerDevPixel); - wr::LayoutRect deviceBoxRect = wr::ToLayoutRect(deviceBox); - - bool dummy; - LayoutDeviceRect clipRect = LayoutDeviceRect::FromAppUnits( - GetBounds(aDisplayListBuilder, &dummy), appUnitsPerDevPixel); - wr::LayoutRect deviceClipRect = wr::ToLayoutRect(clipRect); - - bool hasBorderRadius; - Unused << nsCSSRendering::HasBoxShadowNativeTheme(mFrame, hasBorderRadius); - - LayoutDeviceSize zeroSize; - wr::BorderRadius borderRadius = - wr::ToBorderRadius(zeroSize, zeroSize, zeroSize, zeroSize); - if (hasBorderRadius) { - gfx::RectCornerRadii borderRadii; - hasBorderRadius = nsCSSRendering::GetBorderRadii(shadowRect, shadowRect, - mFrame, borderRadii); - if (hasBorderRadius) { - borderRadius = wr::ToBorderRadius(borderRadii); - } - } - - const Span shadows = - mFrame->StyleEffects()->mBoxShadow.AsSpan(); - MOZ_ASSERT(!shadows.IsEmpty()); - - for (const StyleBoxShadow& shadow : Reversed(shadows)) { - if (shadow.inset) { - continue; - } - float blurRadius = - float(shadow.base.blur.ToAppUnits()) / float(appUnitsPerDevPixel); - gfx::DeviceColor shadowColor = - ToDeviceColor(nsCSSRendering::GetShadowColor(shadow.base, mFrame, 1.0)); - - LayoutDevicePoint shadowOffset = LayoutDevicePoint::FromAppUnits( - nsPoint(shadow.base.horizontal.ToAppUnits(), - shadow.base.vertical.ToAppUnits()), - appUnitsPerDevPixel); - - float spreadRadius = - float(shadow.spread.ToAppUnits()) / float(appUnitsPerDevPixel); - - aBuilder.PushBoxShadow(deviceBoxRect, deviceClipRect, !BackfaceIsHidden(), - deviceBoxRect, wr::ToLayoutVector2D(shadowOffset), - wr::ToColorF(shadowColor), blurRadius, spreadRadius, - borderRadius, wr::BoxShadowClipMode::Outset); - } - return true; -} - -class nsDisplayButtonBorder final : public nsPaintedDisplayItem { - public: - nsDisplayButtonBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, - nsButtonFrameRenderer* aRenderer) - : nsPaintedDisplayItem(aBuilder, aFrame), mBFR(aRenderer) { - MOZ_COUNT_CTOR(nsDisplayButtonBorder); - } - MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayButtonBorder) - - virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, - HitTestState* aState, - nsTArray* aOutFrames) override { - aOutFrames->AppendElement(mFrame); - } - virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, - bool* aSnap) const override; - virtual bool CreateWebRenderCommands( - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - mozilla::layers::RenderRootStateManager* aManager, - nsDisplayListBuilder* aDisplayListBuilder) override; - NS_DISPLAY_DECL_NAME("ButtonBorderBackground", TYPE_BUTTON_BORDER_BACKGROUND) - private: - nsButtonFrameRenderer* mBFR; -}; - -bool nsDisplayButtonBorder::CreateWebRenderCommands( - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - mozilla::layers::RenderRootStateManager* aManager, - nsDisplayListBuilder* aDisplayListBuilder) { - // This is really a combination of paint box shadow inner + - // paint border. - aBuilder.StartGroup(this); - const nsRect buttonRect = nsRect(ToReferenceFrame(), mFrame->GetSize()); - bool snap; - nsRect visible = GetBounds(aDisplayListBuilder, &snap); - nsDisplayBoxShadowInner::CreateInsetBoxShadowWebRenderCommands( - aBuilder, aSc, visible, mFrame, buttonRect); - - bool borderIsEmpty = false; - Maybe br = nsCSSRendering::CreateBorderRenderer( - mFrame->PresContext(), nullptr, mFrame, nsRect(), - nsRect(ToReferenceFrame(), mFrame->GetSize()), mFrame->Style(), - &borderIsEmpty, mFrame->GetSkipSides()); - if (!br) { - if (borderIsEmpty) { - aBuilder.FinishGroup(); - } else { - aBuilder.CancelGroup(true); - } - - return borderIsEmpty; - } - - br->CreateWebRenderCommands(this, aBuilder, aResources, aSc); - aBuilder.FinishGroup(); - return true; -} - -void nsDisplayButtonBorder::Paint(nsDisplayListBuilder* aBuilder, - gfxContext* aCtx) { - NS_ASSERTION(mFrame, "No frame?"); - nsPresContext* pc = mFrame->PresContext(); - nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize()); - - // draw the border and background inside the focus and outline borders - Unused << mBFR->PaintBorder(aBuilder, pc, *aCtx, GetPaintRect(aBuilder, aCtx), - r); -} - -nsRect nsDisplayButtonBorder::GetBounds(nsDisplayListBuilder* aBuilder, - bool* aSnap) const { - *aSnap = false; - return aBuilder->IsForEventDelivery() - ? nsRect(ToReferenceFrame(), mFrame->GetSize()) - : mFrame->InkOverflowRectRelativeToSelf() + ToReferenceFrame(); -} - -class nsDisplayButtonForeground final : public nsPaintedDisplayItem { - public: - nsDisplayButtonForeground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, - nsButtonFrameRenderer* aRenderer) - : nsPaintedDisplayItem(aBuilder, aFrame), mBFR(aRenderer) { - MOZ_COUNT_CTOR(nsDisplayButtonForeground); - } - MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayButtonForeground) - - void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; - bool CreateWebRenderCommands( - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - mozilla::layers::RenderRootStateManager* aManager, - nsDisplayListBuilder* aDisplayListBuilder) override; - NS_DISPLAY_DECL_NAME("ButtonForeground", TYPE_BUTTON_FOREGROUND) - private: - nsButtonFrameRenderer* mBFR; -}; - -void nsDisplayButtonForeground::Paint(nsDisplayListBuilder* aBuilder, - gfxContext* aCtx) { - nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize()); - - // Draw the -moz-focus-inner border - Unused << mBFR->PaintInnerFocusBorder(aBuilder, mFrame->PresContext(), *aCtx, - GetPaintRect(aBuilder, aCtx), r); -} - -bool nsDisplayButtonForeground::CreateWebRenderCommands( - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - mozilla::layers::RenderRootStateManager* aManager, - nsDisplayListBuilder* aDisplayListBuilder) { - Maybe br; - bool borderIsEmpty = false; - bool dummy; - nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize()); - br = mBFR->CreateInnerFocusBorderRenderer( - aDisplayListBuilder, mFrame->PresContext(), nullptr, - GetBounds(aDisplayListBuilder, &dummy), r, &borderIsEmpty); - - if (!br) { - return borderIsEmpty; - } - - aBuilder.StartGroup(this); - br->CreateWebRenderCommands(this, aBuilder, aResources, aSc); - aBuilder.FinishGroup(); - - return true; -} - -} // namespace mozilla diff --git a/layout/forms/nsButtonFrameRenderer.h b/layout/forms/nsButtonFrameRenderer.h deleted file mode 100644 index ea5a9cdea4..0000000000 --- a/layout/forms/nsButtonFrameRenderer.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- 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 nsButtonFrameRenderer_h___ -#define nsButtonFrameRenderer_h___ - -#include "nsMargin.h" -#include "nsCSSRenderingBorders.h" - -class gfxContext; -class nsIFrame; -class nsPresContext; -struct nsRect; - -namespace mozilla { -class nsDisplayList; -class nsDisplayListBuilder; -} // namespace mozilla - -#define NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX 0 -#define NS_BUTTON_RENDERER_LAST_CONTEXT_INDEX \ - NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX - -class nsButtonFrameRenderer { - using nsDisplayList = mozilla::nsDisplayList; - using nsDisplayListBuilder = mozilla::nsDisplayListBuilder; - - typedef mozilla::image::ImgDrawResult ImgDrawResult; - typedef mozilla::ComputedStyle ComputedStyle; - - public: - nsButtonFrameRenderer(); - ~nsButtonFrameRenderer(); - - /** - * Create display list items for the button - */ - nsresult DisplayButton(nsDisplayListBuilder* aBuilder, - nsDisplayList* aBackground, - nsDisplayList* aForeground); - - ImgDrawResult PaintInnerFocusBorder(nsDisplayListBuilder* aBuilder, - nsPresContext* aPresContext, - gfxContext& aRenderingContext, - const nsRect& aDirtyRect, - const nsRect& aRect); - - mozilla::Maybe CreateInnerFocusBorderRenderer( - nsDisplayListBuilder* aBuilder, nsPresContext* aPresContext, - gfxContext* aRenderingContext, const nsRect& aDirtyRect, - const nsRect& aRect, bool* aBorderIsEmpty); - - ImgDrawResult PaintBorder(nsDisplayListBuilder* aBuilder, - nsPresContext* aPresContext, - gfxContext& aRenderingContext, - const nsRect& aDirtyRect, const nsRect& aRect); - - void SetFrame(nsIFrame* aFrame, nsPresContext* aPresContext); - - void SetDisabled(bool aDisabled, bool notify); - - bool isActive(); - bool isDisabled(); - - void GetButtonInnerFocusRect(const nsRect& aRect, nsRect& aResult); - - ComputedStyle* GetComputedStyle(int32_t aIndex) const; - void SetComputedStyle(int32_t aIndex, ComputedStyle* aComputedStyle); - void ReResolveStyles(nsPresContext* aPresContext); - - nsIFrame* GetFrame(); - - private: - // cached style for optional inner focus outline (used on Windows). - RefPtr mInnerFocusStyle; - - nsIFrame* mFrame; -}; - -#endif diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index a935e3c761..1d4ff15b4f 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -8,25 +8,17 @@ #include "gfxContext.h" #include "gfxUtils.h" -#include "mozilla/gfx/2D.h" -#include "mozilla/gfx/PathHelpers.h" #include "nsCOMPtr.h" #include "nsDeviceContext.h" #include "nsFocusManager.h" -#include "nsCheckboxRadioFrame.h" #include "nsGkAtoms.h" -#include "nsCSSAnonBoxes.h" #include "nsHTMLParts.h" #include "nsIFormControl.h" #include "nsILayoutHistoryState.h" -#include "nsNameSpaceManager.h" #include "nsListControlFrame.h" #include "nsPIDOMWindow.h" -#include "mozilla/PresState.h" #include "nsView.h" #include "nsViewManager.h" -#include "nsIContentInlines.h" -#include "nsIDOMEventListener.h" #include "nsISelectControlFrame.h" #include "nsContentUtils.h" #include "mozilla/dom/Event.h" @@ -48,12 +40,8 @@ #include "nsTextNode.h" #include "mozilla/AsyncEventDispatcher.h" #include "mozilla/LookAndFeel.h" -#include "mozilla/MouseEvents.h" #include "mozilla/PresShell.h" #include "mozilla/PresShellInlines.h" -#include "mozilla/Unused.h" -#include "gfx2DGlue.h" -#include "mozilla/widget/nsAutoRollup.h" using namespace mozilla; using namespace mozilla::gfx; @@ -85,124 +73,17 @@ nsComboboxControlFrame* NS_NewComboboxControlFrame(PresShell* aPresShell, NS_IMPL_FRAMEARENA_HELPERS(nsComboboxControlFrame) -//----------------------------------------------------------- -// Reflow Debugging Macros -// These let us "see" how many reflow counts are happening -//----------------------------------------------------------- -#ifdef DO_REFLOW_COUNTER - -# define MAX_REFLOW_CNT 1024 -static int32_t gTotalReqs = 0; -; -static int32_t gTotalReflows = 0; -; -static int32_t gReflowControlCntRQ[MAX_REFLOW_CNT]; -static int32_t gReflowControlCnt[MAX_REFLOW_CNT]; -static int32_t gReflowInx = -1; - -# define REFLOW_COUNTER() \ - if (mReflowId > -1) gReflowControlCnt[mReflowId]++; - -# define REFLOW_COUNTER_REQUEST() \ - if (mReflowId > -1) gReflowControlCntRQ[mReflowId]++; - -# define REFLOW_COUNTER_DUMP(__desc) \ - if (mReflowId > -1) { \ - gTotalReqs += gReflowControlCntRQ[mReflowId]; \ - gTotalReflows += gReflowControlCnt[mReflowId]; \ - printf("** Id:%5d %s RF: %d RQ: %d %d/%d %5.2f\n", mReflowId, \ - (__desc), gReflowControlCnt[mReflowId], \ - gReflowControlCntRQ[mReflowId], gTotalReflows, gTotalReqs, \ - float(gTotalReflows) / float(gTotalReqs) * 100.0f); \ - } - -# define REFLOW_COUNTER_INIT() \ - if (gReflowInx < MAX_REFLOW_CNT) { \ - gReflowInx++; \ - mReflowId = gReflowInx; \ - gReflowControlCnt[mReflowId] = 0; \ - gReflowControlCntRQ[mReflowId] = 0; \ - } else { \ - mReflowId = -1; \ - } - -// reflow messages -# define REFLOW_DEBUG_MSG(_msg1) printf((_msg1)) -# define REFLOW_DEBUG_MSG2(_msg1, _msg2) printf((_msg1), (_msg2)) -# define REFLOW_DEBUG_MSG3(_msg1, _msg2, _msg3) \ - printf((_msg1), (_msg2), (_msg3)) -# define REFLOW_DEBUG_MSG4(_msg1, _msg2, _msg3, _msg4) \ - printf((_msg1), (_msg2), (_msg3), (_msg4)) - -#else //------------- - -# define REFLOW_COUNTER_REQUEST() -# define REFLOW_COUNTER() -# define REFLOW_COUNTER_DUMP(__desc) -# define REFLOW_COUNTER_INIT() - -# define REFLOW_DEBUG_MSG(_msg) -# define REFLOW_DEBUG_MSG2(_msg1, _msg2) -# define REFLOW_DEBUG_MSG3(_msg1, _msg2, _msg3) -# define REFLOW_DEBUG_MSG4(_msg1, _msg2, _msg3, _msg4) - -#endif - -//------------------------------------------ -// This is for being VERY noisy -//------------------------------------------ -#ifdef DO_VERY_NOISY -# define REFLOW_NOISY_MSG(_msg1) printf((_msg1)) -# define REFLOW_NOISY_MSG2(_msg1, _msg2) printf((_msg1), (_msg2)) -# define REFLOW_NOISY_MSG3(_msg1, _msg2, _msg3) \ - printf((_msg1), (_msg2), (_msg3)) -# define REFLOW_NOISY_MSG4(_msg1, _msg2, _msg3, _msg4) \ - printf((_msg1), (_msg2), (_msg3), (_msg4)) -#else -# define REFLOW_NOISY_MSG(_msg) -# define REFLOW_NOISY_MSG2(_msg1, _msg2) -# define REFLOW_NOISY_MSG3(_msg1, _msg2, _msg3) -# define REFLOW_NOISY_MSG4(_msg1, _msg2, _msg3, _msg4) -#endif - -//------------------------------------------ -// Displays value in pixels or twips -//------------------------------------------ -#ifdef DO_PIXELS -# define PX(__v) __v / 15 -#else -# define PX(__v) __v -#endif - -//------------------------------------------------------ -//-- Done with macros -//------------------------------------------------------ - nsComboboxControlFrame::nsComboboxControlFrame(ComputedStyle* aStyle, nsPresContext* aPresContext) - : nsBlockFrame(aStyle, aPresContext, kClassID), - mDisplayFrame(nullptr), - mButtonFrame(nullptr), - mDisplayISize(0), - mMaxDisplayISize(0), - mRecentSelectedIndex(NS_SKIP_NOTIFY_INDEX), - mDisplayedIndex(-1), - mInRedisplayText(false), - mIsOpenInParentProcess(false){REFLOW_COUNTER_INIT()} - - //-------------------------------------------------------------- - nsComboboxControlFrame::~nsComboboxControlFrame() { - REFLOW_COUNTER_DUMP("nsCCF"); -} + : nsHTMLButtonControlFrame(aStyle, aPresContext, kClassID) {} -//-------------------------------------------------------------- +nsComboboxControlFrame::~nsComboboxControlFrame() = default; NS_QUERYFRAME_HEAD(nsComboboxControlFrame) NS_QUERYFRAME_ENTRY(nsComboboxControlFrame) - NS_QUERYFRAME_ENTRY(nsIFormControlFrame) NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator) NS_QUERYFRAME_ENTRY(nsISelectControlFrame) -NS_QUERYFRAME_TAIL_INHERITING(nsBlockFrame) +NS_QUERYFRAME_TAIL_INHERITING(nsHTMLButtonControlFrame) #ifdef ACCESSIBILITY a11y::AccType nsComboboxControlFrame::AccessibleType() { @@ -210,66 +91,6 @@ a11y::AccType nsComboboxControlFrame::AccessibleType() { } #endif -void nsComboboxControlFrame::SetFocus(bool aOn, bool aRepaint) { - // This is needed on a temporary basis. It causes the focus - // rect to be drawn. This is much faster than ReResolvingStyle - // Bug 32920 - InvalidateFrame(); -} - -nsPoint nsComboboxControlFrame::GetCSSTransformTranslation() { - nsIFrame* frame = this; - bool is3DTransform = false; - Matrix transform; - while (frame) { - nsIFrame* parent; - Matrix4x4Flagged ctm = frame->GetTransformMatrix( - ViewportType::Layout, RelativeTo{nullptr}, &parent); - Matrix matrix; - if (ctm.Is2D(&matrix)) { - transform = transform * matrix; - } else { - is3DTransform = true; - break; - } - frame = parent; - } - nsPoint translation; - if (!is3DTransform && !transform.HasNonTranslation()) { - nsPresContext* pc = PresContext(); - // To get the translation introduced only by transforms we subtract the - // regular non-transform translation. - nsRootPresContext* rootPC = pc->GetRootPresContext(); - if (rootPC) { - int32_t apd = pc->AppUnitsPerDevPixel(); - translation.x = NSFloatPixelsToAppUnits(transform._31, apd); - translation.y = NSFloatPixelsToAppUnits(transform._32, apd); - translation -= GetOffsetToCrossDoc(rootPC->PresShell()->GetRootFrame()); - } - } - return translation; -} - -//---------------------------------------------------------- -// -//---------------------------------------------------------- -#ifdef DO_REFLOW_DEBUG -static int myCounter = 0; - -static void printSize(char* aDesc, nscoord aSize) { - printf(" %s: ", aDesc); - if (aSize == NS_UNCONSTRAINEDSIZE) { - printf("UC"); - } else { - printf("%d", PX(aSize)); - } -} -#endif - -//------------------------------------------------------------------- -//-- Main Reflow for the Combobox -//------------------------------------------------------------------- - bool nsComboboxControlFrame::HasDropDownButton() const { const nsStyleDisplay* disp = StyleDisplay(); // FIXME(emilio): Blink also shows this for menulist-button and such... Seems @@ -357,7 +178,7 @@ nscoord nsComboboxControlFrame::GetIntrinsicISize(gfxContext* aRenderingContext, return *containISize; } - nscoord displayISize = mDisplayFrame->IntrinsicISizeOffsets().padding; + nscoord displayISize = 0; if (!containISize && !StyleContent()->mContent.IsNone()) { displayISize += GetLongestOptionISize(aRenderingContext); } @@ -408,12 +229,6 @@ void nsComboboxControlFrame::Reflow(nsPresContext* aPresContext, // 3) Default block size of button is block size of display area // 4) Inline size of display area is whatever is left over from our // inline size after allocating inline size for the button. - - if (!mDisplayFrame) { - NS_ERROR("Why did the frame constructor allow this to happen? Fix it!!"); - return; - } - // Make sure the displayed text is the same as the selected option, // bug 297389. mDisplayedIndex = Select().SelectedIndex(); @@ -427,53 +242,29 @@ void nsComboboxControlFrame::Reflow(nsPresContext* aPresContext, // Check if the theme specifies a minimum size for the dropdown button // first. const nscoord buttonISize = DropDownButtonISize(); - const auto borderPadding = aReflowInput.ComputedLogicalBorderPadding(wm); const auto padding = aReflowInput.ComputedLogicalPadding(wm); - const auto border = borderPadding - padding; + // We ignore inline-end-padding (by adding it to our label box size) if we + // have a dropdown button, so that the button aligns with the end of the + // padding box. mDisplayISize = aReflowInput.ComputedISize() - buttonISize; - mMaxDisplayISize = mDisplayISize + padding.IEnd(wm); - - nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowInput, aStatus); - - // The button should occupy the same space as a scrollbar, and its position - // starts from the border edge. - if (mButtonFrame) { - LogicalRect buttonRect(wm); - buttonRect.IStart(wm) = borderPadding.IStart(wm) + mMaxDisplayISize; - buttonRect.BStart(wm) = border.BStart(wm); - - buttonRect.ISize(wm) = buttonISize; - buttonRect.BSize(wm) = mDisplayFrame->BSize(wm) + padding.BStartEnd(wm); - - const nsSize containerSize = aDesiredSize.PhysicalSize(); - mButtonFrame->SetRect(buttonRect, containerSize); + if (buttonISize) { + mDisplayISize += padding.IEnd(wm); } - if (!aStatus.IsInlineBreakBefore() && !aStatus.IsFullyComplete()) { - // This frame didn't fit inside a fragmentation container. Splitting - // a nsComboboxControlFrame makes no sense, so we override the status here. - aStatus.Reset(); - } + nsHTMLButtonControlFrame::Reflow(aPresContext, aDesiredSize, aReflowInput, + aStatus); } void nsComboboxControlFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, nsIFrame* aPrevInFlow) { - nsBlockFrame::Init(aContent, aParent, aPrevInFlow); + nsHTMLButtonControlFrame::Init(aContent, aParent, aPrevInFlow); mEventListener = new HTMLSelectEventListener( Select(), HTMLSelectEventListener::SelectType::Combobox); } -#ifdef DEBUG_FRAME_DUMP -nsresult nsComboboxControlFrame::GetFrameName(nsAString& aResult) const { - return MakeFrameName(u"ComboboxControl"_ns, aResult); -} -#endif - -/////////////////////////////////////////////////////////////// - nsresult nsComboboxControlFrame::RedisplaySelectedText() { nsAutoScriptBlocker scriptBlocker; mDisplayedIndex = Select().SelectedIndex(); @@ -494,16 +285,12 @@ nsresult nsComboboxControlFrame::RedisplayText() { mDisplayedOptionTextOrPreview.Truncate(); } - REFLOW_DEBUG_MSG2( - "RedisplayText \"%s\"\n", - NS_LossyConvertUTF16toASCII(mDisplayedOptionTextOrPreview).get()); - // Send reflow command because the new text maybe larger nsresult rv = NS_OK; - if (mDisplayContent && !previousText.Equals(mDisplayedOptionTextOrPreview)) { - // Don't call ActuallyDisplayText(true) directly here since that - // could cause recursive frame construction. See bug 283117 and the comment - // in HandleRedisplayTextEvent() below. + if (!previousText.Equals(mDisplayedOptionTextOrPreview)) { + // Don't call ActuallyDisplayText(true) directly here since that could cause + // recursive frame construction. See bug 283117 and the comment in + // HandleRedisplayTextEvent() below. // Revoke outstanding events to avoid out-of-order events which could mean // displaying the wrong text. @@ -512,7 +299,6 @@ nsresult nsComboboxControlFrame::RedisplayText() { NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), "If we happen to run our redisplay event now, we might kill " "ourselves!"); - mRedisplayTextEvent = new RedisplayTextEvent(this); nsContentUtils::AddScriptRunner(mRedisplayTextEvent.get()); } @@ -520,59 +306,37 @@ nsresult nsComboboxControlFrame::RedisplayText() { } void nsComboboxControlFrame::HandleRedisplayTextEvent() { - // First, make sure that the content model is up to date and we've - // constructed the frames for all our content in the right places. - // Otherwise they'll end up under the wrong insertion frame when we - // ActuallyDisplayText, since that flushes out the content sink by - // calling SetText on a DOM node with aNotify set to true. See bug - // 289730. + // First, make sure that the content model is up to date and we've constructed + // the frames for all our content in the right places. Otherwise they'll end + // up under the wrong insertion frame when we ActuallyDisplayText, since that + // flushes out the content sink by calling SetText on a DOM node with aNotify + // set to true. See bug 289730. AutoWeakFrame weakThis(this); PresContext()->Document()->FlushPendingNotifications( FlushType::ContentAndNotify); - if (!weakThis.IsAlive()) return; - - // Redirect frame insertions during this method (see - // GetContentInsertionFrame()) so that any reframing that the frame - // constructor forces upon us is inserted into the correct parent - // (mDisplayFrame). See bug 282607. - MOZ_ASSERT(!mInRedisplayText, "Nested RedisplayText"); - mInRedisplayText = true; - mRedisplayTextEvent.Forget(); - - ActuallyDisplayText(true); if (!weakThis.IsAlive()) { return; } - - // XXXbz This should perhaps be IntrinsicDirty::None. Check. - PresShell()->FrameNeedsReflow(mDisplayFrame, - IntrinsicDirty::FrameAncestorsAndDescendants, - NS_FRAME_IS_DIRTY); - - mInRedisplayText = false; + mRedisplayTextEvent.Forget(); + ActuallyDisplayText(true); + // Note: `this` might be dead here. } void nsComboboxControlFrame::ActuallyDisplayText(bool aNotify) { - RefPtr displayContent = mDisplayContent; - if (mDisplayedOptionTextOrPreview.IsEmpty()) { - // Have to use a space character of some sort for line-block-size - // calculations to be right. Also, the space character must be zero-width - // in order for the the inline-size calculations to be consistent between - // size-contained comboboxes vs. empty comboboxes. - // - // XXXdholbert Does this space need to be "non-breaking"? I'm not sure - // if it matters, but we previously had a comment here (added in 2002) - // saying "Have to use a non-breaking space for line-height calculations - // to be right". So I'll stick with a non-breaking space for now... - static const char16_t space = 0xFEFF; - displayContent->SetText(&space, 1, aNotify); - } else { - displayContent->SetText(mDisplayedOptionTextOrPreview, aNotify); - } -} - -int32_t nsComboboxControlFrame::GetIndexOfDisplayArea() { - return mDisplayedIndex; + RefPtr displayContent = mDisplayLabel->GetFirstChild()->AsText(); + // Have to use a space character of some sort for line-block-size calculations + // to be right. Also, the space character must be zero-width in order for the + // inline-size calculations to be consistent between size-contained comboboxes + // vs. empty comboboxes. + // + // XXXdholbert Does this space need to be "non-breaking"? I'm not sure if it + // matters, but we previously had a comment here (added in 2002) saying "Have + // to use a non-breaking space for line-height calculations to be right". So + // I'll stick with a non-breaking space for now... + displayContent->SetText(mDisplayedOptionTextOrPreview.IsEmpty() + ? u"\ufeff"_ns + : mDisplayedOptionTextOrPreview, + aNotify); } bool nsComboboxControlFrame::IsDroppedDown() const { @@ -631,53 +395,19 @@ nsresult nsComboboxControlFrame::HandleEvent(nsPresContext* aPresContext, return NS_OK; } - if (mContent->AsElement()->State().HasState(dom::ElementState::DISABLED)) { - return NS_OK; - } - - // If we have style that affects how we are selected, feed event down to - // nsIFrame::HandleEvent so that selection takes place when appropriate. - if (IsContentDisabled()) { - return nsBlockFrame::HandleEvent(aPresContext, aEvent, aEventStatus); - } - return NS_OK; -} - -nsContainerFrame* nsComboboxControlFrame::GetContentInsertionFrame() { - return mInRedisplayText ? mDisplayFrame : nullptr; -} - -void nsComboboxControlFrame::AppendDirectlyOwnedAnonBoxes( - nsTArray& aResult) { - aResult.AppendElement(OwnedAnonBox(mDisplayFrame)); + return nsHTMLButtonControlFrame::HandleEvent(aPresContext, aEvent, + aEventStatus); } nsresult nsComboboxControlFrame::CreateAnonymousContent( nsTArray& aElements) { - // The frames used to display the combo box and the button used to popup the - // dropdown list are created through anonymous content. The dropdown list is - // not created through anonymous content because its frame is initialized - // specifically for the drop-down case and it is placed a special list - // referenced through NS_COMBO_FRAME_POPUP_LIST_INDEX to keep separate from - // the layout of the display and button. - // - // Note: The value attribute of the display content is set when an item is - // selected in the dropdown list. If the content specified below does not - // honor the value attribute than nothing will be displayed. - - // For now the content that is created corresponds to two input buttons. It - // would be better to create the tag as something other than input, but then - // there isn't any way to create a button frame since it isn't possible to set - // the display type in CSS2 to create a button frame. - - // create content used for display - // nsAtom* tag = NS_Atomize("mozcombodisplay"); - - // Add a child text content node for the label + dom::Document* doc = mContent->OwnerDoc(); + mDisplayLabel = doc->CreateHTMLElement(nsGkAtoms::label); - nsNodeInfoManager* nimgr = mContent->NodeInfo()->NodeInfoManager(); - - mDisplayContent = new (nimgr) nsTextNode(nimgr); + { + RefPtr text = doc->CreateEmptyTextNode(); + mDisplayLabel->AppendChildTo(text, false, IgnoreErrors()); + } // set the value of the text node mDisplayedIndex = Select().SelectedIndex(); @@ -686,14 +416,17 @@ nsresult nsComboboxControlFrame::CreateAnonymousContent( } ActuallyDisplayText(false); - aElements.AppendElement(mDisplayContent); + aElements.AppendElement(mDisplayLabel); if (HasDropDownButton()) { mButtonContent = mContent->OwnerDoc()->CreateHTMLElement(nsGkAtoms::button); - if (!mButtonContent) { - return NS_ERROR_OUT_OF_MEMORY; + { + // This gives the button a reasonable height. This could be done via CSS + // instead, but relative font units like 1lh don't play very well with our + // font inflation implementation, so we do it this way instead. + RefPtr text = doc->CreateTextNode(u"\ufeff"_ns); + mButtonContent->AppendChildTo(text, false, IgnoreErrors()); } - - // make someone to listen to the button. + // Make someone to listen to the button. mButtonContent->SetAttr(kNameSpaceID_None, nsGkAtoms::type, u"button"_ns, false); // Set tabindex="-1" so that the button is not tabbable @@ -707,8 +440,8 @@ nsresult nsComboboxControlFrame::CreateAnonymousContent( void nsComboboxControlFrame::AppendAnonymousContentTo( nsTArray& aElements, uint32_t aFilter) { - if (mDisplayContent) { - aElements.AppendElement(mDisplayContent); + if (mDisplayLabel) { + aElements.AppendElement(mDisplayLabel); } if (mButtonContent) { @@ -716,226 +449,66 @@ void nsComboboxControlFrame::AppendAnonymousContentTo( } } -nsIContent* nsComboboxControlFrame::GetDisplayNode() const { - return mDisplayContent; -} +namespace mozilla { -// XXXbz this is a for-now hack. Now that display:inline-block works, -// need to revisit this. -class nsComboboxDisplayFrame final : public nsBlockFrame { +class ComboboxLabelFrame final : public nsBlockFrame { public: - NS_DECL_FRAMEARENA_HELPERS(nsComboboxDisplayFrame) - - nsComboboxDisplayFrame(ComputedStyle* aStyle, - nsComboboxControlFrame* aComboBox) - : nsBlockFrame(aStyle, aComboBox->PresContext(), kClassID), - mComboBox(aComboBox) {} + NS_DECL_QUERYFRAME + NS_DECL_FRAMEARENA_HELPERS(ComboboxLabelFrame) #ifdef DEBUG_FRAME_DUMP nsresult GetFrameName(nsAString& aResult) const final { - return MakeFrameName(u"ComboboxDisplay"_ns, aResult); + return MakeFrameName(u"ComboboxLabel"_ns, aResult); } #endif void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, const ReflowInput& aReflowInput, nsReflowStatus& aStatus) final; - void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsDisplayListSet& aLists) final; - - protected: - nsComboboxControlFrame* mComboBox; + public: + ComboboxLabelFrame(ComputedStyle* aStyle, nsPresContext* aPresContext) + : nsBlockFrame(aStyle, aPresContext, kClassID) {} }; -NS_IMPL_FRAMEARENA_HELPERS(nsComboboxDisplayFrame) +NS_QUERYFRAME_HEAD(ComboboxLabelFrame) + NS_QUERYFRAME_ENTRY(ComboboxLabelFrame) +NS_QUERYFRAME_TAIL_INHERITING(nsBlockFrame) +NS_IMPL_FRAMEARENA_HELPERS(ComboboxLabelFrame) -void nsComboboxDisplayFrame::Reflow(nsPresContext* aPresContext, - ReflowOutput& aDesiredSize, - const ReflowInput& aReflowInput, - nsReflowStatus& aStatus) { +void ComboboxLabelFrame::Reflow(nsPresContext* aPresContext, + ReflowOutput& aDesiredSize, + const ReflowInput& aReflowInput, + nsReflowStatus& aStatus) { MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); - MOZ_ASSERT(aReflowInput.mParentReflowInput && - aReflowInput.mParentReflowInput->mFrame == mComboBox, - "Combobox's frame tree is wrong!"); - ReflowInput state(aReflowInput); - if (state.ComputedBSize() == NS_UNCONSTRAINEDSIZE) { - state.SetLineHeight(state.mParentReflowInput->GetLineHeight()); - } - const WritingMode wm = aReflowInput.GetWritingMode(); - const LogicalMargin bp = state.ComputedLogicalBorderPadding(wm); - MOZ_ASSERT(bp.BStartEnd(wm) == 0, - "We shouldn't have border and padding in the block axis in UA!"); - nscoord inlineBp = bp.IStartEnd(wm); - nscoord computedISize = mComboBox->mDisplayISize - inlineBp; - - // Other UAs ignore padding in some (but not all) platforms for (themed only) - // comboboxes. Instead of doing that, we prevent that padding if present from - // clipping the display text, by enforcing the display text minimum size in - // that situation. - const bool shouldHonorMinISize = - mComboBox->StyleDisplay()->EffectiveAppearance() == - StyleAppearance::Menulist; - if (shouldHonorMinISize) { - computedISize = std::max(state.ComputedMinISize(), computedISize); - // Don't let this size go over mMaxDisplayISize, since that'd be - // observable via clientWidth / scrollWidth. - computedISize = - std::min(computedISize, mComboBox->mMaxDisplayISize - inlineBp); - } + const nsComboboxControlFrame* combobox = + do_QueryFrame(GetParent()->GetParent()); + MOZ_ASSERT(combobox, "Combobox's frame tree is wrong!"); + MOZ_ASSERT(aReflowInput.ComputedPhysicalBorderPadding() == nsMargin(), + "We shouldn't have border and padding in UA!"); - state.SetComputedISize(std::max(0, computedISize)); + ReflowInput state(aReflowInput); + state.SetComputedISize(combobox->mDisplayISize); nsBlockFrame::Reflow(aPresContext, aDesiredSize, state, aStatus); aStatus.Reset(); // this type of frame can't be split } -void nsComboboxDisplayFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsDisplayListSet& aLists) { - nsDisplayListCollection set(aBuilder); - nsBlockFrame::BuildDisplayList(aBuilder, set); - - // remove background items if parent frame is themed - if (mComboBox->IsThemed()) { - set.BorderBackground()->DeleteAll(aBuilder); - } - - set.MoveTo(aLists); -} - -nsIFrame* nsComboboxControlFrame::CreateFrameForDisplayNode() { - MOZ_ASSERT(mDisplayContent); - - // Get PresShell - mozilla::PresShell* ps = PresShell(); - ServoStyleSet* styleSet = ps->StyleSet(); - - // create the ComputedStyle for the anonymous block frame and text frame - RefPtr computedStyle = - styleSet->ResolveInheritingAnonymousBoxStyle( - PseudoStyleType::mozDisplayComboboxControlFrame, mComputedStyle); - - RefPtr textComputedStyle = - styleSet->ResolveStyleForText(mDisplayContent, mComputedStyle); - - // Start by creating our anonymous block frame - mDisplayFrame = new (ps) nsComboboxDisplayFrame(computedStyle, this); - mDisplayFrame->Init(mContent, this, nullptr); - - // Create a text frame and put it inside the block frame - nsIFrame* textFrame = NS_NewTextFrame(ps, textComputedStyle); - - // initialize the text frame - textFrame->Init(mDisplayContent, mDisplayFrame, nullptr); - mDisplayContent->SetPrimaryFrame(textFrame); +} // namespace mozilla - mDisplayFrame->SetInitialChildList(FrameChildListID::Principal, - nsFrameList(textFrame, textFrame)); - return mDisplayFrame; +nsIFrame* NS_NewComboboxLabelFrame(PresShell* aPresShell, + ComputedStyle* aStyle) { + return new (aPresShell) + ComboboxLabelFrame(aStyle, aPresShell->GetPresContext()); } void nsComboboxControlFrame::Destroy(DestroyContext& aContext) { // Revoke any pending RedisplayTextEvent mRedisplayTextEvent.Revoke(); - mEventListener->Detach(); - // Cleanup frames in popup child list - aContext.AddAnonymousContent(mDisplayContent.forget()); + aContext.AddAnonymousContent(mDisplayLabel.forget()); aContext.AddAnonymousContent(mButtonContent.forget()); - nsBlockFrame::Destroy(aContext); -} - -const nsFrameList& nsComboboxControlFrame::GetChildList( - ChildListID aListID) const { - return nsBlockFrame::GetChildList(aListID); -} - -void nsComboboxControlFrame::GetChildLists(nsTArray* aLists) const { - nsBlockFrame::GetChildLists(aLists); -} - -void nsComboboxControlFrame::SetInitialChildList(ChildListID aListID, - nsFrameList&& aChildList) { - for (nsIFrame* f : aChildList) { - MOZ_ASSERT(f->GetParent() == this, "Unexpected parent"); - nsCOMPtr formControl = do_QueryInterface(f->GetContent()); - if (formControl && - formControl->ControlType() == FormControlType::ButtonButton) { - mButtonFrame = f; - break; - } - } - nsBlockFrame::SetInitialChildList(aListID, std::move(aChildList)); -} - -namespace mozilla { - -class nsDisplayComboboxFocus : public nsPaintedDisplayItem { - public: - nsDisplayComboboxFocus(nsDisplayListBuilder* aBuilder, - nsComboboxControlFrame* aFrame) - : nsPaintedDisplayItem(aBuilder, aFrame) { - MOZ_COUNT_CTOR(nsDisplayComboboxFocus); - } - MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayComboboxFocus) - - void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; - NS_DISPLAY_DECL_NAME("ComboboxFocus", TYPE_COMBOBOX_FOCUS) -}; - -void nsDisplayComboboxFocus::Paint(nsDisplayListBuilder* aBuilder, - gfxContext* aCtx) { - static_cast(mFrame)->PaintFocus( - *aCtx->GetDrawTarget(), ToReferenceFrame()); -} - -} // namespace mozilla - -void nsComboboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsDisplayListSet& aLists) { - if (aBuilder->IsForEventDelivery()) { - // Don't allow children to receive events. - // REVIEW: following old GetFrameForPoint - DisplayBorderBackgroundOutline(aBuilder, aLists); - } else { - // REVIEW: Our in-flow child frames are inline-level so they will paint in - // our content list, so we don't need to mess with layers. - nsBlockFrame::BuildDisplayList(aBuilder, aLists); - } - - // draw a focus indicator only when focus rings should be drawn - if (Select().State().HasState(dom::ElementState::FOCUSRING) && IsThemed() && - PresContext()->Theme()->ThemeWantsButtonInnerFocusRing()) { - aLists.Content()->AppendNewToTop(aBuilder, this); - } - - DisplaySelectionOverlay(aBuilder, aLists.Content()); -} - -void nsComboboxControlFrame::PaintFocus(DrawTarget& aDrawTarget, nsPoint aPt) { - /* Do we need to do anything? */ - dom::ElementState state = mContent->AsElement()->State(); - if (state.HasState(dom::ElementState::DISABLED) || - !state.HasState(dom::ElementState::FOCUS)) { - return; - } - - int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); - - nsRect clipRect = mDisplayFrame->GetRect() + aPt; - aDrawTarget.PushClipRect( - NSRectToSnappedRect(clipRect, appUnitsPerDevPixel, aDrawTarget)); - - StrokeOptions strokeOptions; - nsLayoutUtils::InitDashPattern(strokeOptions, StyleBorderStyle::Dotted); - ColorPattern color(ToDeviceColor(StyleText()->mColor)); - nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1); - clipRect.width -= onePixel; - clipRect.height -= onePixel; - Rect r = ToRect(nsLayoutUtils::RectToGfxRect(clipRect, appUnitsPerDevPixel)); - StrokeSnappedEdgesOfRect(r, aDrawTarget, color, strokeOptions); - - aDrawTarget.PopClip(); + nsHTMLButtonControlFrame::Destroy(aContext); } //--------------------------------------------------------- @@ -960,6 +533,7 @@ nsComboboxControlFrame::OnOptionSelected(int32_t aIndex, bool aSelected) { void nsComboboxControlFrame::FireValueChangeEvent() { // Fire ValueChange event to indicate data value of combo box has changed + // FIXME(emilio): This shouldn't be exposed to content. nsContentUtils::AddScriptRunner(new AsyncEventDispatcher( mContent, u"ValueChange"_ns, CanBubble::eYes, ChromeOnlyDispatch::eNo)); } diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h index e878c0ebe3..4daa636f1a 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -7,56 +7,30 @@ #ifndef nsComboboxControlFrame_h___ #define nsComboboxControlFrame_h___ -#ifdef DEBUG_evaughan -// #define DEBUG_rods -#endif - -#ifdef DEBUG_rods -// #define DO_REFLOW_DEBUG -// #define DO_REFLOW_COUNTER -// #define DO_UNCONSTRAINED_CHECK -// #define DO_PIXELS -// #define DO_NEW_REFLOW -#endif - -// Mark used to indicate when onchange has been fired for current combobox item -#define NS_SKIP_NOTIFY_INDEX -2 - #include "mozilla/Attributes.h" -#include "nsBlockFrame.h" #include "nsIFormControlFrame.h" #include "nsIAnonymousContentCreator.h" #include "nsISelectControlFrame.h" #include "nsIRollupListener.h" #include "nsThreadUtils.h" - -class nsComboboxDisplayFrame; -class nsTextNode; +#include "nsHTMLButtonControlFrame.h" namespace mozilla { class PresShell; class HTMLSelectEventListener; +class ComboboxLabelFrame; namespace dom { class HTMLSelectElement; } - -namespace gfx { -class DrawTarget; -} // namespace gfx } // namespace mozilla -class nsComboboxControlFrame final : public nsBlockFrame, - public nsIFormControlFrame, +class nsComboboxControlFrame final : public nsHTMLButtonControlFrame, public nsIAnonymousContentCreator, public nsISelectControlFrame { - using DrawTarget = mozilla::gfx::DrawTarget; using Element = mozilla::dom::Element; public: - friend nsComboboxControlFrame* NS_NewComboboxControlFrame( - mozilla::PresShell* aPresShell, ComputedStyle* aStyle); - friend class nsComboboxDisplayFrame; - + friend class mozilla::ComboboxLabelFrame; explicit nsComboboxControlFrame(ComputedStyle* aStyle, nsPresContext* aPresContext); ~nsComboboxControlFrame(); @@ -69,17 +43,17 @@ class nsComboboxControlFrame final : public nsBlockFrame, void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) final; - nsIContent* GetDisplayNode() const; - nsIFrame* CreateFrameForDisplayNode(); - #ifdef ACCESSIBILITY mozilla::a11y::AccType AccessibleType() final; #endif nscoord GetMinISize(gfxContext* aRenderingContext) final; - nscoord GetPrefISize(gfxContext* aRenderingContext) final; + // We're a leaf, so we need to report ourselves as the content insertion + // frame. + nsContainerFrame* GetContentInsertionFrame() override { return this; } + void Reflow(nsPresContext* aCX, ReflowOutput& aDesiredSize, const ReflowInput& aReflowInput, nsReflowStatus& aStatus) final; @@ -88,60 +62,26 @@ class nsComboboxControlFrame final : public nsBlockFrame, mozilla::WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) final; - void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsDisplayListSet& aLists) final; - - void PaintFocus(DrawTarget& aDrawTarget, nsPoint aPt); - void Init(nsIContent* aContent, nsContainerFrame* aParent, nsIFrame* aPrevInFlow) final; + void Destroy(DestroyContext&) final; #ifdef DEBUG_FRAME_DUMP - nsresult GetFrameName(nsAString& aResult) const final; + nsresult GetFrameName(nsAString& aResult) const final { + return MakeFrameName(u"ComboboxControl"_ns, aResult); + } #endif - void Destroy(DestroyContext&) final; - - void SetInitialChildList(ChildListID aListID, nsFrameList&& aChildList) final; - const nsFrameList& GetChildList(ChildListID aListID) const final; - void GetChildLists(nsTArray* aLists) const final; - - nsContainerFrame* GetContentInsertionFrame() final; - - // Return the dropdown and display frame. - void AppendDirectlyOwnedAnonBoxes(nsTArray& aResult) final; // nsIFormControlFrame nsresult SetFormProperty(nsAtom* aName, const nsAString& aValue) final { return NS_OK; } - /** - * Inform the control that it got (or lost) focus. - * If it lost focus, the dropdown menu will be rolled up if needed, - * and FireOnChange() will be called. - * @param aOn true if got focus, false if lost focus. - * @param aRepaint if true then force repaint (NOTE: we always force repaint - * currently) - * @note This method might destroy |this|. - */ - MOZ_CAN_RUN_SCRIPT_BOUNDARY - void SetFocus(bool aOn, bool aRepaint) final; - - /** - * Return the available space before and after this frame for - * placing the drop-down list, and the current 2D translation. - * Note that either or both can be less than or equal to zero, - * if both are then the drop-down should be closed. - */ - void GetAvailableDropdownSpace(mozilla::WritingMode aWM, nscoord* aBefore, - nscoord* aAfter, - mozilla::LogicalPoint* aTranslation); - int32_t GetIndexOfDisplayArea(); /** * @note This method might destroy |this|. */ + void FireValueChangeEvent(); nsresult RedisplaySelectedText(); - int32_t UpdateRecentIndex(int32_t aIndex); bool IsDroppedDown() const; @@ -192,53 +132,23 @@ class nsComboboxControlFrame final : public nsBlockFrame, nsComboboxControlFrame* mControlFrame; }; - void CheckFireOnChange(); - void FireValueChangeEvent(); nsresult RedisplayText(); void HandleRedisplayTextEvent(); void ActuallyDisplayText(bool aNotify); - // If our total transform to the root frame of the root document is only a 2d - // translation then return that translation, otherwise returns (0,0). - nsPoint GetCSSTransformTranslation(); - mozilla::dom::HTMLSelectElement& Select() const; void GetOptionText(uint32_t aIndex, nsAString& aText) const; - RefPtr mDisplayContent; // Anonymous content used to display the - // current selection - RefPtr mButtonContent; // Anonymous content for the button - nsContainerFrame* mDisplayFrame; // frame to display selection - nsIFrame* mButtonFrame; // button frame - - // The inline size of our display area. Used by that frame's reflow - // to size to the full inline size except the drop-marker. - nscoord mDisplayISize; - // The maximum inline size of our display area, which is the - // nsComoboxControlFrame's border-box. - // - // Going over this would be observable via DOM APIs like client / scrollWidth. - nscoord mMaxDisplayISize; - + RefPtr mDisplayLabel; // Anonymous content for the label + RefPtr mButtonContent; // Anonymous content for the button nsRevocableEventPtr mRedisplayTextEvent; - int32_t mRecentSelectedIndex; - int32_t mDisplayedIndex; + // The inline size of our display area. Used by that frame's reflow to size to + // the full inline size except the drop-marker. + nscoord mDisplayISize = 0; + int32_t mDisplayedIndex = -1; nsString mDisplayedOptionTextOrPreview; - RefPtr mEventListener; - - // See comment in HandleRedisplayTextEvent(). - bool mInRedisplayText; - bool mIsOpenInParentProcess; - - // static class data member for Bug 32920 - // only one control can be focused at a time - static nsComboboxControlFrame* sFocused; - -#ifdef DO_REFLOW_COUNTER - int32_t mReflowId; -#endif }; #endif diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index 03781da8bd..c96b293e82 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -785,11 +785,6 @@ void nsFieldSetFrame::Reflow(nsPresContext* aPresContext, void nsFieldSetFrame::SetInitialChildList(ChildListID aListID, nsFrameList&& aChildList) { nsContainerFrame::SetInitialChildList(aListID, std::move(aChildList)); - if (nsBlockFrame* legend = do_QueryFrame(GetLegend())) { - // A rendered legend always establish a new formatting context. - // https://html.spec.whatwg.org/multipage/rendering.html#rendered-legend - legend->AddStateBits(NS_BLOCK_STATIC_BFC); - } MOZ_ASSERT( aListID != FrameChildListID::Principal || GetInner() || GetLegend(), "Setting principal child list should populate our inner frame " @@ -816,11 +811,6 @@ void nsFieldSetFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, nsContainerFrame::InsertFrames(aListID, aPrevFrame, aPrevFrameLine, std::move(aFrameList)); MOZ_ASSERT(GetLegend()); - if (nsBlockFrame* legend = do_QueryFrame(GetLegend())) { - // A rendered legend always establish a new formatting context. - // https://html.spec.whatwg.org/multipage/rendering.html#rendered-legend - legend->AddStateBits(NS_BLOCK_STATIC_BFC); - } } #ifdef DEBUG diff --git a/layout/forms/nsGfxButtonControlFrame.cpp b/layout/forms/nsGfxButtonControlFrame.cpp index 37aa996c27..b250030e13 100644 --- a/layout/forms/nsGfxButtonControlFrame.cpp +++ b/layout/forms/nsGfxButtonControlFrame.cpp @@ -160,10 +160,6 @@ nsresult nsGfxButtonControlFrame::AttributeChanged(int32_t aNameSpaceID, return rv; } -nsContainerFrame* nsGfxButtonControlFrame::GetContentInsertionFrame() { - return this; -} - nsresult nsGfxButtonControlFrame::HandleEvent(nsPresContext* aPresContext, WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) { diff --git a/layout/forms/nsGfxButtonControlFrame.h b/layout/forms/nsGfxButtonControlFrame.h index 32d4689559..38c30590ab 100644 --- a/layout/forms/nsGfxButtonControlFrame.h +++ b/layout/forms/nsGfxButtonControlFrame.h @@ -7,9 +7,7 @@ #ifndef nsGfxButtonControlFrame_h___ #define nsGfxButtonControlFrame_h___ -#include "mozilla/Attributes.h" #include "nsHTMLButtonControlFrame.h" -#include "nsCOMPtr.h" #include "nsIAnonymousContentCreator.h" class nsTextNode; @@ -29,26 +27,25 @@ class nsGfxButtonControlFrame final : public nsHTMLButtonControlFrame, void Destroy(DestroyContext&) override; - virtual nsresult HandleEvent(nsPresContext* aPresContext, - mozilla::WidgetGUIEvent* aEvent, - nsEventStatus* aEventStatus) override; + nsresult HandleEvent(nsPresContext* aPresContext, + mozilla::WidgetGUIEvent* aEvent, + nsEventStatus* aEventStatus) override; #ifdef DEBUG_FRAME_DUMP - virtual nsresult GetFrameName(nsAString& aResult) const override; + nsresult GetFrameName(nsAString& aResult) const override; #endif NS_DECL_QUERYFRAME // 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 nsContainerFrame* GetContentInsertionFrame() override; + nsContainerFrame* GetContentInsertionFrame() override { return this; } protected: nsresult GetDefaultLabel(nsAString& aLabel) const; diff --git a/layout/forms/nsHTMLButtonControlFrame.cpp b/layout/forms/nsHTMLButtonControlFrame.cpp index 7a599f093b..cb24ccbfb9 100644 --- a/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/layout/forms/nsHTMLButtonControlFrame.cpp @@ -10,15 +10,17 @@ #include "mozilla/PresShell.h" #include "nsIFrameInlines.h" #include "nsContainerFrame.h" +#include "nsPresContextInlines.h" #include "nsIFormControlFrame.h" #include "nsPresContext.h" #include "nsLayoutUtils.h" #include "nsGkAtoms.h" -#include "nsButtonFrameRenderer.h" #include "nsDisplayList.h" +#include "nsCSSRendering.h" #include using namespace mozilla; +using namespace mozilla::image; nsContainerFrame* NS_NewHTMLButtonControlFrame(PresShell* aPresShell, ComputedStyle* aStyle) { @@ -39,7 +41,13 @@ void nsHTMLButtonControlFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, nsIFrame* aPrevInFlow) { nsContainerFrame::Init(aContent, aParent, aPrevInFlow); - mRenderer.SetFrame(this, PresContext()); + + // get all the styles + ServoStyleSet* styleSet = PresContext()->StyleSet(); + + // Get styles assigned to -moz-focus-inner (i.e. dotted border on Windows) + mInnerFocusStyle = styleSet->ProbePseudoElementStyle( + *mContent->AsElement(), PseudoStyleType::mozFocusInner, nullptr, Style()); } NS_QUERYFRAME_HEAD(nsHTMLButtonControlFrame) @@ -57,8 +65,8 @@ void nsHTMLButtonControlFrame::SetFocus(bool aOn, bool aRepaint) {} nsresult nsHTMLButtonControlFrame::HandleEvent(nsPresContext* aPresContext, WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) { - // if disabled do nothing - if (mRenderer.isDisabled()) { + if (mContent->AsElement()->IsDisabled()) { + // If disabled do nothing return NS_OK; } @@ -67,14 +75,125 @@ nsresult nsHTMLButtonControlFrame::HandleEvent(nsPresContext* aPresContext, return nsIFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } -bool nsHTMLButtonControlFrame::ShouldClipPaintingToBorderBox() { +bool nsHTMLButtonControlFrame::ShouldClipPaintingToBorderBox() const { // FIXME(emilio): probably should account for per-axis clipping... return StyleDisplay()->mOverflowX != StyleOverflow::Visible; } +namespace mozilla { + +class nsDisplayButtonForeground final : public nsPaintedDisplayItem { + public: + nsDisplayButtonForeground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) + : nsPaintedDisplayItem(aBuilder, aFrame) { + MOZ_COUNT_CTOR(nsDisplayButtonForeground); + } + MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayButtonForeground) + + void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; + bool CreateWebRenderCommands( + mozilla::wr::DisplayListBuilder& aBuilder, + mozilla::wr::IpcResourceUpdateQueue& aResources, + const StackingContextHelper& aSc, + mozilla::layers::RenderRootStateManager* aManager, + nsDisplayListBuilder* aDisplayListBuilder) override; + NS_DISPLAY_DECL_NAME("ButtonForeground", TYPE_BUTTON_FOREGROUND) +}; + +void nsDisplayButtonForeground::Paint(nsDisplayListBuilder* aBuilder, + gfxContext* aCtx) { + static_cast(mFrame)->PaintInnerFocusBorder( + aBuilder, *aCtx, GetPaintRect(aBuilder, aCtx), + nsRect(ToReferenceFrame(), mFrame->GetSize())); +} + +bool nsDisplayButtonForeground::CreateWebRenderCommands( + mozilla::wr::DisplayListBuilder& aBuilder, + mozilla::wr::IpcResourceUpdateQueue& aResources, + const StackingContextHelper& aSc, + mozilla::layers::RenderRootStateManager* aManager, + nsDisplayListBuilder* aDisplayListBuilder) { + bool borderIsEmpty = false; + bool dummy; + Maybe br = + static_cast(mFrame) + ->CreateInnerFocusBorderRenderer( + aDisplayListBuilder, nullptr, + GetBounds(aDisplayListBuilder, &dummy), + nsRect(ToReferenceFrame(), mFrame->GetSize()), &borderIsEmpty); + + if (!br) { + return borderIsEmpty; + } + + aBuilder.StartGroup(this); + br->CreateWebRenderCommands(this, aBuilder, aResources, aSc); + aBuilder.FinishGroup(); + + return true; +} + +} // namespace mozilla + +static nsRect GetButtonInnerFocusRect(const nsIFrame* aFrame, + const ComputedStyle& aFocusStyle, + const nsRect& aRect) { + nsRect result = aRect; + result.Deflate(aFrame->GetUsedBorderAndPadding()); + + nsMargin innerFocusPadding; + aFocusStyle.StylePadding()->GetPadding(innerFocusPadding); + + nsMargin framePadding = aFrame->GetUsedPadding(); + innerFocusPadding.top = std::min(innerFocusPadding.top, framePadding.top); + innerFocusPadding.right = + std::min(innerFocusPadding.right, framePadding.right); + innerFocusPadding.bottom = + std::min(innerFocusPadding.bottom, framePadding.bottom); + innerFocusPadding.left = std::min(innerFocusPadding.left, framePadding.left); + + result.Inflate(innerFocusPadding); + return result; +} + +void nsHTMLButtonControlFrame::PaintInnerFocusBorder( + nsDisplayListBuilder* aBuilder, gfxContext& aRenderingContext, + const nsRect& aDirtyRect, const nsRect& aRect) { + if (!mInnerFocusStyle) { + return; + } + + // we draw the -moz-focus-inner border just inside the button's + // normal border and padding, to match Windows themes. + PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages() + ? PaintBorderFlags::SyncDecodeImages + : PaintBorderFlags(); + + nsRect rect = GetButtonInnerFocusRect(this, *mInnerFocusStyle, aRect); + // We don't paint border images here, so the ImgDrawResult is useless. + Unused << nsCSSRendering::PaintBorder(PresContext(), aRenderingContext, this, + aDirtyRect, rect, mInnerFocusStyle, + flags); +} + +Maybe +nsHTMLButtonControlFrame::CreateInnerFocusBorderRenderer( + nsDisplayListBuilder* aBuilder, gfxContext* aRenderingContext, + const nsRect& aDirtyRect, const nsRect& aRect, bool* aBorderIsEmpty) { + if (!mInnerFocusStyle) { + return Nothing(); + } + + nsRect rect = GetButtonInnerFocusRect(this, *mInnerFocusStyle, aRect); + gfx::DrawTarget* dt = + aRenderingContext ? aRenderingContext->GetDrawTarget() : nullptr; + return nsCSSRendering::CreateBorderRenderer(PresContext(), dt, this, + aDirtyRect, rect, + mInnerFocusStyle, aBorderIsEmpty); +} + void nsHTMLButtonControlFrame::BuildDisplayList( nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) { - nsDisplayList onTop(aBuilder); if (IsVisibleForPainting()) { // Clip the button itself to its border area for event hit testing. Maybe eventClipState; @@ -87,11 +206,9 @@ void nsHTMLButtonControlFrame::BuildDisplayList( rect, hasRadii ? radii : nullptr); } - mRenderer.DisplayButton(aBuilder, aLists.BorderBackground(), &onTop); + DisplayBorderBackgroundOutline(aBuilder, aLists); } - nsDisplayListCollection set(aBuilder); - { DisplayListClipState::AutoSaveRestore clipState(aBuilder); @@ -100,22 +217,23 @@ void nsHTMLButtonControlFrame::BuildDisplayList( nsRect rect(aBuilder->ToReferenceFrame(this), GetSize()); rect.Deflate(border); nscoord radii[8]; - bool hasRadii = GetPaddingBoxBorderRadii(radii); + const bool hasRadii = GetPaddingBoxBorderRadii(radii); clipState.ClipContainingBlockDescendants(rect, hasRadii ? radii : nullptr); } - BuildDisplayListForChild(aBuilder, mFrames.FirstChild(), set, + BuildDisplayListForChild(aBuilder, mFrames.FirstChild(), aLists, DisplayChildFlag::ForcePseudoStackingContext); } - // Put the foreground outline and focus rects on top of the children - set.Content()->AppendToTop(&onTop); - set.MoveTo(aLists); - - DisplayOutline(aBuilder, aLists); + // Put the foreground outline on top of the children. + if (IsVisibleForPainting() && mInnerFocusStyle && + mInnerFocusStyle->StyleBorder()->HasBorder() && IsThemed() && + PresContext()->Theme()->ThemeWantsButtonInnerFocusRing()) { + aLists.Content()->AppendNewToTop(aBuilder, this); + } - // to draw border when selected in editor + // To draw border when selected in editor DisplaySelectionOverlay(aBuilder, aLists.Content()); } @@ -237,12 +355,14 @@ void nsHTMLButtonControlFrame::ReflowButtonContents( // Button has a fixed block-size -- that's its content-box bSize. buttonContentBox.BSize(wm) = aButtonReflowInput.ComputedBSize(); } else { - // Button is intrinsically sized -- it should shrinkwrap the - // button-contents' bSize. But if it has size containment in block axis, - // ignore the contents and use contain-intrinsic-block-size. - nscoord bSize = aButtonReflowInput.mFrame->ContainIntrinsicBSize().valueOr( - contentsDesiredSize.BSize(wm)); - + // Button is intrinsically sized -- it should shrinkwrap the contents' + // bSize. + // If we have size containment in block axis, ignore the contents and use + // contain-intrinsic-block-size. The combobox content size with no content + // is one line-height, not zero. + const Maybe containBSize = ContainIntrinsicBSize( + IsComboboxControlFrame() ? aButtonReflowInput.GetLineHeight() : 0); + const nscoord bSize = containBSize.valueOr(contentsDesiredSize.BSize(wm)); // Make sure we obey min/max-bSize in the case when we're doing intrinsic // sizing (we get it for free when we have a non-intrinsic // aButtonReflowInput.ComputedBSize()). Note that we do this before @@ -359,12 +479,17 @@ nsresult nsHTMLButtonControlFrame::SetFormProperty(nsAtom* aName, ComputedStyle* nsHTMLButtonControlFrame::GetAdditionalComputedStyle( int32_t aIndex) const { - return mRenderer.GetComputedStyle(aIndex); + if (aIndex == 0) { + return mInnerFocusStyle; + } + return nullptr; } void nsHTMLButtonControlFrame::SetAdditionalComputedStyle( int32_t aIndex, ComputedStyle* aComputedStyle) { - mRenderer.SetComputedStyle(aIndex, aComputedStyle); + if (aIndex == 0) { + mInnerFocusStyle = aComputedStyle; + } } void nsHTMLButtonControlFrame::AppendDirectlyOwnedAnonBoxes( diff --git a/layout/forms/nsHTMLButtonControlFrame.h b/layout/forms/nsHTMLButtonControlFrame.h index b4409d66a7..760418f954 100644 --- a/layout/forms/nsHTMLButtonControlFrame.h +++ b/layout/forms/nsHTMLButtonControlFrame.h @@ -7,10 +7,9 @@ #ifndef nsHTMLButtonControlFrame_h___ #define nsHTMLButtonControlFrame_h___ -#include "mozilla/Attributes.h" #include "nsContainerFrame.h" +#include "nsCSSRenderingBorders.h" #include "nsIFormControlFrame.h" -#include "nsButtonFrameRenderer.h" class gfxContext; class nsPresContext; @@ -83,6 +82,14 @@ class nsHTMLButtonControlFrame : public nsContainerFrame, // Return the ::-moz-button-content anonymous box. void AppendDirectlyOwnedAnonBoxes(nsTArray& aResult) override; + mozilla::Maybe CreateInnerFocusBorderRenderer( + nsDisplayListBuilder* aBuilder, gfxContext* aRenderingContext, + const nsRect& aDirtyRect, const nsRect& aRect, bool* aBorderIsEmpty); + + void PaintInnerFocusBorder(nsDisplayListBuilder* aBuilder, + gfxContext& aRenderingContext, + const nsRect& aDirtyRect, const nsRect& aRect); + protected: nsHTMLButtonControlFrame(ComputedStyle* aStyle, nsPresContext* aPresContext, nsIFrame::ClassID aID); @@ -90,7 +97,7 @@ class nsHTMLButtonControlFrame : public nsContainerFrame, // Indicates whether we should clip our children's painting to our // border-box (either because of "overflow" or because of legacy reasons // about how -flavored buttons work). - bool ShouldClipPaintingToBorderBox(); + bool ShouldClipPaintingToBorderBox() const; // Reflows the button's sole child frame, and computes the desired size // of the button itself from the results. @@ -104,7 +111,7 @@ class nsHTMLButtonControlFrame : public nsContainerFrame, mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup) const override; - nsButtonFrameRenderer mRenderer; + RefPtr mInnerFocusStyle; }; #endif diff --git a/layout/forms/nsNumberControlFrame.cpp b/layout/forms/nsNumberControlFrame.cpp index e8ed87c8f3..518ba91e24 100644 --- a/layout/forms/nsNumberControlFrame.cpp +++ b/layout/forms/nsNumberControlFrame.cpp @@ -64,22 +64,29 @@ nsresult nsNumberControlFrame::CreateAnonymousContent( nsTextControlFrame::CreateAnonymousContent(aElements); +#if defined(MOZ_WIDGET_ANDROID) + // We don't want spin buttons on Android + return NS_OK; +#else // The author has elected to hide the spinner by setting this // -moz-appearance. We will reframe if it changes. - if (StyleDisplay()->EffectiveAppearance() != StyleAppearance::Textfield) { - // Create the ::-moz-number-spin-box pseudo-element: - mSpinBox = MakeAnonElement(PseudoStyleType::mozNumberSpinBox); + if (StyleDisplay()->EffectiveAppearance() == StyleAppearance::Textfield) { + return NS_OK; + } - // Create the ::-moz-number-spin-up pseudo-element: - mSpinUp = MakeAnonElement(PseudoStyleType::mozNumberSpinUp, mSpinBox); + // Create the ::-moz-number-spin-box pseudo-element: + mSpinBox = MakeAnonElement(PseudoStyleType::mozNumberSpinBox); - // Create the ::-moz-number-spin-down pseudo-element: - mSpinDown = MakeAnonElement(PseudoStyleType::mozNumberSpinDown, mSpinBox); + // Create the ::-moz-number-spin-up pseudo-element: + mSpinUp = MakeAnonElement(PseudoStyleType::mozNumberSpinUp, mSpinBox); - aElements.AppendElement(mSpinBox); - } + // Create the ::-moz-number-spin-down pseudo-element: + mSpinDown = MakeAnonElement(PseudoStyleType::mozNumberSpinDown, mSpinBox); + + aElements.AppendElement(mSpinBox); return NS_OK; +#endif } /* static */ diff --git a/layout/forms/test/test_bug536567_perwindowpb.html b/layout/forms/test/test_bug536567_perwindowpb.html index 224b2c74a4..e27803157e 100644 --- a/layout/forms/test/test_bug536567_perwindowpb.html +++ b/layout/forms/test/test_bug536567_perwindowpb.html @@ -19,7 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=536567 const Cm = Components.manager; var MockFilePicker = SpecialPowers.MockFilePicker; -MockFilePicker.init(window); +MockFilePicker.init(SpecialPowers.wrap(window).browsingContext); var tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile); var homeDir = Services.dirsvc.get("Desk", Ci.nsIFile); diff --git a/layout/forms/test/test_bug935876.html b/layout/forms/test/test_bug935876.html index 4488fdf962..465fcac732 100644 --- a/layout/forms/test/test_bug935876.html +++ b/layout/forms/test/test_bug935876.html @@ -112,7 +112,7 @@ function runTests() var listbox = document.getElementById("listbox"); listbox.addEventListener("keydown", onKeydown); listbox.addEventListener("keypress", onKeypress); - SpecialPowers.addSystemEventListener(listbox, "keydown", onkeydownInSystemEventGroup, false); + SpecialPowers.wrap(listbox).addEventListener("keydown", onkeydownInSystemEventGroup, { mozSystemGroup: true }); listbox.focus(); @@ -185,14 +185,13 @@ function runTests() listbox.removeEventListener("keydown", onKeydown); listbox.removeEventListener("keypress", onKeypress); - SpecialPowers.removeSystemEventListener(listbox, "keydown", onkeydownInSystemEventGroup, false); - + SpecialPowers.wrap(listbox).removeEventListener("keydown", onkeydownInSystemEventGroup, { mozSystemGroup: true }); var multipleListbox = document.getElementById("multipleListbox"); multipleListbox.addEventListener("keydown", onKeydown); multipleListbox.addEventListener("keypress", onKeypress); - SpecialPowers.addSystemEventListener(multipleListbox, "keydown", onkeydownInSystemEventGroup, false); + SpecialPowers.wrap(multipleListbox).addEventListener("keydown", onkeydownInSystemEventGroup, { mozSystemGroup: true }); multipleListbox.focus(); @@ -265,14 +264,13 @@ function runTests() multipleListbox.removeEventListener("keydown", onKeydown); multipleListbox.removeEventListener("keypress", onKeypress); - SpecialPowers.removeSystemEventListener(multipleListbox, "keydown", onkeydownInSystemEventGroup, false); - + SpecialPowers.wrap(multipleListbox).removeEventListener("keydown", onkeydownInSystemEventGroup, { mozSystemGroup: true }); var combobox = document.getElementById("combobox"); combobox.addEventListener("keydown", onKeydown); combobox.addEventListener("keypress", onKeypress); - SpecialPowers.addSystemEventListener(combobox, "keydown", onkeydownInSystemEventGroup, false); + SpecialPowers.wrap(combobox).addEventListener("keydown", onkeydownInSystemEventGroup, { mozSystemGroup: true }); combobox.focus(); @@ -353,7 +351,7 @@ function runTests() { combobox.removeEventListener("keydown", onKeydown); combobox.removeEventListener("keypress", onKeypress); - SpecialPowers.removeSystemEventListener(combobox, "keydown", onkeydownInSystemEventGroup, false); + SpecialPowers.wrap(combobox).removeEventListener("keydown", onkeydownInSystemEventGroup, { mozSystemGroup: true }); SimpleTest.finish(); } diff --git a/layout/generic/BlockReflowState.cpp b/layout/generic/BlockReflowState.cpp index 6163a200a3..78dab82e98 100644 --- a/layout/generic/BlockReflowState.cpp +++ b/layout/generic/BlockReflowState.cpp @@ -47,7 +47,8 @@ BlockReflowState::BlockReflowState( mMinLineHeight(aReflowInput.GetLineHeight()), mLineNumber(0), mTrailingClearFromPIF(StyleClear::None), - mConsumedBSize(aConsumedBSize) { + mConsumedBSize(aConsumedBSize), + mAlignContentShift(mBlock->GetAlignContentShift()) { NS_ASSERTION(mConsumedBSize != NS_UNCONSTRAINEDSIZE, "The consumed block-size should be constrained!"); @@ -87,8 +88,8 @@ BlockReflowState::BlockReflowState( // the "overflow" property. When we don't have a specified style block-size, // then we may end up limiting our block-size if the available block-size is // constrained (this situation occurs when we are paginated). - if (const nscoord availableBSize = aReflowInput.AvailableBSize(); - availableBSize != NS_UNCONSTRAINEDSIZE) { + const nscoord availableBSize = aReflowInput.AvailableBSize(); + if (availableBSize != NS_UNCONSTRAINEDSIZE) { // We are in a paginated situation. The block-end edge of the available // space to reflow the children is within our block-end border and padding. // If we're cloning our border and padding, and we're going to request @@ -112,10 +113,34 @@ BlockReflowState::BlockReflowState( mContentArea.IStart(wm) = mBorderPadding.IStart(wm); mBCoord = mContentArea.BStart(wm) = mBorderPadding.BStart(wm); + // Account for existing cached shift, we'll re-position in AlignContent() if + // needed. + if (mAlignContentShift) { + mBCoord += mAlignContentShift; + mContentArea.BStart(wm) += mAlignContentShift; + + if (availableBSize != NS_UNCONSTRAINEDSIZE) { + mContentArea.BSize(wm) += mAlignContentShift; + } + } + mPrevChild = nullptr; mCurrentLine = aFrame->LinesEnd(); } +void BlockReflowState::UndoAlignContentShift() { + if (!mAlignContentShift) { + return; + } + + mBCoord -= mAlignContentShift; + mContentArea.BStart(mReflowInput.GetWritingMode()) -= mAlignContentShift; + + if (mReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE) { + mContentArea.BSize(mReflowInput.GetWritingMode()) -= mAlignContentShift; + } +} + void BlockReflowState::ComputeFloatAvoidingOffsets( nsIFrame* aFloatAvoidingBlock, const LogicalRect& aFloatAvailableSpace, nscoord& aIStartResult, nscoord& aIEndResult) const { diff --git a/layout/generic/BlockReflowState.h b/layout/generic/BlockReflowState.h index 1dfaa4d9ad..6f05b6ab0a 100644 --- a/layout/generic/BlockReflowState.h +++ b/layout/generic/BlockReflowState.h @@ -41,16 +41,16 @@ class BlockReflowState { mCanHaveOverflowMarkers(false) {} // Set in the BlockReflowState constructor when reflowing a "block margin - // root" frame (i.e. a frame with any of the NS_BLOCK_BFC_STATE_BITS flag - // set, for which margins apply by default). + // root" frame (i.e. a frame with any of the NS_BLOCK_BFC flag set, for + // which margins apply by default). // // The flag is also set when reflowing a frame whose computed BStart border // padding is non-zero. bool mIsBStartMarginRoot : 1; // Set in the BlockReflowState constructor when reflowing a "block margin - // root" frame (i.e. a frame with any of the NS_BLOCK_BFC_STATE_BITS flag - // set, for which margins apply by default). + // root" frame (i.e. a frame with any of the NS_BLOCK_BFC flag set, for + // which margins apply by default). // // The flag is also set when reflowing a frame whose computed BEnd border // padding is non-zero. @@ -101,6 +101,13 @@ class BlockReflowState { const nscoord aEffectiveContentBoxBSize, const nscoord aInset = 0); + /** + * Unshifts coords, restores availableBSize to reality. + * (Constructor applies any cached shift before reflow + * so that frames are reflowed with cached shift) + */ + void UndoAlignContentShift(); + /** * Get the available reflow space (the area not occupied by floats) * for the current y coordinate. The available space is relative to @@ -407,6 +414,11 @@ class BlockReflowState { // continuations. const nscoord mConsumedBSize; + // The amount of block-axis alignment shift to assume during reflow. + // Cached between reflows in the AlignContentShift property. + // (This system optimizes reflow for not changing the shift.) + nscoord mAlignContentShift; + // Cache the current line's BSize if nsBlockFrame::PlaceLine() fails to // place the line. When redoing the line, it will be used to query the // accurate float available space in AddFloat() and diff --git a/layout/generic/FrameClasses.py b/layout/generic/FrameClasses.py index d1d0a0b13b..36c1af10d1 100644 --- a/layout/generic/FrameClasses.py +++ b/layout/generic/FrameClasses.py @@ -14,6 +14,7 @@ COMMON = { LEAF = {"Leaf"} MATHML = {"MathML"} SVG = {"SVG"} +BFC = {"BlockFormattingContext"} BLOCK = COMMON | {"CanContainOverflowContainers"} @@ -54,18 +55,13 @@ FRAME_CLASSES = [ Frame("nsCheckboxRadioFrame", "CheckboxRadio", REPLACED_WITH_BLOCK | LEAF), Frame("nsColorControlFrame", "ColorControl", REPLACED_WITH_BLOCK | LEAF), Frame("nsColumnSetFrame", "ColumnSet", COMMON), - Frame("ColumnSetWrapperFrame", "ColumnSetWrapper", BLOCK), - Frame("nsComboboxControlFrame", "ComboboxControl", BLOCK | REPLACED_WITH_BLOCK), - # FIXME(emilio, bug 1362907): Revisit these after that bug, this is the - # only frame that has ReplacedContainsBlock but not Replaced, which is - # sketchy. - Frame( - "nsComboboxDisplayFrame", "ComboboxDisplay", REPLACED_WITH_BLOCK - {"Replaced"} - ), + Frame("ColumnSetWrapperFrame", "ColumnSetWrapper", BLOCK | BFC), + Frame("nsComboboxControlFrame", "ComboboxControl", REPLACED_WITH_BLOCK | LEAF), + Frame("ComboboxLabelFrame", "Block", BLOCK), Frame("nsContinuingTextFrame", "Text", TEXT), Frame("nsDateTimeControlFrame", "DateTimeControl", REPLACED_WITH_BLOCK), Frame("nsFieldSetFrame", "FieldSet", BLOCK), - Frame("nsFileControlFrame", "Block", REPLACED_WITH_BLOCK | LEAF), + Frame("nsFileControlFrame", "Block", REPLACED_WITH_BLOCK | LEAF | BFC), Frame("FileControlLabelFrame", "Block", BLOCK | LEAF), Frame("nsFirstLetterFrame", "Letter", INLINE), Frame("nsFloatingFirstLetterFrame", "Letter", INLINE - {"LineParticipant"}), @@ -84,7 +80,7 @@ FRAME_CLASSES = [ Frame("nsImageFrame", "Image", REPLACED_SIZING | {"LeafDynamic"}), Frame("nsInlineFrame", "Inline", INLINE), Frame("nsListControlFrame", "ListControl", REPLACED_WITH_BLOCK), - Frame("nsMathMLmathBlockFrame", "Block", BLOCK | MATHML), + Frame("nsMathMLmathBlockFrame", "Block", BLOCK | MATHML | BFC), Frame("nsMathMLmathInlineFrame", "Inline", INLINE | MATHML), Frame("nsMathMLmencloseFrame", "None", MATHML_CONTAINER), Frame("nsMathMLmfracFrame", "None", MATHML_CONTAINER), @@ -120,7 +116,7 @@ FRAME_CLASSES = [ Frame("nsScrollbarButtonFrame", "SimpleXULLeaf", COMMON | LEAF), Frame("nsScrollbarFrame", "Scrollbar", COMMON), Frame("nsSearchControlFrame", "SearchControl", LEAF), - Frame("nsSelectsAreaFrame", "Block", BLOCK), + Frame("nsSelectsAreaFrame", "Block", BLOCK | BFC), Frame("nsPageSequenceFrame", "PageSequence", COMMON), Frame("nsSliderFrame", "Slider", COMMON), Frame("nsSplitterFrame", "SimpleXULLeaf", COMMON | LEAF), diff --git a/layout/generic/ScrollAnchorContainer.cpp b/layout/generic/ScrollAnchorContainer.cpp index 5e1d8aa56d..93336480f7 100644 --- a/layout/generic/ScrollAnchorContainer.cpp +++ b/layout/generic/ScrollAnchorContainer.cpp @@ -539,11 +539,8 @@ void ScrollAnchorContainer::ApplyAdjustments() { MOZ_RELEASE_ASSERT(!mApplyingAnchorAdjustment); // We should use AutoRestore here, but that doesn't work with bitfields mApplyingAnchorAdjustment = true; - Frame()->ScrollToInternal( - Frame()->GetScrollPosition() + physicalAdjustment, ScrollMode::Instant, - StaticPrefs::layout_css_scroll_anchoring_absolute_update() - ? ScrollOrigin::AnchorAdjustment - : ScrollOrigin::Relative); + Frame()->ScrollToInternal(Frame()->GetScrollPosition() + physicalAdjustment, + ScrollMode::Instant, ScrollOrigin::Relative); mApplyingAnchorAdjustment = false; if (Frame()->mIsRoot) { diff --git a/layout/generic/ScrollAnimationMSDPhysics.cpp b/layout/generic/ScrollAnimationMSDPhysics.cpp index de67f9c59a..8f0ae32d3b 100644 --- a/layout/generic/ScrollAnimationMSDPhysics.cpp +++ b/layout/generic/ScrollAnimationMSDPhysics.cpp @@ -5,7 +5,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ScrollAnimationMSDPhysics.h" +#include "mozilla/Logging.h" #include "mozilla/StaticPrefs_general.h" +#include "mozilla/ToString.h" + +static mozilla::LazyLogModule sApzMsdLog("apz.msd"); +#define MSD_LOG(...) MOZ_LOG(sApzMsdLog, LogLevel::Debug, (__VA_ARGS__)) using namespace mozilla; @@ -108,13 +113,17 @@ double ScrollAnimationMSDPhysics::ComputeSpringConstant( } void ScrollAnimationMSDPhysics::SimulateUntil(const TimeStamp& aTime) { - if (!mLastSimulatedTime || aTime < mLastSimulatedTime) { + if (!mLastSimulatedTime || aTime <= mLastSimulatedTime) { return; } TimeDuration delta = aTime - mLastSimulatedTime; mModelX.Simulate(delta); mModelY.Simulate(delta); mLastSimulatedTime = aTime; + MSD_LOG("Simulated for duration %f, finished %d position %s velocity %s\n", + delta.ToMilliseconds(), IsFinished(aTime), + ToString(CSSPoint::FromAppUnits(PositionAt(aTime))).c_str(), + ToString(CSSPoint::FromAppUnits(VelocityAt(aTime))).c_str()); } nsPoint ScrollAnimationMSDPhysics::PositionAt(const TimeStamp& aTime) { @@ -152,6 +161,9 @@ ScrollAnimationMSDPhysics::NonOscillatingAxisPhysicsMSDModel:: ClampVelocityToMaximum(aInitialVelocity, aInitialPosition, aInitialDestination, aSpringConstant), aSpringConstant, aDampingRatio) { + MSD_LOG("Constructing axis physics model with parameters %f %f %f %f %f\n", + aInitialPosition, aInitialDestination, aInitialVelocity, + aSpringConstant, aDampingRatio); MOZ_ASSERT(aDampingRatio >= 1.0, "Damping ratio must be >= 1.0 to avoid oscillation"); } diff --git a/layout/generic/ScrollOrigin.h b/layout/generic/ScrollOrigin.h index f1ad0e3367..edffa2d4f6 100644 --- a/layout/generic/ScrollOrigin.h +++ b/layout/generic/ScrollOrigin.h @@ -33,8 +33,6 @@ enum class ScrollOrigin : uint8_t { // The scroll came from an attempt by the main thread to re-clamp the scroll // position after a reflow. Clamp, - // The scroll came from a scroll adjustment triggered by scroll anchoring. - AnchorAdjustment, // The following scroll origins also are associated with prefs of the form // general.smoothScroll.(.*) diff --git a/layout/generic/ScrollPositionUpdate.cpp b/layout/generic/ScrollPositionUpdate.cpp index 9607d2d18a..a680768525 100644 --- a/layout/generic/ScrollPositionUpdate.cpp +++ b/layout/generic/ScrollPositionUpdate.cpp @@ -93,20 +93,6 @@ ScrollPositionUpdate ScrollPositionUpdate::NewPureRelativeScroll( return ret; } -/*static*/ -ScrollPositionUpdate ScrollPositionUpdate::NewMergeableScroll( - ScrollOrigin aOrigin, nsPoint aDestination) { - MOZ_ASSERT(aOrigin == ScrollOrigin::AnchorAdjustment); - - ScrollPositionUpdate ret; - ret.mScrollGeneration = sGenerationCounter.NewMainThreadGeneration(); - ret.mType = ScrollUpdateType::MergeableAbsolute; - ret.mScrollMode = ScrollMode::Instant; - ret.mScrollOrigin = aOrigin; - ret.mDestination = CSSPoint::FromAppUnits(aDestination); - return ret; -} - bool ScrollPositionUpdate::operator==( const ScrollPositionUpdate& aOther) const { // instances are immutable, and all the fields are set when the generation @@ -126,7 +112,6 @@ ScrollOrigin ScrollPositionUpdate::GetOrigin() const { return mScrollOrigin; } CSSPoint ScrollPositionUpdate::GetDestination() const { MOZ_ASSERT(mType == ScrollUpdateType::Absolute || - mType == ScrollUpdateType::MergeableAbsolute || mType == ScrollUpdateType::Relative); return mDestination; } diff --git a/layout/generic/ScrollPositionUpdate.h b/layout/generic/ScrollPositionUpdate.h index 0e8dc020c1..ca22da8af0 100644 --- a/layout/generic/ScrollPositionUpdate.h +++ b/layout/generic/ScrollPositionUpdate.h @@ -34,9 +34,6 @@ enum class ScrollUpdateType { // The delta should be applied to whatever the current scroll position is // on the receiver side. PureRelative, - // Similar to |Absolute|, but even if there's an active async scroll animation - // the position update will NOT cancel the async scroll animation. - MergeableAbsolute, }; enum class ScrollTriggeredByScript : bool { No, Yes }; @@ -86,9 +83,6 @@ class ScrollPositionUpdate { ScrollMode aMode, const nsPoint& aDelta); - static ScrollPositionUpdate NewMergeableScroll(ScrollOrigin aOrigin, - nsPoint aDestination); - bool operator==(const ScrollPositionUpdate& aOther) const; MainThreadScrollGeneration GetGeneration() const; diff --git a/layout/generic/StickyScrollContainer.cpp b/layout/generic/StickyScrollContainer.cpp index 2e9d32ab5f..416bbbf4c4 100644 --- a/layout/generic/StickyScrollContainer.cpp +++ b/layout/generic/StickyScrollContainer.cpp @@ -186,12 +186,17 @@ void StickyScrollContainer::ComputeStickyLimits(nsIFrame* aFrame, // Containing block limits for the position of aFrame relative to its parent. // The margin box of the sticky element stays within the content box of the - // contaning-block element. + // containing-block element. if (cbFrame == scrolledFrame) { // cbFrame is the scrolledFrame, and it won't have continuations. Unlike the - // else clause, we consider scrollable overflow rect because and the union - // of its in-flow rects doesn't include the scrollable overflow area. + // else clause, we consider scrollable overflow rect because the union of + // its in-flow rects doesn't include the scrollable overflow area. We need + // to subtract the padding however, which _is_ included in the scrollable + // area, since we want the content box. + MOZ_ASSERT(cbFrame->GetUsedBorder() == nsMargin(), + "How did the ::-moz-scrolled-frame end up with border?"); *aContain = cbFrame->ScrollableOverflowRectRelativeToSelf(); + aContain->Deflate(cbFrame->GetUsedPadding()); nsLayoutUtils::TransformRect(cbFrame, aFrame->GetParent(), *aContain); } else { *aContain = nsLayoutUtils::GetAllInFlowRectsUnion( diff --git a/layout/generic/TextOverflow.cpp b/layout/generic/TextOverflow.cpp index f529a2268d..758b61a99b 100644 --- a/layout/generic/TextOverflow.cpp +++ b/layout/generic/TextOverflow.cpp @@ -29,8 +29,7 @@ using mozilla::layout::TextDrawTarget; -namespace mozilla { -namespace css { +namespace mozilla::css { class LazyReferenceRenderingDrawTargetGetterFromFrame final : public gfxFontGroup::LazyReferenceDrawTargetGetter { @@ -165,8 +164,7 @@ class nsDisplayTextOverflowMarker final : public nsPaintedDisplayItem { virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override { *aSnap = false; - nsRect shadowRect = nsLayoutUtils::GetTextShadowRectsUnion(mRect, mFrame); - return mRect.Union(shadowRect); + return nsLayoutUtils::GetTextShadowRectsUnion(mRect, mFrame); } virtual nsRect GetComponentAlphaBounds( @@ -835,9 +833,10 @@ bool TextOverflow::CanHaveOverflowMarkers(nsBlockFrame* aBlockFrame, return false; } - // Skip ComboboxControlFrame because it would clip the drop-down arrow. - // Its anon block inherits 'text-overflow' and does what is expected. - if (aBlockFrame->IsComboboxControlFrame()) { + // Skip the combobox anonymous block because it would clip the drop-down + // arrow. The inner label inherits 'text-overflow' and does the right thing. + if (aBlockFrame->GetParent() && + aBlockFrame->GetParent()->IsComboboxControlFrame()) { return false; } @@ -932,5 +931,4 @@ void TextOverflow::Marker::SetupString(nsIFrame* aFrame) { mInitialized = true; } -} // namespace css -} // namespace mozilla +} // namespace mozilla::css diff --git a/layout/generic/ViewportFrame.cpp b/layout/generic/ViewportFrame.cpp index 1837441e86..812aaa8e33 100644 --- a/layout/generic/ViewportFrame.cpp +++ b/layout/generic/ViewportFrame.cpp @@ -21,7 +21,6 @@ #include "nsCanvasFrame.h" #include "nsLayoutUtils.h" #include "nsSubDocumentFrame.h" -#include "nsIMozBrowserFrame.h" #include "nsPlaceholderFrame.h" #include "MobileViewportManager.h" diff --git a/layout/generic/WritingModes.h b/layout/generic/WritingModes.h index 2f28b73775..e84c5e276d 100644 --- a/layout/generic/WritingModes.h +++ b/layout/generic/WritingModes.h @@ -62,11 +62,11 @@ constexpr auto AllLogicalSides() { eLogicalSideIEnd); } -enum LogicalCorner { - eLogicalCornerBStartIStart = 0, - eLogicalCornerBStartIEnd = 1, - eLogicalCornerBEndIEnd = 2, - eLogicalCornerBEndIStart = 3 +enum class LogicalCorner : uint8_t { + BStartIStart, + BStartIEnd, + BEndIEnd, + BEndIStart, }; // Physical axis constants. diff --git a/layout/generic/crashtests/1140268-1.html b/layout/generic/crashtests/1140268-1.html deleted file mode 100644 index 5e5510ba7f..0000000000 --- a/layout/generic/crashtests/1140268-1.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - -boom! - - diff --git a/layout/generic/crashtests/364686-1.xhtml b/layout/generic/crashtests/364686-1.xhtml deleted file mode 100644 index 93a1eeaa4b..0000000000 --- a/layout/generic/crashtests/364686-1.xhtml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/layout/generic/crashtests/368461-1.xhtml b/layout/generic/crashtests/368461-1.xhtml deleted file mode 100644 index d5baccf523..0000000000 --- a/layout/generic/crashtests/368461-1.xhtml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - -

Foo bar baz

- - - diff --git a/layout/generic/crashtests/370884-1.xhtml b/layout/generic/crashtests/370884-1.xhtml deleted file mode 100644 index 3959d4b178..0000000000 --- a/layout/generic/crashtests/370884-1.xhtml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - -
-
Y
-
-
- - - diff --git a/layout/generic/crashtests/382208-1.xhtml b/layout/generic/crashtests/382208-1.xhtml deleted file mode 100644 index 5264b8845d..0000000000 --- a/layout/generic/crashtests/382208-1.xhtml +++ /dev/null @@ -1,7 +0,0 @@ - - - -
- - - diff --git a/layout/generic/crashtests/382396-1.xhtml b/layout/generic/crashtests/382396-1.xhtml deleted file mode 100644 index f334bbfdf5..0000000000 --- a/layout/generic/crashtests/382396-1.xhtml +++ /dev/null @@ -1,7 +0,0 @@ - - - -

a

- - - diff --git a/layout/generic/crashtests/385265-1.xhtml b/layout/generic/crashtests/385265-1.xhtml deleted file mode 100644 index 7994653ffa..0000000000 --- a/layout/generic/crashtests/385265-1.xhtml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - x - - - - - - \ No newline at end of file diff --git a/layout/generic/crashtests/395450-1.xhtml b/layout/generic/crashtests/395450-1.xhtml deleted file mode 100644 index 79510267ba..0000000000 --- a/layout/generic/crashtests/395450-1.xhtml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/layout/generic/crashtests/467914-1.html b/layout/generic/crashtests/467914-1.html deleted file mode 100644 index 4f518f09df..0000000000 --- a/layout/generic/crashtests/467914-1.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/layout/generic/crashtests/547843-1.xhtml b/layout/generic/crashtests/547843-1.xhtml deleted file mode 100644 index 0ad086d90c..0000000000 --- a/layout/generic/crashtests/547843-1.xhtml +++ /dev/null @@ -1 +0,0 @@ -
diff --git a/layout/generic/crashtests/700031.xhtml b/layout/generic/crashtests/700031.xhtml deleted file mode 100644 index 70f924279e..0000000000 --- a/layout/generic/crashtests/700031.xhtml +++ /dev/null @@ -1,9 +0,0 @@ - - -
- -abcdef - -
- - diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list index 51589c9aba..1c184739d7 100644 --- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -63,14 +63,12 @@ load 363722-1.html load 363722-2.html load 364220.html load 364407-1.html -load 364686-1.xhtml load 366021-1.xhtml load 366667-1.html load 366952-1.html load 367246-1.html load 367360.html load 368330-1.html -load 368461-1.xhtml load 368568.html load 368752.html load 368860-1.html @@ -86,7 +84,6 @@ load 370174-2.html load 370174-3.html load 370699-1.html load 370794-1.html -load 370884-1.xhtml load 371348-1.xhtml load 371561-1.html load 371566-1.xhtml @@ -105,11 +102,8 @@ load 381152-1.html load 382129-1.xhtml load 382131-1.html load 382199-1.html -load 382208-1.xhtml load 382262-1.html -load 382396-1.xhtml load 383089-1.html -load 385265-1.xhtml load 385295-1.xhtml load 385344-1.html load 385344-2.html @@ -158,7 +152,6 @@ load 394818-1.html load 394818-2.html load 394820-1.html load 395316-1.html -load 395450-1.xhtml load 397007-1.html load 397187-1.html load 397844-1.xhtml @@ -316,7 +309,6 @@ load 467487-1.html load 467493-1.html load 467493-2.html load 467875-1.xhtml -load 467914-1.html asserts-if(winWidget,0-2) load 468207-1.html # bug 1647811 load 468771-1.xhtml load 468771-2.xhtml @@ -391,7 +383,6 @@ load 541714-1.html load 541714-2.html load 542136-1.html load 545571-1.html -load 547843-1.xhtml load 551635-1.html load 553504-1.xhtml load 564368-1.xhtml @@ -457,7 +448,6 @@ load 683712.html load 688996-1.html load 688996-2.html load 691210.html -load 700031.xhtml load 709398-1.html load 718516.html load 723108.html @@ -553,7 +543,7 @@ load 942794-1.html load 943509-1.html asserts(2-3) load 944909-1.html # bogus sizes load 946167-1.html -skip-if(Android&&browserIsRemote) load 947158.html # bug 1507207 +skip-if(Android) load 947158.html # bug 1507207 load 949932.html load 963878.html load 964078.html @@ -587,7 +577,6 @@ load 1137723-2.html asserts(1) load 1140043-1.html asserts(1) load 1140043-2.html asserts(1) load 1140043-3.html -load 1140268-1.html load 1145768.html load 1145931.html load 1145950-1.html @@ -631,7 +620,7 @@ load first-letter-638937-1.html load first-letter-638937-2.html load flex-nested-abspos-1.html pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLine,15) asserts(0-100) load font-inflation-762332.html # bug 762332 -asserts-if(Android||OSX,0-2) load outline-on-frameset.xhtml # bug 762332, bug 1594135 +asserts-if(Android||cocoaWidget,0-2) load outline-on-frameset.xhtml # bug 762332, bug 1594135 load summary-position-out-of-flow.html pref(widget.windows.window_occlusion_tracking.enabled,false) load text-overflow-bug666751-1.html # Bug 1819154 pref(widget.windows.window_occlusion_tracking.enabled,false) load text-overflow-bug666751-2.html # Bug 1819154 @@ -672,7 +661,7 @@ load 1343552-2.html load 1346454-1.html load 1346454-2.html load 1349650.html -asserts-if(browserIsRemote,0-5) load 1349816-1.html # bug 1350352 +asserts(0-5) load 1349816-1.html # bug 1350352 load 1350372.html load 1364361-1.html load 1367413-1.html diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 54976ecc47..a25e4e996e 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -41,7 +41,6 @@ #include "nsPresContextInlines.h" #include "nsHTMLParts.h" #include "nsGkAtoms.h" -#include "nsAttrValueInlines.h" #include "mozilla/Sprintf.h" #include "nsFloatManager.h" #include "prenv.h" @@ -50,22 +49,15 @@ #include #include "nsLayoutUtils.h" #include "nsDisplayList.h" -#include "nsCSSAnonBoxes.h" #include "nsCSSFrameConstructor.h" #include "TextOverflow.h" #include "nsIFrameInlines.h" #include "CounterStyleManager.h" -#include "mozilla/dom/HTMLDetailsElement.h" -#include "mozilla/dom/HTMLSummaryElement.h" #include "mozilla/dom/Selection.h" #include "mozilla/PresShell.h" #include "mozilla/RestyleManager.h" #include "mozilla/ServoStyleSet.h" -#include "mozilla/Telemetry.h" #include "nsFlexContainerFrame.h" -#include "nsFileControlFrame.h" -#include "nsMathMLContainerFrame.h" -#include "nsSelectsAreaFrame.h" #include "nsBidiPresUtils.h" @@ -95,7 +87,7 @@ static void MarkAllDescendantLinesDirty(nsBlockFrame* aBlock) { static void MarkSameFloatManagerLinesDirty(nsBlockFrame* aBlock) { nsBlockFrame* blockWithFloatMgr = aBlock; - while (!blockWithFloatMgr->HasAnyStateBits(NS_BLOCK_BFC_STATE_BITS)) { + while (!blockWithFloatMgr->HasAnyStateBits(NS_BLOCK_BFC)) { nsBlockFrame* bf = do_QueryFrame(blockWithFloatMgr->GetParent()); if (!bf) { break; @@ -130,47 +122,37 @@ static bool BlockHasAnyFloats(nsIFrame* aFrame) { return false; } -/** - * Determines whether the given frame is visible or has - * visible children that participate in the same line. Frames - * that are not line participants do not have their - * children checked. - */ -static bool FrameHasVisibleInlineContent(nsIFrame* aFrame) { +// Determines whether the given frame is visible text or has visible text that +// participate in the same line. Frames that are not line participants do not +// have their children checked. +static bool FrameHasVisibleInlineText(nsIFrame* aFrame) { MOZ_ASSERT(aFrame, "Frame argument cannot be null"); - - if (aFrame->StyleVisibility()->IsVisible()) { - return true; + if (!aFrame->IsLineParticipant()) { + return false; } - - if (aFrame->IsLineParticipant()) { - for (nsIFrame* kid : aFrame->PrincipalChildList()) { - if (kid->StyleVisibility()->IsVisible() || - FrameHasVisibleInlineContent(kid)) { - return true; - } + if (aFrame->IsTextFrame()) { + return aFrame->StyleVisibility()->IsVisible() && + NS_GET_A(aFrame->StyleText()->mWebkitTextFillColor.CalcColor( + aFrame)) != 0; + } + for (nsIFrame* kid : aFrame->PrincipalChildList()) { + if (FrameHasVisibleInlineText(kid)) { + return true; } } return false; } -/** - * Determines whether any of the frames descended from the - * given line have inline content with 'visibility: visible'. - * This function calls FrameHasVisibleInlineContent to process - * each frame in the line's child list. - */ -static bool LineHasVisibleInlineContent(nsLineBox* aLine) { +// Determines whether any of the frames from the given line have visible text. +static bool LineHasVisibleInlineText(nsLineBox* aLine) { nsIFrame* kid = aLine->mFirstChild; int32_t n = aLine->GetChildCount(); while (n-- > 0) { - if (FrameHasVisibleInlineContent(kid)) { + if (FrameHasVisibleInlineText(kid)) { return true; } - kid = kid->GetNextSibling(); } - return false; } @@ -446,13 +428,6 @@ nsBlockFrame* NS_NewBlockFrame(PresShell* aPresShell, ComputedStyle* aStyle) { return new (aPresShell) nsBlockFrame(aStyle, aPresShell->GetPresContext()); } -nsBlockFrame* NS_NewBlockFormattingContext(PresShell* aPresShell, - ComputedStyle* aComputedStyle) { - nsBlockFrame* blockFrame = NS_NewBlockFrame(aPresShell, aComputedStyle); - blockFrame->AddStateBits(NS_BLOCK_STATIC_BFC); - return blockFrame; -} - NS_IMPL_FRAMEARENA_HELPERS(nsBlockFrame) nsBlockFrame::~nsBlockFrame() = default; @@ -1194,7 +1169,7 @@ static LogicalSize CalculateContainingBlockSizeForAbsolutes( */ static const nsBlockFrame* GetAsLineClampDescendant(const nsIFrame* aFrame) { if (const nsBlockFrame* block = do_QueryFrame(aFrame)) { - if (!block->HasAnyStateBits(NS_BLOCK_BFC_STATE_BITS)) { + if (!block->HasAnyStateBits(NS_BLOCK_BFC)) { return block; } } @@ -1211,7 +1186,7 @@ static bool IsLineClampRoot(const nsBlockFrame* aFrame) { return false; } - if (!aFrame->HasAnyStateBits(NS_BLOCK_BFC_STATE_BITS)) { + if (!aFrame->HasAnyStateBits(NS_BLOCK_BFC)) { return false; } @@ -2023,6 +1998,9 @@ nsReflowStatus nsBlockFrame::TrialReflow(nsPresContext* aPresContext, ComputeFinalSize(aReflowInput, state, aMetrics); aTrialState.mContainerWidth = state.ContainerSize().width; + // Align content + AlignContent(state, aMetrics, aTrialState.mBlockEndEdgeOfChildren); + return state.mReflowStatus; } @@ -2191,6 +2169,11 @@ nscoord nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, aState.ClearFloats(blockEndEdgeOfChildren, StyleClear::Both); } + // undo cached alignment shift for sizing purposes + // (we used shifted positions because the float manager uses them) + blockEndEdgeOfChildren -= aState.mAlignContentShift; + aState.UndoAlignContentShift(); + if (NS_UNCONSTRAINEDSIZE != aReflowInput.ComputedBSize()) { // Note: We don't use blockEndEdgeOfChildren because it includes the // previous margin. @@ -2221,97 +2204,83 @@ nscoord nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, // calculated from aspect-ratio. i.e. Don't carry out block margin-end if it // is replaced by the block size from aspect-ratio and inline size. aMetrics.mCarriedOutBEndMargin.Zero(); - } else { - Maybe containBSize = ContainIntrinsicBSize( - IsComboboxControlFrame() ? NS_UNCONSTRAINEDSIZE : 0); - if (containBSize && *containBSize != NS_UNCONSTRAINEDSIZE) { - // If we're size-containing in block axis and we don't have a specified - // block size, then our final size should actually be computed from only - // our border, padding and contain-intrinsic-block-size, ignoring the - // actual contents. Hence this case is a simplified version of the case - // below. - // - // NOTE: We exempt the nsComboboxControlFrame subclass from taking this - // special case when it has 'contain-intrinsic-block-size: none', because - // comboboxes implicitly honors the size-containment behavior on its - // nsComboboxDisplayFrame child (which it shrinkwraps) rather than on the - // nsComboboxControlFrame. (Moreover, the DisplayFrame child doesn't even - // need any special content-size-ignoring behavior in its reflow method, - // because that method just resolves "auto" BSize values to one - // line-height rather than by measuring its contents' BSize.) - nscoord contentBSize = *containBSize; - nscoord autoBSize = - aReflowInput.ApplyMinMaxBSize(contentBSize, aState.mConsumedBSize); + } else if (Maybe containBSize = ContainIntrinsicBSize()) { + // If we're size-containing in block axis and we don't have a specified + // block size, then our final size should actually be computed from only + // our border, padding and contain-intrinsic-block-size, ignoring the + // actual contents. Hence this case is a simplified version of the case + // below. + nscoord contentBSize = *containBSize; + nscoord autoBSize = + aReflowInput.ApplyMinMaxBSize(contentBSize, aState.mConsumedBSize); + aMetrics.mCarriedOutBEndMargin.Zero(); + autoBSize += borderPadding.BStartEnd(wm); + finalSize.BSize(wm) = autoBSize; + } else if (aState.mReflowStatus.IsInlineBreakBefore()) { + // Our parent is expected to push this frame to the next page/column so + // what size we set here doesn't really matter. + finalSize.BSize(wm) = aReflowInput.AvailableBSize(); + } else if (aState.mReflowStatus.IsComplete()) { + const nscoord lineClampedContentBlockEndEdge = + ApplyLineClamp(aReflowInput, this, blockEndEdgeOfChildren); + + const nscoord bpBStart = borderPadding.BStart(wm); + const nscoord contentBSize = blockEndEdgeOfChildren - bpBStart; + const nscoord lineClampedContentBSize = + lineClampedContentBlockEndEdge - bpBStart; + + const nscoord autoBSize = aReflowInput.ApplyMinMaxBSize( + lineClampedContentBSize, aState.mConsumedBSize); + if (autoBSize != contentBSize) { + // Our min-block-size, max-block-size, or -webkit-line-clamp value made + // our bsize change. Don't carry out our kids' block-end margins. aMetrics.mCarriedOutBEndMargin.Zero(); - autoBSize += borderPadding.BStartEnd(wm); - finalSize.BSize(wm) = autoBSize; - } else if (aState.mReflowStatus.IsInlineBreakBefore()) { - // Our parent is expected to push this frame to the next page/column so - // what size we set here doesn't really matter. - finalSize.BSize(wm) = aReflowInput.AvailableBSize(); - } else if (aState.mReflowStatus.IsComplete()) { - const nscoord lineClampedContentBlockEndEdge = - ApplyLineClamp(aReflowInput, this, blockEndEdgeOfChildren); - - const nscoord bpBStart = borderPadding.BStart(wm); - const nscoord contentBSize = blockEndEdgeOfChildren - bpBStart; - const nscoord lineClampedContentBSize = - lineClampedContentBlockEndEdge - bpBStart; - - const nscoord autoBSize = aReflowInput.ApplyMinMaxBSize( - lineClampedContentBSize, aState.mConsumedBSize); - if (autoBSize != contentBSize) { - // Our min-block-size, max-block-size, or -webkit-line-clamp value made - // our bsize change. Don't carry out our kids' block-end margins. - aMetrics.mCarriedOutBEndMargin.Zero(); - } - nscoord bSize = autoBSize + borderPadding.BStartEnd(wm); - if (MOZ_UNLIKELY(autoBSize > contentBSize && - bSize > aReflowInput.AvailableBSize() && - aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE)) { - // Applying `min-size` made us overflow our available size. - // Clamp it and report that we're Incomplete, or BreakBefore if we have - // 'break-inside: avoid' that is applicable. - bSize = aReflowInput.AvailableBSize(); - if (ShouldAvoidBreakInside(aReflowInput)) { - aState.mReflowStatus.SetInlineLineBreakBeforeAndReset(); - } else { - aState.mReflowStatus.SetIncomplete(); - } + } + nscoord bSize = autoBSize + borderPadding.BStartEnd(wm); + if (MOZ_UNLIKELY(autoBSize > contentBSize && + bSize > aReflowInput.AvailableBSize() && + aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE)) { + // Applying `min-size` made us overflow our available size. + // Clamp it and report that we're Incomplete, or BreakBefore if we have + // 'break-inside: avoid' that is applicable. + bSize = aReflowInput.AvailableBSize(); + if (ShouldAvoidBreakInside(aReflowInput)) { + aState.mReflowStatus.SetInlineLineBreakBeforeAndReset(); + } else { + aState.mReflowStatus.SetIncomplete(); } - finalSize.BSize(wm) = bSize; - } else { - NS_ASSERTION( - aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE, - "Shouldn't be incomplete if availableBSize is UNCONSTRAINED."); - nscoord bSize = std::max(aState.mBCoord, aReflowInput.AvailableBSize()); - if (aReflowInput.AvailableBSize() == NS_UNCONSTRAINEDSIZE) { - // This should never happen, but it does. See bug 414255 - bSize = aState.mBCoord; - } - const nscoord maxBSize = aReflowInput.ComputedMaxBSize(); - if (maxBSize != NS_UNCONSTRAINEDSIZE && - aState.mConsumedBSize + bSize - borderPadding.BStart(wm) > maxBSize) { - // Compute this fragment's block-size, with the max-block-size - // constraint taken into consideration. - const nscoord clampedBSizeWithoutEndBP = - std::max(0, maxBSize - aState.mConsumedBSize) + - borderPadding.BStart(wm); - const nscoord clampedBSize = - clampedBSizeWithoutEndBP + borderPadding.BEnd(wm); - if (clampedBSize <= aReflowInput.AvailableBSize()) { - // We actually fit after applying `max-size` so we should be - // Overflow-Incomplete instead. - bSize = clampedBSize; - aState.mReflowStatus.SetOverflowIncomplete(); - } else { - // We cannot fit after applying `max-size` with our block-end BP, so - // we should draw it in our next continuation. - bSize = clampedBSizeWithoutEndBP; - } + } + finalSize.BSize(wm) = bSize; + } else { + NS_ASSERTION(aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE, + "Shouldn't be incomplete if availableBSize is UNCONSTRAINED."); + nscoord bSize = std::max(aState.mBCoord, aReflowInput.AvailableBSize()); + if (aReflowInput.AvailableBSize() == NS_UNCONSTRAINEDSIZE) { + // This should never happen, but it does. See bug 414255 + bSize = aState.mBCoord; + } + const nscoord maxBSize = aReflowInput.ComputedMaxBSize(); + if (maxBSize != NS_UNCONSTRAINEDSIZE && + aState.mConsumedBSize + bSize - borderPadding.BStart(wm) > maxBSize) { + // Compute this fragment's block-size, with the max-block-size + // constraint taken into consideration. + const nscoord clampedBSizeWithoutEndBP = + std::max(0, maxBSize - aState.mConsumedBSize) + + borderPadding.BStart(wm); + const nscoord clampedBSize = + clampedBSizeWithoutEndBP + borderPadding.BEnd(wm); + if (clampedBSize <= aReflowInput.AvailableBSize()) { + // We actually fit after applying `max-size` so we should be + // Overflow-Incomplete instead. + bSize = clampedBSize; + aState.mReflowStatus.SetOverflowIncomplete(); + } else { + // We cannot fit after applying `max-size` with our block-end BP, so + // we should draw it in our next continuation. + bSize = clampedBSizeWithoutEndBP; } - finalSize.BSize(wm) = bSize; } + finalSize.BSize(wm) = bSize; } if (IsTrueOverflowContainer()) { @@ -2381,6 +2350,77 @@ nscoord nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, return blockEndEdgeOfChildren; } +void nsBlockFrame::AlignContent(BlockReflowState& aState, + ReflowOutput& aMetrics, + nscoord aBEndEdgeOfChildren) { + if (!StaticPrefs::layout_css_align_content_blocks_enabled()) { + return; + } + + StyleAlignFlags alignment = StylePosition()->mAlignContent.primary; + alignment &= ~StyleAlignFlags::FLAG_BITS; + + // Short circuit + const bool isCentered = alignment == StyleAlignFlags::CENTER || + alignment == StyleAlignFlags::SPACE_AROUND || + alignment == StyleAlignFlags::SPACE_EVENLY; + const bool isEndAlign = alignment == StyleAlignFlags::END || + alignment == StyleAlignFlags::FLEX_END || + alignment == StyleAlignFlags::LAST_BASELINE; + if (!isEndAlign && !isCentered && !aState.mAlignContentShift) { + // desired shift = 0, no cached shift to undo + return; + } + + // NOTE: ComputeFinalSize already called aState.UndoAlignContentShift(), + // so metrics no longer include cached shift. + // NOTE: Content is currently positioned at cached shift + // NOTE: Content has been fragmented against 0-shift assumption. + + // Calculate shift + nscoord shift = 0; + WritingMode wm = aState.mReflowInput.GetWritingMode(); + if ((isCentered || isEndAlign) && !mLines.empty() && + aState.mReflowStatus.IsFullyComplete() && !GetPrevInFlow()) { + nscoord availB = aState.mReflowInput.AvailableBSize(); + nscoord endB = aMetrics.BSize(wm) - aState.BorderPadding().BEnd(wm); + shift = std::min(availB, endB) - aBEndEdgeOfChildren; + + // note: these measures all include start BP, so it subtracts out + if (!(StylePosition()->mAlignContent.primary & StyleAlignFlags::UNSAFE)) { + shift = std::max(0, shift); + } + if (isCentered) { + shift = shift / 2; + } + } + // else: zero shift if start-aligned or if fragmented + + nscoord delta = shift - aState.mAlignContentShift; + if (delta) { + // Shift children + LogicalPoint translation(wm, 0, delta); + for (nsLineBox& line : Lines()) { + SlideLine(aState, &line, delta); + } + for (nsIFrame* kid : GetChildList(FrameChildListID::Float)) { + kid->MovePositionBy(wm, translation); + nsContainerFrame::PlaceFrameView(kid); + } + if (HasOutsideMarker() && !mLines.empty()) { + nsIFrame* marker = GetOutsideMarker(); + marker->MovePositionBy(wm, translation); + } + } + + if (shift) { + // Cache shift + SetProperty(AlignContentShift(), shift); + } else { + RemoveProperty(AlignContentShift()); + } +} + void nsBlockFrame::ConsiderBlockEndEdgeOfChildren( OverflowAreas& aOverflowAreas, nscoord aBEndEdgeOfChildren, const nsStyleDisplay* aDisplay) const { @@ -3153,9 +3193,12 @@ bool nsBlockFrame::ReflowDirtyLines(BlockReflowState& aState) { // Immediately fragment for page-name. It is possible we could break // out of the loop right here, but this should make it more similar to // what happens when reflow causes fragmentation. - PushTruncatedLine(aState, line, &keepGoing); + // Set the page name, so that PushTruncatedLine does not need to + // recalculate the new page name. PresShell()->FrameConstructor()->SetNextPageContentFramePageName( nextPageName ? nextPageName : GetAutoPageValue()); + PushTruncatedLine(aState, line, &keepGoing, + ComputeNewPageNameIfNeeded::No); } else { // Reflow the dirty line. If it's an incremental reflow, then force // it to invalidate the dirty area if necessary @@ -3867,7 +3910,7 @@ bool nsBlockFrame::IsSelfEmpty() { // Blocks which are margin-roots (including inline-blocks) cannot be treated // as empty for margin-collapsing and other purposes. They're more like // replaced elements. - if (HasAnyStateBits(NS_BLOCK_BFC_STATE_BITS)) { + if (HasAnyStateBits(NS_BLOCK_BFC)) { return false; } @@ -4730,11 +4773,25 @@ void nsBlockFrame::SetBreakBeforeStatusBeforeLine(BlockReflowState& aState, *aKeepReflowGoing = false; } -void nsBlockFrame::PushTruncatedLine(BlockReflowState& aState, - LineIterator aLine, - bool* aKeepReflowGoing) { +void nsBlockFrame::PushTruncatedLine( + BlockReflowState& aState, LineIterator aLine, bool* aKeepReflowGoing, + ComputeNewPageNameIfNeeded aComputeNewPageName) { PushLines(aState, aLine.prev()); *aKeepReflowGoing = false; + + if (aComputeNewPageName == ComputeNewPageNameIfNeeded::Yes) { + // mCanHaveClassABreakpoints can only be true during paginated reflow, and + // we expect this function to only be called when the available bsize is + // constrained. + const WritingMode wm = GetWritingMode(); + const bool canBreakForPageNames = + aState.mReflowInput.mFlags.mCanHaveClassABreakpoints && + !PresShell()->GetRootFrame()->GetWritingMode().IsOrthogonalTo(wm); + if (canBreakForPageNames) { + PresShell()->FrameConstructor()->MaybeSetNextPageContentFramePageName( + aLine->mFirstChild); + } + } aState.mReflowStatus.SetIncomplete(); } @@ -5177,7 +5234,7 @@ void nsBlockFrame::SplitFloat(BlockReflowState& aState, nsIFrame* aFloat, } aState.AppendPushedFloatChain(nextInFlow); - if (MOZ_LIKELY(!HasAnyStateBits(NS_BLOCK_BFC_STATE_BITS)) || + if (MOZ_LIKELY(!HasAnyStateBits(NS_BLOCK_BFC)) || MOZ_UNLIKELY(IsTrueOverflowContainer())) { aState.mReflowStatus.SetOverflowIncomplete(); } else { @@ -6290,7 +6347,7 @@ nsContainerFrame* nsBlockFrame::GetRubyContentPseudoFrame() { auto* firstChild = PrincipalChildList().FirstChild(); if (firstChild && firstChild->IsRubyFrame() && firstChild->Style()->GetPseudoType() == - mozilla::PseudoStyleType::blockRubyContent) { + PseudoStyleType::blockRubyContent) { return static_cast(firstChild); } return nullptr; @@ -6425,15 +6482,80 @@ nsBlockInFlowLineIterator::nsBlockInFlowLineIterator(nsBlockFrame* aFrame, *aFoundValidLine = FindValidLine(); } +static bool AnonymousBoxIsBFC(const ComputedStyle* aStyle) { + switch (aStyle->GetPseudoType()) { + case PseudoStyleType::fieldsetContent: + case PseudoStyleType::columnContent: + case PseudoStyleType::buttonContent: + case PseudoStyleType::cellContent: + case PseudoStyleType::scrolledContent: + case PseudoStyleType::anonymousItem: + return true; + default: + return false; + } +} + static bool StyleEstablishesBFC(const ComputedStyle* aStyle) { // paint/layout containment boxes and multi-column containers establish an // independent formatting context. // https://drafts.csswg.org/css-contain/#containment-paint // https://drafts.csswg.org/css-contain/#containment-layout + // https://drafts.csswg.org/css-align/#distribution-block // https://drafts.csswg.org/css-multicol/#columns - return aStyle->StyleDisplay()->IsContainPaint() || - aStyle->StyleDisplay()->IsContainLayout() || - aStyle->GetPseudoType() == PseudoStyleType::columnContent; + const auto* disp = aStyle->StyleDisplay(); + return disp->IsContainPaint() || disp->IsContainLayout() || + disp->DisplayInside() == StyleDisplayInside::FlowRoot || + disp->IsAbsolutelyPositionedStyle() || disp->IsFloatingStyle() || + aStyle->StylePosition()->mAlignContent.primary != + StyleAlignFlags::NORMAL || + aStyle->IsRootElementStyle() || AnonymousBoxIsBFC(aStyle); +} + +static bool EstablishesBFC(const nsBlockFrame* aFrame) { + if (aFrame->HasAnyClassFlag(LayoutFrameClassFlags::BlockFormattingContext)) { + return true; + } + + if (nsIFrame* parent = aFrame->GetParent()) { + if (parent->IsFieldSetFrame()) { + // A rendered legend always establishes a new formatting context, and so + // does the fieldset content frame, so we can just return true here. + // https://html.spec.whatwg.org/#rendered-legend + return true; + } + + const auto wm = aFrame->GetWritingMode(); + const auto parentWM = parent->GetWritingMode(); + if (wm.GetBlockDir() != parentWM.GetBlockDir() || + wm.IsVerticalSideways() != parentWM.IsVerticalSideways()) { + // If a box has a different writing-mode value than its containing block + // [...] if the box is a block container, then it establishes a new block + // formatting context. + // https://drafts.csswg.org/css-writing-modes/#block-flow + return true; + } + } + + if (aFrame->IsColumnSpan()) { + return true; + } + + if (aFrame->IsSuppressedScrollableBlockForPrint()) { + return true; + } + + const auto* style = aFrame->Style(); + if (style->GetPseudoType() == PseudoStyleType::marker) { + if (aFrame->GetParent() && + aFrame->GetParent()->StyleList()->mListStylePosition == + StyleListStylePosition::Outside) { + // An outside ::marker needs to be an independent formatting context + // to avoid being influenced by the float manager etc. + return true; + } + } + return StyleEstablishesBFC(style); } void nsBlockFrame::DidSetComputedStyle(ComputedStyle* aOldStyle) { @@ -6442,24 +6564,16 @@ void nsBlockFrame::DidSetComputedStyle(ComputedStyle* aOldStyle) { return; } - // If NS_BLOCK_STATIC_BFC flag was set when the frame was initialized, it - // remains set during the lifetime of the frame and always forces it to be - // treated as a BFC, independently of the value of NS_BLOCK_DYNAMIC_BFC. - // Consequently, we don't bother invalidating or updating that latter flag. - if (HasAnyStateBits(NS_BLOCK_STATIC_BFC)) { - return; - } - - bool isBFC = StyleEstablishesBFC(Style()); - if (StyleEstablishesBFC(aOldStyle) != isBFC) { + const bool isBFC = EstablishesBFC(this); + if (HasAnyStateBits(NS_BLOCK_BFC) != isBFC) { if (MaybeHasFloats()) { // If the frame contains floats, this update may change their float // manager. Be safe by dirtying all descendant lines of the nearest // ancestor's float manager. - RemoveStateBits(NS_BLOCK_DYNAMIC_BFC); + RemoveStateBits(NS_BLOCK_BFC); MarkSameFloatManagerLinesDirty(this); } - AddOrRemoveStateBits(NS_BLOCK_DYNAMIC_BFC, isBFC); + AddOrRemoveStateBits(NS_BLOCK_BFC, isBFC); } } @@ -7469,11 +7583,11 @@ void nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // We'll try to draw an accessibility backplate behind text (to ensure it's // readable over any possible background-images), if all of the following // hold: - // (A) the backplate feature is preffed on - // (B) we are not honoring the document colors + // (A) we are not honoring the document colors + // (B) the backplate feature is preffed on // (C) the force color adjust property is set to auto - if (StaticPrefs::browser_display_permit_backplate() && - PresContext()->ForcingColors() && !IsComboboxControlFrame() && + if (PresContext()->ForcingColors() && + StaticPrefs::browser_display_permit_backplate() && StyleText()->mForcedColorAdjust != StyleForcedColorAdjust::None) { backplateColor.emplace(GetBackplateColor(this)); } @@ -7565,7 +7679,7 @@ void nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } lastY = lineArea.y; lastYMost = lineArea.YMost(); - if (lineInLine && backplateColor && LineHasVisibleInlineContent(line)) { + if (lineInLine && backplateColor && LineHasVisibleInlineText(line)) { nsRect lineBackplate = GetLineTextArea(line, aBuilder) + aBuilder->ToReferenceFrame(this); if (curBackplateArea.IsEmpty()) { @@ -7762,35 +7876,15 @@ void nsBlockFrame::ChildIsDirty(nsIFrame* aChild) { nsContainerFrame::ChildIsDirty(aChild); } -static bool AlwaysEstablishesBFC(const nsBlockFrame* aFrame) { - switch (aFrame->Type()) { - case LayoutFrameType::ColumnSetWrapper: - // CSS Multi-column level 1 section 2: A multi-column container - // establishes a new block formatting context, as per CSS 2.1 section - // 9.4.1. - case LayoutFrameType::ComboboxControl: - return true; - case LayoutFrameType::Block: - return static_cast(do_QueryFrame(aFrame)) || - // Ensure that the options inside the select aren't expanded by - // right floats outside the select. - static_cast(do_QueryFrame(aFrame)) || - // See bug 1373767 and bug 353894. - static_cast(do_QueryFrame(aFrame)); - default: - return false; - } -} - void nsBlockFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, nsIFrame* aPrevInFlow) { // These are all the block specific frame bits, they are copied from // the prev-in-flow to a newly created next-in-flow, except for the // NS_BLOCK_FLAGS_NON_INHERITED_MASK bits below. constexpr nsFrameState NS_BLOCK_FLAGS_MASK = - NS_BLOCK_BFC_STATE_BITS | NS_BLOCK_CLIP_PAGINATED_OVERFLOW | - NS_BLOCK_HAS_FIRST_LETTER_STYLE | NS_BLOCK_FRAME_HAS_OUTSIDE_MARKER | - NS_BLOCK_HAS_FIRST_LETTER_CHILD | NS_BLOCK_FRAME_HAS_INSIDE_MARKER; + NS_BLOCK_BFC | NS_BLOCK_HAS_FIRST_LETTER_STYLE | + NS_BLOCK_FRAME_HAS_OUTSIDE_MARKER | NS_BLOCK_HAS_FIRST_LETTER_CHILD | + NS_BLOCK_FRAME_HAS_INSIDE_MARKER; // This is the subset of NS_BLOCK_FLAGS_MASK that is NOT inherited // by default. They should only be set on the first-in-flow. @@ -7812,37 +7906,12 @@ void nsBlockFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, AddStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION); } - // A display:flow-root box establishes a block formatting context. - // - // If a box has a different writing-mode value than its containing block: - // ... - // If the box is a block container, then it establishes a new block - // formatting context. - // (https://drafts.csswg.org/css-writing-modes/#block-flow) - // - // If the box has contain: paint or contain:layout (or contain:strict), - // then it should also establish a formatting context. - // - // Per spec, a column-span always establishes a new block formatting context. - // - // Other more specific frame types also always establish a BFC. - // - if (StyleDisplay()->mDisplay == mozilla::StyleDisplay::FlowRoot || - (GetParent() && - (GetWritingMode().GetBlockDir() != - GetParent()->GetWritingMode().GetBlockDir() || - GetWritingMode().IsVerticalSideways() != - GetParent()->GetWritingMode().IsVerticalSideways())) || - IsColumnSpan() || AlwaysEstablishesBFC(this)) { - AddStateBits(NS_BLOCK_STATIC_BFC); - } - - if (StyleEstablishesBFC(Style())) { - AddStateBits(NS_BLOCK_DYNAMIC_BFC); + if (EstablishesBFC(this)) { + AddStateBits(NS_BLOCK_BFC); } if (HasAnyStateBits(NS_FRAME_FONT_INFLATION_CONTAINER) && - HasAnyStateBits(NS_BLOCK_BFC_STATE_BITS)) { + HasAnyStateBits(NS_BLOCK_BFC)) { AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT); } } @@ -7866,13 +7935,13 @@ void nsBlockFrame::SetInitialChildList(ChildListID aListID, (pseudo == PseudoStyleType::cellContent && !GetParent()->Style()->IsPseudoOrAnonBox()) || pseudo == PseudoStyleType::fieldsetContent || - pseudo == PseudoStyleType::buttonContent || + (pseudo == PseudoStyleType::buttonContent && + !GetParent()->IsComboboxControlFrame()) || pseudo == PseudoStyleType::columnContent || (pseudo == PseudoStyleType::scrolledContent && !GetParent()->IsListControlFrame()) || pseudo == PseudoStyleType::mozSVGText) && - !IsComboboxControlFrame() && !IsMathMLFrame() && - !IsColumnSetWrapperFrame() && + !IsMathMLFrame() && !IsColumnSetWrapperFrame() && RefPtr(GetFirstLetterStyle(PresContext())) != nullptr; NS_ASSERTION(haveFirstLetterStyle == HasAnyStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE), @@ -7895,11 +7964,6 @@ void nsBlockFrame::SetMarkerFrameForListItem(nsIFrame* aMarkerFrame) { SetProperty(InsideMarkerProperty(), aMarkerFrame); AddStateBits(NS_BLOCK_FRAME_HAS_INSIDE_MARKER); } else { - if (nsBlockFrame* marker = do_QueryFrame(aMarkerFrame)) { - // An outside ::marker needs to be an independent formatting context - // to avoid being influenced by the float manager etc. - marker->AddStateBits(NS_BLOCK_STATIC_BFC); - } SetProperty(OutsideMarkerProperty(), new (PresShell()) nsFrameList(aMarkerFrame, aMarkerFrame)); AddStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_MARKER); @@ -8100,7 +8164,7 @@ void nsBlockFrame::CheckFloats(BlockReflowState& aState) { void nsBlockFrame::IsMarginRoot(bool* aBStartMarginRoot, bool* aBEndMarginRoot) { nsIFrame* parent = GetParent(); - if (!HasAnyStateBits(NS_BLOCK_BFC_STATE_BITS)) { + if (!HasAnyStateBits(NS_BLOCK_BFC)) { if (!parent || parent->IsFloatContainingBlock()) { *aBStartMarginRoot = false; *aBEndMarginRoot = false; @@ -8127,14 +8191,14 @@ bool nsBlockFrame::BlockNeedsFloatManager(nsIFrame* aBlock) { NS_ASSERTION(aBlock->IsBlockFrameOrSubclass(), "aBlock must be a block"); nsIFrame* parent = aBlock->GetParent(); - return aBlock->HasAnyStateBits(NS_BLOCK_BFC_STATE_BITS) || + return aBlock->HasAnyStateBits(NS_BLOCK_BFC) || (parent && !parent->IsFloatContainingBlock()); } /* static */ bool nsBlockFrame::BlockCanIntersectFloats(nsIFrame* aFrame) { return aFrame->IsBlockFrameOrSubclass() && !aFrame->IsReplaced() && - !aFrame->HasAnyStateBits(NS_BLOCK_BFC_STATE_BITS); + !aFrame->HasAnyStateBits(NS_BLOCK_BFC); } // Note that this width can vary based on the vertical position. diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index 15dd4c3278..9fb909430c 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -491,6 +491,14 @@ class nsBlockFrame : public nsContainerFrame { nscoord ComputeFinalSize(const ReflowInput& aReflowInput, BlockReflowState& aState, ReflowOutput& aMetrics); + /** + * Calculates the necessary shift to honor 'align-content' and applies it. + */ + void AlignContent(BlockReflowState& aState, ReflowOutput& aMetrics, + nscoord aBEndEdgeOfChildren); + // Stash the effective align-content shift value between reflows + NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(AlignContentShift, nscoord) + /** * Helper method for Reflow(). Computes the overflow areas created by our * children, and includes them into aOverflowAreas. @@ -540,6 +548,16 @@ class nsBlockFrame : public nsContainerFrame { */ bool IsVisualFormControl(nsPresContext* aPresContext); + /** Whether this block has an effective align-content property */ + bool IsAligned() const { + return StylePosition()->mAlignContent.primary != + mozilla::StyleAlignFlags::NORMAL; + } + + nscoord GetAlignContentShift() const { + return IsAligned() ? GetProperty(AlignContentShift()) : 0; + } + /** * For text-wrap:balance, we iteratively try reflowing with adjusted inline * size to find the "best" result (the tightest size that can be applied @@ -848,13 +866,24 @@ class nsBlockFrame : public nsContainerFrame { LineIterator aLine, bool* aKeepReflowGoing); + /** + * Indicates if we need to compute a page name for the next page when pushing + * a truncated line. + * + * Using a value of No saves work when a new page name has already been set + * with nsCSSFrameConstructor::SetNextPageContentFramePageName. + */ + enum class ComputeNewPageNameIfNeeded : uint8_t { Yes, No }; + /** * Push aLine (and any after it), since it cannot be placed on this * page/column. Set aKeepReflowGoing to false and set * flag aState.mReflowStatus as incomplete. */ void PushTruncatedLine(BlockReflowState& aState, LineIterator aLine, - bool* aKeepReflowGoing); + bool* aKeepReflowGoing, + ComputeNewPageNameIfNeeded aComputeNewPageName = + ComputeNewPageNameIfNeeded::Yes); void SplitLine(BlockReflowState& aState, nsLineLayout& aLineLayout, LineIterator aLine, nsIFrame* aFrame, diff --git a/layout/generic/nsBlockReflowContext.cpp b/layout/generic/nsBlockReflowContext.cpp index ceae9f4849..23f3b83645 100644 --- a/layout/generic/nsBlockReflowContext.cpp +++ b/layout/generic/nsBlockReflowContext.cpp @@ -275,7 +275,7 @@ void nsBlockReflowContext::ReflowBlock(const LogicalRect& aSpace, tI = space.LineLeft(mWritingMode, mContainerSize); tB = mBCoord; - if (!mFrame->HasAnyStateBits(NS_BLOCK_BFC_STATE_BITS)) { + if (!mFrame->HasAnyStateBits(NS_BLOCK_BFC)) { aFrameRI.mBlockDelta = mOuterReflowInput.mBlockDelta + mBCoord - aLine->BStart(); } diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 9629905968..2577a7a00d 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -1124,7 +1124,6 @@ void nsContainerFrame::ReflowOverflowContainerChildren( // isn't dirty. if (shouldReflowAllKids || frame->IsSubtreeDirty() || ScrollableOverflowExceedsAvailableBSize(frame)) { - // Get prev-in-flow nsIFrame* prevInFlow = frame->GetPrevInFlow(); NS_ASSERTION(prevInFlow, "overflow container frame must have a prev-in-flow"); @@ -1132,38 +1131,45 @@ void nsContainerFrame::ReflowOverflowContainerChildren( frame->HasAnyStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER), "overflow container frame must have overflow container bit set"); WritingMode wm = frame->GetWritingMode(); - nsSize containerSize = - aContainerSize ? *aContainerSize - : aReflowInput.AvailableSize(wm).GetPhysicalSize(wm); - LogicalRect prevRect = prevInFlow->GetLogicalRect(wm, containerSize); - - // Initialize reflow params - LogicalSize availSpace(wm, prevRect.ISize(wm), - aReflowInput.AvailableSize(wm).BSize(wm)); - ReflowOutput desiredSize(aReflowInput); + // Note: aReflowInput's available inline-size is technically wrong for us + // to hand off to children here, because it doesn't account for the space + // that's been used for the container's margin/border/padding (and some + // other space that a concrete container type, e.g. fieldset and grid [1], + // might reserve before setting up the available space for their + // children). Since we don't have a way to query the specific available + // inline-size each container type used, nor do we know how the container + // computes its non-overflow-container children's inline-size, we just + // unconditionally override the frame's inline-size, so that the available + // inline-size for the children doesn't really matter anyway. + // + // [1] For example, fieldset uses its computed inline-size with padding as + // the available inline-size to reflow its inner child frame. + // https://searchfox.org/mozilla-central/rev/04f7743d94691fa24212fb43099f9d84c3bfc890/layout/forms/nsFieldSetFrame.cpp#535-536 + const LogicalSize availSpace = aReflowInput.AvailableSize(wm); StyleSizeOverrides sizeOverride; - if (frame->IsFlexItem()) { - // A flex item's size is determined by the flex algorithm, not solely by - // its style. Thus, the following overrides are necessary. - // - // Use the overflow container flex item's prev-in-flow inline-size since - // this continuation's inline-size is the same. - sizeOverride.mStyleISize.emplace( - StyleSize::LengthPercentage(LengthPercentage::FromAppUnits( - frame->StylePosition()->mBoxSizing == StyleBoxSizing::Border - ? prevRect.ISize(wm) - : prevInFlow->ContentISize(wm)))); + // We override current continuation's inline-size by using the + // prev-in-flow's inline-size since both should be the same. + sizeOverride.mStyleISize.emplace( + StyleSize::LengthPercentage(LengthPercentage::FromAppUnits( + frame->StylePosition()->mBoxSizing == StyleBoxSizing::Border + ? prevInFlow->ISize(wm) + : prevInFlow->ContentISize(wm)))); + if (frame->IsFlexItem()) { // An overflow container's block-size must be 0. sizeOverride.mStyleBSize.emplace( StyleSize::LengthPercentage(LengthPercentage::FromAppUnits(0))); } + ReflowOutput desiredSize(wm); ReflowInput reflowInput(aPresContext, aReflowInput, frame, availSpace, Nothing(), {}, sizeOverride); - - LogicalPoint pos(wm, prevRect.IStart(wm), 0); + const nsSize containerSize = + aContainerSize ? *aContainerSize + : aReflowInput.AvailableSize(wm).GetPhysicalSize(wm); + const LogicalPoint pos(wm, prevInFlow->IStart(wm, containerSize), 0); nsReflowStatus frameStatus; + ReflowChild(frame, aPresContext, desiredSize, reflowInput, wm, pos, containerSize, aFlags, frameStatus, &tracker); FinishReflowChild(frame, aPresContext, desiredSize, &reflowInput, wm, pos, diff --git a/layout/generic/nsFloatManager.h b/layout/generic/nsFloatManager.h index f947567383..eb12d44e1d 100644 --- a/layout/generic/nsFloatManager.h +++ b/layout/generic/nsFloatManager.h @@ -70,8 +70,8 @@ struct nsFlowAreaRect { /** * nsFloatManager is responsible for implementing CSS's rules for * positioning floats. An nsFloatManager object is created during reflow for - * any block with NS_BLOCK_BFC_STATE_BITS. During reflow, the float manager for - * the nearest such ancestor block is found in ReflowInput::mFloatManager. + * any block with NS_BLOCK_BFC. During reflow, the float manager for the nearest + * such ancestor block is found in ReflowInput::mFloatManager. * * According to the line-relative mappings in CSS Writing Modes spec [1], * line-right and line-left are calculated with respect to the writing mode diff --git a/layout/generic/nsFrameSelection.cpp b/layout/generic/nsFrameSelection.cpp index 002d26c4fa..f1a8c7e27c 100644 --- a/layout/generic/nsFrameSelection.cpp +++ b/layout/generic/nsFrameSelection.cpp @@ -31,7 +31,6 @@ #include "nsFrameTraversal.h" #include "nsString.h" #include "nsISelectionListener.h" -#include "nsContentCID.h" #include "nsDeviceContext.h" #include "nsIContent.h" #include "nsRange.h" @@ -48,7 +47,6 @@ #include "nsGkAtoms.h" #include "nsLayoutUtils.h" -#include "nsLayoutCID.h" #include "nsBidiPresUtils.h" #include "nsTextFrame.h" diff --git a/layout/generic/nsFrameStateBits.h b/layout/generic/nsFrameStateBits.h index a9a1700737..db00deab95 100644 --- a/layout/generic/nsFrameStateBits.h +++ b/layout/generic/nsFrameStateBits.h @@ -541,41 +541,30 @@ FRAME_STATE_BIT(Block, 21, NS_BLOCK_HAS_PUSHED_FLOATS) // 2. This indicates that a block frame should create its own float manager. // This is required by each block frame that can contain floats. The float // manager is used to reserve space for the floated frames. -FRAME_STATE_BIT(Block, 22, NS_BLOCK_STATIC_BFC) +FRAME_STATE_BIT(Block, 22, NS_BLOCK_BFC) -// This is the same as NS_BLOCK_STATIC_BFC but can be updated dynamically after -// the frame construction (e.g. paint/layout containment). -// FIXME(bug 1874823): Try and merge this and NS_BLOCK_STATIC_BFC. -FRAME_STATE_BIT(Block, 23, NS_BLOCK_DYNAMIC_BFC) +FRAME_STATE_BIT(Block, 23, NS_BLOCK_HAS_LINE_CURSOR) -// For testing the relevant bits on a block formatting context: -#define NS_BLOCK_BFC_STATE_BITS (NS_BLOCK_STATIC_BFC | NS_BLOCK_DYNAMIC_BFC) +FRAME_STATE_BIT(Block, 24, NS_BLOCK_HAS_OVERFLOW_LINES) -FRAME_STATE_BIT(Block, 24, NS_BLOCK_HAS_LINE_CURSOR) - -FRAME_STATE_BIT(Block, 25, NS_BLOCK_HAS_OVERFLOW_LINES) - -FRAME_STATE_BIT(Block, 26, NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS) +FRAME_STATE_BIT(Block, 25, NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS) // Set on any block that has descendant frames in the normal // flow with 'clear' set to something other than 'none' // (including
frames) -FRAME_STATE_BIT(Block, 27, NS_BLOCK_HAS_CLEAR_CHILDREN) - -// NS_BLOCK_CLIP_PAGINATED_OVERFLOW is only set in paginated prescontexts, on -// blocks which were forced to not have scrollframes but still need to clip -// the display of their kids. -FRAME_STATE_BIT(Block, 28, NS_BLOCK_CLIP_PAGINATED_OVERFLOW) +FRAME_STATE_BIT(Block, 26, NS_BLOCK_HAS_CLEAR_CHILDREN) // NS_BLOCK_HAS_FIRST_LETTER_STYLE means that the block has first-letter style, // even if it has no actual first-letter frame among its descendants. -FRAME_STATE_BIT(Block, 29, NS_BLOCK_HAS_FIRST_LETTER_STYLE) +FRAME_STATE_BIT(Block, 27, NS_BLOCK_HAS_FIRST_LETTER_STYLE) // NS_BLOCK_FRAME_HAS_OUTSIDE_MARKER and NS_BLOCK_FRAME_HAS_INSIDE_MARKER // means the block has an associated ::marker frame, they are mutually // exclusive. -FRAME_STATE_BIT(Block, 30, NS_BLOCK_FRAME_HAS_OUTSIDE_MARKER) -FRAME_STATE_BIT(Block, 31, NS_BLOCK_FRAME_HAS_INSIDE_MARKER) +FRAME_STATE_BIT(Block, 28, NS_BLOCK_FRAME_HAS_OUTSIDE_MARKER) +FRAME_STATE_BIT(Block, 29, NS_BLOCK_FRAME_HAS_INSIDE_MARKER) + +// bits 30 and 31 free. // NS_BLOCK_HAS_LINE_CLAMP_ELLIPSIS indicates that exactly one line in this // block has the LineClampEllipsis flag set, and that such a line must be found diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index b51f3eccb7..361847b753 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1172,10 +1172,16 @@ void nsHTMLScrollFrame::PlaceScrollArea(ScrollReflowInput& aState, scrolledArea, ReflowChildFlags::Default); } -nscoord nsHTMLScrollFrame::IntrinsicScrollbarGutterSizeAtInlineEdges() { - const bool isVerticalWM = GetWritingMode().IsVertical(); +nscoord nsHTMLScrollFrame::IntrinsicScrollbarGutterSizeAtInlineEdges() const { + const auto wm = GetWritingMode(); + const LogicalMargin gutter(wm, IntrinsicScrollbarGutterSize()); + return gutter.IStartEnd(wm); +} + +nsMargin nsHTMLScrollFrame::IntrinsicScrollbarGutterSize() const { if (PresContext()->UseOverlayScrollbars()) { - return 0; + // Overlay scrollbars do not consume space per spec. + return {}; } const auto* styleForScrollbar = nsLayoutUtils::StyleForScrollbar(this); @@ -1183,28 +1189,30 @@ nscoord nsHTMLScrollFrame::IntrinsicScrollbarGutterSizeAtInlineEdges() { styleForScrollbar->StyleUIReset()->ScrollbarWidth(); if (styleScrollbarWidth == StyleScrollbarWidth::None) { // Scrollbar shouldn't appear at all with "scrollbar-width: none". - return 0; + return {}; } const auto& styleScrollbarGutter = styleForScrollbar->StyleDisplay()->mScrollbarGutter; - ScrollStyles ss = GetScrollStyles(); - const StyleOverflow& inlineEndStyleOverflow = - isVerticalWM ? ss.mHorizontal : ss.mVertical; - - // Return the scrollbar-gutter size only if we have "overflow:scroll" or - // non-auto "scrollbar-gutter", so early-return here if the conditions aren't - // satisfied. - if (inlineEndStyleOverflow != StyleOverflow::Scroll && - styleScrollbarGutter == StyleScrollbarGutter::AUTO) { - return 0; + nsMargin gutter = + ComputeStableScrollbarGutter(styleScrollbarWidth, styleScrollbarGutter); + if (gutter.LeftRight() == 0 || gutter.TopBottom() == 0) { + // If there is no stable scrollbar-gutter at vertical or horizontal + // dimension, check if a scrollbar is always shown at that dimension. + ScrollStyles scrollStyles = GetScrollStyles(); + const nscoord scrollbarSize = + GetNonOverlayScrollbarSize(PresContext(), styleScrollbarWidth); + if (gutter.LeftRight() == 0 && + scrollStyles.mVertical == StyleOverflow::Scroll) { + (IsScrollbarOnRight() ? gutter.right : gutter.left) = scrollbarSize; + } + if (gutter.TopBottom() == 0 && + scrollStyles.mHorizontal == StyleOverflow::Scroll) { + // The horizontal scrollbar is always at the bottom side. + gutter.bottom = scrollbarSize; + } } - - const nscoord scrollbarSize = - GetNonOverlayScrollbarSize(PresContext(), styleScrollbarWidth); - const auto bothEdges = - bool(styleScrollbarGutter & StyleScrollbarGutter::BOTH_EDGES); - return bothEdges ? scrollbarSize * 2 : scrollbarSize; + return gutter; } nsMargin nsHTMLScrollFrame::ComputeStableScrollbarGutter( @@ -2040,8 +2048,13 @@ class nsHTMLScrollFrame::AsyncSmoothMSDScroll final * Should be used at most once during the lifetime of this object. */ void SetRefreshObserver(nsHTMLScrollFrame* aCallee) { - NS_ASSERTION(aCallee && !mCallee, - "AsyncSmoothMSDScroll::SetRefreshObserver - Invalid usage."); + MOZ_ASSERT(aCallee, + "AsyncSmoothMSDScroll::SetRefreshObserver needs " + "a non-null aCallee in order to get a refresh driver"); + MOZ_RELEASE_ASSERT(!mCallee, + "AsyncSmoothMSDScroll::SetRefreshObserver " + "shouldn't be called if we're already registered with " + "a refresh driver, via a preexisting mCallee"); RefreshDriver(aCallee)->AddRefreshObserver(this, FlushType::Style, "Smooth scroll (MSD) animation"); @@ -2168,8 +2181,13 @@ class nsHTMLScrollFrame::AsyncScroll final : public nsARefreshObserver { * Should be used at most once during the lifetime of this object. */ void SetRefreshObserver(nsHTMLScrollFrame* aCallee) { - NS_ASSERTION(aCallee && !mCallee, - "AsyncScroll::SetRefreshObserver - Invalid usage."); + MOZ_ASSERT(aCallee, + "AsyncScroll::SetRefreshObserver needs " + "a non-null aCallee in order to get a refresh driver"); + MOZ_RELEASE_ASSERT(!mCallee, + "AsyncScroll::SetRefreshObserver " + "shouldn't be called if we're already registered with " + "a refresh driver, via a preexisting mCallee"); RefreshDriver(aCallee)->AddRefreshObserver(this, FlushType::Style, "Smooth scroll animation"); @@ -2235,12 +2253,7 @@ void nsHTMLScrollFrame::AsyncScroll::InitSmoothScroll( case ScrollOrigin::Apz: // Likewise we should never get APZ-triggered scrolls here, and if that // changes something is likely broken somewhere. - MOZ_ASSERT_UNREACHABLE( - "APZ scroll position updates should never be smooth"); - break; - case ScrollOrigin::AnchorAdjustment: - MOZ_ASSERT_UNREACHABLE( - "scroll anchor adjustments should never be smooth"); + MOZ_ASSERT(false); break; default: break; @@ -3016,7 +3029,6 @@ void nsHTMLScrollFrame::ScrollToImpl( (mLastScrollOrigin != ScrollOrigin::None && mLastScrollOrigin != ScrollOrigin::NotSpecified && mLastScrollOrigin != ScrollOrigin::Relative && - mLastScrollOrigin != ScrollOrigin::AnchorAdjustment && mLastScrollOrigin != ScrollOrigin::Apz)) { aOrigin = ScrollOrigin::Other; } @@ -3069,10 +3081,8 @@ void nsHTMLScrollFrame::ScrollToImpl( // may simplify this a bit and should be fine from the APZ side. if (mApzSmoothScrollDestination && aOrigin != ScrollOrigin::Clamp) { if (aOrigin == ScrollOrigin::Relative) { - AppendScrollUpdate(ScrollPositionUpdate::NewRelativeScroll( - // Clamp |mApzScrollPos| here. See the comment for this clamping - // reason below NewRelativeScroll call. - GetLayoutScrollRange().ClampPoint(mApzScrollPos), pt)); + AppendScrollUpdate( + ScrollPositionUpdate::NewRelativeScroll(mApzScrollPos, pt)); mApzScrollPos = pt; } else if (aOrigin != ScrollOrigin::Apz) { ScrollOrigin origin = @@ -3159,15 +3169,8 @@ void nsHTMLScrollFrame::ScrollToImpl( if (aOrigin == ScrollOrigin::Relative) { MOZ_ASSERT(!isScrollOriginDowngrade); MOZ_ASSERT(mLastScrollOrigin == ScrollOrigin::Relative); - AppendScrollUpdate(ScrollPositionUpdate::NewRelativeScroll( - // It's possible that |mApzScrollPos| is no longer within the scroll - // range, we need to clamp it to the current scroll range, otherwise - // calculating a relative scroll distance from the outside point will - // result a point far from the desired point. - GetLayoutScrollRange().ClampPoint(mApzScrollPos), pt)); - mApzScrollPos = pt; - } else if (aOrigin == ScrollOrigin::AnchorAdjustment) { - AppendScrollUpdate(ScrollPositionUpdate::NewMergeableScroll(aOrigin, pt)); + AppendScrollUpdate( + ScrollPositionUpdate::NewRelativeScroll(mApzScrollPos, pt)); mApzScrollPos = pt; } else if (aOrigin != ScrollOrigin::Apz) { AppendScrollUpdate(ScrollPositionUpdate::NewScroll(mLastScrollOrigin, pt)); diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index e05a2a077b..ce2a75a3df 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -110,7 +110,13 @@ class nsHTMLScrollFrame : public nsContainerFrame, // Return the sum of inline-size of the scrollbar gutters (if any) at the // inline-start and inline-end edges of the scroll frame (for a potential // scrollbar that scrolls in the block axis). - nscoord IntrinsicScrollbarGutterSizeAtInlineEdges(); + nscoord IntrinsicScrollbarGutterSizeAtInlineEdges() const; + + // Return the size of space created by scrollbar-gutter or actual scrollbars, + // assuming that the content is *not* overflowing the container. In other + // words, this space is created by stable scrollbar-gutter or by scrollbars + // due to "overflow: scroll". + nsMargin IntrinsicScrollbarGutterSize() const; // Compute stable scrollbar-gutter from scrollbar-width and scrollbar-gutter // properties. diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 97d8549cb0..5eb9cde7da 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -28,6 +28,7 @@ #include "nsCSSFrameConstructor.h" #include "nsDisplayList.h" #include "nsFieldSetFrame.h" +#include "nsGfxScrollFrame.h" #include "nsHashKeys.h" #include "nsIFrameInlines.h" // for nsIFrame::GetLogicalNormalPosition (don't remove) #include "nsLayoutUtils.h" @@ -3685,7 +3686,8 @@ static Subgrid* SubgridComputeMarginBorderPadding( sz.ComputedLogicalMargin(cbWM) + sz.ComputedLogicalBorderPadding(cbWM); if (aGridItem.mFrame != subgridFrame) { - nsIScrollableFrame* scrollFrame = aGridItem.mFrame->GetScrollTargetFrame(); + nsHTMLScrollFrame* scrollFrame = + do_QueryFrame(aGridItem.mFrame->GetScrollTargetFrame()); if (scrollFrame) { MOZ_ASSERT( sz.ComputedLogicalMargin(cbWM) == LogicalMargin(cbWM) && @@ -3699,7 +3701,7 @@ static Subgrid* SubgridComputeMarginBorderPadding( szScrollFrame.ComputedLogicalMargin(cbWM) + szScrollFrame.ComputedLogicalBorder(cbWM); - nsMargin ssz = scrollFrame->GetActualScrollbarSizes(); + nsMargin ssz = scrollFrame->IntrinsicScrollbarGutterSize(); subgrid->mMarginBorderPadding += LogicalMargin(cbWM, ssz); } @@ -4032,16 +4034,6 @@ static void AlignSelf(const nsGridContainerFrame::GridItemInfo& aGridItem, aAlignSelf == StyleAlignFlags::LAST_BASELINE) { aAlignSelf = aGridItem.GetSelfBaseline(aAlignSelf, eLogicalAxisBlock, &baselineAdjust); - // Adjust the baseline alignment value if the baseline affects the opposite - // side of what AlignJustifySelf expects. - auto state = aGridItem.mState[eLogicalAxisBlock]; - if (aAlignSelf == StyleAlignFlags::LAST_BASELINE && - !GridItemInfo::BaselineAlignmentAffectsEndSide(state)) { - aAlignSelf = StyleAlignFlags::BASELINE; - } else if (aAlignSelf == StyleAlignFlags::BASELINE && - GridItemInfo::BaselineAlignmentAffectsEndSide(state)) { - aAlignSelf = StyleAlignFlags::LAST_BASELINE; - } } bool isOrthogonal = aCBWM.IsOrthogonalTo(childWM); @@ -4083,16 +4075,6 @@ static void JustifySelf(const nsGridContainerFrame::GridItemInfo& aGridItem, aJustifySelf == StyleAlignFlags::LAST_BASELINE) { aJustifySelf = aGridItem.GetSelfBaseline(aJustifySelf, eLogicalAxisInline, &baselineAdjust); - // Adjust the baseline alignment value if the baseline affects the opposite - // side of what AlignJustifySelf expects. - auto state = aGridItem.mState[eLogicalAxisInline]; - if (aJustifySelf == StyleAlignFlags::LAST_BASELINE && - !GridItemInfo::BaselineAlignmentAffectsEndSide(state)) { - aJustifySelf = StyleAlignFlags::BASELINE; - } else if (aJustifySelf == StyleAlignFlags::BASELINE && - GridItemInfo::BaselineAlignmentAffectsEndSide(state)) { - aJustifySelf = StyleAlignFlags::LAST_BASELINE; - } } bool isOrthogonal = aCBWM.IsOrthogonalTo(childWM); @@ -6006,6 +5988,12 @@ void nsGridContainerFrame::Tracks::InitializeItemBaselines( const WritingMode containerWM = aState.mWM; ComputedStyle* containerStyle = aState.mFrame->Style(); + // The physical side of the container's block start side. We use it to match + // against the physical block start side of the child to determine its + // baseline sharing group. + auto containerBlockStartSide = + containerWM.PhysicalSide(MakeLogicalSide(mAxis, eLogicalEdgeStart)); + for (GridItemInfo& gridItem : aGridItems) { if (gridItem.IsSubgrid(mAxis)) { // A subgrid itself is never baseline-aligned. @@ -6101,6 +6089,27 @@ void nsGridContainerFrame::Tracks::InitializeItemBaselines( } if (state & ItemState::eIsBaselineAligned) { + // The item is baseline aligned, so calculate the baseline sharing group. + // + BaselineSharingGroup baselineAlignment = + (state & ItemState::eFirstBaseline) ? BaselineSharingGroup::First + : BaselineSharingGroup::Last; + + BaselineSharingGroup baselineSharingGroup = [&]() { + { + auto childAxis = isOrthogonal ? GetOrthogonalAxis(mAxis) : mAxis; + auto childBlockStartSide = childWM.PhysicalSide( + MakeLogicalSide(childAxis, eLogicalEdgeStart)); + bool isFirstBaseline = (state & ItemState::eFirstBaseline) != 0; + const bool containerAndChildHasEqualBaselineSide = + containerBlockStartSide == childBlockStartSide; + + return isFirstBaseline == containerAndChildHasEqualBaselineSide + ? BaselineSharingGroup::First + : BaselineSharingGroup::Last; + } + }(); + // XXXmats if |child| is a descendant of a subgrid then the metrics // below needs to account for the accumulated MPB somehow... @@ -6128,16 +6137,13 @@ void nsGridContainerFrame::Tracks::InitializeItemBaselines( : margin.BStartEnd(containerWM)); Maybe baseline; - auto baselineSharingGroup = state & ItemState::eFirstBaseline - ? BaselineSharingGroup::First - : BaselineSharingGroup::Last; if (grid) { baseline.emplace((isOrthogonal == isInlineAxis) - ? grid->GetBBaseline(baselineSharingGroup) - : grid->GetIBaseline(baselineSharingGroup)); + ? grid->GetBBaseline(baselineAlignment) + : grid->GetIBaseline(baselineAlignment)); } else { baseline = child->GetNaturalBaselineBOffset( - childWM, baselineSharingGroup, BaselineExportContext::Other); + childWM, baselineAlignment, BaselineExportContext::Other); if (!baseline) { // If baseline alignment is specified on a grid item whose size in @@ -6162,7 +6168,7 @@ void nsGridContainerFrame::Tracks::InitializeItemBaselines( if (!isTrackAutoSize || !gridItem.IsBSizeDependentOnContainerSize(containerWM)) { baseline.emplace(Baseline::SynthesizeBOffsetFromBorderBox( - child, containerWM, baselineSharingGroup)); + child, containerWM, baselineAlignment)); } } } @@ -6172,15 +6178,19 @@ void nsGridContainerFrame::Tracks::InitializeItemBaselines( NS_ASSERTION(finalBaseline != NS_INTRINSIC_ISIZE_UNKNOWN, "about to use an unknown baseline"); + nscoord marginAdjust = 0; if (baselineSharingGroup == BaselineSharingGroup::First) { - finalBaseline += isInlineAxis ? margin.IStart(containerWM) - : margin.BStart(containerWM); - + marginAdjust = isInlineAxis ? margin.IStart(containerWM) + : margin.BStart(containerWM); } else { - finalBaseline += isInlineAxis ? margin.IEnd(containerWM) - : margin.BEnd(containerWM); - state |= ItemState::eEndSideBaseline; + marginAdjust = isInlineAxis ? margin.IEnd(containerWM) + : margin.BEnd(containerWM); + + // This flag is used in ::AlignSelf(...) to check whether the item is + // last baseline aligned, but this flag should go away. + state |= GridItemInfo::eEndSideBaseline; } + finalBaseline += marginAdjust; auto& baselineItems = (baselineSharingGroup == BaselineSharingGroup::First) @@ -7602,7 +7612,12 @@ void nsGridContainerFrame::ReflowInFlowChild( // This happens when the subtree overflows its track. // XXX spec issue? it's unclear how to handle this. baselineAdjust = nscoord(0); - } else if (GridItemInfo::BaselineAlignmentAffectsEndSide(state)) { + } else if (state & ItemState::eLastBaseline) { + // FIXME: We're not setting the ItemState::eEndSideBaseline flag any + // more as the new baseline sharing group calculation handles most of + // the cases we need. For non-masonry grids this flag was always set + // for LAST_BASELINE items, so we're just mimicking that behavior here. + // That said, masonry grids might not work 100% any more.. baselineAdjust = -baselineAdjust; } if (baselineAdjust != nscoord(0)) { diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h index d785d65a50..cf3a3b5776 100644 --- a/layout/generic/nsGridContainerFrame.h +++ b/layout/generic/nsGridContainerFrame.h @@ -106,12 +106,10 @@ class nsGridContainerFrame final : public nsContainerFrame, using NamedArea = mozilla::StyleNamedArea; template - using PerBaseline = mozilla::EnumeratedArray; + using PerBaseline = mozilla::EnumeratedArray; template - using PerLogicalAxis = - mozilla::EnumeratedArray; + using PerLogicalAxis = mozilla::EnumeratedArray; // nsIFrame overrides void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, diff --git a/layout/generic/nsHTMLParts.h b/layout/generic/nsHTMLParts.h index e1d7ef4d2d..e3cab48343 100644 --- a/layout/generic/nsHTMLParts.h +++ b/layout/generic/nsHTMLParts.h @@ -57,10 +57,6 @@ nsresult NS_NewAttributeContent(nsNodeInfoManager* aNodeInfoManager, nsContainerFrame* NS_NewSelectsAreaFrame(mozilla::PresShell* aPresShell, mozilla::ComputedStyle* aStyle); -// Create a block formatting context blockframe -nsBlockFrame* NS_NewBlockFormattingContext(mozilla::PresShell* aPresShell, - mozilla::ComputedStyle* aStyle); - nsIFrame* NS_NewBRFrame(mozilla::PresShell* aPresShell, mozilla::ComputedStyle* aStyle); diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp index 81109151ff..479c26d18b 100644 --- a/layout/generic/nsIFrame.cpp +++ b/layout/generic/nsIFrame.cpp @@ -2117,8 +2117,8 @@ nsIFrame::CaretBlockAxisMetrics nsIFrame::GetCaretBlockAxisMetrics( return CaretBlockAxisMetrics{.mOffset = baseline - ascent, .mExtent = height}; } -const nsAtom* nsIFrame::ComputePageValue() const { - const nsAtom* value = nsGkAtoms::_empty; +const nsAtom* nsIFrame::ComputePageValue(const nsAtom* aAutoValue) const { + const nsAtom* value = aAutoValue ? aAutoValue : nsGkAtoms::_empty; const nsIFrame* frame = this; // Find what CSS page name value this frame's subtree has, if any. // Starting with this frame, check if a page name other than auto is present, @@ -2484,7 +2484,7 @@ bool nsIFrame::CanBeDynamicReflowRoot() const { // If we participate in a container's block reflow context, or margins // can collapse through us, we can't be a dynamic reflow root. - if (IsBlockFrameOrSubclass() && !HasAnyStateBits(NS_BLOCK_BFC_STATE_BITS)) { + if (IsBlockFrameOrSubclass() && !HasAnyStateBits(NS_BLOCK_BFC)) { return false; } @@ -3409,6 +3409,9 @@ void nsIFrame::BuildDisplayListForStackingContext( ApplyClipProp(transformedCssClip); } + uint32_t numActiveScrollframesEncounteredBefore = + aBuilder->GetNumActiveScrollframesEncountered(); + nsDisplayListCollection set(aBuilder); Maybe clipForMask; { @@ -3692,17 +3695,22 @@ void nsIFrame::BuildDisplayListForStackingContext( if (transformItem) { resultList.AppendToTop(transformItem); createdContainer = true; - } - if (hasPerspective) { - transformItem->MarkWithAssociatedPerspective(); + if (numActiveScrollframesEncounteredBefore != + aBuilder->GetNumActiveScrollframesEncountered()) { + transformItem->SetContainsASRs(true); + } + + if (hasPerspective) { + transformItem->MarkWithAssociatedPerspective(); - if (clipCapturedBy == ContainerItemType::Perspective) { - clipState.Restore(); + if (clipCapturedBy == ContainerItemType::Perspective) { + clipState.Restore(); + } + resultList.AppendNewToTop(aBuilder, this, + &resultList); + createdContainer = true; } - resultList.AppendNewToTop(aBuilder, this, - &resultList); - createdContainer = true; } } @@ -5413,7 +5421,15 @@ static FrameTarget GetSelectionClosestFrame(nsIFrame* aFrame, const nsPoint& aPoint, uint32_t aFlags); -static bool SelfIsSelectable(nsIFrame* aFrame, uint32_t aFlags) { +static bool SelfIsSelectable(nsIFrame* aFrame, nsIFrame* aParentFrame, + uint32_t aFlags) { + // We should not move selection into a native anonymous subtree when handling + // selection outside it. + if ((aFlags & nsIFrame::IGNORE_NATIVE_ANONYMOUS_SUBTREE) && + aParentFrame->GetClosestNativeAnonymousSubtreeRoot() != + aFrame->GetClosestNativeAnonymousSubtreeRoot()) { + return false; + } if ((aFlags & nsIFrame::SKIP_HIDDEN) && !aFrame->StyleVisibility()->IsVisible()) { return false; @@ -5476,21 +5492,28 @@ static FrameTarget DrillDownToSelectionFrame(nsIFrame* aFrame, bool aEndFrame, nsIFrame* result = nullptr; nsIFrame* frame = aFrame->PrincipalChildList().FirstChild(); if (!aEndFrame) { - while (frame && (!SelfIsSelectable(frame, aFlags) || frame->IsEmpty())) + while (frame && + (!SelfIsSelectable(frame, aFrame, aFlags) || frame->IsEmpty())) { frame = frame->GetNextSibling(); - if (frame) result = frame; + } + if (frame) { + result = frame; + } } else { // Because the frame tree is singly linked, to find the last frame, // we have to iterate through all the frames // XXX I have a feeling this could be slow for long blocks, although // I can't find any slowdowns while (frame) { - if (!frame->IsEmpty() && SelfIsSelectable(frame, aFlags)) + if (!frame->IsEmpty() && SelfIsSelectable(frame, aFrame, aFlags)) { result = frame; + } frame = frame->GetNextSibling(); } } - if (result) return DrillDownToSelectionFrame(result, aEndFrame, aFlags); + if (result) { + return DrillDownToSelectionFrame(result, aEndFrame, aFlags); + } } // If the current frame has no targetable children, target the current frame return FrameTarget{aFrame, true, aEndFrame}; @@ -5502,8 +5525,9 @@ static FrameTarget GetSelectionClosestFrameForLine( nsBlockFrame* aParent, nsBlockFrame::LineIterator aLine, const nsPoint& aPoint, uint32_t aFlags) { // Account for end of lines (any iterator from the block is valid) - if (aLine == aParent->LinesEnd()) + if (aLine == aParent->LinesEnd()) { return DrillDownToSelectionFrame(aParent, true, aFlags); + } nsIFrame* frame = aLine->mFirstChild; nsIFrame* closestFromIStart = nullptr; nsIFrame* closestFromIEnd = nullptr; @@ -5519,7 +5543,7 @@ static FrameTarget GetSelectionClosestFrameForLine( // the previous thing had a different editableness than us, since then we // may end up not being able to select after it if the br is the last thing // on the line. - if (!SelfIsSelectable(frame, aFlags) || frame->IsEmpty() || + if (!SelfIsSelectable(frame, aParent, aFlags) || frame->IsEmpty() || (canSkipBr && frame->IsBrFrame() && lastFrameWasEditable == frame->GetContent()->IsEditable())) { continue; @@ -5699,7 +5723,7 @@ static FrameTarget GetSelectionClosestFrame(nsIFrame* aFrame, // Go through all the child frames to find the closest one nsIFrame::FrameWithDistance closest = {nullptr, nscoord_MAX, nscoord_MAX}; for (; kid; kid = kid->GetNextSibling()) { - if (!SelfIsSelectable(kid, aFlags) || kid->IsEmpty()) { + if (!SelfIsSelectable(kid, aFrame, aFlags) || kid->IsEmpty()) { continue; } @@ -9368,7 +9392,8 @@ nsresult nsIFrame::PeekOffsetForLineEdge(PeekOffsetStruct* aPos) { } } } - FrameTarget targetFrame = DrillDownToSelectionFrame(baseFrame, endOfLine, 0); + FrameTarget targetFrame = DrillDownToSelectionFrame( + baseFrame, endOfLine, nsIFrame::IGNORE_NATIVE_ANONYMOUS_SUBTREE); SetPeekResultFromFrame(*aPos, targetFrame.frame, endOfLine ? -1 : 0, OffsetIsAtLineEdge::Yes); if (endOfLine && targetFrame.frame->HasSignificantTerminalNewline()) { @@ -11538,11 +11563,44 @@ nsIFrame::PhysicalAxes nsIFrame::ShouldApplyOverflowClipping( return PhysicalAxes::None; } - // If we're paginated and a block, and have NS_BLOCK_CLIP_PAGINATED_OVERFLOW - // set, then we want to clip our overflow. - bool clip = HasAnyStateBits(NS_BLOCK_CLIP_PAGINATED_OVERFLOW) && - PresContext()->IsPaginated() && IsBlockFrame(); - return clip ? PhysicalAxes::Both : PhysicalAxes::None; + return IsSuppressedScrollableBlockForPrint() ? PhysicalAxes::Both + : PhysicalAxes::None; +} + +bool nsIFrame::IsSuppressedScrollableBlockForPrint() const { + // This condition needs to match the suppressScrollFrame logic in the frame + // constructor. + if (!PresContext()->IsPaginated() || !IsBlockFrame() || + !StyleDisplay()->IsScrollableOverflow() || + !StyleDisplay()->IsBlockOutsideStyle() || + mContent->IsInNativeAnonymousSubtree()) { + return false; + } + if (auto* element = Element::FromNode(mContent); + element && PresContext()->ElementWouldPropagateScrollStyles(*element)) { + return false; + } + return true; +} + +bool nsIFrame::HasUnreflowedContainerQueryAncestor() const { + // If this frame has done the first reflow, its ancestors are guaranteed to + // have as well. + if (!HasAnyStateBits(NS_FRAME_FIRST_REFLOW) || + !PresContext()->HasContainerQueryFrames()) { + return false; + } + for (nsIFrame* cur = GetInFlowParent(); cur; cur = cur->GetInFlowParent()) { + if (!cur->HasAnyStateBits(NS_FRAME_FIRST_REFLOW)) { + // Done first reflow from this ancestor up, including query containers. + return false; + } + if (cur->StyleDisplay()->IsQueryContainer()) { + return true; + } + } + // No query container from this frame up to root. + return false; } #ifdef DEBUG diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index a29786488f..16f3d17d64 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -562,6 +562,8 @@ enum class LayoutFrameClassFlags : uint16_t { SupportsContainLayoutAndPaint = 1 << 13, // Whether this frame class supports the `aspect-ratio` property. SupportsAspectRatio = 1 << 14, + // Whether this frame class is always a BFC. + BlockFormattingContext = 1 << 15, }; MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(LayoutFrameClassFlags) @@ -1380,6 +1382,8 @@ class nsIFrame : public nsQueryFrame { return nullptr; } + bool HasUnreflowedContainerQueryAncestor() const; + private: // The value that the CSS page-name "auto" keyword resolves to for children // of this frame. @@ -1643,7 +1647,13 @@ class nsIFrame : public nsQueryFrame { // This is intended to be used either on the root frame to find the first // page's page-name, or on a newly created continuation to find what the new // page's page-name will be. - const nsAtom* ComputePageValue() const MOZ_NONNULL_RETURN; + // + // The auto page value can be set by the caller. This is useful when trying + // to compute a page value in the middle of a frame tree. In that case the + // auto value can be found from the AutoPageValue frame property of the + // parent frame. A null auto value is interpreted as the empty-string atom. + const nsAtom* ComputePageValue(const nsAtom* aAutoValue = nullptr) const + MOZ_NONNULL_RETURN; /////////////////////////////////////////////////////////////////////////////// // The public visibility API. @@ -3027,6 +3037,9 @@ class nsIFrame : public nsQueryFrame { nsSize OverflowClipMargin(PhysicalAxes aClipAxes) const; // Returns the axes on which this frame should apply overflow clipping. PhysicalAxes ShouldApplyOverflowClipping(const nsStyleDisplay* aDisp) const; + // Returns whether this frame is a block that was supposed to be a + // scrollframe, but that was suppressed for print. + bool IsSuppressedScrollableBlockForPrint() const; /** * Helper method used by block reflow to identify runs of text so diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index e0a6243ed2..c1e69df6c9 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -18,6 +18,7 @@ #include "mozilla/DebugOnly.h" #include "mozilla/Encoding.h" #include "mozilla/HTMLEditor.h" +#include "mozilla/dom/FetchPriority.h" #include "mozilla/dom/ImageTracker.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/Helpers.h" @@ -268,7 +269,7 @@ BrokenImageIcon::BrokenImageIcon(const nsImageFrame& aFrame) { loadFlags, nullptr, contentPolicyType, u""_ns, false, /* aUseUrgentStartForChannel */ false, /* aLinkPreload */ - 0, getter_AddRefs(mImage)); + 0, FetchPriority::Auto, getter_AddRefs(mImage)); Unused << NS_WARN_IF(NS_FAILED(rv)); } @@ -554,15 +555,16 @@ void nsImageFrame::DidSetComputedStyle(ComputedStyle* aOldStyle) { // // TODO(emilio): We might want to do the same for regular list-style-image or // even simple content: url() changes. - if (mKind == Kind::XULImage) { - if (!mContent->AsElement()->HasNonEmptyAttr(nsGkAtoms::src) && aOldStyle && + if (mKind == Kind::XULImage && aOldStyle) { + if (!mContent->AsElement()->HasNonEmptyAttr(nsGkAtoms::src) && aOldStyle->StyleList()->mListStyleImage != StyleList()->mListStyleImage) { UpdateXULImage(); } - if (!mOwnedRequest && aOldStyle && - aOldStyle->StyleDisplay()->EffectiveAppearance() != - StyleDisplay()->EffectiveAppearance()) { + // If we have no image our intrinsic size might be themed. We need to + // update the size even if the effective appearance hasn't changed to + // deal correctly with theme changes. + if (!mOwnedRequest) { UpdateIntrinsicSize(); } } diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 03aa6e87b3..ab6924faa4 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -430,7 +430,7 @@ void nsLineLayout::BeginSpan(nsIFrame* aFrame, psd->mIStart = aIStart; psd->mICoord = aIStart; psd->mIEnd = aIEnd; - psd->mInset = mCurrentSpan->mInset; + psd->mInset = 0; // inset applies only to the root span psd->mBaseline = aBaseline; nsIFrame* frame = aSpanReflowInput->mFrame; @@ -735,8 +735,7 @@ static bool IsPercentageAware(const nsIFrame* aFrame, WritingMode aWM) { disp->DisplayInside() == StyleDisplayInside::Table)) || fType == LayoutFrameType::HTMLButtonControl || fType == LayoutFrameType::GfxButtonControl || - fType == LayoutFrameType::FieldSet || - fType == LayoutFrameType::ComboboxDisplay) { + fType == LayoutFrameType::FieldSet) { return true; } diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 369722fe8d..9afefc5c28 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -226,6 +226,7 @@ struct nsTextFrame::DrawTextRunParams { float textStrokeWidth = 0.0f; bool drawSoftHyphen = false; bool hasTextShadow = false; + bool paintingShadows = false; DrawTextRunParams(gfxContext* aContext, mozilla::gfx::PaletteCache& aPaletteCache) : context(aContext), paletteCache(aPaletteCache) {} @@ -276,6 +277,7 @@ struct nsTextFrame::PaintShadowParams { Point framePt; Point textBaselinePt; gfxContext* context; + DrawPathCallbacks* callbacks = nullptr; nscolor foregroundColor = NS_RGBA(0, 0, 0, 0); const ClipEdges* clipEdges = nullptr; PropertyProvider* provider = nullptr; @@ -5374,9 +5376,8 @@ void nsTextFrame::UnionAdditionalOverflow(nsPresContext* aPresContext, // Text-shadow overflows if (aIncludeShadows) { - nsRect shadowRect = + *aInkOverflowRect = nsLayoutUtils::GetTextShadowRectsUnion(*aInkOverflowRect, this); - aInkOverflowRect->UnionRect(*aInkOverflowRect, shadowRect); } // When this frame is not selected, the text-decoration area must be in @@ -5460,6 +5461,7 @@ struct nsTextFrame::PaintDecorationLineParams gfxFloat baselineOffset = 0.0f; DecorationType decorationType = DecorationType::Normal; DrawPathCallbacks* callbacks = nullptr; + bool paintingShadows = false; }; void nsTextFrame::PaintDecorationLine( @@ -5474,9 +5476,11 @@ void nsTextFrame::PaintDecorationLine( if (aParams.callbacks) { Rect path = nsCSSRendering::DecorationLineToPath(params); if (aParams.decorationType == DecorationType::Normal) { - aParams.callbacks->PaintDecorationLine(path, params.color); + aParams.callbacks->PaintDecorationLine(path, aParams.paintingShadows, + params.color); } else { - aParams.callbacks->PaintSelectionDecorationLine(path, params.color); + aParams.callbacks->PaintSelectionDecorationLine( + path, aParams.paintingShadows, params.color); } } else { nsCSSRendering::PaintDecorationLine(this, *aParams.context->GetDrawTarget(), @@ -5938,6 +5942,7 @@ void nsTextFrame::PaintOneShadow(const PaintShadowParams& aParams, gfxFloat advanceWidth; nsTextPaintStyle textPaintStyle(this); DrawTextParams params(shadowContext, PresContext()->FontPaletteCache()); + params.paintingShadows = true; params.advanceWidth = &advanceWidth; params.dirtyRect = aParams.dirtyRect; params.framePt = aParams.framePt + shadowGfxOffset; @@ -5945,9 +5950,10 @@ void nsTextFrame::PaintOneShadow(const PaintShadowParams& aParams, params.textStyle = &textPaintStyle; params.textColor = aParams.context == shadowContext ? shadowColor : NS_RGB(0, 0, 0); + params.callbacks = aParams.callbacks; params.clipEdges = aParams.clipEdges; params.drawSoftHyphen = HasAnyStateBits(TEXT_HYPHEN_BREAK); - // Multi-color shadow is not allowed, so we use the same color of the text + // Multi-color shadow is not allowed, so we use the same color as the text // color. params.decorationOverrideColor = ¶ms.textColor; params.fontPalette = StyleFont()->GetFontPaletteAtom(); @@ -6253,6 +6259,7 @@ bool nsTextFrame::PaintTextWithSelectionColors( PaintShadowParams shadowParams(aParams); shadowParams.provider = aParams.provider; + shadowParams.callbacks = aParams.callbacks; shadowParams.clipEdges = &aClipEdges; // Draw text @@ -6815,6 +6822,7 @@ void nsTextFrame::PaintText(const PaintTextParams& aParams, shadowParams.textBaselinePt = textBaselinePt; shadowParams.leftSideOffset = snappedStartEdge; shadowParams.provider = &provider; + shadowParams.callbacks = aParams.callbacks; shadowParams.foregroundColor = foregroundColor; shadowParams.clipEdges = &clipEdges; PaintShadows(textStyle->mTextShadow.AsSpan(), shadowParams); @@ -6854,7 +6862,8 @@ static void DrawTextRun(const gfxTextRun* aTextRun, params.callbacks = aParams.callbacks; params.hasTextShadow = aParams.hasTextShadow; if (aParams.callbacks) { - aParams.callbacks->NotifyBeforeText(aParams.textColor); + aParams.callbacks->NotifyBeforeText(aParams.paintingShadows, + aParams.textColor); params.drawMode = DrawMode::GLYPH_PATH; aTextRun->Draw(aRange, aTextBaselinePt, params); aParams.callbacks->NotifyAfterText(); @@ -6995,6 +7004,7 @@ void nsTextFrame::DrawTextRunAndDecorations( params.callbacks = aParams.callbacks; params.glyphRange = aParams.glyphRange; params.provider = aParams.provider; + params.paintingShadows = aParams.paintingShadows; // pt is the physical point where the decoration is to be drawn, // relative to the frame; one of its coordinates will be updated below. params.pt = Point(x / app, y / app); diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h index 568d3333c2..707d39dba2 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -513,20 +513,22 @@ class nsTextFrame : public nsIFrame { * Called before (for under/over-line) or after (for line-through) the text * is drawn to have a text decoration line drawn. */ - virtual void PaintDecorationLine(Rect aPath, nscolor aColor) {} + virtual void PaintDecorationLine(Rect aPath, bool aPaintingShadows, + nscolor aColor) {} /** * Called after selected text is drawn to have a decoration line drawn over * the text. (All types of text decoration are drawn after the text when * text is selected.) */ - virtual void PaintSelectionDecorationLine(Rect aPath, nscolor aColor) {} + virtual void PaintSelectionDecorationLine(Rect aPath, bool aPaintingShadows, + nscolor aColor) {} /** * Called just before any paths have been emitted to the gfxContext * for the glyphs of the frame's text. */ - virtual void NotifyBeforeText(nscolor aColor) {} + virtual void NotifyBeforeText(bool aPaintingShadows, nscolor aColor) {} /** * Called just after all the paths have been emitted to the gfxContext diff --git a/layout/generic/nsTextPaintStyle.cpp b/layout/generic/nsTextPaintStyle.cpp index 0eff737602..e97a059b07 100644 --- a/layout/generic/nsTextPaintStyle.cpp +++ b/layout/generic/nsTextPaintStyle.cpp @@ -417,8 +417,8 @@ struct StyleIDs { LookAndFeel::IntID mLineStyle; LookAndFeel::FloatID mLineRelativeSize; }; -EnumeratedArray +EnumeratedArray SelectionStyleIDs = { StyleIDs{LookAndFeel::ColorID::IMERawInputForeground, LookAndFeel::ColorID::IMERawInputBackground, diff --git a/layout/generic/nsTextPaintStyle.h b/layout/generic/nsTextPaintStyle.h index a99ee9fd46..adf28fdad8 100644 --- a/layout/generic/nsTextPaintStyle.h +++ b/layout/generic/nsTextPaintStyle.h @@ -144,8 +144,9 @@ class MOZ_STACK_CLASS nsTextPaintStyle { StyleTextDecorationStyle mUnderlineStyle; float mUnderlineRelativeSize; }; - mozilla::EnumeratedArray> + mozilla::EnumeratedArray, + size_t(SelectionStyleIndex::Count)> mSelectionStyle; // Color initializations diff --git a/layout/inspector/InspectorUtils.cpp b/layout/inspector/InspectorUtils.cpp index e2111aa9bd..f1886a0dd0 100644 --- a/layout/inspector/InspectorUtils.cpp +++ b/layout/inspector/InspectorUtils.cpp @@ -351,9 +351,7 @@ uint32_t InspectorUtils::GetRelativeRuleLine(GlobalObject& aGlobal, return aRule.GetLineNumber() + 1; } - -void InspectorUtils::GetRuleIndex(GlobalObject& aGlobal, - css::Rule& aRule, +void InspectorUtils::GetRuleIndex(GlobalObject& aGlobal, css::Rule& aRule, nsTArray& aResult) { css::Rule* currentRule = &aRule; @@ -401,21 +399,56 @@ bool InspectorUtils::HasRulesModifiedByCSSOM(GlobalObject& aGlobal, return aSheet.HasModifiedRulesForDevtools(); } -static void CollectRules(ServoCSSRuleList& aRuleList, - nsTArray>& aResult) { - for (uint32_t i = 0, len = aRuleList.Length(); i < len; ++i) { +static uint32_t CollectAtRules(ServoCSSRuleList& aRuleList, + Sequence>& aResult) { + uint32_t len = aRuleList.Length(); + uint32_t ruleCount = len; + for (uint32_t i = 0; i < len; ++i) { css::Rule* rule = aRuleList.GetRule(i); - aResult.AppendElement(rule); + // This collect rules we want to display in Devtools Style Editor toolbar. + // When adding a new StyleCssRuleType, put it in the "default" list, and + // file a new bug with + // https://bugzilla.mozilla.org/enter_bug.cgi?product=DevTools&component=Style%20Editor&short_desc=Consider%20displaying%20new%20XXX%20rule%20type%20in%20at-rules%20sidebar + // so the DevTools team gets notified and can decide if it should be + // displayed. + switch (rule->Type()) { + case StyleCssRuleType::Media: + case StyleCssRuleType::Supports: + case StyleCssRuleType::LayerBlock: + case StyleCssRuleType::Container: { + Unused << aResult.AppendElement(OwningNonNull(*rule), fallible); + break; + } + case StyleCssRuleType::Style: + case StyleCssRuleType::Import: + case StyleCssRuleType::Document: + case StyleCssRuleType::LayerStatement: + case StyleCssRuleType::FontFace: + case StyleCssRuleType::Page: + case StyleCssRuleType::Property: + case StyleCssRuleType::Keyframes: + case StyleCssRuleType::Keyframe: + case StyleCssRuleType::Margin: + case StyleCssRuleType::Namespace: + case StyleCssRuleType::CounterStyle: + case StyleCssRuleType::FontFeatureValues: + case StyleCssRuleType::FontPaletteValues: + break; + } + if (rule->IsGroupRule()) { - CollectRules(*static_cast(rule)->CssRules(), aResult); + ruleCount += CollectAtRules( + *static_cast(rule)->CssRules(), aResult); } } + return ruleCount; } -void InspectorUtils::GetAllStyleSheetCSSStyleRules( +void InspectorUtils::GetStyleSheetRuleCountAndAtRules( GlobalObject& aGlobal, StyleSheet& aSheet, - nsTArray>& aResult) { - CollectRules(*aSheet.GetCssRulesInternal(), aResult); + InspectorStyleSheetRuleCountAndAtRulesResult& aResult) { + aResult.mRuleCount = + CollectAtRules(*aSheet.GetCssRulesInternal(), aResult.mAtRules); } /* static */ @@ -601,6 +634,26 @@ void InspectorUtils::ColorToRGBA(GlobalObject&, const nsACString& aColorString, tuple.mA = nsStyleUtil::ColorComponentToFloat(NS_GET_A(color)); } +/* static */ +void InspectorUtils::ColorTo(GlobalObject&, const nsACString& aFromColor, + const nsACString& aToColorSpace, + Nullable& aResult) { + nsCString resultColor; + nsTArray resultComponents; + bool resultAdjusted = false; + + if (!ServoCSSParser::ColorTo(aFromColor, aToColorSpace, &resultColor, + &resultComponents, &resultAdjusted)) { + aResult.SetNull(); + return; + } + + auto& result = aResult.SetValue(); + result.mColor.AssignASCII(resultColor); + result.mComponents = std::move(resultComponents); + result.mAdjusted = resultAdjusted; +} + /* static */ bool InspectorUtils::IsValidCSSColor(GlobalObject& aGlobalObject, const nsACString& aColorString) { @@ -946,5 +999,23 @@ void InspectorUtils::GetCSSRegisteredProperties( } } +/* static */ +void InspectorUtils::GetRuleBodyTextOffsets( + GlobalObject&, const nsACString& aInitialText, + Nullable& aResult) { + uint32_t resultStartOffset; + uint32_t resultEndOffset; + + if (!Servo_GetRuleBodyTextOffsets(&aInitialText, &resultStartOffset, + &resultEndOffset)) { + aResult.SetNull(); + return; + } + + InspectorGetRuleBodyTextResult& offsets = aResult.SetValue(); + offsets.mStartOffset = resultStartOffset; + offsets.mEndOffset = resultEndOffset; +} + } // namespace dom } // namespace mozilla diff --git a/layout/inspector/InspectorUtils.h b/layout/inspector/InspectorUtils.h index 06bc0ff5fc..f375e51472 100644 --- a/layout/inspector/InspectorUtils.h +++ b/layout/inspector/InspectorUtils.h @@ -78,9 +78,9 @@ class InspectorUtils { static bool HasRulesModifiedByCSSOM(GlobalObject& aGlobal, StyleSheet& aSheet); - static void GetAllStyleSheetCSSStyleRules( + static void GetStyleSheetRuleCountAndAtRules( GlobalObject& aGlobal, StyleSheet& aSheet, - nsTArray>& aResult); + InspectorStyleSheetRuleCountAndAtRulesResult& aResult); // Utilities for working with CSS properties // @@ -118,6 +118,11 @@ class InspectorUtils { const Document*, Nullable& aResult); + // Convert a given CSS color string to another color space. + static void ColorTo(GlobalObject&, const nsACString& aFromColor, + const nsACString& aToColorSpace, + Nullable& aResult); + // Check whether a given color is a valid CSS color. static bool IsValidCSSColor(GlobalObject& aGlobal, const nsACString& aColorString); @@ -263,6 +268,13 @@ class InspectorUtils { static void GetCSSRegisteredProperties( GlobalObject& aGlobal, Document& aDocument, nsTArray& aResult); + + /** + * Get the rule body text start and end offsets within aInitialText + */ + static void GetRuleBodyTextOffsets( + GlobalObject&, const nsACString& aInitialText, + Nullable& aResult); }; } // namespace mozilla::dom diff --git a/layout/inspector/tests/mochitest.toml b/layout/inspector/tests/mochitest.toml index 3db9693c20..e51941752b 100644 --- a/layout/inspector/tests/mochitest.toml +++ b/layout/inspector/tests/mochitest.toml @@ -3,6 +3,7 @@ prefs = [ "layout.css.basic-shape-rect.enabled=true", "layout.css.basic-shape-xywh.enabled=true", "layout.css.properties-and-values.enabled=true", + "layout.css.transition-behavior.enabled=true", "dom.customHighlightAPI.enabled=true", ] support-files = [ @@ -32,6 +33,8 @@ support-files = [ ["test_bug1006595.html"] +["test_color_to.html"] + ["test_color_to_rgba.html"] ["test_containing_block_of.html"] diff --git a/layout/inspector/tests/test_bug877690.html b/layout/inspector/tests/test_bug877690.html index 0c01428176..9e5efca0d3 100644 --- a/layout/inspector/tests/test_bug877690.html +++ b/layout/inspector/tests/test_bug877690.html @@ -145,7 +145,7 @@ function do_test() { var values = InspectorUtils.getCSSValuesForProperty(prop); var expected = [ "initial", "all", "unset", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "revert", "revert-layer", "linear", "none", "step-end", "step-start", - "steps" ]; + "steps", "normal", "allow-discrete" ]; ok(testValues(values, expected), "property transition's values."); // test invalid property diff --git a/layout/inspector/tests/test_color_to.html b/layout/inspector/tests/test_color_to.html new file mode 100644 index 0000000000..b2c14e68c1 --- /dev/null +++ b/layout/inspector/tests/test_color_to.html @@ -0,0 +1,116 @@ + + + + + Test InspectorUtils::ColorTo + + + + + +

+ +

+
+
diff --git a/layout/mathml/nsIMathMLFrame.h b/layout/mathml/nsIMathMLFrame.h
index f27ef806e9..efe550e0fa 100644
--- a/layout/mathml/nsIMathMLFrame.h
+++ b/layout/mathml/nsIMathMLFrame.h
@@ -291,11 +291,6 @@ struct nsPresentationData {
 // feature setting.
 #define NS_MATHML_DTLS 0x00000080U
 
-// This bit is set when the frame cannot be formatted due to an
-// error (e.g., invalid markup such as a  without an overscript).
-// When set, a visual feedback will be provided to the user.
-#define NS_MATHML_ERROR 0x80000000U
-
 // a bit used for debug
 #define NS_MATHML_STRETCH_DONE 0x20000000U
 
@@ -324,9 +319,6 @@ struct nsPresentationData {
 #define NS_MATHML_IS_DTLS_SET(_flags) \
   (NS_MATHML_DTLS == ((_flags) & NS_MATHML_DTLS))
 
-#define NS_MATHML_HAS_ERROR(_flags) \
-  (NS_MATHML_ERROR == ((_flags) & NS_MATHML_ERROR))
-
 #define NS_MATHML_STRETCH_WAS_DONE(_flags) \
   (NS_MATHML_STRETCH_DONE == ((_flags) & NS_MATHML_STRETCH_DONE))
 
diff --git a/layout/mathml/nsMathMLContainerFrame.cpp b/layout/mathml/nsMathMLContainerFrame.cpp
index 7a62146504..b63792c288 100644
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -33,45 +33,6 @@ NS_QUERYFRAME_HEAD(nsMathMLContainerFrame)
   NS_QUERYFRAME_ENTRY(nsMathMLContainerFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
-// =============================================================================
-
-namespace mozilla {
-
-class nsDisplayMathMLError : public nsPaintedDisplayItem {
- public:
-  nsDisplayMathMLError(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
-      : nsPaintedDisplayItem(aBuilder, aFrame) {
-    MOZ_COUNT_CTOR(nsDisplayMathMLError);
-  }
-  MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayMathMLError)
-
-  virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
-  NS_DISPLAY_DECL_NAME("MathMLError", TYPE_MATHML_ERROR)
-};
-
-void nsDisplayMathMLError::Paint(nsDisplayListBuilder* aBuilder,
-                                 gfxContext* aCtx) {
-  // Set color and font ...
-  RefPtr fm =
-      nsLayoutUtils::GetFontMetricsForFrame(mFrame, 1.0f);
-
-  nsPoint pt = ToReferenceFrame();
-  int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
-  DrawTarget* drawTarget = aCtx->GetDrawTarget();
-  Rect rect = NSRectToSnappedRect(nsRect(pt, mFrame->GetSize()),
-                                  appUnitsPerDevPixel, *drawTarget);
-  ColorPattern red(ToDeviceColor(sRGBColor(1.f, 0.f, 0.f, 1.f)));
-  drawTarget->FillRect(rect, red);
-
-  aCtx->SetColor(sRGBColor::OpaqueWhite());
-  nscoord ascent = fm->MaxAscent();
-  constexpr auto errorMsg = u"invalid-markup"_ns;
-  nsLayoutUtils::DrawUniDirString(errorMsg.get(), uint32_t(errorMsg.Length()),
-                                  nsPoint(pt.x, pt.y + ascent), *fm, *aCtx);
-}
-
-}  // namespace mozilla
-
 /* /////////////
  * nsIMathMLFrame - support methods for stretchy elements
  * =============================================================================
@@ -244,11 +205,6 @@ nsMathMLContainerFrame::Stretch(DrawTarget* aDrawTarget,
     }
     mPresentationData.flags |= NS_MATHML_STRETCH_DONE;
 
-    if (NS_MATHML_HAS_ERROR(mPresentationData.flags)) {
-      NS_WARNING("it is wrong to fire stretch on a erroneous frame");
-      return NS_OK;
-    }
-
     // Pass the stretch to the base child ...
 
     nsIFrame* baseFrame = mPresentationData.baseFrame;
@@ -341,7 +297,7 @@ nsMathMLContainerFrame::Stretch(DrawTarget* aDrawTarget,
 
         // re-position all our children
         nsresult rv = Place(aDrawTarget, true, aDesiredStretchSize);
-        if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
+        if (NS_FAILED(rv)) {
           // Make sure the child frames get their DidReflow() calls.
           DidReflowChildren(mFrames.FirstChild());
         }
@@ -430,7 +386,7 @@ nsresult nsMathMLContainerFrame::FinalizeReflow(DrawTarget* aDrawTarget,
   // that still needs it here (or we may crash - bug 366012).
   // If placeOrigin is false we should reach Place() with aPlaceOrigin == true
   // through Stretch() eventually.
-  if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
+  if (NS_FAILED(rv)) {
     GatherAndStoreOverflow(&aDesiredSize);
     DidReflowChildren(PrincipalChildList().FirstChild());
     return rv;
@@ -566,14 +522,6 @@ void nsMathMLContainerFrame::PropagatePresentationDataFromChildAt(
 
 void nsMathMLContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
                                               const nsDisplayListSet& aLists) {
-  // report an error if something wrong was found in this frame
-  if (NS_MATHML_HAS_ERROR(mPresentationData.flags)) {
-    if (!IsVisibleForPainting()) return;
-
-    aLists.Content()->AppendNewToTop(aBuilder, this);
-    return;
-  }
-
   BuildDisplayListForInline(aBuilder, aLists);
 
 #if defined(DEBUG) && defined(SHOW_BOUNDING_BOX)
@@ -798,7 +746,6 @@ void nsMathMLContainerFrame::Reflow(nsPresContext* aPresContext,
   MarkInReflow();
   MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
 
-  mPresentationData.flags &= ~NS_MATHML_ERROR;
   aDesiredSize.Width() = aDesiredSize.Height() = 0;
   aDesiredSize.SetBlockStartAscent(0);
   aDesiredSize.mBoundingMetrics = nsBoundingMetrics();
diff --git a/layout/mathml/nsMathMLTokenFrame.cpp b/layout/mathml/nsMathMLTokenFrame.cpp
index 5481e6faec..61cb65ef87 100644
--- a/layout/mathml/nsMathMLTokenFrame.cpp
+++ b/layout/mathml/nsMathMLTokenFrame.cpp
@@ -116,8 +116,6 @@ void nsMathMLTokenFrame::Reflow(nsPresContext* aPresContext,
   MarkInReflow();
   MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
 
-  mPresentationData.flags &= ~NS_MATHML_ERROR;
-
   // initializations needed for empty markup like 
   aDesiredSize.ClearSize();
   aDesiredSize.SetBlockStartAscent(0);
diff --git a/layout/mathml/nsMathMLmencloseFrame.cpp b/layout/mathml/nsMathMLmencloseFrame.cpp
index 1b8a03991b..9f0afc9857 100644
--- a/layout/mathml/nsMathMLmencloseFrame.cpp
+++ b/layout/mathml/nsMathMLmencloseFrame.cpp
@@ -206,8 +206,6 @@ void nsMathMLmencloseFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
   // paint the menclosed content
   nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists);
 
-  if (NS_MATHML_HAS_ERROR(mPresentationData.flags)) return;
-
   nsRect mencloseRect = nsIFrame::GetRect();
   mencloseRect.x = mencloseRect.y = 0;
 
@@ -322,7 +320,7 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
   ReflowOutput baseSize(aDesiredSize.GetWritingMode());
   nsresult rv = nsMathMLContainerFrame::Place(aDrawTarget, false, baseSize);
 
-  if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
+  if (NS_FAILED(rv)) {
     DidReflowChildren(PrincipalChildList().FirstChild());
     return rv;
   }
diff --git a/layout/mathml/nsMathMLmoFrame.cpp b/layout/mathml/nsMathMLmoFrame.cpp
index 45c61124df..e0d68234ae 100644
--- a/layout/mathml/nsMathMLmoFrame.cpp
+++ b/layout/mathml/nsMathMLmoFrame.cpp
@@ -732,7 +732,7 @@ nsMathMLmoFrame::Stretch(DrawTarget* aDrawTarget,
   // Place our children using the default method
   // This will allow our child text frame to get its DidReflow()
   nsresult rv = Place(aDrawTarget, true, aDesiredStretchSize);
-  if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
+  if (NS_FAILED(rv)) {
     // Make sure the child frames get their DidReflow() calls.
     DidReflowChildren(mFrames.FirstChild());
   }
diff --git a/layout/mathml/nsMathMLmpaddedFrame.cpp b/layout/mathml/nsMathMLmpaddedFrame.cpp
index 07711fefa9..930a87f698 100644
--- a/layout/mathml/nsMathMLmpaddedFrame.cpp
+++ b/layout/mathml/nsMathMLmpaddedFrame.cpp
@@ -303,7 +303,6 @@ void nsMathMLmpaddedFrame::Reflow(nsPresContext* aPresContext,
                                   nsReflowStatus& aStatus) {
   MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
 
-  mPresentationData.flags &= ~NS_MATHML_ERROR;
   ProcessAttributes();
 
   ///////////////
@@ -317,7 +316,7 @@ void nsMathMLmpaddedFrame::Reflow(nsPresContext* aPresContext,
 nsresult nsMathMLmpaddedFrame::Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
                                      ReflowOutput& aDesiredSize) {
   nsresult rv = nsMathMLContainerFrame::Place(aDrawTarget, false, aDesiredSize);
-  if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
+  if (NS_FAILED(rv)) {
     DidReflowChildren(PrincipalChildList().FirstChild());
     return rv;
   }
diff --git a/layout/mathml/nsMathMLmrootFrame.cpp b/layout/mathml/nsMathMLmrootFrame.cpp
index c74767d777..5e8d65f8a8 100644
--- a/layout/mathml/nsMathMLmrootFrame.cpp
+++ b/layout/mathml/nsMathMLmrootFrame.cpp
@@ -80,20 +80,18 @@ void nsMathMLmrootFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
 
   /////////////
   // paint the sqrt symbol
-  if (!NS_MATHML_HAS_ERROR(mPresentationData.flags)) {
-    mSqrChar.Display(aBuilder, this, aLists, 0);
+  mSqrChar.Display(aBuilder, this, aLists, 0);
 
-    DisplayBar(aBuilder, this, mBarRect, aLists);
+  DisplayBar(aBuilder, this, mBarRect, aLists);
 
 #if defined(DEBUG) && defined(SHOW_BOUNDING_BOX)
-    // for visual debug
-    nsRect rect;
-    mSqrChar.GetRect(rect);
-    nsBoundingMetrics bm;
-    mSqrChar.GetBoundingMetrics(bm);
-    DisplayBoundingMetrics(aBuilder, this, rect.TopLeft(), bm, aLists);
+  // for visual debug
+  nsRect rect;
+  mSqrChar.GetRect(rect);
+  nsBoundingMetrics bm;
+  mSqrChar.GetBoundingMetrics(bm);
+  DisplayBoundingMetrics(aBuilder, this, rect.TopLeft(), bm, aLists);
 #endif
-  }
 }
 
 void nsMathMLmrootFrame::GetRadicalXOffsets(nscoord aIndexWidth,
@@ -162,7 +160,6 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
   MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
 
   nsReflowStatus childStatus;
-  mPresentationData.flags &= ~NS_MATHML_ERROR;
   aDesiredSize.ClearSize();
   aDesiredSize.SetBlockStartAscent(0);
 
diff --git a/layout/mathml/nsMathMLmspaceFrame.cpp b/layout/mathml/nsMathMLmspaceFrame.cpp
index 49746df8e4..1f87c095df 100644
--- a/layout/mathml/nsMathMLmspaceFrame.cpp
+++ b/layout/mathml/nsMathMLmspaceFrame.cpp
@@ -93,7 +93,6 @@ void nsMathMLmspaceFrame::Reflow(nsPresContext* aPresContext,
   MarkInReflow();
   MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
 
-  mPresentationData.flags &= ~NS_MATHML_ERROR;
   ProcessAttributes(aPresContext);
 
   auto borderPadding = aReflowInput.ComputedPhysicalBorderPadding();
diff --git a/layout/mathml/tests/chrome.toml b/layout/mathml/tests/chrome.toml
index ec3d54556e..f3c23766f1 100644
--- a/layout/mathml/tests/chrome.toml
+++ b/layout/mathml/tests/chrome.toml
@@ -1,6 +1,15 @@
+# WARNING: This directory was used for MathML mochitests and is only preserved
+# for the ones that cannot be rewritten as web-platform-tests.
+# If you want to add new tests for MathML, please instead consider adding them
+# to `testing/web-platform/tests/mathml` (for MathML Core tests) or to
+# `testing/web-platform/mozilla/tests/mathml/` (for Gecko-specific tests).
+
 [DEFAULT]
 
 support-files = ["test_disabled_chrome_iframe.html"]
 prefs = ["mathml.disabled=true"]
 
+# FIXME(bug 1847206): Rather than a chrome mochitest, this should probably be a
+# browser mochitest, because the goal was to check `mathml.disabled` doesn't
+# apply to the user interface.
 ["test_disabled_chrome.html"]
diff --git a/layout/painting/ActiveLayerTracker.cpp b/layout/painting/ActiveLayerTracker.cpp
index 053445e486..b30ecdf5c2 100644
--- a/layout/painting/ActiveLayerTracker.cpp
+++ b/layout/painting/ActiveLayerTracker.cpp
@@ -218,23 +218,47 @@ void ActiveLayerTracker::TransferActivityToFrame(nsIContent* aContent,
 
 static void IncrementScaleRestyleCountIfNeeded(nsIFrame* aFrame,
                                                LayerActivity* aActivity) {
+  // This function is basically a simplified copy of
+  // nsDisplayTransform::GetResultingTransformMatrixInternal.
+
+  Matrix svgTransform, parentsChildrenOnlyTransform;
+  const bool hasSVGTransforms =
+      aFrame->HasAnyStateBits(NS_FRAME_MAY_BE_TRANSFORMED) &&
+      aFrame->IsSVGTransformed(&svgTransform, &parentsChildrenOnlyTransform);
+
   const nsStyleDisplay* display = aFrame->StyleDisplay();
-  if (!display->HasTransformProperty() && !display->HasIndividualTransform() &&
-      display->mOffsetPath.IsNone()) {
-    // The transform was removed.
-    aActivity->mPreviousTransformScale = Nothing();
-    IncrementMutationCount(
-        &aActivity->mRestyleCounts[LayerActivity::ACTIVITY_SCALE]);
+  if (!aFrame->HasAnyStateBits(NS_FRAME_MAY_BE_TRANSFORMED) ||
+      (!display->HasTransformProperty() && !display->HasIndividualTransform() &&
+       display->mOffsetPath.IsNone() && !hasSVGTransforms)) {
+    if (aActivity->mPreviousTransformScale.isSome()) {
+      // The transform was removed.
+      aActivity->mPreviousTransformScale = Nothing();
+      IncrementMutationCount(
+          &aActivity->mRestyleCounts[LayerActivity::ACTIVITY_SCALE]);
+    }
+
     return;
   }
 
-  // Compute the new scale due to the CSS transform property.
-  // Note: Motion path doesn't contribute to scale factor. (It only has 2d
-  // translate and 2d rotate, so we use Nothing() for it.)
-  nsStyleTransformMatrix::TransformReferenceBox refBox(aFrame);
-  Matrix4x4 transform = nsStyleTransformMatrix::ReadTransforms(
-      display->mTranslate, display->mRotate, display->mScale, nullptr,
-      display->mTransform, refBox, AppUnitsPerCSSPixel());
+  Matrix4x4 transform;
+  if (aFrame->IsCSSTransformed()) {
+    // Compute the new scale due to the CSS transform property.
+    // Note: Motion path doesn't contribute to scale factor. (It only has 2d
+    // translate and 2d rotate, so we use Nothing() for it.)
+    nsStyleTransformMatrix::TransformReferenceBox refBox(aFrame);
+    transform = nsStyleTransformMatrix::ReadTransforms(
+        display->mTranslate, display->mRotate, display->mScale, nullptr,
+        display->mTransform, refBox, AppUnitsPerCSSPixel());
+  } else if (hasSVGTransforms) {
+    transform = Matrix4x4::From2D(svgTransform);
+  }
+
+  const bool parentHasChildrenOnlyTransform =
+      hasSVGTransforms && !parentsChildrenOnlyTransform.IsIdentity();
+  if (parentHasChildrenOnlyTransform) {
+    transform *= Matrix4x4::From2D(parentsChildrenOnlyTransform);
+  }
+
   Matrix transform2D;
   if (!transform.Is2D(&transform2D)) {
     // We don't attempt to handle 3D transforms; just assume the scale changed.
diff --git a/layout/painting/RetainedDisplayListBuilder.cpp b/layout/painting/RetainedDisplayListBuilder.cpp
index bb3a896b9a..ca8f37a252 100644
--- a/layout/painting/RetainedDisplayListBuilder.cpp
+++ b/layout/painting/RetainedDisplayListBuilder.cpp
@@ -523,6 +523,17 @@ class MergeState {
     // current ASR, which gets reset during RestoreState(), so we always need
     // to run it again.
     aOutItem->UpdateBounds(mBuilder->Builder());
+
+    if (aOutItem->GetType() == DisplayItemType::TYPE_TRANSFORM) {
+      MOZ_ASSERT(!aNewItem ||
+                 aNewItem->GetType() == DisplayItemType::TYPE_TRANSFORM);
+      MOZ_ASSERT(aOldItem->GetType() == DisplayItemType::TYPE_TRANSFORM);
+      static_cast(aOutItem)->SetContainsASRs(
+          static_cast(aOldItem)->GetContainsASRs() ||
+          (aNewItem
+               ? static_cast(aNewItem)->GetContainsASRs()
+               : false));
+    }
   }
 
   bool ShouldUseNewItem(nsDisplayItem* aNewItem) {
diff --git a/layout/painting/nsDisplayItemTypesList.h b/layout/painting/nsDisplayItemTypesList.h
index b3d4f14c4d..ecc107a20b 100644
--- a/layout/painting/nsDisplayItemTypesList.h
+++ b/layout/painting/nsDisplayItemTypesList.h
@@ -18,9 +18,6 @@ DECLARE_DISPLAY_ITEM_TYPE(BLEND_MODE,
 DECLARE_DISPLAY_ITEM_TYPE(BORDER, 0)
 DECLARE_DISPLAY_ITEM_TYPE(BOX_SHADOW_INNER, TYPE_RENDERS_NO_IMAGES)
 DECLARE_DISPLAY_ITEM_TYPE(BOX_SHADOW_OUTER, TYPE_RENDERS_NO_IMAGES)
-DECLARE_DISPLAY_ITEM_TYPE(BUTTON_BORDER_BACKGROUND, TYPE_IS_CONTENTFUL)
-DECLARE_DISPLAY_ITEM_TYPE(BUTTON_BOX_SHADOW_OUTER,
-                          TYPE_RENDERS_NO_IMAGES | TYPE_IS_CONTENTFUL)
 DECLARE_DISPLAY_ITEM_TYPE(BUTTON_FOREGROUND, TYPE_IS_CONTENTFUL)
 DECLARE_DISPLAY_ITEM_TYPE(CANVAS, TYPE_RENDERS_NO_IMAGES)
 DECLARE_DISPLAY_ITEM_TYPE(CANVAS_BACKGROUND_COLOR, TYPE_RENDERS_NO_IMAGES)
@@ -34,7 +31,6 @@ DECLARE_DISPLAY_ITEM_TYPE(CHECKED_CHECKBOX,
 DECLARE_DISPLAY_ITEM_TYPE(CHECKED_RADIOBUTTON,
                           TYPE_RENDERS_NO_IMAGES | TYPE_IS_CONTENTFUL)
 DECLARE_DISPLAY_ITEM_TYPE(COLUMN_RULE, TYPE_RENDERS_NO_IMAGES)
-DECLARE_DISPLAY_ITEM_TYPE(COMBOBOX_FOCUS, TYPE_RENDERS_NO_IMAGES)
 DECLARE_DISPLAY_ITEM_TYPE(COMPOSITOR_HITTEST_INFO, TYPE_RENDERS_NO_IMAGES)
 DECLARE_DISPLAY_ITEM_TYPE(CONTAINER, TYPE_RENDERS_NO_IMAGES | TYPE_IS_CONTAINER)
 DECLARE_DISPLAY_ITEM_TYPE(DESTINATION, TYPE_RENDERS_NO_IMAGES)
diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp
index 46f8b05f82..78388d2185 100644
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -868,6 +868,11 @@ void nsDisplayListBuilder::SetIsRelativeToLayoutViewport() {
   UpdateShouldBuildAsyncZoomContainer();
 }
 
+void nsDisplayListBuilder::ForceLayerForScrollParent() {
+  mForceLayerForScrollParent = true;
+  mNumActiveScrollframesEncountered++;
+}
+
 void nsDisplayListBuilder::UpdateShouldBuildAsyncZoomContainer() {
   const Document* document = mReferenceFrame->PresContext()->Document();
   mBuildAsyncZoomContainer = !mIsRelativeToLayoutViewport &&
@@ -5974,7 +5979,8 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
       mPrerenderDecision(PrerenderDecision::No),
       mIsTransformSeparator(true),
       mHasTransformGetter(false),
-      mHasAssociatedPerspective(false) {
+      mHasAssociatedPerspective(false),
+      mContainsASRs(false) {
   MOZ_COUNT_CTOR(nsDisplayTransform);
   MOZ_ASSERT(aFrame, "Must have a frame!");
   Init(aBuilder, aList);
@@ -5990,7 +5996,8 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
       mPrerenderDecision(aPrerenderDecision),
       mIsTransformSeparator(false),
       mHasTransformGetter(false),
-      mHasAssociatedPerspective(false) {
+      mHasAssociatedPerspective(false),
+      mContainsASRs(false) {
   MOZ_COUNT_CTOR(nsDisplayTransform);
   MOZ_ASSERT(aFrame, "Must have a frame!");
   SetReferenceFrameToAncestor(aBuilder);
@@ -6007,7 +6014,8 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
       mPrerenderDecision(PrerenderDecision::No),
       mIsTransformSeparator(false),
       mHasTransformGetter(true),
-      mHasAssociatedPerspective(false) {
+      mHasAssociatedPerspective(false),
+      mContainsASRs(false) {
   MOZ_COUNT_CTOR(nsDisplayTransform);
   MOZ_ASSERT(aFrame, "Must have a frame!");
   MOZ_ASSERT(aFrame->GetTransformGetter());
@@ -6194,6 +6202,9 @@ Matrix4x4 nsDisplayTransform::GetResultingTransformMatrixInternal(
   NS_ASSERTION(frame || !(aFlags & INCLUDE_PERSPECTIVE),
                "Must have a frame to compute perspective!");
 
+  // IncrementScaleRestyleCountIfNeeded in ActiveLayerTracker.cpp is a
+  // simplified copy of this function.
+
   // Get the underlying transform matrix:
 
   /* Get the matrix, then change its basis to factor in the origin. */
@@ -6637,12 +6648,12 @@ bool nsDisplayTransform::CreateWebRenderCommands(
                                key};
 
   nsDisplayTransform* deferredTransformItem = nullptr;
-  if (!mFrame->ChildrenHavePerspective()) {
+  if (ShouldDeferTransform()) {
     // If it has perspective, we create a new scroll data via the
-    // UpdateScrollData call because that scenario is more complex. Otherwise
-    // we can just stash the transform on the StackingContextHelper and
-    // apply it to any scroll data that are created inside this
-    // nsDisplayTransform.
+    // UpdateScrollData call because that scenario is more complex. Otherwise,
+    // if we don't contain any ASRs then just stash the transform on the
+    // StackingContextHelper and apply it to any scroll data that are created
+    // inside this nsDisplayTransform.
     deferredTransformItem = this;
   }
 
@@ -6693,14 +6704,14 @@ bool nsDisplayTransform::CreateWebRenderCommands(
 
 bool nsDisplayTransform::UpdateScrollData(
     WebRenderScrollData* aData, WebRenderLayerScrollData* aLayerData) {
-  if (!mFrame->ChildrenHavePerspective()) {
+  if (ShouldDeferTransform()) {
     // This case is handled in CreateWebRenderCommands by stashing the transform
     // on the stacking context.
     return false;
   }
   if (aLayerData) {
     aLayerData->SetTransform(GetTransform().GetMatrix());
-    aLayerData->SetTransformIsPerspective(true);
+    aLayerData->SetTransformIsPerspective(mFrame->ChildrenHavePerspective());
   }
   return true;
 }
diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h
index cf4eb1dd16..5064677cc7 100644
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -457,7 +457,10 @@ class nsDisplayListBuilder {
    * a displayport, and for scroll handoff to work properly the ancestor
    * scrollframes should also get their own scrollable layers.
    */
-  void ForceLayerForScrollParent() { mForceLayerForScrollParent = true; }
+  void ForceLayerForScrollParent();
+  uint32_t GetNumActiveScrollframesEncountered() const {
+    return mNumActiveScrollframesEncountered;
+  }
   /**
    * Set the flag that indicates there is a non-minimal display port in the
    * current subtree. This is used to determine display port expiry.
@@ -1848,6 +1851,8 @@ class nsDisplayListBuilder {
   nsDisplayListBuilderMode mMode;
   static uint32_t sPaintSequenceNumber;
 
+  uint32_t mNumActiveScrollframesEncountered = 0;
+
   bool mContainsBlendMode;
   bool mIsBuildingScrollbar;
   bool mCurrentScrollbarWillHaveLayer;
@@ -3570,7 +3575,7 @@ class RetainedDisplayList : public nsDisplayList {
     for (OldItemInfo& i : mOldItems) {
       if (i.mItem && i.mOwnsItem) {
         i.mItem->Destroy(aBuilder);
-        MOZ_ASSERT(!GetBottom(),
+        MOZ_ASSERT(!GetBottom() || aBuilder->PartialBuildFailed(),
                    "mOldItems should not be owning items if we also have items "
                    "in the normal list");
       }
@@ -6414,6 +6419,12 @@ class nsDisplayTransform : public nsPaintedDisplayItem {
 
   bool CreatesStackingContextHelper() override { return true; }
 
+  void SetContainsASRs(bool aContainsASRs) { mContainsASRs = aContainsASRs; }
+  bool GetContainsASRs() const { return mContainsASRs; }
+  bool ShouldDeferTransform() const {
+    return !mFrame->ChildrenHavePerspective() && !mContainsASRs;
+  }
+
  private:
   void ComputeBounds(nsDisplayListBuilder* aBuilder);
   nsRect TransformUntransformedBounds(nsDisplayListBuilder* aBuilder,
@@ -6459,6 +6470,7 @@ class nsDisplayTransform : public nsPaintedDisplayItem {
   // True if this item is created together with `nsDisplayPerspective`
   // from the same CSS stacking context.
   bool mHasAssociatedPerspective : 1;
+  bool mContainsASRs : 1;
 };
 
 /* A display item that applies a perspective transformation to a single
diff --git a/layout/reftests/abs-pos/reftest.list b/layout/reftests/abs-pos/reftest.list
index 3e5b85de9b..c595d14368 100644
--- a/layout/reftests/abs-pos/reftest.list
+++ b/layout/reftests/abs-pos/reftest.list
@@ -51,7 +51,7 @@ pref(layout.display-list.improve-fragmentation,true) == table-cell-8.html table-
 == continuation-positioned-inline-1.html continuation-positioned-inline-ref.html
 == continuation-positioned-inline-2.html continuation-positioned-inline-ref.html
 == scrollframe-1.html scrollframe-1-ref.html
-fuzzy-if(gtkWidget,0-1,0-1) fuzzy-if(Android,0-9,0-185) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-140,0-144) == scrollframe-2.html scrollframe-2-ref.html #bug 756530
+fuzzy-if(gtkWidget,0-1,0-1) fuzzy-if(Android,0-9,0-185) == scrollframe-2.html scrollframe-2-ref.html #bug 756530
 fuzzy-if(gtkWidget,0-1,0-8) fuzzy-if(Android,0-4,0-2) == select-1.html select-1-ref.html
 fuzzy-if(gtkWidget,0-1,0-8) fuzzy-if(Android,0-4,0-2) == select-1-dynamic.html select-1-ref.html
 == select-2.html select-2-ref.html
diff --git a/layout/reftests/async-scrolling/reftest.list b/layout/reftests/async-scrolling/reftest.list
index 2602ed541b..d74a1544b2 100644
--- a/layout/reftests/async-scrolling/reftest.list
+++ b/layout/reftests/async-scrolling/reftest.list
@@ -1,86 +1,86 @@
-skip-if(!asyncPan) == bg-fixed-1.html bg-fixed-1-ref.html
-skip-if(!asyncPan) == bg-fixed-cover-1.html bg-fixed-cover-1-ref.html
-skip-if(!asyncPan) == bg-fixed-cover-2.html bg-fixed-cover-2-ref.html
-skip-if(!asyncPan) == bg-fixed-cover-3.html bg-fixed-cover-3-ref.html
-skip-if(!asyncPan) == bg-fixed-child.html bg-fixed-child-ref.html
-skip-if(!asyncPan) == bg-fixed-child-clip-1.html bg-fixed-child-clip-ref.html
-skip-if(!asyncPan) == bg-fixed-child-clip-2.html bg-fixed-child-clip-ref.html
-skip-if(!asyncPan) fuzzy(0-1,0-87) == bg-fixed-child-mask.html bg-fixed-child-mask-ref.html
-skip-if(!asyncPan) == bg-fixed-in-opacity.html bg-fixed-in-opacity-ref.html
+skip-if(useDrawSnapshot) == bg-fixed-1.html bg-fixed-1-ref.html
+skip-if(useDrawSnapshot) == bg-fixed-cover-1.html bg-fixed-cover-1-ref.html
+skip-if(useDrawSnapshot) == bg-fixed-cover-2.html bg-fixed-cover-2-ref.html
+skip-if(useDrawSnapshot) == bg-fixed-cover-3.html bg-fixed-cover-3-ref.html
+skip-if(useDrawSnapshot) == bg-fixed-child.html bg-fixed-child-ref.html
+skip-if(useDrawSnapshot) == bg-fixed-child-clip-1.html bg-fixed-child-clip-ref.html
+skip-if(useDrawSnapshot) == bg-fixed-child-clip-2.html bg-fixed-child-clip-ref.html
+skip-if(useDrawSnapshot) fuzzy(0-1,0-87) == bg-fixed-child-mask.html bg-fixed-child-mask-ref.html
+skip-if(useDrawSnapshot) == bg-fixed-in-opacity.html bg-fixed-in-opacity-ref.html
 # Passing the test below without WebRender would require implementing CSS filters in the Gecko compositor.
-skip-if(!asyncPan) fuzzy-if(gtkWidget,0-1,0-87) fuzzy-if(!gtkWidget,0-1,0-3951) == bg-fixed-in-css-filter.html bg-fixed-in-css-filter-ref.html # bug 1454794 for webrender fuzziness
-skip-if(!asyncPan) == bg-fixed-child-no-culling-1.html bg-fixed-child-no-culling-1-ref.html
-skip-if(!asyncPan) == bg-fixed-child-no-culling-2.html bg-fixed-child-no-culling-2-ref.html
-skip-if(!asyncPan) == bg-fixed-child-no-culling-3.html bg-fixed-child-no-culling-3-ref.html
-fuzzy-if(Android,0-2,0-4000) fuzzy-if(browserIsRemote&&cocoaWidget,0-2,0-179524) fuzzy-if(browserIsRemote&&winWidget,0-1,0-74590) fuzzy-if(gtkWidget&&layersGPUAccelerated,0-1,0-3528) skip-if(!asyncPan) fuzzy-if(geckoview,0-1,0-74590) == bg-fixed-transformed-image.html bg-fixed-transformed-image-ref.html
-skip-if(!asyncPan) == contain-paint-scrollable-frame-1.html contain-paint-scrollable-frame-1-ref.html
-skip-if(!asyncPan) == element-1.html element-1-ref.html
-pref(layers.force-active,true) skip-if(!asyncPan) == iframe-1.html iframe-1-ref.html
-skip-if(!asyncPan) == nested-1.html nested-1-ref.html
-skip-if(!asyncPan) == nested-2.html nested-2-ref.html
-skip-if(!asyncPan) == position-fixed-1.html position-fixed-1-ref.html
-skip-if(!asyncPan) == position-fixed-2.html position-fixed-2-ref.html
-fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-3120) skip-if(!asyncPan) == position-fixed-body.html position-fixed-body-ref.html
-skip-if(!asyncPan) == position-fixed-cover-1.html position-fixed-cover-1-ref.html
-skip-if(!asyncPan) == position-fixed-cover-2.html position-fixed-cover-2-ref.html
-skip-if(!asyncPan) == position-fixed-cover-3.html position-fixed-cover-3-ref.html
-fuzzy-if(Android,0-15,0-11) fuzzy-if(gtkWidget,20-33,14-32) fuzzy-if(cocoaWidget,9-21,20-44) skip-if(!asyncPan) == position-fixed-transformed-1.html position-fixed-transformed-1-ref.html # Bug 1604338
-skip-if(!asyncPan) == split-layers-1.html split-layers-1-ref.html
-skip-if(!asyncPan) == split-layers-multi-scrolling-1.html split-layers-multi-scrolling-1-ref.html
-fuzzy(0-2,0-240000) skip-if(!asyncPan) == split-opacity-layers-1.html split-opacity-layers-1-ref.html
-skip-if(!asyncPan) fuzzy-if(appleSilicon,0-1,0-8) == sticky-pos-scrollable-1.html sticky-pos-scrollable-1-ref.html
-skip-if(!asyncPan) == sticky-pos-scrollable-2.html sticky-pos-scrollable-2-ref.html
-skip-if(!asyncPan) == sticky-pos-scrollable-3.html sticky-pos-scrollable-3-ref.html
-skip-if(!asyncPan) == sticky-pos-scrollable-4.html sticky-pos-scrollable-4-ref.html
-skip-if(!asyncPan) == sticky-pos-scrollable-5.html sticky-pos-scrollable-5-ref.html
-skip-if(!asyncPan) == sticky-pos-scrollable-6.html sticky-pos-scrollable-6-ref.html
-skip-if(!asyncPan) fuzzy-if(appleSilicon,0-1,0-8) == sticky-pos-scrollable-7.html sticky-pos-scrollable-7-ref.html
-skip-if(!asyncPan) fuzzy(0-2,0-2) fuzzy-if(gtkWidget,0-1,0-4) fuzzy-if(winWidget,0-1,0-51) fuzzy-if(appleSilicon,0-1,0-8) == fixed-pos-scrollable-1.html fixed-pos-scrollable-1-ref.html
-skip-if(!asyncPan) == culling-1.html culling-1-ref.html
-skip-if(!asyncPan) == position-fixed-iframe-1.html position-fixed-iframe-1-ref.html
-skip-if(!asyncPan) == position-fixed-iframe-2.html position-fixed-iframe-2-ref.html
-fuzzy(0-1,0-11300) skip-if(!asyncPan) == position-fixed-in-scroll-container.html position-fixed-in-scroll-container-ref.html
-fuzzy(0-1,0-400) skip-if(!asyncPan) == position-fixed-inside-clip-path.html position-fixed-inside-clip-path-ref.html
-skip-if(!asyncPan) == position-fixed-inside-sticky-1.html position-fixed-inside-sticky-1-ref.html
-skip-if(!asyncPan) == position-fixed-inside-sticky-2.html position-fixed-inside-sticky-2-ref.html
-skip-if(!asyncPan) == position-fixed-inside-sticky-3.html position-fixed-inside-sticky-3-ref.html
-skip-if(!asyncPan) == sticky-inside-fixed-1.html sticky-inside-fixed-1-ref.html
-skip-if(!asyncPan) == sticky-inside-transform-1.html sticky-inside-transform-1-ref.html
-fuzzy(0-1,0-60000) skip-if(!asyncPan) == group-opacity-surface-size-1.html group-opacity-surface-size-1-ref.html
-fuzzy(0-55,0-295) skip-if(!asyncPan) == position-sticky-transformed.html position-sticky-transformed-ref.html
-skip-if(!asyncPan) fuzzy-if(cocoaWidget,0-1,0-396) fuzzy-if(winWidget,0-1,0-396) == offscreen-prerendered-active-opacity.html offscreen-prerendered-active-opacity-ref.html
-fuzzy-if(Android,0-43,0-40) fuzzy-if(!Android,0-1,0-34) fuzzy-if(gtkWidget,22-74,20-32) fuzzy-if(cocoaWidget,6-7,18-39) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-7,0-39) skip-if(!asyncPan) == offscreen-clipped-blendmode-1.html offscreen-clipped-blendmode-ref.html # Bug 1604338
-fuzzy-if(Android,0-43,0-40) fuzzy-if(gtkWidget,22-74,20-32) fuzzy-if(cocoaWidget,6-7,18-39) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-7,0-39) skip-if(!asyncPan) == offscreen-clipped-blendmode-2.html offscreen-clipped-blendmode-ref.html # Bug 1604338
+skip-if(useDrawSnapshot) fuzzy-if(gtkWidget,0-1,0-87) fuzzy-if(!gtkWidget,0-1,0-3951) == bg-fixed-in-css-filter.html bg-fixed-in-css-filter-ref.html # bug 1454794 for webrender fuzziness
+skip-if(useDrawSnapshot) == bg-fixed-child-no-culling-1.html bg-fixed-child-no-culling-1-ref.html
+skip-if(useDrawSnapshot) == bg-fixed-child-no-culling-2.html bg-fixed-child-no-culling-2-ref.html
+skip-if(useDrawSnapshot) == bg-fixed-child-no-culling-3.html bg-fixed-child-no-culling-3-ref.html
+fuzzy-if(Android,0-2,0-4000) fuzzy-if(cocoaWidget,0-2,0-179524) fuzzy-if(winWidget,0-1,0-74590) fuzzy-if(gtkWidget&&layersGPUAccelerated,0-1,0-3528) skip-if(useDrawSnapshot) fuzzy-if(geckoview,0-1,0-74590) == bg-fixed-transformed-image.html bg-fixed-transformed-image-ref.html
+skip-if(useDrawSnapshot) == contain-paint-scrollable-frame-1.html contain-paint-scrollable-frame-1-ref.html
+skip-if(useDrawSnapshot) == element-1.html element-1-ref.html
+pref(layers.force-active,true) skip-if(useDrawSnapshot) == iframe-1.html iframe-1-ref.html
+skip-if(useDrawSnapshot) == nested-1.html nested-1-ref.html
+skip-if(useDrawSnapshot) == nested-2.html nested-2-ref.html
+skip-if(useDrawSnapshot) == position-fixed-1.html position-fixed-1-ref.html
+skip-if(useDrawSnapshot) == position-fixed-2.html position-fixed-2-ref.html
+fuzzy-if(winWidget,0-1,0-3120) skip-if(useDrawSnapshot) == position-fixed-body.html position-fixed-body-ref.html
+skip-if(useDrawSnapshot) == position-fixed-cover-1.html position-fixed-cover-1-ref.html
+skip-if(useDrawSnapshot) == position-fixed-cover-2.html position-fixed-cover-2-ref.html
+skip-if(useDrawSnapshot) == position-fixed-cover-3.html position-fixed-cover-3-ref.html
+fuzzy-if(Android,0-15,0-11) fuzzy-if(gtkWidget,20-33,14-32) fuzzy-if(cocoaWidget,9-21,20-44) skip-if(useDrawSnapshot) == position-fixed-transformed-1.html position-fixed-transformed-1-ref.html # Bug 1604338
+skip-if(useDrawSnapshot) == split-layers-1.html split-layers-1-ref.html
+skip-if(useDrawSnapshot) == split-layers-multi-scrolling-1.html split-layers-multi-scrolling-1-ref.html
+fuzzy(0-2,0-240000) skip-if(useDrawSnapshot) == split-opacity-layers-1.html split-opacity-layers-1-ref.html
+skip-if(useDrawSnapshot) fuzzy-if(appleSilicon,0-1,0-8) == sticky-pos-scrollable-1.html sticky-pos-scrollable-1-ref.html
+skip-if(useDrawSnapshot) == sticky-pos-scrollable-2.html sticky-pos-scrollable-2-ref.html
+skip-if(useDrawSnapshot) == sticky-pos-scrollable-3.html sticky-pos-scrollable-3-ref.html
+skip-if(useDrawSnapshot) == sticky-pos-scrollable-4.html sticky-pos-scrollable-4-ref.html
+skip-if(useDrawSnapshot) == sticky-pos-scrollable-5.html sticky-pos-scrollable-5-ref.html
+skip-if(useDrawSnapshot) == sticky-pos-scrollable-6.html sticky-pos-scrollable-6-ref.html
+skip-if(useDrawSnapshot) fuzzy-if(appleSilicon,0-1,0-8) == sticky-pos-scrollable-7.html sticky-pos-scrollable-7-ref.html
+skip-if(useDrawSnapshot) fuzzy(0-2,0-2) fuzzy-if(gtkWidget,0-1,0-4) fuzzy-if(winWidget,0-1,0-51) fuzzy-if(appleSilicon,0-1,0-8) == fixed-pos-scrollable-1.html fixed-pos-scrollable-1-ref.html
+skip-if(useDrawSnapshot) == culling-1.html culling-1-ref.html
+skip-if(useDrawSnapshot) == position-fixed-iframe-1.html position-fixed-iframe-1-ref.html
+skip-if(useDrawSnapshot) == position-fixed-iframe-2.html position-fixed-iframe-2-ref.html
+fuzzy(0-1,0-11300) skip-if(useDrawSnapshot) == position-fixed-in-scroll-container.html position-fixed-in-scroll-container-ref.html
+fuzzy(0-1,0-400) skip-if(useDrawSnapshot) == position-fixed-inside-clip-path.html position-fixed-inside-clip-path-ref.html
+skip-if(useDrawSnapshot) == position-fixed-inside-sticky-1.html position-fixed-inside-sticky-1-ref.html
+skip-if(useDrawSnapshot) == position-fixed-inside-sticky-2.html position-fixed-inside-sticky-2-ref.html
+skip-if(useDrawSnapshot) == position-fixed-inside-sticky-3.html position-fixed-inside-sticky-3-ref.html
+skip-if(useDrawSnapshot) == sticky-inside-fixed-1.html sticky-inside-fixed-1-ref.html
+skip-if(useDrawSnapshot) == sticky-inside-transform-1.html sticky-inside-transform-1-ref.html
+fuzzy(0-1,0-60000) skip-if(useDrawSnapshot) == group-opacity-surface-size-1.html group-opacity-surface-size-1-ref.html
+fuzzy(0-55,0-295) skip-if(useDrawSnapshot) == position-sticky-transformed.html position-sticky-transformed-ref.html
+skip-if(useDrawSnapshot) fuzzy-if(cocoaWidget,0-1,0-396) fuzzy-if(winWidget,0-1,0-396) == offscreen-prerendered-active-opacity.html offscreen-prerendered-active-opacity-ref.html
+fuzzy-if(Android,0-43,0-40) fuzzy-if(!Android,0-1,0-34) fuzzy-if(gtkWidget,22-74,20-32) fuzzy-if(cocoaWidget,6-7,18-39) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-7,0-39) skip-if(useDrawSnapshot) == offscreen-clipped-blendmode-1.html offscreen-clipped-blendmode-ref.html # Bug 1604338
+fuzzy-if(Android,0-43,0-40) fuzzy-if(gtkWidget,22-74,20-32) fuzzy-if(cocoaWidget,6-7,18-39) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-7,0-39) skip-if(useDrawSnapshot) == offscreen-clipped-blendmode-2.html offscreen-clipped-blendmode-ref.html # Bug 1604338
 fuzzy-if(Android,0-43,0-40) skip == offscreen-clipped-blendmode-3.html offscreen-clipped-blendmode-ref.html # bug 1251588 - wrong AGR on mix-blend-mode item
-fuzzy-if(Android,0-43,0-40) fuzzy-if(gtkWidget,22-74,20-32) fuzzy-if(cocoaWidget,6-7,18-39) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-7,0-39) skip-if(!asyncPan) == offscreen-clipped-blendmode-4.html offscreen-clipped-blendmode-ref.html # Bug 1604338
-fuzzy-if(Android,0-7,0-1680) fuzzy-if(gtkWidget,1-1,2-20) fuzzy-if(cocoaWidget,1-2,10-18) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-2,0-18) skip-if(!asyncPan) == perspective-scrolling-1.html perspective-scrolling-1-ref.html # Bug 1604338
-fuzzy-if(Android,0-7,0-4) skip-if(!asyncPan) == perspective-scrolling-2.html perspective-scrolling-2-ref.html
-fuzzy-if(Android,0-19,0-10) fuzzy-if(gtkWidget,8-13,12-32) fuzzy-if(cocoaWidget,10-13,20-44) skip-if(!asyncPan) == perspective-scrolling-3.html perspective-scrolling-3-ref.html # Bug 1604338
-fuzzy-if(Android,0-14,0-11) fuzzy-if(gtkWidget,18-30,14-32) fuzzy-if(cocoaWidget,16-20,20-44) skip-if(!asyncPan) == perspective-scrolling-4.html perspective-scrolling-4-ref.html # Bug 1604338
-skip-if(!asyncPan) == perspective-scrolling-5.html perspective-scrolling-5-ref.html
-pref(apz.disable_for_scroll_linked_effects,true) skip-if(!asyncPan) == disable-apz-for-sle-pages.html disable-apz-for-sle-pages-ref.html
-fuzzy-if(browserIsRemote&&d2d,0-1,0-22) skip-if(!asyncPan) fuzzy-if(swgl,0-255,0-11) == background-blend-mode-1.html background-blend-mode-1-ref.html
-skip-if(Android||!asyncPan) != opaque-fractional-displayport-1.html about:blank
-skip-if(Android||!asyncPan) != opaque-fractional-displayport-2.html about:blank
-fuzzy-if(Android,0-19,0-10) fuzzy-if(gtkWidget,12-19,12-32) fuzzy-if(cocoaWidget,17-21,20-44) skip-if(!asyncPan) == fixed-pos-scrolled-clip-1.html fixed-pos-scrolled-clip-1-ref.html # Bug 1604338
-fuzzy-if(Android,0-44,0-136) fuzzy-if(gtkWidget,16-26,26-64) fuzzy-if(cocoaWidget,10-13,38-82) fuzzy-if(winWidget,0-4,0-36) skip-if(!asyncPan) == fixed-pos-scrolled-clip-2.html fixed-pos-scrolled-clip-2-ref.html # Bug 1604338
-fuzzy-if(Android,0-13,0-465) fuzzy-if(gtkWidget,17-28,24-60) fuzzy-if(cocoaWidget,15-19,40-75) skip-if(!asyncPan) == fixed-pos-scrolled-clip-3.html fixed-pos-scrolled-clip-3-ref.html # Bug 1604338
-fuzzy-if(Android,0-13,0-465) fuzzy-if(gtkWidget,17-29,24-60) fuzzy-if(cocoaWidget,15-19,40-75) skip-if(!asyncPan) == fixed-pos-scrolled-clip-4.html fixed-pos-scrolled-clip-4-ref.html # Bug 1604338
-skip-if(!asyncPan) == fixed-pos-scrolled-clip-5.html fixed-pos-scrolled-clip-5-ref.html
-skip-if(!asyncPan) == position-sticky-bug1434250.html position-sticky-bug1434250-ref.html
-fuzzy-if(Android,0-12,0-11) fuzzy-if(gtkWidget,16-25,12-32) fuzzy-if(cocoaWidget,13-16,20-44) skip-if(!asyncPan) == position-sticky-scrolled-clip-1.html position-sticky-scrolled-clip-1-ref.html # Bug 1604338
+fuzzy-if(Android,0-43,0-40) fuzzy-if(gtkWidget,22-74,20-32) fuzzy-if(cocoaWidget,6-7,18-39) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-7,0-39) skip-if(useDrawSnapshot) == offscreen-clipped-blendmode-4.html offscreen-clipped-blendmode-ref.html # Bug 1604338
+fuzzy-if(Android,0-7,0-1680) fuzzy-if(gtkWidget,1-1,2-20) fuzzy-if(cocoaWidget,1-2,10-18) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-2,0-18) skip-if(useDrawSnapshot) == perspective-scrolling-1.html perspective-scrolling-1-ref.html # Bug 1604338
+fuzzy-if(Android,0-7,0-4) skip-if(useDrawSnapshot) == perspective-scrolling-2.html perspective-scrolling-2-ref.html
+fuzzy-if(Android,0-19,0-10) fuzzy-if(gtkWidget,8-13,12-32) fuzzy-if(cocoaWidget,10-13,20-44) skip-if(useDrawSnapshot) == perspective-scrolling-3.html perspective-scrolling-3-ref.html # Bug 1604338
+fuzzy-if(Android,0-14,0-11) fuzzy-if(gtkWidget,18-30,14-32) fuzzy-if(cocoaWidget,16-20,20-44) skip-if(useDrawSnapshot) == perspective-scrolling-4.html perspective-scrolling-4-ref.html # Bug 1604338
+skip-if(useDrawSnapshot) == perspective-scrolling-5.html perspective-scrolling-5-ref.html
+pref(apz.disable_for_scroll_linked_effects,true) skip-if(useDrawSnapshot) == disable-apz-for-sle-pages.html disable-apz-for-sle-pages-ref.html
+fuzzy-if(winWidget,0-1,0-22) skip-if(useDrawSnapshot) fuzzy-if(swgl,0-255,0-11) == background-blend-mode-1.html background-blend-mode-1-ref.html
+skip-if(Android||useDrawSnapshot) != opaque-fractional-displayport-1.html about:blank
+skip-if(Android||useDrawSnapshot) != opaque-fractional-displayport-2.html about:blank
+fuzzy-if(Android,0-19,0-10) fuzzy-if(gtkWidget,12-19,12-32) fuzzy-if(cocoaWidget,17-21,20-44) skip-if(useDrawSnapshot) == fixed-pos-scrolled-clip-1.html fixed-pos-scrolled-clip-1-ref.html # Bug 1604338
+fuzzy-if(Android,0-44,0-136) fuzzy-if(gtkWidget,16-26,26-64) fuzzy-if(cocoaWidget,10-13,38-82) fuzzy-if(winWidget,0-4,0-36) skip-if(useDrawSnapshot) == fixed-pos-scrolled-clip-2.html fixed-pos-scrolled-clip-2-ref.html # Bug 1604338
+fuzzy-if(Android,0-13,0-465) fuzzy-if(gtkWidget,17-28,24-60) fuzzy-if(cocoaWidget,15-19,40-75) skip-if(useDrawSnapshot) == fixed-pos-scrolled-clip-3.html fixed-pos-scrolled-clip-3-ref.html # Bug 1604338
+fuzzy-if(Android,0-13,0-465) fuzzy-if(gtkWidget,17-29,24-60) fuzzy-if(cocoaWidget,15-19,40-75) skip-if(useDrawSnapshot) == fixed-pos-scrolled-clip-4.html fixed-pos-scrolled-clip-4-ref.html # Bug 1604338
+skip-if(useDrawSnapshot) == fixed-pos-scrolled-clip-5.html fixed-pos-scrolled-clip-5-ref.html
+skip-if(useDrawSnapshot) == position-sticky-bug1434250.html position-sticky-bug1434250-ref.html
+fuzzy-if(Android,0-12,0-11) fuzzy-if(gtkWidget,16-25,12-32) fuzzy-if(cocoaWidget,13-16,20-44) skip-if(useDrawSnapshot) == position-sticky-scrolled-clip-1.html position-sticky-scrolled-clip-1-ref.html # Bug 1604338
 fuzzy-if(Android,0-6,0-4) skip == position-sticky-scrolled-clip-2.html position-sticky-scrolled-clip-2-ref.html # bug ?????? - incorrectly applying clip to sticky contents
-fuzzy-if(Android,0-8,0-27) fuzzy-if(cocoaWidget,9-11,20-44) skip-if(!asyncPan) == curtain-effect-1.html curtain-effect-1-ref.html
-fuzzy-if(Android,0-7,0-9) fuzzy-if(gtkWidget,10-15,12-32) fuzzy-if(cocoaWidget,5-9,20-42) skip-if(!asyncPan) == transformed-1.html transformed-1-ref.html # Bug 1604338
-fuzzy-if(Android,2-7,1-12) fuzzy-if(gtkWidget,3-5,12-28) fuzzy-if(cocoaWidget,5-6,18-38) skip-if(!asyncPan) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-6,0-38) == position-sticky-transformed-in-scrollframe-1.html position-sticky-transformed-in-scrollframe-1-ref.html # Bug 1604338
-fuzzy-if(Android,3-3,1-470) fuzzy-if(Android&&swgl&&isDebugBuild&&/^aarch64-gcc3/.test(xulRuntime.XPCOMABI),3-3,457-457) fuzzy-if(gtkWidget,13-20,12-32) fuzzy-if(cocoaWidget,12-16,20-44) skip-if(!asyncPan) == position-sticky-transformed-in-scrollframe-2.html position-sticky-transformed-in-scrollframe-2-ref.html # Bug 1604338
-fuzzy-if(Android,12-13,4-31) fuzzy-if(gtkWidget,16-27,14-32) fuzzy-if(cocoaWidget,13-16,20-44) skip-if(!asyncPan) == position-sticky-in-transformed-scrollframe-1.html position-sticky-in-transformed-scrollframe-ref.html # Bug 1604338
-fuzzy-if(Android,12-13,4-31) fuzzy-if(gtkWidget,16-27,14-32) fuzzy-if(cocoaWidget,13-16,20-44) skip-if(!asyncPan) == position-sticky-in-transformed-scrollframe-2.html position-sticky-in-transformed-scrollframe-ref.html # Bug 1604338
+fuzzy-if(Android,0-8,0-27) fuzzy-if(cocoaWidget,9-11,20-44) skip-if(useDrawSnapshot) == curtain-effect-1.html curtain-effect-1-ref.html
+fuzzy-if(Android,0-7,0-9) fuzzy-if(gtkWidget,10-15,12-32) fuzzy-if(cocoaWidget,5-9,20-42) skip-if(useDrawSnapshot) == transformed-1.html transformed-1-ref.html # Bug 1604338
+fuzzy-if(Android,2-7,1-12) fuzzy-if(gtkWidget,3-5,12-28) fuzzy-if(cocoaWidget,5-6,18-38) skip-if(useDrawSnapshot) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-6,0-38) == position-sticky-transformed-in-scrollframe-1.html position-sticky-transformed-in-scrollframe-1-ref.html # Bug 1604338
+fuzzy-if(Android,3-3,1-470) fuzzy-if(Android&&swgl&&isDebugBuild&&/^aarch64-gcc3/.test(xulRuntime.XPCOMABI),3-3,457-457) fuzzy-if(gtkWidget,13-20,12-32) fuzzy-if(cocoaWidget,12-16,20-44) skip-if(useDrawSnapshot) == position-sticky-transformed-in-scrollframe-2.html position-sticky-transformed-in-scrollframe-2-ref.html # Bug 1604338
+fuzzy-if(Android,12-13,4-31) fuzzy-if(gtkWidget,16-27,14-32) fuzzy-if(cocoaWidget,13-16,20-44) skip-if(useDrawSnapshot) == position-sticky-in-transformed-scrollframe-1.html position-sticky-in-transformed-scrollframe-ref.html # Bug 1604338
+fuzzy-if(Android,12-13,4-31) fuzzy-if(gtkWidget,16-27,14-32) fuzzy-if(cocoaWidget,13-16,20-44) skip-if(useDrawSnapshot) == position-sticky-in-transformed-scrollframe-2.html position-sticky-in-transformed-scrollframe-ref.html # Bug 1604338
 
-skip-if(!asyncPan) == checkerboard-1.html checkerboard-1-ref.html
-skip-if(!asyncPan) == checkerboard-2.html checkerboard-2-ref.html
-skip-if(!asyncPan) == checkerboard-3.html checkerboard-3-ref.html
-skip-if(!asyncPan) == position-sticky-in-checkerboard-land-1.html position-sticky-in-checkerboard-land-1-ref.html
+skip-if(useDrawSnapshot) == checkerboard-1.html checkerboard-1-ref.html
+skip-if(useDrawSnapshot) == checkerboard-2.html checkerboard-2-ref.html
+skip-if(useDrawSnapshot) == checkerboard-3.html checkerboard-3-ref.html
+skip-if(useDrawSnapshot) == position-sticky-in-checkerboard-land-1.html position-sticky-in-checkerboard-land-1-ref.html
 
 skip-if(!Android) pref(apz.allow_zooming,true) == position-fixed-async-zoom-1.html position-fixed-async-zoom-1-ref.html
 skip-if(!Android) pref(apz.allow_zooming,true) == position-fixed-async-zoom-2.html position-fixed-async-zoom-2-ref.html
@@ -92,16 +92,16 @@ skip-if(!Android) pref(apz.allow_zooming,true) == position-sticky-async-zoom-2.h
 pref(apz.allow_zooming,true) == async-scroll-and-zoom.html async-scroll-and-zoom-ref.html
 
 # on Android we have a different overscroll effect so this test is disabled
-skip-if(!asyncPan||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll.html overscroll-ref.html
-skip-if(!asyncPan||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-subframe.html overscroll-ref.html
-skip-if(!asyncPan||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-fixed.html no-overscroll-ref.html
-skip-if(!asyncPan||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-fixed-transform.html overscroll-ref.html
-skip-if(!asyncPan||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-fixed-iframe.html overscroll-ref.html
-skip-if(!asyncPan||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-fixed-iframe-overscroll.html no-overscroll-ref.html
+skip-if(useDrawSnapshot||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll.html overscroll-ref.html
+skip-if(useDrawSnapshot||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-subframe.html overscroll-ref.html
+skip-if(useDrawSnapshot||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-fixed.html no-overscroll-ref.html
+skip-if(useDrawSnapshot||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-fixed-transform.html overscroll-ref.html
+skip-if(useDrawSnapshot||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-fixed-iframe.html overscroll-ref.html
+skip-if(useDrawSnapshot||Android) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-fixed-iframe-overscroll.html no-overscroll-ref.html
 # This one needs to be fuzzed due to the fact that squishing a scrollbar
 # thumb on the compositor doesn't preserve its shape exactly.
-skip-if(!asyncPan||Android) fuzzy(0-56,0-33) fuzzy-if(winWidget,0-107,0-17) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-scrollbar.html overscroll-scrollbar-ref.html
-skip-if(!asyncPan||Android) pref(apz.overscroll.enabled,false) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-disabled.html no-overscroll-ref.html
+skip-if(useDrawSnapshot||Android) fuzzy(0-56,0-33) fuzzy-if(winWidget,0-107,0-17) pref(apz.overscroll.enabled,true) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-scrollbar.html overscroll-scrollbar-ref.html
+skip-if(useDrawSnapshot||Android) pref(apz.overscroll.enabled,false) pref(apz.overscroll.test_async_scroll_offset.enabled,true) == overscroll-disabled.html no-overscroll-ref.html
 
 # for this test, apz.allow_zooming is needed to ensure we take the containerless scrolling codepath that creates
 # an async zoom container (since we are testing a regression in that codepath)
diff --git a/layout/reftests/backgrounds/reftest.list b/layout/reftests/backgrounds/reftest.list
index 1be6e54d53..3370e98006 100644
--- a/layout/reftests/backgrounds/reftest.list
+++ b/layout/reftests/backgrounds/reftest.list
@@ -97,7 +97,7 @@ fails-if(useDrawSnapshot) == background-size-zoom-no-repeat.html background-size
 == background-size-contain-clip-padding-origin-border-padding.html background-size-contain-clip-padding-origin-border-padding-ref.html
 
 == background-layers-1a.html background-layers-1-ref.html
-fuzzy-if(OSX,0-1,0-324) == background-layers-1b.html background-layers-1-ref.html
+fuzzy-if(cocoaWidget,0-1,0-324) == background-layers-1b.html background-layers-1-ref.html
 
 # box-decoration-break's effect on backgrounds is touchy and hard to test due to stretching
 # artifacts and the difficulty of covering exact lines, so just make sure
diff --git a/layout/reftests/bidi/dirAuto/1103348-1-ref.html b/layout/reftests/bidi/dirAuto/1103348-1-ref.html
deleted file mode 100644
index 50fba8c41d..0000000000
--- a/layout/reftests/bidi/dirAuto/1103348-1-ref.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-  
-    
-    Dynamic changes and dir=auto
-  
-  
-    
Test for elements with dir="auto" whose content changes between directional and neutral
-
xyz
-
ابج
-
456
-
xyz
-
ابج
-
456
-
xyz
-
ابج
-
456
- - diff --git a/layout/reftests/bidi/dirAuto/1103348-1.html b/layout/reftests/bidi/dirAuto/1103348-1.html deleted file mode 100644 index 4092f27f87..0000000000 --- a/layout/reftests/bidi/dirAuto/1103348-1.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - Dynamic changes and dir=auto - - -
Test for elements with dir="auto" whose content changes between directional and neutral
-
abc
-
abc
-
abc
-
אבג
-
אבג
-
אבג
-
123
-
123
-
123
- - - diff --git a/layout/reftests/bidi/dirAuto/reftest.list b/layout/reftests/bidi/dirAuto/reftest.list index 14ce0aa670..f47c635124 100644 --- a/layout/reftests/bidi/dirAuto/reftest.list +++ b/layout/reftests/bidi/dirAuto/reftest.list @@ -112,7 +112,6 @@ fuzzy-if(Android,0-3,0-2) == dynamicDirAuto-DeleteText-LTR3.html dynamicDirAuto- == 839886-1.html 839886-1-ref.html == 859093-1.html 859093-1-ref.html == 889742-1.html 889742-1-ref.html -== 1103348-1.html 1103348-1-ref.html == 1169267-delete-add-1a.html 1169267-delete-add-1-ref.html == 1169267-delete-add-1b.html 1169267-delete-add-1-ref.html == 1169267-delete-add-2a.html 1169267-delete-add-2-ref.html diff --git a/layout/reftests/bidi/numeral/reftest.list b/layout/reftests/bidi/numeral/reftest.list index c32d92c866..5e0b101eba 100644 --- a/layout/reftests/bidi/numeral/reftest.list +++ b/layout/reftests/bidi/numeral/reftest.list @@ -34,9 +34,9 @@ pref(bidi.numeral,2) == bug441782-2.html bug441782-2-ref.html pref(bidi.numeral,3) == bug441782-2.html bug441782-2-ref.html pref(bidi.numeral,4) == bug441782-2.html bug441782-2-ref.html pref(bidi.numeral,0) != bug441782-3.html bug441782-3-ref.html -fuzzy-if(winWidget&&!d2d&&d3d11,0-13,0-1) pref(bidi.numeral,1) == bug441782-3.html bug441782-3-ref.html -fuzzy-if(winWidget&&!d2d&&d3d11,0-13,0-1) pref(bidi.numeral,2) == bug441782-3.html bug441782-3-ref.html -fuzzy-if(winWidget&&!d2d&&d3d11,0-13,0-1) pref(bidi.numeral,3) == bug441782-3.html bug441782-3-ref.html +pref(bidi.numeral,1) == bug441782-3.html bug441782-3-ref.html +pref(bidi.numeral,2) == bug441782-3.html bug441782-3-ref.html +pref(bidi.numeral,3) == bug441782-3.html bug441782-3-ref.html pref(bidi.numeral,4) == bug441782-3.html bug441782-3-ref.html pref(bidi.numeral,0) != bug441782-4.html bug441782-4-ref.html pref(bidi.numeral,1) == bug441782-4.html bug441782-4-ref.html diff --git a/layout/reftests/bidi/reftest.list b/layout/reftests/bidi/reftest.list index 4916028c89..c9e77cd88a 100644 --- a/layout/reftests/bidi/reftest.list +++ b/layout/reftests/bidi/reftest.list @@ -18,8 +18,8 @@ fuzzy-if(Android,0-253,0-77) == bidiSVG-03.svg bidiSVG-03-ref.svg fuzzy(0-1,0-1) fuzzy-if(winWidget,0-1,0-2) == bidiSVG-04.svg bidiSVG-04-ref.svg == bidiSVG-05.svg bidiSVG-05-ref.svg == bidiMirroring.svg bidiMirroring-ref.svg # Bug 1392106 -fuzzy-if(Android,0-9,0-134) random-if(layersGPUAccelerated) == visualmarquee.html marquee-ref.html -fuzzy-if(Android,0-9,0-134) random-if(layersGPUAccelerated) == logicalmarquee.html marquee-ref.html +fuzzy-if(Android,0-9,0-134) random == visualmarquee.html marquee-ref.html +fuzzy-if(Android,0-9,0-134) random == logicalmarquee.html marquee-ref.html == visualmarquee.html logicalmarquee.html # test for glyph mirroring in right-to-left text == mirroring-01.html mirroring-01-ref.html @@ -144,7 +144,7 @@ fuzzy(0-1,0-3) == 698291-1.html 698291-1-ref.html == 847242-1.html 847242-1-ref.html # Skip on Android because this is a test and we don't have the requisite XUL on Android. -skip-if(Android) fuzzy(0-92,0-350) fuzzy-if(xulRuntime.widgetToolkit=="gtk",0-1,0-11) == chrome://reftest/content/bidi/869833-1.xhtml chrome://reftest/content/bidi/869833-1-ref.xhtml +skip-if(Android) fuzzy(0-92,0-350) fuzzy-if(gtkWidget,0-1,0-11) == chrome://reftest/content/bidi/869833-1.xhtml chrome://reftest/content/bidi/869833-1-ref.xhtml == 922530-1.html 922530-1-ref.html == 922550-1.html 922550-1-ref.html # Bug 1392106 diff --git a/layout/reftests/border-image/reftest.list b/layout/reftests/border-image/reftest.list index 677d7c65ec..6938d9717c 100644 --- a/layout/reftests/border-image/reftest.list +++ b/layout/reftests/border-image/reftest.list @@ -36,7 +36,7 @@ fuzzy-if(useDrawSnapshot,35-35,5220-5220) == center-scaling-3.html center-scalin == border-image-outset-1c.html border-image-outset-1-ref.html == border-image-nofill-1.html border-image-nofill-1-ref.html == border-image-outset-resize-1.html border-image-outset-resize-1-ref.html -fuzzy-if(asyncPan&&!layersGPUAccelerated,0-140,0-514) fuzzy-if(winWidget,0-144,0-448) == border-image-outset-move-1.html border-image-outset-move-1-ref.html +fuzzy-if(winWidget,0-144,0-448) == border-image-outset-move-1.html border-image-outset-move-1-ref.html == border-image-style-none.html border-image-style-none-ref.html == border-image-style-none-length.html border-image-style-none-length-ref.html == border-image-style-none-auto.html border-image-style-none-auto-ref.html @@ -48,12 +48,12 @@ fuzzy(1-150,1-2650) fails-if(useDrawSnapshot) == border-image-repeat-space-8z.ht # border images with gradients fuzzy-if(!useDrawSnapshot&&!geckoview,1-3,300-1804) == border-image-linear-gradient.html border-image-linear-gradient-ref.html fuzzy(0-1,0-350) fuzzy-if(!geckoview,1-3,179-37537) == border-image-linear-gradient-slice-1.html border-image-linear-gradient-slice-1-ref.html -fuzzy(0-1,0-515) fuzzy-if(OSX,0-1,0-10595) fuzzy-if(!geckoview,1-3,272-25136) == border-image-linear-gradient-slice-2.html border-image-linear-gradient-slice-2-ref.html +fuzzy(0-1,0-515) fuzzy-if(cocoaWidget,0-1,0-10595) fuzzy-if(!geckoview,1-3,272-25136) == border-image-linear-gradient-slice-2.html border-image-linear-gradient-slice-2-ref.html fuzzy(0-1,0-2500) fuzzy-if(!geckoview,1-3,200-86037) == border-image-linear-gradient-slice-fill-1.html border-image-linear-gradient-slice-fill-1-ref.html -fuzzy(0-1,0-649) fuzzy-if(OSX,0-1,0-25771) fuzzy-if(!Android,0-1,0-546) fuzzy-if(Android,0-1,0-6093) fuzzy-if(!geckoview,1-3,477-57480) == border-image-linear-gradient-slice-fill-2.html border-image-linear-gradient-slice-fill-2-ref.html -fuzzy(0-1,0-134) fuzzy-if(OSX,0-5,0-1676) fuzzy-if(!geckoview,1-1,0-4537) == border-image-linear-gradient-width.html border-image-linear-gradient-width-ref.html -fuzzy(0-2,0-60590) fuzzy-if(Android,0-4,0-18022) fuzzy-if(OSX,0-1,0-15000) fuzzy-if(!useDrawSnapshot&&!geckoview,1-2,3900-60581) == border-image-linear-gradient-slice-width.html border-image-linear-gradient-slice-width-ref.html -fuzzy(0-2,0-26758) fuzzy-if(OSX,0-1,0-6000) fuzzy-if(!geckoview,1-3,2400-26758) == border-image-linear-gradient-outset.html border-image-linear-gradient-outset-ref.html +fuzzy(0-1,0-649) fuzzy-if(cocoaWidget,0-1,0-25771) fuzzy-if(!Android,0-1,0-546) fuzzy-if(Android,0-1,0-6093) fuzzy-if(!geckoview,1-3,477-57480) == border-image-linear-gradient-slice-fill-2.html border-image-linear-gradient-slice-fill-2-ref.html +fuzzy(0-1,0-134) fuzzy-if(cocoaWidget,0-5,0-1676) fuzzy-if(!geckoview,1-1,0-4537) == border-image-linear-gradient-width.html border-image-linear-gradient-width-ref.html +fuzzy(0-2,0-60590) fuzzy-if(Android,0-4,0-18022) fuzzy-if(cocoaWidget,0-1,0-15000) fuzzy-if(!useDrawSnapshot&&!geckoview,1-2,3900-60581) == border-image-linear-gradient-slice-width.html border-image-linear-gradient-slice-width-ref.html +fuzzy(0-2,0-26758) fuzzy-if(cocoaWidget,0-1,0-6000) fuzzy-if(!geckoview,1-3,2400-26758) == border-image-linear-gradient-outset.html border-image-linear-gradient-outset-ref.html fuzzy(0-1,0-400) fuzzy-if(!geckoview,1-3,200-26872) == border-image-linear-gradient-repeat-repeat-1.html border-image-linear-gradient-repeat-repeat-1-ref.html fuzzy(0-1,0-300) fuzzy-if(!geckoview,1-3,200-27131) == border-image-linear-gradient-repeat-round-1.html border-image-linear-gradient-repeat-round-1-ref.html fuzzy-if(Android,0-1,0-1894) fuzzy-if(!useDrawSnapshot&&!geckoview,1-2,2400-67805) == border-image-linear-gradient-repeat-repeat-2.html border-image-linear-gradient-repeat-repeat-2-ref.html @@ -71,18 +71,18 @@ fuzzy(0-3,0-66698) == border-image-radial-gradient-slice-width.html border-image # OS X failures tracked in bug 957025 fuzzy-if(!useDrawSnapshot&&!geckoview,1-4,455-2000) == border-image-repeating-linear-gradient.html border-image-repeating-linear-gradient-ref.html -fails-if(OSX) fuzzy(0-3,0-95449) == border-image-repeating-linear-gradient-slice-fill-2.html border-image-repeating-linear-gradient-slice-fill-2-ref.html -fails-if(OSX) fuzzy(0-3,0-20000) fuzzy-if(!geckoview,1-4,800-14000) == border-image-repeating-linear-gradient-repeat-round-2.html border-image-repeating-linear-gradient-repeat-round-2-ref.html +fails-if(cocoaWidget) fuzzy(0-3,0-95449) == border-image-repeating-linear-gradient-slice-fill-2.html border-image-repeating-linear-gradient-slice-fill-2-ref.html +fails-if(cocoaWidget) fuzzy(0-3,0-20000) fuzzy-if(!geckoview,1-4,800-14000) == border-image-repeating-linear-gradient-repeat-round-2.html border-image-repeating-linear-gradient-repeat-round-2-ref.html fuzzy(0-3,0-3008) == border-image-repeating-radial-gradient.html border-image-repeating-radial-gradient-ref.html fuzzy(0-3,0-62078) == border-image-repeating-radial-gradient-slice-1.html border-image-repeating-radial-gradient-slice-1-ref.html fuzzy(0-3,0-40536) == border-image-repeating-radial-gradient-slice-2.html border-image-repeating-radial-gradient-slice-2-ref.html fuzzy(0-3,0-1794) fuzzy-if(!geckoview,1-3,30-12194) == border-image-repeating-radial-gradient-slice-fill-1.html border-image-repeating-radial-gradient-slice-fill-1-ref.html -fails-if(OSX) fuzzy(0-3,0-1435) fuzzy-if(!geckoview,1-2,20-8000) == border-image-repeating-radial-gradient-slice-fill-2.html border-image-repeating-radial-gradient-slice-fill-2-ref.html +fails-if(cocoaWidget) fuzzy(0-3,0-1435) fuzzy-if(!geckoview,1-2,20-8000) == border-image-repeating-radial-gradient-slice-fill-2.html border-image-repeating-radial-gradient-slice-fill-2-ref.html fuzzy(0-3,0-7441) == border-image-repeating-radial-gradient-width.html border-image-repeating-radial-gradient-width-ref.html -fails-if(OSX) fuzzy(0-8,0-99728) == border-image-repeating-radial-gradient-slice-width.html border-image-repeating-radial-gradient-slice-width-ref.html +fails-if(cocoaWidget) fuzzy(0-8,0-99728) == border-image-repeating-radial-gradient-slice-width.html border-image-repeating-radial-gradient-slice-width-ref.html fuzzy(0-3,0-117768) == border-image-repeating-radial-gradient-repeat-repeat-2.html border-image-repeating-radial-gradient-repeat-repeat-2-ref.html -fails-if(OSX) fuzzy(0-3,0-116185) == border-image-repeating-radial-gradient-repeat-round-2.html border-image-repeating-radial-gradient-repeat-round-2-ref.html +fails-if(cocoaWidget) fuzzy(0-3,0-116185) == border-image-repeating-radial-gradient-repeat-round-2.html border-image-repeating-radial-gradient-repeat-round-2-ref.html # border-image-source (-moz-)element fuzzy(0-125,0-5903) == border-image-element.html border-image-element-ref.html diff --git a/layout/reftests/border-radius/reftest.list b/layout/reftests/border-radius/reftest.list index b548c11b33..831d8f05db 100644 --- a/layout/reftests/border-radius/reftest.list +++ b/layout/reftests/border-radius/reftest.list @@ -47,14 +47,14 @@ skip-if(Android&&emulator) fuzzy(0-8,0-20) fuzzy-if(useDrawSnapshot,1-1,172-172) fuzzy(0-1,0-172) == clipping-4-image.html clipping-4-ref.html fuzzy(0-1,0-77) == clipping-4-overflow-hidden.html clipping-4-ref.html skip-if(Android&&emulator) == clipping-5-canvas.html clipping-5-refc.html -fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-5) == clipping-5-image.html clipping-5-refi.html +fuzzy-if(winWidget,0-1,0-5) == clipping-5-image.html clipping-5-refi.html fuzzy(0-1,0-77) == clipping-5-overflow-hidden.html clipping-5-ref.html fuzzy(0-1,0-97) == clipping-5-refi.html clipping-5-ref.html skip-if(Android&&emulator) fuzzy(0-1,0-77) fuzzy-if(useDrawSnapshot,1-1,97-97) == clipping-5-refc.html clipping-5-ref.html # bug 732535 fuzzy(0-21,0-76) fuzzy-if(winWidget,0-144,0-335) == clipping-6.html clipping-6-ref.html # PaintedLayer and MaskLayer with transforms that aren't identical fuzzy(0-28,0-97) == clipping-7.html clipping-7-ref.html # ColorLayer and MaskLayer with transforms that aren't identical. Reference image rendered without using layers (which causes fuzzy failures). == clipping-and-zindex-1.html clipping-and-zindex-1-ref.html -skip-if(Android&&emulator) fuzzy-if(cocoaWidget,0-1,0-4) fuzzy-if(d2d,0-59,0-342) == intersecting-clipping-1-canvas.html intersecting-clipping-1-refc.html +skip-if(Android&&emulator) fuzzy-if(cocoaWidget,0-1,0-4) fuzzy-if(winWidget,0-59,0-342) == intersecting-clipping-1-canvas.html intersecting-clipping-1-refc.html == intersecting-clipping-1-image.html intersecting-clipping-1-refi.html == intersecting-clipping-1-overflow-hidden.html intersecting-clipping-1-ref.html fuzzy(0-1,0-300) == intersecting-clipping-1-refi.html intersecting-clipping-1-ref.html @@ -73,7 +73,7 @@ fuzzy(0-1,0-116) == invalidate-1a.html invalidate-1-ref.html fuzzy(0-1,0-117) == invalidate-1b.html invalidate-1-ref.html # test that border-radius is reduced for scrollbars -fails-if(Android) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-12,0-12) fuzzy-if(!Android,0-1,0-50) fuzzy-if(gtkWidget&&layersGPUAccelerated,0-12,0-12) == scrollbar-clamping-1.html scrollbar-clamping-1-ref.html +fails-if(Android) fuzzy-if(!Android,0-1,0-50) fuzzy-if(gtkWidget,0-12,0-12) == scrollbar-clamping-1.html scrollbar-clamping-1-ref.html fails-if(Android) == scrollbar-clamping-2.html scrollbar-clamping-2-ref.html # Test for bad corner joins. @@ -82,7 +82,7 @@ random-if(winWidget) fuzzy(0-255,0-610) == corner-joins-2.xhtml corner-joins-2-r fuzzy(0-59,0-146) == scroll-1.html scroll-1-ref.html # see bug 732535 #Bug 959166 -fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-35,0-194) fuzzy-if(swgl,0-1,0-2) == transforms-1.html transforms-1-ref.html # bug 1507152 +fuzzy-if(winWidget,0-35,0-194) fuzzy-if(swgl,0-1,0-2) == transforms-1.html transforms-1-ref.html # bug 1507152 == zero-radius-clip-1.html zero-radius-clip-ref.html diff --git a/layout/reftests/box-shadow/reftest.list b/layout/reftests/box-shadow/reftest.list index ed6baf7946..f8f302b1cc 100644 --- a/layout/reftests/box-shadow/reftest.list +++ b/layout/reftests/box-shadow/reftest.list @@ -15,21 +15,21 @@ fuzzy(0-14,0-179) fuzzy-if(swgl&&!Android,0-1,0-952) fuzzy-if(useDrawSnapshot&&s == boxshadow-fileupload.html boxshadow-fileupload-ref.html fuzzy(13-19,28-51) == boxshadow-inner-basic.html boxshadow-inner-basic-ref.svg -fuzzy(0-1,0-18) random-if(layersGPUAccelerated) == boxshadow-mixed.html boxshadow-mixed-ref.html +fuzzy(0-1,0-18) random == boxshadow-mixed.html boxshadow-mixed-ref.html fuzzy(0-1,0-17) == boxshadow-mixed-2.html boxshadow-mixed-2-ref.html -random-if(d2d) fuzzy(0-127,0-3528) == boxshadow-rounded-spread.html boxshadow-rounded-spread-ref.html +random-if(winWidget) fuzzy(0-127,0-3528) == boxshadow-rounded-spread.html boxshadow-rounded-spread-ref.html fuzzy(0-1,0-50) == chrome://reftest/content/box-shadow/boxshadow-dynamic.xhtml chrome://reftest/content/box-shadow/boxshadow-dynamic-ref.xhtml -random-if(d2d) fuzzy(0-1,0-14) == boxshadow-onecorner.html boxshadow-onecorner-ref.html -random-if(d2d) fuzzy(0-1,0-22) == boxshadow-twocorners.html boxshadow-twocorners-ref.html -random-if(d2d) fuzzy(0-1,0-36) == boxshadow-threecorners.html boxshadow-threecorners-ref.html +random-if(winWidget) fuzzy(0-1,0-14) == boxshadow-onecorner.html boxshadow-onecorner-ref.html +random-if(winWidget) fuzzy(0-1,0-22) == boxshadow-twocorners.html boxshadow-twocorners-ref.html +random-if(winWidget) fuzzy(0-1,0-36) == boxshadow-threecorners.html boxshadow-threecorners-ref.html fuzzy(0-2,0-440) == boxshadow-skiprect.html boxshadow-skiprect-ref.html fuzzy-if(useDrawSnapshot,1-1,1197-2400) == boxshadow-opacity.html boxshadow-opacity-ref.html == boxshadow-color-rounding.html boxshadow-color-rounding-ref.html == boxshadow-color-rounding-middle.html boxshadow-color-rounding-middle-ref.html -fuzzy(0-3,0-500) fuzzy-if(d2d,0-2,0-1080) == boxshadow-border-radius-int.html boxshadow-border-radius-int-ref.html +fuzzy(0-3,0-500) fuzzy-if(winWidget,0-2,0-1080) == boxshadow-border-radius-int.html boxshadow-border-radius-int-ref.html == boxshadow-inset-neg-spread.html about:blank == boxshadow-inset-neg-spread2.html boxshadow-inset-neg-spread2-ref.html -fuzzy(0-26,0-3610) fuzzy-if(d2d,0-26,0-5910) fuzzy-if(!(swgl&&Android),0-6,378-4500) == boxshadow-rotated.html boxshadow-rotated-ref.html # Bug 1211264 +fuzzy(0-26,0-3610) fuzzy-if(winWidget,0-26,0-5910) fuzzy-if(!(swgl&&Android),0-6,378-4500) == boxshadow-rotated.html boxshadow-rotated-ref.html # Bug 1211264 == boxshadow-inset-large-border-radius.html boxshadow-inset-large-border-radius-ref.html # fuzzy due to blur going inside, but as long as it's essentially black instead of a light gray its ok. @@ -39,7 +39,7 @@ fuzzy(12-15,9400-13267) == boxshadow-inset-large-offset.html boxshadow-inset-lar == overflow-not-scrollable-1.html overflow-not-scrollable-1-ref2.html == overflow-not-scrollable-2.html overflow-not-scrollable-2-ref.html fuzzy(0-1,0-655) == 611574-1.html 611574-1-ref.html -fuzzy(0-4,0-144) fuzzy-if(d2d,0-1,0-36) == 611574-2.html 611574-2-ref.html +fuzzy(0-4,0-144) fuzzy-if(winWidget,0-1,0-36) == 611574-2.html 611574-2-ref.html fuzzy(0-16,0-10) == fieldset.html fieldset-ref.html # minor anti-aliasing problem on Windows fuzzy(0-16,0-10) == fieldset-inset.html fieldset-inset-ref.html # minor anti-aliasing problem on Windows == 1178575.html 1178575-ref.html diff --git a/layout/reftests/bugs/1553571-1.html b/layout/reftests/bugs/1553571-1.html index abb2c6ae5b..ee9e4782ab 100644 --- a/layout/reftests/bugs/1553571-1.html +++ b/layout/reftests/bugs/1553571-1.html @@ -2,6 +2,8 @@ + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 902e7e63f0..d85d5e7310 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -67,9 +67,9 @@ skip-if(isDebugBuild) == 256180-5.html 256180-5-ref.html == 25888-2r-block.html 25888-2r-ref.html == 25888-3l-block.html 25888-3l-ref.html == 25888-3r-block.html 25888-3r-ref.html -fuzzy-if(winWidget||gtkWidget,0-1,0-4) == 28811-1a.html 28811-1-ref.html +fuzzy-if(gtkWidget||winWidget,0-1,0-4) == 28811-1a.html 28811-1-ref.html fuzzy-if(gtkWidget,0-6,0-26200) == 28811-1b.html 28811-1-ref.html # Bug 1128229 -fuzzy-if(winWidget||gtkWidget,0-1,0-4) == 28811-2a.html 28811-2-ref.html +fuzzy-if(gtkWidget||winWidget,0-1,0-4) == 28811-2a.html 28811-2-ref.html fuzzy-if(gtkWidget,0-6,0-26200) == 28811-2b.html 28811-2-ref.html # Bug 1128229 == 40596-1a.html 40596-1-ref.html != 40596-1b.html 40596-1-ref.html @@ -185,18 +185,18 @@ test-pref(font.minimum-size.x-western,32) == 1503662.html 1503662-ref.html == chrome://reftest/content/bugs/192767-27.xhtml chrome://reftest/content/bugs/192767-37.xhtml != chrome://reftest/content/bugs/192767-01.xhtml chrome://reftest/content/bugs/192767-21.xhtml != chrome://reftest/content/bugs/192767-02.xhtml chrome://reftest/content/bugs/192767-22.xhtml -fails-if(Android&&!asyncPan) != chrome://reftest/content/bugs/192767-03.xhtml chrome://reftest/content/bugs/192767-23.xhtml +!= chrome://reftest/content/bugs/192767-03.xhtml chrome://reftest/content/bugs/192767-23.xhtml != chrome://reftest/content/bugs/192767-04.xhtml chrome://reftest/content/bugs/192767-24.xhtml != chrome://reftest/content/bugs/192767-05.xhtml chrome://reftest/content/bugs/192767-25.xhtml -fails-if(Android&&!asyncPan) != chrome://reftest/content/bugs/192767-06.xhtml chrome://reftest/content/bugs/192767-26.xhtml -fails-if(Android&&!asyncPan) != chrome://reftest/content/bugs/192767-07.xhtml chrome://reftest/content/bugs/192767-27.xhtml +!= chrome://reftest/content/bugs/192767-06.xhtml chrome://reftest/content/bugs/192767-26.xhtml +!= chrome://reftest/content/bugs/192767-07.xhtml chrome://reftest/content/bugs/192767-27.xhtml != chrome://reftest/content/bugs/192767-11.xhtml chrome://reftest/content/bugs/192767-31.xhtml != chrome://reftest/content/bugs/192767-12.xhtml chrome://reftest/content/bugs/192767-32.xhtml -fails-if(Android&&!asyncPan) != chrome://reftest/content/bugs/192767-13.xhtml chrome://reftest/content/bugs/192767-33.xhtml +!= chrome://reftest/content/bugs/192767-13.xhtml chrome://reftest/content/bugs/192767-33.xhtml != chrome://reftest/content/bugs/192767-14.xhtml chrome://reftest/content/bugs/192767-34.xhtml != chrome://reftest/content/bugs/192767-15.xhtml chrome://reftest/content/bugs/192767-35.xhtml -fails-if(Android&&!asyncPan) != chrome://reftest/content/bugs/192767-16.xhtml chrome://reftest/content/bugs/192767-36.xhtml -fails-if(Android&&!asyncPan) != chrome://reftest/content/bugs/192767-17.xhtml chrome://reftest/content/bugs/192767-37.xhtml +!= chrome://reftest/content/bugs/192767-16.xhtml chrome://reftest/content/bugs/192767-36.xhtml +!= chrome://reftest/content/bugs/192767-17.xhtml chrome://reftest/content/bugs/192767-37.xhtml != 200774-1.html about:blank == 201215-1.html 201215-1-ref.html == 201293-1a.html 201293-1-ref.html @@ -258,7 +258,7 @@ fuzzy(0-4,0-2) == 236539-1.html 236539-1-ref.html skip-if(Android) == 240933-2.html 240933-2-ref.html == 243266-1.html 243266-1-ref.html == 243302-1.html 243302-1-ref.html -skip-if(Android&&asyncPan) == 243519-1.html 243519-1-ref.html +skip-if(Android) == 243519-1.html 243519-1-ref.html == 243519-2.html 243519-2-ref.html == 243519-3.html 243519-3-ref.html == 243519-4a.html 243519-4-ref.html @@ -315,7 +315,7 @@ fuzzy(0-1,0-133) == 273681-1.html 273681-1-ref.html == 283686-2.html 283686-2-ref.html == 283686-3.html about:blank == 289384-1.xhtml 289384-ref.xhtml -random-if(d2d) fuzzy(0-25,0-2148) fails-if(useDrawSnapshot) HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 578114 for the d2d failures +random-if(winWidget) fuzzy(0-25,0-2148) fails-if(useDrawSnapshot) HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 578114 for the winWidget failures == 290129-1.html 290129-1-ref.html == 291078-1.html 291078-1-ref.html == 291078-2.html 291078-2-ref.html @@ -326,7 +326,7 @@ random-if(d2d) fuzzy(0-25,0-2148) fails-if(useDrawSnapshot) HTTP == 289480.html# == 296904-1.html 296904-1-ref.html == 299136-1.html 299136-1-ref.html == 299837-1.html 299837-1-ref.html -skip-if(Android) random-if(d2d) == chrome://reftest/content/bugs/299837-3.xhtml chrome://reftest/content/bugs/299837-3-ref.xhtml # bug 587631 +skip-if(Android) random-if(winWidget) == chrome://reftest/content/bugs/299837-3.xhtml chrome://reftest/content/bugs/299837-3-ref.xhtml # bug 587631 == 300691-1a.html 300691-1-ref.html == 300691-1b.html 300691-1-ref.html == 300691-1c.html 300691-1-ref.html @@ -554,9 +554,9 @@ fuzzy(0-4,0-11) == 363858-1.html 363858-1-ref.html == 363858-2.html 363858-2-ref.html fuzzy(0-1,0-4) == 363858-3.html 363858-3-ref.html == 363858-4.html 363858-4-ref.html -# fuzzy-if(OSX,0-45,0-2) fuzzy-if(winWidget,0-116,0-1) == 363858-5a.html 363858-5-ref.html # bug 1452797 +# fuzzy-if(cocoaWidget,0-45,0-2) fuzzy-if(winWidget,0-116,0-1) == 363858-5a.html 363858-5-ref.html # bug 1452797 fuzzy-if(Android,0-1,0-4) == 363858-5b.html 363858-5-ref.html -# fuzzy-if(OSX,0-45,0-2) fuzzy-if(winWidget,0-116,0-1) == 363858-6a.html 363858-6-ref.html # bug 1452797 +# fuzzy-if(cocoaWidget,0-45,0-2) fuzzy-if(winWidget,0-116,0-1) == 363858-6a.html 363858-6-ref.html # bug 1452797 == 363858-6b.html 363858-6-ref.html == 363874.html 363874-ref.html == 363874-max-width.html 363874-max-width-ref.html @@ -574,7 +574,7 @@ fuzzy-if(Android,0-1,0-4) == 363858-5b.html 363858-5-ref.html == 367247-s-hidden.html 367247-s-auto.html fails-if(Android) != 367247-s-auto.html 367247-s-scroll.html != 367247-l-visible.html 367247-l-hidden.html -fails-if(Android&&!asyncPan) != 367247-l-hidden.html 367247-l-scroll.html +!= 367247-l-hidden.html 367247-l-scroll.html == 367247-l-scroll.html 367247-l-auto.html == 367332-1a.html 367332-1-ref.html == 367332-1b.html 367332-1-ref.html @@ -595,7 +595,7 @@ fails-if(Android&&!asyncPan) != 367247-l-hidden.html 367247-l-scroll.html == 367612-1e.html 367612-1-ref.html == 367612-1f.html 367612-1-ref.html != 367612-1g.html 367612-1-ref.html -fuzzy(0-32,0-33) fuzzy-if(d2d,0-5,0-2) == 368020-1.html 368020-1-ref.html +fuzzy(0-32,0-33) fuzzy-if(winWidget,0-5,0-2) == 368020-1.html 368020-1-ref.html == 368020-2.html 368020-2-ref.html random-if(useDrawSnapshot) == 368020-3.html 368020-3-ref.html # Bug 1715408 random-if(useDrawSnapshot) == 368020-5.html 368020-5-ref.html # Bug 1715408 @@ -638,7 +638,7 @@ fuzzy(0-1,0-4) == 370422-1.html 370422-1-ref.html == 371043-1.html 371043-1-ref.html == 371354-1.html 371354-1-ref.html == 371483-1.html about:blank # assertion test -fails-if(Android&&!asyncPan) == 371561-1.html 371561-1-ref.html +== 371561-1.html 371561-1-ref.html != 371681-1.xhtml about:blank == 371925-1a.html 371925-1-ref.html == 371925-1b.html 371925-1-ref.html @@ -652,7 +652,7 @@ fuzzy-if(winWidget,46-92,1-2) == 373295-1.html 373295-1-ref.html == 373298-1.html 373298-1-ref.html == 373381-1.html 373381-1-ref.html fuzzy-if(!Android,0-2,0-40) == 373381-2.html 373381-2-ref.html -random-if(d2d) == 373381-3.html 373381-3-ref.html +random-if(winWidget) == 373381-3.html 373381-3-ref.html == 373381-4.html 373381-4-ref.html == 373383-1.html 373383-1-ref.html == 373433-1.html 373433-1-ref.html @@ -693,7 +693,7 @@ fuzzy-if(Android,0-2,0-140) == 379349-3b.xhtml 379349-3-ref.xhtml == 379461-1.xhtml 379461-1.html == 379461-2.xhtml 379461-2.html == 379461-3-container-xhtml.html 379461-3-container-html.html -fails-if(Android&&!asyncPan) != 379461-3-container-xhtml.html 379461-3-container-blank.html # there is a scrollbar +!= 379461-3-container-xhtml.html 379461-3-container-blank.html # there is a scrollbar fuzzy(0-1,0-5) == 380004-1.html 380004-1-ref.html fuzzy(0-2,0-5) == 380227-1.html 380227-1-ref.html == 380825-1.html 380825-1-ref.html @@ -990,7 +990,7 @@ fuzzy(0-92,0-430) == chrome://reftest/content/bugs/421203-2.xhtml 421203-1-ref.h == 421436-1b.html 421436-1-ref.html fuzzy(0-1,0-40) == 421632-1.html 421632-1-ref.html != 421710-1.html about:blank -fails-if(Android) fuzzy(63-65,1024-1024) fails-if(usesRepeatResampling&&!winWidget) == 421885-1.xml 421885-1-ref.xml +fails-if(Android) fuzzy(63-65,1024-1024) == 421885-1.xml 421885-1-ref.xml == 421955-1.html 421955-1-ref.html == 422249-1.html 422249-1-ref.html == 422394-1.html 422394-1-ref.html @@ -1140,13 +1140,13 @@ random == 445004-1.html 445004-1-ref.html # bug 472268 == 445142-1c.html 445142-1-ref.html == 445142-2a.html 445142-2-ref.html == 445142-2b.html 445142-2-ref.html -skip-if(winWidget&&isCoverageBuild) fails-if(usesRepeatResampling) fails-if(!winWidget) == 446100-1a.html about:blank -fuzzy-if(winWidget,177-178,127-127) fails-if(usesRepeatResampling) fails-if(!winWidget) == 446100-1b.html about:blank +skip-if(winWidget&&isCoverageBuild) fails == 446100-1a.html about:blank +fuzzy-if(winWidget,177-178,127-127) fails == 446100-1b.html about:blank fuzzy-if(winWidget,171-172,192-192) fails-if(!winWidget) == 446100-1c.html about:blank -fails-if(usesRepeatResampling) fails-if(!winWidget) == 446100-1d.html about:blank -fails-if(usesRepeatResampling) fails-if(!useDrawSnapshot&&!winWidget) == 446100-1e.html about:blank +fails == 446100-1d.html about:blank +fails-if(!useDrawSnapshot) == 446100-1e.html about:blank == 446100-1f.html about:blank -fails-if(winWidget&&isCoverageBuild) fails-if(usesRepeatResampling) fails-if(Android) fails-if(!useDrawSnapshot&&!winWidget) == 446100-1g.html about:blank +fails-if(!useDrawSnapshot) == 446100-1g.html about:blank == 446100-1h.html about:blank == 447749-1.html 447749-1-ref.html fuzzy(0-127,0-2) == 448193.html 448193-ref.html @@ -1253,7 +1253,7 @@ fuzzy(0-1,0-5) == 474472-1.html 474472-1-ref.html == 476598-1b.html 476598-1-ref2.html != 476598-1-ref.html about:blank == 476856-1.html 476856-1-ref.html -skip-if(Android) random-if(d2d) == chrome://reftest/content/bugs/478377-1.xhtml chrome://reftest/content/bugs/478377-1-ref.xhtml +skip-if(Android) random-if(winWidget) == chrome://reftest/content/bugs/478377-1.xhtml chrome://reftest/content/bugs/478377-1-ref.xhtml == 478614-1.html 478614-1-ref.html == 478614-2.html 478614-1-ref.html == 478614-3.html 478614-3-ref.html @@ -1282,8 +1282,8 @@ skip-if(Android) random-if(d2d) == chrome://reftest/content/bugs/478377-1.xhtml != 481948-2.html 481948-2-ref.html fails-if(Android||gtkWidget) random-if(winWidget||cocoaWidget) == 481948-3.html 481948-3-ref.html # questionable test, see bug 488364 == 482398-1.html 482398-1-ref.html -random-if(d2d) == 482592-1a-shadow.xhtml 482592-1-ref.html # bug 586771 -random-if(d2d) == 482592-1b-shadow.xhtml 482592-1-ref.html # bug 586771 +random-if(winWidget) == 482592-1a-shadow.xhtml 482592-1-ref.html # bug 586771 +random-if(winWidget) == 482592-1b-shadow.xhtml 482592-1-ref.html # bug 586771 random-if(winWidget) fuzzy(0-1,0-5) == 482659-1a.html 482659-1-ref.html fuzzy(0-1,0-5) == 482659-1b.html 482659-1-ref.html fuzzy(0-1,0-5) == 482659-1c.html 482659-1-ref.html @@ -1373,7 +1373,7 @@ fuzzy(0-1,0-4) == 513153-1b.html 513153-1-ref.html pref(widget.non-native-theme.webrender,true) == 513153-2a.html 513153-2-ref.html # appleSilicon: bug 1724583 fuzzy-if(cocoaWidget,0-112,0-108) == 513153-2b.html 513153-2-ref.html # only fuzzy when widget.non-native-theme.webrender=false, snapping difference == chrome://reftest/content/bugs/513318-1.xhtml chrome://reftest/content/bugs/513318-1-ref.xhtml -fails-if(Android&&(!asyncPan)) != chrome://reftest/content/bugs/513318-2.xhtml chrome://reftest/content/bugs/513318-2-ref.xhtml +!= chrome://reftest/content/bugs/513318-2.xhtml chrome://reftest/content/bugs/513318-2-ref.xhtml == 514917-1.html 514917-1-ref.html == 518172-1a.html 518172-a-ref.html fuzzy-if(winWidget,0-73,0-133) fuzzy-if(cocoaWidget,0-103,0-133) == 518172-1b.html 518172-b-ref.html @@ -1389,7 +1389,7 @@ fuzzy(0-1,0-3) == 521525-1.html 521525-1-ref.html == 521685-1.html 521685-1-ref.html == 522632-1.html 522632-1-ref.html == 523096-1.html 523096-1-ref.html -random-if(d2d) == 523468-1.html 523468-1-ref.html +random-if(winWidget) == 523468-1.html 523468-1-ref.html == 524175-1.html 524175-1-ref.html fuzzy(0-5,0-50) == 526463-1.html 526463-1-ref.html == 527464-1.html 527464-ref.html @@ -1445,7 +1445,7 @@ fuzzy-if(Android,0-12,0-300) == 551463-1.html 551463-1-ref.html # Marked "random" rather than "fails" because it may (spuriously) appear to pass # on Android devices that completely lack any Sinhala font support. random != 553571-1.html 553571-1-notref.html # expect dotted circle in test, not in ref: "fails" under harfbuzz, which doesn't consider the sequence invalid -random-if(d2d) skip-if(azureSkiaGL) fuzzy(0-32,0-219) == 555388-1.html 555388-1-ref.html +random-if(winWidget) fuzzy(0-32,0-219) == 555388-1.html 555388-1-ref.html == 556661-1.html 556661-1-ref.html fuzzy(0-4,0-9) == 557087-1.html 557087-ref.html fuzzy(0-2,0-5) fuzzy-if(Android,0-1,0-9) == 557087-2.html 557087-ref.html @@ -1461,7 +1461,7 @@ fuzzy(0-1,0-5) == 561981-5.html 561981-5-ref.html fuzzy(0-1,0-5) == 561981-7.html 561981-7-ref.html == 561981-8.html 561981-8-ref.html == 562835-1.html 562835-ref.html -== 562835-2.html 562835-ref.html +pref(layout.css.h1-in-section-ua-styles.enabled,true) == 562835-2.html 562835-ref.html fuzzy-if(Android,0-2,0-48) == 563584-1.html 563584-1-ref.html fuzzy-if(Android,0-2,0-48) == 563584-2.html 563584-2-ref.html fuzzy-if(Android,0-4,0-180) == 563584-3.html 563584-3-ref.html @@ -1487,7 +1487,7 @@ fuzzy-if(Android,0-2,0-48) == 563584-11.html 563584-11-ref.html == 563884-1.html 563884-1-ref.html == 564002-1.html 564002-1-ref.html == 564054-1.html 564054-1-ref.html -fails-if(Android) random-if(layersGPUAccelerated) fuzzy(0-1,0-1200) == 564991-1.html 564991-1-ref.html +fails-if(Android) random fuzzy(0-1,0-1200) == 564991-1.html 564991-1-ref.html == 565819-1.html 565819-ref.html == 565819-2.html 565819-ref.html fuzzy-if(Android,0-1,0-1) needs-focus == 568441.html 568441-ref.html @@ -1513,9 +1513,9 @@ random-if(!winWidget) != 574907-3.html 574907-3-notref.html == chrome://reftest/content/bugs/579323-1.html chrome://reftest/content/bugs/579323-1-ref.html == 579349-1.html 579349-1-ref.html == 579655-1.html 579655-1-ref.html -fails-if(Android) random-if(layersGPUAccelerated) fuzzy(0-1,0-10000) == 579985-1.html 579985-1-ref.html # this bug was only for a regression in BasicLayers anyway -fuzzy-if(asyncPan&&!layersGPUAccelerated,0-255,0-141) == 580863-1.html 580863-1-ref.html -fails-if(Android) random-if(layersGPUAccelerated) fuzzy(0-1,0-6436) == 581317-1.html 581317-1-ref.html +fails-if(Android) random fuzzy(0-1,0-10000) == 579985-1.html 579985-1-ref.html # this bug was only for a regression in BasicLayers anyway +== 580863-1.html 580863-1-ref.html +fails-if(Android) random fuzzy(0-1,0-6436) == 581317-1.html 581317-1-ref.html == 581579-1.html 581579-1-ref.html == 582037-1a.html 582037-1-ref.html == 582037-1b.html 582037-1-ref.html @@ -1527,7 +1527,7 @@ asserts(1-2) == 582146-1.html about:blank == 584699-1.html 584699-1-ref.html fuzzy(0-2,0-48) fuzzy-if(winWidget,0-1,0-33) == 585598-2.xhtml 585598-2-ref.xhtml == 586400-1.html 586400-1-ref.html -fuzzy-if(d2d,0-52,0-1051) == 586683-1.html 586683-1-ref.html +fuzzy-if(winWidget,0-52,0-1051) == 586683-1.html 586683-1-ref.html == 589615-1a.xhtml 589615-1-ref.html == 589615-1b.html 589615-1-ref.html == 589672-1.html 589672-1-ref.html @@ -1590,19 +1590,19 @@ fails-if(useDrawSnapshot) == 621253-2-externalFilter.html 621253-2-ref.html fails-if(useDrawSnapshot) == 621253-2-internalFilter.html 621253-2-ref.html random-if(winWidget) == 621918-1.svg 621918-1-ref.svg # 1-pixel diacritic positioning discrepancy in rotated text (may depend on platform fonts) random-if(winWidget) fuzzy-if(geckoview&&!emulator,0-255,0-22) == 621918-2.svg 621918-2-ref.svg # same 1px issue as above -fuzzy-if(d2d,0-5,0-1) == 622585-1.html 622585-1-ref.html # bug 789402 +fuzzy-if(winWidget,0-5,0-1) == 622585-1.html 622585-1-ref.html # bug 789402 fuzzy(0-1,0-40000) == 625409-1.html 625409-1-ref.html == 627393-1.html about:blank fuzzy(0-1,0-500) == 630835-1.html about:blank == 631352-1.html 631352-1-ref.html random-if(winWidget) == 632781-verybig.html 632781-ref.html == 632781-normalsize.html 632781-ref.html -fuzzy-if(!isDebugBuild&>kWidget&&/^Linux\x20i686/.test(http.oscpu),0-102,0-140) == 633344-1.html 633344-1-ref.html # bug 1103623, Linux32 from GCC update +== 633344-1.html 633344-1-ref.html # bug 1103623, Linux32 from GCC update fuzzy(0-1,0-500) == 634232-1.html 634232-1-ref.html skip-if(Android&&emulator) fuzzy(0-3,0-120000) == 635302-1.html 635302-1-ref.html fuzzy(0-1,0-68) fuzzy-if(gtkWidget,0-1,0-70) fuzzy-if(!Android,0-2,0-300) == 635373-1.html 635373-1-ref.html -random-if(d2d) fuzzy-if(winWidget&&!d2d,0-20,0-118) fuzzy-if(!Android,0-2,0-550) == 635373-2.html 635373-2-ref.html -random-if(d2d) fuzzy-if(winWidget&&!d2d,0-20,0-116) fuzzy-if(!Android,0-2,0-650) == 635373-3.html 635373-3-ref.html +random-if(winWidget) fuzzy-if(!Android,0-2,0-550) == 635373-2.html 635373-2-ref.html +random-if(winWidget) fuzzy-if(!Android,0-2,0-650) == 635373-3.html 635373-3-ref.html == 635639-1.html 635639-1-ref.html == 635639-2.html 635639-2-ref.html == 637597-1.html 637597-1-ref.html @@ -1615,7 +1615,7 @@ fuzzy-if(Android,0-8,0-500) == 637852-3.html 637852-3-ref.html == 645647-1.html 645647-1-ref.html == 645647-2.html 645647-2-ref.html == 645768-1.html 645768-1-ref.html -fails-if(layersGPUAccelerated&&cocoaWidget) fuzzy(0-57,0-11000) == 650228-1.html 650228-1-ref.html # Quartz alpha blending doesn't match GL alpha blending +fails-if(cocoaWidget) fuzzy(0-57,0-11000) == 650228-1.html 650228-1-ref.html # Quartz alpha blending doesn't match GL alpha blending needs-focus == 652301-1a.html 652301-1-ref.html needs-focus == 652301-1b.html 652301-1-ref.html fuzzy(0-2,0-5) == 652775-1.html 652775-1-ref.html @@ -1638,7 +1638,7 @@ skip-if(Android) fuzzy(0-1,0-68000) == chrome://reftest/content/bugs/664127-1.xh == 667079-1.html 667079-1-ref.html skip-if(Android) == chrome://reftest/content/bugs/668319-1.xhtml about:blank != chrome://reftest/content/bugs/669015-1.xhtml chrome://reftest/content/bugs/669015-1-notref.xhtml -skip-if(azureSkiaGL) fuzzy-if(Android&&device,0-55,0-3742) == 670442-1.html 670442-1-ref.html +fuzzy-if(Android&&device,0-55,0-3742) == 670442-1.html 670442-1-ref.html == 670467-1.html 670467-1-ref.html == 670467-2.html 670467-2-ref.html == 690164-1.html 690164-1-ref.html @@ -1660,7 +1660,7 @@ fuzzy(0-1,0-3) needs-focus == 712130-2.html 712130-2-ref.html == 714519-1-q.html 714519-1-ref.html == 714519-2-as.html 714519-2-ref.html == 714519-2-q.html 714519-2-ref.html -skip-if(Android&&emulator) fuzzy(0-1,0-21) fuzzy-if(d2d,0-77,0-173) fuzzy-if(cocoaWidget,0-1,0-170) fuzzy-if(useDrawSnapshot,1-1,163-163) == 718521.html 718521-ref.html # bug 773482 +skip-if(Android&&emulator) fuzzy(0-1,0-21) fuzzy-if(winWidget,0-77,0-173) fuzzy-if(cocoaWidget,0-1,0-170) fuzzy-if(useDrawSnapshot,1-1,163-163) == 718521.html 718521-ref.html # bug 773482 == 720987.html 720987-ref.html == 722888-1.html 722888-1-ref.html fuzzy(0-2,0-40000) == 722923-1.html 722923-1-ref.html @@ -1711,7 +1711,7 @@ fuzzy-if(Android,0-4,0-400) == 815593-1.html 815593-1-ref.html fuzzy(0-1,0-5) == 816948-1.html 816948-1-ref.html == 817019-1.html about:blank fuzzy(0-1,0-5) == 818276-1.html 818276-1-ref.html -fuzzy-if(asyncPan,0-190,0-510) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-102,0-510) == 825999.html 825999-ref.html +fuzzy-if(!useDrawSnapshot,0-190,0-510) == 825999.html 825999-ref.html == 827577-1a.html 827577-1-ref.html == 827577-1b.html 827577-1-ref.html == 827799-1.html about:blank @@ -1751,7 +1751,7 @@ test-pref(font.minimum-size.x-western,32) fuzzy-if(Android,0-45,0-324) == 935056 == 936670-1.svg 936670-1-ref.svg == 941940-1.html 941940-1-ref.html fails == 942017.html 942017-ref.html # bug 942017 -fuzzy(0-2,0-160000) fuzzy-if(winWidget&&isDebugBuild&&layersGPUAccelerated&&!is64Bit,1-1,12-175) == 942672-1.html 942672-1-ref.html +fuzzy(0-2,0-160000) fuzzy-if(winWidget&&isDebugBuild&&!is64Bit,1-1,12-175) == 942672-1.html 942672-1-ref.html == 953334-win32-clipping.html 953334-win32-clipping-ref.html fuzzy(0-1,0-5) == 956513-1.svg 956513-1-ref.svg == 944291-1.html 944291-1-ref.html @@ -1813,7 +1813,7 @@ fuzzy(15-65,100-500) fuzzy-if(useDrawSnapshot,33-33,218-218) == 1081185-1.html 1 == 1097437-1.html 1097437-1-ref.html == 1103258-1.html 1103258-1-ref.html # assertion crash test with layers culling test == 1105137-1.html 1105137-1-ref.html -fuzzy-if(d2d,0-36,0-304) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&d2d,0-139,0-701) == 1116480-1-fakeitalic-overflow.html 1116480-1-fakeitalic-overflow-ref.html +fuzzy-if(winWidget,0-139,0-701) == 1116480-1-fakeitalic-overflow.html 1116480-1-fakeitalic-overflow-ref.html == 1111753-1.html about:blank == chrome://reftest/content/bugs/1114526-1.html 1114526-1-ref.html fuzzy(0-1,0-800000) == 1119117-1a.html 1119117-1-ref.html @@ -1943,12 +1943,12 @@ fuzzy-if(Android,0-27,0-874) fuzzy-if(!Android,0-14,0-43) fuzzy-if(gtkWidget&&fi fuzzy(0-3,0-320000) fails-if(useDrawSnapshot) == 1315113-1.html 1315113-1-ref.html fuzzy(0-3,0-20000) == 1315113-2.html 1315113-2-ref.html == 1315632-1.html 1315632-1-ref.html -fuzzy(0-3,0-40000) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-13,0-40000) == 1316719-1a.html 1316719-1-ref.html -fuzzy(0-13,0-40000) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-13,0-40000) == 1316719-1b.html 1316719-1-ref.html -fuzzy(0-13,0-40000) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-13,0-40000) == 1316719-1c.html 1316719-1-ref.html +fuzzy(0-3,0-40000) fuzzy-if(winWidget,0-13,0-40000) == 1316719-1a.html 1316719-1-ref.html +fuzzy(0-13,0-40000) fuzzy-if(winWidget,0-13,0-40000) == 1316719-1b.html 1316719-1-ref.html +fuzzy(0-13,0-40000) fuzzy-if(winWidget,0-13,0-40000) == 1316719-1c.html 1316719-1-ref.html != 1318769-1.html 1318769-1-ref.html == 1322512-1.html 1322512-1-ref.html -skip-if(isDebugBuild&&winWidget) == 1330051.svg 1330051-ref.svg +skip-if(winWidget&&isDebugBuild) == 1330051.svg 1330051-ref.svg != 1336591-1.html 1336591-1-ref.html == 1348481-1.html 1348481-ref.html == 1348481-2.html 1348481-ref.html @@ -2017,7 +2017,7 @@ skip-if(winWidget&&isCoverageBuild) == 1424177.html 1424177-ref.html == 1424680.html 1424680-ref.html == 1424798-1.html 1424798-ref.html fuzzy-if(swgl,0-1,0-31430) == 1425243-1.html 1425243-1-ref.html -fuzzy-if(Android,0-66,0-574) fuzzy-if(d2d,0-89,0-777) fuzzy-if(!Android&&!d2d,0-1,0-31430) fuzzy-if(winWidget,1-1,31240-31430) == 1425243-2.html 1425243-2-ref.html +fuzzy-if(Android,0-66,0-574) fuzzy-if(winWidget,1-1,31240-31430) fuzzy-if(!Android&&!winWidget,0-1,0-31430) == 1425243-2.html 1425243-2-ref.html == 1430869.html 1430869-ref.html == 1432541.html 1432541-ref.html == 1446470.html 1035091-ref.html @@ -2046,7 +2046,7 @@ fuzzy(0-5,0-2300) == 1529992-1.html 1529992-1-ref.html fuzzy-if(Android,9-14,44-60) fails-if(!useDrawSnapshot) == 1529992-2.html 1529992-2-ref.html == 1535040-1.html 1535040-1-ref.html == 1545360-1.xhtml 1545360-1-ref.xhtml -skip-if(!asyncPan) == 1544895.html 1544895-ref.html +skip-if(useDrawSnapshot) == 1544895.html 1544895-ref.html random-if(useDrawSnapshot) == 1546856-1.html 1546856-ref.html == 1546856-2.html 1546856-ref.html == 1547759-1.html 1547759-1-ref.html @@ -2054,8 +2054,8 @@ random-if(useDrawSnapshot) == 1546856-1.html 1546856-ref.html test-pref(layout.css.prefers-color-scheme.content-override,0) != 1551040.txt 1551040.txt test-pref(layout.css.prefers-color-scheme.content-override,0) == 1551040.html 1551040.html != 1552789-1.html 1552789-ref-1.html -pref(image.downscale-during-decode.enabled,true) skip-if(((gtkWidget&&isDebugBuild)||(gtkWidget&&AddressSanitizer)||Android||ThreadSanitizer)||(Android&&isDebugBuild)) random-if(useDrawSnapshot) fuzzy(0-2,0-188) == 1553571-1.html 1553571-1-ref.html -pref(image.downscale-during-decode.enabled,true) fuzzy(0-2,0-2004) skip-if(((gtkWidget&&isDebugBuild)||(gtkWidget&&AddressSanitizer)||Android||ThreadSanitizer)||(Android&&isDebugBuild)) random-if(useDrawSnapshot) == 1553571-2.html 1553571-2-ref.html +pref(image.downscale-during-decode.enabled,true) skip-if(((gtkWidget&&isDebugBuild)||(gtkWidget&&AddressSanitizer)||ThreadSanitizer)||(Android&&isDebugBuild)) random-if(useDrawSnapshot) fuzzy(0-2,0-188) == 1553571-1.html 1553571-1-ref.html +pref(image.downscale-during-decode.enabled,true) fuzzy(0-2,0-2004) skip-if(((gtkWidget&&isDebugBuild)||(gtkWidget&&AddressSanitizer)||ThreadSanitizer)||(Android&&isDebugBuild)) random-if(useDrawSnapshot) == 1553571-2.html 1553571-2-ref.html == 1558937-1.html 1558937-1-ref.html != 1563484.html 1563484-notref.html == 1563484.html 1563484-ref.html @@ -2071,11 +2071,11 @@ asserts(1-2) == 1588954.html 1588954-ref.html # Bug 1588954 != 1599841-2.html 1599841-2-notref.html == chrome://reftest/content/bugs/1606130.html chrome://reftest/content/bugs/1606130-ref.html == 1608124-1.html 1608124-1-ref.html -skip-if(!OSX) != 1608124-2.html 1608124-2-notref.html +skip-if(!cocoaWidget) != 1608124-2.html 1608124-2-notref.html == 1613380.html 1613380-ref.html fuzzy(0-145,0-48536) == 1614788-1.svg 1614788-1-ref.svg # large fuzz necesary to test bug: 239,202824 is how much it differs when bug exists == blob-fallback-clip.html blob-fallback-clip-ref.html -fuzzy-if(OSX,0-42,0-4) fuzzy-if(winWidget,249-249,999-999) == 1617515-1.html 1617515-1-ref.html +fuzzy-if(cocoaWidget,0-42,0-4) fuzzy-if(winWidget,249-249,999-999) == 1617515-1.html 1617515-1-ref.html == 1624118.html 1624118-ref.html fuzzy(0-2,0-21184) == 1626259-1.html 1626259-1-ref.html fuzzy(0-2,0-21184) == 1626259-2.html 1626259-2-ref.html @@ -2091,9 +2091,9 @@ fuzzy(0-2,0-96600) == 1648282-1b.html 1648282-1-ref.html == 1673677-3.html 1673677-3-ref.html == 1686729-1.html 1686729-1-ref.html != chrome://reftest/content/bugs/1688004.xhtml about:blank -pref(image.downscale-during-decode.enabled,true) fuzzy-if(OSX||winWidget,0-167,0-44310) fuzzy-if(gtkWidget,0-2,0-37220) == 1714763-1.html 1714763-1-ref.html -pref(image.downscale-during-decode.enabled,true) fuzzy-if(OSX||winWidget,0-166,0-22530) fuzzy-if(gtkWidget,0-18,0-19006) fuzzy-if(Android,0-21,0-22260) == 1714763-2.html 1714763-2-ref.html -pref(image.downscale-during-decode.enabled,true) fuzzy-if(OSX||winWidget,0-235,0-289) fuzzy-if(gtkWidget,0-186,0-240) fuzzy-if(Android,0-185,0-232) == 1714763-3.html 1714763-3-ref.html +pref(image.downscale-during-decode.enabled,true) fuzzy-if(cocoaWidget||winWidget,0-167,0-44310) fuzzy-if(gtkWidget,0-2,0-37220) == 1714763-1.html 1714763-1-ref.html +pref(image.downscale-during-decode.enabled,true) fuzzy-if(cocoaWidget||winWidget,0-166,0-22530) fuzzy-if(gtkWidget,0-18,0-19006) fuzzy-if(Android,0-21,0-22260) == 1714763-2.html 1714763-2-ref.html +pref(image.downscale-during-decode.enabled,true) fuzzy-if(cocoaWidget||winWidget,0-235,0-289) fuzzy-if(gtkWidget,0-186,0-240) fuzzy-if(Android,0-185,0-232) == 1714763-3.html 1714763-3-ref.html skip-if(!appleSilicon) != 1721223-1.html 1721223-1-notref.html # Big Sur required for updated system font; OSX value is clamped to 10.15 skip-if(Android) == 1727172-1.xhtml 1727172-1-ref.html == 1726663-1.html 1726663-1-ref.html @@ -2134,8 +2134,8 @@ pref(layout.css.prefers-color-scheme.content-override,0) == 1787127.html 1787127 pref(layout.css.prefers-color-scheme.content-override,1) == 1787127.html 1787127-ref.html pref(layout.css.prefers-color-scheme.content-override,2) == 1787127.html 1787127-ref.html == 1792643-1.html 1792643-1-ref.html -skip-if(!/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == 1798297-1.html 1798297-1-ref.html -skip-if(!/^Windows\x20NT\x2010\.0/.test(http.oscpu)) != 1798297-1.html 1798297-1-notref.html +skip-if(!winWidget) == 1798297-1.html 1798297-1-ref.html +skip-if(!winWidget) != 1798297-1.html 1798297-1-notref.html == 1799425-1.html 1799425-1-ref.html fuzzy-if(winWidget,114-114,572-572) == 1800437-1.html 1800437-1-ref.html == 1803999-1.html 1803999-1-ref.html @@ -2149,9 +2149,9 @@ pref(image.downscale-during-decode.enabled,true) == 1804872-3.html 1804872-3-ref == 1827009-1.html 1827009-1-ref.html pref(layout.testing.overlay-scrollbars.always-visible,true) pref(ui.useOverlayScrollbars,1) == 1827337-1.html 1827337-1-ref.html pref(layout.testing.overlay-scrollbars.always-visible,true) pref(ui.useOverlayScrollbars,1) fuzzy-if(winWidget,0-21,0-134) fuzzy-if(cocoaWidget,0-2,0-12) == 1828879-1.html 1828879-1-ref.html -skip-if(!OSX) != 1834316-1.html 1834316-1-notref.html -skip-if(!OSX) test-pref(layout.css.font-visibility.standard,1) ref-pref(layout.css.font-visibility.standard,3) == 1835271-1.html 1835271-1-ref.html -skip-if(!OSX) != 1836024-1.html 1836024-1-notref.html +skip-if(!cocoaWidget) != 1834316-1.html 1834316-1-notref.html +skip-if(!cocoaWidget) test-pref(layout.css.font-visibility.standard,1) ref-pref(layout.css.font-visibility.standard,3) == 1835271-1.html 1835271-1-ref.html +skip-if(!cocoaWidget) != 1836024-1.html 1836024-1-notref.html # The 1840511-* tests are reliably fuzzy on certain configurations, per bug # 1840511. (It passes on macOS and Android. It also passes with software WR, # or when using drawSnapshot.) @@ -2164,3 +2164,4 @@ fuzzy-if(!useDrawSnapshot,18-19,294-322) == 1840747-1.html about:blank # through, which is unexpected and is responsible for the 255-255 difference # 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 diff --git a/layout/reftests/canvas/reftest.list b/layout/reftests/canvas/reftest.list index a95705d633..66e84dd1d6 100644 --- a/layout/reftests/canvas/reftest.list +++ b/layout/reftests/canvas/reftest.list @@ -30,8 +30,8 @@ random-if(cocoaWidget) == subpixel-1.html about:blank # see bug 1192616, re-enab == text-ltr-alignment-test.html text-ltr-alignment-ref.html == text-rtl-alignment-test.html text-rtl-alignment-ref.html -fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-256) == text-horzline-with-bottom.html text-horzline.html -fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-256) fails-if(azureSkia&&OSX) == text-horzline-with-top.html text-horzline.html +fuzzy-if(winWidget,0-1,0-256) == text-horzline-with-bottom.html text-horzline.html +fuzzy-if(winWidget,0-1,0-256) fails-if(cocoaWidget) == text-horzline-with-top.html text-horzline.html != text-big-stroke.html text-blank.html != text-big-stroke.html text-big-fill.html @@ -42,7 +42,7 @@ fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-256) fails-if(azureSki == text-no-frame-test.html text-no-frame-ref.html == text-no-frame-2-test.html text-not-in-doc-ref.html -fuzzy-if(azureSkiaGL,0-10,0-400) == text-not-in-doc-test.html text-not-in-doc-ref.html +== text-not-in-doc-test.html text-not-in-doc-ref.html == text-bidi-ltr-test.html text-bidi-ltr-ref.html != text-bidi-ltr-test.html text-bidi-ltr-notref.html # for bug 698185 @@ -53,7 +53,7 @@ fuzzy-if(azureSkiaGL,0-10,0-400) == text-not-in-doc-test.html text-not-in-doc-re == text-measure.html text-measure-ref.html == text-small-caps-1.html text-small-caps-1-ref.html -random-if(!d2d) != text-subpixel-1.html text-subpixel-1-ref.html +random-if(!winWidget) != text-subpixel-1.html text-subpixel-1-ref.html == strokeText-path.html strokeText-path-ref.html @@ -79,7 +79,7 @@ fuzzy(0-9,0-470) random-if(Android) == dash-1.html dash-1-ref.svg # Bug 668412 ( == ctm-singular-sanity.html data:text/html,Pass == 672646-alpha-radial-gradient.html 672646-alpha-radial-gradient-ref.html -fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-45) == 674003-alpha-radial-gradient-superlum.html 674003-alpha-radial-gradient-superlum-ref.html +fuzzy-if(winWidget,0-1,0-45) == 674003-alpha-radial-gradient-superlum.html 674003-alpha-radial-gradient-superlum-ref.html != 693610-1.html 693610-1-notref.html # bug 693610: multiple glyph runs should not be overprinted @@ -92,7 +92,7 @@ fuzzy(0-1,0-20) == transformed-gradient.html transformed-gradient-ref.html == 749467-1.html 749467-1-ref.html # You get a little bit of rounding fuzz on OSX from transforming the paths between user space and device space -fuzzy(0-16,0-84) fuzzy-if(d2d&&/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-2,0-153) == 784573-1.html 784573-1-ref.html +fuzzy(0-16,0-84) fuzzy-if(winWidget,0-2,0-153) == 784573-1.html 784573-1-ref.html == 802658-1.html 802658-1-ref.html == 1074733-1.html 1074733-1-ref.html diff --git a/layout/reftests/columns/reftest.list b/layout/reftests/columns/reftest.list index 916817f49f..9a6f694e2e 100644 --- a/layout/reftests/columns/reftest.list +++ b/layout/reftests/columns/reftest.list @@ -22,7 +22,7 @@ pref(layout.outline.include-overflow,true) == column-balancing-overflow-005.html == column-box-alignment-rtl-3.html column-box-alignment-rtl-3-ref.html == column-box-alignment-rtl-4.html column-box-alignment-rtl-4-ref.html == columnfill-balance.html columnfill-balance-ref.html -fuzzy-if(OSX,0-32,0-1000) == columnfill-auto.html columnfill-auto-ref.html +fuzzy-if(cocoaWidget,0-32,0-1000) == columnfill-auto.html columnfill-auto-ref.html == columnfill-auto-2.html columnfill-auto-2-ref.html == columnfill-auto-3.html columnfill-auto-2-ref.html == columnrule-basic.html columnrule-basic-ref.html @@ -37,7 +37,7 @@ fuzzy-if(OSX,0-32,0-1000) == columnfill-auto.html columnfill-auto-ref.html == columnrule-overflow.html columnrule-overflow-ref.html == columns-table-caption-000.html columns-table-caption-000-ref.html == positioning-transforms-bug1112501.html positioning-transforms-bug1112501-ref.html -fuzzy-if(browserIsRemote&&winWidget,0-142,0-276) == fieldset-columns-001.html fieldset-columns-001-ref.html +fuzzy-if(winWidget,0-142,0-276) == fieldset-columns-001.html fieldset-columns-001-ref.html == fieldset-columns-002.html fieldset-columns-002-ref.html == fieldset-columns-003.html fieldset-columns-003-ref.html == fieldset-columns-004.html fieldset-columns-004-ref.html diff --git a/layout/reftests/css-animations/reftest.list b/layout/reftests/css-animations/reftest.list index ee84b01a30..11558a5c08 100644 --- a/layout/reftests/css-animations/reftest.list +++ b/layout/reftests/css-animations/reftest.list @@ -84,4 +84,4 @@ pref(layout.css.marker.restricted,false) == marker-reframe-and-animation-starts- == background-color-on-html.html background-color-on-html-ref.html skip-if(Android) == replace-with-new-positive-delay-animation.html replace-with-new-positive-delay-animation-ref.html # bug 1787682 for Android -pref(layout.css.scroll-driven-animations.enabled,true) skip-if(!asyncPan) == scroll-timeline-in-delay-omta.html scroll-timeline-in-delay-omta-ref.html +pref(layout.css.scroll-driven-animations.enabled,true) skip-if(useDrawSnapshot) == scroll-timeline-in-delay-omta.html scroll-timeline-in-delay-omta-ref.html diff --git a/layout/reftests/css-blending/reftest.list b/layout/reftests/css-blending/reftest.list index 8d2ca77586..9ed4c37029 100644 --- a/layout/reftests/css-blending/reftest.list +++ b/layout/reftests/css-blending/reftest.list @@ -7,11 +7,11 @@ fuzzy-if(geckoview&&device,3-3,5-5) == blend-difference-stacking.html blend-diff fuzzy(0-1,0-30000) == background-blending-alpha.html background-blending-alpha-ref.html == background-blending-gradient-color.html background-blending-gradient-color-ref.html fuzzy(0-2,0-9450) fuzzy-if(!geckoview,0-1,0-6200) == background-blending-gradient-gradient.html background-blending-gradient-gradient-ref.html -fuzzy-if(azureSkiaGL,0-2,0-7174) == background-blending-gradient-image.html background-blending-gradient-color-ref.html -fuzzy-if(azureSkia||d2d||gtkWidget,0-1,0-10000) == background-blending-image-color-jpg.html background-blending-image-color-ref.html +== background-blending-gradient-image.html background-blending-gradient-color-ref.html +fuzzy(0-1,0-10000) == background-blending-image-color-jpg.html background-blending-image-color-ref.html == background-blending-image-color-png.html background-blending-image-color-ref.html == background-blending-image-color-svg.html background-blending-image-color-ref.html -fuzzy-if(azureSkiaGL,0-2,0-7174) == background-blending-image-gradient.html background-blending-gradient-color-ref.html +== background-blending-image-gradient.html background-blending-gradient-color-ref.html == background-blending-image-image.html background-blending-image-color-ref.html == background-blending-isolation.html background-blending-isolation-ref.html random-if(useDrawSnapshot) == background-blending-list-repeat.html background-blending-list-repeat-ref.html @@ -20,22 +20,22 @@ random-if(useDrawSnapshot) == background-blending-list-repeat.html background-bl == background-blending-color-burn.html background-blending-color-burn-ref.svg == background-blending-color-dodge.html background-blending-color-dodge-ref.svg # need to investigate why these tests are fuzzy - first suspect is a possible color space conversion on some platforms; same for mix-blend-mode tests -fuzzy-if(azureSkia||gtkWidget,0-2,0-9600) fuzzy-if(appleSilicon,0-1,0-11200) fuzzy-if(d2d,0-1,0-8000) fuzzy-if(swgl&&!Android,1-1,8000-9600) == background-blending-color.html background-blending-color-ref.svg +fuzzy-if(!winWidget,0-2,0-9600) fuzzy-if(appleSilicon,0-1,0-11200) fuzzy-if(winWidget,0-1,0-8000) fuzzy-if(swgl&&!Android,1-1,8000-9600) == background-blending-color.html background-blending-color-ref.svg == background-blending-darken.html background-blending-darken-ref.svg == background-blending-difference.html background-blending-difference-ref.svg fuzzy(0-1,0-1600) == background-blending-exclusion.html background-blending-exclusion-ref.svg -fuzzy-if(cocoaWidget||d2d||swgl,0-1,0-1600) == background-blending-hard-light.html background-blending-hard-light-ref.svg -fuzzy-if(d2d,0-1,0-9600) fuzzy-if(azureSkia||gtkWidget,0-1,0-11200) fuzzy-if(!geckoview,1-1,9600-11240) == background-blending-hue.html background-blending-hue-ref.svg +fuzzy-if(cocoaWidget||winWidget||swgl,0-1,0-1600) == background-blending-hard-light.html background-blending-hard-light-ref.svg +fuzzy-if(winWidget,0-1,0-9600) fuzzy-if(!winWidget,0-1,0-11200) fuzzy-if(!geckoview,1-1,9600-11240) == background-blending-hue.html background-blending-hue-ref.svg == background-blending-lighten.html background-blending-lighten-ref.svg -fuzzy-if(d2d,0-1,0-8000) fuzzy-if(azureSkia||gtkWidget,0-2,0-9600) fuzzy-if(appleSilicon,0-1,0-11200) fuzzy-if(swgl&&!Android,1-1,8000-9600) == background-blending-luminosity.html background-blending-luminosity-ref.svg +fuzzy-if(winWidget,0-1,0-8000) fuzzy-if(!winWidget,0-2,0-9600) fuzzy-if(appleSilicon,0-1,0-11200) fuzzy-if(swgl&&!Android,1-1,8000-9600) == background-blending-luminosity.html background-blending-luminosity-ref.svg fuzzy(0-1,0-1600) == background-blending-multiply.html background-blending-multiply-ref.svg == background-blending-normal.html background-blending-normal-ref.svg -fuzzy-if(azureSkia||gtkWidget,0-1,0-1600) == background-blending-overlay.html background-blending-overlay-ref.svg -fuzzy-if(d2d,0-1,0-3200) fuzzy-if(azureSkia||gtkWidget,0-2,0-12800) == background-blending-saturation.html background-blending-saturation-ref.svg -fuzzy-if(d2d||azureSkia||gtkWidget,0-1,0-1600) == background-blending-screen.html background-blending-screen-ref.svg -fuzzy-if(d2d||azureSkia||gtkWidget,0-10,0-4800) == background-blending-soft-light.html background-blending-soft-light-ref.svg +fuzzy-if(!winWidget,0-1,0-1600) == background-blending-overlay.html background-blending-overlay-ref.svg +fuzzy-if(winWidget,0-1,0-3200) fuzzy-if(!winWidget,0-2,0-12800) == background-blending-saturation.html background-blending-saturation-ref.svg +fuzzy(0-1,0-1600) == background-blending-screen.html background-blending-screen-ref.svg +fuzzy(0-10,0-4800) == background-blending-soft-light.html background-blending-soft-light-ref.svg -fuzzy-if(azureSkia||d2d||gtkWidget,0-1,0-40000) == background-blending-image-color-959674.html background-blending-image-color-959674-ref.html +fuzzy(0-1,0-40000) == background-blending-image-color-959674.html background-blending-image-color-959674-ref.html #fuzzy due to inconsistencies in rounded rect cliping between parent and child; may be related to antialiasing. Between platforms, the max difference is the same, and the number of different pixels is either 36 or 37. (Win, Mac and Lin) fuzzy(0-65,0-53) fuzzy-if(geckoview&&device,63-64,163-328) == mix-blend-mode-952051.html mix-blend-mode-952051-ref.html diff --git a/layout/reftests/css-gradients/reftest.list b/layout/reftests/css-gradients/reftest.list index cb22973622..1574996fa3 100644 --- a/layout/reftests/css-gradients/reftest.list +++ b/layout/reftests/css-gradients/reftest.list @@ -32,19 +32,19 @@ fuzzy(0-3,0-21070) == linear-vertical-subpixel-1.html linear-vertical-subpixel-1 == linear-viewport.html linear-viewport-ref.html == nostops.html about:blank == onestop.html about:blank -random-if(d2d) fuzzy(0-4,0-6000) == radial-1a.html radial-1-ref.html -random-if(d2d) fuzzy(0-4,0-6000) == radial-1b.html radial-1-ref.html -fuzzy(0-3,0-7860) fuzzy-if(cocoaWidget,0-5,0-89041) fuzzy-if(azureSkiaGL,0-4,0-90000) == radial-2a.html radial-2-ref.html -fuzzy(0-3,0-7860) fuzzy-if(cocoaWidget,0-5,0-89041) fuzzy-if(azureSkiaGL,0-4,0-90000) == radial-2b.html radial-2-ref.html -fuzzy(0-3,0-7860) fuzzy-if(cocoaWidget,0-5,0-89041) fuzzy-if(azureSkiaGL,0-4,0-90000) == radial-2c.html radial-2-ref.html -fuzzy(0-3,0-7860) fuzzy-if(cocoaWidget,0-5,0-89041) fuzzy-if(azureSkiaGL,0-4,0-90000) == radial-2d.html radial-2-ref.html +random-if(winWidget) fuzzy(0-4,0-6000) == radial-1a.html radial-1-ref.html +random-if(winWidget) fuzzy(0-4,0-6000) == radial-1b.html radial-1-ref.html +fuzzy(0-3,0-7860) fuzzy-if(cocoaWidget,0-5,0-89041) == radial-2a.html radial-2-ref.html +fuzzy(0-3,0-7860) fuzzy-if(cocoaWidget,0-5,0-89041) == radial-2b.html radial-2-ref.html +fuzzy(0-3,0-7860) fuzzy-if(cocoaWidget,0-5,0-89041) == radial-2c.html radial-2-ref.html +fuzzy(0-3,0-7860) fuzzy-if(cocoaWidget,0-5,0-89041) == radial-2d.html radial-2-ref.html fuzzy(0-1,0-50) == radial-position-1b.html radial-position-1-ref.html fuzzy-if(cocoaWidget,0-4,0-22317) fuzzy-if(Android,0-8,0-771) == radial-shape-closest-corner-1a.html radial-shape-closest-corner-1-ref.html fuzzy(0-2,0-300) == radial-shape-closest-corner-1b.html radial-shape-closest-corner-1-ref.html fuzzy(0-5,0-30000) fuzzy-if(Android,0-17,0-5000) == radial-shape-closest-side-1a.html radial-shape-closest-side-1-ref.html fuzzy(0-5,0-30000) fuzzy-if(Android,0-17,0-5000) == radial-shape-closest-side-1b.html radial-shape-closest-side-1-ref.html fuzzy-if(Android,0-8,0-771) == radial-shape-farthest-corner-1a.html radial-shape-farthest-corner-1-ref.html -fails-if(gtkWidget&&/x86_64-/.test(xulRuntime.XPCOMABI)) fuzzy(0-2,0-500) == radial-shape-farthest-corner-1b.html radial-shape-farthest-corner-1-ref.html +fails-if(gtkWidget) fuzzy(0-2,0-500) == radial-shape-farthest-corner-1b.html radial-shape-farthest-corner-1-ref.html fuzzy(0-2,0-15000) fuzzy-if(Android,0-17,0-13320) == radial-shape-farthest-side-1a.html radial-shape-farthest-side-1-ref.html fuzzy(0-2,0-15000) fuzzy-if(Android,0-17,0-13320) == radial-shape-farthest-side-1b.html radial-shape-farthest-side-1-ref.html == radial-size-1a.html radial-size-1-ref.html @@ -60,9 +60,9 @@ fuzzy(0-1,0-40) == radial-premul.html radial-premul-ref.html == repeating-linear-1a.html repeating-linear-1-ref.html == repeating-linear-1b.html repeating-linear-1-ref.html == repeating-linear-2a.html repeating-linear-2-ref.html -fuzzy-if(d2d,0-127,0-2612) == repeating-radial-1a.html repeating-radial-1-ref.html +fuzzy-if(winWidget,0-127,0-2612) == repeating-radial-1a.html repeating-radial-1-ref.html == repeating-radial-1b.html repeating-radial-1-ref.html -fuzzy-if(d2d,0-127,0-2612) == repeating-radial-1c.html repeating-radial-1-ref.html +fuzzy-if(winWidget,0-127,0-2612) == repeating-radial-1c.html repeating-radial-1-ref.html == repeating-radial-1d.html repeating-radial-1-ref.html == repeating-radial-2a.html repeating-radial-2-ref.html == repeating-radial-2b.html repeating-radial-2-ref.html @@ -73,7 +73,7 @@ fuzzy(0-141,0-300) == twostops-1d.html twostops-1-ref.html fuzzy(0-73,0-900) == twostops-1e.html twostops-1-ref.html # from http://www.xanthir.com/:4bhipd by way of http://a-ja.net/newgrad.html -fuzzy-if(!contentSameGfxBackendAsCanvas,0-3,0-20000) fuzzy-if(azureSkiaGL||layersGPUAccelerated,0-8,0-20000) == aja-linear-1a.html aja-linear-1-ref.html +fuzzy-if(winWidget,0-3,0-20000) fuzzy(0-8,0-20000) == aja-linear-1a.html aja-linear-1-ref.html fuzzy(0-1,0-20000) == aja-linear-1b.html aja-linear-1-ref.html # bug 526694 fuzzy(0-8,0-20000) == aja-linear-1c.html aja-linear-1-ref.html fuzzy(0-8,0-20000) == aja-linear-1d.html aja-linear-1-ref.html @@ -90,7 +90,7 @@ fuzzy-if(cocoaWidget,0-1,0-40000) fuzzy-if(Android,0-6,0-10576) == height-depend fuzzy-if(Android,0-6,0-10576) == height-dependence-3.html height-dependence-3-ref.html == linear-onestopposition-1.html linear-onestopposition-1-ref.html -fuzzy-if(d2d,0-47,0-400) fuzzy-if(winWidget,0-1,0-1375) == linear-onestopposition-1.html linear-onestopposition-1-ref2.html # d2d interpolates the hard stop +fuzzy-if(winWidget,0-1,0-1375) == linear-onestopposition-1.html linear-onestopposition-1-ref2.html # winWidget interpolates the hard stop == radial-onestopposition-1a.html radial-onestopposition-1-ref.html == radial-onestopposition-1b.html radial-onestopposition-1-ref.html fuzzy-if(winWidget,0-1,0-1875) == repeating-linear-onestopposition-1.html orange-square.html diff --git a/layout/reftests/css-grid/reftest.list b/layout/reftests/css-grid/reftest.list index 8673b99897..789159ffe9 100644 --- a/layout/reftests/css-grid/reftest.list +++ b/layout/reftests/css-grid/reftest.list @@ -36,7 +36,7 @@ fails == grid-abspos-items-016.html grid-abspos-items-015-ref.html fuzzy(0-1,0-200) == grid-order-placement-definite-001.html grid-order-placement-definite-001-ref.html == grid-placement-definite-implicit-001.html grid-placement-definite-implicit-001-ref.html == grid-placement-definite-implicit-002.html grid-placement-definite-implicit-002-ref.html -fuzzy(0-64,0-1) skip-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == grid-placement-auto-implicit-001.html grid-placement-auto-implicit-001-ref.html # win10: bug 1507154 +fuzzy(0-64,0-1) skip-if(winWidget) == grid-placement-auto-implicit-001.html grid-placement-auto-implicit-001-ref.html # win10: bug 1507154 == grid-placement-abspos-implicit-001.html grid-placement-abspos-implicit-001-ref.html == rtl-grid-placement-definite-001.html rtl-grid-placement-definite-001-ref.html == rtl-grid-placement-auto-row-sparse-001.html rtl-grid-placement-auto-row-sparse-001-ref.html diff --git a/layout/reftests/display-list/reftest.list b/layout/reftests/display-list/reftest.list index 7ac7edc4f8..f11bd1efdb 100644 --- a/layout/reftests/display-list/reftest.list +++ b/layout/reftests/display-list/reftest.list @@ -1,26 +1,26 @@ # These tests are testing merging RDL implementation. -skip-if(!retainedDisplayList||retainedDisplayListNew) == retained-dl-style-change-1.html retained-dl-style-change-1-ref.html -skip-if(!retainedDisplayList||retainedDisplayListNew) == retained-dl-frame-deleted-1.html retained-dl-style-change-1-ref.html -skip-if(!retainedDisplayList||retainedDisplayListNew) == retained-dl-frame-created-1.html retained-dl-style-change-1-ref.html -skip-if(!retainedDisplayList||retainedDisplayListNew) == retained-dl-style-change-stacking-context-1.html retained-dl-style-change-stacking-context-1-ref.html -skip-if(!retainedDisplayList||retainedDisplayListNew) == retained-dl-style-change-stacking-context-2.html retained-dl-style-change-stacking-context-2-ref.html +skip-if(useDrawSnapshot) == retained-dl-style-change-1.html retained-dl-style-change-1-ref.html +skip-if(useDrawSnapshot) == retained-dl-frame-deleted-1.html retained-dl-style-change-1-ref.html +skip-if(useDrawSnapshot) == retained-dl-frame-created-1.html retained-dl-style-change-1-ref.html +skip-if(useDrawSnapshot) == retained-dl-style-change-stacking-context-1.html retained-dl-style-change-stacking-context-1-ref.html +skip-if(useDrawSnapshot) == retained-dl-style-change-stacking-context-2.html retained-dl-style-change-stacking-context-2-ref.html fails == retained-dl-style-change-stacking-context-3.html retained-dl-style-change-stacking-context-3-ref.html # bug 1650699 tracks this failure -skip-if(!retainedDisplayList||retainedDisplayListNew) == retained-dl-style-change-stacking-context-4.html retained-dl-style-change-stacking-context-4-ref.html -skip-if(!retainedDisplayList||retainedDisplayListNew||Android) == retained-dl-displayport-1.html retained-dl-displayport-1-ref.html -skip-if(!retainedDisplayList||retainedDisplayListNew) == retained-dl-prerender-transform-1.html retained-dl-prerender-transform-1-ref.html -skip-if(!retainedDisplayList||retainedDisplayListNew) == retained-dl-animation-on-pseudo.html retained-dl-animation-on-pseudo-ref.html +skip-if(useDrawSnapshot) == retained-dl-style-change-stacking-context-4.html retained-dl-style-change-stacking-context-4-ref.html +skip-if(useDrawSnapshot||Android) == retained-dl-displayport-1.html retained-dl-displayport-1-ref.html +skip-if(useDrawSnapshot) == retained-dl-prerender-transform-1.html retained-dl-prerender-transform-1-ref.html +skip-if(useDrawSnapshot) == retained-dl-animation-on-pseudo.html retained-dl-animation-on-pseudo-ref.html # -skip-if(!retainedDisplayList||!asyncPan) == retained-dl-async-scrolled-1.html retained-dl-async-scrolled-1-ref.html -skip-if(!retainedDisplayList) == retained-dl-remove-for-ancestor-change-1.html retained-dl-remove-for-ancestor-change-1-ref.html -skip-if(!retainedDisplayList) == retained-dl-scroll-out-of-view-1.html retained-dl-scroll-out-of-view-1-ref.html -skip-if(!retainedDisplayList) == retained-dl-opacity-animation-on-ib-split.html retained-dl-opacity-animation-on-ib-split-ref.html -skip-if(!retainedDisplayList) == 1544948-1.html 1544948-1-ref.html +skip-if(useDrawSnapshot) == retained-dl-async-scrolled-1.html retained-dl-async-scrolled-1-ref.html +skip-if(useDrawSnapshot) == retained-dl-remove-for-ancestor-change-1.html retained-dl-remove-for-ancestor-change-1-ref.html +skip-if(useDrawSnapshot) == retained-dl-scroll-out-of-view-1.html retained-dl-scroll-out-of-view-1-ref.html +skip-if(useDrawSnapshot) == retained-dl-opacity-animation-on-ib-split.html retained-dl-opacity-animation-on-ib-split-ref.html +skip-if(useDrawSnapshot) == 1544948-1.html 1544948-1-ref.html -skip-if(!retainedDisplayListNew) == reuse-sc-style-change-1.html reuse-sc-style-change-1-ref.html -skip-if(!retainedDisplayListNew) == reuse-sc-style-change-nested-1.html reuse-sc-style-change-nested-1-ref.html -skip-if(!retainedDisplayListNew) == reuse-sc-style-change-abs-pos-1.html reuse-sc-style-change-abs-pos-1-ref.html -skip-if(!retainedDisplayListNew) == reuse-sc-style-change-fixed-pos-1.html reuse-sc-style-change-fixed-pos-1-ref.html +skip == reuse-sc-style-change-1.html reuse-sc-style-change-1-ref.html +skip == reuse-sc-style-change-nested-1.html reuse-sc-style-change-nested-1-ref.html +skip == reuse-sc-style-change-abs-pos-1.html reuse-sc-style-change-abs-pos-1-ref.html +skip == reuse-sc-style-change-fixed-pos-1.html reuse-sc-style-change-fixed-pos-1-ref.html == retained-dl-wrap-list.html retained-dl-wrap-list-ref.html == retained-dl-zindex-1.html retained-dl-zindex-1-ref.html @@ -38,7 +38,7 @@ needs-focus fuzzy(0-3,0-2) == 1429027-1.html 1429027-1-ref.html == 1432553-1.html 1432553-1-ref.html == 1432553-2.html 1432553-2-ref.html == 1436189-1.html 1436189-1-ref.html -skip-if(!asyncPan) == 1437374-1.html 1437374-1-ref.html +skip-if(useDrawSnapshot) == 1437374-1.html 1437374-1-ref.html == 1439809-1.html 1439809-1-ref.html == 1443027-1.html 1443027-ref.html == 1443027-2.html 1443027-ref.html @@ -48,13 +48,13 @@ skip-if(!asyncPan) == 1437374-1.html 1437374-1-ref.html == 1453541-2.html 1453541-ref.html == 1452805-1.html 1452805-ref.html == 1461231-1.html about:blank -fuzzy(0-2,0-40000) skip-if(!asyncPan) == 1464288-1.html 1464288-ref.html +fuzzy(0-2,0-40000) skip-if(useDrawSnapshot) == 1464288-1.html 1464288-ref.html == 1482403-1.html 1482403-1-ref.html == 1504233-1.html 1504233-1-ref.html == 1533317-1.html 1533317-1-ref.html fuzzy-if(swgl,0-1,0-1) == 1551053-1.html 1551053-1-ref.html == 1553828-1.html 1553828-1-ref.html -fuzzy-if(browserIsFission,0-1,0-300) == 1619370-1.html 1619370-1-ref.html +fuzzy-if(fission,0-1,0-300) == 1619370-1.html 1619370-1-ref.html == 1677568-1.html 1677568-1-ref.html == 1709452-1.html 1709452-ref.html == 1719346-1.html 1719346-1-ref.html diff --git a/layout/reftests/first-letter/reftest.list b/layout/reftests/first-letter/reftest.list index b6aaa5e5e6..72c6e6739f 100644 --- a/layout/reftests/first-letter/reftest.list +++ b/layout/reftests/first-letter/reftest.list @@ -23,7 +23,7 @@ fails == quote-1e.html quote-1-ref.html # bug 509685 == quote-1e.html quote-1b.html == quote-1f.html quote-1-ref.html == dynamic-1.html dynamic-1-ref.html -random-if(d2d) == dynamic-2.html dynamic-2-ref.html +random-if(winWidget) == dynamic-2.html dynamic-2-ref.html == dynamic-3a.html dynamic-3-ref.html == dynamic-3b.html dynamic-3-ref.html == dynamic-4.html dynamic-4-ref.html @@ -66,7 +66,7 @@ fails-if(winWidget||cocoaWidget) fails-if(geckoview) == 617869-1.html 617869-1-r == 922550-1.html 922550-1-ref.html == 958249.html 958249-ref.html == font-text-styles.html font-text-styles-ref.html -random-if(gtkWidget) random-if(winWidget&&!d2d) == font-text-styles-floater.html font-text-styles-floater-ref.html # bug 992846 +random-if(gtkWidget) == font-text-styles-floater.html font-text-styles-floater-ref.html # bug 992846 == inline-height-empty.html inline-height-empty-ref.html == indic-clusters-1.html indic-clusters-1-ref.html == overflow-float-nooverflow.html overflow-float-nooverflow-ref.html diff --git a/layout/reftests/floats/reftest.list b/layout/reftests/floats/reftest.list index c35925f2ce..701673f534 100644 --- a/layout/reftests/floats/reftest.list +++ b/layout/reftests/floats/reftest.list @@ -91,8 +91,8 @@ fuzzy(0-1,0-12000) == float-in-rtl-4d.html float-in-rtl-4-ref.html == float-in-rtl-vrl-4b.html float-in-rtl-vrl-4-ref.html == float-in-rtl-vrl-4c.html float-in-rtl-vrl-4-ref.html == float-in-rtl-vrl-4d.html float-in-rtl-vrl-4-ref.html -fuzzy-if(OSX,0-28,0-11) fuzzy-if(Android,0-16,0-2) == orthogonal-floats-1a.html orthogonal-floats-1-ref.html -fuzzy-if(OSX,0-28,0-11) fuzzy-if(winWidget,0-137,0-3) == orthogonal-floats-1b.html orthogonal-floats-1-ref.html +fuzzy-if(cocoaWidget,0-28,0-11) fuzzy-if(Android,0-16,0-2) == orthogonal-floats-1a.html orthogonal-floats-1-ref.html +fuzzy-if(cocoaWidget,0-28,0-11) fuzzy-if(winWidget,0-137,0-3) == orthogonal-floats-1b.html orthogonal-floats-1-ref.html fuzzy-if(winWidget,0-135,0-700) == orthogonal-floats-1c.html orthogonal-floats-1-ref.html fuzzy-if(winWidget,0-135,0-700) == orthogonal-floats-1d.html orthogonal-floats-1-ref.html diff --git a/layout/reftests/font-face/reftest.list b/layout/reftests/font-face/reftest.list index 920a53a4d0..5d534ead55 100644 --- a/layout/reftests/font-face/reftest.list +++ b/layout/reftests/font-face/reftest.list @@ -1,9 +1,9 @@ != download-1.html download-1-notref.html == download-2.html download-2-ref.html != download-2.html about:blank -random-if(winWidget||gtkWidget) == download-2-big.html download-2-big-otf.html # bug 470713 +random-if(gtkWidget||winWidget) == download-2-big.html download-2-big-otf.html # bug 470713 != download-2-big-otf.html about:blank -asserts-if(Android&&!asyncPan,1-8) != download-3-notref.html download-3.html # bug 1019192 +!= download-3-notref.html download-3.html # bug 1019192 asserts-if(Android,0-8) == download-3-ref.html download-3.html # same bugs as above asserts-if(Android,0-8) == fallback-to-system-1.html fallback-to-system-1-ref.html # just delayed assertions from above tests == name-override-simple-1.html name-override-simple-1-ref.html @@ -13,7 +13,7 @@ fails == name-override-1.html name-override-1-ref.html != multiple-descriptor-1.html multiple-descriptor-1-notref.html == src-list-1.html src-list-1-ref.html == src-list-2.html src-list-2-ref.html -random-if(winWidget||gtkWidget) == src-list-2-big-otf.html src-list-2-big-ref.html # bug 470713 +random-if(gtkWidget||winWidget) == src-list-2-big-otf.html src-list-2-big-ref.html # bug 470713 == src-list-format-1.html src-list-format-1-ref.html == src-list-format-2.html src-list-format-2-ref.html == src-list-format-4.html src-list-format-1-ref.html @@ -154,9 +154,9 @@ HTTP(..) == font-redirect.html order-1-ref.html == dynamic-duplicate-rule-1c.html dynamic-duplicate-rule-1-ref.html # Test for COLR and CPAL support -fuzzy-if(OSX,198-198,172-172) == color-1a.html color-1-ref.html +fuzzy-if(cocoaWidget,198-198,172-172) == color-1a.html color-1-ref.html != color-1a.html color-1-notref.html -fuzzy-if(OSX,198-198,172-172) == color-1b.html color-1-ref.html +fuzzy-if(cocoaWidget,198-198,172-172) == color-1b.html color-1-ref.html == color-2a.html color-2-ref.html != color-2a.html color-2-notref.html diff --git a/layout/reftests/font-inflation/reftest.list b/layout/reftests/font-inflation/reftest.list index 20548830e7..7be883a42f 100644 --- a/layout/reftests/font-inflation/reftest.list +++ b/layout/reftests/font-inflation/reftest.list @@ -37,7 +37,7 @@ test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceE test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == textarea-3.html textarea-3-ref.html test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == css-transform-1.html css-transform-1-ref.html test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) fuzzy(0-1,0-19) == css-transform-2.html css-transform-2-ref.html -fuzzy-if(asyncPan&&!layersGPUAccelerated,0-102,0-1764) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == container-with-clamping.html container-with-clamping-ref.html +test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == container-with-clamping.html container-with-clamping-ref.html test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) load video-1.html test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == intrinsic-min-1.html intrinsic-min-1-ref.html test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == intrinsic-max-1.html intrinsic-max-1-ref.html diff --git a/layout/reftests/font-matching/reftest.list b/layout/reftests/font-matching/reftest.list index fe5f3a2065..0fd4a4ce1f 100644 --- a/layout/reftests/font-matching/reftest.list +++ b/layout/reftests/font-matching/reftest.list @@ -147,14 +147,14 @@ random-if(Android) != emoji-subregion-flag.html emoji-subregion-flag-notref.html # Bug 1212731 - initial implementation caused startup regression and # regression with full-width digits display in UI elements. Disable # tests until these problems are corrected. -# random-if(!OSX) == system-generic-fallback-1.html system-generic-fallback-1-ref.html -# random-if(!OSX) == system-generic-fallback-2.html system-generic-fallback-2-ref.html -# random-if(!OSX) == system-generic-fallback-3.html system-generic-fallback-3-ref.html -# random-if(!OSX) == system-generic-fallback-4.html system-generic-fallback-4-ref.html -# random-if(!OSX) != system-generic-fallback-ko.html system-generic-fallback-ja.html -# random-if(!OSX) != system-generic-fallback-zh-tw.html system-generic-fallback-ja.html -# random-if(!OSX) != system-generic-fallback-zh-cn.html system-generic-fallback-ja.html -# random-if(!OSX) != system-generic-fallback-zh-tw.html system-generic-fallback-zh-cn.html +# random-if(!cocoaWidget) == system-generic-fallback-1.html system-generic-fallback-1-ref.html +# random-if(!cocoaWidget) == system-generic-fallback-2.html system-generic-fallback-2-ref.html +# random-if(!cocoaWidget) == system-generic-fallback-3.html system-generic-fallback-3-ref.html +# random-if(!cocoaWidget) == system-generic-fallback-4.html system-generic-fallback-4-ref.html +# random-if(!cocoaWidget) != system-generic-fallback-ko.html system-generic-fallback-ja.html +# random-if(!cocoaWidget) != system-generic-fallback-zh-tw.html system-generic-fallback-ja.html +# random-if(!cocoaWidget) != system-generic-fallback-zh-cn.html system-generic-fallback-ja.html +# random-if(!cocoaWidget) != system-generic-fallback-zh-tw.html system-generic-fallback-zh-cn.html # Tests for legacy font family name (GDI-model families) matching; # these depend on specific fonts that are available as standard on macOS and Windows, diff --git a/layout/reftests/forms/fieldset/reftest.list b/layout/reftests/forms/fieldset/reftest.list index f99032a3ec..86d6250a44 100644 --- a/layout/reftests/forms/fieldset/reftest.list +++ b/layout/reftests/forms/fieldset/reftest.list @@ -5,7 +5,7 @@ fuzzy(0-2,0-13) == dynamic-legend-scroll-1.html dynamic-legend-scroll-1-ref.html == fieldset-scroll-1.html fieldset-scroll-1-ref.html == fieldset-scrolled-1.html fieldset-scrolled-1-ref.html == fieldset-overflow-auto-1.html fieldset-overflow-auto-1-ref.html -fuzzy-if(!layersGPUAccelerated,0-142,0-276) == positioned-container-1.html positioned-container-1-ref.html +== positioned-container-1.html positioned-container-1-ref.html == relpos-legend-1.html relpos-legend-1-ref.html == relpos-legend-2.html relpos-legend-2-ref.html == relpos-legend-3.html relpos-legend-3-ref.html diff --git a/layout/reftests/forms/input/file/reftest.list b/layout/reftests/forms/input/file/reftest.list index 2ad51b2f69..d8276cb941 100644 --- a/layout/reftests/forms/input/file/reftest.list +++ b/layout/reftests/forms/input/file/reftest.list @@ -5,7 +5,7 @@ fuzzy(0-1,0-10) == background.html chrome://reftest/content/forms/input/file/bac fuzzy-if(gtkWidget,0-1,0-10) == style.html chrome://reftest/content/forms/input/file/style-ref.xhtml != width-clip.html width-clip-ref.html == color-inherit.html color-inherit-ref.html -pref(widget.non-native-theme.webrender,true) fuzzy(0-1,0-5) fuzzy-if(OSX,0-46,0-134) == dynamic-max-width.html dynamic-max-width-ref.html # bug 1496542 for webrender, bug 1724582 for appleSilicon +pref(widget.non-native-theme.webrender,true) fuzzy(0-1,0-5) fuzzy-if(cocoaWidget,0-46,0-134) == dynamic-max-width.html dynamic-max-width-ref.html # bug 1496542 for webrender, bug 1724582 for appleSilicon == label-min-inline-size.html label-min-inline-size-ref.html == css-overflow.html css-overflow-ref.html == css-display.html css-display-ref.html diff --git a/layout/reftests/forms/input/number/number.html b/layout/reftests/forms/input/number/number.html new file mode 100644 index 0000000000..0b4221fe70 --- /dev/null +++ b/layout/reftests/forms/input/number/number.html @@ -0,0 +1,2 @@ + + diff --git a/layout/reftests/forms/input/number/reftest.list b/layout/reftests/forms/input/number/reftest.list index 0a50ef8113..256e3f1df1 100644 --- a/layout/reftests/forms/input/number/reftest.list +++ b/layout/reftests/forms/input/number/reftest.list @@ -1,5 +1,5 @@ # sanity checks: -!= not-other-type-unthemed-1.html not-other-type-unthemed-1a-notref.html +fails-if(Android) pref(dom.forms.number.hide_spin_buttons_when_no_hover_or_focus,false) != not-other-type-unthemed-1.html not-other-type-unthemed-1a-notref.html != not-other-type-unthemed-1.html not-other-type-unthemed-1b-notref.html # should look the same as type=text, except for the spin box @@ -17,7 +17,7 @@ fuzzy(0-2,0-13) == show-value.html show-value-ref.html # disabled == number-disabled.html number-disabled-ref.html -!= number-spinbox-disabled.html number-spinbox-disabled-notref.html +fails-if(Android) pref(dom.forms.number.hide_spin_buttons_when_no_hover_or_focus,false) != number-spinbox-disabled.html number-spinbox-disabled-notref.html # auto width: == number-auto-width-1.html number-auto-width-1-ref.html @@ -72,3 +72,5 @@ fuzzy(0-14,0-4) == clipped-text.html clipped-text-ref.html fails-if(useDrawSnapshot) needs-focus != caret-right.html caret-right-notref.html fails-if(useDrawSnapshot) needs-focus != caret-left-rtl.html caret-left-rtl-notref.html fails-if(useDrawSnapshot) needs-focus != caret-right-vertical.html caret-right-vertical-notref.html + +fails-if(Android) test-pref(dom.forms.number.hide_spin_buttons_when_no_hover_or_focus,true) ref-pref(dom.forms.number.hide_spin_buttons_when_no_hover_or_focus,false) != number.html number.html diff --git a/layout/reftests/forms/input/radio/reftest.list b/layout/reftests/forms/input/radio/reftest.list index 6c80eaf447..f500a83d0d 100644 --- a/layout/reftests/forms/input/radio/reftest.list +++ b/layout/reftests/forms/input/radio/reftest.list @@ -5,5 +5,5 @@ != checked-native.html about:blank != checked-native-notref.html about:blank == radio-clamp-01.html radio-clamp-01-ref.html -skip-if(OSX||winWidget||Android) == radio-clamp-02.html radio-clamp-02-ref.html +skip-if(!gtkWidget) == radio-clamp-02.html radio-clamp-02-ref.html != radio-minimum-size.html radio-minimum-size-notref.html diff --git a/layout/reftests/forms/input/text/autofill-author-background.html b/layout/reftests/forms/input/text/autofill-author-background.html new file mode 100644 index 0000000000..691adaa1ff --- /dev/null +++ b/layout/reftests/forms/input/text/autofill-author-background.html @@ -0,0 +1,9 @@ + + + diff --git a/layout/reftests/forms/input/text/reftest.list b/layout/reftests/forms/input/text/reftest.list index b6217d46bc..6c649a5196 100644 --- a/layout/reftests/forms/input/text/reftest.list +++ b/layout/reftests/forms/input/text/reftest.list @@ -15,9 +15,10 @@ fuzzy(0-1,0-500) needs-focus == select.html select-ref.html == autofill-blank.html autofill-preview-blank.html != autofill.html autofill-blank.html != autofill-preview.html autofill-preview-blank.html -!= autofill.html autofill-preview.html +== autofill.html autofill-preview.html == autofill-prefilled-value.html autofill-preview.html == autofill-preview-line-height.html autofill-line-height.html +== autofill-author-background.html autofill.html == pseudo-class-lock.html pseudo-class-lock-ref.html diff --git a/layout/reftests/forms/placeholder/reftest.list b/layout/reftests/forms/placeholder/reftest.list index 54ec3b06e0..1e00ce0131 100644 --- a/layout/reftests/forms/placeholder/reftest.list +++ b/layout/reftests/forms/placeholder/reftest.list @@ -18,9 +18,9 @@ == placeholder-5.html placeholder-visible-ref.html # This tests assumes that the overflowing placeholder won't eat the padding, which is just not true in some platforms... -fuzzy-if(winWidget,0-160,0-10) fuzzy-if(Android,0-160,0-41) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-146,0-317) == placeholder-6.html placeholder-overflow-ref.html +fuzzy-if(winWidget,0-160,0-10) fuzzy-if(Android,0-160,0-41) == placeholder-6.html placeholder-overflow-ref.html -skip-if(Android&&asyncPan) == placeholder-6-textarea.html placeholder-overflow-textarea-ref.html +skip-if(Android) == placeholder-6-textarea.html placeholder-overflow-textarea-ref.html # needs-focus == placeholder-7.html placeholder-focus-ref.html # needs-focus == placeholder-8.html placeholder-focus-ref.html # needs-focus == placeholder-9.html placeholder-focus-ref.html diff --git a/layout/reftests/forms/textarea/reftest.list b/layout/reftests/forms/textarea/reftest.list index f27e99726e..ee9c32d4e9 100644 --- a/layout/reftests/forms/textarea/reftest.list +++ b/layout/reftests/forms/textarea/reftest.list @@ -12,7 +12,7 @@ skip-if(Android) != rtl.html no-resize.html # bug 834724 fuzzy(0-1,0-1) == rtl.html rtl-dynamic-attr.html fuzzy(0-1,0-1) == rtl.html rtl-dynamic-style.html == rtl.html in-dynamic-rtl-doc.html -fuzzy-if(asyncPan&&!layersGPUAccelerated,0-102,0-4168) == padding-scrollbar-placement.html padding-scrollbar-placement-ref.html +== padding-scrollbar-placement.html padding-scrollbar-placement-ref.html == various-cols.html various-cols-ref.html == appearance-background-change.html appearance-background-change-ref.html != padding-text-overflow.html padding-text-overflow-notref.html diff --git a/layout/reftests/forms/textbox/reftest.list b/layout/reftests/forms/textbox/reftest.list index edb83da6e2..9717969ebd 100644 --- a/layout/reftests/forms/textbox/reftest.list +++ b/layout/reftests/forms/textbox/reftest.list @@ -8,4 +8,3 @@ skip-if(cocoaWidget||Android) != chrome://reftest/content/forms/textbox/accesske fuzzy(0-1,0-4) skip-if(cocoaWidget||Android) == chrome://reftest/content/forms/textbox/accesskey-4.xhtml chrome://reftest/content/forms/textbox/accesskey-4-ref.xhtml skip-if(cocoaWidget||Android) != chrome://reftest/content/forms/textbox/accesskey-4.xhtml chrome://reftest/content/forms/textbox/accesskey-4-notref.xhtml skip-if(Android) == chrome://reftest/content/forms/textbox/align-baseline-1.xhtml chrome://reftest/content/forms/textbox/align-baseline-1-ref.xhtml # test for bug 494901 -skip-if(Android) == chrome://reftest/content/forms/textbox/setsize.xhtml chrome://reftest/content/forms/textbox/setsize-ref.xhtml diff --git a/layout/reftests/forms/textbox/setsize-ref.xhtml b/layout/reftests/forms/textbox/setsize-ref.xhtml deleted file mode 100644 index 5db79ff9d9..0000000000 --- a/layout/reftests/forms/textbox/setsize-ref.xhtml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/layout/reftests/forms/textbox/setsize.xhtml b/layout/reftests/forms/textbox/setsize.xhtml deleted file mode 100644 index 14ccdfb27b..0000000000 --- a/layout/reftests/forms/textbox/setsize.xhtml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/layout/reftests/high-contrast/reftest.list b/layout/reftests/high-contrast/reftest.list index 0057a92b2e..d6e2dbbfe7 100644 --- a/layout/reftests/high-contrast/reftest.list +++ b/layout/reftests/high-contrast/reftest.list @@ -103,3 +103,4 @@ pref(ui.use_standins_for_native_colors,false) pref(browser.display.use_system_co # Forced color adjust pref(layout.css.forced-color-adjust.enabled,true) == backplate-force-color-adjust.html backplate-force-color-adjust-ref.html +== transparent-textarea.html transparent-textarea-ref.html diff --git a/layout/reftests/high-contrast/transparent-textarea-ref.html b/layout/reftests/high-contrast/transparent-textarea-ref.html new file mode 100644 index 0000000000..1c9fb2288e --- /dev/null +++ b/layout/reftests/high-contrast/transparent-textarea-ref.html @@ -0,0 +1,4 @@ + +
+  PASS
+
diff --git a/layout/reftests/high-contrast/transparent-textarea.html b/layout/reftests/high-contrast/transparent-textarea.html new file mode 100644 index 0000000000..a82aef57d5 --- /dev/null +++ b/layout/reftests/high-contrast/transparent-textarea.html @@ -0,0 +1,17 @@ + + + +
+  PASS
+
diff --git a/layout/reftests/image-element/reftest.list b/layout/reftests/image-element/reftest.list index 2b31398ccf..a31ebb89b8 100644 --- a/layout/reftests/image-element/reftest.list +++ b/layout/reftests/image-element/reftest.list @@ -5,30 +5,30 @@ random == bug-364968.html bug-364968-ref.html == mozsetimageelement-02.html about:blank == image-outside-document-invalidate.html about:blank == canvas-outside-document-invalidate-01.html about:blank -fails-if(azureSkia&&!winWidget) fails-if(cocoaWidget) fails-if(remoteCanvas&&swgl&&winWidget) == canvas-outside-document-invalidate-02.html about:blank # See bug 666800 +fails-if(!winWidget) fails-if(swgl&&winWidget) == canvas-outside-document-invalidate-02.html about:blank # See bug 666800 #fails with Skia due to Skia bug http://code.google.com/p/skia/issues/detail?id=568 fuzzy-if(winWidget,47-129,47-54) == element-paint-simple.html element-paint-simple-ref.html == element-paint-repeated.html element-paint-repeated-ref.html == element-paint-recursion.html element-paint-recursion-ref.html == element-paint-continuation.html element-paint-continuation-ref.html == element-paint-transform-01.html element-paint-transform-01-ref.html -random-if(d2d) fuzzy-if(!useDrawSnapshot,255-255,39-42) == element-paint-transform-02.html element-paint-transform-02-ref.html # bug 587133 +random-if(winWidget) fuzzy-if(!useDrawSnapshot,255-255,39-42) == element-paint-transform-02.html element-paint-transform-02-ref.html # bug 587133 == element-paint-background-size-01.html element-paint-background-size-01-ref.html == element-paint-background-size-02.html element-paint-background-size-02-ref.html fuzzy(0-255,0-4) == element-paint-transform-repeated.html element-paint-transform-repeated-ref.html # Bug 1475907 -fuzzy-if(d2d,0-255,0-24) fuzzy-if(!useDrawSnapshot,255-255,50-115) == element-paint-transform-03.html element-paint-transform-03-ref.html +fuzzy-if(winWidget,0-255,0-24) fuzzy-if(!useDrawSnapshot,255-255,50-115) == element-paint-transform-03.html element-paint-transform-03-ref.html # For element() uses fallback / skia in WebRender, which antialiases differently from WR. # For Windows: bug 1496542, the scrollframe snaps differently. # For the rest: -ref the scrollframe is active and layerized differently with APZ. -fuzzy(0-24,0-106) fuzzy-if(winWidget&&!layersGPUAccelerated,149-149,1203-1203) fuzzy-if(!useDrawSnapshot,1-48,5-68) fuzzy-if(winWidget,47-222,1197-1588) fuzzy-if(Android,0-40,0-81) == element-paint-native-widget.html element-paint-native-widget-ref.html +fuzzy(0-24,0-106) fuzzy-if(!useDrawSnapshot,1-48,5-68) fuzzy-if(winWidget,47-222,1197-1588) fuzzy-if(Android,0-40,0-81) == element-paint-native-widget.html element-paint-native-widget-ref.html # This fails with CreateSamplingRestrictedDrawable removed fails-if(!Android&&!useDrawSnapshot) == element-paint-subimage-sampling-restriction.html about:blank == element-paint-clippath.html element-paint-clippath-ref.html -fuzzy-if(!useDrawSnapshot,1-1,128-128) fuzzy-if(d2d,47-47,650-652) fuzzy-if(!useDrawSnapshot,36-39,704-738) == element-paint-sharpness-01a.html element-paint-sharpness-01b.html +fuzzy-if(winWidget,47-47,650-652) fuzzy-if(!useDrawSnapshot,36-39,704-738) == element-paint-sharpness-01a.html element-paint-sharpness-01b.html fuzzy(0-1,0-326) fails-if(useDrawSnapshot) == element-paint-sharpness-01b.html element-paint-sharpness-01c.html -fuzzy-if(!useDrawSnapshot,1-1,128-128) fuzzy-if(d2d,47-47,650-652) fuzzy-if(!useDrawSnapshot,36-39,704-738) == element-paint-sharpness-01c.html element-paint-sharpness-01d.html +fuzzy-if(winWidget,47-47,650-652) fuzzy-if(!useDrawSnapshot,36-39,704-738) == element-paint-sharpness-01c.html element-paint-sharpness-01d.html == element-paint-sharpness-02a.html element-paint-sharpness-02b.html fails-if(useDrawSnapshot) == element-paint-sharpness-02b.html element-paint-sharpness-02c.html == element-paint-paintserversize-rounding-01.html element-paint-paintserversize-rounding-01-ref.html diff --git a/layout/reftests/image/reftest.list b/layout/reftests/image/reftest.list index ad07b512fe..e6e24a1cf5 100644 --- a/layout/reftests/image/reftest.list +++ b/layout/reftests/image/reftest.list @@ -1,5 +1,5 @@ fuzzy-if(Android,0-8,0-30) fails-if(useDrawSnapshot) == background-image-zoom-1.html background-image-zoom-1-ref.html -fails-if(usesRepeatResampling&&!winWidget) fails-if(useDrawSnapshot) == background-image-zoom-2.html about:blank +fails-if(useDrawSnapshot) == background-image-zoom-2.html about:blank == image-in-iframe-1.html image-in-iframe-1-ref.html == image-seam-1a.html image-seam-1-ref.html == image-seam-1b.html image-seam-1-ref.html diff --git a/layout/reftests/invalidation/reftest.list b/layout/reftests/invalidation/reftest.list index 27b228fa2b..99465a7f7f 100644 --- a/layout/reftests/invalidation/reftest.list +++ b/layout/reftests/invalidation/reftest.list @@ -97,7 +97,7 @@ pref(layers.single-tile.enabled,false) != fast-scrolling.html about:blank == clip-path-invalidation-1d.html mask-invalidation-2-ref.html != fractional-transform-1.html about:blank -skip-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) != fractional-transform-2.html about:blank +skip-if(winWidget) != fractional-transform-2.html about:blank != fractional-transform-3.html about:blank == partially-scrolled-svg-group.html partially-scrolled-svg-group-ref.html diff --git a/layout/reftests/layers/reftest.list b/layout/reftests/layers/reftest.list index f65a93a165..d200d69d70 100644 --- a/layout/reftests/layers/reftest.list +++ b/layout/reftests/layers/reftest.list @@ -16,19 +16,19 @@ skip != pull-background-animated-position-3.html about:blank # Fails because Pai skip != pull-background-animated-position-4.html about:blank # Fails because PaintedLayer item assignment and background pulling don't recognize overflow:hidden clips skip != pull-background-animated-position-5.html about:blank # Fails because ownLayer bounds don't anticipate changes of animated contents, but doesn't fail with event regions -skip-if(!asyncPan) != pull-background-displayport-1.html about:blank -skip-if(!asyncPan) != pull-background-displayport-2.html about:blank -skip-if(!asyncPan) != pull-background-displayport-3.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 -skip-if(!asyncPan) != pull-background-displayport-4.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 -skip-if(!asyncPan) != pull-background-displayport-5.html about:blank -skip-if(!asyncPan) != pull-background-displayport-6.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 +skip-if(useDrawSnapshot) != pull-background-displayport-1.html about:blank +skip-if(useDrawSnapshot) != pull-background-displayport-2.html about:blank +skip-if(useDrawSnapshot) != pull-background-displayport-3.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 +skip-if(useDrawSnapshot) != pull-background-displayport-4.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 +skip-if(useDrawSnapshot) != pull-background-displayport-5.html about:blank +skip-if(useDrawSnapshot) != pull-background-displayport-6.html about:blank # fails with non-overlay scrollbars and event regions due to bug 1148515 skip-if(Android&&emulator) fuzzy(0-2,0-30150) == opacity-blending.html opacity-blending-ref.html fuzzy(0-16,0-30) == mask-layer-transform.html mask-layer-transform-ref.html fuzzy-if(gtkWidget,0-1,0-17) fuzzy-if(Android,0-3,0-4) == forced-bg-color-outside-visible-region.html forced-bg-color-outside-visible-region-ref.html != layerize-over-fixed-bg-1.html about:blank -skip-if(!asyncPan) != fixed-pos-scrolled-clip-layerize.html about:blank -skip-if(!asyncPan) == fixed-pos-scrolled-clip-opacity-layerize.html fixed-pos-scrolled-clip-opacity-inside-layerize.html +skip-if(useDrawSnapshot) != fixed-pos-scrolled-clip-layerize.html about:blank +skip-if(useDrawSnapshot) == fixed-pos-scrolled-clip-opacity-layerize.html fixed-pos-scrolled-clip-opacity-inside-layerize.html fuzzy(0-1,0-8033) == opacity-background-1.html opacity-background-1-ref.html == opacity-flattening-large-image.html opacity-flattening-large-image-ref.html diff --git a/layout/reftests/list-item/reftest.list b/layout/reftests/list-item/reftest.list index 36ab01f78b..5ade8fe480 100644 --- a/layout/reftests/list-item/reftest.list +++ b/layout/reftests/list-item/reftest.list @@ -1,7 +1,7 @@ -fuzzy-if(OSX,0-55,0-4) == numbering-1.html numbering-1-ref.html +fuzzy-if(cocoaWidget,0-55,0-4) == numbering-1.html numbering-1-ref.html == numbering-2.html numbering-2-ref.html -fuzzy-if(OSX,0-11,0-1) == numbering-3.html numbering-3-ref.html -fuzzy-if(OSX,0-76,0-2) == numbering-4.html numbering-4-ref.html +fuzzy-if(cocoaWidget,0-11,0-1) == numbering-3.html numbering-3-ref.html +fuzzy-if(cocoaWidget,0-76,0-2) == numbering-4.html numbering-4-ref.html == numbering-5.html numbering-5-ref.html == ol-reversed-1a.html ol-reversed-1-ref.html == ol-reversed-1b.html ol-reversed-1-ref.html diff --git a/layout/reftests/mathml/largeop-1-ref.html b/layout/reftests/mathml/largeop-1-ref.html deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/layout/reftests/mathml/largeop-1.html b/layout/reftests/mathml/largeop-1.html deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/layout/reftests/mathml/mathml-mmultiscript-base-ref.html b/layout/reftests/mathml/mathml-mmultiscript-base-ref.html deleted file mode 100644 index 45f43e9f9b..0000000000 --- a/layout/reftests/mathml/mathml-mmultiscript-base-ref.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - mmultiscript with only base - - - - - - base - - - - diff --git a/layout/reftests/mathml/mathml-mmultiscript-base.html b/layout/reftests/mathml/mathml-mmultiscript-base.html deleted file mode 100644 index f2832df479..0000000000 --- a/layout/reftests/mathml/mathml-mmultiscript-base.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - mmultiscript with only base and none as placeholder - - - - - - base - - - - - - diff --git a/layout/reftests/mathml/mathml-mmultiscript-mprescript-ref.html b/layout/reftests/mathml/mathml-mmultiscript-mprescript-ref.html deleted file mode 100644 index b30e7fb976..0000000000 --- a/layout/reftests/mathml/mathml-mmultiscript-mprescript-ref.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - mmultiscript with mprescripts without none - - - - - - base - - - - - diff --git a/layout/reftests/mathml/mathml-mmultiscript-mprescript.html b/layout/reftests/mathml/mathml-mmultiscript-mprescript.html deleted file mode 100644 index 5bc0b5a5ad..0000000000 --- a/layout/reftests/mathml/mathml-mmultiscript-mprescript.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - mmultiscript with mprescripts with none as placeholders - - - - - - base - - - - - - - - diff --git a/layout/reftests/mathml/mirror-op-1-ref.html b/layout/reftests/mathml/mirror-op-1-ref.html deleted file mode 100644 index d7515156c3..0000000000 --- a/layout/reftests/mathml/mirror-op-1-ref.html +++ /dev/null @@ -1,19 +0,0 @@ - - - Test mirror op - - - -

(

-

)

-

[

-

]

-

{

-

}

- - - diff --git a/layout/reftests/mathml/mirror-op-1.html b/layout/reftests/mathml/mirror-op-1.html deleted file mode 100644 index bb59e16c23..0000000000 --- a/layout/reftests/mathml/mirror-op-1.html +++ /dev/null @@ -1,14 +0,0 @@ - - - Test mirror op - - -

(

-

)

-

[

-

]

-

{

-

}

- - - diff --git a/layout/reftests/mathml/mirror-op-2-ref.html b/layout/reftests/mathml/mirror-op-2-ref.html deleted file mode 100644 index c67710cca6..0000000000 --- a/layout/reftests/mathml/mirror-op-2-ref.html +++ /dev/null @@ -1,9 +0,0 @@ - - - Test mirror op - - -

- - - diff --git a/layout/reftests/mathml/mirror-op-2.html b/layout/reftests/mathml/mirror-op-2.html deleted file mode 100644 index 5db6819cfe..0000000000 --- a/layout/reftests/mathml/mirror-op-2.html +++ /dev/null @@ -1,9 +0,0 @@ - - - Test mirror op - - -

- - - diff --git a/layout/reftests/mathml/mirror-op-3-ref.html b/layout/reftests/mathml/mirror-op-3-ref.html deleted file mode 100644 index fc3a183ef3..0000000000 --- a/layout/reftests/mathml/mirror-op-3-ref.html +++ /dev/null @@ -1,9 +0,0 @@ - - - Test mirror op - - -

- - - diff --git a/layout/reftests/mathml/mirror-op-3.html b/layout/reftests/mathml/mirror-op-3.html deleted file mode 100644 index 501af10926..0000000000 --- a/layout/reftests/mathml/mirror-op-3.html +++ /dev/null @@ -1,9 +0,0 @@ - - - Test mirror op - - -

- - - diff --git a/layout/reftests/mathml/mirror-op-4-ref.html b/layout/reftests/mathml/mirror-op-4-ref.html deleted file mode 100644 index 6c39a47a33..0000000000 --- a/layout/reftests/mathml/mirror-op-4-ref.html +++ /dev/null @@ -1,9 +0,0 @@ - - - Test mirror op - - -

- - - diff --git a/layout/reftests/mathml/mirror-op-4.html b/layout/reftests/mathml/mirror-op-4.html deleted file mode 100644 index ba1acf89f7..0000000000 --- a/layout/reftests/mathml/mirror-op-4.html +++ /dev/null @@ -1,9 +0,0 @@ - - - Test mirror op - - -

- - - diff --git a/layout/reftests/mathml/mmultiscript-align-ref.html b/layout/reftests/mathml/mmultiscript-align-ref.html deleted file mode 100644 index 337852837f..0000000000 --- a/layout/reftests/mathml/mmultiscript-align-ref.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - alignment of mmultiscript sub/superscripts - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - diff --git a/layout/reftests/mathml/mmultiscript-align.html b/layout/reftests/mathml/mmultiscript-align.html deleted file mode 100644 index 44fb713a34..0000000000 --- a/layout/reftests/mathml/mmultiscript-align.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - alignment of mmultiscript sub/superscripts - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - diff --git a/layout/reftests/mathml/mo-glyph-size-ref.html b/layout/reftests/mathml/mo-glyph-size-ref.html deleted file mode 100644 index e4dd43747e..0000000000 --- a/layout/reftests/mathml/mo-glyph-size-ref.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - -
- - diff --git a/layout/reftests/mathml/mo-glyph-size.html b/layout/reftests/mathml/mo-glyph-size.html deleted file mode 100644 index c0cc726daf..0000000000 --- a/layout/reftests/mathml/mo-glyph-size.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - | - - f - - ( - x - ) - - - - - f - - ( - - x - 0 - - ) - - - - | - - -