15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderRuby.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderRubyRun.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/style/RenderStyle.h" 3702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/RefPtr.h" 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//=== generic helper functions to avoid excessive code duplication === 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isAnonymousRubyInlineBlock(const RenderObject* object) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!object 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || !object->parent()->isRuby() 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || object->isRubyRun() 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || (object->isInline() && (object->isBeforeContent() || object->isAfterContent())) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) || (object->isAnonymous() && object->isRenderBlock() && object->style()->display() == INLINE_BLOCK)); 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return object 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && object->parent()->isRuby() 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && object->isRenderBlock() 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && !object->isRubyRun(); 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isRubyBeforeBlock(const RenderObject* object) 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isAnonymousRubyInlineBlock(object) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && !object->previousSibling() 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && object->firstChild() 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && object->firstChild()->style()->styleType() == BEFORE; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isRubyAfterBlock(const RenderObject* object) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isAnonymousRubyInlineBlock(object) 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && !object->nextSibling() 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && object->firstChild() 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && object->firstChild()->style()->styleType() == AFTER; 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RenderBlock* rubyBeforeBlock(const RenderObject* ruby) 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* child = ruby->firstChild(); 76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return isRubyBeforeBlock(child) ? toRenderBlock(child) : 0; 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RenderBlock* rubyAfterBlock(const RenderObject* ruby) 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* child = ruby->lastChild(); 82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return isRubyAfterBlock(child) ? toRenderBlock(child) : 0; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static RenderBlock* createAnonymousRubyInlineBlock(RenderObject* ruby) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(ruby->style(), INLINE_BLOCK); 88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) RenderBlock* newBlock = RenderBlock::createAnonymous(ruby->document()); 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newBlock->setStyle(newStyle.release()); 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newBlock; 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static RenderRubyRun* lastRubyRun(const RenderObject* ruby) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* child = ruby->lastChild(); 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child && !child->isRubyRun()) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) child = child->previousSibling(); 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!child || child->isRubyRun() || child->isBeforeContent() || child == rubyBeforeBlock(ruby)); 99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return child && child->isRubyRun() ? toRenderRubyRun(child) : 0; 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RenderRubyRun* findRubyRunParent(RenderObject* child) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (child && !child->isRubyRun()) 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) child = child->parent(); 106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return toRenderRubyRun(child); 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//=== ruby as inline object === 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)RenderRubyAsInline::RenderRubyAsInline(Element* element) 112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : RenderInline(element) 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderRubyAsInline::~RenderRubyAsInline() 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderRubyAsInline::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderInline::styleDidChange(diff, oldStyle); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) propagateStyleToAnonymousChildren(); 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Insert :before and :after content before/after the RenderRubyRun(s) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->isBeforeContent()) { 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->isInline()) { 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Add generated inline content normally 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderInline::addChild(child, firstChild()); 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Wrap non-inline content with an anonymous inline-block. 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* beforeBlock = rubyBeforeBlock(this); 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!beforeBlock) { 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) beforeBlock = createAnonymousRubyInlineBlock(this); 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderInline::addChild(beforeBlock, firstChild()); 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) beforeBlock->addChild(child); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->isAfterContent()) { 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->isInline()) { 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Add generated inline content normally 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderInline::addChild(child); 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Wrap non-inline content with an anonymous inline-block. 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* afterBlock = rubyAfterBlock(this); 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!afterBlock) { 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) afterBlock = createAnonymousRubyInlineBlock(this); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderInline::addChild(afterBlock); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) afterBlock->addChild(child); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the child is a ruby run, just add it normally. 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->isRubyRun()) { 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderInline::addChild(child, beforeChild); 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (beforeChild && !isAfterContent(beforeChild)) { 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // insert child into run 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!beforeChild->isRubyRun()); 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* run = beforeChild; 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (run && !run->isRubyRun()) 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run = run->parent(); 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (run) { 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run->addChild(child, beforeChild); 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent! 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Emergency fallback: fall through and just append. 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the new child would be appended, try to add the child to the previous run 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // if possible, or create a new run otherwise. 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // (The RenderRubyRun object will handle the details) 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyRun* lastRun = lastRubyRun(this); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!lastRun || lastRun->hasRubyText()) { 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastRun = RenderRubyRun::staticCreateRubyRun(this); 186926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) RenderInline::addChild(lastRun, beforeChild); 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastRun->addChild(child); 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderRubyAsInline::removeChild(RenderObject* child) 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the child's parent is *this (must be a ruby run or generated content or anonymous block), 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // just use the normal remove method. 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->parent() == this) { 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(child->isRubyRun() || child->isBeforeContent() || child->isAfterContent() || isAnonymousRubyInlineBlock(child)); 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderInline::removeChild(child); 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the child's parent is an anoymous block (must be generated :before/:after content) 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // just use the block's remove method. 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isAnonymousRubyInlineBlock(child->parent())) { 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(child->isBeforeContent() || child->isAfterContent()); 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) child->parent()->removeChild(child); 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) removeChild(child->parent()); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Otherwise find the containing run and remove it from there. 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyRun* run = findRubyRunParent(child); 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(run); 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run->removeChild(child); 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//=== ruby as block object === 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 217926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)RenderRubyAsBlock::RenderRubyAsBlock(Element* element) 218926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : RenderBlock(element) 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderRubyAsBlock::~RenderRubyAsBlock() 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderRubyAsBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock::styleDidChange(diff, oldStyle); 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) propagateStyleToAnonymousChildren(); 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild) 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Insert :before and :after content before/after the RenderRubyRun(s) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->isBeforeContent()) { 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->isInline()) { 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Add generated inline content normally 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock::addChild(child, firstChild()); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Wrap non-inline content with an anonymous inline-block. 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* beforeBlock = rubyBeforeBlock(this); 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!beforeBlock) { 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) beforeBlock = createAnonymousRubyInlineBlock(this); 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock::addChild(beforeBlock, firstChild()); 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) beforeBlock->addChild(child); 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->isAfterContent()) { 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->isInline()) { 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Add generated inline content normally 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock::addChild(child); 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Wrap non-inline content with an anonymous inline-block. 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* afterBlock = rubyAfterBlock(this); 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!afterBlock) { 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) afterBlock = createAnonymousRubyInlineBlock(this); 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock::addChild(afterBlock); 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) afterBlock->addChild(child); 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the child is a ruby run, just add it normally. 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->isRubyRun()) { 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock::addChild(child, beforeChild); 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (beforeChild && !isAfterContent(beforeChild)) { 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // insert child into run 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!beforeChild->isRubyRun()); 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* run = beforeChild; 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (run && !run->isRubyRun()) 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run = run->parent(); 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (run) { 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run->addChild(child, beforeChild); 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent! 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Emergency fallback: fall through and just append. 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the new child would be appended, try to add the child to the previous run 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // if possible, or create a new run otherwise. 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // (The RenderRubyRun object will handle the details) 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyRun* lastRun = lastRubyRun(this); 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!lastRun || lastRun->hasRubyText()) { 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastRun = RenderRubyRun::staticCreateRubyRun(this); 292926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) RenderBlock::addChild(lastRun, beforeChild); 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastRun->addChild(child); 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderRubyAsBlock::removeChild(RenderObject* child) 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the child's parent is *this (must be a ruby run or generated content or anonymous block), 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // just use the normal remove method. 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->parent() == this) { 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(child->isRubyRun() || child->isBeforeContent() || child->isAfterContent() || isAnonymousRubyInlineBlock(child)); 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock::removeChild(child); 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the child's parent is an anoymous block (must be generated :before/:after content) 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // just use the block's remove method. 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isAnonymousRubyInlineBlock(child->parent())) { 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(child->isBeforeContent() || child->isAfterContent()); 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) child->parent()->removeChild(child); 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) removeChild(child->parent()); 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Otherwise find the containing run and remove it from there. 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyRun* run = findRubyRunParent(child); 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(run); 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) run->removeChild(child); 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 322