Changeset 21199 in webkit
- Timestamp:
- Apr 30, 2007 9:57:01 PM (17 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 38 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r21197 r21199 1 2007-04-30 David Hyatt <hyatt@apple.com> 2 3 Fix for bug 12691, generated content and display: table-cell duplicates 4 content on a size change. Make sure that the code to update before/after 5 content is smart enough to drill into anonymous containers to find the 6 old child. 7 8 Reviewed by olliej 9 10 * fast/css-generated-content/table-cell-before-content-expected.checksum: Added. 11 * fast/css-generated-content/table-cell-before-content-expected.png: Added. 12 * fast/css-generated-content/table-cell-before-content-expected.txt: Added. 13 * fast/css-generated-content/table-cell-before-content.html: Added. 14 1 15 2007-04-30 Justin Garcia <justin.garcia@apple.com> 2 16 -
trunk/LayoutTests/fast/css-generated-content/001-expected.checksum
r11995 r21199 1 5a1eaea28a6f2f4ca9faf34688ac75da 1 15b6770648d6215032d82f7d7755edec -
trunk/LayoutTests/fast/css-generated-content/002-expected.checksum
r11995 r21199 1 cc56cbafef88b915896638711c3e0166 1 3901ed1eb917f31eae2277f53316f887 -
trunk/LayoutTests/fast/css-generated-content/003-expected.checksum
r11995 r21199 1 6401710e919a59aa2dd474045d93ed81 1 e9612bc16f0b8aedcfd4749d94ae18e9 -
trunk/LayoutTests/fast/css-generated-content/004-expected.checksum
r11995 r21199 1 6b2147cae934ab0955815266658cb106 1 e6c6d3479c831601d1c1dc01430801d0 -
trunk/LayoutTests/fast/css-generated-content/005-expected.checksum
r11995 r21199 1 7eabf69f016f7c563dfa8d7ab315593a 1 92627b6407dbabc4f7ff782a686f2a24 -
trunk/LayoutTests/fast/css-generated-content/007-expected.checksum
r11995 r21199 1 20bb3acec550791aa6a3810a2f72bb60 1 7fa9fc5a02fa37c9ca37366f0ce47abd -
trunk/LayoutTests/fast/css-generated-content/008-expected.checksum
r11995 r21199 1 e7aca4a190654692aecc5e5f5388af0e 1 3b77e2a9a460aeddd15d097029ad6698 -
trunk/LayoutTests/fast/css-generated-content/009-expected.checksum
r11995 r21199 1 75bfb31180db5277d80fcfeb39a536da 1 bc1d6919ef07a75401d1cd250bb84718 -
trunk/LayoutTests/fast/css-generated-content/010-expected.checksum
r11995 r21199 1 d87a201e85d4ba7a1d3febc802baa20a 1 168b63888f5bec1a3aa2e63a38a26c25 -
trunk/LayoutTests/fast/css-generated-content/011-expected.checksum
r11995 r21199 1 d3577b2d46a983bd9872421dd2864f7e 1 55f5141c12025f6bd82350297db678d2 -
trunk/LayoutTests/fast/css-generated-content/012-expected.checksum
r11995 r21199 1 e9a64955e6a9b4485e7171d716aa33df1 14366d3b8d0af4751ef359e32ff7ee2f -
trunk/LayoutTests/fast/css-generated-content/013-expected.checksum
r11995 r21199 1 453d3a89bbebe7fe37873dbd43547e5c 1 78b1143810da16f3b06435ab3b938942 -
trunk/LayoutTests/fast/css-generated-content/014-expected.checksum
r13919 r21199 1 785625e6023382e9f63997e162226949 1 2eee05608369dd32d5ca44ad5a6dc99f -
trunk/LayoutTests/fast/css-generated-content/015-expected.checksum
r12747 r21199 1 0f7715dd42d3616064574fd1175a1cb9 1 6c84d4e531cc58cf0794aa3ae772b5b6 -
trunk/LayoutTests/fast/css-generated-content/016-expected.checksum
r14687 r21199 1 66b165746887fabca725d7d58b42b908 1 5e53e8dd0bb2483830e0a603c14f0f37 -
trunk/LayoutTests/fast/css-generated-content/after-order-expected.checksum
r18559 r21199 1 ef6b13928c5d6d2384357727c9152247 1 f5642216213c99bd08bce08b6f86caf8 -
trunk/LayoutTests/fast/css-generated-content/hover-style-change-expected.checksum
r13919 r21199 1 dc9ef0cb912ab96f5ce37ae333cf258b 1 99111651f96e72284287db748b416250 -
trunk/LayoutTests/fast/css-generated-content/inline-display-types-expected.checksum
r18566 r21199 1 80f63779262971456417f3ec87bf30a9 1 0ccb2dcfa77e593bcb1b90f0604025e5 -
trunk/LayoutTests/fast/css-generated-content/inline-display-types-expected.txt
r18566 r21199 19 19 RenderText {#text} at (31,0) size 46x18 20 20 text run at (31,0) width 46: "content" 21 RenderBlock {DIV} at (0,94) size 784x18 22 RenderBlock (generated) at (0,0) size 31x18 23 RenderText at (0,0) size 31x18 24 text run at (0,0) width 31: "Test:" 25 RenderText {#text} at (31,0) size 46x18 26 text run at (31,0) width 46: "content" 27 RenderBlock {H1} at (0,133) size 784x37 21 RenderBlock {DIV} at (0,94) size 784x22 22 RenderTable at (0,0) size 31x18 23 RenderTableSection at (0,0) size 31x18 24 RenderTableRow at (0,0) size 31x18 25 RenderTableCell at (0,0) size 31x18 [r=0 c=0 rs=1 cs=1] 26 RenderText at (0,0) size 31x18 27 text run at (0,0) width 31: "Test:" 28 RenderText {#text} at (31,4) size 46x18 29 text run at (31,4) width 46: "content" 30 RenderBlock {H1} at (0,137) size 784x37 28 31 RenderText {#text} at (0,0) size 92x37 29 32 text run at (0,0) width 92: "Inlines" 30 RenderBlock (anonymous) at (0,19 1) size 784x5433 RenderBlock (anonymous) at (0,195) size 784x58 31 34 RenderInline {SPAN} at (0,0) size 81x18 32 35 RenderInline (generated) at (0,0) size 35x18 … … 44 47 RenderBR {BR} at (77,32) size 0x0 45 48 RenderInline {SPAN} at (0,0) size 77x18 46 RenderBlock (generated) at (0,36) size 31x18 47 RenderText at (0,0) size 31x18 48 text run at (0,0) width 31: "Test:" 49 RenderText {#text} at (31,36) size 46x18 50 text run at (31,36) width 46: "content" 51 RenderBR {BR} at (77,50) size 0x0 49 RenderTable at (0,36) size 31x18 50 RenderTableSection at (0,0) size 31x18 51 RenderTableRow at (0,0) size 31x18 52 RenderTableCell at (0,0) size 31x18 [r=0 c=0 rs=1 cs=1] 53 RenderText at (0,0) size 31x18 54 text run at (0,0) width 31: "Test:" 55 RenderText {#text} at (31,40) size 46x18 56 text run at (31,40) width 46: "content" 57 RenderBR {BR} at (77,54) size 0x0 -
trunk/LayoutTests/fast/css-generated-content/no-openclose-quote-expected.checksum
r12074 r21199 1 cc816742f1809da53c1ca6d1030286e6 1 9993d61a37b008206fcc3e6ae2301490 -
trunk/LayoutTests/fast/css-generated-content/spellingToolTip-assert-expected.checksum
r17642 r21199 1 67b18848c3f6ef8fe7c75052da11d6bd 1 76b632a5a1ecb009f28cefd6931b0ab5 -
trunk/WebCore/ChangeLog
r21198 r21199 1 2007-04-30 David Hyatt <hyatt@apple.com> 2 3 Fix for bug 12691, generated content and display: table-cell duplicates 4 content on a size change. Make sure that the code to update before/after 5 content is smart enough to drill into anonymous containers to find the 6 old child. 7 8 Reviewed by olliej 9 10 Added fast/css-generated-content/table-cell-before-content.html 11 12 * rendering/RenderBlock.cpp: 13 (WebCore::RenderBlock::setStyle): 14 * rendering/RenderButton.cpp: 15 (WebCore::RenderButton::updateBeforeAfterContent): 16 * rendering/RenderButton.h: 17 * rendering/RenderContainer.cpp: 18 (WebCore::RenderContainer::beforeAfterContainer): 19 (WebCore::RenderContainer::updateBeforeAfterContent): 20 (WebCore::RenderContainer::updateBeforeAfterContentForObject): 21 * rendering/RenderContainer.h: 22 * rendering/RenderInline.cpp: 23 (WebCore::RenderInline::setStyle): 24 (WebCore::RenderInline::addChildToFlow): 25 (WebCore::RenderInline::splitInlines): 26 1 27 2007-04-30 Jungshik Shin <jungshik.shin@gmail.com> 2 28 -
trunk/WebCore/rendering/RenderBlock.cpp
r21183 r21199 149 149 150 150 // Update pseudos for :before and :after now. 151 updatePseudoChild(RenderStyle::BEFORE); 152 updatePseudoChild(RenderStyle::AFTER); 153 } 154 155 static inline bool isAfterContent(RenderObject* child) 156 { 157 if (!child) 158 return false; 159 if (child->style()->styleType() != RenderStyle::AFTER) 160 return false; 161 // Text nodes don't have their own styles, so ignore the style on a text node. 162 if (child->isText() && !child->isBR()) 163 return false; 164 return true; 151 if (!isAnonymous()) { 152 updateBeforeAfterContent(RenderStyle::BEFORE); 153 updateBeforeAfterContent(RenderStyle::AFTER); 154 } 165 155 } 166 156 -
trunk/WebCore/rendering/RenderButton.cpp
r18819 r21199 101 101 } 102 102 103 void RenderButton::update PseudoChild(RenderStyle::PseudoId type)103 void RenderButton::updateBeforeAfterContent(RenderStyle::PseudoId type) 104 104 { 105 105 if (m_inner) 106 m_inner->update PseudoChildForObject(type, this);106 m_inner->updateBeforeAfterContentForContainer(type, this); 107 107 else 108 update PseudoChildForObject(type, this);108 updateBeforeAfterContentForContainer(type, this); 109 109 } 110 110 -
trunk/WebCore/rendering/RenderButton.h
r18819 r21199 45 45 virtual void updateFromElement(); 46 46 47 virtual void update PseudoChild(RenderStyle::PseudoId);47 virtual void updateBeforeAfterContent(RenderStyle::PseudoId); 48 48 49 49 virtual bool hasControlClip() const { return true; } -
trunk/WebCore/rendering/RenderContainer.cpp
r21183 r21199 232 232 } 233 233 234 RenderObject* RenderContainer:: pseudoChild(RenderStyle::PseudoId type) const234 RenderObject* RenderContainer::beforeAfterContainer(RenderStyle::PseudoId type) 235 235 { 236 236 if (type == RenderStyle::BEFORE) { 237 RenderObject* first = firstChild(); 238 while (first && first->isListMarker()) 239 first = first->nextSibling(); 237 RenderObject* first = this; 238 do { 239 // Skip list markers. 240 first = first->firstChild(); 241 while (first && first->isListMarker()) 242 first = first->nextSibling(); 243 } while (first && first->isAnonymous() && first->style()->styleType() == RenderStyle::NOPSEUDO); 244 if (first && first->style()->styleType() != type) 245 return 0; 240 246 return first; 241 247 } 242 if (type == RenderStyle::AFTER) 243 return lastChild(); 248 if (type == RenderStyle::AFTER) { 249 RenderObject* last = this; 250 do { 251 last = last->lastChild(); 252 } while (last && last->isAnonymous() && last->style()->styleType() == RenderStyle::NOPSEUDO && !last->isListMarker()); 253 if (last && last->style()->styleType() != type) 254 return 0; 255 return last; 256 } 244 257 245 258 ASSERT_NOT_REACHED(); … … 247 260 } 248 261 249 void RenderContainer::update PseudoChild(RenderStyle::PseudoId type)250 { 251 // If this is an anonymous wrapper, then parent applies its own pseudostyle to it.262 void RenderContainer::updateBeforeAfterContent(RenderStyle::PseudoId type) 263 { 264 // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it. 252 265 if (parent() && parent()->createsAnonymousWrapper()) 253 266 return; 254 update PseudoChildForObject(type, this);255 } 256 257 void RenderContainer::update PseudoChildForObject(RenderStyle::PseudoId type, RenderObject* styledObject)267 updateBeforeAfterContentForContainer(type, this); 268 } 269 270 void RenderContainer::updateBeforeAfterContentForContainer(RenderStyle::PseudoId type, RenderContainer* styledObject) 258 271 { 259 272 // In CSS2, before/after pseudo-content cannot nest. Check this first. … … 261 274 return; 262 275 263 RenderStyle* pseudo = styledObject->getPseudoStyle(type);264 RenderObject* child = pseudoChild(type);276 RenderStyle* pseudoElementStyle = styledObject->getPseudoStyle(type); 277 RenderObject* child = beforeAfterContainer(type); 265 278 266 279 // Whether or not we currently have generated content attached. 267 bool oldContentPresent = child && (child->style()->styleType() == type);280 bool oldContentPresent = child; 268 281 269 282 // Whether or not we now want generated content. 270 bool newContentWanted = pseudo && pseudo->display() != NONE;283 bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display() != NONE; 271 284 272 285 // For <q><p/></q>, if this object is the inline continuation of the <q>, we only want to generate … … 283 296 // identical to the new content data we want to build render objects for, then we nuke all 284 297 // of the old generated content. 285 if (!newContentWanted || (oldContentPresent && !child->style()->contentDataEquivalent(pseudo ))) {298 if (!newContentWanted || (oldContentPresent && !child->style()->contentDataEquivalent(pseudoElementStyle))) { 286 299 // Nuke the child. 287 300 if (child && child->style()->styleType() == type) { … … 292 305 } 293 306 294 // If we have no pseudo- style or if the pseudo's display type is NONE, then we307 // If we have no pseudo-element style or if the pseudo-element style's display type is NONE, then we 295 308 // have no generated content and can now return. 296 309 if (!newContentWanted) 297 310 return; 298 311 299 if (isInlineFlow() && !pseudo ->isDisplayInlineType())312 if (isInlineFlow() && !pseudoElementStyle->isDisplayInlineType()) 300 313 // According to the CSS2 spec (the end of section 12.1), the only allowed 301 314 // display values for the pseudo style are NONE and INLINE for inline flows. … … 303 316 // For now we at least relax the restriction to allow all inline types like inline-block 304 317 // and inline-table. 305 pseudo ->setDisplay(INLINE);318 pseudoElementStyle->setDisplay(INLINE); 306 319 307 320 if (oldContentPresent) { 308 321 if (child && child->style()->styleType() == type) { 309 322 // We have generated content present still. We want to walk this content and update our 310 // style information with the new pseudo style.311 child->setStyle(pseudo );323 // style information with the new pseudo-element style. 324 child->setStyle(pseudoElementStyle); 312 325 313 326 // Note that if we ever support additional types of generated content (which should be way off … … 315 328 for (RenderObject* genChild = child->firstChild(); genChild; genChild = genChild->nextSibling()) { 316 329 if (genChild->isText()) 317 // Generated text content is a child whose style also needs to be set to the pseudo style.318 genChild->setStyle(pseudo );330 // Generated text content is a child whose style also needs to be set to the pseudo-element style. 331 genChild->setStyle(pseudoElementStyle); 319 332 else { 320 333 // Images get an empty style that inherits from the pseudo. 321 334 RenderStyle* style = new (renderArena()) RenderStyle; 322 style->inheritFrom(pseudo );335 style->inheritFrom(pseudoElementStyle); 323 336 genChild->setStyle(style); 324 337 } … … 328 341 } 329 342 330 RenderObject* insertBefore = (type == RenderStyle::BEFORE) ? child: 0;343 RenderObject* insertBefore = (type == RenderStyle::BEFORE) ? firstChild() : 0; 331 344 332 345 // Generated content consists of a single container that houses multiple children (specified 333 // by the content property). This pseudo container gets the pseudostyle set on it.334 RenderObject* pseudoContainer = 0;346 // by the content property). This generated content container gets the pseudo-element style set on it. 347 RenderObject* generatedContentContainer = 0; 335 348 336 349 // Walk our list of generated content and create render objects for each. 337 for (const ContentData* content = pseudo ->contentData(); content; content = content->m_next) {350 for (const ContentData* content = pseudoElementStyle->contentData(); content; content = content->m_next) { 338 351 RenderObject* renderer = 0; 339 352 switch (content->m_type) { … … 342 355 case CONTENT_TEXT: 343 356 renderer = new (renderArena()) RenderTextFragment(document() /* anonymous object */, content->m_content.m_text); 344 renderer->setStyle(pseudo );357 renderer->setStyle(pseudoElementStyle); 345 358 break; 346 359 case CONTENT_OBJECT: … … 349 362 RenderImage* image = new (renderArena()) RenderImage(document()); // anonymous object 350 363 RenderStyle* style = new (renderArena()) RenderStyle; 351 style->inheritFrom(pseudo );364 style->inheritFrom(pseudoElementStyle); 352 365 image->setStyle(style); 353 366 image->setCachedImage(static_cast<CachedImage*>(resource)); … … 358 371 case CONTENT_COUNTER: 359 372 renderer = new (renderArena()) RenderCounter(document(), *content->m_content.m_counter); 360 renderer->setStyle(pseudo );373 renderer->setStyle(pseudoElementStyle); 361 374 break; 362 375 } 363 376 364 377 if (renderer) { 365 if (!pseudoContainer) 366 pseudoContainer = RenderFlow::createAnonymousFlow(document(), pseudo); // anonymous box 367 pseudoContainer->addChild(renderer); 378 if (!generatedContentContainer) { 379 // Make a generated box that might be any display type now that we are able to drill down into children 380 // to find the original content properly. 381 generatedContentContainer = RenderObject::createObject(document(), pseudoElementStyle); 382 generatedContentContainer->setStyle(pseudoElementStyle); 383 } 384 generatedContentContainer->addChild(renderer); 368 385 } 369 386 } … … 371 388 // Add the pseudo after we've installed all our content so that addChild will be able to find the text 372 389 // inside the inline for e.g., first-letter styling. 373 if (pseudoContainer) 374 addChild(pseudoContainer, insertBefore); 375 } 376 390 if (generatedContentContainer) 391 addChild(generatedContentContainer, insertBefore); 392 } 393 394 bool RenderContainer::isAfterContent(RenderObject* child) const 395 { 396 if (!child) 397 return false; 398 if (child->style()->styleType() != RenderStyle::AFTER) 399 return false; 400 // Text nodes don't have their own styles, so ignore the style on a text node. 401 if (child->isText() && !child->isBR()) 402 return false; 403 return true; 404 } 377 405 378 406 void RenderContainer::appendChildNode(RenderObject* newChild, bool fullAppend) -
trunk/WebCore/rendering/RenderContainer.h
r21093 r21199 55 55 virtual void removeLeftoverAnonymousBoxes(); 56 56 57 RenderObject* pseudoChild(RenderStyle::PseudoId) const; 58 virtual void updatePseudoChild(RenderStyle::PseudoId); 59 void updatePseudoChildForObject(RenderStyle::PseudoId, RenderObject*); 57 RenderObject* beforeAfterContainer(RenderStyle::PseudoId); 58 virtual void updateBeforeAfterContent(RenderStyle::PseudoId); 59 void updateBeforeAfterContentForContainer(RenderStyle::PseudoId, RenderContainer*); 60 bool isAfterContent(RenderObject* child) const; 60 61 61 62 virtual VisiblePosition positionForCoordinates(int x, int y); -
trunk/WebCore/rendering/RenderInline.cpp
r21093 r21199 67 67 68 68 // Update pseudos for :before and :after now. 69 updatePseudoChild(RenderStyle::BEFORE); 70 updatePseudoChild(RenderStyle::AFTER); 69 if (!isAnonymous()) { 70 updateBeforeAfterContent(RenderStyle::BEFORE); 71 updateBeforeAfterContent(RenderStyle::AFTER); 72 } 71 73 } 72 74 … … 109 111 110 112 // Someone may have put a <p> inside a <q>, causing a split. When this happens, the :after content 111 // has to move into the inline continuation. Call update PseudoChildto ensure that our :after113 // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that our :after 112 114 // content gets properly destroyed. 113 115 bool isLastChild = (beforeChild == lastChild()); 114 update PseudoChild(RenderStyle::AFTER);116 updateBeforeAfterContent(RenderStyle::AFTER); 115 117 if (isLastChild && beforeChild != lastChild()) 116 118 beforeChild = 0; // We destroyed the last child, so now we need to update our insertion … … 182 184 183 185 // Someone may have indirectly caused a <q> to split. When this happens, the :after content 184 // has to move into the inline continuation. Call update PseudoChildto ensure that the inline's :after186 // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that the inline's :after 185 187 // content gets properly destroyed. 186 curr->update PseudoChild(RenderStyle::AFTER);188 curr->updateBeforeAfterContent(RenderStyle::AFTER); 187 189 188 190 // Now we need to take all of the children starting from the first child -
trunk/WebCore/rendering/RenderObject.cpp
r21186 r21199 89 89 RenderObject* RenderObject::createObject(Node* node, RenderStyle* style) 90 90 { 91 RenderArena* arena = node->document()->renderArena(); 91 Document* doc = node->document(); 92 RenderArena* arena = doc->renderArena(); 92 93 93 94 // Minimal support for content properties replacing an entire element. … … 95 96 // Otherwise acts as if we didn't support this feature. 96 97 const ContentData* contentData = style->contentData(); 97 if (contentData && !contentData->m_next && contentData->m_type == CONTENT_OBJECT ) {98 if (contentData && !contentData->m_next && contentData->m_type == CONTENT_OBJECT && doc != node) { 98 99 RenderImage* image = new (arena) RenderImage(node); 99 100 image->setStyle(style); … … 736 737 { 737 738 if (isTableCell()) { 738 if (parent()) 739 return static_cast<const RenderTableCell*>(this)->table(); 739 const RenderTableCell* cell = static_cast<const RenderTableCell*>(this); 740 if (parent() && cell->section()) 741 return cell->table(); 740 742 return 0; 741 743 } -
trunk/WebCore/rendering/RenderTable.cpp
r21183 r21199 108 108 void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild) 109 109 { 110 // Make sure we don't append things after :after-generated content if we have it. 111 if (!beforeChild && isAfterContent(lastChild())) 112 beforeChild = lastChild(); 113 110 114 bool wrapInAnonymousSection = true; 111 115 bool isTableElement = element() && element()->hasTagName(tableTag); -
trunk/WebCore/rendering/RenderTableRow.cpp
r21183 r21199 65 65 void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild) 66 66 { 67 // Make sure we don't append things after :after-generated content if we have it. 68 if (!beforeChild && isAfterContent(lastChild())) 69 beforeChild = lastChild(); 70 67 71 bool isTableRow = element() && element()->hasTagName(trTag); 68 72 … … 103 107 RenderTableCell* cell = static_cast<RenderTableCell*>(child); 104 108 105 section()->addCell(cell, this); 109 // Generated content can result in us having a null section so make sure to null check our parent. 110 if (parent()) 111 section()->addCell(cell, this); 106 112 107 113 RenderContainer::addChild(cell, beforeChild); -
trunk/WebCore/rendering/RenderTableSection.cpp
r21183 r21199 94 94 void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild) 95 95 { 96 // Make sure we don't append things after :after-generated content if we have it. 97 if (!beforeChild && isAfterContent(lastChild())) 98 beforeChild = lastChild(); 99 96 100 bool isTableSection = element() && (element()->hasTagName(theadTag) || element()->hasTagName(tbodyTag) || element()->hasTagName(tfootTag)); 97 101
Note: See TracChangeset
for help on using the changeset viewer.