⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 244036 in webkit


Ignore:
Timestamp:
Apr 8, 2019, 1:31:05 PM (7 years ago)
Author:
jfernandez@igalia.com
Message:

Implement white-space:break-spaces value
https://bugs.webkit.org/show_bug.cgi?id=177327

Reviewed by Myles Maxfield and Zalan Bujtas.

LayoutTests/imported/w3c:

Imoprted a few aditional tests from the CSS Text WPT suite that are relevant for this change.

  • web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-008-expected.html: Added.
  • web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-008.html: Added.
  • web-platform-tests/css/css-text/overflow-wrap/w3c-import.log:
  • web-platform-tests/css/css-text/parsing/white-space-valid-expected.txt:
  • web-platform-tests/css/css-text/white-space/break-spaces-003-expected.html: Added.
  • web-platform-tests/css/css-text/white-space/break-spaces-003.html: Added.
  • web-platform-tests/css/css-text/white-space/break-spaces-009-expected.html: Added.
  • web-platform-tests/css/css-text/white-space/break-spaces-009.html: Added.
  • web-platform-tests/css/css-text/white-space/w3c-import.log:

Source/WebCore:

Finally the CSS WG decided [1] to move back the 'break-spaces' value to
the 'white-space' property. This makes the parsing logic easier than
the previous approach of using the 'overflow-wrap' property.

This new value prevents the white-space sequence to collapse and gives
breaking opportunities after every preserved white-space.

https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces

Additionally, unlike 'pre-wrap', non-collapsible spaces or tabs at the
end of a line cannot be hung or visually collapsed, since we want them
to be preserved and broken.

[1] https://github.com/w3c/csswg-drafts/pull/2841

Tests: imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-008.html

imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-003.html
imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-009.html

  • css/CSSPrimitiveValueMappings.h:

(WebCore::CSSPrimitiveValue::CSSPrimitiveValue): New mapping for CSSVaueBreakSpaces.
(WebCore::CSSPrimitiveValue::operator WhiteSpace const): New value BreakSpaces for the Whitespace enum.

  • css/CSSProperties.json: new 'break-spaces' value for the 'white-space' property.
  • css/CSSValueKeywords.in: new break-spaces keyword
  • css/parser/CSSParserFastPaths.cpp:

(WebCore::CSSParserFastPaths::isValidKeywordPropertyAndValue):

  • rendering/SimpleLineLayout.cpp: The SimpleLineLayut codepath must handle properly the new behavior of preserved whitespaces.

(WebCore::SimpleLineLayout::LineState::hasTrailingWhitespace const): Require that m_trailingWhitespaceWidth being greater than zero.
(WebCore::SimpleLineLayout::LineState::hasWhitespaceFragments const): New function to detect former whitespae fragments that could be breaking opportunities.
(WebCore::SimpleLineLayout::removeTrailingWhitespace): The 'break-spaces' feature forbids to remove any trailing whitespace.
(WebCore::SimpleLineLayout::firstFragment): We have now leading whitespace sequences comming from the previous line.
(WebCore::SimpleLineLayout::createLineRuns): We should revert some breaking opportunities if others were formerly found in the line.

  • rendering/SimpleLineLayoutTextFragmentIterator.cpp:

(WebCore::SimpleLineLayout::TextFragmentIterator::Style::Style): New style fields to determine whether the break-space feature is being used. Also split out the break-all and breal-all values.

  • rendering/SimpleLineLayoutTextFragmentIterator.h:
  • rendering/line/BreakingContext.h: Different codepath but similar changes to properly handle the new behavior of preserved whitespace.

(WebCore::BreakingContext::BreakingContext): New class field to determine whether there are some whitespace that may prevent the word ot be broken.
(WebCore::BreakingContext::handleText): New line-breaking logic to implement the break-spaces behavior.
(WebCore::BreakingContext::trailingSpacesHang): Cases where the preserved breakspaces should hand or overflow.

  • rendering/style/RenderStyle.h:

