Index: source =================================================================== --- source (revision 6033) +++ source (working copy) @@ -37489,42 +37489,43 @@ interface TextTrackCue { // rects void clearRect(in double x, in double y, in double w, in double h); void fillRect(in double x, in double y, in double w, in double h); void strokeRect(in double x, in double y, in double w, in double h); // path API void beginPath(); void closePath(); void moveTo(in double x, in double y); void lineTo(in double x, in double y); void quadraticCurveTo(in double cpx, in double cpy, in double x, in double y); void bezierCurveTo(in double cp1x, in double cp1y, in double cp2x, in double cp2y, in double x, in double y); void arcTo(in double x1, in double y1, in double x2, in double y2, in double radius); void rect(in double x, in double y, in double w, in double h); void arc(in double x, in double y, in double radius, in double startAngle, in double endAngle, in optional boolean anticlockwise); void fill(); void stroke(); void clip(); boolean isPointInPath(in double x, in double y); - // focus management - boolean drawFocusRing(in Element element, in double xCaret, in double yCaret, in optional boolean canDrawCustom); + // focus and selection management + boolean drawFocusRing(in Element element, in optional boolean canDrawCustom); + void setCaretSelectionPos(in Element element, in double x, in double y, in double w, in double h); // text attribute DOMString font; // (default 10px sans-serif) attribute DOMString textAlign; // "start", "end", "left", "right", "center" (default: "start") attribute DOMString textBaseline; // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic") void fillText(in DOMString text, in double x, in double y, in optional double maxWidth); void strokeText(in DOMString text, in double x, in double y, in optional double maxWidth); TextMetrics measureText(in DOMString text); // drawing images void drawImage(in HTMLImageElement image, in double dx, in double dy, in optional double dw, in double dh); void drawImage(in HTMLImageElement image, in double sx, in double sy, in double sw, in double sh, in double dx, in double dy, in double dw, in double dh); void drawImage(in HTMLCanvasElement image, in double dx, in double dy, in optional double dw, in double dh); void drawImage(in HTMLCanvasElement image, in double sx, in double sy, in double sw, in double sh, in double dx, in double dy, in double dw, in double dh); void drawImage(in HTMLVideoElement image, in double dx, in double dy, in optional double dw, in double dh); void drawImage(in HTMLVideoElement image, in double sx, in double sy, in double sw, in double sh, in double dx, in double dy, in double dw, in double dh); // pixel manipulation @@ -39369,193 +39370,310 @@ hairline width with transform. ack Shaun non-zero winding number rule; and must return false otherwise. Points on the path itself are considered to be inside the path. If either of the arguments is infinite or NaN, then the method must return false.
When a canvas is interactive, authors should include focusable elements in the element's fallback content corresponding to each focusable part of the canvas.
To indicate which focusable part of the canvas is currently
focused, authors should use the drawFocusRing() method,
passing it the element for which a ring is being drawn. This method
only draws the focus ring if the element is focused, so that it can
simply be called whenever drawing the element, without checking
- whether the element is focused or not first. The position of the
- center of the control, or of the editing caret if the control has
- one, should be given in the x and y arguments.
drawFocusRing(element, x, y, [ canDrawCustom ])drawFocusRing(element, [ canDrawCustom ])If the given element is focused, draws a focus ring around the current path, following the platform conventions for focus - rings. The given coordinate is used if the user's attention needs - to be brought to a particular position (e.g. if a magnifier is - following the editing caret in a text field).
+ rings.If the canDrawCustom argument is true, then the focus ring is only drawn if the user has configured his system to draw focus rings in a particular manner. (For example, high contrast focus rings.)
Returns true if the given element is focused, the canDrawCustom argument is true, and the user has not configured his system to draw focus rings in a particular manner. Otherwise, returns false.
When the method returns true, the author is expected to manually draw a focus ring.
The drawFocusRing(element, x, y, [canDrawCustom])
- method, when invoked, must run the following steps:
If element is not focused or is not a descendant of the element with whose context the method is associated, then return false and abort these steps.
Transform the given point (x, y) according to the current transformation - matrix.
Optionally, inform the user that the focus is at the given - (transformed) coordinate on the canvas. (For example, this could - involve moving the user's magnification tool.)
If the user has requested the use of particular focus rings (e.g. high-contrast focus rings), or if the canDrawCustom argument is absent or false, then draw a focus ring of the appropriate style along the path, following platform conventions, return false, and abort these steps.
The focus ring should not be subject to the shadow effects, the global alpha, or the global composition operators, but should be subject to the clipping region.
Optionally, inform the user that the focus is at the + location given by the path. (For example, this could involve moving + the user's magnification tool.) User agents may wait until the next + time the event loop reaches its "update the rendering" + step to optionally inform the user.
Return true.
This canvas element has a couple of checkboxes:
<canvas height=400 width=750>
<label><input type=checkbox id=showA> Show As</label>
<label><input type=checkbox id=showB> Show Bs</label>
<!-- ... -->
</canvas>
<script>
- function drawCheckbox(context, element, x, y) {
+ function drawCheckbox(context, element, x, y, paint) {
context.save();
context.font = '10px sans-serif';
context.textAlign = 'left';
context.textBaseline = 'middle';
var metrics = context.measureText(element.labels[0].textContent);
- context.beginPath();
- context.strokeStyle = 'black';
- context.rect(x-5, y-5, 10, 10);
- context.stroke();
- if (element.checked) {
- context.fillStyle = 'black';
- context.fill();
+ if (paint) {
+ context.beginPath();
+ context.strokeStyle = 'black';
+ context.rect(x-5, y-5, 10, 10);
+ context.stroke();
+ if (element.checked) {
+ context.fillStyle = 'black';
+ context.fill();
+ }
+ context.fillText(element.labels[0].textContent, x+5, y);
}
- context.fillText(element.labels[0].textContent, x+5, y);
context.beginPath();
context.rect(x-7, y-7, 12 + metrics.width+2, 14);
- if (context.drawFocusRing(element, x, y, true)) {
+ if (paint && context.drawFocusRing(element, x, y, true)) {
context.strokeStyle = 'silver';
context.stroke();
}
context.restore();
}
function drawBase() { /* ... */ }
function drawAs() { /* ... */ }
function drawBs() { /* ... */ }
function redraw() {
var canvas = document.getElementsByTagName('canvas')[0];
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
- drawCheckbox(context, document.getElementById('showA'), 20, 40);
- drawCheckbox(context, document.getElementById('showB'), 20, 60);
+ drawCheckbox(context, document.getElementById('showA'), 20, 40, true);
+ drawCheckbox(context, document.getElementById('showB'), 20, 60, true);
drawBase();
if (document.getElementById('showA').checked)
drawAs();
if (document.getElementById('showB').checked)
drawBs();
}
function processClick(event) {
var canvas = document.getElementsByTagName('canvas')[0];
var context = canvas.getContext('2d');
- var x = event.clientX - canvas.offsetLeft;
- var y = event.clientY - canvas.offsetTop;
- drawCheckbox(context, document.getElementById('showA'), 20, 40);
+ var x = event.clientX;
+ var y = event.clientY;
+ while (node) {
+ x -= node.offsetLeft - node.scrollLeft;
+ y -= node.offsetTop - node.scrollTop;
+ node = node.offsetParent;
+ }
+ drawCheckbox(context, document.getElementById('showA'), 20, 40, false);
if (context.isPointInPath(x, y))
document.getElementById('showA').checked = !(document.getElementById('showA').checked);
- drawCheckbox(context, document.getElementById('showB'), 20, 60);
+ drawCheckbox(context, document.getElementById('showB'), 20, 60, false);
if (context.isPointInPath(x, y))
document.getElementById('showB').checked = !(document.getElementById('showB').checked);
redraw();
}
document.getElementsByTagName('canvas')[0].addEventListener('focus', redraw, true);
document.getElementsByTagName('canvas')[0].addEventListener('blur', redraw, true);
document.getElementsByTagName('canvas')[0].addEventListener('change', redraw, true);
document.getElementsByTagName('canvas')[0].addEventListener('click', processClick, false);
redraw();
</script>
Authors should avoid implementing text editing controls using the
+ canvas element. Doing so has a large number of
+ disadvantages:
This is a huge amount of work, and authors are most strongly
+ encouraged to avoid doing any of it by instead using the
+ input element, the textarea element, or
+ the contenteditable
+ attribute.
Authors that eschew these existing solutions and instead take on
+ the monumental task of implementing a text editor from scratch must
+ expose the position of the caret and selection using the setCaretSelectionPos()
+ method.
This method must be passed the element that corresponds to the + text field as its first argument, and the position of the caret or + selection as its four other arguments. The method then reports the + position of the caret position and/or selection size to the + platform's accessibility subsystem, where it can be used to drive a + magnification feature, if any. The method does not have any other + effect.
+ +setCaretSelectionPos(element, x, y, w, h)If the given element is focused, notifies the platform's + accessibilty subsystem that the given element's caret and/or + selection cover the given rectangle.
+ +The setCaretSelectionPos(element, x, w, h) method, when
+ invoked, must run the following steps:
If element is not focused or is not a + descendant of the element with whose context the method is + associated, then return false and abort these steps.
Apply the current transformation + matrix to the following four coordinates, which form a path + that must then be closed to get the specified + rectangle: (x, y), (x+w, y), (x+w, y+h), (x, y+h).
Optionally, inform the user that the caret and/or selection + cover the specified rectangle of the canvas. + (For example, this could involve moving the user's magnification + tool.) User agents may wait until the next time the event + loop reaches its "update the rendering" step to optionally + inform the user.
font [ = value ]Returns the current font settings.
Can be set, to change the font. The syntax is the same as for the CSS 'font' property; values that cannot be parsed as CSS font values are ignored.
Relative keywords and lengths are computed relative to the font
of the canvas element.
textAlign [ = value ]Navigator objectThe navigator
attribute of the Window interface must return an
instance of the Navigator interface, which represents
the identity and state of the user agent (the client), and allows
Web pages to register themselves as potential protocol and content
handlers:
interface Navigator {
// objects implementing this interface also implement the interfaces given below
};
Navigator implements NavigatorID;
Navigator implements NavigatorOnLine;
Navigator implements NavigatorContentUtils;
-Navigator implements NavigatorStorageUtils;
+Navigator implements NavigatorStorageUtils;
+Navigator implements NavigatorUserPreferences;
These interfaces are defined separately so that other
specifications can re-use parts of the Navigator
interface.