Changeset 220795 in webkit


Ignore:
Timestamp:
Aug 16, 2017 6:15:20 AM (7 years ago)
Author:
Antti Koivisto
Message:

Move first-letter renderer mutation code out of RenderBlock and into RenderTreeUpdater
https://bugs.webkit.org/show_bug.cgi?id=175627

Reviewed by Andreas Kling.

Render tree should not mutate itself. We already fixed this for first-letter, supporting code
can now move to RenderTreeUpdater too.

  • CMakeLists.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • rendering/RenderBlock.cpp:

(WebCore::styleForFirstLetter): Deleted.
(WebCore::isPunctuationForFirstLetter): Deleted.
(WebCore::shouldSkipForFirstLetter): Deleted.
(WebCore::RenderBlock::updateFirstLetterStyle): Deleted.
(WebCore::RenderBlock::createFirstLetterRenderer): Deleted.
(WebCore::RenderBlock::updateFirstLetter): Deleted.

  • rendering/RenderBlock.h:
  • rendering/RenderRubyRun.cpp:

(WebCore::RenderRubyRun::updateFirstLetter): Deleted.

  • rendering/RenderRubyRun.h:
  • rendering/RenderTable.cpp:

(WebCore::RenderTable::updateFirstLetter): Deleted.

  • rendering/RenderTable.h:

Virtual overrides just disabled first letter for some RenderBlock subclasses. This is now achieved via
supportsFirstLetter test in the first letter updater.

  • rendering/TextAutoSizing.cpp:

(WebCore::TextAutoSizingValue::adjustTextNodeSizes):

  • rendering/svg/RenderSVGText.cpp:

(WebCore::RenderSVGText::updateFirstLetter): Deleted.

  • rendering/svg/RenderSVGText.h:
  • style/RenderTreeUpdater.cpp:

(WebCore::RenderTreeUpdater::popParent):

  • style/RenderTreeUpdater.h:
  • style/RenderTreeUpdaterFirstLetter.cpp: Added.

(WebCore::styleForFirstLetter):
(WebCore::isPunctuationForFirstLetter):
(WebCore::shouldSkipForFirstLetter):
(WebCore::updateFirstLetterStyle):
(WebCore::createFirstLetterRenderer):
(WebCore::supportsFirstLetter):
(WebCore::RenderTreeUpdater::FirstLetter::update):

  • style/RenderTreeUpdaterFirstLetter.h: Added.
