Add support for @href attribute in MathML
authorfred.wang@free.fr <fred.wang@free.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jul 2016 04:28:16 +0000 (04:28 +0000)
committerfred.wang@free.fr <fred.wang@free.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jul 2016 04:28:16 +0000 (04:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=85733

Patch by Frederic Wang <fwang@igalia.com> on 2016-07-11
Reviewed by Brent Fulgham.

Source/WebCore:

We add support for the href attribute from MathML 3 but ignore the deprecated XLink version.
We also use the code from HTMLAnchorElement SVGAElement to make MathMLElement with a href
attribute behave as a link.
Finally, we adjust mathml.css based on rules from the html and svg user agent stylesheets.

Tests: mathml/mathml-in-html5/href-click-1.html
       mathml/mathml-in-html5/href-click-2.html
       mathml/presentation/href-enter.html
       mathml/presentation/href-style.html
       mathml/presentation/maction-toggle-href.html
       mathml/presentation/semantics-href.html

* css/mathml.css:
(:any-link): Set color and mouse cursor of links.
(:any-link:active): Set color of active links.
(:focus): Set outline of focused links.
* mathml/MathMLElement.cpp:
(WebCore::MathMLElement::parseAttribute): Parse the href attribute.
(WebCore::MathMLElement::willRespondToMouseClickEvents): Based on HTMLAnchorElement/SVGAElement.
(WebCore::MathMLElement::defaultEventHandler): Based on HTMLAnchorElement/SVGAElement.
(WebCore::MathMLElement::canStartSelection): Based on HTMLAnchorElement/SVGAElement.
(WebCore::MathMLElement::isFocusable): Based on HTMLAnchorElement/SVGAElement.
(WebCore::MathMLElement::isKeyboardFocusable): Based on HTMLAnchorElement/SVGAElement.
(WebCore::MathMLElement::isMouseFocusable): Based on HTMLAnchorElement/SVGAElement.
(WebCore::MathMLElement::isURLAttribute): Based on HTMLAnchorElement/SVGAElement.
(WebCore::MathMLElement::supportsFocus): Based on HTMLAnchorElement/SVGAElement.
(WebCore::MathMLElement::tabIndex): Based on HTMLAnchorElement/SVGAElement.
* mathml/MathMLElement.h: Define new members.
* mathml/MathMLSelectElement.cpp:
(WebCore::MathMLSelectElement::willRespondToMouseClickEvents): We also verify whether
the parent class will respond.
* mathml/mathattrs.in: Add href attribute.

LayoutTests:

We import some tests from the MathML in HTML5 test suite to
test clicks on href attributes and write similar tests.
We also test tab/enter keys and user agent style with links.

* mathml/mathml-in-html5/href-click-1.html: Added. Verify mouse click on a MathML link.
* mathml/mathml-in-html5/href-click-1-expected.html: Added.
* mathml/mathml-in-html5/href-click-2.html: Added.
Verify mouse click on a descendant of a MathML link.
* mathml/mathml-in-html5/href-click-2-expected.html: Added.
* mathml/presentation/href-enter.html: Added.
Verify tab navigation and activing link with enter.
* mathml/presentation/href-enter-expected.html: Added.
* mathml/presentation/href-style.html: Added.
Verify default style of links and of focused links.
* mathml/presentation/href-style-expected.html: Added.
* mathml/presentation/maction-toggle-href.html: Added.
Verify conflicts between maction toggle and href link.
* mathml/presentation/maction-toggle-href-expected.html: Added.
* mathml/presentation/semantics-href.html: Added. Verify mouse click on a <semantics> link.
* mathml/presentation/semantics-href-expected.html: Added.
* platform/mac/TestExpectations: Disable MathML link tests that rely on keyboard events.
* platform/ios-simulator/TestExpectations: Ditto.

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

21 files changed:
LayoutTests/ChangeLog
LayoutTests/imported/mathml-in-html5/mathml/relations/html5-tree/href-click-1-expected.html [new file with mode: 0644]
LayoutTests/imported/mathml-in-html5/mathml/relations/html5-tree/href-click-1.html [new file with mode: 0644]
LayoutTests/imported/mathml-in-html5/mathml/relations/html5-tree/href-click-2-expected.html [new file with mode: 0644]
LayoutTests/imported/mathml-in-html5/mathml/relations/html5-tree/href-click-2.html [new file with mode: 0644]
LayoutTests/mathml/presentation/href-enter-expected.html [new file with mode: 0644]
LayoutTests/mathml/presentation/href-enter.html [new file with mode: 0644]
LayoutTests/mathml/presentation/href-style-expected.html [new file with mode: 0644]
LayoutTests/mathml/presentation/href-style.html [new file with mode: 0644]
LayoutTests/mathml/presentation/maction-toggle-href-expected.html [new file with mode: 0644]
LayoutTests/mathml/presentation/maction-toggle-href.html [new file with mode: 0644]
LayoutTests/mathml/presentation/semantics-href-expected.html [new file with mode: 0644]
LayoutTests/mathml/presentation/semantics-href.html [new file with mode: 0644]
LayoutTests/platform/ios-simulator/TestExpectations
LayoutTests/platform/mac/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/css/mathml.css
Source/WebCore/mathml/MathMLElement.cpp
Source/WebCore/mathml/MathMLElement.h
Source/WebCore/mathml/MathMLSelectElement.cpp
Source/WebCore/mathml/mathattrs.in

index 4a4a886..9e6cd72 100644 (file)
@@ -1,5 +1,35 @@
 2016-07-11  Frederic Wang  <fwang@igalia.com>
 
+        Add support for @href attribute in MathML
+        https://bugs.webkit.org/show_bug.cgi?id=85733
+
+        Reviewed by Brent Fulgham.
+
+        We import some tests from the MathML in HTML5 test suite to
+        test clicks on href attributes and write similar tests.
+        We also test tab/enter keys and user agent style with links.
+
+        * mathml/mathml-in-html5/href-click-1.html: Added. Verify mouse click on a MathML link.
+        * mathml/mathml-in-html5/href-click-1-expected.html: Added.
+        * mathml/mathml-in-html5/href-click-2.html: Added.
+        Verify mouse click on a descendant of a MathML link.
+        * mathml/mathml-in-html5/href-click-2-expected.html: Added.
+        * mathml/presentation/href-enter.html: Added.
+        Verify tab navigation and activing link with enter.
+        * mathml/presentation/href-enter-expected.html: Added.
+        * mathml/presentation/href-style.html: Added.
+        Verify default style of links and of focused links.
+        * mathml/presentation/href-style-expected.html: Added.
+        * mathml/presentation/maction-toggle-href.html: Added.
+        Verify conflicts between maction toggle and href link.
+        * mathml/presentation/maction-toggle-href-expected.html: Added.
+        * mathml/presentation/semantics-href.html: Added. Verify mouse click on a <semantics> link.
+        * mathml/presentation/semantics-href-expected.html: Added.
+        * platform/mac/TestExpectations: Disable MathML link tests that rely on keyboard events.
+        * platform/ios-simulator/TestExpectations: Ditto.
+
+2016-07-11  Frederic Wang  <fwang@igalia.com>
+
         Replace reftest mathml/presentation/fractions-positions.html with script tests
         https://bugs.webkit.org/show_bug.cgi?id=159558
 
diff --git a/LayoutTests/imported/mathml-in-html5/mathml/relations/html5-tree/href-click-1-expected.html b/LayoutTests/imported/mathml-in-html5/mathml/relations/html5-tree/href-click-1-expected.html
new file mode 100644 (file)
index 0000000..8695256
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>href click (reference)</title>
+</head>
+<body>
+
+  <p>This test passes if you see a green square.</p>
+
+  <div style="width: 150px; height: 150px; background: green">
+  </div>
+
+</body>
+</html>
diff --git a/LayoutTests/imported/mathml-in-html5/mathml/relations/html5-tree/href-click-1.html b/LayoutTests/imported/mathml-in-html5/mathml/relations/html5-tree/href-click-1.html
new file mode 100644 (file)
index 0000000..ffc1703
--- /dev/null
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>href click</title>
+<link rel="help" href="http://www.mathml-association.org/MathMLinHTML5/S2.html#SS2">
+<link rel="match" href="href-click-ref.html"/>
+<meta name="assert" content="Verify that a click on a link moves to the target.">
+<script type="text/javascript">
+  function test()
+  {
+    var event = new MouseEvent('click', {bubbles: true, cancelable: true});
+    document.getElementById('link').dispatchEvent(event);
+  }
+</script>
+</head>
+<body onload="test()">
+
+  <p>This test passes if you see a green square.</p>
+
+  <div style="width: 150px; height: 150px; overflow: hidden">
+    <math style="padding: 0">
+      <mrow id="link" href="#target">
+        <mspace id="space" width="150px" height="150px" mathbackground="red"/>
+      </mrow>
+    </math>
+    <div style="height: 500px;"></div>
+    <math id="target" style="padding: 0">
+      <mspace width="150px" height="150px" mathbackground="green"/>
+    </math>
+  </div>
+
+</body>
+</html>
diff --git a/LayoutTests/imported/mathml-in-html5/mathml/relations/html5-tree/href-click-2-expected.html b/LayoutTests/imported/mathml-in-html5/mathml/relations/html5-tree/href-click-2-expected.html
new file mode 100644 (file)
index 0000000..8695256
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>href click (reference)</title>
+</head>
+<body>
+
+  <p>This test passes if you see a green square.</p>
+
+  <div style="width: 150px; height: 150px; background: green">
+  </div>
+
+</body>
+</html>
diff --git a/LayoutTests/imported/mathml-in-html5/mathml/relations/html5-tree/href-click-2.html b/LayoutTests/imported/mathml-in-html5/mathml/relations/html5-tree/href-click-2.html
new file mode 100644 (file)
index 0000000..5293be1
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>href click</title>
+<link rel="help" href="http://www.mathml-association.org/MathMLinHTML5/S2.html#SS2">
+<link rel="match" href="href-click-ref.html"/>
+<meta name="assert" content="Test that a click on an element bubbles to an ancestor link.">
+<script type="text/javascript">
+  function test()
+  {
+    var event = new MouseEvent('click', {bubbles: true, cancelable: true});
+    document.getElementById('space').dispatchEvent(event);
+  }
+</script>
+</head>
+<body onload="test()">
+
+  <p>This test passes if you see a green square.</p>
+
+  <div style="width: 150px; height: 150px; overflow: hidden">
+    <math style="padding: 0">
+      <mrow href="#target">
+        <mrow>
+          <mrow>
+            <mspace id="space" width="150px" height="150px" mathbackground="red"/>
+          </mrow>
+        </mrow>
+      </mrow>
+    </math>
+    <div style="height: 500px;"></div>
+    <math id="target" style="padding: 0">
+      <mspace width="150px" height="150px" mathbackground="green"/>
+    </math>
+  </div>
+
+</body>
+</html>
diff --git a/LayoutTests/mathml/presentation/href-enter-expected.html b/LayoutTests/mathml/presentation/href-enter-expected.html
new file mode 100644 (file)
index 0000000..6502bc2
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>href enter</title>
+</head>
+<body onload="runTest()">
+
+  <p>This test passes if you see a green square.</p>
+
+  <div style="width: 150px; height: 150px; background: green">
+  </div>
+
+</body>
+</html>
diff --git a/LayoutTests/mathml/presentation/href-enter.html b/LayoutTests/mathml/presentation/href-enter.html
new file mode 100644 (file)
index 0000000..dbee3e5
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<meta charset="utf-8"/>
+<title>href enter</title>
+<script>
+  function runTest() {
+    if (window.eventSender) {
+      eventSender.keyDown('\t'); // focus the link
+      eventSender.keyDown('\r'); // press enter
+      document.documentElement.removeAttribute("class");
+    }
+  }
+</script>
+</head>
+<body onload="runTest()">
+
+  <p>This test passes if you see a green square.</p>
+
+  <div style="width: 150px; height: 150px; overflow: hidden">
+    <math style="padding: 0">
+      <mrow id="link" href="#target">
+        <mspace id="space" width="150px" height="150px" mathbackground="red"/>
+      </mrow>
+    </math>
+    <div style="height: 500px;"></div>
+    <math id="target" style="padding: 0">
+      <mspace width="150px" height="150px" mathbackground="green"/>
+    </math>
+  </div>
+
+</body>
+</html>
diff --git a/LayoutTests/mathml/presentation/href-style-expected.html b/LayoutTests/mathml/presentation/href-style-expected.html
new file mode 100644 (file)
index 0000000..7e53abf
--- /dev/null
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+  <head>
+    <title>href style</title>
+    <meta charset="utf-8"/>
+    <style>
+      #Link {
+        color: -webkit-link;
+      }
+      #FocusedLink {
+        outline: auto 5px -webkit-focus-ring-color;
+        color: -webkit-link;
+      }
+    </style>
+  </head>
+  <body>
+
+    <math>
+      <mrow><mtext>Non-Link</mtext></mrow>
+      <mrow id="Link"><mtext>Link</mtext></mrow>
+      <mrow id="FocusedLink"><mtext>Focused Link</mtext></mrow>
+    </math>
+
+  </body>
+</html>
diff --git a/LayoutTests/mathml/presentation/href-style.html b/LayoutTests/mathml/presentation/href-style.html
new file mode 100644 (file)
index 0000000..9a0283b
--- /dev/null
@@ -0,0 +1,25 @@
+<!doctype html>
+<html class="reftest-wait">
+  <head>
+    <title>href style</title>
+    <meta charset="utf-8"/>
+    <script>
+      function runTest() {
+        if (window.eventSender) {
+          eventSender.keyDown('\t'); // focus #Link
+          eventSender.keyDown('\t'); // focus #FocusedLink
+          document.documentElement.removeAttribute("class");
+        }
+      }
+    </script>
+  </head>
+  <body onload="runTest()">
+
+    <math>
+      <mrow><mtext>Non-Link</mtext></mrow>
+      <mrow href="#Link"><mtext>Link</mtext></mrow>
+      <mrow href="#FocusedLink"><mtext>Focused Link</mtext></mrow>
+    </math>
+
+  </body>
+</html>
diff --git a/LayoutTests/mathml/presentation/maction-toggle-href-expected.html b/LayoutTests/mathml/presentation/maction-toggle-href-expected.html
new file mode 100644 (file)
index 0000000..9a1ba36
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>href on a maction toggle</title>
+</head>
+<body>
+
+  <p>This test passes if you see a green square.</p>
+
+  <div style="width: 150px; height: 150px; background: green">
+  </div>
+
+</body>
+</html>
diff --git a/LayoutTests/mathml/presentation/maction-toggle-href.html b/LayoutTests/mathml/presentation/maction-toggle-href.html
new file mode 100644 (file)
index 0000000..39582e6
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>href on a maction toggle</title>
+<script type="text/javascript">
+  function test()
+  {
+    var event = new MouseEvent('click', {bubbles: true, cancelable: true});
+    document.getElementById('link').dispatchEvent(event);
+  }
+</script>
+</head>
+<body onload="test()">
+
+  <p>This test passes if you see a green square.</p>
+
+  <div style="width: 150px; height: 150px; overflow: hidden">
+    <math style="padding: 0">
+      <!-- Initially, the maction element displays its second child which is a red mspace.
+           After the click, the selection moves to the third child which is a green mspace.
+           We should not follow the link, whose target is a red space.
+        -->
+      <maction id="link" href="#target" actiontype="toggle" selection="2">
+        <mspace width="150px" height="150px" mathbackground="red"/>
+        <mspace width="150px" height="150px" mathbackground="red"/>
+        <mspace width="150px" height="150px" mathbackground="green"/>
+      </semantics>
+    </math>
+    <div style="height: 500px;"></div>
+    <math id="target" style="padding: 0">
+      <mspace id="space" width="150px" height="150px" mathbackground="red"/>
+    </math>
+  </div>
+
+</body>
+</html>
diff --git a/LayoutTests/mathml/presentation/semantics-href-expected.html b/LayoutTests/mathml/presentation/semantics-href-expected.html
new file mode 100644 (file)
index 0000000..c452887
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>href on a semantics element (expected)</title>
+</head>
+<body>
+
+  <p>This test passes if you see a green square.</p>
+
+  <div style="width: 150px; height: 150px; background: green">
+  </div>
+
+</body>
+</html>
diff --git a/LayoutTests/mathml/presentation/semantics-href.html b/LayoutTests/mathml/presentation/semantics-href.html
new file mode 100644 (file)
index 0000000..5fecddc
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>href on a semantics element</title>
+<script type="text/javascript">
+  function test()
+  {
+    var event = new MouseEvent('click', {bubbles: true, cancelable: true});
+    document.getElementById('link').dispatchEvent(event);
+  }
+</script>
+</head>
+<body onload="test()">
+
+  <p>This test passes if you see a green square.</p>
+
+  <div style="width: 150px; height: 150px; overflow: hidden">
+    <math style="padding: 0">
+      <semantics id="link" href="#target">
+        <mspace id="space" width="150px" height="150px" mathbackground="red"/>
+        <annotation>red square</annotation>
+      </semantics>
+    </math>
+    <div style="height: 500px;"></div>
+    <math id="target" style="padding: 0">
+      <mspace width="150px" height="150px" mathbackground="green"/>
+    </math>
+  </div>
+
+</body>
+</html>
index 87c8bd7..c1ba942 100644 (file)
@@ -680,6 +680,10 @@ mathml/presentation/mathvariant-tokens.html [ Skip ]
 # The web font loading & relayout seems to be performed too late.
 imported/mathml-in-html5/mathml/relations/css-styling/mathvariant-transforms-1.html [ Pass ImageOnlyFailure ]
 
