Merge mozilla-central to inbound. a=merge CLOSED TREE

This commit is contained in:
Cosmin Sabou 2018-06-01 12:44:57 +03:00
commit 1bc774a842
164 changed files with 2464 additions and 2901 deletions

View File

@ -400,29 +400,6 @@ html|input.urlbar-input {
box-shadow: var(--focus-ring-box-shadow);
}
.editBookmarkPanelBottomButton {
@hudButton@
margin: 0;
min-width: 82px;
min-height: 22px;
}
.editBookmarkPanelBottomButton:hover:active {
@hudButtonPressed@
}
.editBookmarkPanelBottomButton:-moz-focusring {
box-shadow: var(--focus-ring-box-shadow);
}
.editBookmarkPanelBottomButton[default="true"] {
background-color: #666;
}
.editBookmarkPanelBottomButton:last-child {
margin-inline-start: 8px;
}
/* The following elements come from editBookmarkPanel.inc.xul. Styling that's
specific to the editBookmarkPanel should be in browser.css. Styling that
should be shared by all editBookmarkPanel.inc.xul consumers should be in

View File

@ -8,7 +8,6 @@
padding: 0;
}
#editBookmarkPanelBottomButtons,
#editBookmarkPanelRows {
padding: var(--arrowpanel-padding);
}
@ -17,3 +16,42 @@
#editBMPanel_folderTree {
min-width: 27em;
}
#editBookmarkPanelBottomButtons {
display: flex;
}
.editBookmarkPanelBottomButton {
flex: 1;
-moz-appearance: none;
margin: 0;
padding: .8em;
color: inherit;
background-color: var(--arrowpanel-dimmed);
border-top: 1px solid var(--panel-separator-color);
}
.editBookmarkPanelBottomButton:not(:last-child) {
border-inline-end: 1px solid var(--panel-separator-color);
}
.editBookmarkPanelBottomButton:hover {
background-color: var(--arrowpanel-dimmed-further);
}
.editBookmarkPanelBottomButton:hover:active {
background-color: var(--arrowpanel-dimmed-even-further);
}
.editBookmarkPanelBottomButton[default] {
color: white;
background-color: #0996f8;
}
.editBookmarkPanelBottomButton[default]:hover {
background-color: #0675d3;
}
.editBookmarkPanelBottomButton[default]:hover:active {
background-color: #0568ba;
}

View File

@ -110,11 +110,16 @@ class ToolboxTabs extends Component {
*/
updateCachedToolTabsWidthMap() {
let thisNode = findDOMNode(this);
let utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
// Force a reflow before calling getBoundingWithoutFlushing on each tab.
thisNode.clientWidth;
for (let tab of thisNode.querySelectorAll(".devtools-tab")) {
let tabId = tab.id.replace("toolbox-tab-", "");
if (!this._cachedToolTabsWidthMap.has(tabId)) {
let cs = getComputedStyle(tab);
this._cachedToolTabsWidthMap.set(tabId, parseInt(cs.width, 10));
let rect = utils.getBoundsWithoutFlushing(tab);
this._cachedToolTabsWidthMap.set(tabId, rect.width);
}
}
}
@ -160,11 +165,12 @@ class ToolboxTabs extends Component {
let removingToolWidth = this._cachedToolTabsWidthMap.get(removingToolId);
sumWidth -= removingToolWidth;
}
visibleTabs.push(currentToolId);
}
if (visibleTabs.length === 0) {
visibleTabs = [enabledTabs[0]];
// If toolbox width is narrow, toolbox display only chevron menu.
// i.e. All tool tabs will overflow.
if ((sumWidth + selectedToolWidth) <= toolboxWidth) {
visibleTabs.push(currentToolId);
}
}
let willOverflowTabs = enabledTabs.filter(id => !visibleTabs.includes(id));
@ -177,7 +183,7 @@ class ToolboxTabs extends Component {
window.cancelIdleCallback(this._resizeTimerId);
this._resizeTimerId = window.requestIdleCallback(() => {
this.updateOverflowedTabs();
}, { timeout: 300 });
}, { timeout: 100 });
}
/**

View File

@ -88,18 +88,30 @@ class ToolboxToolbar extends Component {
* render functions for how each of the sections is rendered.
*/
render() {
const containerProps = {className: "devtools-tabbar"};
let classnames = ["devtools-tabbar"];
let startButtons = renderToolboxButtonsStart(this.props);
let endButtons = renderToolboxButtonsEnd(this.props);
if (!startButtons) {
classnames.push("devtools-tabbar-has-start");
}
if (!endButtons) {
classnames.push("devtools-tabbar-has-end");
}
return this.props.canRender
? (
div(
containerProps,
renderToolboxButtonsStart(this.props),
{
className: classnames.join(" ")
},
startButtons,
ToolboxTabs(this.props),
renderToolboxButtonsEnd(this.props),
endButtons,
renderToolboxControls(this.props)
)
)
: div(containerProps);
: div({ className: classnames.join(" ") });
}
}

View File

@ -206,6 +206,7 @@ select > option.divider {
#global-toolbar > .toolbar-button::before {
width: 12px;
height: 12px;
background-size: cover;
}
#global-toolbar .toolbar-dropdown {

View File

@ -5,7 +5,9 @@
@import url("resource://devtools/client/themes/splitters.css");
.devtools-toolbox-side-iframe {
min-width: 250px;
/* Toolbar should display the chevron and meatball (and close) button.
This size is sum of chevron and meatball and close button. */
min-width: 74px;
}
/* Eyedropper Widget */

View File

@ -23,7 +23,16 @@
.devtools-tabbar {
-moz-appearance: none;
display: flex;
/* For narrow devtool width, we define the each column width of tabbar.
Defined layout is as follow:
-------------------------------------------------
| Picker | tooltabs | commands | controls |
| auto | 26px ~ 1fr | auto | max-content|
-------------------------------------------------
*/
display: grid;
grid-template-columns: auto minmax(26px, 1fr) auto max-content;
background: var(--theme-tab-toolbar-background);
border-bottom: 1px solid var(--theme-splitter-color);
box-sizing: border-box;
@ -36,6 +45,22 @@
flex: 1;
}
/* These classes use to stretch the tool tabs wrapper width if toolbox does'n
have start buttons or end buttons element. */
.devtools-tabbar .toolbox-tabs-wrapper {
grid-column-start: 2;
grid-column-end: 3;
}
.devtools-tabbar-has-start .toolbox-tabs-wrapper {
grid-column-start: 1;
}
.devtools-tabbar-has-end .toolbox-tabs-wrapper {
grid-column-end: 4;
}
.toolbox-tabs-wrapper .tools-chevron-menu {
border-top-width: 0;
border-bottom-width: 0;
@ -60,6 +85,7 @@
#toolbox-controls {
display: flex;
align-items: stretch;
overflow: hidden;
}
/* Toolbox tabs */
@ -175,11 +201,19 @@
margin-inline-end: 5px;
}
#toolbox-close {
min-width: 24px;
}
#toolbox-close::before {
fill: var(--theme-toolbar-photon-icon-color);
background-image: var(--close-button-image);
}
#toolbox-meatball-menu-button {
min-width: 24px;
}
#toolbox-meatball-menu-button::before {
fill: var(--theme-toolbar-photon-icon-color);
background-image: var(--more-button-image);

View File

