// FIXME: It's cleaner to only call updateFromElement when an attribute has changed. The body of // this method should probably be moved to a private stretchHeightChanged or checkStretchHeight // method. Probably at the same time, addChild/removeChild methods should be made to work for // dynamic DOM changes. void RenderMathMLOperator::updateFromElement() { RenderElement* savedRenderer = element().renderer(); // Destroy our current children destroyLeftoverChildren(); // Since we share a node with our children, destroying our children may set our node's // renderer to 0, so we need to restore it. element().setRenderer(savedRenderer); RefPtr<RenderStyle> newStyle = RenderStyle::create(); newStyle->inheritFrom(style()); newStyle->setDisplay(FLEX); RenderMathMLBlock* container = new RenderMathMLBlock(element()); // This container doesn't offer any useful information to accessibility. container->setIgnoreInAccessibilityTree(true); container->setStyle(newStyle.release()); addChild(container); RenderText* text; if (m_operator) text = new RenderText(document(), String(&m_operator, 1)); else text = new RenderText(document(), element().textContent().replace(hyphenMinus, minusSign).impl()); // If we can't figure out the text, leave it blank. if (text) container->addChild(text); updateStyle(); setNeedsLayoutAndPrefWidthsRecalc(); }
RenderMathMLBlock* RenderMathMLBlock::createAnonymousMathMLBlock(EDisplay display) { RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), display); RenderMathMLBlock* newBlock = new (renderArena()) RenderMathMLBlock(0); newBlock->setDocumentForAnonymous(document()); newBlock->setStyle(newStyle.release()); return newBlock; }
void RenderMathMLSubSup::addChild(RenderObject* child, RenderObject* beforeChild) { // Note: The RenderMathMLBlock only allows element children to be added. Element* childElement = toElement(child->node()); if (childElement && !childElement->previousElementSibling()) { // Position 1 is always the base of the msub/msup/msubsup. RenderMathMLBlock* wrapper = new (renderArena()) RenderMathMLBlock(node()); RefPtr<RenderStyle> wrapperStyle = RenderStyle::create(); wrapperStyle->inheritFrom(style()); wrapperStyle->setDisplay(INLINE_BLOCK); wrapperStyle->setVerticalAlign(BASELINE); wrapper->setStyle(wrapperStyle.release()); RenderMathMLBlock::addChild(wrapper, firstChild()); wrapper->addChild(child); // Make sure we have a script block for rendering. if (m_kind == SubSup && !m_scripts) { m_scripts = new (renderArena()) RenderMathMLBlock(node()); RefPtr<RenderStyle> scriptsStyle = RenderStyle::create(); scriptsStyle->inheritFrom(style()); scriptsStyle->setDisplay(INLINE_BLOCK); scriptsStyle->setVerticalAlign(TOP); scriptsStyle->setMarginLeft(Length(gSubsupScriptMargin, Fixed)); scriptsStyle->setTextAlign(LEFT); // Set this wrapper's font-size for its line-height & baseline position. scriptsStyle->setBlendedFontSize(static_cast<int>(0.75 * style()->fontSize())); m_scripts->setStyle(scriptsStyle.release()); RenderMathMLBlock::addChild(m_scripts, beforeChild); } } else { if (m_kind == SubSup) { ASSERT(childElement); if (!childElement) return; RenderBlock* script = new (renderArena()) RenderMathMLBlock(node()); RefPtr<RenderStyle> scriptStyle = RenderStyle::create(); scriptStyle->inheritFrom(m_scripts->style()); scriptStyle->setDisplay(BLOCK); script->setStyle(scriptStyle.release()); // The order is always backwards so the first script is the subscript and the superscript // is last. That means the superscript is the first to render vertically. Element* previousSibling = childElement->previousElementSibling(); if (previousSibling && !previousSibling->previousElementSibling()) m_scripts->addChild(script); else m_scripts->addChild(script, m_scripts->firstChild()); script->addChild(child); } else RenderMathMLBlock::addChild(child, beforeChild); } }
void RenderMathMLUnderOver::addChild(RenderObject* child, RenderObject* beforeChild) { RenderMathMLBlock* row = new (renderArena()) RenderMathMLBlock(node()); RefPtr<RenderStyle> rowStyle = createBlockStyle(); row->setStyle(rowStyle.release()); row->setIsAnonymous(true); // look through the children for rendered elements counting the blocks so we know what child // we are adding int blocks = 0; RenderObject* current = this->firstChild(); while (current) { blocks++; current = current->nextSibling(); } switch (blocks) { case 0: // this is the base so just append it RenderBlock::addChild(row, beforeChild); break; case 1: // the under or over // FIXME: text-align: center does not work row->style()->setTextAlign(CENTER); if (m_kind == Over) { // add the over as first RenderBlock::addChild(row, firstChild()); } else { // add the under as last RenderBlock::addChild(row, beforeChild); } break; case 2: // the under or over // FIXME: text-align: center does not work row->style()->setTextAlign(CENTER); if (m_kind == UnderOver) { // add the over as first RenderBlock::addChild(row, firstChild()); } else { // we really shouldn't get here as only munderover should have three children RenderBlock::addChild(row, beforeChild); } break; default: // munderover shouldn't have more than three children. In theory we shouldn't // get here if the MathML is correctly formed, but that isn't a guarantee. // We will treat this as another under element and they'll get something funky. RenderBlock::addChild(row, beforeChild); } row->addChild(child); }
void RenderMathMLSubSup::addChild(RenderObject* child, RenderObject* beforeChild) { if (firstChild()) { // We already have a base, so this is the super/subscripts being added. if (m_kind == SubSup) { if (!m_scripts) { m_scripts = new (renderArena()) RenderMathMLBlock(node()); RefPtr<RenderStyle> scriptsStyle = RenderStyle::create(); scriptsStyle->inheritFrom(style()); scriptsStyle->setDisplay(INLINE_BLOCK); scriptsStyle->setVerticalAlign(MIDDLE); scriptsStyle->setMarginLeft(Length(gSubsupScriptMargin, Fixed)); scriptsStyle->setTextAlign(LEFT); m_scripts->setStyle(scriptsStyle.release()); RenderMathMLBlock::addChild(m_scripts, beforeChild); } RenderBlock* script = new (renderArena()) RenderMathMLBlock(node()); RefPtr<RenderStyle> scriptStyle = RenderStyle::create(); scriptStyle->inheritFrom(m_scripts->style()); scriptStyle->setDisplay(BLOCK); script->setStyle(scriptStyle.release()); m_scripts->addChild(script, m_scripts->firstChild()); script->addChild(child); } else RenderMathMLBlock::addChild(child, beforeChild); } else { RenderMathMLBlock* wrapper = new (renderArena()) RenderMathMLBlock(node()); RefPtr<RenderStyle> wrapperStyle = RenderStyle::create(); wrapperStyle->inheritFrom(style()); wrapperStyle->setDisplay(INLINE_BLOCK); wrapperStyle->setVerticalAlign(MIDDLE); wrapper->setStyle(wrapperStyle.release()); RenderMathMLBlock::addChild(wrapper, beforeChild); wrapper->addChild(child); } }