Bug 690187 - Clip or suppress a marker if it makes the line empty. r=roc

This commit is contained in:
Mats Palmgren 2011-12-19 15:48:31 +01:00
Родитель 084e39e944
Коммит 0d801fb5ed
12 изменённых файлов: 355 добавлений и 134 удалений

Просмотреть файл

@ -287,7 +287,8 @@ TextOverflow::ExamineFrameSubtree(nsIFrame* aFrame,
const nsRect& aInsideMarkersArea,
FrameHashtable* aFramesToHide,
AlignmentEdges* aAlignmentEdges,
bool* aFoundVisibleTextOrAtomic)
bool* aFoundVisibleTextOrAtomic,
InnerClipEdges* aClippedMarkerEdges)
{
const nsIAtom* frameType = aFrame->GetType();
if (frameType == nsGkAtoms::brFrame ||
@ -312,7 +313,8 @@ TextOverflow::ExamineFrameSubtree(nsIFrame* aFrame,
} else if (isAtomic || frameType == nsGkAtoms::textFrame) {
AnalyzeMarkerEdges(aFrame, frameType, aInsideMarkersArea,
aFramesToHide, aAlignmentEdges,
aFoundVisibleTextOrAtomic);
aFoundVisibleTextOrAtomic,
aClippedMarkerEdges);
}
}
if (isAtomic) {
@ -323,7 +325,8 @@ TextOverflow::ExamineFrameSubtree(nsIFrame* aFrame,
while (child) {
ExamineFrameSubtree(child, aContentArea, aInsideMarkersArea,
aFramesToHide, aAlignmentEdges,
aFoundVisibleTextOrAtomic);
aFoundVisibleTextOrAtomic,
aClippedMarkerEdges);
child = child->GetNextSibling();
}
}
@ -334,7 +337,8 @@ TextOverflow::AnalyzeMarkerEdges(nsIFrame* aFrame,
const nsRect& aInsideMarkersArea,
FrameHashtable* aFramesToHide,
AlignmentEdges* aAlignmentEdges,
bool* aFoundVisibleTextOrAtomic)
bool* aFoundVisibleTextOrAtomic,
InnerClipEdges* aClippedMarkerEdges)
{
nsRect borderRect(aFrame->GetOffsetTo(mBlock), aFrame->GetSize());
nscoord leftOverlap =
@ -344,19 +348,23 @@ TextOverflow::AnalyzeMarkerEdges(nsIFrame* aFrame,
bool insideLeftEdge = aInsideMarkersArea.x <= borderRect.XMost();
bool insideRightEdge = borderRect.x <= aInsideMarkersArea.XMost();
if ((leftOverlap > 0 && insideLeftEdge) ||
(rightOverlap > 0 && insideRightEdge)) {
if (aFrameType == nsGkAtoms::textFrame &&
aInsideMarkersArea.x < aInsideMarkersArea.XMost()) {
if (leftOverlap > 0) {
aClippedMarkerEdges->AccumulateLeft(borderRect);
if (!mLeft.mActive) {
leftOverlap = 0;
}
}
if (rightOverlap > 0) {
aClippedMarkerEdges->AccumulateRight(borderRect);
if (!mRight.mActive) {
rightOverlap = 0;
}
if (leftOverlap == 0 && rightOverlap == 0) {
return;
}
if ((leftOverlap > 0 && insideLeftEdge) ||
(rightOverlap > 0 && insideRightEdge)) {
if (aFrameType == nsGkAtoms::textFrame) {
if (aInsideMarkersArea.x < aInsideMarkersArea.XMost()) {
// a clipped text frame and there is some room between the markers
nscoord snappedLeft, snappedRight;
bool isFullyClipped =
@ -374,13 +382,9 @@ TextOverflow::AnalyzeMarkerEdges(nsIFrame* aFrame,
aAlignmentEdges->Accumulate(snappedRect);
*aFoundVisibleTextOrAtomic = true;
}
} else if (IsAtomicElement(aFrame, aFrameType)) {
if ((leftOverlap > 0 && insideLeftEdge && mLeft.mActive) ||
(rightOverlap > 0 && insideRightEdge && mRight.mActive)) {
aFramesToHide->PutEntry(aFrame);
} else {
*aFoundVisibleTextOrAtomic = true;
}
} else {
aFramesToHide->PutEntry(aFrame);
}
} else if (!insideLeftEdge || !insideRightEdge) {
// frame is outside
@ -434,11 +438,14 @@ TextOverflow::ExamineLineFrames(nsLineBox* aLine,
return;
}
PRUint32 pass = 0;
int pass = 0;
bool retryEmptyLine = true;
bool guessLeft = leftOverflow;
bool guessRight = rightOverflow;
mLeft.mActive = leftOverflow;
mRight.mActive = rightOverflow;
bool clippedLeftMarker = false;
bool clippedRightMarker = false;
do {
// Setup marker strings as needed.
if (guessLeft) {
@ -450,9 +457,9 @@ TextOverflow::ExamineLineFrames(nsLineBox* aLine,
// If there is insufficient space for both markers then keep the one on the
// end side per the block's 'direction'.
nscoord rightMarkerWidth = mRight.mWidth;
nscoord leftMarkerWidth = mLeft.mWidth;
if (leftOverflow && rightOverflow &&
nscoord rightMarkerWidth = mRight.mActive ? mRight.mWidth : 0;
nscoord leftMarkerWidth = mLeft.mActive ? mLeft.mWidth : 0;
if (leftMarkerWidth && rightMarkerWidth &&
leftMarkerWidth + rightMarkerWidth > contentArea.width) {
if (mBlockIsRTL) {
rightMarkerWidth = 0;
@ -476,12 +483,52 @@ TextOverflow::ExamineLineFrames(nsLineBox* aLine,
bool foundVisibleTextOrAtomic = false;
PRInt32 n = aLine->GetChildCount();
nsIFrame* child = aLine->mFirstChild;
InnerClipEdges clippedMarkerEdges;
for (; n-- > 0; child = child->GetNextSibling()) {
ExamineFrameSubtree(child, contentArea, insideMarkersArea,
aFramesToHide, aAlignmentEdges,
&foundVisibleTextOrAtomic);
&foundVisibleTextOrAtomic,
&clippedMarkerEdges);
}
if (guessLeft == mLeft.IsNeeded() && guessRight == mRight.IsNeeded()) {
if (!foundVisibleTextOrAtomic && retryEmptyLine) {
aAlignmentEdges->mAssigned = false;
aFramesToHide->Clear();
pass = -1;
if (mLeft.IsNeeded() && mLeft.mActive && !clippedLeftMarker) {
if (clippedMarkerEdges.mAssignedLeft &&
clippedMarkerEdges.mLeft - mContentArea.X() > 0) {
mLeft.mWidth = clippedMarkerEdges.mLeft - mContentArea.X();
NS_ASSERTION(mLeft.mWidth < mLeft.mIntrinsicWidth,
"clipping a marker should make it strictly smaller");
clippedLeftMarker = true;
} else {
mLeft.mActive = guessLeft = false;
}
continue;
}
if (mRight.IsNeeded() && mRight.mActive && !clippedRightMarker) {
if (clippedMarkerEdges.mAssignedRight &&
mContentArea.XMost() - clippedMarkerEdges.mRight > 0) {
mRight.mWidth = mContentArea.XMost() - clippedMarkerEdges.mRight;
NS_ASSERTION(mRight.mWidth < mRight.mIntrinsicWidth,
"clipping a marker should make it strictly smaller");
clippedRightMarker = true;
} else {
mRight.mActive = guessRight = false;
}
continue;
}
// The line simply has no visible content even without markers,
// so examine the line again without suppressing markers.
retryEmptyLine = false;
mLeft.mWidth = mLeft.mIntrinsicWidth;
mLeft.mActive = guessLeft = leftOverflow;
mRight.mWidth = mRight.mIntrinsicWidth;
mRight.mActive = guessRight = rightOverflow;
continue;
}
if (guessLeft == (mLeft.mActive && mLeft.IsNeeded()) &&
guessRight == (mRight.mActive && mRight.IsNeeded())) {
break;
} else {
guessLeft = mLeft.IsNeeded();
@ -492,10 +539,10 @@ TextOverflow::ExamineLineFrames(nsLineBox* aLine,
}
NS_ASSERTION(pass == 0, "2nd pass should never guess wrong");
} while (++pass != 2);
if (!leftOverflow) {
if (!leftOverflow || !mLeft.mActive) {
mLeft.Reset();
}
if (!rightOverflow) {
if (!rightOverflow || !mRight.mActive) {
mRight.Reset();
}
}
@ -647,9 +694,9 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine,
const nsRect& aInsideMarkersArea) const
{
if (aCreateLeft) {
nsRect markerRect = nsRect(aInsideMarkersArea.x - mLeft.mWidth,
nsRect markerRect = nsRect(aInsideMarkersArea.x - mLeft.mIntrinsicWidth,
aLine->mBounds.y,
mLeft.mWidth, aLine->mBounds.height);
mLeft.mIntrinsicWidth, aLine->mBounds.height);
markerRect += mBuilder->ToReferenceFrame(mBlock);
nsDisplayItem* marker = new (mBuilder)
nsDisplayTextOverflowMarker(mBuilder, mBlock, markerRect,
@ -665,7 +712,7 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine,
if (aCreateRight) {
nsRect markerRect = nsRect(aInsideMarkersArea.XMost(),
aLine->mBounds.y,
mRight.mWidth, aLine->mBounds.height);
mRight.mIntrinsicWidth, aLine->mBounds.height);
markerRect += mBuilder->ToReferenceFrame(mBlock);
nsDisplayItem* marker = new (mBuilder)
nsDisplayTextOverflowMarker(mBuilder, mBlock, markerRect,
@ -696,6 +743,7 @@ TextOverflow::Marker::SetupString(nsIFrame* aFrame)
GetEllipsis(fm) : mStyle->mString;
mWidth = nsLayoutUtils::GetStringWidth(aFrame, rc, mMarkerString.get(),
mMarkerString.Length());
mIntrinsicWidth = mWidth;
mInitialized = true;
}

Просмотреть файл

@ -98,6 +98,30 @@ class TextOverflow {
bool mAssigned;
};
struct InnerClipEdges {
InnerClipEdges() : mAssignedLeft(false), mAssignedRight(false) {}
void AccumulateLeft(const nsRect& aRect) {
if (NS_LIKELY(mAssignedLeft)) {
mLeft = NS_MAX(mLeft, aRect.X());
} else {
mLeft = aRect.X();
mAssignedLeft = true;
}
}
void AccumulateRight(const nsRect& aRect) {
if (NS_LIKELY(mAssignedRight)) {
mRight = NS_MIN(mRight, aRect.XMost());
} else {
mRight = aRect.XMost();
mAssignedRight = true;
}
}
nscoord mLeft;
nscoord mRight;
bool mAssignedLeft;
bool mAssignedRight;
};
/**
* Examines frames on the line to determine whether we should draw a left
* and/or right marker, and if so, which frames should be completely hidden
@ -122,13 +146,16 @@ class TextOverflow {
* inline-level frames that are inside the area between the markers
* @param aFoundVisibleTextOrAtomic is set to true if a text or atomic
* inline-level frame is visible between the marker edges
* @param aClippedMarkerEdges the innermost edges of all text and atomic
* inline-level frames that are clipped by the current marker width
*/
void ExamineFrameSubtree(nsIFrame* aFrame,
const nsRect& aContentArea,
const nsRect& aInsideMarkersArea,
FrameHashtable* aFramesToHide,
AlignmentEdges* aAlignmentEdges,
bool* aFoundVisibleTextOrAtomic);
bool* aFoundVisibleTextOrAtomic,
InnerClipEdges* aClippedMarkerEdges);
/**
* ExamineFrameSubtree calls this to analyze a frame against the hypothetical
@ -146,13 +173,16 @@ class TextOverflow {
* inside aInsideMarkersArea
* @param aFoundVisibleTextOrAtomic is set to true if a text or atomic
* inline-level frame is visible between the marker edges
* @param aClippedMarkerEdges the innermost edges of all text and atomic
* inline-level frames that are clipped by the current marker width
*/
void AnalyzeMarkerEdges(nsIFrame* aFrame,
const nsIAtom* aFrameType,
const nsRect& aInsideMarkersArea,
FrameHashtable* aFramesToHide,
AlignmentEdges* aAlignmentEdges,
bool* aFoundVisibleTextOrAtomic);
bool* aFoundVisibleTextOrAtomic,
InnerClipEdges* aClippedMarkerEdges);
/**
* Clip or remove items given the final marker edges. ("clip" here just means
@ -205,8 +235,10 @@ class TextOverflow {
mHasOverflow = false;
}
// The intrinsic width of the marker string.
// The current width of the marker, the range is [0 .. mIntrinsicWidth].
nscoord mWidth;
// The intrinsic width of the marker string.
nscoord mIntrinsicWidth;
// The marker text.
nsString mMarkerString;
// The style for this side.
@ -215,7 +247,8 @@ class TextOverflow {
bool mHasOverflow;
// True if mMarkerString and mWidth have been setup from style.
bool mInitialized;
// True if the style is text-overflow:clip on this side.
// True if the style is text-overflow:clip on this side and the marker
// won't cause the line to become empty.
bool mActive;
};

Просмотреть файл

@ -0,0 +1,85 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/licenses/publicdomain/
Test: text-overflow with overflow where introducing a marker would cause
the line to have no visible text or atomic inline-level content --
then we should either suppress or clip the marker
-->
<html><head>
<title>text-overflow: suppress or clip the marker when it hides all content</title>
<style type="text/css">
@font-face {
font-family: DejaVuSansMono;
src: url(../fonts/DejaVuSansMono.woff),url(DejaVuSansMono.woff);
}
html,body {
color:black; background-color:white; font-size:16px; padding:0; margin:0; font-family:DejaVuSansMono;
}
.test {
overflow:hidden;
width:100px;
white-space:nowrap;
margin:0 100px;
}
span {
width:97px;
display:inline-block;
}
s {
width:3px;
height:10px;
margin-left:-2px;
display:inline-block;
background:blue;
}
.rlo {
unicode-bidi: bidi-override; direction:rtl;
}
.lro {
unicode-bidi: bidi-override;
}
.rtl {
direction:rtl;
}
.ltr {
direction:ltr;
}
.t1 { }
.t2 { }
.t3 { margin-left:98px; padding-left:3px; }
i {
display:inline-block;
width:2px;
height:10px;
background:blue;
}
</style>
</head><body>
<div style="float:left;">
<div class="test t1"><span>!</span>&#x2026;</div> <!-- atomic under marker -->
<div class="test t1"><span>!</span>&#x2026;</div> <!-- atomic in padding -->
<div class="test t1"><span>!</span>&#x2026;</div> <!-- atomic under marker and in padding -->
<div class="test t2"><span>!</span>&#x2026;</div> <!-- atomic under marker -->
<div class="test t2"><span>!</span>&#x2026;</div> <!-- atomic in padding -->
<div class="test t2"><span>!</span>&#x2026;</div> <!-- atomic under marker and in padding -->
<div class="test rtl t1"><span>!</span>&#x2026;</div> <!-- atomic under marker -->
<div class="test rtl t1"><span>!</span>&#x2026;</div> <!-- atomic in padding -->
<div class="test rtl t1"><span>!</span>&#x2026;</div> <!-- atomic under marker and in padding -->
<div class="test t2"><x style="margin-left:3px">.|</style></div> <!-- atomic under marker -->
<div class="test t3">g<i></i></div> <!-- atomic in padding -->
<div class="test t2"><s style="margin-left:1px;"></s><i style="width:17px"></i></div> <!-- atomic under marker and in padding -->
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,85 @@
<!DOCTYPE HTML>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/licenses/publicdomain/
Test: text-overflow with overflow where introducing a marker would cause
the line to have no visible text or atomic inline-level content --
then we should either suppress or clip the marker
-->
<html><head>
<title>text-overflow: suppress or clip the marker when it hides all content</title>
<style type="text/css">
@font-face {
font-family: DejaVuSansMono;
src: url(../fonts/DejaVuSansMono.woff),url(DejaVuSansMono.woff);
}
html,body {
color:black; background-color:white; font-size:16px; padding:0; margin:0; font-family:DejaVuSansMono;
}
.test {
overflow:hidden;
width:100px;
white-space:nowrap;
padding:0 100px;
}
span {
width:97px;
display:inline-block;
}
s {
width:3px;
height:10px;
margin-left:-2px;
display:inline-block;
background:blue;
}
.rlo {
unicode-bidi: bidi-override; direction:rtl;
}
.lro {
unicode-bidi: bidi-override;
}
.rtl {
direction:rtl;
}
.ltr {
direction:ltr;
}
.t1 { text-overflow:ellipsis; }
.t2 { text-overflow:"." ellipsis; }
.t3 { text-overflow:"long" ellipsis; }
i {
display:inline-block;
width:2px;
height:10px;
background:blue;
}
</style>
</head><body>
<div style="float:left;">
<div class="test t1"><span>!</span><i></i>||</div> <!-- atomic under marker -->
<div class="test t1"><span>!</span>||<i></i></div> <!-- atomic in padding -->
<div class="test t1"><span>!</span><i style="width:20px"></i></div> <!-- atomic under marker and in padding -->
<div class="test t2"><span>!</span><i></i>||</div> <!-- atomic under marker -->
<div class="test t2"><span>!</span>||<i></i></div> <!-- atomic in padding -->
<div class="test t2"><span>!</span><i style="width:20px"></i></div> <!-- atomic under marker and in padding -->
<div class="test rtl t1"><span>!</span><i></i>||</div> <!-- atomic under marker -->
<div class="test rtl t1"><span>!</span>||<i></i></div> <!-- atomic in padding -->
<div class="test rtl t1"><span>!</span><i style="width:20px"></i></div> <!-- atomic under marker and in padding -->
<div class="test t2"><s></s><i></i>||</div> <!-- atomic under marker -->
<div class="test t3"><s></s>|<i></i></div> <!-- atomic in padding -->
<div class="test t2"><s></s><i style="width:20px"></i></div> <!-- atomic under marker and in padding -->
</div>
</body>
</html>

Просмотреть файл

@ -25,32 +25,32 @@ select[size="4"],iframe,textarea,hr { height:10px; margin:0; }
<body>
<div style="position:absolute; top:0; left:0;">
<div class="test">&#x2026;</div>
<div class="test">&#x2026;</div>
<div class="test"><fieldset style="display:inline;"></fieldset></div>
<div class="test"><fieldset style="display:inline-block;"></fieldset></div>
<div class="test"><fieldset style="display:block;"></fieldset></div>
<div class="test">&#x2026;</div>
<div class="test">&#x2026;</div>
<div class="test"><input type="button"></div>
<div class="test"><input type="button" style="display:inline-block;"></div>
<div class="test"><input type="button" style="display:list-item;"></div>
<div class="test"><input type="button" style="display:block;"></div>
<div class="test">&#x2026;</div>
<div class="test">&#x2026;</div>
<div class="test"><input type="text"></div>
<div class="test"><input type="text" style="display:inline-block;"></div>
<div class="test"><input type="text" style="display:block;"></div>
<div class="test">&#x2026;</div>
<div class="test">&#x2026;</div>
<div class="test"><textarea></textarea></div>
<div class="test"><textarea style="display:inline-block;"></textarea></div>
<div class="test"><textarea style="display:block;"></textarea></div>
<div class="test">&#x2026;</div>
<div class="test"><select size="1" style=""><option>&nbsp;<option>&nbsp;</select></div>
<div class="test"><select size="1" style="display:block;"><option>&nbsp;<option>&nbsp;</select></div>
<div class="test">&#x2026;</div>
<div class="test"><select size="4" style=""><option>&nbsp;<option>&nbsp;</select></div>
<div class="test"><select size="4" style="display:block;"><option>&nbsp;<option>&nbsp;</select></div>
</div>
<div style="position:absolute; top:0; left:100px;">
<div class="test">&#x2026;</div>
<div class="test"><iframe src="about:blank" style=""></iframe></div>
<div class="test"><iframe src="about:blank" style="display:block"></iframe></div>
<div class="test" style="text-align:left">&nbsp;&#x2026;</div>
@ -58,12 +58,12 @@ select[size="4"],iframe,textarea,hr { height:10px; margin:0; }
<div class="test"><img style="display:block;" src="../image/big.png"></div>
<div class="test"><x style="display:inline-block; height:100px; width:100%; background:lime">&#x2026;</x></div>
<div class="test">&#x2026;</div>
<div class="test"><hr style="display:inline-block;vertical-align:top"></div>
<div class="test"><hr style="display:block;"></div>
<div class="test">&#x2026;</div>
<div class="test">&#x2026;</div>
<div class="test">&#x2026;</div>
<div class="test"><span style="display:inline-block;"></span></div>
<div class="test"></div>
<div class="test"><span style="display:list-item;"></span></div>
<div class="test"><span style="display:block;"></span></div>
<div class="test rel">1<span style="position:relative;"></span></div>

Просмотреть файл

@ -132,16 +132,16 @@ m {
<div id="test3d"><div class="s3 rtl"><div class="p o"><span class="c rlo">&nbsp;X<m>...</m></span></div></div></div>
<!-- start + end marker, no characters fit, marker is clipped -->
<div id="test6a"><div class="s6 ltr"><div class="p o"><span class=" lro"><m>...</m></span></div></div></div>
<div id="test6b"><div class="s6 ltr"><div class="p o"><span class=" lro"><m>...</m></span></div></div></div>
<div id="test6c"><div class="s6 ltr"><div class="p o"><span class=" lro"><m>...</m></span></div></div></div>
<div id="test6d"><div class="s6 ltr"><div class="p o"><span class=" lro"><m>...</m></span></div></div></div>
<div id="test6a"><div class="s6 ltr"><div class="p o"><span class="c lro">XXXXXXXXXXXX</span></div></div></div>
<div id="test6b"><div class="s6 rtl"><div class="p o"><span class="c lro">XXXXXXXXXXXX</span></div></div></div>
<div id="test6c"><div class="s6 ltr"><div class="p o"><span class="c rlo">XXXXXXXXXXXX</span></div></div></div>
<div id="test6d"><div class="s6 rtl"><div class="p o"><span class="c rlo">XXXXXXXXXXXX</span></div></div></div>
<!-- start marker, all characters overlapped by marker -->
<div id="test7a"><div class="s7 ltr"><div class="p o"><span class=" lro"><m>...</m>&nbsp;</span></div></div></div>
<div id="test7b"><div class="s7 rtl"><div class="p o"><span class=" lro">&nbsp;<m>...</m></span></div></div></div>
<div id="test7c"><div class="s7 ltr"><div class="p o"><span class=" rlo">&nbsp;<m>...</m></span></div></div></div>
<div id="test7d"><div class="s7 rtl"><div class="p o"><span class=" rlo"><m>...</m>&nbsp;</span></div></div></div>
<div id="test7a"><div class="s7 ltr"><div class="p o"><span class="c lro">XXX</span></div></div></div>
<div id="test7b"><div class="s7 rtl"><div class="p o"><span class="c lro">XXX</span></div></div></div>
<div id="test7c"><div class="s7 ltr"><div class="p o"><span class="c rlo">XXX</span></div></div></div>
<div id="test7d"><div class="s7 rtl"><div class="p o"><span class="c rlo">XXX</span></div></div></div>
</div>

Просмотреть файл

@ -209,51 +209,17 @@ x1 m { position:absolute; right:0; font-size:16px; }
</div></div>
</div>
<div id="test4a">
<div class="s a"><div class="p rel">
<div class="abs0" style="text-align:left"><m>&#x2026;</m><span class="cl a">&nbsp;</span></div>
</div></div>
</div>
<div id="test4b">
<div class="s a"><div class="p rel">
<div class="abs0" style="text-align:left"><m>&#x2026;</m><span class="cl a">&nbsp;</span></div>
</div></div>
</div>
<div id="test4c">
<div class="s a"><div class="p rel">
<div class="abs0" style="text-align:right; left:auto; right:0;"><span class="cr a">&nbsp;&nbsp;&nbsp;</span><m>&#x2026;</m></div>
</div></div>
</div>
<div id="test4d">
<div class="s a"><div class="p rel">
<div class="abs0" style="text-align:right; left:auto; right:0;"><span class="cr a">&nbsp;&nbsp;&nbsp;</span><m>&#x2026;</m></div>
</div></div>
</div>
<!-- start marker, marker partly overlaps image, nothing to align with -->
<div id="test4a"><div class="s a"><div class="p o ltr"><span class="cl a"><img class="overlap1" src="../image/big.png"></span></div></div></div>
<div id="test4b"><div class="s a"><div class="p o rtl l"><span class="cl a"><img class="overlap1" src="../image/big.png"></span></div></div></div>
<div id="test4c"><div class="s a"><div class="p o ltr r"><span class="cr a"><img class="overlap1" src="../image/big.png"></span></div></div></div>
<div id="test4d"><div class="s a"><div class="p o rtl"><span class="cr a"><img class="overlap1" src="../image/big.png"></span></div></div></div>
<div id="test5a">
<div class="s a"><div class="p rel">
<div class="abs0" style="text-align:right; left:auto; right:0;"><span class="cr a">&nbsp;</span><m>&#x2026;</m></div>
<div class="abs0" style="text-align:left"><m>&#x2026;</m><span class="cl a">&nbsp;</span></div>
</div></div>
</div>
<div id="test5b">
<div class="s a"><div class="p rel">
<div class="abs0" style="text-align:right; left:auto; right:0;"><span class="cr a">&nbsp;</span><m>&#x2026;</m></div>
<div class="abs0" style="text-align:left"><m>&#x2026;</m><span class="cl a">&nbsp;</span></div>
</div></div>
</div>
<div id="test5c">
<div class="s a"><div class="p rel">
<div class="abs0" style="text-align:right; left:auto; right:0;"><span class="cr a">&nbsp;</span><m>&#x2026;</m></div>
<div class="abs0" style="text-align:left"><m>&#x2026;</m><span class="cl a">&nbsp;</span></div>
</div></div>
</div>
<div id="test5d">
<div class="s a"><div class="p rel">
<div class="abs0" style="text-align:right; left:auto; right:0;"><span class="cr a">&nbsp;</span><m>&#x2026;</m></div>
<div class="abs0" style="text-align:left"><m>&#x2026;</m><span class="cl a">&nbsp;</span></div>
</div></div>
</div>
<!-- start marker + end, marker partly overlaps image, nothing to align with -->
<div id="test5a"><div class="s a"><div class="p o ltr"><span class="cl a"><img class="overlap2" src="../image/big.png"></span></div></div></div>
<div id="test5b"><div class="s a"><div class="p o rtl l"><span class="cl a"><img class="overlap2" src="../image/big.png"></span></div></div></div>
<div id="test5c"><div class="s a"><div class="p o ltr r"><span class="cr a"><img class="overlap2" src="../image/big.png"></span></div></div></div>
<div id="test5d"><div class="s a"><div class="p o rtl"><span class="cr a"><img class="overlap2" src="../image/big.png"></span></div></div></div>
<div id="test6a">
<div class="s a"><div class="p rel">

Просмотреть файл

@ -24,6 +24,9 @@ html,body {
margin-left:2em;
position:relative;
}
span {
margin: 0 -0.5ch;
}
m {
margin: 0;
position:relative;
@ -54,11 +57,11 @@ mr {
<div class="test t1"><m>&nbsp;x</m></div>
<div class="test rtl t1"><m>&nbsp;x</m></div>
<div class="test t2"><m>Hello World</m></div>
<div class="test rtl t2"><m>Hello World</m></div>
<div class="test t2"><span>xx</span></div>
<div class="test rtl t2"><span>xx</span></div>
<div class="test t2" style="width:3ch"><m>Hel</m></div>
<div class="test rtl t2" style="width:3ch"><m>Hel</m></div>
<div class="test t2" style="width:3ch"><span>xx</span></div>
<div class="test rtl t2" style="width:3ch"><span>xx</span></div>
<div class="test"><m>X</m><mr>X</mr></div>
<div class="test"><m>X</m><mr>X</mr></div>

Просмотреть файл

@ -64,9 +64,9 @@ m { font-size:20px; color:blue; }
<div class="test t1"><span><span class="xspan">0123&nbsp;56789012</span><m>&#x2026;</m></span></div>
<div class="test rtl t1"><span><span class="xspan">1&nbsp;56789012345</span><m>&#x2026;</m></span></div>
<div class="test rtl t2"><span><m>&#x2026;</m><span style="visibility:hidden">&nbsp;</span></span></div>
<div class="test rtl t3"><span><m>&#x2026;</m><span style="visibility:hidden">&nbsp;</span></span></div>
<div class="test t4"><span><m>&#x2026;</m><span style="visibility:hidden">&nbsp;</span></span></div>
<div class="test t2"><span class="xspan">xxxx<m>x</m></span></div>
<div class="test t3"><span class="xspan">x<m>x</m></span></div>
<div class="test t4"><span class="xspan">x<m>x</m></span></div>
</body>

Просмотреть файл

@ -16,7 +16,8 @@ HTTP(..) == selection.html selection-ref.html
HTTP(..) == marker-shadow.html marker-shadow-ref.html
== aligned-baseline.html aligned-baseline-ref.html
skip-if(Android) == clipped-elements.html clipped-elements-ref.html
== theme-overflow.html theme-overflow-ref.html
HTTP(..) == theme-overflow.html theme-overflow-ref.html
HTTP(..) == table-cell.html table-cell-ref.html
HTTP(..) == two-value-syntax.html two-value-syntax-ref.html
HTTP(..) == single-value.html single-value-ref.html
HTTP(..) == atomic-under-marker.html atomic-under-marker-ref.html

Просмотреть файл

@ -63,9 +63,9 @@ m { font-size:20px; color:blue; }
<div class="test t1"><span><span class="xspan">0123&nbsp;56789012</span><m>&#x2026;</m></span></div>
<div class="test rtl t1"><span><span class="xspan">1&nbsp;56789012345</span><m>&#x2026;</m></span></div>
<div class="test rtl t2" style="color:black">&#x2026;&nbsp;</div>
<div class="test rtl t3"><span><m>&#x2026;</m><span style="visibility:hidden">&nbsp;</span></span></div>
<div class="test t4"><span><m>&#x2026;</m><span style="visibility:hidden">&nbsp;</span></span></div>
<div class="test t2" style="color:black"><span class="xspan">xxxx</span></div>
<div class="test t3"><span class="xspan">x</span></div>
<div class="test t4"><span class="xspan">x</span></div>
</body>

Просмотреть файл

@ -17,7 +17,7 @@
.x1 { margin:1px;}
.x2 { margin:2px;}
.x3 { margin:3px;}
.x4 { margin-left:-1px; visibility:hidden;}
.x4 { margin-left:-1px; }
.r .x4 { margin-right:-1px;}
f { float:left; width:1px; height:1px; margin-left:-100px; }
@ -30,7 +30,7 @@ f { float:left; width:1px; height:1px; margin-left:-100px; }
<input type="checkbox" class="x1"> 1<f></f><br>
<input type="checkbox" class="x2"> 2<f></f><br>
<input type="checkbox" class="x3"> 3<f></f><br>
&#x2026;<input type="checkbox" class="x4"><f></f><br>
<input type="checkbox" class="x4"><f></f><br>
</p>
<p>
@ -38,7 +38,7 @@ f { float:left; width:1px; height:1px; margin-left:-100px; }
<input type="radio" class="x1"> 1<f></f><br>
<input type="radio" class="x2"> 2<f></f><br>
<input type="radio" class="x3"> 3<f></f><br>
&#x2026;<input type="radio" class="x4"><f></f><br>
<input type="radio" class="x4"><f></f><br>
</p>
<p class="r">
@ -46,7 +46,7 @@ f { float:left; width:1px; height:1px; margin-left:-100px; }
<input type="checkbox" class="x1"> 1<f></f><br>
<input type="checkbox" class="x2"> 2<f></f><br>
<input type="checkbox" class="x3"> 3<f></f><br>
&#x2026;<input type="radio" class="x4"><f></f><br>
<input type="checkbox" class="x4"><f></f><br>
</p>
<p class="r">
@ -54,7 +54,7 @@ f { float:left; width:1px; height:1px; margin-left:-100px; }
<input type="radio" class="x1"> 1<f></f><br>
<input type="radio" class="x2"> 2<f></f><br>
<input type="radio" class="x3"> 3<f></f><br>
&#x2026;<input type="radio" class="x4"><f></f><br>
<input type="radio" class="x4"><f></f><br>
</p>
</body>