Replace PassRef with Ref/Ref&& across the board.
[WebKit-https.git] / Source / WebCore / rendering / mathml / RenderMathMLFenced.cpp
index f35c336..363e3d3 100644 (file)
@@ -40,32 +40,28 @@ namespace WebCore {
     
 using namespace MathMLNames;
     
-enum Braces { OpeningBraceChar = 0x28, ClosingBraceChar = 0x29 };
-    
-static const float gSeparatorMarginEndEms = 0.25f;
-static const float gFenceMarginEms = 0.1f;
+static const char* gOpeningBraceChar = "(";
+static const char* gClosingBraceChar = ")";
 
-RenderMathMLFenced::RenderMathMLFenced(Element* element)
-    : RenderMathMLRow(element)
-    , m_open(OpeningBraceChar)
-    , m_close(ClosingBraceChar)
-    , m_closeFenceRenderer(0)
+RenderMathMLFenced::RenderMathMLFenced(MathMLInlineContainerElement& element, Ref<RenderStyle>&& style)
+    : RenderMathMLRow(element, WTF::move(style))
+    , m_closeFenceRenderer(nullptr)
 {
 }
 
 void RenderMathMLFenced::updateFromElement()
 {
-    Element* fenced = static_cast<Element*>(node());
+    const auto& fenced = element();
  
-    // FIXME: Handle open/close values with more than one character (they should be treated like text).
-    AtomicString openValue = fenced->getAttribute(MathMLNames::openAttr);
-    if (openValue.length() > 0)
-        m_open = openValue[0];
-    AtomicString closeValue = fenced->getAttribute(MathMLNames::closeAttr);
-    if (closeValue.length() > 0)
-        m_close = closeValue[0];
-    
-    AtomicString separators = fenced->getAttribute(MathMLNames::separatorsAttr);
+    // The open operator defaults to a left parenthesis.
+    AtomicString open = fenced.fastGetAttribute(MathMLNames::openAttr);
+    m_open = open.isNull() ? gOpeningBraceChar : open;
+
+    // The close operator defaults to a right parenthesis.
+    AtomicString close = fenced.fastGetAttribute(MathMLNames::closeAttr);
+    m_close = close.isNull() ? gClosingBraceChar : close;
+
+    AtomicString separators = fenced.fastGetAttribute(MathMLNames::separatorsAttr);
     if (!separators.isNull()) {
         StringBuilder characters;
         for (unsigned int i = 0; i < separators.length(); i++) {
@@ -80,25 +76,28 @@ void RenderMathMLFenced::updateFromElement()
     
     if (isEmpty())
         makeFences();
+    else {
+        // FIXME: The mfenced element fails to update dynamically when its open, close and separators attributes are changed (https://bugs.webkit.org/show_bug.cgi?id=57696).
+        downcast<RenderMathMLOperator>(*firstChild()).updateTokenContent(m_open);
+        m_closeFenceRenderer->updateTokenContent(m_close);
+    }
 }
 
-RenderMathMLOperator* RenderMathMLFenced::createMathMLOperator(UChar uChar, OperatorType operatorType)
+RenderPtr<RenderMathMLOperator> RenderMathMLFenced::createMathMLOperator(const String& operatorString, MathMLOperatorDictionary::Form form, MathMLOperatorDictionary::Flag flag)
 {
-    RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), FLEX);
-    newStyle->setFlexDirection(FlowColumn);
-    newStyle->setMarginEnd(Length((operatorType == Fence ? gFenceMarginEms : gSeparatorMarginEndEms) * style()->fontSize(), Fixed));
-    if (operatorType == Fence)
-        newStyle->setMarginStart(Length(gFenceMarginEms * style()->fontSize(), Fixed));
-    RenderMathMLOperator* newOperator = new (renderArena()) RenderMathMLOperator(node() /* "almost anonymous" */, uChar);
-    newOperator->setStyle(newStyle.release());
+    RenderPtr<RenderMathMLOperator> newOperator = createRenderer<RenderMathMLOperator>(document(), RenderStyle::createAnonymousStyleWithDisplay(&style(), FLEX), operatorString, form, flag);
+    newOperator->initializeStyle();
     return newOperator;
 }
 
 void RenderMathMLFenced::makeFences()
 {
-    RenderMathMLRow::addChild(createMathMLOperator(m_open, Fence), firstChild());
-    m_closeFenceRenderer = createMathMLOperator(m_close, Fence);
-    RenderMathMLRow::addChild(m_closeFenceRenderer);
+    RenderPtr<RenderMathMLOperator> openFence = createMathMLOperator(m_open, MathMLOperatorDictionary::Prefix, MathMLOperatorDictionary::Fence);
+    RenderMathMLRow::addChild(openFence.leakPtr(), firstChild());
+
+    RenderPtr<RenderMathMLOperator> closeFence = createMathMLOperator(m_close, MathMLOperatorDictionary::Postfix, MathMLOperatorDictionary::Fence);
+    m_closeFenceRenderer = closeFence.get();
+    RenderMathMLRow::addChild(closeFence.leakPtr());
 }
 
 void RenderMathMLFenced::addChild(RenderObject* child, RenderObject* beforeChild)
@@ -107,10 +106,9 @@ void RenderMathMLFenced::addChild(RenderObject* child, RenderObject* beforeChild
     if (isEmpty())
         updateFromElement();
     
-    // FIXME: Adding or removing a child should possibly cause all later separators to shift places if they're different,
-    // as later child positions change by +1 or -1.
+    // FIXME: Adding or removing a child should possibly cause all later separators to shift places if they're different, as later child positions change by +1 or -1. This should also handle surrogate pairs. See https://bugs.webkit.org/show_bug.cgi?id=125938.
     
-    RenderObject* separatorRenderer = 0;
+    RenderPtr<RenderMathMLOperator> separatorRenderer;
     if (m_separators.get()) {
         unsigned int count = 0;
         for (Node* position = child->node(); position; position = position->previousSibling()) {
@@ -132,7 +130,9 @@ void RenderMathMLFenced::addChild(RenderObject* child, RenderObject* beforeChild
             else
                 separator = (*m_separators.get())[count - 1];
                 
-            separatorRenderer = createMathMLOperator(separator, Separator);
+            StringBuilder builder;
+            builder.append(separator);
+            separatorRenderer = createMathMLOperator(builder.toString(), MathMLOperatorDictionary::Infix, MathMLOperatorDictionary::Separator);
         }
     }
     
@@ -140,32 +140,15 @@ void RenderMathMLFenced::addChild(RenderObject* child, RenderObject* beforeChild
         // Adding |x| before an existing |y| e.g. in element (y) - first insert our new child |x|, then its separator, to get (x, y).
         RenderMathMLRow::addChild(child, beforeChild);
         if (separatorRenderer)
-            RenderMathMLRow::addChild(separatorRenderer, beforeChild);
+            RenderMathMLRow::addChild(separatorRenderer.leakPtr(), beforeChild);
     } else {
         // Adding |y| at the end of an existing element e.g. (x) - insert the separator first before the closing fence, then |y|, to get (x, y).
         if (separatorRenderer)
-            RenderMathMLRow::addChild(separatorRenderer, m_closeFenceRenderer);
+            RenderMathMLRow::addChild(separatorRenderer.leakPtr(), m_closeFenceRenderer);
         RenderMathMLRow::addChild(child, m_closeFenceRenderer);
     }
 }
 
-// FIXME: Change createMathMLOperator() above to create an isAnonymous() operator, and remove this styleDidChange() function.
-void RenderMathMLFenced::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
-    RenderMathMLBlock::styleDidChange(diff, oldStyle);
-    
-    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
-        if (child->node() == node()) {
-            ASSERT(child->style()->refCount() == 1);
-            child->style()->inheritFrom(style());
-            bool isFence = child == firstChild() || child == lastChild();
-            child->style()->setMarginEnd(Length((isFence ? gFenceMarginEms : gSeparatorMarginEndEms) * style()->fontSize(), Fixed));
-            if (isFence)
-                child->style()->setMarginStart(Length(gFenceMarginEms * style()->fontSize(), Fixed));
-        }
-    }
-}
-
 }    
 
 #endif