Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp

Issue 2450093005: Support display: contents for elements, first-line and first-letter pseudos. (Closed)
Patch Set: Support display: contents for elements, first-line and first-letter pseudos. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> 7 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
8 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> 8 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
9 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. 9 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
10 * (http://www.torchmobile.com/) 10 * (http://www.torchmobile.com/)
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 return display; 68 return display;
69 case EDisplay::InlineTable: 69 case EDisplay::InlineTable:
70 return EDisplay::Table; 70 return EDisplay::Table;
71 case EDisplay::WebkitInlineBox: 71 case EDisplay::WebkitInlineBox:
72 return EDisplay::WebkitBox; 72 return EDisplay::WebkitBox;
73 case EDisplay::InlineFlex: 73 case EDisplay::InlineFlex:
74 return EDisplay::Flex; 74 return EDisplay::Flex;
75 case EDisplay::InlineGrid: 75 case EDisplay::InlineGrid:
76 return EDisplay::Grid; 76 return EDisplay::Grid;
77 77
78 case EDisplay::Contents:
78 case EDisplay::Inline: 79 case EDisplay::Inline:
79 case EDisplay::InlineBlock: 80 case EDisplay::InlineBlock:
80 case EDisplay::TableRowGroup: 81 case EDisplay::TableRowGroup:
81 case EDisplay::TableHeaderGroup: 82 case EDisplay::TableHeaderGroup:
82 case EDisplay::TableFooterGroup: 83 case EDisplay::TableFooterGroup:
83 case EDisplay::TableRow: 84 case EDisplay::TableRow:
84 case EDisplay::TableColumnGroup: 85 case EDisplay::TableColumnGroup:
85 case EDisplay::TableColumn: 86 case EDisplay::TableColumn:
86 case EDisplay::TableCell: 87 case EDisplay::TableCell:
87 case EDisplay::TableCaption: 88 case EDisplay::TableCaption:
88 return EDisplay::Block; 89 return EDisplay::Block;
89 case EDisplay::None: 90 case EDisplay::None:
90 case EDisplay::Contents:
91 ASSERT_NOT_REACHED(); 91 ASSERT_NOT_REACHED();
92 return display; 92 return display;
93 } 93 }
94 ASSERT_NOT_REACHED(); 94 ASSERT_NOT_REACHED();
95 return EDisplay::Block; 95 return EDisplay::Block;
96 } 96 }
97 97
98 static bool isOutermostSVGElement(const Element* element) { 98 static bool isOutermostSVGElement(const Element* element) {
99 return element && element->isSVGElement() && 99 return element && element->isSVGElement() &&
100 toSVGElement(*element).isOutermostSVGSVGElement(); 100 toSVGElement(*element).isOutermostSVGSVGElement();
(...skipping 23 matching lines...) Expand all
124 (isHTMLFontElement(element) || isHTMLAnchorElement(element)); 124 (isHTMLFontElement(element) || isHTMLAnchorElement(element));
125 } 125 }
126 126
127 // FIXME: This helper is only needed because pseudoStyleForElement passes a null 127 // FIXME: This helper is only needed because pseudoStyleForElement passes a null
128 // element to adjustComputedStyle, so we can't just use element->isInTopLayer(). 128 // element to adjustComputedStyle, so we can't just use element->isInTopLayer().
129 static bool isInTopLayer(const Element* element, const ComputedStyle& style) { 129 static bool isInTopLayer(const Element* element, const ComputedStyle& style) {
130 return (element && element->isInTopLayer()) || 130 return (element && element->isInTopLayer()) ||
131 style.styleType() == PseudoIdBackdrop; 131 style.styleType() == PseudoIdBackdrop;
132 } 132 }
133 133
134 static bool parentStyleForcesZIndexToCreateStackingContext( 134 static bool layoutParentStyleForcesZIndexToCreateStackingContext(
135 const ComputedStyle& parentStyle) { 135 const ComputedStyle& layoutParentStyle) {
136 return parentStyle.isDisplayFlexibleOrGridBox(); 136 return layoutParentStyle.isDisplayFlexibleOrGridBox();
137 } 137 }
138 138
139 void StyleAdjuster::adjustStyleForEditing(ComputedStyle& style) { 139 void StyleAdjuster::adjustStyleForEditing(ComputedStyle& style) {
140 if (style.userModify() != READ_WRITE_PLAINTEXT_ONLY) 140 if (style.userModify() != READ_WRITE_PLAINTEXT_ONLY)
141 return; 141 return;
142 // Collapsing whitespace is harmful in plain-text editing. 142 // Collapsing whitespace is harmful in plain-text editing.
143 if (style.whiteSpace() == EWhiteSpace::kNormal) 143 if (style.whiteSpace() == EWhiteSpace::kNormal)
144 style.setWhiteSpace(EWhiteSpace::kPreWrap); 144 style.setWhiteSpace(EWhiteSpace::kPreWrap);
145 else if (style.whiteSpace() == EWhiteSpace::kNowrap) 145 else if (style.whiteSpace() == EWhiteSpace::kNowrap)
146 style.setWhiteSpace(EWhiteSpace::kPre); 146 style.setWhiteSpace(EWhiteSpace::kPre);
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 } 317 }
318 318
319 // Menulists should have visible overflow 319 // Menulists should have visible overflow
320 if (style.appearance() == MenulistPart) { 320 if (style.appearance() == MenulistPart) {
321 style.setOverflowX(EOverflow::kVisible); 321 style.setOverflowX(EOverflow::kVisible);
322 style.setOverflowY(EOverflow::kVisible); 322 style.setOverflowY(EOverflow::kVisible);
323 } 323 }
324 } 324 }
325 325
326 static void adjustStyleForDisplay(ComputedStyle& style, 326 static void adjustStyleForDisplay(ComputedStyle& style,
327 const ComputedStyle& parentStyle, 327 const ComputedStyle& layoutParentStyle,
328 Document* document) { 328 Document* document) {
329 if (style.display() == EDisplay::Block && !style.isFloating()) 329 if (style.display() == EDisplay::Block && !style.isFloating())
330 return; 330 return;
331 331
332 if (style.display() == EDisplay::Contents)
333 return;
334
332 // FIXME: Don't support this mutation for pseudo styles like first-letter or 335 // FIXME: Don't support this mutation for pseudo styles like first-letter or
333 // first-line, since it's not completely clear how that should work. 336 // first-line, since it's not completely clear how that should work.
334 if (style.display() == EDisplay::Inline && 337 if (style.display() == EDisplay::Inline &&
335 style.styleType() == PseudoIdNone && 338 style.styleType() == PseudoIdNone &&
336 style.getWritingMode() != parentStyle.getWritingMode()) 339 style.getWritingMode() != layoutParentStyle.getWritingMode())
337 style.setDisplay(EDisplay::InlineBlock); 340 style.setDisplay(EDisplay::InlineBlock);
338 341
339 // After performing the display mutation, check table rows. We do not honor 342 // After performing the display mutation, check table rows. We do not honor
340 // position: relative table rows. This has been established for position: 343 // position: relative table rows. This has been established for position:
341 // relative in CSS2.1 (and caused a crash in containingBlock() on some sites). 344 // relative in CSS2.1 (and caused a crash in containingBlock() on some sites).
342 if ((style.display() == EDisplay::TableHeaderGroup || 345 if ((style.display() == EDisplay::TableHeaderGroup ||
343 style.display() == EDisplay::TableRowGroup || 346 style.display() == EDisplay::TableRowGroup ||
344 style.display() == EDisplay::TableFooterGroup || 347 style.display() == EDisplay::TableFooterGroup ||
345 style.display() == EDisplay::TableRow) && 348 style.display() == EDisplay::TableRow) &&
346 style.position() == EPosition::kRelative) 349 style.position() == EPosition::kRelative)
(...skipping 11 matching lines...) Expand all
358 // rows, and table columns. 361 // rows, and table columns.
359 // FIXME: Table cells should be allowed to be perpendicular or flipped with 362 // FIXME: Table cells should be allowed to be perpendicular or flipped with
360 // respect to the table, though. 363 // respect to the table, though.
361 if (style.display() == EDisplay::TableColumn || 364 if (style.display() == EDisplay::TableColumn ||
362 style.display() == EDisplay::TableColumnGroup || 365 style.display() == EDisplay::TableColumnGroup ||
363 style.display() == EDisplay::TableFooterGroup || 366 style.display() == EDisplay::TableFooterGroup ||
364 style.display() == EDisplay::TableHeaderGroup || 367 style.display() == EDisplay::TableHeaderGroup ||
365 style.display() == EDisplay::TableRow || 368 style.display() == EDisplay::TableRow ||
366 style.display() == EDisplay::TableRowGroup || 369 style.display() == EDisplay::TableRowGroup ||
367 style.display() == EDisplay::TableCell) 370 style.display() == EDisplay::TableCell)
368 style.setWritingMode(parentStyle.getWritingMode()); 371 style.setWritingMode(layoutParentStyle.getWritingMode());
369 372
370 // FIXME: Since we don't support block-flow on flexible boxes yet, disallow 373 // FIXME: Since we don't support block-flow on flexible boxes yet, disallow
371 // setting of block-flow to anything other than TopToBottomWritingMode. 374 // setting of block-flow to anything other than TopToBottomWritingMode.
372 // https://bugs.webkit.org/show_bug.cgi?id=46418 - Flexible box support. 375 // https://bugs.webkit.org/show_bug.cgi?id=46418 - Flexible box support.
373 if (style.getWritingMode() != WritingMode::kHorizontalTb && 376 if (style.getWritingMode() != WritingMode::kHorizontalTb &&
374 (style.display() == EDisplay::WebkitBox || 377 (style.display() == EDisplay::WebkitBox ||
375 style.display() == EDisplay::WebkitInlineBox)) 378 style.display() == EDisplay::WebkitInlineBox))
376 style.setWritingMode(WritingMode::kHorizontalTb); 379 style.setWritingMode(WritingMode::kHorizontalTb);
377 380
378 if (parentStyle.isDisplayFlexibleOrGridBox()) { 381 if (layoutParentStyle.isDisplayFlexibleOrGridBox()) {
379 style.setFloating(EFloat::kNone); 382 style.setFloating(EFloat::kNone);
380 style.setDisplay(equivalentBlockDisplay(style.display())); 383 style.setDisplay(equivalentBlockDisplay(style.display()));
381 384
382 // We want to count vertical percentage paddings/margins on flex items 385 // We want to count vertical percentage paddings/margins on flex items
383 // because our current behavior is different from the spec and we want to 386 // because our current behavior is different from the spec and we want to
384 // gather compatibility data. 387 // gather compatibility data.
385 if (style.paddingBefore().isPercentOrCalc() || 388 if (style.paddingBefore().isPercentOrCalc() ||
386 style.paddingAfter().isPercentOrCalc()) 389 style.paddingAfter().isPercentOrCalc())
387 UseCounter::count(document, UseCounter::FlexboxPercentagePaddingVertical); 390 UseCounter::count(document, UseCounter::FlexboxPercentagePaddingVertical);
388 if (style.marginBefore().isPercentOrCalc() || 391 if (style.marginBefore().isPercentOrCalc() ||
389 style.marginAfter().isPercentOrCalc()) 392 style.marginAfter().isPercentOrCalc())
390 UseCounter::count(document, UseCounter::FlexboxPercentageMarginVertical); 393 UseCounter::count(document, UseCounter::FlexboxPercentageMarginVertical);
391 } 394 }
392 } 395 }
393 396
394 void StyleAdjuster::adjustComputedStyle(ComputedStyle& style, 397 void StyleAdjuster::adjustComputedStyle(ComputedStyle& style,
395 const ComputedStyle& parentStyle, 398 const ComputedStyle& parentStyle,
399 const ComputedStyle& layoutParentStyle,
396 Element* element) { 400 Element* element) {
397 if (style.display() != EDisplay::None && 401 if (style.display() != EDisplay::None) {
398 style.display() != EDisplay::Contents) {
399 if (element && element->isHTMLElement()) 402 if (element && element->isHTMLElement())
400 adjustStyleForHTMLElement(style, toHTMLElement(*element)); 403 adjustStyleForHTMLElement(style, toHTMLElement(*element));
401 404
402 // Per the spec, position 'static' and 'relative' in the top layer compute 405 // Per the spec, position 'static' and 'relative' in the top layer compute
403 // to 'absolute'. 406 // to 'absolute'.
404 if (isInTopLayer(element, style) && 407 if (isInTopLayer(element, style) &&
405 (style.position() == EPosition::kStatic || 408 (style.position() == EPosition::kStatic ||
406 style.position() == EPosition::kRelative)) 409 style.position() == EPosition::kRelative))
407 style.setPosition(EPosition::kAbsolute); 410 style.setPosition(EPosition::kAbsolute);
408 411
409 // Absolute/fixed positioned elements, floating elements and the document 412 // Absolute/fixed positioned elements, floating elements and the document
410 // element need block-like outside display. 413 // element need block-like outside display.
411 if (style.hasOutOfFlowPosition() || style.isFloating() || 414 if (style.display() != EDisplay::Contents &&
412 (element && element->document().documentElement() == element)) 415 (style.hasOutOfFlowPosition() || style.isFloating()))
416 style.setDisplay(equivalentBlockDisplay(style.display()));
417
418 if (element && element->document().documentElement() == element)
413 style.setDisplay(equivalentBlockDisplay(style.display())); 419 style.setDisplay(equivalentBlockDisplay(style.display()));
414 420
415 // We don't adjust the first letter style earlier because we may change the 421 // We don't adjust the first letter style earlier because we may change the
416 // display setting in adjustStyeForTagName() above. 422 // display setting in adjustStyeForTagName() above.
417 adjustStyleForFirstLetter(style); 423 adjustStyleForFirstLetter(style);
418 424
419 adjustStyleForDisplay(style, parentStyle, 425 adjustStyleForDisplay(style, layoutParentStyle,
420 element ? &element->document() : 0); 426 element ? &element->document() : 0);
421 427
422 // Paint containment forces a block formatting context, so we must coerce 428 // Paint containment forces a block formatting context, so we must coerce
423 // from inline. https://drafts.csswg.org/css-containment/#containment-paint 429 // from inline. https://drafts.csswg.org/css-containment/#containment-paint
424 if (style.containsPaint() && style.display() == EDisplay::Inline) 430 if (style.containsPaint() && style.display() == EDisplay::Inline)
425 style.setDisplay(EDisplay::Block); 431 style.setDisplay(EDisplay::Block);
426 } else { 432 } else {
427 adjustStyleForFirstLetter(style); 433 adjustStyleForFirstLetter(style);
428 } 434 }
429 435
430 if (element && element->hasCompositorProxy()) 436 if (element && element->hasCompositorProxy())
431 style.setHasCompositorProxy(true); 437 style.setHasCompositorProxy(true);
432 438
433 // Make sure our z-index value is only applied if the object is positioned. 439 // Make sure our z-index value is only applied if the object is positioned.
434 if (style.position() == EPosition::kStatic && 440 if (style.position() == EPosition::kStatic &&
435 !parentStyleForcesZIndexToCreateStackingContext(parentStyle)) { 441 !layoutParentStyleForcesZIndexToCreateStackingContext(
442 layoutParentStyle)) {
436 style.setIsStackingContext(false); 443 style.setIsStackingContext(false);
437 // TODO(alancutter): Avoid altering z-index here. 444 // TODO(alancutter): Avoid altering z-index here.
438 if (!style.hasAutoZIndex()) 445 if (!style.hasAutoZIndex())
439 style.setZIndex(0); 446 style.setZIndex(0);
440 } else if (!style.hasAutoZIndex()) { 447 } else if (!style.hasAutoZIndex()) {
441 style.setIsStackingContext(true); 448 style.setIsStackingContext(true);
442 } 449 }
443 450
444 if (style.overflowX() != EOverflow::kVisible || 451 if (style.overflowX() != EOverflow::kVisible ||
445 style.overflowY() != EOverflow::kVisible) 452 style.overflowY() != EOverflow::kVisible)
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 style.setDisplay(EDisplay::Block); 503 style.setDisplay(EDisplay::Block);
497 504
498 // Columns don't apply to svg text elements. 505 // Columns don't apply to svg text elements.
499 if (isSVGTextElement(*element)) 506 if (isSVGTextElement(*element))
500 style.clearMultiCol(); 507 style.clearMultiCol();
501 } 508 }
502 adjustStyleForAlignment(style, parentStyle); 509 adjustStyleForAlignment(style, parentStyle);
503 } 510 }
504 511
505 } // namespace blink 512 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698