@ -16,7 +16,7 @@
'use strict';
function waitForDocLoad() {
return new Promise(function(resolve, reject) {
return new Promise((resolve, reject) => {
if (document.readyState === 'complete') {
resolve();
} else {
@ -26,12 +26,12 @@ function waitForDocLoad() {
}
function waitForPaints() {
return new Promise(function(resolve, reject) {
return new Promise((resolve, reject) => {
waitForAllPaintsFlushed(resolve);
});
}
promise_test(function(t) {
promise_test(async t => {
// Test that empty animations actually start.
//
// Normally we tie the start of animations to when their first frame of
@ -48,32 +48,31 @@ promise_test(function(t) {
//
// As a result, it's better to wait until we have a more stable state before
// continuing.
var div;
var promiseCallbackDone = false;
return waitForDocLoad().then(function() {
div = addDiv(t);
await waitForDocLoad();
return waitForPaints();
}).then(function() {
div.style.animation = 'empty 1000s';
var animation = div.getAnimations()[0];
const div = addDiv(t);
animation.ready.then(function() {
promiseCallbackDone = true;
}).catch(function() {
assert_unreached('ready promise was rejected');
});
await waitForPaints();
// We need to wait for up to three frames. This is because in some
// cases it can take up to two frames for the initial layout
// to take place. Even after that happens we don't actually resolve the
// ready promise until the following tick.
return waitForAnimationFrames(3);
}).then(function() {
assert_true(promiseCallbackDone,
'ready promise for an empty animation was resolved'
+ ' within three animation frames');
div.style.animation = 'empty 1000s';
const animation = div.getAnimations()[0];
let promiseCallbackDone = false;
animation.ready.then(() => {
promiseCallbackDone = true;
}).catch(() => {
assert_unreached('ready promise was rejected');
});
// We need to wait for up to three frames. This is because in some
// cases it can take up to two frames for the initial layout
// to take place. Even after that happens we don't actually resolve the
// ready promise until the following tick.
await waitForAnimationFrames(3);
assert_true(promiseCallbackDone,
'ready promise for an empty animation was resolved'
+ ' within three animation frames');
}, 'Animation.ready is resolved for an empty animation');
// Test that compositor animations with delays get synced correctly
@ -81,7 +80,7 @@ promise_test(function(t) {
// NOTE: It is important that we DON'T use
// SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh here since that takes
// us through a different code path.
promise_test(function(t) {
promise_test(async t => {
assert_false(SpecialPowers.DOMWindowUtils.isTestControllingRefreshes,
'Test should run without the refresh driver being under'
+ ' test control');
@ -96,24 +95,27 @@ promise_test(function(t) {
// As with the above test, any stray paints can cause this test to produce
// a false negative (that is, pass when it should fail). To avoid this we
// wait for paints and only then do we commence the test.
return waitForPaints().then(() => {
await waitForPaints();
const animation =
div.animate({ transform: [ 'translate(0px)', 'translate(100px)' ] },
{ duration: 400 * MS_PER_SEC,
delay: -200 * MS_PER_SEC });
return waitForPaints();
}).then(() => {
const transformStr =
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
const translateX = getTranslateXFromTransform(transformStr);
await waitForAnimationReadyToRestyle(animation);
// If the delay has been applied we should be about half-way through
// the animation. However, if we applied it twice we will be at the
// end of the animation already so check that we are roughly half way
// through.
assert_between_inclusive(translateX, 40, 75,
'Animation is about half-way through on the compositor');
});
await waitForPaints();
const transformStr =
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
const translateX = getTranslateXFromTransform(transformStr);
// If the delay has been applied we should be about half-way through
// the animation. However, if we applied it twice we will be at the
// end of the animation already so check that we are roughly half way
// through.
assert_between_inclusive(translateX, 40, 75,
'Animation is about half-way through on the compositor');
}, 'Starting an animation with a delay starts from the correct point');
// Test that compositor animations with a playback rate start at the
@ -122,7 +124,7 @@ promise_test(function(t) {
// NOTE: As with the previous test, it is important that we DON'T use
// SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh here since that takes
// us through a different code path.
promise_test(function(t) {
promise_test(async t => {
assert_false(SpecialPowers.DOMWindowUtils.isTestControllingRefreshes,
'Test should run without the refresh driver being under'
+ ' test control');
@ -135,27 +137,27 @@ promise_test(function(t) {
const div = addDiv(t, { class: 'target' });
// Wait for the document to load and painting (see notes in previous test).
return waitForPaints().then(() => {
const animation =
div.animate({ transform: [ 'translate(0px)', 'translate(100px)' ] },
200 * MS_PER_SEC);
animation.currentTime = 100 * MS_PER_SEC;
animation.playbackRate = 0.1;
await waitForPaints();
return waitForPaints();
}).then(() => {
const transformStr =
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
const translateX = getTranslateXFromTransform(transformStr);
const animation =
div.animate({ transform: [ 'translate(0px)', 'translate(100px)' ] },
200 * MS_PER_SEC);
animation.currentTime = 100 * MS_PER_SEC;
animation.playbackRate = 0.1;
// We pass the playback rate to the compositor independently and we have
// tests to ensure that it is correctly applied there. However, if, when
// we resolve the start time of the pending animation, we fail to
// incorporate the playback rate, we will end up starting from the wrong
// point and the current time calculated on the compositor will be wrong.
assert_between_inclusive(translateX, 25, 75,
'Animation is about half-way through on the compositor');
});
await waitForPaints();
const transformStr =
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
const translateX = getTranslateXFromTransform(transformStr);
// We pass the playback rate to the compositor independently and we have
// tests to ensure that it is correctly applied there. However, if, when
// we resolve the start time of the pending animation, we fail to
// incorporate the playback rate, we will end up starting from the wrong
// point and the current time calculated on the compositor will be wrong.
assert_between_inclusive(translateX, 25, 75,
'Animation is about half-way through on the compositor');
}, 'Starting an animation with a playbackRate starts from the correct point');
function getTranslateXFromTransform(transformStr) {

View File

@ -132,18 +132,6 @@ function waitForWheelEvent(aTarget) {
});
}
async function waitForAnimationReadyToRestyle(aAnimation) {
await aAnimation.ready;
// If |aAnimation| begins at the current timeline time, we will not process
// restyling in the initial frame because of aligning with the refresh driver,
// the animation frame in which the ready promise is resolved happens to
// coincide perfectly with the start time of the animation. In this case no
// restyling is needed in the frame so we have to wait one more frame.
if (animationStartsRightNow(aAnimation)) {
await waitForNextFrame();
}
}
var omtaEnabled = isOMTAEnabled();
const isWebRender =

View File

@ -423,3 +423,15 @@ function animationStartsRightNow(aAnimation) {
aAnimation.currentTime === 0;
}
// Waits for a given animation being ready to restyle.
async function waitForAnimationReadyToRestyle(aAnimation) {
await aAnimation.ready;
// If |aAnimation| begins at the current timeline time, we will not process
// restyling in the initial frame because of aligning with the refresh driver,
// the animation frame in which the ready promise is resolved happens to
// coincide perfectly with the start time of the animation. In this case no
// restyling is needed in the frame so we have to wait one more frame.
if (animationStartsRightNow(aAnimation)) {
await waitForNextFrame();
}
}

View File

@ -124,15 +124,29 @@ ShapeUtils::ComputeInsetRect(const UniquePtr<StyleBasicShape>& aBasicShape,
const nsTArray<nsStyleCoord>& coords = aBasicShape->Coordinates();
MOZ_ASSERT(coords.Length() == 4, "wrong number of arguments");
nsMargin inset(coords[0].ComputeCoordPercentCalc(aRefBox.height),
coords[1].ComputeCoordPercentCalc(aRefBox.width),
coords[2].ComputeCoordPercentCalc(aRefBox.height),
coords[3].ComputeCoordPercentCalc(aRefBox.width));
nsMargin inset(coords[0].ComputeCoordPercentCalc(aRefBox.Height()),
coords[1].ComputeCoordPercentCalc(aRefBox.Width()),
coords[2].ComputeCoordPercentCalc(aRefBox.Height()),
coords[3].ComputeCoordPercentCalc(aRefBox.Width()));
nsRect insetRect(aRefBox);
insetRect.Deflate(inset);
nscoord x = aRefBox.X() + inset.left;
nscoord width = aRefBox.Width() - inset.LeftRight();
nscoord y = aRefBox.Y() + inset.top;
nscoord height = aRefBox.Height() - inset.TopBottom();
return insetRect;
// Invert left and right, if necessary.
if (width < 0) {
width *= -1;
x -= width;
}
// Invert top and bottom, if necessary.
if (height < 0) {
height *= -1;
y -= height;
}
return nsRect(x, y, width, height);
}
/* static */ bool

View File

@ -57,7 +57,16 @@ struct ShapeUtils final
const UniquePtr<StyleBasicShape>& aBasicShape,
const nsPoint& aCenter, const nsRect& aRefBox);
// Compute the rect for an inset.
// Compute the rect for an inset. If the inset amount is larger than
// aRefBox itself, this will return a rect the same shape as the inverse
// rect that would be created by insetting aRefBox by the inset amount.
// This process is *not* what is called for by the current spec at
// https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes.
// The spec currently treats empty shapes, including overly-inset rects, as
// defining 'empty float areas' that don't affect layout. However, it is
// practically useful to treat empty shapes as having edges for purposes of
// affecting layout, and there is growing momentum for the approach we
// are taking here.
// @param aRefBox the reference box of the inset.
// @return The inset rect in app units.
static nsRect ComputeInsetRect(

View File

@ -0,0 +1,7 @@
<style>
.cl { -webkit-transform-style: preserve-3d }
:not(mask) { -webkit-perspective: 0px }
:root { columns: 0px }
</style>
<textarea class="cl"></textarea>
<p class="cl">z

View File

@ -538,3 +538,4 @@ load 1461812.html
load 1462412.html
load 1463940.html
pref(dom.webcomponents.shadowdom.enabled,true) HTTP load 1464641.html
load 1464737.html

View File

@ -730,7 +730,10 @@ public:
return mCenter.y + mRadii.height + mShapeMargin;
}
bool IsEmpty() const override {
return mRadii.IsEmpty();
// An EllipseShapeInfo is never empty, because an ellipse or circle with
// a zero radius acts like a point, and an ellipse with one zero radius
// acts like a line.
return false;
}
void Translate(nscoord aLineLeft, nscoord aBlockStart) override
@ -866,10 +869,16 @@ nsFloatManager::EllipseShapeInfo::EllipseShapeInfo(const nsPoint& aCenter,
// adjust it to compensate for the expansion of the inline dimension.
// If we're in the expanded region, or if we're using a b that's more
// than the bEnd of the ellipse, the intercept is nscoord_MIN.
const int32_t iIntercept = (bIsInExpandedRegion ||
bIsMoreThanEllipseBEnd) ? nscoord_MIN :
// We have one other special case to consider: when the ellipse has no
// height. In that case we treat the bInAppUnits == 0 case as
// intercepting at the width of the ellipse. All other cases solve
// the intersection mathematically.
const int32_t iIntercept =
(bIsInExpandedRegion || bIsMoreThanEllipseBEnd) ? nscoord_MIN :
iExpand + NSAppUnitsToIntPixels(
XInterceptAtY(bInAppUnits, mRadii.width, mRadii.height),
(!!mRadii.height || bInAppUnits) ?
XInterceptAtY(bInAppUnits, mRadii.width, mRadii.height) :
mRadii.width,
aAppUnitsPerDevPixel);
// Set iMax in preparation for this block row.
@ -886,8 +895,10 @@ nsFloatManager::EllipseShapeInfo::EllipseShapeInfo(const nsPoint& aCenter,
// Case 1: Expanded reqion pixel.
df[index] = MAX_MARGIN_5X;
} else if ((int32_t)i <= iIntercept) {
// Case 2: Pixel within the ellipse.
df[index] = 0;
// Case 2: Pixel within the ellipse, or just outside the edge of it.
// Having a positive height indicates that there's an area we can
// be inside of.
df[index] = (!!mRadii.height) ? 0 : 5;
} else {
// Case 3: Other pixel.
@ -1073,7 +1084,13 @@ public:
const nscoord aBEnd) const override;
nscoord BStart() const override { return mRect.y; }
nscoord BEnd() const override { return mRect.YMost(); }
bool IsEmpty() const override { return mRect.IsEmpty(); }
bool IsEmpty() const override {
// A RoundedBoxShapeInfo is never empty, because if it is collapsed to
// zero area, it acts like a point. If it is collapsed further, to become
// inside-out, it acts like a rect in the same shape as the inside-out
// rect.
return false;
}
void Translate(nscoord aLineLeft, nscoord aBlockStart) override
{
@ -1260,14 +1277,20 @@ public:
const nscoord aBEnd) const override;
nscoord BStart() const override { return mBStart; }
nscoord BEnd() const override { return mBEnd; }
bool IsEmpty() const override { return mEmpty; }
bool IsEmpty() const override {
// A PolygonShapeInfo is never empty, because the parser prevents us from
// creating a shape with no vertices. If we only have 1 vertex, the
// shape acts like a point. With 2 non-coincident vertices, the shape
// acts like a line.
return false;
}
void Translate(nscoord aLineLeft, nscoord aBlockStart) override;
private:
// Helper method for determining if the vertices define a float area at
// all, and to set mBStart and mBEnd based on the vertices' y extent.
void ComputeEmptinessAndExtent();
// Helper method for determining the mBStart and mBEnd based on the
// vertices' y extent.
void ComputeExtent();
// Helper method for implementing LineLeft() and LineRight().
nscoord ComputeLineIntercept(
@ -1295,15 +1318,10 @@ private:
// The intervals are stored in ascending order on y.
nsTArray<nsRect> mIntervals;
// If mEmpty is true, that means the polygon encloses no area.
bool mEmpty = false;
// Computed block start and block end value of the polygon shape.
//
// If mEmpty is false, their initial values nscoord_MAX and nscoord_MIN
// are used as sentinels for computing min() and max() in the
// constructor, and mBStart is guaranteed to be less than or equal to
// mBEnd. If mEmpty is true, their values do not matter.
// Computed block start and block end value of the polygon shape. These
// initial values are set to correct values in ComputeExtent(), which is
// called from all constructors. Afterwards, mBStart is guaranteed to be
// less than or equal to mBEnd.
nscoord mBStart = nscoord_MAX;
nscoord mBEnd = nscoord_MIN;
};
@ -1311,7 +1329,7 @@ private:
nsFloatManager::PolygonShapeInfo::PolygonShapeInfo(nsTArray<nsPoint>&& aVertices)
: mVertices(aVertices)
{
ComputeEmptinessAndExtent();
ComputeExtent();
}
nsFloatManager::PolygonShapeInfo::PolygonShapeInfo(
@ -1324,13 +1342,7 @@ nsFloatManager::PolygonShapeInfo::PolygonShapeInfo(
MOZ_ASSERT(aShapeMargin > 0, "This constructor should only be used for a "
"polygon with a positive shape-margin.");
ComputeEmptinessAndExtent();
// If we're empty, then the float area stays empty, even with a positive
// shape-margin.
if (mEmpty) {
return;
}
ComputeExtent();
// With a positive aShapeMargin, we have to calculate a distance
// field from the opaque pixels, then build intervals based on
@ -1419,7 +1431,7 @@ nsFloatManager::PolygonShapeInfo::PolygonShapeInfo(
// converting the app units to dev pixels.
nscoord bInAppUnitsMarginRect = bInAppUnits + aMarginRect.y;
bool bIsLessThanPolygonBStart(bInAppUnitsMarginRect < mBStart);
bool bIsMoreThanPolygonBEnd(bInAppUnitsMarginRect >= mBEnd);
bool bIsMoreThanPolygonBEnd(bInAppUnitsMarginRect > mBEnd);
const int32_t iLeftEdge = (bIsInExpandedRegion ||
bIsLessThanPolygonBStart ||
@ -1450,9 +1462,11 @@ nsFloatManager::PolygonShapeInfo::PolygonShapeInfo(
bIsInExpandedRegion) {
// Case 1: Expanded pixel.
df[index] = MAX_MARGIN_5X;
} else if ((int32_t)i >= iLeftEdge && (int32_t)i < iRightEdge) {
// Case 2: Polygon pixel.
df[index] = 0;
} else if ((int32_t)i >= iLeftEdge && (int32_t)i <= iRightEdge) {
// Case 2: Polygon pixel, either inside or just adjacent to the right
// edge. We need this special distinction to detect a space between
// edges that is less than one dev pixel.
df[index] = (int32_t)i < iRightEdge ? 0 : 5;
} else {
// Case 3: Other pixel.
@ -1605,8 +1619,6 @@ nscoord
nsFloatManager::PolygonShapeInfo::LineLeft(const nscoord aBStart,
const nscoord aBEnd) const
{
MOZ_ASSERT(!mEmpty, "Shouldn't be called if the polygon encloses no area.");
// Use intervals if we have them.
if (!mIntervals.IsEmpty()) {
return LineEdge(mIntervals, aBStart, aBEnd, true);
@ -1628,8 +1640,6 @@ nscoord
nsFloatManager::PolygonShapeInfo::LineRight(const nscoord aBStart,
const nscoord aBEnd) const
{
MOZ_ASSERT(!mEmpty, "Shouldn't be called if the polygon encloses no area.");
// Use intervals if we have them.
if (!mIntervals.IsEmpty()) {
return LineEdge(mIntervals, aBStart, aBEnd, false);
@ -1643,44 +1653,8 @@ nsFloatManager::PolygonShapeInfo::LineRight(const nscoord aBStart,
}
void
nsFloatManager::PolygonShapeInfo::ComputeEmptinessAndExtent()
nsFloatManager::PolygonShapeInfo::ComputeExtent()
{
// Polygons with fewer than three vertices result in an empty area.
// https://drafts.csswg.org/css-shapes/#funcdef-polygon
if (mVertices.Length() < 3) {
mEmpty = true;
return;
}
auto Determinant = [] (const nsPoint& aP0, const nsPoint& aP1) {
// Returns the determinant of the 2x2 matrix [aP0 aP1].
// https://en.wikipedia.org/wiki/Determinant#2_.C3.97_2_matrices
return aP0.x * aP1.y - aP0.y * aP1.x;
};
// See if we have any vertices that are non-collinear with the first two.
// (If a polygon's vertices are all collinear, it encloses no area.)
bool isEntirelyCollinear = true;
const nsPoint& p0 = mVertices[0];
const nsPoint& p1 = mVertices[1];
for (size_t i = 2; i < mVertices.Length(); ++i) {
const nsPoint& p2 = mVertices[i];
// If the determinant of the matrix formed by two points is 0, that
// means they're collinear with respect to the origin. Here, if it's
// nonzero, then p1 and p2 are non-collinear with respect to p0, i.e.
// the three points are non-collinear.
if (Determinant(p2 - p0, p1 - p0) != 0) {
isEntirelyCollinear = false;
break;
}
}
if (isEntirelyCollinear) {
mEmpty = true;
return;
}
// mBStart and mBEnd are the lower and the upper bounds of all the
// vertex.y, respectively. The vertex.y is actually on the block-axis of
// the float manager's writing mode.
@ -1688,6 +1662,9 @@ nsFloatManager::PolygonShapeInfo::ComputeEmptinessAndExtent()
mBStart = std::min(mBStart, vertex.y);
mBEnd = std::max(mBEnd, vertex.y);
}
MOZ_ASSERT(mBStart <= mBEnd, "Start of float area should be less than "
"or equal to the end.");
}
nscoord
@ -1703,6 +1680,16 @@ nsFloatManager::PolygonShapeInfo::ComputeLineIntercept(
const size_t len = mVertices.Length();
nscoord lineIntercept = aLineInterceptInitialValue;
// We have some special treatment of horizontal lines between vertices.
// Generally, we can ignore the impact of the horizontal lines since their
// endpoints will be included in the lines preceeding or following them.
// However, it's possible the polygon is entirely a horizontal line,
// possibly built from more than one horizontal segment. In such a case,
// we need to have the horizontal line(s) contribute to the line intercepts.
// We do this by accepting horizontal lines until we find a non-horizontal
// line, after which all further horizontal lines are ignored.
bool canIgnoreHorizontalLines = false;
// Iterate each line segment {p0, p1}, {p1, p2}, ..., {pn, p0}.
for (size_t i = 0; i < len; ++i) {
const nsPoint* smallYVertex = &mVertices[i];
@ -1714,24 +1701,46 @@ nsFloatManager::PolygonShapeInfo::ComputeLineIntercept(
std::swap(smallYVertex, bigYVertex);
}
if (aBStart >= bigYVertex->y || aBEnd <= smallYVertex->y ||
smallYVertex->y == bigYVertex->y) {
// Skip computing the intercept if a) the band doesn't intersect the
// line segment (even if it crosses one of two the vertices); or b)
// the line segment is horizontal. It's OK because the two end points
// forming this horizontal segment will still be considered if each of
// them is forming another non-horizontal segment with other points.
// Generally, we need to ignore line segments that either don't intersect
// the band, or merely touch it. However, if the polygon has no block extent
// (it is a point, or a horizontal line), and the band touches the line
// segment, we let that line segment through.
if ((aBStart >= bigYVertex->y || aBEnd <= smallYVertex->y) &&
!(mBStart == mBEnd && aBStart == bigYVertex->y)) {
// Skip computing the intercept if the band doesn't intersect the
// line segment.
continue;
}
nscoord bStartLineIntercept =
aBStart <= smallYVertex->y
? smallYVertex->x
: XInterceptAtY(aBStart, *smallYVertex, *bigYVertex);
nscoord bEndLineIntercept =
aBEnd >= bigYVertex->y
? bigYVertex->x
: XInterceptAtY(aBEnd, *smallYVertex, *bigYVertex);
nscoord bStartLineIntercept;
nscoord bEndLineIntercept;
if (smallYVertex->y == bigYVertex->y) {
// The line is horizontal; see if we can ignore it.
if (canIgnoreHorizontalLines) {
continue;
}
// For a horizontal line that we can't ignore, we treat the two x value
// ends as the bStartLineIntercept and bEndLineIntercept. It doesn't
// matter which is applied to which, because they'll both be applied
// to aCompareOp.
bStartLineIntercept = smallYVertex->x;
bEndLineIntercept = bigYVertex->x;
} else {
// This is not a horizontal line. We can now ignore all future
// horizontal lines.
canIgnoreHorizontalLines = true;
bStartLineIntercept =
aBStart <= smallYVertex->y
? smallYVertex->x
: XInterceptAtY(aBStart, *smallYVertex, *bigYVertex);
bEndLineIntercept =
aBEnd >= bigYVertex->y
? bigYVertex->x
: XInterceptAtY(aBEnd, *smallYVertex, *bigYVertex);
}
// If either new intercept is more extreme than lineIntercept (per
// aCompareOp), then update lineIntercept to that value.

View File

@ -2669,10 +2669,9 @@ static bool
ItemParticipatesIn3DContext(nsIFrame* aAncestor, nsDisplayItem* aItem)
{
nsIFrame* transformFrame;
if (aItem->GetType() == DisplayItemType::TYPE_TRANSFORM) {
if (aItem->GetType() == DisplayItemType::TYPE_TRANSFORM ||
aItem->GetType() == DisplayItemType::TYPE_PERSPECTIVE) {
transformFrame = aItem->Frame();
} else if (aItem->GetType() == DisplayItemType::TYPE_PERSPECTIVE) {
transformFrame = static_cast<nsDisplayPerspective*>(aItem)->TransformFrame();
} else {
return false;
}
@ -2866,7 +2865,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
const bool extend3DContext = Extend3DContext(disp, effectSet);
const bool combines3DTransformWithAncestors =
(extend3DContext || isTransformed) && Combines3DTransformWithAncestors(disp);
const bool childrenHavePerspective = ChildrenHavePerspective(disp);
Maybe<nsDisplayListBuilder::AutoPreserves3DContext> autoPreserves3DContext;
if (extend3DContext && !combines3DTransformWithAncestors) {
@ -2885,15 +2883,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
}
}
// nsDisplayPerspective items use an index to keep their PerFrameKey unique.
// We need to make sure we build all of them for them to be consistent, so
// rebuild all items if we have perspective. Bug 1431249 should remove
// this requirement.
if (aBuilder->IsRetainingDisplayList() && childrenHavePerspective) {
dirtyRect = visibleRect;
aBuilder->SetDisablePartialUpdates(true);
}
// reset blend mode so we can keep track if this stacking context needs have
// a nsDisplayBlendContainer. Set the blend mode back when the routine exits
// so we keep track if the parent stacking context needs a container too.
@ -3064,8 +3053,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
DisplayListClipState::AutoSaveRestore nestedClipState(aBuilder);
nsDisplayListBuilder::AutoInTransformSetter
inTransformSetter(aBuilder, inTransform);
nsDisplayListBuilder::AutoSaveRestorePerspectiveIndex
perspectiveIndex(aBuilder, childrenHavePerspective);
nsDisplayListBuilder::AutoFilterASRSetter
filterASRSetter(aBuilder, usingFilter);
@ -3382,9 +3369,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
}
resultList.AppendToTop(
MakeDisplayItem<nsDisplayPerspective>(
aBuilder, this,
GetContainingBlock(0, disp)->GetContent()->GetPrimaryFrame(),
&resultList));
aBuilder, this, &resultList));
}
if (aCreatedContainerItem) {

View File

@ -4635,7 +4635,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
// frame's FrameMetrics on our child transform ContainerLayer instead.
// It's worth investigating whether this ASR adjustment can be done at
// display item creation time.
scrollMetadataASR = GetASRForPerspective(scrollMetadataASR, item->Frame());
scrollMetadataASR = GetASRForPerspective(scrollMetadataASR, item->Frame()->GetContainingBlock(nsIFrame::SKIP_SCROLLED_FRAME));
params.mScrollMetadataASR = scrollMetadataASR;
itemASR = scrollMetadataASR;
}

View File

@ -998,7 +998,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mMode(aMode),
mCurrentScrollParentId(FrameMetrics::NULL_SCROLL_ID),
mCurrentScrollbarTarget(FrameMetrics::NULL_SCROLL_ID),
mPerspectiveItemIndex(0),
mSVGEffectsBuildingDepth(0),
mFilterASR(nullptr),
mContainsBlendMode(false),
@ -2971,7 +2970,7 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
(itemType == DisplayItemType::TYPE_TRANSFORM &&
static_cast<nsDisplayTransform*>(item)->IsParticipating3DContext()) ||
(itemType == DisplayItemType::TYPE_PERSPECTIVE &&
static_cast<nsDisplayPerspective*>(item)->TransformFrame()->Extend3DContext());
item->Frame()->Extend3DContext());
if (same3DContext &&
(itemType != DisplayItemType::TYPE_TRANSFORM ||
!static_cast<nsDisplayTransform*>(item)->IsLeafOf3DContext())) {
@ -9171,20 +9170,14 @@ nsDisplayTransform::WriteDebugInfo(std::stringstream& aStream)
}
nsDisplayPerspective::nsDisplayPerspective(nsDisplayListBuilder* aBuilder,
nsIFrame* aTransformFrame,
nsIFrame* aPerspectiveFrame,
nsIFrame* aFrame,
nsDisplayList* aList)
: nsDisplayItem(aBuilder, aPerspectiveFrame)
, mList(aBuilder, aPerspectiveFrame, aList, true)
, mTransformFrame(aTransformFrame)
, mIndex(aBuilder->AllocatePerspectiveItemIndex())
: nsDisplayItem(aBuilder, aFrame)
, mList(aBuilder, aFrame, aList, true)
{
MOZ_ASSERT(mList.GetChildren()->Count() == 1);
MOZ_ASSERT(mList.GetChildren()->GetTop()->GetType() == DisplayItemType::TYPE_TRANSFORM);
if (aBuilder->IsRetainingDisplayList()) {
mTransformFrame->AddDisplayItem(this);
}
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(mFrame->GetContainingBlock(nsIFrame::SKIP_SCROLLED_FRAME));
}
already_AddRefed<Layer>
@ -9196,7 +9189,7 @@ nsDisplayPerspective::BuildLayer(nsDisplayListBuilder *aBuilder,
Matrix4x4 perspectiveMatrix;
DebugOnly<bool> hasPerspective =
nsDisplayTransform::ComputePerspectiveMatrix(mTransformFrame, appUnitsPerPixel,
nsDisplayTransform::ComputePerspectiveMatrix(mFrame, appUnitsPerPixel,
perspectiveMatrix);
MOZ_ASSERT(hasPerspective, "Why did we create nsDisplayPerspective?");
@ -9259,7 +9252,7 @@ nsDisplayPerspective::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& a
float appUnitsPerPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
Matrix4x4 perspectiveMatrix;
DebugOnly<bool> hasPerspective =
nsDisplayTransform::ComputePerspectiveMatrix(mTransformFrame, appUnitsPerPixel,
nsDisplayTransform::ComputePerspectiveMatrix(mFrame, appUnitsPerPixel,
perspectiveMatrix);
MOZ_ASSERT(hasPerspective, "Why did we create nsDisplayPerspective?");
@ -9305,12 +9298,6 @@ nsDisplayPerspective::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& a
aManager, aDisplayListBuilder);
}
int32_t
nsDisplayPerspective::ZIndex() const
{
return ZIndexForFrame(mTransformFrame);
}
nsDisplayItemGeometry*
nsCharClipDisplayItem::AllocateGeometry(nsDisplayListBuilder* aBuilder)
{

View File

@ -1194,31 +1194,6 @@ public:
const ActiveScrolledRoot* mOldValue;
};
class AutoSaveRestorePerspectiveIndex {
public:
AutoSaveRestorePerspectiveIndex(nsDisplayListBuilder* aBuilder,
const bool aChildrenHavePerspective)
: mBuilder(nullptr)
{
if (aChildrenHavePerspective) {
mBuilder = aBuilder;
mCachedItemIndex = aBuilder->mPerspectiveItemIndex;
aBuilder->mPerspectiveItemIndex = 0;
}
}
~AutoSaveRestorePerspectiveIndex()
{
if (mBuilder) {
mBuilder->mPerspectiveItemIndex = mCachedItemIndex;
}
}
private:
nsDisplayListBuilder* mBuilder;
uint32_t mCachedItemIndex;
};
/**
* A helper class to temporarily set the value of mCurrentScrollParentId.
*/
@ -1641,8 +1616,6 @@ public:
void SetContainsBlendMode(bool aContainsBlendMode) { mContainsBlendMode = aContainsBlendMode; }
bool ContainsBlendMode() const { return mContainsBlendMode; }
uint32_t AllocatePerspectiveItemIndex() { return mPerspectiveItemIndex++; }
DisplayListClipState& ClipState() { return mClipState; }
const ActiveScrolledRoot* CurrentActiveScrolledRoot() { return mCurrentActiveScrolledRoot; }
const ActiveScrolledRoot* CurrentAncestorASRStackingContextContents() { return mCurrentContainerASR; }
@ -1822,6 +1795,7 @@ private:
friend class nsDisplayCanvasBackgroundImage;
friend class nsDisplayBackgroundImage;
friend class nsDisplayFixedPosition;
friend class nsDisplayPerspective;
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsDisplayItem* aItem);
friend class nsDisplayItem;
@ -1963,7 +1937,6 @@ private:
ViewID mCurrentScrollbarTarget;
MaybeScrollDirection mCurrentScrollbarDirection;
Preserves3DContext mPreserves3DCtx;
uint32_t mPerspectiveItemIndex;
int32_t mSVGEffectsBuildingDepth;
// When we are inside a filter, the current ASR at the time we entered the
// filter. Otherwise nullptr.
@ -6889,18 +6862,10 @@ class nsDisplayPerspective : public nsDisplayItem
public:
NS_DISPLAY_DECL_NAME("nsDisplayPerspective", TYPE_PERSPECTIVE)
nsDisplayPerspective(nsDisplayListBuilder* aBuilder, nsIFrame* aTransformFrame,
nsIFrame* aPerspectiveFrame,
nsDisplayPerspective(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList);
~nsDisplayPerspective()
{
if (mTransformFrame) {
mTransformFrame->RemoveDisplayItem(this);
}
}
virtual uint32_t GetPerFrameKey() const override {
return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
}
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
@ -6985,12 +6950,6 @@ public:
return mList.GetComponentAlphaBounds(aBuilder);
}
nsIFrame* TransformFrame() { return mTransformFrame; }
virtual nsIFrame* FrameForInvalidation() const override { return mTransformFrame; }
virtual int32_t ZIndex() const override;
virtual void
DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) override {
if (mList.GetChildren()->GetTop()) {
@ -7004,21 +6963,14 @@ public:
nsDisplayItem::Destroy(aBuilder);
}
virtual bool HasDeletedFrame() const override { return !mTransformFrame || nsDisplayItem::HasDeletedFrame(); }
virtual void RemoveFrame(nsIFrame* aFrame) override
{
if (aFrame == mTransformFrame) {
mTransformFrame = nullptr;
}
nsDisplayItem::RemoveFrame(aFrame);
mList.RemoveFrame(aFrame);
}
private:
nsDisplayWrapList mList;
nsIFrame* mTransformFrame;
uint32_t mIndex;
};
/**

View File

@ -1 +1,33 @@
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),16,4) pref(layout.css.shape-outside.enabled,true) == dynamic-shape-outside-1.html dynamic-shape-outside-1-ref.html
== shape-outside-empty-circle-1.html shape-outside-empty-point-ref.html
== shape-outside-empty-circle-2.html shape-outside-empty-circle-ref.html
== shape-outside-empty-circle-3.html shape-outside-empty-nothing-ref.html
== shape-outside-empty-ellipse-1.html shape-outside-empty-point-ref.html
== shape-outside-empty-ellipse-2.html shape-outside-empty-circle-ref.html
== shape-outside-empty-ellipse-3.html shape-outside-empty-point-ref.html
# The next test needs fuzzy due to chamfer aberration
fuzzy(255,520) == shape-outside-empty-ellipse-4.html shape-outside-empty-circle-ref.html
== shape-outside-empty-ellipse-5.html shape-outside-empty-line-ref.html
== shape-outside-empty-ellipse-6.html shape-outside-empty-line-ref.html
== shape-outside-empty-ellipse-7.html shape-outside-empty-nothing-ref.html
== shape-outside-empty-ellipse-8.html shape-outside-empty-nothing-ref.html
== shape-outside-empty-inset-1.html shape-outside-empty-point-ref.html
== shape-outside-empty-inset-2.html shape-outside-empty-circle-ref.html
== shape-outside-empty-inset-3.html shape-outside-empty-point-ref.html
== shape-outside-empty-inset-4.html shape-outside-empty-circle-ref.html
== shape-outside-empty-inset-5.html shape-outside-empty-line-ref.html
== shape-outside-empty-inset-6.html shape-outside-empty-line-ref.html
== shape-outside-empty-inset-7.html shape-outside-empty-nothing-ref.html
== shape-outside-empty-inset-8.html shape-outside-empty-nothing-ref.html
== shape-outside-empty-polygon-1.html shape-outside-empty-point-ref.html
# The next test needs fuzzy due to chamfer aberration
fuzzy(255,520) == shape-outside-empty-polygon-2.html shape-outside-empty-circle-ref.html
== shape-outside-empty-polygon-3.html shape-outside-empty-line-ref.html
== shape-outside-empty-polygon-4.html shape-outside-empty-line-ref.html
== shape-outside-empty-polygon-5.html shape-outside-empty-point-ref.html
== shape-outside-empty-polygon-6.html shape-outside-empty-nothing-ref.html
== shape-outside-empty-polygon-7.html shape-outside-empty-nothing-ref.html

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty circle, acts like a point</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: circle(0px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty circle, with shape-margin acts like a circle</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: circle(0px);
shape-margin: 90px;
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty circle, positioned between elements, acts like nothing</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: circle(0px at 100px 20px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Reference: Shape-outside empty area, float elements around a circle</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: circle(90px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty point ellipse, acts like a point</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: ellipse(0px 0px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty point ellipse, with shape-margin acts like a circle</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: ellipse(0px 0px);
shape-margin: 90px;
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty horizontal ellipse, acts like a point</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: ellipse(50px 0px at 50px 90px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty horizontal ellipse, with shape-margin acts like a circle (with some aberration)</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: ellipse(50px 0px at 50px 90px);
shape-margin: 90px;
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty vertical ellipse, acts like a line</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: ellipse(0px 100px at 190px 100px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty vertical ellipse, with shape-margin acts like a capsule (with rounded endpoints at top and bottom)</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: ellipse(0px 100px at 100px 100px);
shape-margin: 90px;
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty point ellipse, positioned between elements, acts like nothing</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: ellipse(0px 0px at 100px 20px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty horizontal ellipse, positioned between elements, acts like nothing</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: ellipse(50px 0px at 50px 20px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty zero-sized inset, acts like a point</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: inset(50% 50%);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty zero-sized inset, with shape-margin acts like a circle</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: inset(50% 50%);
shape-margin: 90px;
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty horizontal flat inset, acts like a point</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: inset(50% 50% 50% 0%);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty horizontal flat inset, with shape-margin acts like a circle</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: inset(50% 50% 50% 0%);
shape-margin: 90px;
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty vertical flat inset, acts like a line</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: inset(0% 5% 0% 95%);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside inside-out vertical flat inset, acts like a line</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: inset(0% 100% 0% 95%);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty zero-sized inset, positioned between elements, acts like nothing</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: inset(20px 100px 160px 100px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside empty horizontal inset, positioned between elements, acts like nothing</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: inset(20px 0px 160px 50px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Reference: Shape-outside empty area, float text around a vertical line</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
margin-left: 190px;
}
</style>
</head>
<body>
<div class="container">
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Reference: Shape-outside empty area, no float impact</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
</style>
</head>
<body>
<div class="container">
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Reference: Shape-outside empty area, float text around a point</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
</style>
</head>
<body>
<div class="container">
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box style="margin-left: 100px"></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside polygon with 1 vertex, acts like a point</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: polygon(100px 90px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside polygon with 1 vertex, with shape-margin acts like a circle (with some aberration)</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: polygon(100px 90px);
shape-margin: 90px;
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside polygon with 2 vertices, acts like a line</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: polygon(190px 0px, 190px 200px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside polygon with 2 vertices, with shape-margin acts like a line with rounded endpoints</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: polygon(100px 0px, 100px 200px);
shape-margin: 90px;
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside polygon with 3 coincident vertices, acts like a point</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: polygon(100px 90px, 100px 90px, 100px 90px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside polygon with 1 vertex, positioned between elements, acts like nothing</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: polygon(100px 20px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Shape-outside polygon with 2 vertices, positioned between elements, acts like nothing</title>
<style>
body {
line-height: 0;
}
.container {
width: 600px;
}
box {
display: inline-block;
background-color: blue;
width: 100px;
height: 20px;
}
.shape {
float: left;
width: 200px;
height: 180px;
shape-outside: polygon(0px 20px, 100px 20px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape"></div>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
<box></box><br>
</div>
</body>
</html>

View File

@ -44,14 +44,10 @@ fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),7,6) == shape-outside-circle
== shape-outside-circle-036.html shape-outside-circle-036-ref.html
== shape-outside-circle-037.html shape-outside-circle-036-ref.html
== shape-outside-circle-038.html shape-outside-circle-036-ref.html
== shape-outside-circle-039.html shape-outside-circle-039-ref.html
== shape-outside-circle-040.html shape-outside-circle-039-ref.html
== shape-outside-circle-041.html shape-outside-circle-041-ref.html
== shape-outside-circle-042.html shape-outside-circle-042-ref.html
== shape-outside-circle-043.html shape-outside-circle-042-ref.html
== shape-outside-circle-044.html shape-outside-circle-042-ref.html
== shape-outside-circle-045.html shape-outside-circle-045-ref.html
== shape-outside-circle-046.html shape-outside-circle-045-ref.html
== shape-outside-circle-047.html shape-outside-circle-047-ref.html
== shape-outside-circle-048.html shape-outside-circle-048-ref.html
== shape-outside-circle-049.html shape-outside-circle-049-ref.html
@ -89,8 +85,6 @@ fuzzy(108,81) == shape-outside-ellipse-052.html shape-outside-ellipse-052-ref.ht
# Basic shape: inset()
== shape-outside-inset-016.html shape-outside-inset-016-ref.html
== shape-outside-inset-017.html shape-outside-inset-017-ref.html
== shape-outside-inset-018.html shape-outside-inset-018-ref.html
== shape-outside-inset-019.html shape-outside-inset-019-ref.html
== shape-outside-inset-020.html shape-outside-inset-020-ref.html
== shape-outside-inset-021.html shape-outside-inset-021-ref.html
== shape-outside-inset-022.html shape-outside-inset-022-ref.html
@ -109,10 +103,4 @@ fuzzy(108,81) == shape-outside-ellipse-052.html shape-outside-ellipse-052-ref.ht
== shape-outside-polygon-023.html shape-outside-polygon-023-ref.html
== shape-outside-polygon-024.html shape-outside-polygon-024-ref.html
== shape-outside-polygon-025.html shape-outside-polygon-025-ref.html
== shape-outside-polygon-026.html shape-outside-polygon-026-ref.html
== shape-outside-polygon-027.html shape-outside-polygon-027-ref.html
== shape-outside-polygon-028.html shape-outside-polygon-026-ref.html
== shape-outside-polygon-029.html shape-outside-polygon-027-ref.html
== shape-outside-polygon-030.html shape-outside-polygon-030-ref.html
== shape-outside-polygon-031.html shape-outside-polygon-031-ref.html
fuzzy(101,2263) == shape-outside-polygon-032.html shape-outside-polygon-032-ref.html

View File

@ -1,46 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float left, circle(0%) border-box reference</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<style>
.container {
position: absolute;
width: 200px;
line-height: 0;
}
.shape {
float: left;
/* Omit shape-outside */
clip-path: circle(0%) border-box;
box-sizing: content-box;
height: 20px;
width: 20px;
padding: 20px;
border: 20px solid lightgreen;
margin: 10px;
background-color: orange;
}
.box {
position: absolute;
width: 200px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 12px; top: 0px; left: 0px;"></div>
<div class="box" style="height: 12px; top: 12px; left: 0px;"></div>
<div class="box" style="height: 36px; top: 24px; left: 0px;"></div>
<div class="box" style="height: 36px; top: 60px; left: 0px;"></div>
<div class="box" style="height: 12px; top: 96px; left: 0px;"></div>
<div class="box" style="height: 12px; top: 108px; left: 0px;"></div>
</body>
</html>

View File

@ -1,49 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float left, circle(0%) border-box</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes">
<link rel="match" href="shape-outside-circle-039-ref.html">
<meta name="flags" content="">
<meta name="assert" content="Test the left float shape defines an empty float area by the basic shape circle(0%) border-box value.">
<style>
.container {
width: 200px;
line-height: 0;
}
.shape {
float: left;
shape-outside: circle(0%) border-box;
clip-path: circle(0%) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
border: 20px solid lightgreen;
margin: 10px;
background-color: orange;
}
.box {
display: inline-block;
width: 200px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 12px;"></div>
<div class="box" style="height: 12px;"></div>
<div class="box" style="height: 36px;"></div>
<div class="box" style="height: 36px;"></div>
<div class="box" style="height: 12px;"></div>
<div class="box" style="height: 12px;"></div>
</body>
</html>

View File

@ -1,49 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float left, circle(closest-side at left center) border-box</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes">
<link rel="match" href="shape-outside-circle-039-ref.html">
<meta name="flags" content="">
<meta name="assert" content="Test the left float shape defines an empty float area by the basic shape circle(closest-side at left center) border-box value.">
<style>
.container {
width: 200px;
line-height: 0;
}
.shape {
float: left;
shape-outside: circle(closest-side at left center) border-box;
clip-path: circle(closest-side at left center) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
border: 20px solid lightgreen;
margin: 10px;
background-color: orange;
}
.box {
display: inline-block;
width: 200px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 12px;"></div>
<div class="box" style="height: 12px;"></div>
<div class="box" style="height: 36px;"></div>
<div class="box" style="height: 36px;"></div>
<div class="box" style="height: 12px;"></div>
<div class="box" style="height: 12px;"></div>
</body>
</html>

View File

@ -1,47 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float right, circle(0%) border-box reference</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<style>
.container {
direction: rtl;
position: absolute;
width: 200px;
line-height: 0;
}
.shape {
float: right;
/* Omit shape-outside */
clip-path: circle(0%) border-box;
box-sizing: content-box;
height: 20px;
width: 20px;
padding: 20px;
border: 20px solid lightgreen;
margin: 10px;
background-color: orange;
}
.box {
position: absolute;
width: 200px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 12px; top: 0px; right: 0px;"></div>
<div class="box" style="height: 12px; top: 12px; right: 0px;"></div>
<div class="box" style="height: 36px; top: 24px; right: 0px;"></div>
<div class="box" style="height: 36px; top: 60px; right: 0px;"></div>
<div class="box" style="height: 12px; top: 96px; right: 0px;"></div>
<div class="box" style="height: 12px; top: 108px; right: 0px;"></div>
</body>
</html>

View File

@ -1,50 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float right, circle(0%) border-box</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes">
<link rel="match" href="shape-outside-circle-045-ref.html">
<meta name="flags" content="">
<meta name="assert" content="Test the right float shape defines an empty float area by the basic shape circle(0%) border-box value.">
<style>
.container {
direction: rtl;
width: 200px;
line-height: 0;
}
.shape {
float: right;
shape-outside: circle(0%) border-box;
clip-path: circle(0%) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
border: 20px solid lightgreen;
margin: 10px;
background-color: orange;
}
.box {
display: inline-block;
width: 200px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 12px;"></div>
<div class="box" style="height: 12px;"></div>
<div class="box" style="height: 36px;"></div>
<div class="box" style="height: 36px;"></div>
<div class="box" style="height: 12px;"></div>
<div class="box" style="height: 12px;"></div>
</body>
</html>

View File

@ -1,50 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float right, circle(closest-side at right center) border-box</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes">
<link rel="match" href="shape-outside-circle-045-ref.html">
<meta name="flags" content="">
<meta name="assert" content="Test the right float shape defines an empty float area by the basic shape circle(closest-side at right center) border-box value.">
<style>
.container {
direction: rtl;
width: 200px;
line-height: 0;
}
.shape {
float: right;
shape-outside: circle(closest-side at right center) border-box;
clip-path: circle(closest-side at right center) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
border: 20px solid lightgreen;
margin: 10px;
background-color: orange;
}
.box {
display: inline-block;
width: 200px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 12px;"></div>
<div class="box" style="height: 12px;"></div>
<div class="box" style="height: 36px;"></div>
<div class="box" style="height: 36px;"></div>
<div class="box" style="height: 12px;"></div>
<div class="box" style="height: 12px;"></div>
</body>
</html>

View File

@ -1,44 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float left, inset(50%) reference</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<style>
.container {
position: absolute;
width: 200px;
line-height: 0;
}
.shape {
float: left;
/* Omit shape-outside */
clip-path: inset(50%);
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
border: 20px solid lightgreen;
margin: 20px;
background-color: orange;
}
.box {
position: absolute;
width: 200px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 24px; top: 0; left: 0;"></div>
<div class="box" style="height: 36px; top: 24px; left: 0;"></div>
<div class="box" style="height: 36px; top: 60px; left: 0;"></div>
<div class="box" style="height: 24px; top: 96px; left: 0;"></div>
</body>
</html>

View File

@ -1,47 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float left, inset(50%)</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes">
<link rel="match" href="shape-outside-inset-018-ref.html">
<meta name="flags" content="">
<meta name="assert" content="Test the left float shape defines an empty float area by the basic shape inset(50%) value.">
<style>
.container {
width: 200px;
line-height: 0;
}
.shape {
float: left;
shape-outside: inset(50%);
clip-path: inset(50%);
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
border: 20px solid lightgreen;
margin: 20px;
background-color: orange;
}
.box {
display: inline-block;
width: 200px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 24px;"></div>
<div class="box" style="height: 36px;"></div>
<div class="box" style="height: 36px;"></div>
<div class="box" style="height: 24px;"></div>
</body>
</html>

View File

@ -1,45 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float right, inset(50%) reference</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<style>
.container {
direction: rtl;
position: absolute;
width: 200px;
line-height: 0;
}
.shape {
float: right;
/* Omit shape-outside */
clip-path: inset(50%);
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
border: 20px solid lightgreen;
margin: 20px;
background-color: orange;
}
.box {
position: absolute;
width: 200px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 24px; top: 0; right: 0;"></div>
<div class="box" style="height: 36px; top: 24px; right: 0;"></div>
<div class="box" style="height: 36px; top: 60px; right: 0;"></div>
<div class="box" style="height: 24px; top: 96px; right: 0;"></div>
</body>
</html>

View File

@ -1,48 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float right, inset(50%)</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes">
<link rel="match" href="shape-outside-inset-019-ref.html">
<meta name="flags" content="">
<meta name="assert" content="Test the right float shape defines an empty float area by the basic shape inset(50%) value.">
<style>
.container {
direction: rtl;
width: 200px;
line-height: 0;
}
.shape {
float: right;
shape-outside: inset(50%);
clip-path: inset(50%);
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
border: 20px solid lightgreen;
margin: 20px;
background-color: orange;
}
.box {
display: inline-block;
width: 200px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 24px;"></div>
<div class="box" style="height: 36px;"></div>
<div class="box" style="height: 36px;"></div>
<div class="box" style="height: 24px;"></div>
</body>
</html>

View File

@ -1,50 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float left, polygon(60px 20px, 100px 60px) border-box reference</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<style>
.container {
position: absolute;
width: 200px;
line-height: 0;
}
.shape {
float: left;
/* Omit shape-outside */
clip-path: polygon(60px 20px, 100px 60px) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
border: 20px solid lightgreen;
margin: 20px;
background-color: orange;
}
.box {
position: absolute;
width: 80px;
background-color: blue;
}
.long {
width: 200px;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="long box" style="height: 30px; top: 0; left: 0;"></div>
<div class="long box" style="height: 30px; top: 30px; left: 0;"></div>
<div class="long box" style="height: 20px; top: 60px; left: 0;"></div>
<div class="long box" style="height: 20px; top: 80px; left: 0;"></div>
<div class="long box" style="height: 30px; top: 100px; left: 0;"></div>
<div class="long box" style="height: 30px; top: 130px; left: 0;"></div>
</body>
</html>

View File

@ -1,54 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float left, polygon(60px 20px, 100px 60px) border-box</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes">
<link rel="match" href="shape-outside-polygon-026-ref.html">
<meta name="flags" content="">
<meta name="assert" content="Test the left float shape defines an empty float area by the polygon(60px 20px, 100px 60px) border-box value.">
<style>
.container {
width: 200px;
line-height: 0;
}
.shape {
float: left;
/* Less than three vertices, resulting an empty area. */
shape-outside: polygon(60px 20px, 100px 60px) border-box;
clip-path: polygon(60px 20px, 100px 60px) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
margin: 20px;
border: 20px solid lightgreen;
background-color: orange;
}
.box {
display: inline-block;
width: 80px;
background-color: blue;
}
.long {
width: 200px;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="long box" style="height: 30px;"></div>
<div class="long box" style="height: 30px;"></div>
<div class="long box" style="height: 20px;"></div>
<div class="long box" style="height: 20px;"></div>
<div class="long box" style="height: 30px;"></div>
<div class="long box" style="height: 30px;"></div>
</body>
</html>

View File

@ -1,50 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float right, polygon(60px 20px, 100px 60px) border-box reference</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<style>
.container {
position: absolute;
width: 200px;
line-height: 0;
}
.shape {
float: right;
/* Omit shape-outside */
clip-path: polygon(60px 20px, 100px 60px) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
border: 20px solid lightgreen;
margin: 20px;
background-color: orange;
}
.box {
position: absolute;
width: 80px;
background-color: blue;
}
.long {
width: 200px;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="long box" style="height: 30px; top: 0; right: 0;"></div>
<div class="long box" style="height: 30px; top: 30px; right: 0;"></div>
<div class="long box" style="height: 20px; top: 60px; right: 0;"></div>
<div class="long box" style="height: 20px; top: 80px; right: 0;"></div>
<div class="long box" style="height: 30px; top: 100px; right: 0;"></div>
<div class="long box" style="height: 30px; top: 130px; right: 0;"></div>
</body>
</html>

View File

@ -1,54 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float right, polygon(60px 20px, 100px 60px) border-box</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes">
<link rel="match" href="shape-outside-polygon-027-ref.html">
<meta name="flags" content="">
<meta name="assert" content="Test the right float shape defines an empty float area by the polygon(60px 20px, 100px 60px) border-box value.">
<style>
.container {
width: 200px;
line-height: 0;
}
.shape {
float: right;
/* Less than three vertices, resulting an empty area. */
shape-outside: polygon(60px 20px, 100px 60px) border-box;
clip-path: polygon(60px 20px, 100px 60px) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
margin: 20px;
border: 20px solid lightgreen;
background-color: orange;
}
.box {
display: inline-block;
width: 80px;
background-color: blue;
}
.long {
width: 200px;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="long box" style="height: 30px;"></div>
<div class="long box" style="height: 30px;"></div>
<div class="long box" style="height: 20px;"></div>
<div class="long box" style="height: 20px;"></div>
<div class="long box" style="height: 30px;"></div>
<div class="long box" style="height: 30px;"></div>
</body>
</html>

View File

@ -1,54 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float left, polygon(50% 50%, 0% 0%, 20% 20%, 100% 100%) border-box</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes">
<link rel="match" href="shape-outside-polygon-026-ref.html">
<meta name="flags" content="">
<meta name="assert" content="Test the left float shape defines an empty float area by the polygon(50% 50%, 0% 0%, 20% 20%, 100% 100%) border-box value.">
<style>
.container {
width: 200px;
line-height: 0;
}
.shape {
float: left;
/* All vertices are collinear, resulting an empty area. */
shape-outside: polygon(50% 50%, 0% 0%, 20% 20%, 100% 100%) border-box;
clip-path: polygon(50% 50%, 0% 0%, 20% 20%, 100% 100%) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
margin: 20px;
border: 20px solid lightgreen;
background-color: orange;
}
.box {
display: inline-block;
width: 80px;
background-color: blue;
}
.long {
width: 200px;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="long box" style="height: 30px;"></div>
<div class="long box" style="height: 30px;"></div>
<div class="long box" style="height: 20px;"></div>
<div class="long box" style="height: 20px;"></div>
<div class="long box" style="height: 30px;"></div>
<div class="long box" style="height: 30px;"></div>
</body>
</html>

View File

@ -1,55 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float right, polygon(50% 50%, 0% 0%, 20% 20%, 100% 100%) border-box</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes">
<link rel="match" href="shape-outside-polygon-027-ref.html">
<meta name="flags" content="">
<meta name="assert" content="Test the right float shape defines an empty float area by the polygon(50% 50%, 0% 0%, 20% 20%, 100% 100%) border-box value.">
<style>
.container {
direction: rtl;
width: 200px;
line-height: 0;
}
.shape {
float: right;
/* All vertices are collinear, resulting an empty area. */
shape-outside: polygon(50% 50%, 0% 0%, 20% 20%, 100% 100%) border-box;
clip-path: polygon(50% 50%, 0% 0%, 20% 20%, 100% 100%) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
margin: 20px;
border: 20px solid lightgreen;
background-color: orange;
}
.box {
display: inline-block;
width: 80px;
background-color: blue;
}
.long {
width: 200px;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="long box" style="height: 30px;"></div>
<div class="long box" style="height: 30px;"></div>
<div class="long box" style="height: 20px;"></div>
<div class="long box" style="height: 20px;"></div>
<div class="long box" style="height: 30px;"></div>
<div class="long box" style="height: 30px;"></div>
</body>
</html>

View File

@ -1,46 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float left, polygon(0% 0%, 50% 0%, 100% 0%, 50% 0%, 50% 100%, 100% 100%, 50% 100%) border-box reference</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<style>
.container {
position: absolute;
width: 200px;
line-height: 0;
}
.shape {
float: left;
/* Omit shape-outside */
clip-path: polygon(0% 0%, 50% 0%, 100% 0%, 50% 0%, 50% 100%, 100% 100%, 50% 100%) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
border: 20px solid lightgreen;
margin: 20px;
background-color: orange;
}
.box {
position: absolute;
width: 80px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 30px; top: 0; left: 80px;"></div>
<div class="box" style="height: 30px; top: 30px; left: 80px;"></div>
<div class="box" style="height: 20px; top: 60px; left: 80px;"></div>
<div class="box" style="height: 20px; top: 80px; left: 80px;"></div>
<div class="box" style="height: 30px; top: 100px; left: 80px;"></div>
<div class="box" style="height: 30px; top: 130px; left: 80px;"></div>
</body>
</html>

View File

@ -1,50 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float left, polygon(0% 0%, 50% 0%, 100% 0%, 50% 0%, 50% 100%, 100% 100%, 50% 100%) border-box</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes">
<link rel="match" href="shape-outside-polygon-030-ref.html">
<meta name="flags" content="">
<meta name="assert" content="Test the boxes are wrapping around the left float shape defined by the polygon(0% 0%, 50% 0%, 100% 0%, 50% 0%, 50% 100%, 100% 100%, 50% 100%) border-box value.">
<style>
.container {
width: 200px;
line-height: 0;
}
.shape {
float: left;
/* polygon contains horizontal lines. */
shape-outside: polygon(0% 0%, 50% 0%, 100% 0%, 50% 0%, 50% 100%, 100% 100%, 50% 100%) border-box;
clip-path: polygon(0% 0%, 50% 0%, 100% 0%, 50% 0%, 50% 100%, 100% 100%, 50% 100%) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
margin: 20px;
border: 20px solid lightgreen;
background-color: orange;
}
.box {
display: inline-block;
width: 80px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 30px;"></div>
<div class="box" style="height: 30px;"></div>
<div class="box" style="height: 20px;"></div>
<div class="box" style="height: 20px;"></div>
<div class="box" style="height: 30px;"></div>
<div class="box" style="height: 30px;"></div>
</body>
</html>

View File

@ -1,47 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float right, polygon(100% 0%, 50% 0%, 0% 0%, 50% 0%, 50% 100%, 0% 100%, 50% 100%) border-box reference</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<style>
.container {
direction: rtl;
position: absolute;
width: 200px;
line-height: 0;
}
.shape {
float: right;
/* Omit shape-outside */
clip-path: polygon(100% 0%, 50% 0%, 0% 0%, 50% 0%, 50% 100%, 0% 100%, 50% 100%) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
border: 20px solid lightgreen;
margin: 20px;
background-color: orange;
}
.box {
position: absolute;
width: 80px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 30px; top: 0; right: 80px;"></div>
<div class="box" style="height: 30px; top: 30px; right: 80px;"></div>
<div class="box" style="height: 20px; top: 60px; right: 80px;"></div>
<div class="box" style="height: 20px; top: 80px; right: 80px;"></div>
<div class="box" style="height: 30px; top: 100px; right: 80px;"></div>
<div class="box" style="height: 30px; top: 130px; right: 80px;"></div>
</body>
</html>

View File

@ -1,51 +0,0 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<meta charset="utf-8">
<title>CSS Shape Test: float right, polygon(100% 0%, 50% 0%, 0% 0%, 50% 0%, 50% 100%, 0% 100%, 50% 100%) border-box</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#supported-basic-shapes">
<link rel="match" href="shape-outside-polygon-031-ref.html">
<meta name="flags" content="">
<meta name="assert" content="Test the boxes are wrapping around the right float shape defined by the polygon(100% 0%, 50% 0%, 0% 0%, 50% 0%, 50% 100%, 0% 100%, 50% 100%) border-box value.">
<style>
.container {
direction: rtl;
width: 200px;
line-height: 0;
}
.shape {
float: right;
/* polygon contains horizontal lines. */
shape-outside: polygon(100% 0%, 50% 0%, 0% 0%, 50% 0%, 50% 100%, 0% 100%, 50% 100%) border-box;
clip-path: polygon(100% 0%, 50% 0%, 0% 0%, 50% 0%, 50% 100%, 0% 100%, 50% 100%) border-box;
box-sizing: content-box;
height: 40px;
width: 40px;
padding: 20px;
margin: 20px;
border: 20px solid lightgreen;
background-color: orange;
}
.box {
display: inline-block;
width: 80px;
background-color: blue;
}
</style>
<body class="container">
<div class="shape"></div>
<div class="box" style="height: 30px;"></div>
<div class="box" style="height: 30px;"></div>
<div class="box" style="height: 20px;"></div>
<div class="box" style="height: 20px;"></div>
<div class="box" style="height: 30px;"></div>
<div class="box" style="height: 30px;"></div>
</body>
</html>

View File

@ -3049,14 +3049,12 @@ const std::string kBasicAudioVideoDataOffer =
"a=setup:actpass" CRLF;
TEST_P(NewSdpTest, BasicAudioVideoDataSdpParse) {
SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432922
ParseSdp(kBasicAudioVideoDataOffer);
ASSERT_EQ(0U, mSdpErrorHolder->GetParseErrors().size()) <<
"Got parse errors: " << GetParseErrors();
}
TEST_P(NewSdpTest, CheckApplicationParameters) {
SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432922
ParseSdp(kBasicAudioVideoDataOffer);
ASSERT_TRUE(!!mSdp);
ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
@ -3087,7 +3085,6 @@ TEST_P(NewSdpTest, CheckApplicationParameters) {
}
TEST_P(NewSdpTest, CheckExtmap) {
SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432922
ParseSdp(kBasicAudioVideoDataOffer);
ASSERT_TRUE(!!mSdp);
ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
@ -3123,7 +3120,6 @@ TEST_P(NewSdpTest, CheckExtmap) {
}
TEST_P(NewSdpTest, CheckRtcpFb) {
SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432922
ParseSdp(kBasicAudioVideoDataOffer);
ASSERT_TRUE(!!mSdp);
ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";

View File

@ -13,6 +13,8 @@
#include <ostream>
#include "mozilla/Assertions.h"
#include <limits>
namespace mozilla
{
@ -455,6 +457,9 @@ RsdparsaSdpAttributeList::LoadAttribute(RustAttributeList *attributeList,
case SdpAttribute::kRtcpAttribute:
LoadRtcp(attributeList);
return;
case SdpAttribute::kRtcpFbAttribute:
LoadRtcpFb(attributeList);
return;
case SdpAttribute::kImageattrAttribute:
LoadImageattr(attributeList);
return;
@ -473,12 +478,12 @@ RsdparsaSdpAttributeList::LoadAttribute(RustAttributeList *attributeList,
case SdpAttribute::kExtmapAttribute:
LoadExtmap(attributeList);
return;
case SdpAttribute::kDtlsMessageAttribute:
case SdpAttribute::kLabelAttribute:
case SdpAttribute::kMaxptimeAttribute:
case SdpAttribute::kSsrcGroupAttribute:
case SdpAttribute::kMaxMessageSizeAttribute:
case SdpAttribute::kRtcpFbAttribute:
case SdpAttribute::kRtcpRsizeAttribute:
case SdpAttribute::kSctpPortAttribute:
case SdpAttribute::kCandidateAttribute:
@ -846,6 +851,39 @@ RsdparsaSdpAttributeList::LoadRtcp(RustAttributeList* attributeList)
}
}
void
RsdparsaSdpAttributeList::LoadRtcpFb(RustAttributeList* attributeList)
{
auto rtcpfbsCount = sdp_get_rtcpfb_count(attributeList);
if (!rtcpfbsCount) {
return;
}
auto rustRtcpfbs = MakeUnique<RustSdpAttributeRtcpFb[]>(rtcpfbsCount);
sdp_get_rtcpfbs(attributeList, rtcpfbsCount, rustRtcpfbs.get());
auto rtcpfbList = MakeUnique<SdpRtcpFbAttributeList>();
for(size_t i = 0; i < rtcpfbsCount; i++) {
RustSdpAttributeRtcpFb& rtcpfb = rustRtcpfbs[i];
uint32_t payloadTypeU32 = rtcpfb.payloadType;
std::stringstream ss;
if(payloadTypeU32 == std::numeric_limits<uint32_t>::max()){
ss << "*";
} else {
ss << payloadTypeU32;
}
uint32_t feedbackType = rtcpfb.feedbackType;
std::string parameter = convertStringView(rtcpfb.parameter);
std::string extra = convertStringView(rtcpfb.extra);
rtcpfbList->PushEntry(ss.str(), static_cast<SdpRtcpFbAttributeList::Type>(feedbackType), parameter, extra);
}
SetAttribute(rtcpfbList.release());
}
void
RsdparsaSdpAttributeList::LoadImageattr(RustAttributeList* attributeList)
{

View File

@ -135,6 +135,7 @@ private:
void LoadMsidSemantics(RustAttributeList* attributeList);
void LoadGroup(RustAttributeList* attributeList);
void LoadRtcp(RustAttributeList* attributeList);
void LoadRtcpFb(RustAttributeList* attributeList);
void LoadImageattr(RustAttributeList* attributeList);
void LoadSctpmaps(RustAttributeList* attributeList);
void LoadDirection(RustAttributeList* attributeList);

View File

@ -94,6 +94,13 @@ struct RustSdpAttributeRtpmap {
uint32_t channels;
};
struct RustSdpAttributeRtcpFb {
uint32_t payloadType;
uint32_t feedbackType;
StringView parameter;
StringView extra;
};
struct RustSdpAttributeFmtp {
uint8_t payloadType;
StringView codecName;
@ -259,6 +266,11 @@ nsresult sdp_get_groups(const RustAttributeList* aList, size_t listSize,
nsresult sdp_get_rtcp(const RustAttributeList* aList,
RustSdpAttributeRtcp* ret);
size_t sdp_get_rtcpfb_count(const RustAttributeList* aList);
void sdp_get_rtcpfbs(const RustAttributeList* aList, size_t listSize,
RustSdpAttributeRtcpFb* ret);
size_t sdp_get_imageattr_count(const RustAttributeList* aList);
void sdp_get_imageattrs(const RustAttributeList* aList, size_t listSize,
StringView* ret);

View File

@ -1100,6 +1100,7 @@ const char* SdpRtcpFbAttributeList::tmmbr = "tmmbr";
const char* SdpRtcpFbAttributeList::tstr = "tstr";
const char* SdpRtcpFbAttributeList::vbcm = "vbcm";
void
SdpRtcpFbAttributeList::Serialize(std::ostream& os) const
{

View File

@ -6,6 +6,13 @@ use SdpType;
use error::SdpParserInternalError;
use network::{parse_nettype, parse_addrtype, parse_unicast_addr};
#[derive(Clone)]
pub enum SdpAttributePayloadType {
PayloadType(u8),
Wildcard, // Wildcard means "*",
}
#[derive(Clone)]
pub enum SdpAttributeCandidateTransport {
Udp,
@ -182,11 +189,23 @@ impl SdpAttributeRtcp {
}
}
#[derive(Clone)]
pub enum SdpAttributeRtcpFbType {
Ack = 0,
Ccm = 2, // This is explicitly 2 to make the conversion to the
// enum used in the glue-code possible. The glue code has "app"
// in the place of 1
Nack,
TrrInt,
Remb
}
#[derive(Clone)]
pub struct SdpAttributeRtcpFb {
pub payload_type: u32,
// TODO parse this and use an enum instead?
pub feedback_type: String,
pub payload_type: SdpAttributePayloadType,
pub feedback_type: SdpAttributeRtcpFbType,
pub parameter: String,
pub extra: String,
}
#[derive(Clone)]
@ -570,6 +589,14 @@ fn string_or_empty(to_parse: &str) -> Result<String, SdpParserInternalError> {
}
}
fn parse_payload_type(to_parse: &str) -> Result<SdpAttributePayloadType, SdpParserInternalError>
{
Ok(match to_parse {
"*" => SdpAttributePayloadType::Wildcard,
_ => SdpAttributePayloadType::PayloadType(to_parse.parse::<u8>()?)
})
}
fn parse_sctp_port(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
let port = to_parse.parse()?;
if port > 65535 {
@ -941,17 +968,106 @@ fn parse_rtcp(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
}
fn parse_rtcp_fb(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
let tokens: Vec<&str> = to_parse.splitn(2, ' ').collect();
let tokens: Vec<&str> = to_parse.splitn(4,' ').collect();
// Parse this in advance to use it later in the parameter switch
let feedback_type = match tokens.get(1) {
Some(x) => match x.as_ref(){
"ack" => SdpAttributeRtcpFbType::Ack,
"ccm" => SdpAttributeRtcpFbType::Ccm,
"nack" => SdpAttributeRtcpFbType::Nack,
"trr-int" => SdpAttributeRtcpFbType::TrrInt,
"goog-remb" => SdpAttributeRtcpFbType::Remb,
_ => {
return Err(SdpParserInternalError::Unsupported(
format!("Unknown rtcpfb feedback type: {:?}",x).to_string()
))
}
},
None => {
return Err(SdpParserInternalError::Generic(
"Error parsing rtcpfb: no feedback type".to_string(),
))
}
};
// Parse this in advance to make the initilization block below better readable
let parameter = match &feedback_type {
&SdpAttributeRtcpFbType::Ack => match tokens.get(2) {
Some(x) => match x.as_ref() {
"rpsi" | "app" => x.to_string(),
_ => {
return Err(SdpParserInternalError::Unsupported(
format!("Unknown rtcpfb ack parameter: {:?}",x).to_string()
))
},
}
None => {
return Err(SdpParserInternalError::Unsupported(
format!("The rtcpfb ack feeback type needs a parameter:").to_string()
))
}
},
&SdpAttributeRtcpFbType::Ccm => match tokens.get(2) {
Some(x) => match x.as_ref() {
"fir" | "tmmbr" | "tstr" | "vbcm" => x.to_string(),
_ => {
return Err(SdpParserInternalError::Unsupported(
format!("Unknown rtcpfb ccm parameter: {:?}",x).to_string()
))
},
}
None => "".to_string(),
},
&SdpAttributeRtcpFbType::Nack => match tokens.get(2) {
Some(x) => match x.as_ref() {
"sli" | "pli" | "rpsi" | "app" => x.to_string(),
_ => {
return Err(SdpParserInternalError::Unsupported(
format!("Unknown rtcpfb nack parameter: {:?}",x).to_string()
))
},
}
None => "".to_string(),
},
&SdpAttributeRtcpFbType::TrrInt => match tokens.get(2) {
Some(x) => match x {
_ if x.parse::<u32>().is_ok() => x.to_string(),
_ => {
return Err(SdpParserInternalError::Generic(
format!("Unknown rtcpfb trr-int parameter: {:?}",x).to_string()
))
},
}
None => {
return Err(SdpParserInternalError::Generic(
format!("The rtcpfb trr-int feedback type needs a parameter").to_string()
))
}
},
&SdpAttributeRtcpFbType::Remb => match tokens.get(2) {
Some(x) => match x {
_ => {
return Err(SdpParserInternalError::Unsupported(
format!("Unknown rtcpfb remb parameter: {:?}",x).to_string()
))
},
}
None => "".to_string(),
}
};
Ok(SdpAttribute::Rtcpfb(SdpAttributeRtcpFb {
// TODO limit this to dymaic PTs
payload_type: tokens[0].parse::<u32>()?,
feedback_type: match tokens.get(1) {
payload_type: parse_payload_type(tokens[0])?,
feedback_type: feedback_type,
parameter: parameter,
extra: match tokens.get(3) {
Some(x) => x.to_string(),
None => {
return Err(SdpParserInternalError::Generic(
"Error parsing rtcpfb".to_string(),
))
}
None => "".to_string(),
},
}))
}

View File

@ -360,6 +360,8 @@ pub fn parse_media_vector(lines: &[SdpLine]) -> Result<Vec<SdpMedia>, SdpParserE
})
}
};
for line in lines.iter().skip(1) {
match line.sdp_type {
SdpType::Connection(ref c) => {
@ -408,7 +410,9 @@ pub fn parse_media_vector(lines: &[SdpLine]) -> Result<Vec<SdpMedia>, SdpParserE
SdpType::Key(_) => (),
};
}
media_sections.push(sdp_media);
Ok(media_sections)
}
// TODO add unit tests for parse_media_vector

View File

@ -2,12 +2,13 @@ use std::slice;
use libc::{size_t, uint8_t, uint16_t, uint32_t, int64_t};
use rsdparsa::SdpSession;
use rsdparsa::attribute_type::{SdpAttribute, SdpAttributeFingerprint, SdpAttributeSetup, SdpAttributeSsrc, SdpAttributeRtpmap, SdpAttributeMsid, SdpAttributeMsidSemantic, SdpAttributeGroupSemantic, SdpAttributeGroup, SdpAttributeRtcp, SdpAttributeSctpmap, SdpAttributeRemoteCandidate, SdpAttributeExtmap, SdpAttributeDirection};
use rsdparsa::attribute_type::{SdpAttribute, SdpAttributePayloadType, SdpAttributeFingerprint, SdpAttributeSetup, SdpAttributeSsrc, SdpAttributeRtpmap, SdpAttributeMsid, SdpAttributeMsidSemantic, SdpAttributeGroupSemantic, SdpAttributeGroup, SdpAttributeRtcp, SdpAttributeRtcpFb, SdpAttributeSctpmap, SdpAttributeRemoteCandidate, SdpAttributeExtmap, SdpAttributeDirection};
use nserror::{nsresult, NS_OK, NS_ERROR_INVALID_ARG};
use types::StringView;
use network::RustIpAddr;
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum RustSdpAttributeType {
@ -570,6 +571,47 @@ pub unsafe extern "C" fn sdp_get_rtcp(attributes: *const Vec<SdpAttribute>, ret:
NS_ERROR_INVALID_ARG
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct RustSdpAttributeRtcpFb {
pub payload_type: u32,
pub feedback_type: u32,
pub parameter: StringView,
pub extra: StringView
}
impl<'a> From<&'a SdpAttributeRtcpFb> for RustSdpAttributeRtcpFb {
fn from(other: &SdpAttributeRtcpFb) -> Self {
RustSdpAttributeRtcpFb {
payload_type: match other.payload_type{
SdpAttributePayloadType::Wildcard => u32::max_value(),
SdpAttributePayloadType::PayloadType(x) => x as u32,
},
feedback_type: other.feedback_type.clone() as u32,
parameter: StringView::from(other.parameter.as_str()),
extra: StringView::from(other.extra.as_str()),
}
}
}
#[no_mangle]
pub unsafe extern "C" fn sdp_get_rtcpfb_count(attributes: *const Vec<SdpAttribute>) -> size_t {
count_attribute((*attributes).as_slice(), RustSdpAttributeType::Rtcpfb)
}
#[no_mangle]
pub unsafe extern "C" fn sdp_get_rtcpfbs(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_rtcpfbs: *mut RustSdpAttributeRtcpFb) {
let attrs: Vec<_> = (*attributes).iter().filter_map(|x| if let SdpAttribute::Rtcpfb(ref data) = *x {
Some(RustSdpAttributeRtcpFb::from(data))
} else {
None
}).collect();
let rtcpfbs = slice::from_raw_parts_mut(ret_rtcpfbs, ret_size);
rtcpfbs.clone_from_slice(attrs.as_slice());
}
#[no_mangle]
pub unsafe extern "C" fn sdp_get_imageattr_count(attributes: *const Vec<SdpAttribute>) -> size_t {
count_attribute((*attributes).as_slice(), RustSdpAttributeType::ImageAttr)

View File

@ -362,7 +362,19 @@ ARCHIVE_FILES = {
'base': '',
'pattern': 'mozinfo.json',
'dest': 'mochitest'
}
},
{
'source': buildconfig.topobjdir,
'base': 'dist/xpi-stage',
'pattern': 'mochijar/**',
'dest': 'mochitest'
},
{
'source': buildconfig.topobjdir,
'base': 'dist/xpi-stage',
'pattern': 'specialpowers/**',
'dest': 'mochitest/extensions'
},
],
'mozharness': [
{

View File

@ -507,13 +507,17 @@ class TupBackend(CommonBackend):
else:
self._process_generated_file(backend_file, obj)
elif (isinstance(obj, ChromeManifestEntry) and
obj.install_target.startswith('dist/bin')):
top_level = mozpath.join(obj.install_target, 'chrome.manifest')
if obj.path != top_level:
entry = 'manifest %s' % mozpath.relpath(obj.path,
obj.install_target)
self._manifest_entries[top_level].add(entry)
self._manifest_entries[obj.path].add(str(obj.entry))
obj.install_target.startswith(('dist/bin', 'dist/xpi-stage'))):
# The quitter extension specifies its chrome.manifest as a
# FINAL_TARGET_FILE, which conflicts with the manifest generation
# we do here, so skip it for now.
if obj.install_target != 'dist/xpi-stage/quitter':
top_level = mozpath.join(obj.install_target, 'chrome.manifest')
if obj.path != top_level:
entry = 'manifest %s' % mozpath.relpath(obj.path,
obj.install_target)
self._manifest_entries[top_level].add(entry)
self._manifest_entries[obj.path].add(str(obj.entry))
elif isinstance(obj, Defines):
self._process_defines(backend_file, obj)
elif isinstance(obj, HostDefines):

View File

@ -993,6 +993,19 @@ class BuildDriver(MozbuildObject):
return False
def backend_out_of_date(backend_file):
if not os.path.isfile(backend_file):
return True
# Check if any of our output files have been removed since
# we last built the backend, re-generate the backend if
# so.
outputs = []
with open(backend_file, 'r') as fh:
outputs = fh.read().splitlines()
for output in outputs:
if not os.path.isfile(mozpath.join(self.topobjdir, output)):
return True
dep_file = '%s.in' % backend_file
return build_out_of_date(backend_file, dep_file)

View File

@ -1166,6 +1166,10 @@ int
Connection::stepStatement(sqlite3 *aNativeConnection, sqlite3_stmt *aStatement)
{
MOZ_ASSERT(aStatement);
AUTO_PROFILER_LABEL_DYNAMIC_CSTR("Connection::stepStatement", OTHER,
::sqlite3_sql(aStatement));
bool checkedMainThread = false;
TimeStamp startTime = TimeStamp::Now();
@ -1279,6 +1283,8 @@ Connection::executeSql(sqlite3 *aNativeConnection, const char *aSqlString)
if (!isConnectionReadyOnThisThread())
return SQLITE_MISUSE;
AUTO_PROFILER_LABEL_DYNAMIC_CSTR("Connection::executeSql", OTHER, aSqlString);
TimeStamp startTime = TimeStamp::Now();
int srv = ::sqlite3_exec(aNativeConnection, aSqlString, nullptr, nullptr,
nullptr);

View File

@ -9,6 +9,7 @@ kind-dependencies:
transforms:
- taskgraph.transforms.build_attrs:transforms
- taskgraph.transforms.build_lints:transforms
- taskgraph.transforms.use_toolchains:transforms
- taskgraph.transforms.job:transforms
- taskgraph.transforms.task:transforms
@ -28,6 +29,8 @@ jobs:
worker-type: aws-provisioner-v1/gecko-{level}-b-linux
worker:
max-run-time: 36000
env:
PERFHERDER_EXTRA_OPTIONS: artifact
run:
using: mozharness
actions: [get-secrets build]

View File

@ -9,6 +9,7 @@ kind-dependencies:
transforms:
- taskgraph.transforms.build_attrs:transforms
- taskgraph.transforms.build_lints:transforms
- taskgraph.transforms.use_toolchains:transforms
- taskgraph.transforms.job:transforms
- taskgraph.transforms.task:transforms

View File

@ -11,6 +11,7 @@ transforms:
kind-dependencies:
- post-beetmover-dummy
- release-generate-checksums-beetmover
- release-bouncer-sub
job-defaults:

View File

@ -9,6 +9,7 @@ kind-dependencies:
transforms:
- taskgraph.transforms.build_attrs:transforms
- taskgraph.transforms.build_lints:transforms
- taskgraph.transforms.use_toolchains:transforms
- taskgraph.transforms.job:transforms
- taskgraph.transforms.task:transforms
@ -32,6 +33,8 @@ jobs:
worker-type: aws-provisioner-v1/gecko-{level}-b-linux
worker:
max-run-time: 36000
env:
PERFHERDER_EXTRA_OPTIONS: searchfox
run:
using: mozharness
actions: [build]
@ -56,6 +59,7 @@ jobs:
max-run-time: 36000
env:
TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-releng.manifest"
PERFHERDER_EXTRA_OPTIONS: searchfox
run:
using: mozharness
actions: [get-secrets build update]
@ -89,6 +93,7 @@ jobs:
max-run-time: 7200
env:
TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
PERFHERDER_EXTRA_OPTIONS: searchfox
run:
using: mozharness
options: [append-env-variables-from-configs]

View File

@ -3,11 +3,12 @@ job-defaults:
require-build: true
worker-type:
by-platform:
linux64.*: aws-provisioner-v1/gecko-t-linux-xlarge
linux64.*: releng-hardware/gecko-t-linux-talos
worker:
by-platform:
linux64.*:
docker-image: {in-tree: "desktop1604-test"}
env:
SHELL: /bin/bash
max-run-time: 1800
treeherder:
kind: test
@ -17,6 +18,7 @@ job-defaults:
use-artifacts:
build:
- target.jsshell.zip
workdir: /home/cltbld
run-on-projects: ['mozilla-central', 'try']
bench-ares6:
@ -28,7 +30,7 @@ bench-ares6:
cd $USE_ARTIFACT_PATH/build &&
unzip -q -d jsshell target.jsshell.zip &&
export JSSHELL=$USE_ARTIFACT_PATH/build/jsshell/js &&
cd /builds/worker/checkouts/gecko &&
cd $GECKO_PATH &&
./mach jsshell-bench --binary $JSSHELL --perfherder ares6
bench-sixspeed:
@ -40,5 +42,5 @@ bench-sixspeed:
cd $USE_ARTIFACT_PATH/build &&
unzip -q -d jsshell target.jsshell.zip &&
export JSSHELL=$USE_ARTIFACT_PATH/build/jsshell/js &&
cd /builds/worker/checkouts/gecko &&
cd $GECKO_PATH &&
./mach jsshell-bench --binary $JSSHELL --perfherder six-speed

View File

@ -10,6 +10,7 @@ kind-dependencies:
transforms:
- taskgraph.transforms.spidermonkey:transforms
- taskgraph.transforms.build_attrs:transforms
- taskgraph.transforms.build_lints:transforms
- taskgraph.transforms.use_toolchains:transforms
- taskgraph.transforms.job:transforms
- taskgraph.transforms.task:transforms

View File

@ -9,6 +9,7 @@ kind-dependencies:
transforms:
- taskgraph.transforms.build_attrs:transforms
- taskgraph.transforms.build_lints:transforms
- taskgraph.transforms.use_toolchains:transforms
- taskgraph.transforms.job:transforms
- taskgraph.transforms.task:transforms
@ -31,6 +32,8 @@ jobs:
worker-type: aws-provisioner-v1/gecko-t-linux-large
worker:
max-run-time: 3600
env:
PERFHERDER_EXTRA_OPTIONS: static-analysis-autotest
run:
using: mozharness
actions: [static-analysis-autotest]

View File

@ -9,6 +9,7 @@ kind-dependencies:
transforms:
- taskgraph.transforms.build_attrs:transforms
- taskgraph.transforms.build_lints:transforms
- taskgraph.transforms.use_toolchains:transforms
- taskgraph.transforms.job:transforms
- taskgraph.transforms.task:transforms
@ -31,6 +32,8 @@ jobs:
worker-type: aws-provisioner-v1/gecko-{level}-b-linux
worker:
max-run-time: 36000
env:
PERFHERDER_EXTRA_OPTIONS: static-analysis
run:
using: mozharness
actions: [build]
@ -54,6 +57,8 @@ jobs:
worker-type: aws-provisioner-v1/gecko-{level}-b-linux
worker:
max-run-time: 36000
env:
PERFHERDER_EXTRA_OPTIONS: static-analysis
run:
using: mozharness
actions: [build]
@ -82,6 +87,7 @@ jobs:
max-run-time: 7200
env:
TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win32/releng.manifest"
PERFHERDER_EXTRA_OPTIONS: static-analysis
run:
using: mozharness
options: [append-env-variables-from-configs]
@ -110,6 +116,7 @@ jobs:
max-run-time: 7200
env:
TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win32/releng.manifest"
PERFHERDER_EXTRA_OPTIONS: static-analysis
run:
using: mozharness
options: [append-env-variables-from-configs]
@ -138,6 +145,7 @@ jobs:
max-run-time: 7200
env:
TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
PERFHERDER_EXTRA_OPTIONS: static-analysis
run:
using: mozharness
options: [append-env-variables-from-configs]
@ -166,6 +174,7 @@ jobs:
max-run-time: 7200
env:
TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
PERFHERDER_EXTRA_OPTIONS: static-analysis
run:
using: mozharness
options: [append-env-variables-from-configs]

View File

@ -9,6 +9,7 @@ kind-dependencies:
transforms:
- taskgraph.transforms.build_attrs:transforms
- taskgraph.transforms.build_lints:transforms
- taskgraph.transforms.use_toolchains:transforms
- taskgraph.transforms.job:transforms
- taskgraph.transforms.task:transforms
@ -28,6 +29,8 @@ jobs:
worker:
docker-image: {in-tree: valgrind-build}
max-run-time: 72000
env:
PERFHERDER_EXTRA_OPTIONS: valgrind
run:
using: mozharness
actions: [get-secrets build valgrind-test]

View File

@ -468,7 +468,7 @@ def vcs_checkout(source_repo, dest, store_path,
def main(args):
print_line(b'setup', b'run-task started\n')
print_line(b'setup', b'run-task started in %s\n' % os.getcwd().encode('utf-8'))
running_as_root = IS_POSIX and os.getuid() == 0
# Arguments up to '--' are ours. After are for the main task
@ -506,18 +506,13 @@ def main(args):
if 'HG_STORE_PATH' in os.environ:
os.environ['HG_STORE_PATH'] = os.path.expanduser(os.environ['HG_STORE_PATH'])
if IS_POSIX:
if running_as_root:
user, group, gids = get_posix_user_group(args.user, args.group)
uid = user.pw_uid
gid = group.gr_gid
else:
print('error: run-task must be run as root on POSIX platforms')
return 1
else:
uid = gid = gids = None
uid = gid = gids = None
if IS_POSIX and running_as_root:
user, group, gids = get_posix_user_group(args.user, args.group)
uid = user.pw_uid
gid = group.gr_gid
if os.path.exists("/dev/kvm"):
if running_as_root and os.path.exists("/dev/kvm"):
# Ensure kvm permissions for worker, required for Android x86
st = os.stat("/dev/kvm")
os.chmod("/dev/kvm", st.st_mode | 0o666)

View File

@ -80,6 +80,18 @@ PER_PROJECT_PARAMETERS = {
'include_nightly': True,
},
'comm-beta': {
'target_tasks_method': 'mozilla_beta_tasks',
'optimize_target_tasks': True,
'include_nightly': True,
},
'comm-esr60': {
'target_tasks_method': 'mozilla_beta_tasks',
'optimize_target_tasks': True,
'include_nightly': True,
},
'pine': {
'target_tasks_method': 'pine_tasks',
'optimize_target_tasks': True,

View File

@ -12,6 +12,8 @@ from taskgraph.transforms.base import TransformSequence
transforms = TransformSequence()
SEEN_CONFIGS = {}
@transforms.add
def check_mozharness_perfherder_options(config, jobs):
@ -26,7 +28,6 @@ def check_mozharness_perfherder_options(config, jobs):
to the same bucket by looking for jobs not defining extra options when
their platform or mozharness config are otherwise similar.
"""
seen_configs = {}
for job in jobs:
if job['run']['using'] != 'mozharness':
@ -47,12 +48,13 @@ def check_mozharness_perfherder_options(config, jobs):
key = (platform, primary_config, nightly, options)
if key in seen_configs:
raise Exception('Non-unique Perfherder data collection for jobs '
'%s and %s: set PERFHERDER_EXTRA_OPTIONS in worker '
'environment variables or use different mozconfigs'
% (job['name'], seen_configs[key]))
if key in SEEN_CONFIGS:
raise Exception(
'Non-unique Perfherder data collection for jobs %s-%s and %s: '
'set PERFHERDER_EXTRA_OPTIONS in worker environment variables '
'or use different mozconfigs'
% (config.kind, job['name'], SEEN_CONFIGS[key]))
seen_configs[key] = job['name']
SEEN_CONFIGS[key] = '{}-{}'.format(config.kind, job['name'])
yield job

View File

@ -82,6 +82,9 @@ job_description_schema = Schema({
# The key to a job implementation in a peer module to this one
'using': basestring,
# Base work directory used to set up the task.
Optional('workdir'): basestring,
# Any remaining content is verified against that job implementation's
# own schema.
Extra: object,
@ -149,6 +152,8 @@ def make_task_description(config, jobs):
if os:
worker['os'] = os
job['run'].setdefault('workdir', '/builds/worker')
taskdesc = copy.deepcopy(job)
# fill in some empty defaults to make run implementations easier

View File

@ -27,7 +27,7 @@ def docker_worker_add_workspace_cache(config, job, taskdesc, extra=None):
taskdesc['attributes']['build_platform'],
taskdesc['attributes']['build_type'],
),
'mount-point': "/builds/worker/workspace",
'mount-point': "{workdir}/workspace".format(**job['run']),
# Don't enable the workspace cache when we can't guarantee its
# behavior, like on Try.
'skip-untrusted': True,
@ -48,7 +48,7 @@ def add_artifacts(config, job, taskdesc, path):
def docker_worker_add_artifacts(config, job, taskdesc):
""" Adds an artifact directory to the task """
add_artifacts(config, job, taskdesc, path='/builds/worker/artifacts/')
add_artifacts(config, job, taskdesc, path='{workdir}/artifacts/'.format(**job['run']))
def generic_worker_add_artifacts(config, job, taskdesc):
@ -85,14 +85,15 @@ def support_vcs_checkout(config, job, taskdesc, sparse=False):
taskdesc['worker'].setdefault('caches', []).append({
'type': 'persistent',
'name': name,
'mount-point': '/builds/worker/checkouts',
'mount-point': '{workdir}/checkouts'.format(**job['run']),
})
taskdesc['worker'].setdefault('env', {}).update({
'GECKO_BASE_REPOSITORY': config.params['base_repository'],
'GECKO_HEAD_REPOSITORY': config.params['head_repository'],
'GECKO_HEAD_REV': config.params['head_rev'],
'HG_STORE_PATH': '/builds/worker/checkouts/hg-store',
'GECKO_PATH': '{workdir}/checkouts/gecko'.format(**job['run']),
'HG_STORE_PATH': '{workdir}/checkouts/hg-store'.format(**job['run']),
})
if 'comm_base_repository' in config.params:
@ -176,11 +177,11 @@ def docker_worker_add_tooltool(config, job, taskdesc, internal=False):
taskdesc['worker'].setdefault('caches', []).append({
'type': 'persistent',
'name': 'level-%s-tooltool-cache' % level,
'mount-point': '/builds/worker/tooltool-cache',
'mount-point': '{workdir}/tooltool-cache'.format(**job['run']),
})
taskdesc['worker'].setdefault('env', {}).update({
'TOOLTOOL_CACHE': '/builds/worker/tooltool-cache',
'TOOLTOOL_CACHE': '{workdir}/tooltool-cache'.format(**job['run']),
})
taskdesc['worker']['relengapi-proxy'] = True
@ -194,7 +195,7 @@ def docker_worker_add_tooltool(config, job, taskdesc, internal=False):
])
def docker_worker_use_artifacts(config, job, taskdesc, use_artifacts):
def support_use_artifacts(config, job, taskdesc, use_artifacts):
"""Set a JSON object of artifact URLs in an environment variable.
This will tell the run-task script to download the artifacts.
@ -214,4 +215,4 @@ def docker_worker_use_artifacts(config, job, taskdesc, use_artifacts):
env = taskdesc['worker'].setdefault('env', {})
env['USE_ARTIFACT_URLS'] = {'task-reference': json.dumps(urls)}
env['USE_ARTIFACT_PATH'] = '/builds/worker/use-artifacts'
env['USE_ARTIFACT_PATH'] = '{workdir}/use-artifacts'.format(**job['run'])

View File

@ -56,6 +56,9 @@ run_schema = Schema({
# a *-backports archive, its solver might not be able to find a
# solution that satisfies the build dependencies.
Optional('resolver'): Any('apt-get', 'aptitude'),
# Base work directory used to set up the task.
Required('workdir'): basestring,
})

View File

@ -34,6 +34,9 @@ haz_run_schema = Schema({
# appropriately. `true` here means ['*'], all secrets. Not supported on
# Windows
Required('secrets', default=False): Any(bool, [basestring]),
# Base work directory used to set up the task.
Required('workdir'): basestring,
})
@ -62,11 +65,11 @@ def docker_worker_hazard(config, job, taskdesc):
# build-haz-linux.sh needs this otherwise it assumes the checkout is in
# the workspace.
env['GECKO_DIR'] = '/builds/worker/checkouts/gecko'
env['GECKO_DIR'] = '{workdir}/checkouts/gecko'.format(**run)
worker['command'] = [
'/builds/worker/bin/run-task',
'--vcs-checkout', '/builds/worker/checkouts/gecko',
'{workdir}/bin/run-task'.format(**run),
'--vcs-checkout', '{workdir}/checkouts/gecko'.format(**run),
'--',
'/bin/bash', '-c', run['command']
]

View File

@ -20,6 +20,9 @@ mach_schema = Schema({
# if true, perform a checkout of a comm-central based branch inside the
# gecko checkout
Required('comm-checkout'): bool,
# Base work directory used to set up the task.
Required('workdir'): basestring,
})
@ -29,7 +32,7 @@ def docker_worker_mach(config, job, taskdesc):
run = job['run']
# defer to the run_task implementation
run['command'] = 'cd /builds/worker/checkouts/gecko && ./mach ' + run['mach']
run['command'] = 'cd {workdir}/checkouts/gecko && ./mach {mach}'.format(**run)
run['using'] = 'run-task'
del run['mach']
configure_taskdesc_for_run(config, job, taskdesc, job['worker']['implementation'])

Some files were not shown because too many files have changed in this diff Show More