+# These tests use key navigation to test MathML links but do not seem to work on iOS simulator.
+webkit.org/b/159662 mathml/presentation/href-enter.html [ Skip ]
+webkit.org/b/159662 mathml/presentation/href-style.html [ Skip ]
+
 # <rdar://problem/19215305> ASSERT(m_cgFont.get()) fails in FontPlatformData::ctFont()
 svg/text/svg-fallback-font-crash.html
 svg/css/font-face-variant-crash.html
index 7e94530..1f962f6 100644 (file)
@@ -805,6 +805,10 @@ mathml/opentype/fraction-line.html [ Skip ]
 mathml/presentation/fractions-linethickness.html [ Skip ]
 mathml/opentype/large-operators-italic-correction.html [ Skip ]
 
+# These tests use key navigation to test MathML links but do not seem to work on Mac.
+webkit.org/b/159662 mathml/presentation/href-enter.html [ Skip ]
+webkit.org/b/159662 mathml/presentation/href-style.html [ Skip ]
+
 webkit.org/b/128255 compositing/columns/composited-lr-paginated-repaint.html [ Pass Failure ]
 webkit.org/b/128255 compositing/columns/composited-rl-paginated-repaint.html [ Pass Failure ]
 
index 9c5bd9b..cb93507 100644 (file)
@@ -1,3 +1,43 @@
+2016-07-11  Frederic Wang  <fwang@igalia.com>
+
+        Add support for @href attribute in MathML
+        https://bugs.webkit.org/show_bug.cgi?id=85733
+
+        Reviewed by Brent Fulgham.
+
+        We add support for the href attribute from MathML 3 but ignore the deprecated XLink version.
+        We also use the code from HTMLAnchorElement SVGAElement to make MathMLElement with a href
+        attribute behave as a link.
+        Finally, we adjust mathml.css based on rules from the html and svg user agent stylesheets.
+
+        Tests: mathml/mathml-in-html5/href-click-1.html
+               mathml/mathml-in-html5/href-click-2.html
+               mathml/presentation/href-enter.html
+               mathml/presentation/href-style.html
+               mathml/presentation/maction-toggle-href.html
+               mathml/presentation/semantics-href.html
+
+        * css/mathml.css:
+        (:any-link): Set color and mouse cursor of links.
+        (:any-link:active): Set color of active links.
+        (:focus): Set outline of focused links.
+        * mathml/MathMLElement.cpp:
+        (WebCore::MathMLElement::parseAttribute): Parse the href attribute.
+        (WebCore::MathMLElement::willRespondToMouseClickEvents): Based on HTMLAnchorElement/SVGAElement.
+        (WebCore::MathMLElement::defaultEventHandler): Based on HTMLAnchorElement/SVGAElement.
+        (WebCore::MathMLElement::canStartSelection): Based on HTMLAnchorElement/SVGAElement.
+        (WebCore::MathMLElement::isFocusable): Based on HTMLAnchorElement/SVGAElement.
+        (WebCore::MathMLElement::isKeyboardFocusable): Based on HTMLAnchorElement/SVGAElement.
+        (WebCore::MathMLElement::isMouseFocusable): Based on HTMLAnchorElement/SVGAElement.
+        (WebCore::MathMLElement::isURLAttribute): Based on HTMLAnchorElement/SVGAElement.
+        (WebCore::MathMLElement::supportsFocus): Based on HTMLAnchorElement/SVGAElement.
+        (WebCore::MathMLElement::tabIndex): Based on HTMLAnchorElement/SVGAElement.
+        * mathml/MathMLElement.h: Define new members.
+        * mathml/MathMLSelectElement.cpp:
+        (WebCore::MathMLSelectElement::willRespondToMouseClickEvents): We also verify whether
+        the parent class will respond.
+        * mathml/mathattrs.in: Add href attribute.
+
 2016-07-11  Sam Weinig  <sam@webkit.org>
 
         Speech Synthesis: getting list of voices no longer works
