[CSS Grid Layout] Upgrade align-self and align-items parsing to CSS 3
[WebKit-https.git] / Source / WebCore / rendering / mathml / RenderMathMLScripts.cpp
1 /*
2  * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
3  * Copyright (C) 2013 The MathJax Consortium.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28
29 #if ENABLE(MATHML)
30
31 #include "RenderMathMLScripts.h"
32
33 #include "MathMLElement.h"
34
35 namespace WebCore {
36     
37 using namespace MathMLNames;
38
39 // RenderMathMLScripts implements various MathML elements drawing scripts attached to a base. For valid MathML elements, the structure of the render tree should be:
40 //
41 // - msub, msup, msubsup: BaseWrapper SubSupPairWrapper
42 // - mmultiscripts: BaseWrapper SubSupPairWrapper* (mprescripts SubSupPairWrapper*)*
43 //
44 // where BaseWrapper and SubSupPairWrapper do not contain any <mprescripts/> children. In addition, BaseWrapper must have one child and SubSupPairWrapper must have either one child (msub, msup) or two children (msubsup, mmultiscripts).
45 //
46 // In order to accept invalid markup and to handle the script elements consistently and uniformly, we will use a more general structure that encompasses both valid and invalid elements:
47 //
48 // BaseWrapper SubSupPairWrapper* (mprescripts SubSupPairWrapper*)*
49 //
50 // where BaseWrapper can now be empty and SubSupPairWrapper can now have one or two elements.
51 //
52
53 static bool isPrescript(RenderObject* renderObject)
54 {
55     ASSERT(renderObject);
56     return renderObject->node() && renderObject->node()->hasTagName(MathMLNames::mprescriptsTag);
57 }
58
59 RenderMathMLScripts::RenderMathMLScripts(Element& element, PassRef<RenderStyle> style)
60     : RenderMathMLBlock(element, WTF::move(style))
61     , m_baseWrapper(0)
62 {
63     // Determine what kind of sub/sup expression we have by element name
64     if (element.hasTagName(MathMLNames::msubTag))
65         m_kind = Sub;
66     else if (element.hasTagName(MathMLNames::msupTag))
67         m_kind = Super;
68     else if (element.hasTagName(MathMLNames::msubsupTag))
69         m_kind = SubSup;
70     else {
71         ASSERT(element.hasTagName(MathMLNames::mmultiscriptsTag));
72         m_kind = Multiscripts;
73     }
74 }
75
76 RenderBoxModelObject* RenderMathMLScripts::base() const
77 {
78     if (!m_baseWrapper)
79         return nullptr;
80     RenderObject* base = m_baseWrapper->firstChild();
81     if (!is<RenderBoxModelObject>(base))
82         return nullptr;
83     return downcast<RenderBoxModelObject>(base);
84 }
85
86 void RenderMathMLScripts::fixAnonymousStyleForSubSupPair(RenderObject* subSupPair, bool isPostScript)
87 {
88     ASSERT(subSupPair && subSupPair->style().refCount() == 1);
89     RenderStyle& scriptsStyle = subSupPair->style();
90
91     // subSup pairs are drawn in column from bottom (subscript) to top (superscript).
92     scriptsStyle.setFlexDirection(FlowColumnReverse);
93
94     // The MathML specification does not specify horizontal alignment of
95     // scripts. We align the bottom (respectively top) edge of the subscript
96     // (respectively superscript) with the bottom (respectively top) edge of
97     // the flex container. Note that for valid <msub> and <msup> elements, the
98     // subSupPair should actually have only one script.
99     scriptsStyle.setJustifyContent(m_kind == Sub ? JustifyFlexStart : m_kind == Super ? JustifyFlexEnd : JustifySpaceBetween);
100
101     // The MathML specification does not specify vertical alignment of scripts.
102     // Let's right align prescripts and left align postscripts.
103     // See http://lists.w3.org/Archives/Public/www-math/2012Aug/0006.html
104     scriptsStyle.setAlignItems(isPostScript ? ItemPositionFlexStart : ItemPositionFlexEnd);
105
106     // We set the order property so that the prescripts are drawn before the base.
107     scriptsStyle.setOrder(isPostScript ? 0 : -1);
108
109     // We set this wrapper's font-size for its line-height.
110     LayoutUnit scriptSize = static_cast<int>(0.75 * style().fontSize());
111     scriptsStyle.setFontSize(scriptSize);
112 }
113
114 void RenderMathMLScripts::fixAnonymousStyles()
115 {
116     // We set the base wrapper's style so that baseHeight in layout() will be an unstretched height.
117     ASSERT(m_baseWrapper && m_baseWrapper->style().hasOneRef());
118     m_baseWrapper->style().setAlignSelf(ItemPositionFlexStart);
119
120     // This sets the style for postscript pairs.
121     RenderObject* subSupPair = m_baseWrapper;
122     for (subSupPair = subSupPair->nextSibling(); subSupPair && !isPrescript(subSupPair); subSupPair = subSupPair->nextSibling())
123         fixAnonymousStyleForSubSupPair(subSupPair, true);
124
125     if (subSupPair && m_kind == Multiscripts) {
126         // This sets the style for prescript pairs.
127         for (subSupPair = subSupPair->nextSibling(); subSupPair && !isPrescript(subSupPair); subSupPair = subSupPair->nextSibling())
128             fixAnonymousStyleForSubSupPair(subSupPair, false);
129     }
130
131     // This resets style for extra subSup pairs.
132     for (; subSupPair; subSupPair = subSupPair->nextSibling()) {
133         if (!isPrescript(subSupPair)) {
134             ASSERT(subSupPair && subSupPair->style().refCount() == 1);
135             RenderStyle& scriptsStyle = subSupPair->style();
136             scriptsStyle.setFlexDirection(FlowRow);
137             scriptsStyle.setJustifyContent(JustifyFlexStart);
138             scriptsStyle.setAlignItems(ItemPositionCenter);
139             scriptsStyle.setOrder(0);
140             scriptsStyle.setFontSize(style().fontSize());
141         }
142     }
143 }
144
145 void RenderMathMLScripts::addChildInternal(bool doNotRestructure, RenderObject* child, RenderObject* beforeChild)
146 {
147     if (doNotRestructure) {
148         RenderMathMLBlock::addChild(child, beforeChild);
149         return;
150     }
151
152     if (beforeChild) {
153         // beforeChild may be a grandchild, so we call the addChild function of the corresponding wrapper instead.
154         RenderObject* parent = beforeChild->parent();
155         if (parent != this) {
156             RenderMathMLBlock& parentBlock = downcast<RenderMathMLBlock>(*parent);
157             if (is<RenderMathMLScriptsWrapper>(parentBlock)) {
158                 RenderMathMLScriptsWrapper& wrapper = downcast<RenderMathMLScriptsWrapper>(parentBlock);
159                 wrapper.addChildInternal(false, child, beforeChild);
160                 return;
161             }
162         }
163     }
164
165     if (beforeChild == m_baseWrapper) {
166         // This is like inserting the child at the beginning of the base wrapper.
167         m_baseWrapper->addChildInternal(false, child, m_baseWrapper->firstChild());
168         return;
169     }
170     
171     if (isPrescript(child)) {
172         // The new child becomes an <mprescripts/> separator.
173         RenderMathMLBlock::addChild(child, beforeChild);
174         return;
175     }
176
177     if (!beforeChild || isPrescript(beforeChild)) {
178         // We are at the end of a sequence of subSup pairs.
179         RenderMathMLBlock* previousSibling = downcast<RenderMathMLBlock>(beforeChild ? beforeChild->previousSibling() : lastChild());
180         if (is<RenderMathMLScriptsWrapper>(previousSibling)) {
181             RenderMathMLScriptsWrapper& wrapper = downcast<RenderMathMLScriptsWrapper>(*previousSibling);
182             if ((wrapper.m_kind == RenderMathMLScriptsWrapper::Base && wrapper.isEmpty()) || (wrapper.m_kind == RenderMathMLScriptsWrapper::SubSupPair && !wrapper.firstChild()->nextSibling())) {
183                 // The previous sibling is either an empty base or a SubSup pair with a single child so we can insert the new child into that wrapper.
184                 wrapper.addChildInternal(true, child);
185                 return;
186             }
187         }
188         // Otherwise we create a new subSupPair to store the new child.
189         RenderMathMLScriptsWrapper* subSupPair = RenderMathMLScriptsWrapper::createAnonymousWrapper(this, RenderMathMLScriptsWrapper::SubSupPair);
190         subSupPair->addChildInternal(true, child);
191         RenderMathMLBlock::addChild(subSupPair, beforeChild);
192         return;
193     }
194
195     // beforeChild is a subSup pair. This is like inserting the new child at the beginning of the subSup wrapper.
196     RenderMathMLScriptsWrapper& wrapper = downcast<RenderMathMLScriptsWrapper>(*beforeChild);
197     ASSERT(wrapper.m_kind == RenderMathMLScriptsWrapper::SubSupPair);
198     ASSERT(!(m_baseWrapper->isEmpty() && m_baseWrapper->nextSibling() == beforeChild));
199     wrapper.addChildInternal(false, child, wrapper.firstChild());
200 }
201
202 RenderObject* RenderMathMLScripts::removeChildInternal(bool doNotRestructure, RenderObject& child)
203 {
204     if (doNotRestructure)
205         return RenderMathMLBlock::removeChild(child);
206
207     ASSERT(isPrescript(&child));
208
209     RenderObject* previousSibling = child.previousSibling();
210     RenderObject* nextSibling = child.nextSibling();
211     ASSERT(previousSibling);
212
213     if (nextSibling && !isPrescript(previousSibling) && !isPrescript(nextSibling)) {
214         RenderMathMLScriptsWrapper& previousWrapper = downcast<RenderMathMLScriptsWrapper>(*previousSibling);
215         RenderMathMLScriptsWrapper& nextWrapper = downcast<RenderMathMLScriptsWrapper>(*nextSibling);
216         ASSERT(nextWrapper.m_kind == RenderMathMLScriptsWrapper::SubSupPair && !nextWrapper.isEmpty());
217         if ((previousWrapper.m_kind == RenderMathMLScriptsWrapper::Base && previousWrapper.isEmpty()) || (previousWrapper.m_kind == RenderMathMLScriptsWrapper::SubSupPair && !previousWrapper.firstChild()->nextSibling())) {
218             RenderObject* script = nextWrapper.firstChild();
219             nextWrapper.removeChildInternal(false, *script);
220             previousWrapper.addChildInternal(true, script);
221         }
222     }
223
224     return RenderMathMLBlock::removeChild(child);
225 }
226
227 void RenderMathMLScripts::addChild(RenderObject* child, RenderObject* beforeChild)
228 {
229     if (isEmpty()) {
230         m_baseWrapper = RenderMathMLScriptsWrapper::createAnonymousWrapper(this, RenderMathMLScriptsWrapper::Base);
231         RenderMathMLBlock::addChild(m_baseWrapper);
232     }
233
234     addChildInternal(false, child, beforeChild);
235
236     fixAnonymousStyles();
237 }
238
239 RenderObject* RenderMathMLScripts::removeChild(RenderObject& child)
240 {
241     if (beingDestroyed() || documentBeingDestroyed()) {
242         // The renderer is being destroyed so we remove the child normally.
243         return RenderMathMLBlock::removeChild(child);
244     }
245
246     RenderObject* next = removeChildInternal(false, child);
247     
248     fixAnonymousStyles();
249     
250     return next;
251 }
252
253 void RenderMathMLScripts::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
254 {
255     RenderMathMLBlock::styleDidChange(diff, oldStyle);
256     
257     if (!isEmpty())
258         fixAnonymousStyles();
259 }
260
261 RenderMathMLOperator* RenderMathMLScripts::unembellishedOperator()
262 {
263     RenderBoxModelObject* base = this->base();
264     if (!is<RenderMathMLBlock>(base))
265         return nullptr;
266     return downcast<RenderMathMLBlock>(*base).unembellishedOperator();
267 }
268
269 void RenderMathMLScripts::layout()
270 {
271     RenderMathMLBlock::layout();
272
273     if (!m_baseWrapper)
274         return;
275     RenderBox* base = m_baseWrapper->firstChildBox();
276     if (!base)
277         return;
278
279     // Our layout rules include: Don't let the superscript go below the "axis" (half x-height above the
280     // baseline), or the subscript above the axis. Also, don't let the superscript's top edge be
281     // below the base's top edge, or the subscript's bottom edge above the base's bottom edge.
282
283     LayoutUnit baseHeight = base->logicalHeight();
284     LayoutUnit baseBaseline = base->firstLineBaseline();
285     if (baseBaseline == -1)
286         baseBaseline = baseHeight;
287     LayoutUnit axis = style().fontMetrics().xHeight() / 2;
288     int fontSize = style().fontSize();
289
290     ASSERT(m_baseWrapper->style().hasOneRef());
291     bool needsSecondLayout = false;
292
293     LayoutUnit topPadding = 0;
294     LayoutUnit bottomPadding = 0;
295
296     Element* scriptElement = element();
297     LayoutUnit superscriptShiftValue = 0;
298     LayoutUnit subscriptShiftValue = 0;
299     if (m_kind == Sub || m_kind == SubSup || m_kind == Multiscripts)
300         parseMathMLLength(scriptElement->fastGetAttribute(MathMLNames::subscriptshiftAttr), subscriptShiftValue, &style(), false);
301     if (m_kind == Super || m_kind == SubSup || m_kind == Multiscripts)
302         parseMathMLLength(scriptElement->fastGetAttribute(MathMLNames::superscriptshiftAttr), superscriptShiftValue, &style(), false);
303
304     bool isPostScript = true;
305     RenderMathMLBlock* subSupPair = downcast<RenderMathMLBlock>(m_baseWrapper->nextSibling());
306     for (; subSupPair; subSupPair = downcast<RenderMathMLBlock>(subSupPair->nextSibling())) {
307
308         // We skip the base and <mprescripts/> elements.
309         if (isPrescript(subSupPair)) {
310             if (!isPostScript)
311                 break;
312             isPostScript = false;
313             continue;
314         }
315
316         if (RenderBox* superscript = m_kind == Sub ? 0 : subSupPair->lastChildBox()) {
317             LayoutUnit superscriptHeight = superscript->logicalHeight();
318             LayoutUnit superscriptBaseline = superscript->firstLineBaseline();
319             if (superscriptBaseline == -1)
320                 superscriptBaseline = superscriptHeight;
321             LayoutUnit minBaseline = std::max<LayoutUnit>(fontSize / 3 + 1 + superscriptBaseline, superscriptHeight + axis + superscriptShiftValue);
322
323             topPadding = std::max<LayoutUnit>(topPadding, minBaseline - baseBaseline);
324         }
325
326         if (RenderBox* subscript = m_kind == Super ? 0 : subSupPair->firstChildBox()) {
327             LayoutUnit subscriptHeight = subscript->logicalHeight();
328             LayoutUnit subscriptBaseline = subscript->firstLineBaseline();
329             if (subscriptBaseline == -1)
330                 subscriptBaseline = subscriptHeight;
331             LayoutUnit baseExtendUnderBaseline = baseHeight - baseBaseline;
332             LayoutUnit subscriptUnderItsBaseline = subscriptHeight - subscriptBaseline;
333             LayoutUnit minExtendUnderBaseline = std::max<LayoutUnit>(fontSize / 5 + 1 + subscriptUnderItsBaseline, subscriptHeight + subscriptShiftValue - axis);
334
335             bottomPadding = std::max<LayoutUnit>(bottomPadding, minExtendUnderBaseline - baseExtendUnderBaseline);
336         }
337     }
338
339     Length newPadding(topPadding, Fixed);
340     if (newPadding != m_baseWrapper->style().paddingTop()) {
341         m_baseWrapper->style().setPaddingTop(newPadding);
342         needsSecondLayout = true;
343     }
344
345     newPadding = Length(bottomPadding, Fixed);
346     if (newPadding != m_baseWrapper->style().paddingBottom()) {
347         m_baseWrapper->style().setPaddingBottom(newPadding);
348         needsSecondLayout = true;
349     }
350
351     if (!needsSecondLayout)
352         return;
353
354     setNeedsLayout(MarkOnlyThis);
355     m_baseWrapper->setChildNeedsLayout(MarkOnlyThis);
356
357     RenderMathMLBlock::layout();
358 }
359
360 int RenderMathMLScripts::firstLineBaseline() const
361 {
362     if (m_baseWrapper) {
363         LayoutUnit baseline = m_baseWrapper->firstLineBaseline();
364         if (baseline != -1)
365             return baseline;
366     }
367     return RenderMathMLBlock::firstLineBaseline();
368 }
369
370 RenderMathMLScriptsWrapper* RenderMathMLScriptsWrapper::createAnonymousWrapper(RenderMathMLScripts* renderObject, WrapperType type)
371 {
372     RenderMathMLScriptsWrapper* newBlock = new RenderMathMLScriptsWrapper(renderObject->document(), RenderStyle::createAnonymousStyleWithDisplay(&renderObject->style(), FLEX), type);
373     newBlock->initializeStyle();
374     return newBlock;
375 }
376
377 void RenderMathMLScriptsWrapper::addChildInternal(bool doNotRestructure, RenderObject* child, RenderObject* beforeChild)
378 {
379     if (doNotRestructure) {
380         RenderMathMLBlock::addChild(child, beforeChild);
381         return;
382     }
383
384     RenderMathMLScripts* parentNode = downcast<RenderMathMLScripts>(parent());
385
386     if (m_kind == Base) {
387         RenderObject* sibling = nextSibling();
388
389         if (!isEmpty() && !beforeChild) {
390             // This is like inserting the child after the base wrapper.
391             parentNode->addChildInternal(false, sibling);
392             return;
393         }
394
395         // The old base (if any) becomes a script ; the new child becomes either the base or an <mprescripts> separator.
396         RenderObject* oldBase = firstChild();
397         if (oldBase)
398             RenderMathMLBlock::removeChild(*oldBase);
399         if (isPrescript(child))
400             parentNode->addChildInternal(true, child, sibling);
401         else
402             RenderMathMLBlock::addChild(child);
403         if (oldBase)
404             parentNode->addChildInternal(false, oldBase, sibling);
405         return;
406     }
407
408     if (isPrescript(child)) {
409         // We insert an <mprescripts> element.
410         if (!beforeChild)
411             parentNode->addChildInternal(true, child, nextSibling());
412         else if (beforeChild == firstChild())
413             parentNode->addChildInternal(true, child, this);
414         else {
415             // We insert the <mprescripts> in the middle of a subSup pair so we must split that pair.
416             RenderObject* sibling = nextSibling();
417             parentNode->removeChildInternal(true, *this);
418             parentNode->addChildInternal(true, child, sibling);
419
420             RenderObject* script = firstChild();
421             RenderMathMLBlock::removeChild(*script);
422             parentNode->addChildInternal(false, script, child);
423
424             script = beforeChild;
425             RenderMathMLBlock::removeChild(*script);
426             parentNode->addChildInternal(false, script, sibling);
427             destroy();
428         }
429         return;
430     }
431
432     // We first move to the last subSup pair in the curent sequence of scripts.
433     RenderMathMLScriptsWrapper* subSupPair = this;
434     while (subSupPair->nextSibling() && !isPrescript(subSupPair->nextSibling()))
435         subSupPair = downcast<RenderMathMLScriptsWrapper>(subSupPair->nextSibling());
436     if (subSupPair->firstChild()->nextSibling()) {
437         // The last pair has two children so we need to create a new pair to leave room for the new child.
438         RenderMathMLScriptsWrapper* newPair = createAnonymousWrapper(parentNode, RenderMathMLScriptsWrapper::SubSupPair);
439         parentNode->addChildInternal(true, newPair, subSupPair->nextSibling());
440         subSupPair = newPair;
441     }
442
443     // We shift the successors in the current sequence of scripts.
444     for (RenderObject* previousSibling = subSupPair->previousSibling(); subSupPair != this; previousSibling = previousSibling->previousSibling()) {
445         RenderMathMLScriptsWrapper& previousSubSupPair = downcast<RenderMathMLScriptsWrapper>(*previousSibling);
446         RenderObject* script = previousSubSupPair.lastChild();
447         previousSubSupPair.removeChildInternal(true, *script);
448         subSupPair->addChildInternal(true, script, subSupPair->firstChild());
449         subSupPair = downcast<RenderMathMLScriptsWrapper>(previousSibling);
450     }
451
452     // This subSup pair now contain one element which is either beforeChild or the script that was before. Hence we can insert the new child before of after that element.
453     RenderMathMLBlock::addChild(child, firstChild() == beforeChild ? beforeChild : nullptr);
454 }
455
456 void RenderMathMLScriptsWrapper::addChild(RenderObject* child, RenderObject* beforeChild)
457 {
458     RenderMathMLScripts* parentNode = downcast<RenderMathMLScripts>(parent());
459
460     addChildInternal(false, child, beforeChild);
461
462     parentNode->fixAnonymousStyles();
463 }
464
465 RenderObject* RenderMathMLScriptsWrapper::removeChildInternal(bool doNotRestructure, RenderObject& child)
466 {
467     if (doNotRestructure)
468         return RenderMathMLBlock::removeChild(child);
469
470     RenderMathMLScripts* parentNode = downcast<RenderMathMLScripts>(parent());
471
472     if (m_kind == Base) {
473         // We remove the child from the base wrapper.
474         RenderObject* sibling = nextSibling();
475         RenderMathMLBlock::removeChild(child);
476         if (sibling && !isPrescript(sibling)) {
477             // If there are postscripts, the first one becomes the base.
478             RenderMathMLScriptsWrapper& wrapper = downcast<RenderMathMLScriptsWrapper>(*sibling);
479             RenderObject* script = wrapper.firstChild();
480             wrapper.removeChildInternal(false, *script);
481             RenderMathMLBlock::addChild(script);
482         }
483         return sibling;
484     }
485
486     // We remove the child and shift the successors in the current sequence of scripts.
487     RenderObject* next = RenderMathMLBlock::removeChild(child);
488     RenderMathMLScriptsWrapper* subSupPair = this;
489     for (RenderObject* nextSibling = subSupPair->nextSibling(); nextSibling && !isPrescript(nextSibling); nextSibling = nextSibling->nextSibling()) {
490         RenderMathMLScriptsWrapper& nextSubSupPair = downcast<RenderMathMLScriptsWrapper>(*nextSibling);
491         RenderObject* script = nextSubSupPair.firstChild();
492         nextSubSupPair.removeChildInternal(true, *script);
493         subSupPair->addChildInternal(true, script);
494         subSupPair = downcast<RenderMathMLScriptsWrapper>(nextSibling);
495     }
496
497     // We remove the last subSup pair if it became empty.
498     if (subSupPair->isEmpty()) {
499         parentNode->removeChildInternal(true, *subSupPair);
500         subSupPair->destroy();
501     }
502     
503     return next;
504 }
505
506 RenderObject* RenderMathMLScriptsWrapper::removeChild(RenderObject& child)
507 {
508     if (beingDestroyed() || documentBeingDestroyed()) {
509         // The renderer is being destroyed so we remove the child normally.
510         return RenderMathMLBlock::removeChild(child);
511     }
512
513     RenderMathMLScripts* parentNode = downcast<RenderMathMLScripts>(parent());
514     RenderObject* next = removeChildInternal(false, child);
515     parentNode->fixAnonymousStyles();
516     return next;
517 }
518
519 }    
520
521 #endif // ENABLE(MATHML)