743c4611d3695badbea34766461bd30c1cbf2b44
[WebKit-https.git] / Source / WebCore / mathml / MathMLMencloseElement.cpp
1 /*
2  * Copyright (C) 2014 Gurpreet Kaur (k.gurpreet@samsung.com). All rights reserved.
3  * Copyright (C) 2016 Igalia S.L.
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 #include "MathMLMencloseElement.h"
29
30 #if ENABLE(MATHML)
31
32 #include "HTMLParserIdioms.h"
33 #include "MathMLNames.h"
34 #include "RenderMathMLMenclose.h"
35
36 namespace WebCore {
37
38 using namespace MathMLNames;
39
40 MathMLMencloseElement::MathMLMencloseElement(const QualifiedName& tagName, Document& document)
41     : MathMLRowElement(tagName, document)
42 {
43     // By default we draw a longdiv.
44     clearNotations();
45     addNotation(LongDiv);
46 }
47
48 Ref<MathMLMencloseElement> MathMLMencloseElement::create(const QualifiedName& tagName, Document& document)
49 {
50     return adoptRef(*new MathMLMencloseElement(tagName, document));
51 }
52
53 RenderPtr<RenderElement> MathMLMencloseElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
54 {
55     return createRenderer<RenderMathMLMenclose>(*this, WTFMove(style));
56 }
57
58 void MathMLMencloseElement::addNotationFlags(StringView notation)
59 {
60     ASSERT(m_notationFlags);
61     if (notation == "longdiv") {
62         addNotation(LongDiv);
63     } else if (notation == "roundedbox") {
64         addNotation(RoundedBox);
65     } else if (notation == "circle") {
66         addNotation(Circle);
67     } else if (notation == "left") {
68         addNotation(Left);
69     } else if (notation == "right") {
70         addNotation(Right);
71     } else if (notation == "top") {
72         addNotation(Top);
73     } else if (notation == "bottom") {
74         addNotation(Bottom);
75     } else if (notation == "updiagonalstrike") {
76         addNotation(UpDiagonalStrike);
77     } else if (notation == "downdiagonalstrike") {
78         addNotation(DownDiagonalStrike);
79     } else if (notation == "verticalstrike") {
80         addNotation(VerticalStrike);
81     } else if (notation == "horizontalstrike") {
82         addNotation(HorizontalStrike);
83     } else if (notation == "updiagonalarrow") {
84         addNotation(UpDiagonalArrow);
85     } else if (notation == "phasorangle") {
86         addNotation(PhasorAngle);
87     } else if (notation == "box") {
88         addNotation(Left);
89         addNotation(Right);
90         addNotation(Top);
91         addNotation(Bottom);
92     } else if (notation == "actuarial") {
93         addNotation(Right);
94         addNotation(Top);
95     } else if (notation == "madruwb") {
96         addNotation(Right);
97         addNotation(Bottom);
98     }
99 }
100
101 void MathMLMencloseElement::parseNotationAttribute()
102 {
103     clearNotations();
104     if (!hasAttribute(notationAttr)) {
105         addNotation(LongDiv); // The default value is longdiv.
106         return;
107     }
108     // We parse the list of whitespace-separated notation names.
109     StringView value = attributeWithoutSynchronization(notationAttr).string();
110     unsigned length = value.length();
111     unsigned start = 0;
112     while (start < length) {
113         if (isHTMLSpace(value[start])) {
114             start++;
115             continue;
116         }
117         unsigned end = start + 1;
118         while (end < length && !isHTMLSpace(value[end]))
119             end++;
120         addNotationFlags(value.substring(start, end - start));
121         start = end;
122     }
123 }
124
125 bool MathMLMencloseElement::hasNotation(MencloseNotationFlag notationFlag)
126 {
127     if (!m_notationFlags)
128         parseNotationAttribute();
129     return m_notationFlags.value() & notationFlag;
130 }
131
132 void MathMLMencloseElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
133 {
134     if (name == notationAttr)
135         m_notationFlags = std::nullopt;
136
137     MathMLRowElement::parseAttribute(name, value);
138 }
139
140 }
141 #endif // ENABLE(MATHML)