mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 540456 - Support HTML5 canvas draw{Custom,System}FocusRing(). r=smaug
This commit is contained in:
parent
081593f897
commit
63eb811541
@ -38,6 +38,7 @@
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsFocusManager.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
||||
@ -1712,6 +1713,90 @@ CanvasRenderingContext2D::Stroke()
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void CanvasRenderingContext2D::DrawSystemFocusRing(mozilla::dom::Element& aElement)
|
||||
{
|
||||
EnsureUserSpacePath();
|
||||
|
||||
if (!mPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(DrawCustomFocusRing(aElement)) {
|
||||
Save();
|
||||
|
||||
// set state to conforming focus state
|
||||
ContextState& state = CurrentState();
|
||||
state.globalAlpha = 1.0;
|
||||
state.shadowBlur = 0;
|
||||
state.shadowOffset.x = 0;
|
||||
state.shadowOffset.y = 0;
|
||||
state.op = mozilla::gfx::OP_OVER;
|
||||
|
||||
state.lineCap = CAP_BUTT;
|
||||
state.lineJoin = mozilla::gfx::JOIN_MITER_OR_BEVEL;
|
||||
state.lineWidth = 1;
|
||||
CurrentState().dash.Clear();
|
||||
|
||||
// color and style of the rings is the same as for image maps
|
||||
// set the background focus color
|
||||
CurrentState().SetColorStyle(STYLE_STROKE, NS_RGBA(255, 255, 255, 255));
|
||||
// draw the focus ring
|
||||
Stroke();
|
||||
|
||||
// set dashing for foreground
|
||||
FallibleTArray<mozilla::gfx::Float>& dash = CurrentState().dash;
|
||||
dash.AppendElement(1);
|
||||
dash.AppendElement(1);
|
||||
|
||||
// set the foreground focus color
|
||||
CurrentState().SetColorStyle(STYLE_STROKE, NS_RGBA(0,0,0, 255));
|
||||
// draw the focus ring
|
||||
Stroke();
|
||||
|
||||
Restore();
|
||||
}
|
||||
}
|
||||
|
||||
bool CanvasRenderingContext2D::DrawCustomFocusRing(mozilla::dom::Element& aElement)
|
||||
{
|
||||
EnsureUserSpacePath();
|
||||
|
||||
HTMLCanvasElement* canvas = GetCanvas();
|
||||
|
||||
if (!canvas|| !nsContentUtils::ContentIsDescendantOf(&aElement, canvas)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
// check that the element i focused
|
||||
nsCOMPtr<nsIDOMElement> focusedElement;
|
||||
fm->GetFocusedElement(getter_AddRefs(focusedElement));
|
||||
if (SameCOMIdentity(aElement.AsDOMNode(), focusedElement)) {
|
||||
// get the bounds of the current path
|
||||
mgfx::Rect bounds;
|
||||
bounds = mPath->GetBounds(mTarget->GetTransform());
|
||||
|
||||
// and set them as the accessible area
|
||||
nsRect rect(canvas->ClientLeft() + bounds.x, canvas->ClientTop() + bounds.y,
|
||||
bounds.width, bounds.height);
|
||||
rect.x *= AppUnitsPerCSSPixel();
|
||||
rect.y *= AppUnitsPerCSSPixel();
|
||||
rect.width *= AppUnitsPerCSSPixel();
|
||||
rect.height *= AppUnitsPerCSSPixel();
|
||||
|
||||
nsIFrame* frame = aElement.GetPrimaryFrame();
|
||||
if(frame) {
|
||||
frame->SetRect(rect);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::Clip(const CanvasWindingRule& winding)
|
||||
{
|
||||
|
@ -171,6 +171,8 @@ public:
|
||||
void BeginPath();
|
||||
void Fill(const CanvasWindingRule& winding);
|
||||
void Stroke();
|
||||
void DrawSystemFocusRing(mozilla::dom::Element& element);
|
||||
bool DrawCustomFocusRing(mozilla::dom::Element& element);
|
||||
void Clip(const CanvasWindingRule& winding);
|
||||
bool IsPointInPath(double x, double y, const CanvasWindingRule& winding);
|
||||
bool IsPointInStroke(double x, double y);
|
||||
|
@ -91,6 +91,7 @@ support-files =
|
||||
[test_bug866575.html]
|
||||
[test_bug902651.html]
|
||||
[test_canvas.html]
|
||||
[test_canvas_focusring.html]
|
||||
[test_canvas_font_setter.html]
|
||||
[test_canvas_strokeStyle_getter.html]
|
||||
[test_drawImageIncomplete.html]
|
||||
|
18
content/canvas/test/reftest/drawCustomFocusRing-ref.html
Normal file
18
content/canvas/test/reftest/drawCustomFocusRing-ref.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!--docytpe html-->
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
window.onload=function(){
|
||||
var c=document.getElementById("myCanvas").getContext("2d");
|
||||
c.beginPath();
|
||||
c.strokeRect(10, 10, 200, 200);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="myCanvas" height="500" width="500" style="border:1px solid black">
|
||||
|
||||
</canvas>
|
||||
|
||||
</body></html>
|
32
content/canvas/test/reftest/drawCustomFocusRing.html
Normal file
32
content/canvas/test/reftest/drawCustomFocusRing.html
Normal file
@ -0,0 +1,32 @@
|
||||
<!--docytpe html-->
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
window.onload=function(){
|
||||
var c=document.getElementById("myCanvas").getContext("2d");
|
||||
var in1=document.getElementById("in1");
|
||||
var in2=document.getElementById("in2");
|
||||
in1.onfocus=function(){
|
||||
c.beginPath();
|
||||
c.rect(10, 10, 200, 200);
|
||||
if(c.drawCustomFocusRing(in1)) {
|
||||
c.stroke();
|
||||
}
|
||||
c.beginPath();
|
||||
c.rect(10, 220, 200, 200);
|
||||
if(c.drawCustomFocusRing(in2)) {
|
||||
c.stroke();
|
||||
}
|
||||
}
|
||||
in1.focus();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="myCanvas" height="500" width="500" style="border:1px solid black">
|
||||
<input id="in1" type="range" min="1" max="12">
|
||||
<input id="in2" type="range" min="1" max="12">
|
||||
</canvas>
|
||||
|
||||
</body></html>
|
18
content/canvas/test/reftest/drawSystemFocusRing-ref.html
Normal file
18
content/canvas/test/reftest/drawSystemFocusRing-ref.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!--docytpe html-->
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
window.onload=function(){
|
||||
var c=document.getElementById("myCanvas").getContext("2d");
|
||||
c.beginPath();
|
||||
c.mozDash = [1,1];
|
||||
c.strokeRect(10, 10, 200, 200);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="myCanvas" height="500" width="500" style="border:1px solid black">
|
||||
</canvas>
|
||||
|
||||
</body></html>
|
28
content/canvas/test/reftest/drawSystemFocusRing.html
Normal file
28
content/canvas/test/reftest/drawSystemFocusRing.html
Normal file
@ -0,0 +1,28 @@
|
||||
<!--docytpe html-->
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
window.onload=function(){
|
||||
var c=document.getElementById("myCanvas").getContext("2d");
|
||||
var in1=document.getElementById("in1");
|
||||
var in2=document.getElementById("in2");
|
||||
in1.onfocus=function(){
|
||||
c.beginPath();
|
||||
c.rect(10, 10, 200, 200);
|
||||
c.drawSystemFocusRing(in1);
|
||||
c.beginPath();
|
||||
c.rect(10, 220, 200, 200);
|
||||
c.drawSystemFocusRing(in2);
|
||||
}
|
||||
in1.focus();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="myCanvas" height="500" width="500" style="border:1px solid black">
|
||||
<input id="in1" type="range" min="1" max="12">
|
||||
<input id="in2" type="range" min="1" max="12">
|
||||
</canvas>
|
||||
|
||||
</body></html>
|
@ -188,3 +188,7 @@ skip-if(!winWidget) pref(webgl.prefer-native-gl,true) pref(webgl.prefer-16bpp,tr
|
||||
|
||||
# Bug 815648
|
||||
== stroketext-shadow.html stroketext-shadow-ref.html
|
||||
|
||||
# focus rings
|
||||
pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawSystemFocusRing.html drawSystemFocusRing-ref.html
|
||||
pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawCustomFocusRing.html drawCustomFocusRing-ref.html
|
||||
|
98
content/canvas/test/test_canvas_focusring.html
Normal file
98
content/canvas/test/test_canvas_focusring.html
Normal file
@ -0,0 +1,98 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title>Canvas Tests</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<body>
|
||||
<script>
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
const Cc = SpecialPowers.Cc;
|
||||
const Cr = SpecialPowers.Cr;
|
||||
SpecialPowers.setBoolPref("canvas.focusring.enabled", true);
|
||||
</script>
|
||||
|
||||
<p>Canvas test: drawCustomFocusRing</p>
|
||||
<canvas id="c688" class="output" width="100" height="50">+
|
||||
<input id="button1" type="range" min="1" max="12"></input>
|
||||
<input id="button2" type="range" min="1" max="12"></input>
|
||||
</canvas>
|
||||
<script type="text/javascript">
|
||||
function test_drawCustomFocusRing_canvas() {
|
||||
var c = document.getElementById("c688");
|
||||
var ctx = c.getContext("2d");
|
||||
ctx.beginPath();
|
||||
var b1 = document.getElementById('button1');
|
||||
var b2 = document.getElementById('button2');
|
||||
ok(!ctx.drawCustomFocusRing(b1), "button 1 is focused");
|
||||
ok(!ctx.drawCustomFocusRing(b2), "button 2 is focused");
|
||||
b1.focus();
|
||||
ok(ctx.drawCustomFocusRing(b1), "button 1 should not be focused");
|
||||
}
|
||||
</script>
|
||||
|
||||
<p>Canvas test: drawSystemFocusRing</p>
|
||||
<canvas id="c689" class="output" width="50" height="25">
|
||||
<input id="button3" type="range" min="1" max="12"></input>
|
||||
<input id="button4" type="range" min="1" max="12"></input>
|
||||
</canvas>
|
||||
<script type="text/javascript">
|
||||
function isEmptyCanvas(ctx, w, h) {
|
||||
var imgdata = ctx.getImageData(0, 0, w, h);
|
||||
for(var x = 0; x < w*h*4; x++)
|
||||
if(imgdata.data[x] != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function test_drawSystemFocusRing_canvas() {
|
||||
var c = document.getElementById("c689");
|
||||
var ctx = c.getContext("2d");
|
||||
var b1 = document.getElementById('button3');
|
||||
var b2 = document.getElementById('button4');
|
||||
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
ctx.beginPath();
|
||||
ctx.rect(10, 10, 30, 30);
|
||||
ctx.drawSystemFocusRing(b1);
|
||||
ok(isEmptyCanvas(ctx, ctx.canvas.width, ctx.canvas.height), "focus of button 1 is drawn");
|
||||
|
||||
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
ctx.beginPath();
|
||||
ctx.rect(50, 10, 30, 30);
|
||||
ctx.drawSystemFocusRing(b2);
|
||||
ctx.rect(50, 10, 30, 30);
|
||||
ctx.drawSystemFocusRing(b2);
|
||||
ok(isEmptyCanvas(ctx, ctx.canvas.width, ctx.canvas.height), "focus of button 2 is drawn");
|
||||
|
||||
b1.focus();
|
||||
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
ctx.beginPath();
|
||||
ctx.rect(10, 10, 30, 30);
|
||||
ctx.drawSystemFocusRing(b1);
|
||||
ok(!isEmptyCanvas(ctx, ctx.canvas.width, ctx.canvas.height) , "focus of button 1 is not drawn");
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function runTests() {
|
||||
try {
|
||||
test_drawCustomFocusRing_canvas();
|
||||
} catch(e) {
|
||||
throw e;
|
||||
ok(false, "unexpected exception thrown in: test_drawCustomFocusRing_canvas");
|
||||
}
|
||||
try {
|
||||
test_drawSystemFocusRing_canvas();
|
||||
} catch(e) {
|
||||
throw e;
|
||||
ok(false, "unexpected exception thrown in: test_drawSystemFocusRing_canvas");
|
||||
}
|
||||
|
||||
SpecialPowers.setBoolPref("canvas.focusring.enabled", false);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addLoadEvent(runTests);
|
||||
|
||||
</script>
|
@ -77,10 +77,10 @@ interface CanvasRenderingContext2D {
|
||||
// NOT IMPLEMENTED void fill(Path path);
|
||||
void stroke();
|
||||
// NOT IMPLEMENTED void stroke(Path path);
|
||||
// NOT IMPLEMENTED void drawSystemFocusRing(Element element);
|
||||
// NOT IMPLEMENTED void drawSystemFocusRing(Path path, Element element);
|
||||
// NOT IMPLEMENTED boolean drawCustomFocusRing(Element element);
|
||||
// NOT IMPLEMENTED boolean drawCustomFocusRing(Path path, Element element);
|
||||
[Pref="canvas.focusring.enabled"] void drawSystemFocusRing(Element element);
|
||||
// NOT IMPLEMENTED void drawSystemFocusRing(Path path, HTMLElement element);
|
||||
[Pref="canvas.focusring.enabled"] boolean drawCustomFocusRing(Element element);
|
||||
// NOT IMPLEMENTED boolean drawCustomFocusRing(Path path, HTMLElement element);
|
||||
// NOT IMPLEMENTED void scrollPathIntoView();
|
||||
// NOT IMPLEMENTED void scrollPathIntoView(Path path);
|
||||
void clip(optional CanvasWindingRule winding = "nonzero");
|
||||
|
@ -421,6 +421,9 @@ pref("ui.scrollToClick", 0);
|
||||
pref("accessibility.tabfocus_applies_to_xul", true);
|
||||
#endif
|
||||
|
||||
// provide ability to turn on support for canvas focus rings
|
||||
pref("canvas.focusring.enabled", false);
|
||||
|
||||
// We want the ability to forcibly disable platform a11y, because
|
||||
// some non-a11y-related components attempt to bring it up. See bug
|
||||
// 538530 for details about Windows; we have a pref here that allows it
|
||||
|
@ -100,6 +100,7 @@
|
||||
"content/base/test/test_child_process_shutdown_message.html":"specialpowers.wrap issue, NS_ERROR_XPC_GS_RETURNED_FAILURE",
|
||||
"content/base/test/test_messagemanager_assertpermission.html":"specialpowers.wrap issue, NS_ERROR_XPC_GS_RETURNED_FAILURE",
|
||||
|
||||
"content/canvas/test/test_canvas_focusring.html":"specialpowers.wrap",
|
||||
|
||||
"content/html/content/test/test_formSubmission.html":"NS_ERROR_FILE_TARGET_DOES_NOT_EXIST",
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user