index f4e29d0..296bbb4 100644 (file)
@@ -1,5 +1,18 @@
 @namespace "http://www.w3.org/1998/Math/MathML";
 
+:any-link {
+    color: -webkit-link;
+    cursor: auto;
+}
+
+:any-link:active {
+    color: -webkit-activelink;
+}
+
+:focus {
+    outline: auto 5px -webkit-focus-ring-color
+}
+
 math {
     /*
     We use the exact bounding boxes of glyphs to avoid excessive gaps in mathematical formulas.
index cf51d4d..41d5117 100644 (file)
@@ -32,6 +32,9 @@
 #include "MathMLElement.h"
 
 #include "ElementIterator.h"
+#include "Event.h"
+#include "EventHandler.h"
+#include "HTMLAnchorElement.h"
 #include "HTMLElement.h"
 #include "HTMLHtmlElement.h"
 #include "HTMLMapElement.h"
 #include "MathMLMathElement.h"
 #include "MathMLNames.h"
 #include "MathMLSelectElement.h"
+#include "MouseEvent.h"
 #include "RenderTableCell.h"
 #include "SVGElement.h"
 #include "SVGNames.h"
 #include "SVGSVGElement.h"
+#include "XLinkNames.h"
 
 namespace WebCore {
 
@@ -216,7 +221,12 @@ unsigned MathMLElement::rowSpan() const
 
 void MathMLElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
-    if (name == rowspanAttr) {
+    if (name == hrefAttr) {
+        bool wasLink = isLink();
+        setIsLink(!value.isNull() && !shouldProhibitLinks(this));
+        if (wasLink != isLink())
+            setNeedsStyleRecalc();
+    } else if (name == rowspanAttr) {
         if (is<RenderTableCell>(renderer()) && hasTagName(mtdTag))
             downcast<RenderTableCell>(*renderer()).colSpanOrRowSpanChanged();
     } else if (name == columnspanAttr) {
@@ -305,6 +315,88 @@ void MathMLElement::attributeChanged(const QualifiedName& name, const AtomicStri
     StyledElement::attributeChanged(name, oldValue, newValue, reason);
 }
 
+bool MathMLElement::willRespondToMouseClickEvents()
+{
+    return isLink() || StyledElement::willRespondToMouseClickEvents();
+}
+
+void MathMLElement::defaultEventHandler(Event* event)
+{
+    if (isLink()) {
+        if (focused() && isEnterKeyKeydownEvent(event)) {
+            event->setDefaultHandled();
+            dispatchSimulatedClick(event);
+            return;
+        }
+        if (MouseEvent::canTriggerActivationBehavior(*event)) {
+            const AtomicString& href = fastGetAttribute(hrefAttr);
+            String url = stripLeadingAndTrailingHTMLSpaces(href);
+            event->setDefaultHandled();
+            if (Frame* frame = document().frame())
+                frame->loader().urlSelected(document().completeURL(url), "_self", event, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate());
+            return;
+        }
+    }
+
+    StyledElement::defaultEventHandler(event);
+}
+
+bool MathMLElement::canStartSelection() const
+{
+    if (!isLink())
+        return StyledElement::canStartSelection();
+
+    return hasEditableStyle();
+}
+
+bool MathMLElement::isFocusable() const
+{
+    if (renderer() && renderer()->absoluteClippedOverflowRect().isEmpty())
+        return false;
+
+    return StyledElement::isFocusable();
+}
+
+bool MathMLElement::isKeyboardFocusable(KeyboardEvent* event) const
+{
+    if (isFocusable() && StyledElement::supportsFocus())
+        return StyledElement::isKeyboardFocusable(event);
+
+    if (isLink())
+        return document().frame()->eventHandler().tabsToLinks(event);
+
+    return StyledElement::isKeyboardFocusable(event);
+}
+
+bool MathMLElement::isMouseFocusable() const
+{
+    // Links are focusable by default, but only allow links with tabindex or contenteditable to be mouse focusable.
+    // https://bugs.webkit.org/show_bug.cgi?id=26856
+    if (isLink())
+        return StyledElement::supportsFocus();
+
+    return StyledElement::isMouseFocusable();
+}
+
+bool MathMLElement::isURLAttribute(const Attribute& attribute) const
+{
+    return attribute.name().localName() == hrefAttr || StyledElement::isURLAttribute(attribute);
+}
+
+bool MathMLElement::supportsFocus() const
+{
+    if (hasEditableStyle())
+        return StyledElement::supportsFocus();
+    // If not a link we should still be able to focus the element if it has tabIndex.
+    return isLink() || StyledElement::supportsFocus();
+}
+
+int MathMLElement::tabIndex() const
+{
+    // Skip the supportsFocus check in StyledElement.
+    return Element::tabIndex();
+}
+
 }
 
 #endif // ENABLE(MATHML)
index 2a5b3ee..d951158 100644 (file)
@@ -69,8 +69,19 @@ protected:
     bool isPhrasingContent(const Node&) const;
     bool isFlowContent(const Node&) const;
 
+    bool willRespondToMouseClickEvents() override;
+    void defaultEventHandler(Event*) override;
+
 private:
     virtual void updateSelectedChild() { }
+
+    bool canStartSelection() const final;
+    bool isFocusable() const final;
+    bool isKeyboardFocusable(KeyboardEvent*) const final;
+    bool isMouseFocusable() const final;
+    bool isURLAttribute(const Attribute&) const final;
+    bool supportsFocus() const final;
+    int tabIndex() const final;
 };
 
 inline bool Node::hasTagName(const MathMLQualifiedName& name) const
index 8129be9..81072ad 100644 (file)
@@ -224,7 +224,7 @@ void MathMLSelectElement::defaultEventHandler(Event* event)
 
 bool MathMLSelectElement::willRespondToMouseClickEvents()
 {
-    return fastGetAttribute(MathMLNames::actiontypeAttr) == "toggle";
+    return fastGetAttribute(MathMLNames::actiontypeAttr) == "toggle" || MathMLInlineContainerElement::willRespondToMouseClickEvents();
 }
 
 void MathMLSelectElement::toggle()
index 87cb7d1..51186c7 100644 (file)
@@ -25,6 +25,7 @@ fontstyle
 fontweight
 form
 height
+href
 largeop
 linethickness
 lspace