Add Support for the semantics element.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Jan 2014 17:49:04 +0000 (17:49 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Jan 2014 17:49:04 +0000 (17:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=100626

Source/WebCore:

Patch by Frédéric Wang <fred.wang@free.fr> on 2014-01-07
Reviewed by Chris Fleizach.

Tests: mathml/presentation/semantics-2.html
       mathml/presentation/semantics-3.html
       mathml/presentation/semantics-4.html

This provides a complete support for the semantics element. When the first child is a content MathML, an annotation can be selected and displayed. The selection algorithm is identical to Gecko's one. The recognized annotations are text (e.g. LaTeX), presentation MathML, SVG and HTML.

* mathml/MathMLElement.cpp:
(WebCore::MathMLElement::childShouldCreateRenderer):
(WebCore::MathMLElement::attributeChanged):
(WebCore::MathMLElement::isPresentationMathML):
* mathml/MathMLElement.h:
(WebCore::MathMLElement::isMathMLToken):
(WebCore::MathMLElement::isSemanticAnnotation):
(WebCore::MathMLElement::isPresentationMathML):
(WebCore::MathMLElement::updateSelectedChild):
* mathml/MathMLInlineContainerElement.h:
* mathml/MathMLSelectElement.cpp:
(WebCore::MathMLSelectElement::getSelectedActionChildAndIndex):
(WebCore::MathMLSelectElement::getSelectedActionChild):
(WebCore::MathMLSelectElement::getSelectedSemanticsChild):
(WebCore::MathMLSelectElement::updateSelectedChild):
(WebCore::MathMLSelectElement::toggle):
* mathml/MathMLSelectElement.h:
* mathml/MathMLTextElement.h:
* mathml/mathattrs.in:
* mathml/mathtags.in:

LayoutTests:

Patch by Frédéric Wang <fred.wang@free.fr> on 2014-01-07
Reviewed by Chris Fleizach.

* TestExpectations:
* mathml/presentation/semantics-2-expected.html: Added.
* mathml/presentation/semantics-2.html: Added.
* mathml/presentation/semantics-3-expected.html: Added.
* mathml/presentation/semantics-3.html: Added.
* mathml/presentation/semantics-4-expected.html: Added.
* mathml/presentation/semantics-4.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@161430 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/mathml/presentation/semantics-2-expected.html [new file with mode: 0644]
LayoutTests/mathml/presentation/semantics-2.html [new file with mode: 0644]
LayoutTests/mathml/presentation/semantics-3-expected.html [new file with mode: 0644]
LayoutTests/mathml/presentation/semantics-3.html [new file with mode: 0644]
LayoutTests/mathml/presentation/semantics-4-expected.html [new file with mode: 0644]
LayoutTests/mathml/presentation/semantics-4.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/mathml/MathMLElement.cpp
Source/WebCore/mathml/MathMLElement.h
Source/WebCore/mathml/MathMLInlineContainerElement.h
Source/WebCore/mathml/MathMLSelectElement.cpp
Source/WebCore/mathml/MathMLSelectElement.h
Source/WebCore/mathml/MathMLTextElement.h
Source/WebCore/mathml/mathattrs.in
Source/WebCore/mathml/mathtags.in

index 197507d..053b696 100644 (file)
@@ -1,3 +1,18 @@
+2014-01-07  Frédéric Wang  <fred.wang@free.fr>
+
+        Add Support for the semantics element.
+        https://bugs.webkit.org/show_bug.cgi?id=100626
+
+        Reviewed by Chris Fleizach.
+
+        * TestExpectations:
+        * mathml/presentation/semantics-2-expected.html: Added.
+        * mathml/presentation/semantics-2.html: Added.
+        * mathml/presentation/semantics-3-expected.html: Added.
+        * mathml/presentation/semantics-3.html: Added.
+        * mathml/presentation/semantics-4-expected.html: Added.
+        * mathml/presentation/semantics-4.html: Added.
+
 2014-01-07  Manuel Rego Casasnovas  <rego@igalia.com>
 
         [GTK] fast/repaint/repaint-regions-overflow.html is failing
index c633b86..9e9cb1a 100644 (file)
@@ -21,9 +21,6 @@ webkit.org/b/99618  mathml/presentation/roots.xhtml [ Failure ]
 webkit.org/b/57700  mathml/presentation/row.xhtml [ Failure ]
 webkit.org/b/57700  mathml/presentation/mo.xhtml [ Failure ]
 
-# MathML regression with foreign objects
-webkit.org/b/124128 mathml/presentation/semantics.html [ Skip ]
-
 # These conformace tests are no longer in sync with the latest specification
 # and expect compareDocumentPosition() to return:
 # DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_DISCONNECTED
diff --git a/LayoutTests/mathml/presentation/semantics-2-expected.html b/LayoutTests/mathml/presentation/semantics-2-expected.html
new file mode 100644 (file)
index 0000000..3bb7fd7
--- /dev/null
@@ -0,0 +1,15 @@
+<!doctype html>
+<html>
+<head>
+  <title>Semantics</title>
+</head>
+
+<body>
+  <p>presentation MathML (no annotations): <math><mrow><mtext>presentation MathML</mtext></mrow></math></p>
+  <p>content MathML (no annotations): <math><maction actiontype="toggle"><csymbol>content MathML</csymbol></maction></math></p>
+  <p>presentation MathML ; annotation: <math><mrow><mtext>presentation MathML</mtext></mrow></math></p>
+  <p>presentation MathML ; annotation-xml: <math><mrow><mtext>presentation MathML</mtext></mrow></math></p>
+  <p>content MathML ; annotation: <math><mrow><mtext>annotation</mtext></mrow></math></p>
+  <p>content MathML ; annotation-xml: <math><mrow><mrow><mtext>annotation-xml</mtext></mrow></mrow></math></p>
+</body>
+</html>
diff --git a/LayoutTests/mathml/presentation/semantics-2.html b/LayoutTests/mathml/presentation/semantics-2.html
new file mode 100644 (file)
index 0000000..23fe423
--- /dev/null
@@ -0,0 +1,22 @@
+<!doctype html>
+<html>
+<head>
+  <title>Semantics</title>
+</head>
+
+<body>
+
+  <!-- No annotations: the first child is displayed -->
+  <p>presentation MathML (no annotations): <math><semantics><mtext>presentation MathML</mtext></semantics></math></p>
+  <p>content MathML (no annotations): <math><semantics><csymbol>content MathML</csymbol></semantics></math></p>
+
+  <!-- Presentation MathML: the child is displayed -->
+  <p>presentation MathML ; annotation: <math><semantics><mtext>presentation MathML</mtext><annotation>annotation</annotation></semantics></math></p>
+  <p>presentation MathML ; annotation-xml: <math><semantics><mtext>presentation MathML</mtext><annotation-xml encoding="application/mathml-presentation+xml"><mtext>annotation-xml</mtext></annotation-xml></semantics></math></p>
+
+  <!-- Content MathML: the annotation is displayed -->
+  <p>content MathML ; annotation: <math><semantics><csymbol>content MathML</csymbol><annotation>annotation</annotation></semantics></math></p>
+  <p>content MathML ; annotation-xml: <math><semantics><csymbol>content MathML</csymbol><annotation-xml encoding="application/mathml-presentation+xml"><mtext>annotation-xml</mtext></annotation-xml></semantics></math></p>
+
+</body>
+</html>
diff --git a/LayoutTests/mathml/presentation/semantics-3-expected.html b/LayoutTests/mathml/presentation/semantics-3-expected.html
new file mode 100644 (file)
index 0000000..3679ddf
--- /dev/null
@@ -0,0 +1,19 @@
+<!doctype html>
+<html>
+<head>
+  <title>Semantics</title>
+</head>
+
+<body>
+  <p>annotation 1: <math><mrow><mtext>annotation</mtext></mrow></math></p>
+  <p>annotation 2: <math><mrow><mtext>\sin x + 5</mtext></mrow></math></p>
+  <p>annotation 3: <math><mrow><mtext>annotation</mtext></mrow></math></p>
+
+  <p>annotation-xml 1: <math><mrow><mrow><mtext>application/mathml-presentation+xml</mtext></mrow></mrow></math></p>
+  <p>annotation-xml 2: <math><mrow><mrow><mtext>MathML-Presentation</mtext></mrow></mrow></math></p>
+  <p>annotation-xml 3: <math><semantics><annotation-xml encoding="image/svg+xml"><svg width="20px" height="20px"><rect width="20px" height="20px" fill="red" stroke="none"/></svg></annotation-xml></semantics></math></p>
+  <p>annotation-xml 4: <math><semantics><annotation-xml encoding="image/svg+xml"><svg width="20px" height="20px"><rect width="20px" height="20px" fill="red" stroke="none"/></svg></annotation-xml></semantics></math></p>
+  <p>annotation-xml 5: <math><semantics><annotation-xml encoding="application/xhtml+xml"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>application/xhtml+xml</title></head><body><p>application/xhtml+xml</p></body></html></annotation-xml></math></p>
+  <p>annotation-xml 6: <math><semantics><annotation-xml encoding="application/xhtml+xml"><html><head><title>text/html</title></head><body><p>text/html</p></body></html></annotation-xml></semantics></math></p>
+  <p>annotation-xml 7: <math><mrow><mrow><mtext>annotation-xml</mtext></mrow></mrow></math></p></body>
+</html>
diff --git a/LayoutTests/mathml/presentation/semantics-3.html b/LayoutTests/mathml/presentation/semantics-3.html
new file mode 100644 (file)
index 0000000..573a465
--- /dev/null
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+<head>
+  <title>Semantics</title>
+</head>
+
+<body>
+
+  <!-- These <semantics> elements are content MathML expressions with various annotations. Only the first recognized annotation should be displayed. WebKit recognizes the following annotations:
+   - Any <annotation> element without src attribute.
+   - An <annotation-xml> element without src attribute and with one of the encoding among "application/mathml-presentation+xml", "MathML-Presentation", "image/svg+xml", "SVG1.1", "application/xhtml+xml" and "text/html".
+   -->
+
+  <p>annotation 1: <math><semantics><csymbol>Content MathML</csymbol><annotation>annotation</annotation><annotation>error</annotation><annotation-xml encoding="application/mathml-presentation+xml"><mtext>error</mtext></annotation-xml></semantics></math></p>
+  <p>annotation 2: <math><semantics><csymbol>Content MathML</csymbol><annotation encoding="application/x-tex">\sin x + 5</annotation><annotation>error</annotation><annotation-xml encoding="application/mathml-presentation+xml"><mtext>error</mtext></annotation-xml></semantics></math></p>
+  <p>annotation 3: <math><semantics><csymbol>Content MathML</csymbol><annotation src="external-resource">error</annotation><annotation>annotation</annotation><annotation-xml encoding="application/mathml-presentation+xml"><mtext>error</mtext></annotation-xml></semantics></math></p>
+
+  <p>annotation-xml 1: <math><semantics><csymbol>Content MathML</csymbol><annotation-xml encoding="application/mathml-presentation+xml"><mtext>application/mathml-presentation+xml</mtext></annotation-xml><annotation-xml encoding="application/mathml-presentation+xml"><mtext>error</mtext></annotation-xml><annotation>error</annotation></semantics></math></p>
+  <p>annotation-xml 2: <math><semantics><csymbol>Content MathML</csymbol><annotation-xml encoding="MathML-Presentation"><mtext>MathML-Presentation</mtext></annotation-xml><annotation-xml encoding="application/mathml-presentation+xml"><mtext>error</mtext></annotation-xml><annotation>error</annotation></semantics></math></p>
+  <p>annotation-xml 3: <math><semantics><csymbol>Content MathML</csymbol><annotation-xml encoding="image/svg+xml"><svg width="20px" height="20px"><rect width="20px" height="20px" fill="red" stroke="none"/></svg></annotation-xml><annotation-xml encoding="application/mathml-presentation+xml"><mtext>error</mtext></annotation-xml><annotation>error</annotation></semantics></math></p>
+  <p>annotation-xml 4: <math><semantics><csymbol>Content MathML</csymbol><annotation-xml encoding="SVG1.1"><svg width="20px" height="20px"><rect width="20px" height="20px" fill="red" stroke="none"/></svg></annotation-xml><annotation-xml encoding="application/mathml-presentation+xml"><mtext>error</mtext></annotation-xml><annotation>error</annotation></semantics></math></p>
+  <p>annotation-xml 5: <math><semantics><csymbol>Content MathML</csymbol><annotation-xml encoding="application/xhtml+xml"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>application/xhtml+xml</title></head><body><p>application/xhtml+xml</p></body></html></annotation-xml><annotation-xml encoding="application/mathml-presentation+xml"><mtext>error</mtext></annotation-xml><annotation>error</annotation></math></p>
+  <p>annotation-xml 6: <math><semantics><csymbol>Content MathML</csymbol><annotation-xml encoding="text/html"><html><head><title>text/html</title></head><body><p>text/html</p></body></html></annotation-xml><annotation-xml encoding="application/mathml-presentation+xml"><mtext>error</mtext></annotation-xml><annotation>error</annotation></semantics></math></p>
+  <p>annotation-xml 7: <math><semantics><csymbol>Content MathML</csymbol><annotation-xml encoding="unknown"><mtext>error</mtext></annotation-xml><annotation-xml encoding="application/mathml+xml"><mtext>error</mtext></annotation-xml><annotation-xml encoding="application/mathml-presentation+xml"><mtext>annotation-xml</mtext></annotation-xml><annotation>error</annotation></semantics></math></p>
+</body>
+</html>
diff --git a/LayoutTests/mathml/presentation/semantics-4-expected.html b/LayoutTests/mathml/presentation/semantics-4-expected.html
new file mode 100644 (file)
index 0000000..4d56b20
--- /dev/null
@@ -0,0 +1,12 @@
+<!doctype html>
+<html>
+<head>
+  <title>Semantics</title>
+</head>
+
+<body>
+
+  <p><math><mrow><mrow id="a"><mtext>PASS</mtext></mrow></mrow></math></p>
+
+</body>
+</html>
diff --git a/LayoutTests/mathml/presentation/semantics-4.html b/LayoutTests/mathml/presentation/semantics-4.html
new file mode 100644 (file)
index 0000000..ddd80b7
--- /dev/null
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+<head>
+  <title>Semantics</title>
+</head>
+
+<body onload="document.getElementById('a').setAttribute('encoding', 'MathML-Presentation')">
+
+  <!-- This test verifies that setting the encoding dynamically updates the selected annotation. This should render the same as the static reference. -->
+
+  <p><math><semantics><csymbol>Content MathML</csymbol><annotation-xml id="a"><mtext>PASS</mtext></annotation-xml><annotation>FAIL</annotation></semantics></math></p>
+
+</body>
+</html>
index 75d5662..08a4a99 100644 (file)
@@ -1,3 +1,38 @@
+2014-01-07  Frédéric Wang  <fred.wang@free.fr>
+
+        Add Support for the semantics element.
+        https://bugs.webkit.org/show_bug.cgi?id=100626
+
+
+        Reviewed by Chris Fleizach.
+
+        Tests: mathml/presentation/semantics-2.html
+               mathml/presentation/semantics-3.html
+               mathml/presentation/semantics-4.html
+
+        This provides a complete support for the semantics element. When the first child is a content MathML, an annotation can be selected and displayed. The selection algorithm is identical to Gecko's one. The recognized annotations are text (e.g. LaTeX), presentation MathML, SVG and HTML.
+
+        * mathml/MathMLElement.cpp:
+        (WebCore::MathMLElement::childShouldCreateRenderer):
+        (WebCore::MathMLElement::attributeChanged):
+        (WebCore::MathMLElement::isPresentationMathML):
+        * mathml/MathMLElement.h:
+        (WebCore::MathMLElement::isMathMLToken):
+        (WebCore::MathMLElement::isSemanticAnnotation):
+        (WebCore::MathMLElement::isPresentationMathML):
+        (WebCore::MathMLElement::updateSelectedChild):
+        * mathml/MathMLInlineContainerElement.h:
+        * mathml/MathMLSelectElement.cpp:
+        (WebCore::MathMLSelectElement::getSelectedActionChildAndIndex):
+        (WebCore::MathMLSelectElement::getSelectedActionChild):
+        (WebCore::MathMLSelectElement::getSelectedSemanticsChild):
+        (WebCore::MathMLSelectElement::updateSelectedChild):
+        (WebCore::MathMLSelectElement::toggle):
+        * mathml/MathMLSelectElement.h:
+        * mathml/MathMLTextElement.h:
+        * mathml/mathattrs.in:
+        * mathml/mathtags.in:
+
 2014-01-07  Pascal Jacquemart  <p.jacquemart@samsung.com>
 
         Fix compilation issue with GLES2 after http://webkit.org/b/126548
index b8d3487..2401792 100644 (file)
@@ -48,6 +48,11 @@ PassRefPtr<MathMLElement> MathMLElement::create(const QualifiedName& tagName, Do
     return adoptRef(new MathMLElement(tagName, document));
 }
 
+bool MathMLElement::isPresentationMathML() const
+{
+    return hasTagName(MathMLNames::mtrTag) || hasTagName(MathMLNames::mtdTag) || hasTagName(MathMLNames::maligngroupTag) || hasTagName(MathMLNames::malignmarkTag) || hasTagName(MathMLNames::mencloseTag) || hasTagName(MathMLNames::mglyphTag) || hasTagName(MathMLNames::mlabeledtrTag) || hasTagName(MathMLNames::mlongdivTag) || hasTagName(MathMLNames::mpaddedTag) || hasTagName(MathMLNames::msTag) || hasTagName(MathMLNames::mscarriesTag) || hasTagName(MathMLNames::mscarryTag) || hasTagName(MathMLNames::msgroupTag) || hasTagName(MathMLNames::mslineTag) || hasTagName(MathMLNames::msrowTag) || hasTagName(MathMLNames::mstackTag);
+}
+
 int MathMLElement::colSpan() const
 {
     if (!hasTagName(mtdTag))
@@ -118,13 +123,23 @@ void MathMLElement::collectStyleForPresentationAttribute(const QualifiedName& na
 
 bool MathMLElement::childShouldCreateRenderer(const Node& child) const
 {
+    if (hasTagName(annotationTag))
+        return child.isTextNode();
+    if (hasTagName(annotation_xmlTag))
+        return StyledElement::childShouldCreateRenderer(child);
+
     // Only create renderers for MathML elements or text. MathML prohibits non-MathML markup inside a <math> element.
     return child.isTextNode() || child.isMathMLElement();
 }
 
-bool MathMLElement::isMathMLToken() const
+void MathMLElement::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
 {
-    return hasTagName(miTag) || hasTagName(mnTag) || hasTagName(moTag) || hasTagName(msTag) || hasTagName(mtextTag);
+    if (isSemanticAnnotation() && (name == MathMLNames::srcAttr || name == MathMLNames::encodingAttr)) {
+        Element* parent = parentElement();
+        if (parent && parent->isMathMLElement() && parent->hasTagName(semanticsTag))
+            toMathMLElement(parent)->updateSelectedChild();
+    }
+    StyledElement::attributeChanged(name, newValue, reason);
 }
 
 }
index 64b29a1..df2ca57 100644 (file)
@@ -30,6 +30,7 @@
 
 #if ENABLE(MATHML)
 
+#include "MathMLNames.h"
 #include "StyledElement.h"
 
 namespace WebCore {
@@ -41,17 +42,30 @@ public:
     int colSpan() const;
     int rowSpan() const;
 
+    bool isMathMLToken() const
+    {
+        return hasTagName(MathMLNames::miTag) || hasTagName(MathMLNames::mnTag) || hasTagName(MathMLNames::moTag) || hasTagName(MathMLNames::msTag) || hasTagName(MathMLNames::mtextTag);
+    }
+
+    bool isSemanticAnnotation() const
+    {
+        return hasTagName(MathMLNames::annotationTag) || hasTagName(MathMLNames::annotation_xmlTag);
+    }
+
+    virtual bool isPresentationMathML() const;
+
 protected:
     MathMLElement(const QualifiedName& tagName, Document&);
 
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
     virtual bool childShouldCreateRenderer(const Node&) const OVERRIDE;
+    virtual void attributeChanged(const QualifiedName&, const AtomicString& newValue, AttributeModificationReason) OVERRIDE;
 
 private:    
     virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) OVERRIDE;
 
-    inline bool isMathMLToken() const;
+    virtual void updateSelectedChild() { };
 };
 
 void isMathMLElement(const MathMLElement&); // Catch unnecessary runtime check of type known at compile time.
index 1245efa..7be2ffe 100644 (file)
@@ -36,6 +36,8 @@ class MathMLInlineContainerElement : public MathMLElement {
 public:
     static PassRefPtr<MathMLInlineContainerElement> create(const QualifiedName& tagName, Document&);
 
+    virtual bool isPresentationMathML() const OVERRIDE { return true; }
+
 protected:
     MathMLInlineContainerElement(const QualifiedName& tagName, Document&);
 
index f911dfc..e570710 100644 (file)
@@ -77,8 +77,10 @@ void MathMLSelectElement::attributeChanged(const QualifiedName& name, const Atom
     MathMLInlineContainerElement::attributeChanged(name, newValue, reason);
 }
 
-int MathMLSelectElement::getSelectedChildAndIndex(Element*& selectedChild)
+int MathMLSelectElement::getSelectedActionChildAndIndex(Element*& selectedChild)
 {
+    ASSERT(hasLocalName(actionTag));
+
     // We "round up or down to the closest allowable value" of the selection attribute, as suggested by the MathML specification.
     selectedChild = firstElementChild();
     if (!selectedChild)
@@ -96,30 +98,85 @@ int MathMLSelectElement::getSelectedChildAndIndex(Element*& selectedChild)
     return i;
 }
 
-void MathMLSelectElement::updateSelectedChild()
+Element* MathMLSelectElement::getSelectedActionChild()
+{
+    ASSERT(hasLocalName(actionTag));
+
+    Element* child = firstElementChild();
+    if (!child)
+        return child;
+
+    // The value of the actiontype attribute is case-sensitive.
+    const AtomicString& actiontype = fastGetAttribute(MathMLNames::actiontypeAttr);
+    if (actiontype == "statusline")
+        // FIXME: implement user interaction for the "statusline" action type (http://wkbug/124922).
+        { }
+    else if (actiontype == "tooltip")
+        // FIXME: implement user interaction for the "tooltip" action type (http://wkbug/124921).
+        { }
+    else {
+        // For the "toggle" action type or any unknown action type, we rely on the value of the selection attribute to determine the visible child.
+        getSelectedActionChildAndIndex(child);
+    }
+
+    return child;
+}
+
+Element* MathMLSelectElement::getSelectedSemanticsChild()
 {
-    Element* newSelectedChild = firstElementChild();
-
-    if (newSelectedChild) {
-        if (hasLocalName(mactionTag)) {
-            // The value of the actiontype attribute is case-sensitive.
-            const AtomicString& actiontype = fastGetAttribute(MathMLNames::actiontypeAttr);
-            if (actiontype == "statusline")
-                // FIXME: implement user interaction for the "statusline" action type (http://wkbug/124922).
-                { }
-            else if (actiontype == "tooltip")
-                // FIXME: implement user interaction for the "tooltip" action type (http://wkbug/124921).
-                { }
-            else {
-                // For the "toggle" action type or any unknown action type, we rely on the value of the selection attribute to determine the visible child.
-                getSelectedChildAndIndex(newSelectedChild);
-            }
-        } else {
-            ASSERT(hasLocalName(semanticsTag));
-            // FIXME: implement Gecko's selection algorithm for <semantics> (http://wkbug/100626).
+    ASSERT(hasLocalName(semanticsTag));
+
+    Element* child = firstElementChild();
+    if (!child)
+        return child;
+
+    if (!child->isMathMLElement() || !toMathMLElement(child)->isPresentationMathML()) { 
+        // The first child is not a presentation MathML element. Hence we move to the second child and start searching an annotation child that could be displayed.
+        child = child->nextElementSibling();
+    } else if (!toMathMLElement(child)->isSemanticAnnotation()) {
+        // The first child is a presentation MathML but not an annotation, so we can just display it.
+        return child;
+    }
+    // Otherwise, the first child is an <annotation> or <annotation-xml> element. This is invalid, but some people use this syntax so we take care of this case too and start the search from this first child.
+
+    for ( ; child; child = child->nextElementSibling()) {
+        if (!child->isMathMLElement())
+            continue;
+
+        if (child->hasLocalName(MathMLNames::annotationTag)) {
+            // If the <annotation> element has an src attribute then it is a reference to arbitrary binary data and it is not clear whether we can display it. Hence we just ignore the annotation.
+            if (child->hasAttribute(MathMLNames::srcAttr))
+                continue;
+            // Otherwise, we assume it is a text annotation that can always be displayed and we stop here.
+            return child;
+        }
+
+        if (child->hasLocalName(MathMLNames::annotation_xmlTag)) {
+            // If the <annotation-xml> element has an src attribute then it is a reference to arbitrary binary data and it is not clear whether we can display it. Hence we just ignore the annotation.
+            if (child->hasAttribute(MathMLNames::srcAttr))
+                continue;
+            // If the <annotation-xml> element has an encoding attribute describing presentation MathML, SVG or HTML we assume the content can be displayed and we stop here. We recognize the following encoding values:
+            //
+            // - "MathML-Presentation", which is mentioned in the MathML 3 recommendation.
+            // - "SVG1.1" which is mentioned in the W3C note.
+            //   http://www.w3.org/Math/Documents/Notes/graphics.xml
+            // - Other MIME Content-Types for SVG and HTML.
+            //
+            // We exclude "application/mathml+xml" which is ambiguous about whether it is Presentation or Content MathML. Authors must use a more explicit encoding value.
+            const AtomicString& value = child->fastGetAttribute(MathMLNames::encodingAttr);
+            if (value == "application/mathml-presentation+xml" || value == "MathML-Presentation" || value == "image/svg+xml" || value == "SVG1.1" || value == "application/xhtml+xml" || value == "text/html")
+                return child;
         }
     }
 
+    // We fallback to the first child.
+    return firstElementChild();
+}
+
+void MathMLSelectElement::updateSelectedChild()
+{
+    Element* newSelectedChild = hasLocalName(mactionTag) ? getSelectedActionChild() : getSelectedSemanticsChild();
+
     if (m_selectedChild == newSelectedChild)
         return;
 
@@ -153,7 +210,7 @@ void MathMLSelectElement::toggle()
     // Select the successor of the currently selected child
     // or the first child if the currently selected child is the last.
     Element* selectedChild;
-    int newSelectedChildIndex = getSelectedChildAndIndex(selectedChild) + 1;
+    int newSelectedChildIndex = getSelectedActionChildAndIndex(selectedChild) + 1;
     if (!selectedChild || !selectedChild->nextElementSibling())
         newSelectedChildIndex = 1;
 
index 435968b..a75c586 100644 (file)
@@ -48,9 +48,11 @@ private:
     virtual bool willRespondToMouseClickEvents() OVERRIDE;
 
     void toggle();
-    int getSelectedChildAndIndex(Element*& selectedChild);
+    int getSelectedActionChildAndIndex(Element*& selectedChild);
+    Element* getSelectedActionChild();
+    Element* getSelectedSemanticsChild();
 
-    void updateSelectedChild();
+    void updateSelectedChild() OVERRIDE;
     Element* m_selectedChild;
 };
 
index 6a9e0ba..e1c3d34 100644 (file)
@@ -37,6 +37,8 @@ public:
     static PassRefPtr<MathMLTextElement> create(const QualifiedName& tagName, Document&);
     virtual void didAttachRenderers() OVERRIDE;
 
+    virtual bool isPresentationMathML() const OVERRIDE { return true; }
+
 private:
     MathMLTextElement(const QualifiedName& tagName, Document&);
 
index 73ac8be..ba1deb6 100644 (file)
@@ -29,6 +29,7 @@ open
 rowspan
 selection
 separators
+src
 stretchy
 subscriptshift
 superscriptshift
index 667159c..daf3334 100644 (file)
@@ -34,8 +34,18 @@ mprescripts interfaceName=MathMLInlineContainerElement
 none interfaceName=MathMLInlineContainerElement
 semantics interfaceName=MathMLSelectElement
 
-#if 0 // Curently only for MathMLNames used by HTMLTreeBuilder.
-ms
-mglyph
-malignmark
-#endif
+# These presentation MathML elements are not implemented.
+maligngroup interfaceName=MathMLElement
+malignmark interfaceName=MathMLElement
+menclose interfaceName=MathMLElement # http://wkbug/85729
+mglyph interfaceName=MathMLElement
+mlabeledtr interfaceName=MathMLElement # http://wkbug/85732
+mlongdiv interfaceName=MathMLElement
+mpadded interfaceName=MathMLElement # http://wkbug/85730
+ms interfaceName=MathMLElement # http://wkbug/125859
+mscarries interfaceName=MathMLElement
+mscarry interfaceName=MathMLElement
+msgroup interfaceName=MathMLElement
+msline interfaceName=MathMLElement
+msrow interfaceName=MathMLElement
+mstack interfaceName=MathMLElement