1/*
2 * Copyright (C) 2016 Igalia S.L. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
26
27#include "config.h"
28#include "MathMLAnnotationElement.h"
29
30#if ENABLE(MATHML)
31
32#include "HTMLHtmlElement.h"
33#include "MathMLMathElement.h"
34#include "MathMLNames.h"
35#include "MathMLSelectElement.h"
36#include "RenderMathMLBlock.h"
37#include "SVGSVGElement.h"
38#include <wtf/IsoMallocInlines.h>
39
40namespace WebCore {
41
42WTF_MAKE_ISO_ALLOCATED_IMPL(MathMLAnnotationElement);
43
44using namespace MathMLNames;
45
46MathMLAnnotationElement::MathMLAnnotationElement(const QualifiedName& tagName, Document& document)
47 : MathMLPresentationElement(tagName, document)
48{
49 ASSERT(hasTagName(annotationTag) || hasTagName(annotation_xmlTag));
50}
51
52Ref<MathMLAnnotationElement> MathMLAnnotationElement::create(const QualifiedName& tagName, Document& document)
53{
54 return adoptRef(*new MathMLAnnotationElement(tagName, document));
55}
56
57RenderPtr<RenderElement> MathMLAnnotationElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition& insertionPosition)
58{
59 if (hasTagName(MathMLNames::annotationTag))
60 return MathMLElement::createElementRenderer(WTFMove(style), insertionPosition);
61
62 ASSERT(hasTagName(annotation_xmlTag));
63 return createRenderer<RenderMathMLBlock>(*this, WTFMove(style));
64}
65
66bool MathMLAnnotationElement::childShouldCreateRenderer(const Node& child) const
67{
68 // For <annotation>, only text children are allowed.
69 if (hasTagName(MathMLNames::annotationTag))
70 return child.isTextNode();
71
72 // For <annotation-xml>, we follow these definitions from the HTML5 RelaxNG schema:
73 // - annotation-xml.model.mathml
74 // - annotation-xml.model.svg
75 // - annotation-xml.model.xhtml
76
77 ASSERT(hasTagName(annotation_xmlTag));
78 auto& value = attributeWithoutSynchronization(encodingAttr);
79
80 if (is<MathMLElement>(child) && (MathMLSelectElement::isMathMLEncoding(value) || MathMLSelectElement::isHTMLEncoding(value))) {
81 auto& mathmlElement = downcast<MathMLElement>(child);
82 return is<MathMLMathElement>(mathmlElement);
83 }
84
85 if (is<SVGElement>(child) && (MathMLSelectElement::isSVGEncoding(value) || MathMLSelectElement::isHTMLEncoding(value))) {
86 auto& svgElement = downcast<SVGElement>(child);
87 return is<SVGSVGElement>(svgElement);
88 }
89
90 if (is<HTMLElement>(child) && MathMLSelectElement::isHTMLEncoding(value)) {
91 auto& htmlElement = downcast<HTMLElement>(child);
92 return is<HTMLHtmlElement>(htmlElement) || (isFlowContent(htmlElement) && StyledElement::childShouldCreateRenderer(child));
93 }
94
95 return false;
96}
97
98void MathMLAnnotationElement::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason reason)
99{
100 if (name == MathMLNames::srcAttr || name == MathMLNames::encodingAttr) {
101 auto* parent = parentElement();
102 if (is<MathMLElement>(parent) && parent->hasTagName(semanticsTag))
103 downcast<MathMLElement>(*parent).updateSelectedChild();
104 }
105 MathMLPresentationElement::attributeChanged(name, oldValue, newValue, reason);
106}
107
108}
109
110#endif // ENABLE(MATHML)
111