Location:
trunk/Source/WebCore
Files:
2 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/CMakeLists.txt

    r220759 r220795  
    27972797    style/RenderTreePosition.cpp
    27982798    style/RenderTreeUpdater.cpp
     2799    style/RenderTreeUpdaterFirstLetter.cpp
    27992800    style/StyleChange.cpp
    28002801    style/StyleFontSizeFunctions.cpp
  • trunk/Source/WebCore/ChangeLog

    r220790 r220795  
     12017-08-16  Antti Koivisto  <antti@apple.com>
     2
     3        Move first-letter renderer mutation code out of RenderBlock and into RenderTreeUpdater
     4        https://bugs.webkit.org/show_bug.cgi?id=175627
     5
     6        Reviewed by Andreas Kling.
     7
     8        Render tree should not mutate itself. We already fixed this for first-letter, supporting code
     9        can now move to RenderTreeUpdater too.
     10
     11        * CMakeLists.txt:
     12        * WebCore.xcodeproj/project.pbxproj:
     13        * rendering/RenderBlock.cpp:
     14        (WebCore::styleForFirstLetter): Deleted.
     15        (WebCore::isPunctuationForFirstLetter): Deleted.
     16        (WebCore::shouldSkipForFirstLetter): Deleted.
     17        (WebCore::RenderBlock::updateFirstLetterStyle): Deleted.
     18        (WebCore::RenderBlock::createFirstLetterRenderer): Deleted.
     19        (WebCore::RenderBlock::updateFirstLetter): Deleted.
     20        * rendering/RenderBlock.h:
     21        * rendering/RenderRubyRun.cpp:
     22        (WebCore::RenderRubyRun::updateFirstLetter): Deleted.
     23        * rendering/RenderRubyRun.h:
     24        * rendering/RenderTable.cpp:
     25        (WebCore::RenderTable::updateFirstLetter): Deleted.
     26        * rendering/RenderTable.h:
     27
     28            Virtual overrides just disabled first letter for some RenderBlock subclasses. This is now achieved via
     29            supportsFirstLetter test in the first letter updater.
     30
     31        * rendering/TextAutoSizing.cpp:
     32        (WebCore::TextAutoSizingValue::adjustTextNodeSizes):
     33        * rendering/svg/RenderSVGText.cpp:
     34        (WebCore::RenderSVGText::updateFirstLetter): Deleted.
     35        * rendering/svg/RenderSVGText.h:
     36        * style/RenderTreeUpdater.cpp:
     37        (WebCore::RenderTreeUpdater::popParent):
     38        * style/RenderTreeUpdater.h:
     39        * style/RenderTreeUpdaterFirstLetter.cpp: Added.
     40        (WebCore::styleForFirstLetter):
     41        (WebCore::isPunctuationForFirstLetter):
     42        (WebCore::shouldSkipForFirstLetter):
     43        (WebCore::updateFirstLetterStyle):
     44        (WebCore::createFirstLetterRenderer):
     45        (WebCore::supportsFirstLetter):
     46        (WebCore::RenderTreeUpdater::FirstLetter::update):
     47        * style/RenderTreeUpdaterFirstLetter.h: Added.
     48
    1492017-08-16  Xabier Rodriguez Calvar  <calvaris@igalia.com>
    250
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r220759 r220795  
    68006800                E47E276816036EDC00EE2AFB /* ExtensionStyleSheets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E47E276716036EDC00EE2AFB /* ExtensionStyleSheets.cpp */; };
    68016801                E48137B91DB3B526005C59BF /* StyleValidity.h in Headers */ = {isa = PBXBuildFile; fileRef = E48137B81DB3B526005C59BF /* StyleValidity.h */; settings = {ATTRIBUTES = (Private, ); }; };
     6802                E48284081F44594C00863AC3 /* RenderTreeUpdaterFirstLetter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48284061F44594B00863AC3 /* RenderTreeUpdaterFirstLetter.cpp */; };
    68026803                E48944A2180B57D800F165D8 /* SimpleLineLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48944A0180B57D800F165D8 /* SimpleLineLayout.cpp */; };
    68036804                E48944A3180B57D800F165D8 /* SimpleLineLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = E48944A1180B57D800F165D8 /* SimpleLineLayout.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1249112492                9B098BDF1F3D673D002DD562 /* JSDataTransferItemList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDataTransferItemList.cpp; sourceTree = "<group>"; };
    1249212493                9B098BE01F3D673D002DD562 /* JSDataTransferItemList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDataTransferItemList.h; sourceTree = "<group>"; };
    12493                 9B098BE61F3D6AF6002DD562 /* JSStringCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSStringCallback.cpp; path = JSStringCallback.cpp; sourceTree = "<group>"; };
    12494                 9B098BE71F3D6AF6002DD562 /* JSStringCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSStringCallback.h; path = JSStringCallback.h; sourceTree = "<group>"; };
     12494                9B098BE61F3D6AF6002DD562 /* JSStringCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStringCallback.cpp; sourceTree = "<group>"; };
     12495                9B098BE71F3D6AF6002DD562 /* JSStringCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringCallback.h; sourceTree = "<group>"; };
    1249512496                9B0FE8731D9E02DF004A8ACB /* DocumentOrShadowRoot.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DocumentOrShadowRoot.idl; sourceTree = "<group>"; };
    1249612497                9B13257B1F3D2ABA00DAAB69 /* DataTransferItemList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataTransferItemList.cpp; sourceTree = "<group>"; };
     
    1542115422                E47E276716036EDC00EE2AFB /* ExtensionStyleSheets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExtensionStyleSheets.cpp; sourceTree = "<group>"; };
    1542215423                E48137B81DB3B526005C59BF /* StyleValidity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleValidity.h; sourceTree = "<group>"; };
     15424                E48284061F44594B00863AC3 /* RenderTreeUpdaterFirstLetter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeUpdaterFirstLetter.cpp; sourceTree = "<group>"; };
     15425                E48284091F44595600863AC3 /* RenderTreeUpdaterFirstLetter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderTreeUpdaterFirstLetter.h; sourceTree = "<group>"; };
    1542315426                E48944A0180B57D800F165D8 /* SimpleLineLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleLineLayout.cpp; sourceTree = "<group>"; };
    1542415427                E48944A1180B57D800F165D8 /* SimpleLineLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayout.h; sourceTree = "<group>"; };
     
    2495124954                                E461802A1C8A06D90026C02C /* RenderTreeUpdater.cpp */,
    2495224955                                E46180281C8A06CD0026C02C /* RenderTreeUpdater.h */,
     24956                                E48284061F44594B00863AC3 /* RenderTreeUpdaterFirstLetter.cpp */,
     24957                                E48284091F44595600863AC3 /* RenderTreeUpdaterFirstLetter.h */,
    2495324958                                E401E0A51C3C0CF700F34D10 /* StyleChange.cpp */,
    2495424959                                E401E0A31C3C0B8300F34D10 /* StyleChange.h */,
     
    2947429479                                2D93AEE319DF5641002A86C3 /* ServicesOverlayController.h in Headers */,
    2947529480                                51F1755D1F3EBC8300C74950 /* ServiceWorker.h in Headers */,
    29476                                 5182C23F1F313A090059BA7C /* ServiceWorker.h in Headers */,
    2947729481                                51F1755F1F3EBC8300C74950 /* ServiceWorkerContainer.h in Headers */,
    29478                                 5182C2411F313A090059BA7C /* ServiceWorkerContainer.h in Headers */,
    2947929482                                51F175611F3EBC8300C74950 /* ServiceWorkerGlobalScope.h in Headers */,
    29480                                 5182C2431F313A090059BA7C /* ServiceWorkerGlobalScope.h in Headers */,
    2948129483                                51F175631F3EBC8300C74950 /* ServiceWorkerJob.h in Headers */,
    29482                                 511CA67E1F3905A60019E074 /* ServiceWorkerJob.h in Headers */,
    2948329484                                51F175641F3EBC8300C74950 /* ServiceWorkerJobClient.h in Headers */,
    29484                                 511CA6801F39331F0019E074 /* ServiceWorkerJobClient.h in Headers */,
    29485                                 511CA67A1F3904B10019E074 /* ServiceWorkerProvider.h in Headers */,
    2948629485                                51F175661F3EBC8300C74950 /* ServiceWorkerProvider.h in Headers */,
    2948729486                                51F175681F3EBC8300C74950 /* ServiceWorkerRegistration.h in Headers */,
    29488                                 5182C2451F313A090059BA7C /* ServiceWorkerRegistration.h in Headers */,
    2948929487                                51F175691F3EBC8300C74950 /* ServiceWorkerRegistrationOptions.h in Headers */,
    2949029488                                51F1756B1F3EBC8300C74950 /* ServiceWorkerRegistrationParameters.h in Headers */,
    2949129489                                51F1756C1F3EBC8300C74950 /* ServiceWorkerUpdateViaCache.h in Headers */,
    29492                                 51F174FF1F35899700C74950 /* ServiceWorkerUpdateViaCache.h in Headers */,
    2949329490                                756B2CE118B7101600FECFAA /* SessionID.h in Headers */,
    2949429491                                93309E10099E64920056E581 /* SetNodeAttributeCommand.h in Headers */,
     
    3190231899                                7C9ACABF1F3CF1AF00F3AA09 /* JSCryptoRsaHashedKeyAlgorithm.cpp in Sources */,
    3190331900                                7C9ACAC11F3CF1AF00F3AA09 /* JSCryptoRsaKeyAlgorithm.cpp in Sources */,
     31901                                E48284081F44594C00863AC3 /* RenderTreeUpdaterFirstLetter.cpp in Sources */,
    3190431902                                BC46C1FC0C0DDC8F0020CFC3 /* JSCSSFontFaceRule.cpp in Sources */,
    3190531903                                BC46C1FE0C0DDC8F0020CFC3 /* JSCSSImportRule.cpp in Sources */,
     
    3333933337                                2D93AEE419DF5641002A86C3 /* ServicesOverlayController.mm in Sources */,
    3334033338                                51F1755C1F3EBC8300C74950 /* ServiceWorker.cpp in Sources */,
    33341                                 5182C23E1F313A090059BA7C /* ServiceWorker.cpp in Sources */,
    3334233339                                51F1755E1F3EBC8300C74950 /* ServiceWorkerContainer.cpp in Sources */,
    33343                                 5182C2401F313A090059BA7C /* ServiceWorkerContainer.cpp in Sources */,
    33344                                 5182C2421F313A090059BA7C /* ServiceWorkerGlobalScope.cpp in Sources */,
    3334533340                                51F175601F3EBC8300C74950 /* ServiceWorkerGlobalScope.cpp in Sources */,
    3334633341                                51F175621F3EBC8300C74950 /* ServiceWorkerJob.cpp in Sources */,
    33347                                 511CA67D1F3905A60019E074 /* ServiceWorkerJob.cpp in Sources */,
    33348                                 511CA6791F3904B10019E074 /* ServiceWorkerProvider.cpp in Sources */,
    3334933342                                51F175651F3EBC8300C74950 /* ServiceWorkerProvider.cpp in Sources */,
    3335033343                                51F175671F3EBC8300C74950 /* ServiceWorkerRegistration.cpp in Sources */,
    33351                                 5182C2441F313A090059BA7C /* ServiceWorkerRegistration.cpp in Sources */,
    3335233344                                51F1756A1F3EBC8300C74950 /* ServiceWorkerRegistrationParameters.cpp in Sources */,
    33353                                 511CA6831F3A3CD90019E074 /* ServiceWorkerRegistrationParameters.cpp in Sources */,
    3335433345                                511F7D441EB1C39100E47B83 /* SessionID.cpp in Sources */,
    3335533346                                93309E0F099E64920056E581 /* SetNodeAttributeCommand.cpp in Sources */,
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r220646 r220795  
    30863086}
    30873087
    3088 static RenderStyle styleForFirstLetter(const RenderElement& firstLetterBlock, const RenderObject& firstLetterContainer)
    3089 {
    3090     auto* containerFirstLetterStyle = firstLetterBlock.getCachedPseudoStyle(FIRST_LETTER, &firstLetterContainer.firstLineStyle());
    3091     // FIXME: There appears to be some path where we have a first letter renderer without first letter style.
    3092     ASSERT(containerFirstLetterStyle);
    3093     auto firstLetterStyle = RenderStyle::clone(containerFirstLetterStyle ? *containerFirstLetterStyle : firstLetterContainer.firstLineStyle());
    3094 
    3095     // If we have an initial letter drop that is >= 1, then we need to force floating to be on.
    3096     if (firstLetterStyle.initialLetterDrop() >= 1 && !firstLetterStyle.isFloating())
    3097         firstLetterStyle.setFloating(firstLetterStyle.isLeftToRightDirection() ? LeftFloat : RightFloat);
    3098 
    3099     // We have to compute the correct font-size for the first-letter if it has an initial letter height set.
    3100     auto* paragraph = firstLetterContainer.isRenderBlockFlow() ? &firstLetterContainer : firstLetterContainer.containingBlock();
    3101     if (firstLetterStyle.initialLetterHeight() >= 1 && firstLetterStyle.fontMetrics().hasCapHeight() && paragraph->style().fontMetrics().hasCapHeight()) {
    3102         // FIXME: For ideographic baselines, we want to go from line edge to line edge. This is equivalent to (N-1)*line-height + the font height.
    3103         // We don't yet support ideographic baselines.
    3104         // For an N-line first-letter and for alphabetic baselines, the cap-height of the first letter needs to equal (N-1)*line-height of paragraph lines + cap-height of the paragraph
    3105         // Mathematically we can't rely on font-size, since font().height() doesn't necessarily match. For reliability, the best approach is simply to
    3106         // compare the final measured cap-heights of the two fonts in order to get to the closest possible value.
    3107         firstLetterStyle.setLineBoxContain(LineBoxContainInitialLetter);
    3108         int lineHeight = paragraph->style().computedLineHeight();
    3109        
    3110         // Set the font to be one line too big and then ratchet back to get to a precise fit. We can't just set the desired font size based off font height metrics
    3111         // because many fonts bake ascent into the font metrics. Therefore we have to look at actual measured cap height values in order to know when we have a good fit.
    3112         auto newFontDescription = firstLetterStyle.fontDescription();
    3113         float capRatio = firstLetterStyle.fontMetrics().floatCapHeight() / firstLetterStyle.computedFontPixelSize();
    3114         float startingFontSize = ((firstLetterStyle.initialLetterHeight() - 1) * lineHeight + paragraph->style().fontMetrics().capHeight()) / capRatio;
    3115         newFontDescription.setSpecifiedSize(startingFontSize);
    3116         newFontDescription.setComputedSize(startingFontSize);
    3117         firstLetterStyle.setFontDescription(newFontDescription);
    3118         firstLetterStyle.fontCascade().update(firstLetterStyle.fontCascade().fontSelector());
    3119        
    3120         int desiredCapHeight = (firstLetterStyle.initialLetterHeight() - 1) * lineHeight + paragraph->style().fontMetrics().capHeight();
    3121         int actualCapHeight = firstLetterStyle.fontMetrics().capHeight();
    3122         while (actualCapHeight > desiredCapHeight) {
    3123             auto newFontDescription = firstLetterStyle.fontDescription();
    3124             newFontDescription.setSpecifiedSize(newFontDescription.specifiedSize() - 1);
    3125             newFontDescription.setComputedSize(newFontDescription.computedSize() -1);
    3126             firstLetterStyle.setFontDescription(newFontDescription);
    3127             firstLetterStyle.fontCascade().update(firstLetterStyle.fontCascade().fontSelector());
    3128             actualCapHeight = firstLetterStyle.fontMetrics().capHeight();
    3129         }
    3130     }
    3131    
    3132     // Force inline display (except for floating first-letters).
    3133     firstLetterStyle.setDisplay(firstLetterStyle.isFloating() ? BLOCK : INLINE);
    3134     // CSS2 says first-letter can't be positioned.
    3135     firstLetterStyle.setPosition(StaticPosition);
    3136     return firstLetterStyle;
    3137 }
    3138 
    3139 // CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
    3140 // "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
    3141 // "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
    3142 static inline bool isPunctuationForFirstLetter(UChar c)
    3143 {
    3144     return U_GET_GC_MASK(c) & (U_GC_PS_MASK | U_GC_PE_MASK | U_GC_PI_MASK | U_GC_PF_MASK | U_GC_PO_MASK);
    3145 }
    3146 
    3147 static inline bool shouldSkipForFirstLetter(UChar c)
    3148 {
    3149     return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
    3150 }
    3151 
    31523088static inline RenderBlock* findFirstLetterBlock(RenderBlock* start)
    31533089{
     
    31703106}
    31713107
    3172 void RenderBlock::updateFirstLetterStyle(RenderElement* firstLetterBlock, RenderObject* currentChild)
    3173 {
    3174     RenderElement* firstLetter = currentChild->parent();
    3175     RenderElement* firstLetterContainer = firstLetter->parent();
    3176     auto pseudoStyle = styleForFirstLetter(*firstLetterBlock, *firstLetterContainer);
    3177     ASSERT(firstLetter->isFloating() || firstLetter->isInline());
    3178 
    3179     if (Style::determineChange(firstLetter->style(), pseudoStyle) == Style::Detach) {
    3180         // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
    3181         RenderBoxModelObject* newFirstLetter;
    3182         if (pseudoStyle.display() == INLINE)
    3183             newFirstLetter = new RenderInline(document(), WTFMove(pseudoStyle));
    3184         else
    3185             newFirstLetter = new RenderBlockFlow(document(), WTFMove(pseudoStyle));
    3186         newFirstLetter->initializeStyle();
    3187 
    3188         // Move the first letter into the new renderer.
    3189         LayoutStateDisabler layoutStateDisabler(view());
    3190         while (RenderObject* child = firstLetter->firstChild()) {
    3191             if (is<RenderText>(*child))
    3192                 downcast<RenderText>(*child).removeAndDestroyTextBoxes();
    3193             firstLetter->removeChild(*child);
    3194             newFirstLetter->addChild(child, nullptr);
    3195         }
    3196 
    3197         RenderObject* nextSibling = firstLetter->nextSibling();
    3198         if (RenderTextFragment* remainingText = downcast<RenderBoxModelObject>(*firstLetter).firstLetterRemainingText()) {
    3199             ASSERT(remainingText->isAnonymous() || remainingText->textNode()->renderer() == remainingText);
    3200             // Replace the old renderer with the new one.
    3201             remainingText->setFirstLetter(*newFirstLetter);
    3202             newFirstLetter->setFirstLetterRemainingText(remainingText);
    3203         }
    3204         // To prevent removal of single anonymous block in RenderBlock::removeChild and causing
    3205         // |nextSibling| to go stale, we remove the old first letter using removeChildNode first.
    3206         firstLetterContainer->removeChildInternal(*firstLetter, NotifyChildren);
    3207         firstLetter->destroy();
    3208         firstLetter = newFirstLetter;
    3209         firstLetterContainer->addChild(firstLetter, nextSibling);
    3210     } else
    3211         firstLetter->setStyle(WTFMove(pseudoStyle));
    3212 }
    3213 
    3214 void RenderBlock::createFirstLetterRenderer(RenderElement* firstLetterBlock, RenderText* currentTextChild)
    3215 {
    3216     RenderElement* firstLetterContainer = currentTextChild->parent();
    3217     auto pseudoStyle = styleForFirstLetter(*firstLetterBlock, *firstLetterContainer);
    3218     RenderBoxModelObject* firstLetter = nullptr;
    3219     if (pseudoStyle.display() == INLINE)
    3220         firstLetter = new RenderInline(document(), WTFMove(pseudoStyle));
    3221     else
    3222         firstLetter = new RenderBlockFlow(document(), WTFMove(pseudoStyle));
    3223     firstLetter->initializeStyle();
    3224     firstLetterContainer->addChild(firstLetter, currentTextChild);
    3225 
    3226     // The original string is going to be either a generated content string or a DOM node's
    3227     // string.  We want the original string before it got transformed in case first-letter has
    3228     // no text-transform or a different text-transform applied to it.
    3229     String oldText = currentTextChild->originalText();
    3230     ASSERT(!oldText.isNull());
    3231 
    3232     if (!oldText.isEmpty()) {
    3233         unsigned length = 0;
    3234 
    3235         // Account for leading spaces and punctuation.
    3236         while (length < oldText.length() && shouldSkipForFirstLetter(oldText[length]))
    3237             length++;
    3238 
    3239         // Account for first grapheme cluster.
    3240         length += numCharactersInGraphemeClusters(StringView(oldText).substring(length), 1);
    3241        
    3242         // Keep looking for whitespace and allowed punctuation, but avoid
    3243         // accumulating just whitespace into the :first-letter.
    3244         for (unsigned scanLength = length; scanLength < oldText.length(); ++scanLength) {
    3245             UChar c = oldText[scanLength];
    3246            
    3247             if (!shouldSkipForFirstLetter(c))
    3248                 break;
    3249 
    3250             if (isPunctuationForFirstLetter(c))
    3251                 length = scanLength + 1;
    3252          }
    3253          
    3254         // Construct a text fragment for the text after the first letter.
    3255         // This text fragment might be empty.
    3256         RenderTextFragment* remainingText;
    3257         if (currentTextChild->textNode())
    3258             remainingText = new RenderTextFragment(*currentTextChild->textNode(), oldText, length, oldText.length() - length);
    3259         else
    3260             remainingText = new RenderTextFragment(document(), oldText, length, oldText.length() - length);
    3261 
    3262         if (remainingText->textNode())
    3263             remainingText->textNode()->setRenderer(remainingText);
    3264 
    3265         firstLetterContainer->addChild(remainingText, currentTextChild);
    3266         firstLetterContainer->removeChild(*currentTextChild);
    3267         remainingText->setFirstLetter(*firstLetter);
    3268         firstLetter->setFirstLetterRemainingText(remainingText);
    3269        
    3270         // construct text fragment for the first letter
    3271         RenderTextFragment* letter;
    3272         if (remainingText->textNode())
    3273             letter = new RenderTextFragment(*remainingText->textNode(), oldText, 0, length);
    3274         else
    3275             letter = new RenderTextFragment(document(), oldText, 0, length);
    3276 
    3277         firstLetter->addChild(letter);
    3278 
    3279         currentTextChild->destroy();
    3280     }
    3281 }
    3282    
    32833108void RenderBlock::getFirstLetter(RenderObject*& firstLetter, RenderElement*& firstLetterContainer, RenderObject* skipObject)
    32843109{
     
    33343159    if (!firstLetter)
    33353160        firstLetterContainer = nullptr;
    3336 }
    3337 
    3338 void RenderBlock::updateFirstLetter()
    3339 {
    3340     ASSERT_WITH_SECURITY_IMPLICATION(!view().layoutState());
    3341 
    3342     RenderObject* firstLetterObj;
    3343     RenderElement* firstLetterContainer;
    3344     // FIXME: The first letter might be composed of a variety of code units, and therefore might
    3345     // be contained within multiple RenderElements.
    3346     getFirstLetter(firstLetterObj, firstLetterContainer);
    3347 
    3348     if (!firstLetterObj || !firstLetterContainer)
    3349         return;
    3350 
    3351     // If the child already has style, then it has already been created, so we just want
    3352     // to update it.
    3353     if (firstLetterObj->parent()->style().styleType() == FIRST_LETTER) {
    3354         updateFirstLetterStyle(firstLetterContainer, firstLetterObj);
    3355         return;
    3356     }
    3357 
    3358     if (!is<RenderText>(*firstLetterObj))
    3359         return;
    3360 
    3361     createFirstLetterRenderer(firstLetterContainer, downcast<RenderText>(firstLetterObj));
    33623161}
    33633162
  • trunk/Source/WebCore/rendering/RenderBlock.h

    r220646 r220795  
    264264    LayoutUnit collapsedMarginAfterForChild(const RenderBox& child) const;
    265265
    266     virtual void updateFirstLetter();
    267266    void getFirstLetter(RenderObject*& firstLetter, RenderElement*& firstLetterContainer, RenderObject* skipObject = nullptr);
    268267
     
    455454    virtual bool childrenPreventSelfCollapsing() const;
    456455   
    457     void createFirstLetterRenderer(RenderElement* firstLetterBlock, RenderText* currentTextChild);
    458     void updateFirstLetterStyle(RenderElement* firstLetterBlock, RenderObject* firstLetterContainer);
    459 
    460456    Node* nodeForHitTest() const;
    461457
  • trunk/Source/WebCore/rendering/RenderRubyRun.cpp

    r220646 r220795  
    100100{
    101101    return 0;
    102 }
    103 
    104 void RenderRubyRun::updateFirstLetter()
    105 {
    106102}
    107103
  • trunk/Source/WebCore/rendering/RenderRubyRun.h

    r220646 r220795  
    6161
    6262    RenderBlock* firstLineBlock() const override;
    63     void updateFirstLetter() override;
    6463
    6564    void getOverhang(bool firstLine, RenderObject* startRenderer, RenderObject* endRenderer, float& startOverhang, float& endOverhang) const;
  • trunk/Source/WebCore/rendering/RenderTable.cpp

    r220646 r220795  
    14861486}
    14871487
    1488 void RenderTable::updateFirstLetter()
    1489 {
    1490 }
    1491 
    14921488int RenderTable::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
    14931489{
  • trunk/Source/WebCore/rendering/RenderTable.h

    r220646 r220795  
    303303
    304304    RenderBlock* firstLineBlock() const final;
    305     void updateFirstLetter() final;
    306305   
    307306    void updateLogicalWidth() final;
  • trunk/Source/WebCore/rendering/TextAutoSizing.cpp

    r220685 r220795  
    3737#include "RenderText.h"
    3838#include "RenderTextFragment.h"
     39#include "RenderTreeUpdaterFirstLetter.h"
    3940#include "StyleResolver.h"
    4041
     
    158159    }
    159160
    160     // FIXME: All render tree mutations should be done via RenderTreeUpdater.
    161161    for (auto& node : m_autoSizedNodes) {
    162162        auto& textRenderer = *node->renderer();
     
    166166        if (!block)
    167167            continue;
    168         block->updateFirstLetter();
     168        // FIXME: All render tree mutations should be done by RenderTreeUpdater commit.
     169        RenderTreeUpdater::FirstLetter::update(*block);
    169170    }
    170171
  • trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp

    r220646 r220795  
    543543}
    544544
    545 // Fix for <rdar://problem/8048875>. We should not render :first-letter CSS Style
    546 // in a SVG text element context.
    547 void RenderSVGText::updateFirstLetter()
    548 {
    549 }
    550 
    551 }
     545}
  • trunk/Source/WebCore/rendering/svg/RenderSVGText.h

    r220646 r220795  
    9292
    9393    RenderBlock* firstLineBlock() const override;
    94     void updateFirstLetter() override;
    9594
    9695    bool shouldHandleSubtreeMutations() const;
  • trunk/Source/WebCore/style/RenderTreeUpdater.cpp

    r220646 r220795  
    4242#include "RenderNamedFlowThread.h"
    4343#include "RenderQuote.h"
     44#include "RenderTreeUpdaterFirstLetter.h"
    4445#include "StyleResolver.h"
    4546#include "StyleTreeResolver.h"
     
    235236        auto* renderer = parent.element->renderer();
    236237        if (is<RenderBlock>(renderer))
    237             downcast<RenderBlock>(*renderer).updateFirstLetter();
     238            FirstLetter::update(downcast<RenderBlock>(*renderer));
    238239
    239240        if (parent.element->hasCustomStyleResolveCallbacks() && parent.styleChange == Style::Detach && renderer)
  • trunk/Source/WebCore/style/RenderTreeUpdater.h

    r220594 r220795  
    5252    static void tearDownRenderer(Text&);
    5353
     54    class FirstLetter;
     55
    5456private:
    5557    void updateRenderTree(ContainerNode& root);
Note: See TracChangeset for help on using the changeset viewer.