(WebCore::RenderStyle::collapseWhiteSpace): With break-spaces collapsing whitespaces is not allowed.
(WebCore::RenderStyle::breakOnlyAfterWhiteSpace const): Add the WhiteSpace::BreakSpaces to this group.

  • rendering/style/RenderStyleConstants.h: A new constan added.

LayoutTests:

Removed many failure expectations of tests that pass now thanks to this change.

The overflow-wrap-break-word-003.html tests fails in mac and iOS platforms due to an issue related to
how we compute widths using 'ch' units and 'monospace' fonts. I filed bug #196169 to report the specific
case of this test (break-word+pre-wrap) but the root cause it's probably the bug #196353.

I have submitted a PR [1] to the Web Platform Tests to change several tests that failed only if the
monospace font is used, but pass with the Ahem font. Additionally, I've requested another PR [2] to
add new layout tests, with the same case than overflow-wrap-break-word-003.html but using the Ahem
font.

[1] https://github.com/web-platform-tests/wpt/pull/16137
[2] https://github.com/web-platform-tests/wpt/pull/16124

  • TestExpectations: Removed many Failure entries on tests that pass now thanks to this change.
  • platform/mac/TestExpectations: Added one Failure entry and filed the corresponding bug report.
Location:
trunk
Files:
6 added
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r244031 r244036  
     12019-04-08  Javier Fernandez  <jfernandez@igalia.com>
     2
     3        Implement white-space:break-spaces value
     4        https://bugs.webkit.org/show_bug.cgi?id=177327
     5
     6        Reviewed by Myles Maxfield and Zalan Bujtas.
     7
     8        Removed many failure expectations of tests that pass now thanks to this change.
     9
     10        The overflow-wrap-break-word-003.html tests fails in mac and iOS platforms due to an issue related to
     11        how we compute widths using 'ch' units and 'monospace' fonts. I filed bug #196169 to report the specific
     12        case of this test (break-word+pre-wrap) but the root cause it's probably the bug #196353.
     13
     14        I have submitted a PR [1] to the Web Platform Tests to change several tests that failed only if the
     15        monospace font is used, but pass with the Ahem font. Additionally, I've requested another PR [2] to
     16        add new layout tests, with the same case than overflow-wrap-break-word-003.html but using the Ahem
     17        font.
     18
     19        [1] https://github.com/web-platform-tests/wpt/pull/16137
     20        [2] https://github.com/web-platform-tests/wpt/pull/16124
     21
     22        * TestExpectations: Removed many Failure entries on tests that pass now thanks to this change.
     23        * platform/mac/TestExpectations: Added one Failure entry and filed the corresponding bug report.
     24
    1252019-04-08  Antoine Quint  <graouts@apple.com>
    226
  • trunk/LayoutTests/TestExpectations

    r243910 r244036  
    18101810webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/line-breaking/line-breaking-ic-002.html [ ImageOnlyFailure ]
    18111811webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/line-breaking/line-breaking-ic-003.html [ ImageOnlyFailure ]
    1812 webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-002.html [ ImageOnlyFailure ]
    1813 webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-003.html [ ImageOnlyFailure ]
    18141812webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/tab-size/tab-size-length-001.html [ ImageOnlyFailure ]
    18151813webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/tab-size/tab-size-length-002.html [ ImageOnlyFailure ]
     
    19081906webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/line-break/line-break-loose-014.xht [ ImageOnlyFailure ]
    19091907webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/line-break/line-break-loose-015.xht [ ImageOnlyFailure ]
    1910 webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-006.html [ ImageOnlyFailure ]
    19111908webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/tab-size/tab-size-spacing-001.html [ ImageOnlyFailure ]
    19121909webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/tab-size/tab-min-rendered-width-1.html [ ImageOnlyFailure ]
     
    19271924webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/white-space-intrinsic-size-004.html [ ImageOnlyFailure ]
    19281925webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/text-space-collapse-discard-001.xht [ ImageOnlyFailure ]
    1929 webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-008.html [ ImageOnlyFailure ]
    19301926webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/tab-stop-threshold-004.html [ ImageOnlyFailure ]
    1931 webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/white-space-intrinsic-size-002.html [ ImageOnlyFailure ]
    19321927webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/control-chars-000.html [ ImageOnlyFailure ]
    19331928webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/white-space-intrinsic-size-001.html [ ImageOnlyFailure ]
     
    19351930webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/trailing-ideographic-space-002.html [ ImageOnlyFailure ]
    19361931webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/tab-stop-threshold-002.html [ ImageOnlyFailure ]
    1937 webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-001.html [ ImageOnlyFailure ]
    19381932webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/line-edge-white-space-collapse-001.html [ ImageOnlyFailure ]
    1939 webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-005.html [ ImageOnlyFailure ]
    1940 webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/tab-stop-threshold-005.html [ ImageOnlyFailure ]
    1941 webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/textarea-break-spaces-001.html [ ImageOnlyFailure ]
    19421933webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/trailing-ideographic-space-003.html [ ImageOnlyFailure ]
    19431934webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-002.html [ ImageOnlyFailure ]
    19441935webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/pre-wrap-014.html [ ImageOnlyFailure ]
    1945 webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-007.html [ ImageOnlyFailure ]
    19461936webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/text-space-trim-trim-inner-001.xht [ ImageOnlyFailure ]
    19471937webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/trailing-ideographic-space-004.html [ ImageOnlyFailure ]
     
    19501940webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/text-space-collapse-preserve-breaks-001.xht [ ImageOnlyFailure ]
    19511941webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/line-edge-white-space-collapse-002.html [ ImageOnlyFailure ]
    1952 webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-004.html [ ImageOnlyFailure ]
    1953 webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-006.html [ ImageOnlyFailure ]
    19541942webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/word-break/word-break-break-all-020.html [ ImageOnlyFailure ]
    1955 webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/word-break/word-break-break-all-012.html [ ImageOnlyFailure ]
    19561943webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/word-break/word-break-keep-all-006.html [ ImageOnlyFailure ]
    19571944webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/word-break/word-break-keep-all-005.html [ ImageOnlyFailure ]
    1958 webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/word-break/word-break-break-all-013.html [ ImageOnlyFailure ]
    19591945webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/writing-system/writing-system-segment-break-001.html [ ImageOnlyFailure ]
    19601946webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/writing-system/writing-system-line-break-002.html [ ImageOnlyFailure ]
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r243933 r244036  
     12019-04-08  Javier Fernandez  <jfernandez@igalia.com>
     2
     3        Implement white-space:break-spaces value
     4        https://bugs.webkit.org/show_bug.cgi?id=177327
     5
     6        Reviewed by Myles Maxfield and Zalan Bujtas.
     7
     8        Imoprted a few aditional tests from the CSS Text WPT suite that are relevant for this change.
     9
     10        * web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-008-expected.html: Added.
     11        * web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-008.html: Added.
     12        * web-platform-tests/css/css-text/overflow-wrap/w3c-import.log:
     13        * web-platform-tests/css/css-text/parsing/white-space-valid-expected.txt:
     14        * web-platform-tests/css/css-text/white-space/break-spaces-003-expected.html: Added.
     15        * web-platform-tests/css/css-text/white-space/break-spaces-003.html: Added.
     16        * web-platform-tests/css/css-text/white-space/break-spaces-009-expected.html: Added.
     17        * web-platform-tests/css/css-text/white-space/break-spaces-009.html: Added.
     18        * web-platform-tests/css/css-text/white-space/w3c-import.log:
     19
    1202019-04-05  Caitlin Potter  <caitp@igalia.com>
    221
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-text/overflow-wrap/w3c-import.log

    r243437 r244036  
    5050/LayoutTests/imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-007-expected.html
    5151/LayoutTests/imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-007.html
     52/LayoutTests/imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-008-expected.html
     53/LayoutTests/imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-008.html
    5254/LayoutTests/imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-fit-content-001-expected.html
    5355/LayoutTests/imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-fit-content-001.html
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-text/parsing/white-space-valid-expected.txt

    r242550 r244036  
    44PASS e.style['white-space'] = "nowrap" should set the property value
    55PASS e.style['white-space'] = "pre-wrap" should set the property value
    6 FAIL e.style['white-space'] = "break-spaces" should set the property value assert_not_equals: property should be set got disallowed value ""
     6PASS e.style['white-space'] = "break-spaces" should set the property value
    77PASS e.style['white-space'] = "pre-line" should set the property value
    88
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/textarea-break-spaces-001-expected.html

    r242550 r244036  
    1515  margin: 0;
    1616  padding: 0;
     17  border-radius: 0px;
    1718  border: none;
    1819  outline: none;
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/w3c-import.log

    r243437 r244036  
    2929/LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-008-expected.html
    3030/LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-008.html
     31/LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-009-expected.html
     32/LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-009.html
    3133/LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/control-chars-000-expected.html
    3234/LayoutTests/imported/w3c/web-platform-tests/css/css-text/white-space/control-chars-000.html
  • trunk/LayoutTests/platform/ios/TestExpectations

    r243763 r244036  
    30673067webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/i18n/css3-text-line-break-opclns-116.html [ ImageOnlyFailure ]
    30683068webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/word-break/word-break-break-all-006.html [ ImageOnlyFailure ]
     3069webkit.org/b/196169 imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-003.html [ ImageOnlyFailure ]
    30693070
    30703071# unsupported
  • trunk/LayoutTests/platform/mac/TestExpectations

    r243871 r244036  
    16871687webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/i18n/css3-text-line-break-opclns-116.html [ ImageOnlyFailure ]
    16881688webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/word-break/word-break-break-all-006.html [ ImageOnlyFailure ]
     1689webkit.org/b/196169 imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-003.html [ ImageOnlyFailure ]
    16891690
    16901691# Color Well is turned off
  • trunk/Source/WebCore/ChangeLog

    r244034 r244036  
     12019-04-08  Javier Fernandez  <jfernandez@igalia.com>
     2
     3        Implement white-space:break-spaces value
     4        https://bugs.webkit.org/show_bug.cgi?id=177327
     5
     6        Reviewed by Myles Maxfield and Zalan Bujtas.
     7
     8        Finally the CSS WG decided [1] to move back the 'break-spaces' value to
     9        the 'white-space' property. This makes the parsing logic easier than
     10        the previous approach of using the 'overflow-wrap' property.
     11
     12        This new value prevents the white-space sequence to collapse and gives
     13        breaking opportunities after every preserved white-space.
     14
     15        https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces
     16
     17        Additionally, unlike 'pre-wrap', non-collapsible spaces or tabs at the
     18        end of a line cannot be hung or visually collapsed, since we want them
     19        to be preserved and broken.
     20
     21        [1] https://github.com/w3c/csswg-drafts/pull/2841
     22
     23        Tests: imported/w3c/web-platform-tests/css/css-text/overflow-wrap/overflow-wrap-break-word-008.html
     24               imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-003.html
     25               imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-009.html
     26
     27        * css/CSSPrimitiveValueMappings.h:
     28        (WebCore::CSSPrimitiveValue::CSSPrimitiveValue): New mapping for CSSVaueBreakSpaces.
     29        (WebCore::CSSPrimitiveValue::operator WhiteSpace const): New value BreakSpaces for the Whitespace enum.
     30        * css/CSSProperties.json: new 'break-spaces' value for the 'white-space' property.
     31        * css/CSSValueKeywords.in: new break-spaces keyword
     32        * css/parser/CSSParserFastPaths.cpp:
     33        (WebCore::CSSParserFastPaths::isValidKeywordPropertyAndValue):
     34        * rendering/SimpleLineLayout.cpp:  The SimpleLineLayut codepath must handle properly the new behavior of preserved whitespaces.
     35        (WebCore::SimpleLineLayout::LineState::hasTrailingWhitespace const): Require that m_trailingWhitespaceWidth being greater than zero.
     36        (WebCore::SimpleLineLayout::LineState::hasWhitespaceFragments const): New function to detect former whitespae fragments that could be breaking opportunities.
     37        (WebCore::SimpleLineLayout::removeTrailingWhitespace): The 'break-spaces' feature forbids to remove any trailing whitespace.
     38        (WebCore::SimpleLineLayout::firstFragment): We have now leading whitespace sequences comming from the previous line.
     39        (WebCore::SimpleLineLayout::createLineRuns): We should revert some breaking opportunities if others were formerly found in the line.
     40        * rendering/SimpleLineLayoutTextFragmentIterator.cpp:
     41        (WebCore::SimpleLineLayout::TextFragmentIterator::Style::Style): New style fields to determine whether the break-space feature is being used. Also split out the break-all and breal-all values.
     42        * rendering/SimpleLineLayoutTextFragmentIterator.h:
     43        * rendering/line/BreakingContext.h: Different codepath but similar changes to properly handle the new behavior of preserved whitespace.
     44        (WebCore::BreakingContext::BreakingContext): New class field to determine whether there are some whitespace that may prevent the word ot be broken.
     45        (WebCore::BreakingContext::handleText): New line-breaking logic to implement the break-spaces behavior.
     46        (WebCore::BreakingContext::trailingSpacesHang): Cases where the preserved breakspaces should hand or overflow.
     47        * rendering/style/RenderStyle.h:
     48        (WebCore::RenderStyle::collapseWhiteSpace): With break-spaces collapsing whitespaces is not allowed.
     49        (WebCore::RenderStyle::breakOnlyAfterWhiteSpace const): Add the WhiteSpace::BreakSpaces to this group.
     50        * rendering/style/RenderStyleConstants.h: A new constan added.
     51
    1522019-04-08  Youenn Fablet  <youenn@apple.com>
    253
  • trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h

    r243841 r244036  
    30523052        m_value.valueID = CSSValueWebkitNowrap;
    30533053        break;
     3054    case WhiteSpace::BreakSpaces:
     3055        m_value.valueID = CSSValueBreakSpaces;
     3056        break;
    30543057    }
    30553058}
     
    30723075    case CSSValueNormal:
    30733076        return WhiteSpace::Normal;
     3077    case CSSValueBreakSpaces:
     3078        return WhiteSpace::BreakSpaces;
    30743079    default:
    30753080        break;
  • trunk/Source/WebCore/css/CSSProperties.json

    r243841 r244036  
    42704270                "pre-wrap",
    42714271                "pre-line",
    4272                 "nowrap"
     4272                "nowrap",
     4273                "break-spaces"
    42734274            ],
    42744275            "specification": {
  • trunk/Source/WebCore/css/CSSValueKeywords.in

    r243841 r244036  
    770770
    771771//
     772// CSS_PROP_WHITE_SPACE
     773//
     774break-spaces
     775
     776//
    772777// CSS_PROP__KHTML_NBSP_MODE
    773778//
  • trunk/Source/WebCore/css/parser/CSSParserFastPaths.cpp

    r243841 r244036  
    762762            || valueID == CSSValueLrTb || valueID == CSSValueRlTb || valueID == CSSValueTbRl
    763763            || valueID == CSSValueLr || valueID == CSSValueRl || valueID == CSSValueTb;
    764     case CSSPropertyWhiteSpace: // normal | pre | nowrap
    765         return valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap;
     764    case CSSPropertyWhiteSpace: // normal | pre | nowrap | pre-line | nowrap | break-spacess
     765        return valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap || valueID == CSSValueBreakSpaces;
    766766    case CSSPropertyWordBreak: // normal | break-all | keep-all | break-word (this is a custom extension)
    767767        return valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueKeepAll || valueID == CSSValueBreakWord;
  • trunk/Source/WebCore/rendering/SimpleLineLayout.cpp

    r243819 r244036  
    423423    float logicalLeftOffset() const { return m_logicalLeftOffset; }
    424424    const TextFragmentIterator::TextFragment& overflowedFragment() const { return m_overflowedFragment; }
    425     bool hasTrailingWhitespace() const { return m_lastFragment.type() == TextFragmentIterator::TextFragment::Whitespace; }
     425    bool hasTrailingWhitespace() const { return m_lastFragment.type() == TextFragmentIterator::TextFragment::Whitespace && m_lastFragment.length() > 0; }
     426    bool hasWhitespaceFragments() const { return m_lastWhitespaceFragment != WTF::nullopt; }
    426427    TextFragmentIterator::TextFragment lastFragment() const { return m_lastFragment; }
    427428    bool isWhitespaceOnly() const { return m_trailingWhitespaceWidth && m_runsWidth == m_trailingWhitespaceWidth; }
     
    506507            (*m_fragments).append(fragment);
    507508
    508         if (fragment.type() == TextFragmentIterator::TextFragment::Whitespace)
     509        if (fragment.type() == TextFragmentIterator::TextFragment::Whitespace) {
    509510            m_trailingWhitespaceWidth += fragment.width();
    510         else {
     511            m_lastWhitespaceFragment = fragment;
     512        } else {
    511513            m_trailingWhitespaceWidth = 0;
    512514            m_lastNonWhitespaceFragment = fragment;
     
    568570    TextFragmentIterator::TextFragment m_lastFragment;
    569571    Optional<TextFragmentIterator::TextFragment> m_lastNonWhitespaceFragment;
     572    Optional<TextFragmentIterator::TextFragment> m_lastWhitespaceFragment;
    570573    TextFragmentIterator::TextFragment m_lastCompleteFragment;
    571574    float m_uncompletedWidth { 0 };
     
    591594    // would produce an empty line.
    592595    const auto& style = textFragmentIterator.style();
    593     bool collapseWhitespace = style.collapseWhitespace | preWrap(style);
     596    bool collapseWhitespace = style.collapseWhitespace || (!style.breakSpaces && preWrap(style));
    594597    if (!collapseWhitespace)
    595598        return;
     
    748751    // Leading whitespace handling.
    749752    auto& style = textFragmentIterator.style();
     753    if (style.breakSpaces) {
     754        // Leading whitespace created after breaking the previous line.
     755        // Breaking before the first space after a word is only allowed in combination with break-all or break-word.
     756        if (style.breakFirstWordOnOverflow || previousLine.hasTrailingWhitespace())
     757            return overflowedFragment;
     758    }
    750759    // Special overflow pre-wrap whitespace handling: skip the overflowed whitespace (even when style says not-collapsible)
    751760    // if we manage to fit at least one character on the previous line.
     
    811820                    // Push collapased whitespace to the next line.
    812821                    line.setOverflowedFragment(fragment);
     822                    break;
     823                }
     824                if (style.breakSpaces && style.breakWordOnOverflow && line.hasWhitespaceFragments() && fragment.length() == 1) {
     825                    // Breaking before the first space after a word is not allowed if there are previous breaking opportunities in the line.
     826                    textFragmentIterator.revertToEndOfFragment(line.revertToLastCompleteFragment(runs));
    813827                    break;
    814828                }
  • trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp

    r239427 r244036  
    4343    , preserveNewline(style.preserveNewline())
    4444    , wrapLines(style.autoWrap())
     45    , breakSpaces(style.whiteSpace() == WhiteSpace::BreakSpaces)
    4546    , breakAnyWordOnOverflow(style.wordBreak() == WordBreak::BreakAll && wrapLines)
    46     , breakFirstWordOnOverflow(breakAnyWordOnOverflow || (style.breakWords() && (wrapLines || preserveNewline)))
     47    , breakWordOnOverflow(style.breakWords() && (wrapLines || preserveNewline))
     48    , breakFirstWordOnOverflow(breakAnyWordOnOverflow || breakWordOnOverflow)
    4749    , breakNBSP(wrapLines && style.nbspMode() == NBSPMode::Space)
    4850    , keepAllWordsForCJK(style.wordBreak() == WordBreak::KeepAll)
  • trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h

    r239427 r244036  
    112112        bool preserveNewline;
    113113        bool wrapLines;
     114        bool breakSpaces;
    114115        bool breakAnyWordOnOverflow;
     116        bool breakWordOnOverflow;
    115117        bool breakFirstWordOnOverflow;
    116118        bool breakNBSP;
  • trunk/Source/WebCore/rendering/line/BreakingContext.h

    r243819 r244036  
    115115        , m_currentCharacterIsSpace(false)
    116116        , m_currentCharacterIsWS(false)
     117        , m_hasFormerOpportunity(false)
    117118        , m_appliedStartWidth(appliedStartWidth)
    118119        , m_includeEndWidth(true)
     
    147148    void handleReplaced();
    148149    bool handleText(WordMeasurements&, bool& hyphenated, unsigned& consecutiveHyphenatedLines);
     150    void trailingSpacesHang(InlineIterator&, RenderObject&, bool canBreakMidWord, bool previousCharacterIsSpace);
    149151    bool canBreakAtThisPosition();
    150152    void commitAndUpdateLineBreakIfNeeded();
     
    216218    bool m_currentCharacterIsSpace;
    217219    bool m_currentCharacterIsWS;
     220    bool m_hasFormerOpportunity;
    218221    bool m_appliedStartWidth;
    219222    bool m_includeEndWidth;
     
    735738
    736739    HashSet<const Font*> fallbackFonts;
     740    m_hasFormerOpportunity = false;
     741    bool canBreakMidWord = breakWords || breakAll;
    737742    UChar lastCharacterFromPreviousRenderText = m_renderTextInfo.lineBreakIterator.lastCharacter();
    738743    UChar lastCharacter = m_renderTextInfo.lineBreakIterator.lastCharacter();
     
    750755        // A single preserved leading white-space doesn't fulfill the 'betweenWords' condition, however it's indeed a
    751756        // soft-breaking opportunty so we may want to avoid breaking in the middle of the word.
    752         if (m_atStart && m_currentCharacterIsSpace && !previousCharacterIsSpace)
     757        if (m_atStart && m_currentCharacterIsSpace && !previousCharacterIsSpace) {
     758            m_hasFormerOpportunity = canBreakMidWord;
    753759            breakWords = false;
     760            canBreakMidWord = breakAll;
     761        }
    754762
    755763        if (canHangPunctuationAtStart && m_width.isFirstLine() && !m_width.committedWidth() && !wrapW && !inlineLogicalWidth(m_current.renderer(), true, false)) {
     
    775783        m_currentCharacterIsWS = m_currentCharacterIsSpace || (breakNBSP && c == noBreakSpace);
    776784
    777         if ((breakAll || breakWords) && !midWordBreak && (!m_currentCharacterIsSpace || m_atStart || style.whiteSpace() != WhiteSpace::PreWrap)) {
     785        if (canBreakMidWord && !midWordBreak && (!m_currentCharacterIsSpace || m_atStart || style.whiteSpace() != WhiteSpace::PreWrap)) {
    778786            wrapW += charWidth;
    779787            bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && U16_IS_TRAIL(renderText.characterAt(m_current.offset() + 1));
     
    847855                // as candidate width for this line.
    848856                bool lineWasTooWide = false;
    849                 if (fitsOnLineOrHangsAtEnd() && m_currentCharacterIsWS && m_currentStyle->breakOnlyAfterWhiteSpace() && !midWordBreak) {
     857                if (fitsOnLineOrHangsAtEnd() && m_currentCharacterIsWS && m_currentStyle->breakOnlyAfterWhiteSpace() && (!midWordBreak || m_currWS == WhiteSpace::BreakSpaces)) {
    850858                    float charWidth = textWidth(renderText, m_current.offset(), 1, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, wordMeasurement.fallbackFonts, textLayout) + (applyWordSpacing ? wordSpacing : 0);
    851859                    // Check if line is too big even without the extra space
     
    856864                    if (!m_width.fitsOnLineIncludingExtraWidth(charWidth)) {
    857865                        lineWasTooWide = true;
    858                         m_lineBreak.moveTo(renderObject, m_current.offset(), m_current.nextBreakablePosition());
    859                         m_lineBreaker.skipTrailingWhitespace(m_lineBreak, m_lineInfo);
     866                        if (m_currWS == WhiteSpace::BreakSpaces)
     867                            trailingSpacesHang(m_lineBreak, renderObject, canBreakMidWord, previousCharacterIsSpace);
     868                        else {
     869                            m_lineBreak.moveTo(renderObject, m_current.offset(), m_current.nextBreakablePosition());
     870                            m_lineBreaker.skipTrailingWhitespace(m_lineBreak, m_lineInfo);
     871                        }
    860872                    }
    861873                }
     
    942954                // Auto-wrapping text should not wrap in the middle of a word once it has had an
    943955                // opportunity to break after a word.
     956                m_hasFormerOpportunity = canBreakMidWord;
    944957                breakWords = false;
     958                canBreakMidWord = breakAll;
    945959            }
    946960
     
    949963                // adding the end width forces a break.
    950964                m_lineBreak.moveTo(renderObject, m_current.offset(), m_current.nextBreakablePosition());
    951                 midWordBreak &= (breakWords || breakAll);
     965                midWordBreak &= canBreakMidWord;
    952966            }
    953967
     
    10731087}
    10741088
     1089inline void BreakingContext::trailingSpacesHang(InlineIterator& lineBreak, RenderObject& renderObject, bool canBreakMidWord, bool previousCharacterIsSpace)
     1090{
     1091    ASSERT(m_currWS == WhiteSpace::BreakSpaces);
     1092    // Avoid breaking before the first white-space after a word if there is a
     1093    // breaking opportunity before.
     1094    if (m_hasFormerOpportunity)
     1095        return;
     1096
     1097    lineBreak.moveTo(renderObject, m_current.offset(), m_current.nextBreakablePosition());
     1098
     1099    // Avoid breaking before the first white-space after a word, unless
     1100    // overflow-wrap or word-break allow to.
     1101    if (!previousCharacterIsSpace && !canBreakMidWord)
     1102        lineBreak.increment();
     1103}
     1104
    10751105inline bool BreakingContext::canBreakAtThisPosition()
    10761106{
  • trunk/Source/WebCore/rendering/style/RenderStyle.h

    r243893 r244036  
    20672067{
    20682068    // Pre and prewrap do not collapse whitespace.
    2069     return ws != WhiteSpace::Pre && ws != WhiteSpace::PreWrap;
     2069    return ws != WhiteSpace::Pre && ws != WhiteSpace::PreWrap && ws != WhiteSpace::BreakSpaces;
    20702070}
    20712071
     
    20852085inline bool RenderStyle::breakOnlyAfterWhiteSpace() const
    20862086{
    2087     return whiteSpace() == WhiteSpace::PreWrap || lineBreak() == LineBreak::AfterWhiteSpace;
     2087    return whiteSpace() == WhiteSpace::PreWrap || whiteSpace() == WhiteSpace::BreakSpaces || lineBreak() == LineBreak::AfterWhiteSpace;
    20882088}
    20892089
  • trunk/Source/WebCore/rendering/style/RenderStyleConstants.h

    r243841 r244036  
    659659    PreLine,
    660660    NoWrap,
    661     KHTMLNoWrap
     661    KHTMLNoWrap,
     662    BreakSpaces
    662663};
    663664
Note: See TracChangeset for help on using the changeset viewer.