RenderMathMLScripts isPrescript() helper should take a reference.
[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(const RenderObject& renderObject)
54 {
55     return renderObject.node() && renderObject.node()->hasTagName(MathMLNames::mprescriptsTag);
56 }
57
58 RenderMathMLScripts::RenderMathMLScripts(Element& element, PassRef<RenderStyle> style)
59     : RenderMathMLBlock(element, WTF::move(style))
60     , m_baseWrapper(0)
61 {
62     // Determine what kind of sub/sup expression we have by element name
63     if (element.hasTagName(MathMLNames::msubTag))
64         m_kind = Sub;
65     else if (element.hasTagName(MathMLNames::msupTag))
66         m_kind = Super;
67     else if (element.hasTagName(MathMLNames::msubsupTag))
68         m_kind = SubSup;
69     else {
70         ASSERT(element.hasTagName(MathMLNames::mmultiscriptsTag));
71         m_kind = Multiscripts;
72     }
73 }
74
75 RenderBoxModelObject* RenderMathMLScripts::base() const
76 {
77     if (!m_baseWrapper)
78         return nullptr;
79     RenderObject* base = m_baseWrapper->firstChild();
80     if (!is<RenderBoxModelObject>(base))
81         return nullptr;
82     return downcast<RenderBoxModelObject>(base);
83 }
84
85 void RenderMathMLScripts::fixAnonymousStyleForSubSupPair(RenderObject* subSupPair, bool isPostScript)
86 {
87     ASSERT(subSupPair && subSupPair->style().refCount() == 1);
88     RenderStyle& scriptsStyle = subSupPair->style();
89
90     // subSup pairs are drawn in column from bottom (subscript) to top (superscript).
91     scriptsStyle.setFlexDirection(FlowColumnReverse);
92
93     // The MathML specification does not specify horizontal alignment of
94     // scripts. We align the bottom (respectively top) edge of the subscript
95     // (respectively superscript) with the bottom (respectively top) edge of
96     // the flex container. Note that for valid <msub> and <msup> elements, the
97     // subSupPair should actually have only one script.
98     scriptsStyle.setJustifyContent(m_kind == Sub ? JustifyFlexStart : m_kind == Super ? JustifyFlexEnd : JustifySpaceBetween);
99
100     // The MathML specification does not specify vertical alignment of scripts.
101     // Let's right align prescripts and left align postscripts.
102     // See http://lists.w3.org/Archives/Public/www-math/2012Aug/0006.html
103     scriptsStyle.setAlignItems(isPostScript ? AlignFlexStart : AlignFlexEnd);
104
105     // We set the order property so that the prescripts are drawn before the base.
106     scriptsStyle.setOrder(isPostScript ? 0 : -1);
107
108     // We set this wrapper's font-size for its line-height.
109     LayoutUnit scriptSize = static_cast<int>(0.75 * style().fontSize());
110     scriptsStyle.setFontSize(scriptSize);
111 }
112
113 void RenderMathMLScripts::fixAnonymousStyles()
114 {
115     // We set the base wrapper's style so that baseHeight in layout() will be an unstretched height.
116     ASSERT(m_baseWrapper && m_baseWrapper->style().hasOneRef());
117     m_baseWrapper->style().setAlignSelf(AlignFlexStart);
118
119     // This sets the style for postscript pairs.
120     RenderObject* subSupPair = m_baseWrapper;
121     for (subSupPair = subSupPair->nextSibling(); subSupPair && !isPrescript(*subSupPair); subSupPair = subSupPair->nextSibling())
122         fixAnonymousStyleForSubSupPair(subSupPair, true);
123
124     if (subSupPair && m_kind == Multiscripts) {
125         // This sets the style for prescript pairs.
126         for (subSupPair = subSupPair->nextSibling(); subSupPair && !isPrescript(*subSupPair); subSupPair = subSupPair->nextSibling())
127             fixAnonymousStyleForSubSupPair(subSupPair, false);
128     }
129
130     // This resets style for extra subSup pairs.
131     for (; subSupPair; subSupPair = subSupPair->nextSibling()) {
132         if (!isPrescript(*subSupPair)) {
133             ASSERT(subSupPair && subSupPair->style().refCount() == 1);
134             RenderStyle& scriptsStyle = subSupPair->style();
135             scriptsStyle.setFlexDirection(FlowRow);
136             scriptsStyle.setJustifyContent(JustifyFlexStart);
137             scriptsStyle.setAlignItems(AlignCenter);
138             scriptsStyle.setOrder(0);
139             scriptsStyle.setFontSize(style().fontSize());
140         }
141     }
142 }
143
144 void RenderMathMLScripts::addChildInternal(bool doNotRestructure, RenderObject* child, RenderObject* beforeChild)
145 {
146     if (doNotRestructure) {
147         RenderMathMLBlock::addChild(child, beforeChild);
148         return;
149     }
150
151     if (beforeChild) {
152         // beforeChild may be a grandchild, so we call the addChild function of the corresponding wrapper instead.
153         RenderObject* parent = beforeChild->parent();
154         if (parent != this) {
155             RenderMathMLBlock& parentBlock = downcast<RenderMathMLBlock>(*parent);
156             if (is<RenderMathMLScriptsWrapper>(parentBlock)) {
157                 RenderMathMLScriptsWrapper& wrapper = downcast<RenderMathMLScriptsWrapper>(parentBlock);
158                 wrapper.addChildInternal(false, child, beforeChild);
159                 return;
160             }
161         }
162     }
163
164     if (beforeChild == m_baseWrapper) {
165         // This is like inserting the child at the beginning of the base wrapper.
166         m_baseWrapper->addChildInternal(false, child, m_baseWrapper->firstChild());
167         return;
168     }
169     
170     if (isPrescript(*child)) {
171         // The new child becomes an <mprescripts/> separator.
172         RenderMathMLBlock::addChild(child, beforeChild);
173         return;
174     }
175
176     if (!beforeChild || isPrescript(*beforeChild)) {
177         // We are at the end of a sequence of subSup pairs.
178         RenderMathMLBlock* previousSibling = downcast<RenderMathMLBlock>(beforeChild ? beforeChild->previousSibling() : lastChild());
179         if (is<RenderMathMLScriptsWrapper>(previousSibling)) {
180             RenderMathMLScriptsWrapper& wrapper = downcast<RenderMathMLScriptsWrapper>(*previousSibling);
181             if ((wrapper.m_kind == RenderMathMLScriptsWrapper::Base && wrapper.isEmpty()) || (wrapper.m_kind == RenderMathMLScriptsWrapper::SubSupPair && !wrapper.firstChild()->nextSibling())) {
182                 // 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.
183                 wrapper.addChildInternal(true, child);
184                 return;
185             }
186         }
187         // Otherwise we create a new subSupPair to store the new child.
188         RenderMathMLScriptsWrapper* subSupPair = RenderMathMLScriptsWrapper::createAnonymousWrapper(this, RenderMathMLScriptsWrapper::SubSupPair);
189         subSupPair->addChildInternal(true, child);
190         RenderMathMLBlock::addChild(subSupPair, beforeChild);
191         return;
192     }
193
194     // beforeChild is a subSup pair. This is like inserting the new child at the beginning of the subSup wrapper.
195     RenderMathMLScriptsWrapper& wrapper = downcast<RenderMathMLScriptsWrapper>(*beforeChild);
196     ASSERT(wrapper.m_kind == RenderMathMLScriptsWrapper::SubSupPair);
197     ASSERT(!(m_baseWrapper->isEmpty() && m_baseWrapper->nextSibling() == beforeChild));
198     wrapper.addChildInternal(false, child, wrapper.firstChild());
199 }
200
201 RenderObject* RenderMathMLScripts::removeChildInternal(bool doNotRestructure, RenderObject& child)
202 {
203     if (doNotRestructure)
204         return RenderMathMLBlock::removeChild(child);
205
206     ASSERT(isPrescript(child));
207
208     RenderObject* previousSibling = child.previousSibling();
209     RenderObject* nextSibling = child.nextSibling();
210     ASSERT(previousSibling);
211
212     if (nextSibling && !isPrescript(*previousSibling) && !isPrescript(*nextSibling)) {
213         RenderMathMLScriptsWrapper& previousWrapper = downcast<RenderMathMLScriptsWrapper>(*previousSibling);
214         RenderMathMLScriptsWrapper& nextWrapper = downcast<RenderMathMLScriptsWrapper>(*nextSibling);
215         ASSERT(nextWrapper.m_kind == RenderMathMLScriptsWrapper::SubSupPair && !nextWrapper.isEmpty());
216         if ((previousWrapper.m_kind == RenderMathMLScriptsWrapper::Base && previousWrapper.isEmpty()) || (previousWrapper.m_kind == RenderMathMLScriptsWrapper::SubSupPair && !previousWrapper.firstChild()->nextSibling())) {
217             RenderObject* script = nextWrapper.firstChild();
218             nextWrapper.removeChildInternal(false, *script);
219             previousWrapper.addChildInternal(true, script);
220         }
221     }
222
223     return RenderMathMLBlock::removeChild(child);
224 }
225
226 void RenderMathMLScripts::addChild(RenderObject* child, RenderObject* beforeChild)
227 {
228     if (isEmpty()) {
229         m_baseWrapper = RenderMathMLScriptsWrapper::createAnonymousWrapper(this, RenderMathMLScriptsWrapper::Base);
230         RenderMathMLBlock::addChild(m_baseWrapper);
231     }
232
233     addChildInternal(false, child, beforeChild);
234
235     fixAnonymousStyles();
236 }
237
238 RenderObject* RenderMathMLScripts::removeChild(RenderObject& child)
239 {
240     if (beingDestroyed() || documentBeingDestroyed()) {
241         // The renderer is being destroyed so we remove the child normally.
242         return RenderMathMLBlock::removeChild(child);
243     }
244
245     RenderObject* next = removeChildInternal(false, child);
246     
247     fixAnonymousStyles();
248     
249     return next;
250 }
251
252 void RenderMathMLScripts::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
253 {
254     RenderMathMLBlock::styleDidChange(diff, oldStyle);
255     
256     if (!isEmpty())
257         fixAnonymousStyles();
258 }
259
260 RenderMathMLOperator* RenderMathMLScripts::unembellishedOperator()
261 {
262     RenderBoxModelObject* base = this->base();
263     if (!is<RenderMathMLBlock>(base))
264         return nullptr;
265     return downcast<RenderMathMLBlock>(*base).unembellishedOperator();
266 }
267
268 void RenderMathMLScripts::layout()
269 {
270     RenderMathMLBlock::layout();
271
272     if (!m_baseWrapper)
273         return;
274     RenderBox* base = m_baseWrapper->firstChildBox();
275     if (!base)
276         return;
277
278     // Our layout rules include: Don't let the superscript go below the "axis" (half x-height above the
279     // baseline), or the subscript above the axis. Also, don't let the superscript's top edge be
280     // below the base's top edge, or the subscript's bottom edge above the base's bottom edge.
281
282     LayoutUnit baseHeight = base->logicalHeight();
283     LayoutUnit baseBaseline = base->firstLineBaseline();
284     if (baseBaseline == -1)
285         baseBaseline = baseHeight;
286     LayoutUnit axis = style().fontMetrics().xHeight() / 2;
287     int fontSize = style().fontSize();
288
289     ASSERT(m_baseWrapper->style().hasOneRef());
290     bool needsSecondLayout = false;
291
292     LayoutUnit topPadding = 0;
293     LayoutUnit bottomPadding = 0;
294
295     Element* scriptElement = element();
296     LayoutUnit superscriptShiftValue = 0;
297     LayoutUnit subscriptShiftValue = 0;
298     if (m_kind == Sub || m_kind == SubSup || m_kind == Multiscripts)
299         parseMathMLLength(scriptElement->fastGetAttribute(MathMLNames::subscriptshiftAttr), subscriptShiftValue, &style(), false);
300     if (m_kind == Super || m_kind == SubSup || m_kind == Multiscripts)
301         parseMathMLLength(scriptElement->fastGetAttribute(MathMLNames::superscriptshiftAttr), superscriptShiftValue, &style(), false);
302
303     bool isPostScript = true;
304     RenderMathMLBlock* subSupPair = downcast<RenderMathMLBlock>(m_baseWrapper->nextSibling());
305     for (; subSupPair; subSupPair = downcast<RenderMathMLBlock>(subSupPair->nextSibling())) {
306
307         // We skip the base and <mprescripts/> elements.
308         if (isPrescript(*subSupPair)) {
309             if (!isPostScript)
310                 break;
311             isPostScript = false;
312             continue;
313         }
314
315         if (RenderBox* superscript = m_kind == Sub ? 0 : subSupPair->lastChildBox()) {
316             LayoutUnit superscriptHeight = superscript->logicalHeight();
317             LayoutUnit superscriptBaseline = superscript->firstLineBaseline();
318             if (superscriptBaseline == -1)
319                 superscriptBaseline = superscriptHeight;
320             LayoutUnit minBaseline = std::max<LayoutUnit>(fontSize / 3 + 1 + superscriptBaseline, superscriptHeight + axis + superscriptShiftValue);
321
322             topPadding = std::max<LayoutUnit>(topPadding, minBaseline - baseBaseline);
323         }
324
325         if (RenderBox* subscript = m_kind == Super ? 0 : subSupPair->firstChildBox()) {
326             LayoutUnit subscriptHeight = subscript->logicalHeight();
327             LayoutUnit subscriptBaseline = subscript->firstLineBaseline();
328             if (subscriptBaseline == -1)
329                 subscriptBaseline = subscriptHeight;
330             LayoutUnit baseExtendUnderBaseline = baseHeight - baseBaseline;
331             LayoutUnit subscriptUnderItsBaseline = subscriptHeight - subscriptBaseline;
332             LayoutUnit minExtendUnderBaseline = std::max<LayoutUnit>(fontSize / 5 + 1 + subscriptUnderItsBaseline, subscriptHeight + subscriptShiftValue - axis);
333
334             bottomPadding = std::max<LayoutUnit>(bottomPadding, minExtendUnderBaseline - baseExtendUnderBaseline);
335         }
336     }
337
338     Length newPadding(topPadding, Fixed);
339     if (newPadding != m_baseWrapper->style().paddingTop()) {
340         m_baseWrapper->style().setPaddingTop(newPadding);
341         needsSecondLayout = true;
342     }
343
344     newPadding = Length(bottomPadding, Fixed);
345     if (newPadding != m_baseWrapper->style().paddingBottom()) {
346         m_baseWrapper->style().setPaddingBottom(newPadding);
347         needsSecondLayout = true;
348     }
349
350     if (!needsSecondLayout)
351         return;
352
353     setNeedsLayout(MarkOnlyThis);
354     m_baseWrapper->setChildNeedsLayout(MarkOnlyThis);
355
356     RenderMathMLBlock::layout();
357 }
358
359 int RenderMathMLScripts::firstLineBaseline() const
360 {
361     if (m_baseWrapper) {
362         LayoutUnit baseline = m_baseWrapper->firstLineBaseline();
363         if (baseline != -1)
364             return baseline;
365     }
366     return RenderMathMLBlock::firstLineBaseline();
367 }
368
369 RenderMathMLScriptsWrapper* RenderMathMLScriptsWrapper::createAnonymousWrapper(RenderMathMLScripts* renderObject, WrapperType type)
370 {
371     RenderMathMLScriptsWrapper* newBlock = new RenderMathMLScriptsWrapper(renderObject->document(), RenderStyle::createAnonymousStyleWithDisplay(&renderObject->style(), FLEX), type);
372     newBlock->initializeStyle();
373     return newBlock;
374 }
375
376 void RenderMathMLScriptsWrapper::addChildInternal(bool doNotRestructure, RenderObject* child, RenderObject* beforeChild)
377 {
378     if (doNotRestructure) {
379         RenderMathMLBlock::addChild(child, beforeChild);
380         return;
381     }
382
383     RenderMathMLScripts* parentNode = downcast<RenderMathMLScripts>(parent());
384
385     if (m_kind == Base) {
386         RenderObject* sibling = nextSibling();
387
388         if (!isEmpty() && !beforeChild) {
389             // This is like inserting the child after the base wrapper.
390             parentNode->addChildInternal(false, sibling);
391             return;
392         }
393
394         // The old base (if any) becomes a script ; the new child becomes either the base or an <mprescripts> separator.
395         RenderObject* oldBase = firstChild();
396         if (oldBase)
397             RenderMathMLBlock::removeChild(*oldBase);
398         if (isPrescript(*child))
399             parentNode->addChildInternal(true, child, sibling);
400         else
401             RenderMathMLBlock::addChild(child);
402         if (oldBase)
403             parentNode->addChildInternal(false, oldBase, sibling);
404         return;
405     }
406
407     if (isPrescript(*child)) {
408         // We insert an <mprescripts> element.
409         if (!beforeChild)
410             parentNode->addChildInternal(true, child, nextSibling());
411         else if (beforeChild == firstChild())
412             parentNode->addChildInternal(true, child, this);
413         else {
414             // We insert the <mprescripts> in the middle of a subSup pair so we must split that pair.
415             RenderObject* sibling = nextSibling();
416             parentNode->removeChildInternal(true, *this);
417             parentNode->addChildInternal(true, child, sibling);
418
419             RenderObject* script = firstChild();
420             RenderMathMLBlock::removeChild(*script);
421             parentNode->addChildInternal(false, script, child);
422
423             script = beforeChild;
424             RenderMathMLBlock::removeChild(*script);
425             parentNode->addChildInternal(false, script, sibling);
426             destroy();
427         }
428         return;
429     }
430
431     // We first move to the last subSup pair in the curent sequence of scripts.
432     RenderMathMLScriptsWrapper* subSupPair = this;
433     while (subSupPair->nextSibling() && !isPrescript(*subSupPair->nextSibling()))
434         subSupPair = downcast<RenderMathMLScriptsWrapper>(subSupPair->nextSibling());
435     if (subSupPair->firstChild()->nextSibling()) {
436         // The last pair has two children so we need to create a new pair to leave room for the new child.
437         RenderMathMLScriptsWrapper* newPair = createAnonymousWrapper(parentNode, RenderMathMLScriptsWrapper::SubSupPair);
438         parentNode->addChildInternal(true, newPair, subSupPair->nextSibling());
439         subSupPair = newPair;
440     }
441
442     // We shift the successors in the current sequence of scripts.
443     for (RenderObject* previousSibling = subSupPair->previousSibling(); subSupPair != this; previousSibling = previousSibling->previousSibling()) {
444         RenderMathMLScriptsWrapper& previousSubSupPair = downcast<RenderMathMLScriptsWrapper>(*previousSibling);
445         RenderObject* script = previousSubSupPair.lastChild();
446         previousSubSupPair.removeChildInternal(true, *script);
447         subSupPair->addChildInternal(true, script, subSupPair->firstChild());
448         subSupPair = downcast<RenderMathMLScriptsWrapper>(previousSibling);
449     }
450
451     // 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.
452     RenderMathMLBlock::addChild(child, firstChild() == beforeChild ? beforeChild : nullptr);
453 }
454
455 void RenderMathMLScriptsWrapper::addChild(RenderObject* child, RenderObject* beforeChild)
456 {
457     RenderMathMLScripts* parentNode = downcast<RenderMathMLScripts>(parent());
458
459     addChildInternal(false, child, beforeChild);
460
461     parentNode->fixAnonymousStyles();
462 }
463
464 RenderObject* RenderMathMLScriptsWrapper::removeChildInternal(bool doNotRestructure, RenderObject& child)
465 {
466     if (doNotRestructure)
467         return RenderMathMLBlock::removeChild(child);
468
469     RenderMathMLScripts* parentNode = downcast<RenderMathMLScripts>(parent());
470
471     if (m_kind == Base) {
472         // We remove the child from the base wrapper.
473         RenderObject* sibling = nextSibling();
474         RenderMathMLBlock::removeChild(child);
475         if (sibling && !isPrescript(*sibling)) {
476             // If there are postscripts, the first one becomes the base.
477             RenderMathMLScriptsWrapper& wrapper = downcast<RenderMathMLScriptsWrapper>(*sibling);
478             RenderObject* script = wrapper.firstChild();
479             wrapper.removeChildInternal(false, *script);
480             RenderMathMLBlock::addChild(script);
481         }
482         return sibling;
483     }
484
485     // We remove the child and shift the successors in the current sequence of scripts.
486     RenderObject* next = RenderMathMLBlock::removeChild(child);
487     RenderMathMLScriptsWrapper* subSupPair = this;
488     for (RenderObject* nextSibling = subSupPair->nextSibling(); nextSibling && !isPrescript(*nextSibling); nextSibling = nextSibling->nextSibling()) {
489         RenderMathMLScriptsWrapper& nextSubSupPair = downcast<RenderMathMLScriptsWrapper>(*nextSibling);
490         RenderObject* script = nextSubSupPair.firstChild();
491         nextSubSupPair.removeChildInternal(true, *script);
492         subSupPair->addChildInternal(true, script);
493         subSupPair = downcast<RenderMathMLScriptsWrapper>(nextSibling);
494     }
495
496     // We remove the last subSup pair if it became empty.
497     if (subSupPair->isEmpty()) {
498         parentNode->removeChildInternal(true, *subSupPair);
499         subSupPair->destroy();
500     }
501     
502     return next;
503 }
504
505 RenderObject* RenderMathMLScriptsWrapper::removeChild(RenderObject& child)
506 {
507     if (beingDestroyed() || documentBeingDestroyed()) {
508         // The renderer is being destroyed so we remove the child normally.
509         return RenderMathMLBlock::removeChild(child);
510     }
511
512     RenderMathMLScripts* parentNode = downcast<RenderMathMLScripts>(parent());
513     RenderObject* next = removeChildInternal(false, child);
514     parentNode->fixAnonymousStyles();
515     return next;
516 }
517
518 }    
519
520 #endif // ENABLE(MATHML)