Permalink
Browse files

[giow] (0) updated drawFocusRing to take recent feedback into account

git-svn-id: http://svn.whatwg.org/webapps@6125 340c8d12-0b0e-0410-8428-c7bf67bfef74
  • Loading branch information...
1 parent a5cbaae commit 7a8cca384a12988e4acfd7e805e55a60084eef66 @Hixie Hixie committed May 11, 2011
Showing with 745 additions and 330 deletions.
  1. +236 −109 complete.html
  2. +243 −110 index
  3. +266 −111 source
View
345 complete.html
@@ -239,7 +239,7 @@
<header class=head id=head><p><a class=logo href=http://www.whatwg.org/ rel=home><img alt=WHATWG height=101 src=/images/logo width=101></a></p>
<hgroup><h1>Web Applications 1.0</h1>
- <h2 class="no-num no-toc">Living Standard &mdash; Last Updated 9 May 2011</h2>
+ <h2 class="no-num no-toc">Living Standard &mdash; Last Updated 10 May 2011</h2>
</hgroup><p>You can take part in this work. <a href=http://www.whatwg.org/mailing-list>Join the working group's discussion list.</a></p>
<p><strong>Web designers!</strong> We have a <a href=http://blog.whatwg.org/faq/>FAQ</a>, a <a href=http://forums.whatwg.org/>forum</a>, and a <a href=http://www.whatwg.org/mailing-list#help>help mailing list</a> for you!</p>
<!--<p class="impl"><strong>Implementors!</strong> We have a <a href="http://www.whatwg.org/mailing-list#implementors">mailing list</a> for you too!</p>-->
@@ -634,11 +634,11 @@ <h2 class="no-num no-toc" id=contents>Table of contents</h2>
<li><a href=#shadows><span class=secno>4.8.11.1.6 </span>Shadows</a></li>
<li><a href=#simple-shapes-(rectangles)><span class=secno>4.8.11.1.7 </span>Simple shapes (rectangles)</a></li>
<li><a href=#complex-shapes-(paths)><span class=secno>4.8.11.1.8 </span>Complex shapes (paths)</a></li>
- <li><a href=#focus-management-0><span class=secno>4.8.11.1.9 </span>Focus management</a></li>
- <li><a href=#text-0><span class=secno>4.8.11.1.10 </span>Text</a></li>
- <li><a href=#images><span class=secno>4.8.11.1.11 </span>Images</a></li>
- <li><a href=#pixel-manipulation><span class=secno>4.8.11.1.12 </span>Pixel manipulation</a></li>
- <li><a href=#drawing-model><span class=secno>4.8.11.1.13 </span>Drawing model</a></li>
+ <li><a href=#text-0><span class=secno>4.8.11.1.9 </span>Text</a></li>
+ <li><a href=#images><span class=secno>4.8.11.1.10 </span>Images</a></li>
+ <li><a href=#pixel-manipulation><span class=secno>4.8.11.1.11 </span>Pixel manipulation</a></li>
+ <li><a href=#drawing-model><span class=secno>4.8.11.1.12 </span>Drawing model</a></li>
+ <li><a href=#best-practices><span class=secno>4.8.11.1.13 </span>Best practices</a></li>
<li><a href=#examples><span class=secno>4.8.11.1.14 </span>Examples</a></ol></li>
<li><a href=#color-spaces-and-color-correction><span class=secno>4.8.11.2 </span>Color spaces and color correction</a></li>
<li><a href=#security-with-canvas-elements><span class=secno>4.8.11.3 </span>Security with <code>canvas</code> elements</a></ol></li>
@@ -34134,7 +34134,7 @@ <h4 id=the-canvas-element><span class=secno>4.8.11 </span>The <dfn id=canvas><co
<h5 id=2dcontext><span class=secno>4.8.11.1 </span>The 2D context</h5>
- <!-- v2: we're on v4. suggestions for next version are marked v5. -->
+ <!-- v2: we're on v4.1. suggestions for next version are marked v5. -->
@@ -34230,12 +34230,12 @@ <h5 id=2dcontext><span class=secno>4.8.11.1 </span>The 2D context</h5>
void <a href=#dom-context-2d-arc title=dom-context-2d-arc>arc</a>(in double x, in double y, in double radius, in double startAngle, in double endAngle, in optional boolean anticlockwise);
void <a href=#dom-context-2d-fill title=dom-context-2d-fill>fill</a>();
void <a href=#dom-context-2d-stroke title=dom-context-2d-stroke>stroke</a>();
+ void <a href=#dom-context-2d-drawosfocusring title=dom-context-2d-drawOSFocusRing>drawOSFocusRing</a>(in <a href=#element>Element</a> element);
+ boolean <a href=#dom-context-2d-drawcustomfocusring title=dom-context-2d-drawCustomFocusRing>drawCustomFocusRing</a>(in <a href=#element>Element</a> element);
+ void <a href=#dom-context-2d-scrollpathintoview title=dom-context-2d-scrollPathIntoView>scrollPathIntoView</a>();
void <a href=#dom-context-2d-clip title=dom-context-2d-clip>clip</a>();
boolean <a href=#dom-context-2d-ispointinpath title=dom-context-2d-isPointInPath>isPointInPath</a>(in double x, in double y);
- // focus management
- boolean <a href=#dom-context-2d-drawfocusring title=dom-context-2d-drawFocusRing>drawFocusRing</a>(in <a href=#element>Element</a> element, in double xCaret, in double yCaret, in optional boolean canDrawCustom);
-
// text
attribute DOMString <a href=#dom-context-2d-font title=dom-context-2d-font>font</a>; // (default 10px sans-serif)
attribute DOMString <a href=#dom-context-2d-textalign title=dom-context-2d-textAlign>textAlign</a>; // "start", "end", "left", "right", "center" (default: "start")
@@ -35550,6 +35550,42 @@ <h6 id=complex-shapes-(paths)><span class=secno>4.8.11.1.8 </span>Complex shapes
</dd>
+ <dt><var title="">context</var> . <code title=dom-context-2d-drawOSFocusRing><a href=#dom-context-2d-drawosfocusring>drawOSFocusRing</a></code>(<var title="">element</var>)</dt>
+
+ <dd>
+
+ <p>If the given element is focused, draws a focus ring around the
+ current path, following the platform conventions for focus
+ rings.</p>
+
+ </dd>
+
+ <dt><var title="">shouldDraw</var> = <var title="">context</var> . <code title=dom-context-2d-drawCustomFocusRing><a href=#dom-context-2d-drawcustomfocusring>drawCustomFocusRing</a></code>(<var title="">element</var>)</dt>
+
+ <dd>
+
+ <p>If the given element is focused, and the user has configured
+ his system to draw focus rings in a particular manner (for
+ example, high contrast focus rings), draws a focus ring around the
+ current path and returns false.</p>
+
+ <p>Otherwise, returns true if the given element is focused, and
+ false otherwise. This can thus be used to determine when to draw a
+ focus ring (see <a href=#drawCustomFocusRingExample>the
+ example</a> below).</p>
+
+ </dd>
+
+ <dt><var title="">context</var> . <code title=dom-context-2d-scrollPathIntoView><a href=#dom-context-2d-scrollpathintoview>scrollPathIntoView</a></code>()</dt>
+
+ <dd>
+
+ <p>Scrolls the current path into view. This is especially useful
+ on devices with small screens, where the whole canvas might not be
+ visible at once.</p>
+
+ </dd>
+
<dt><var title="">context</var> . <code title=dom-context-2d-clip><a href=#dom-context-2d-clip>clip</a></code>()</dt>
<dd>
@@ -35752,8 +35788,100 @@ <h6 id=complex-shapes-(paths)><span class=secno>4.8.11.1.8 </span>Complex shapes
<p>Zero-length line segments must be pruned before stroking a
path. Empty subpaths must be ignored.</p>
+ <hr><p>The <dfn id=dom-context-2d-drawosfocusring title=dom-context-2d-drawOSFocusRing><code>drawOSFocusRing(<var title="">element</var>)</code></dfn> method, when invoked,
+ must run the following steps:</p>
+
+ <ol><li><p>If <var title="">element</var> is not focused or is not a
+ descendant of the element with whose context the method is
+ associated, then abort these steps.</li>
+
+ <li>
+
+ <p>If the user has requested the use of particular focus rings
+ (e.g. high-contrast focus rings), or if the <var title="">element</var> would have a focus ring drawn around it,
+ then draw a focus ring of the appropriate style along the path,
+ following platform conventions, and abort these steps.</p>
+
+ <p class=note>Some platforms only draw focus rings around
+ elements that have been focused from the keyboard, and not those
+ focused from the mouse. Other platforms simply don't draw focus
+ rings around some elements at all unless relevant accessibility
+ features are enabled. This API is intended to follow these
+ conventions.</p>
+
+ <p>The focus ring should not be subject to the <a href=#shadows title=shadows>shadow effects</a>, the <a href=#dom-context-2d-globalalpha title=dom-context-2d-globalAlpha>global alpha</a>, or the <a href=#dom-context-2d-globalcompositeoperation title=dom-context-2d-globalCompositeOperation>global composition
+ operators</a>, but <em>should</em> be subject to the <a href=#clipping-region title="clipping region">clipping region</a>.</p>
+
+ </li>
+
+ <li>
+
+ <p>Optionally, <a href=#inform>inform the user</a> that the
+ focus is at the location given by the path. User agents may wait
+ until the next time the <a href=#event-loop>event loop</a> reaches its
+ "update the rendering" step to optionally inform the user.</p>
+
+ </li>
+
+ </ol><p>The <dfn id=dom-context-2d-drawcustomfocusring title=dom-context-2d-drawCustomFocusRing><code>drawCustomFocusRing(<var title="">element</var>)</code></dfn> method, when invoked, must run
+ the following steps:</p>
+
+ <ol><li><p>If <var title="">element</var> 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.</li>
+
+ <li>
+
+ <p>If the user has requested the use of particular focus rings
+ (e.g. high-contrast focus rings), then draw a focus ring of the
+ appropriate style along the path, return false, and abort these
+ steps.</p>
+
+ <p>The focus ring should not be subject to the <a href=#shadows title=shadows>shadow effects</a>, the <a href=#dom-context-2d-globalalpha title=dom-context-2d-globalAlpha>global alpha</a>, or the <a href=#dom-context-2d-globalcompositeoperation title=dom-context-2d-globalCompositeOperation>global composition
+ operators</a>, but <em>should</em> be subject to the <a href=#clipping-region title="clipping region">clipping region</a>.</p>
+
+ </li>
+
+ <li>
+
+ <p>Optionally, <a href=#inform>inform the user</a> that the
+ focus is at the location given by the path. User agents may wait
+ until the next time the <a href=#event-loop>event loop</a> reaches its
+ "update the rendering" step to optionally inform the user.</p>
+
+ </li>
+
+ <li><p>Return true.</li>
- <p>The <dfn id=dom-context-2d-clip title=dom-context-2d-clip><code>clip()</code></dfn>
+ </ol><p>The <dfn id=dom-context-2d-scrollpathintoview title=dom-context-2d-scrollPathIntoView><code>scrollPathIntoView()</code></dfn>
+ method, when invoked, must run the following steps:</p>
+
+ <ol><li><p>Let <var title="">notional child</var> be a hypothetical
+ element that is a rendered child of the <code><a href=#the-canvas-element>canvas</a></code> element
+ whose dimensions are exactly the rectangle of the bounding box of
+ the current path.</li>
+
+ <li><p><span title="scroll an element into view">Scroll <var title="">notional child</var> into view</span> with the <var title="">align to top flag</var> set.</p>
+
+ <li><p>Optionally, <a href=#inform>inform the user</a> that the
+ caret and/or selection cover <var title="">the specified
+ rectangle</var> of the canvas. User agents may wait until the next
+ time the <a href=#event-loop>event loop</a> reaches its "update the rendering"
+ step to optionally inform the user.</li>
+
+ </ol><p class=note id=inform>"Inform the user", as used in this
+ section, could mean calling a system accessibility API, which would
+ notify assistive technologies such as magnification tools. To
+ properly drive magnification based on a focus change, a system
+ accessibility API driving a screen magnifier needs the bounds for
+ the newly focused object. The methods above are intended to enable
+ this by allowing the user agent to report the bounding box of the
+ path used to render the focus ring as the bounds of the <var title="">element</var> element passed as an argument, if that
+ element is focused, and the bounding box of the area to which the
+ user agent is scrolling as the bounding box of the current
+ selection.</p>
+
+ <hr><p>The <dfn id=dom-context-2d-clip title=dom-context-2d-clip><code>clip()</code></dfn>
method must create a new <dfn id=clipping-region>clipping region</dfn> by calculating
the intersection of the current clipping region and the area
described by the current path, using the non-zero winding number
@@ -35772,8 +35900,7 @@ <h6 id=complex-shapes-(paths)><span class=secno>4.8.11.1.8 </span>Complex shapes
* support ways of resetting the clipping region without save/restore
-->
-
- <p>The <dfn id=dom-context-2d-ispointinpath title=dom-context-2d-isPointInPath><code>isPointInPath(<var title="">x</var>, <var title="">y</var>)</code></dfn> method must
+ <hr><p>The <dfn id=dom-context-2d-ispointinpath title=dom-context-2d-isPointInPath><code>isPointInPath(<var title="">x</var>, <var title="">y</var>)</code></dfn> method must
return true if the point given by the <var title="">x</var> and <var title="">y</var> coordinates passed to the method, when treated as
coordinates in the canvas coordinate space unaffected by the current
transformation, is inside the current path as determined by the
@@ -35785,110 +35912,41 @@ <h6 id=complex-shapes-(paths)><span class=secno>4.8.11.1.8 </span>Complex shapes
</div>
- <h6 id=focus-management-0><span class=secno>4.8.11.1.9 </span>Focus management</h6> <!-- a v4 feature -->
+ <div class=example id=drawCustomFocusRingExample>
- <p>When a canvas is interactive, authors should include focusable
- elements in the element's fallback content corresponding to each
- focusable part of the canvas.</p>
-
- <p>To indicate which focusable part of the canvas is currently
- focused, authors should use the <code title=dom-context-2d-drawFocusRing><a href=#dom-context-2d-drawfocusring>drawFocusRing()</a></code> 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 <var title="">x</var> and <var title="">y</var> arguments.</p>
-
- <dl class=domintro><dt><var title="">shouldDraw</var> = <var title="">context</var> . <code title=dom-context-2d-drawFocusRing><a href=#dom-context-2d-drawfocusring>drawFocusRing</a></code>(<var title="">element</var>, <var title="">x</var>, <var title="">y</var>, [ <var title="">canDrawCustom</var> ])</dt>
-
- <dd>
-
- <p>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).</p>
-
- <p>If the <var title="">canDrawCustom</var> 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.)</p>
-
- <p>Returns true if the given element is focused, the <var title="">canDrawCustom</var> argument is true, and the user has
- not configured his system to draw focus rings in a particular
- manner. Otherwise, returns false.</p>
-
- <p>When the method returns true, the author is expected to
- manually draw a focus ring.</p>
-
- </dd>
-
- </dl><div class=impl>
-
- <p>The <dfn id=dom-context-2d-drawfocusring title=dom-context-2d-drawFocusRing><code>drawFocusRing(<var title="">element</var>, <var title="">x</var>, <var title="">y</var>, [<var title="">canDrawCustom</var>])</code></dfn>
- method, when invoked, must run the following steps:</p>
-
- <ol><li><p>If <var title="">element</var> 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.</li>
-
- <li><p>Transform the given point (<var title="">x</var>, <var title="">y</var>) according to the <a href=#transformations title=dom-context-2d-transformation>current transformation
- matrix</a>.</li>
-
- <li><p>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.)</li>
-
- <li>
-
- <p>If the user has requested the use of particular focus rings
- (e.g. high-contrast focus rings), or if the <var title="">canDrawCustom</var> 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.</p>
-
- <p>The focus ring should not be subject to the <a href=#shadows title=shadows>shadow effects</a>, the <a href=#dom-context-2d-globalalpha title=dom-context-2d-globalAlpha>global alpha</a>, or the <a href=#dom-context-2d-globalcompositeoperation title=dom-context-2d-globalCompositeOperation>global composition
- operators</a>, but <em>should</em> be subject to the <a href=#clipping-region title="clipping region">clipping region</a>.</p>
-
- </li>
-
- <li><p>Return true.</li>
-
- </ol></div>
-
- <div class=example>
-
- <p>This <code><a href=#the-canvas-element>canvas</a></code> element has a couple of checkboxes:</p>
+ <p>This <code><a href=#the-canvas-element>canvas</a></code> element has a couple of checkboxes. The
+ path-related commands are highlighted:</p>
<pre>&lt;canvas height=400 width=750&gt;
&lt;label&gt;&lt;input type=checkbox id=showA&gt; Show As&lt;/label&gt;
&lt;label&gt;&lt;input type=checkbox id=showB&gt; Show Bs&lt;/label&gt;
&lt;!-- ... --&gt;
&lt;/canvas&gt;
&lt;script&gt;
- 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) {
+<strong> context.beginPath();
+ context.strokeStyle = 'black';
+ context.rect(x-5, y-5, 10, 10);
+ context.stroke();
+</strong> if (element.checked) {
+<strong> context.fillStyle = 'black';
+ context.fill();
+</strong> }
+ context.fillText(element.labels[0].textContent, x+5, y);
}
- context.fillText(element.labels[0].textContent, x+5, y);
- context.beginPath();
+<strong> context.beginPath();
context.rect(x-7, y-7, 12 + metrics.width+2, 14);
- if (context.drawFocusRing(element, x, y, true)) {
+ if (paint &amp;&amp; context.drawCustomFocusRing(element)) {
context.strokeStyle = 'silver';
context.stroke();
}
- context.restore();
+</strong> context.restore();
}
function drawBase() { /* ... */ }
function drawAs() { /* ... */ }
@@ -35897,8 +35955,8 @@ <h6 id=focus-management-0><span class=secno>4.8.11.1.9 </span>Focus management</
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();
@@ -35908,12 +35966,17 @@ <h6 id=focus-management-0><span class=secno>4.8.11.1.9 </span>Focus management</
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();
@@ -35929,7 +35992,9 @@ <h6 id=focus-management-0><span class=secno>4.8.11.1.9 </span>Focus management</
</div>
- <h6 id=text-0><span class=secno>4.8.11.1.10 </span>Text</h6> <!-- a v3 feature -->
+
+
+ <h6 id=text-0><span class=secno>4.8.11.1.9 </span>Text</h6> <!-- a v3 feature -->
<dl class=domintro><dt><var title="">context</var> . <code title=dom-context-2d-font><a href=#dom-context-2d-font>font</a></code> [ = <var title="">value</var> ]</dt>
@@ -36437,7 +36502,7 @@ <h6 id=text-0><span class=secno>4.8.11.1.10 </span>Text</h6> <!-- a v3 feature -
- <h6 id=images><span class=secno>4.8.11.1.11 </span>Images</h6>
+ <h6 id=images><span class=secno>4.8.11.1.10 </span>Images</h6>
<p>To draw images onto the canvas, the <dfn id=dom-context-2d-drawimage title=dom-context-2d-drawImage><code>drawImage</code></dfn> method
can be used.</p>
@@ -36578,7 +36643,7 @@ <h6 id=images><span class=secno>4.8.11.1.11 </span>Images</h6>
- <h6 id=pixel-manipulation><span class=secno>4.8.11.1.12 </span><dfn>Pixel manipulation</dfn></h6>
+ <h6 id=pixel-manipulation><span class=secno>4.8.11.1.11 </span><dfn>Pixel manipulation</dfn></h6>
<dl class=domintro><dt><var title="">imagedata</var> = <var title="">context</var> . <code title=dom-context-2d-createImageData><a href=#dom-context-2d-createimagedata>createImageData</a></code>(<var title="">sw</var>, <var title="">sh</var>)</dt>
@@ -36937,7 +37002,7 @@ <h6 id=pixel-manipulation><span class=secno>4.8.11.1.12 </span><dfn>Pixel manipu
<div class=impl>
- <h6 id=drawing-model><span class=secno>4.8.11.1.13 </span><dfn>Drawing model</dfn></h6>
+ <h6 id=drawing-model><span class=secno>4.8.11.1.12 </span><dfn>Drawing model</dfn></h6>
<p>When a shape or image is painted, user agents must follow these
steps, in the order given (or act as if they do):</p>
@@ -36968,6 +37033,68 @@ <h6 id=drawing-model><span class=secno>4.8.11.1.13 </span><dfn>Drawing model</df
</ol></div>
+ <h6 id=best-practices><span class=secno>4.8.11.1.13 </span>Best practices</h6>
+
+ <p><i>This section is non-normative.</i></p>
+
+ <p>When a canvas is interactive, authors should include focusable
+ elements in the element's fallback content corresponding to each
+ focusable part of the canvas, as in the <a href=#drawCustomFocusRingExample>example above</a>.</p>
+
+ <p>To indicate which focusable part of the canvas is currently
+ focused, authors should use the <code title=dom-context-2d-drawOSFocusRing><a href=#dom-context-2d-drawosfocusring>drawOSFocusRing()</a></code> 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.</p>
+
+ <p>Authors should avoid implementing text editing controls using the
+ <code><a href=#the-canvas-element>canvas</a></code> element. Doing so has a large number of
+ disadvantages:</p>
+
+ <ul><li>Mouse placement of the caret has to be reimplemented.</li>
+
+ <li>Keyboard movement of the caret has to be reimplemented (possibly across lines, for multiline text input).</li>
+
+ <li>Scrolling of the text field has to be implemented (horizontally for long lines, vertically for multiline input).</li>
+
+ <li>Native features such as copy-and-paste have to be reimplemented.</li>
+
+ <li>Native features such as spell-checking have to be reimplemented.</li>
+
+ <li>Native features such as drag-and-drop have to be reimplemented.</li>
+
+ <li>Native features such as page-wide text search have to be reimplemented.</li>
+
+ <li>Native features specific to the user, for example custom text
+ services, have to be reimplemented. This is close to impossible
+ since each user might have different services installed, and there
+ is an unbounded set of possible such services.</li>
+
+ <li>Bidirectional text editing has to be reimplemented.</li>
+
+ <li>For multiline text editing, line wrapping has to be implemented for all relevant languages.</li>
+
+ <li>Text selection has to be reimplemented.</li>
+
+ <li>Dragging of bidirectional text selections has to be reimplemented.</li>
+
+ <li>Platform-native keyboard shortcuts have to be reimplemented.</li>
+
+ <li>Platform-native input method editors (IMEs) have to be reimplemented.</li>
+
+ <li>Undo and redo functionality has to be reimplemented.</li>
+
+ <li>Accessibility features such as magnification following the
+ caret or selection have to be reimplemented.</li>
+
+ </ul><p>This is a huge amount of work, and authors are most strongly
+ encouraged to avoid doing any of it by instead using the
+ <code><a href=#the-input-element>input</a></code> element, the <code><a href=#the-textarea-element>textarea</a></code> element, or
+ the <code title=attr-contenteditable><a href=#attr-contenteditable>contenteditable</a></code>
+ attribute.</p>
+
+
<h6 id=examples><span class=secno>4.8.11.1.14 </span>Examples</h6>
<p><i>This section is non-normative.</i></p>
View
353 index
@@ -243,7 +243,7 @@
<header class=head id=head><p><a class=logo href=http://www.whatwg.org/ rel=home><img alt=WHATWG height=101 src=/images/logo width=101></a></p>
<hgroup><h1 class=allcaps>HTML</h1>
- <h2 class="no-num no-toc">Living Standard &mdash; Last Updated 9 May 2011</h2>
+ <h2 class="no-num no-toc">Living Standard &mdash; Last Updated 10 May 2011</h2>
</hgroup><p>You can take part in this work. <a href=http://www.whatwg.org/mailing-list>Join the working group's discussion list.</a></p>
<p><strong>Web designers!</strong> We have a <a href=http://blog.whatwg.org/faq/>FAQ</a>, a <a href=http://forums.whatwg.org/>forum</a>, and a <a href=http://www.whatwg.org/mailing-list#help>help mailing list</a> for you!</p>
<!--<p class="impl"><strong>Implementors!</strong> We have a <a href="http://www.whatwg.org/mailing-list#implementors">mailing list</a> for you too!</p>-->
@@ -642,11 +642,11 @@
<li><a href=#shadows><span class=secno>4.8.11.1.6 </span>Shadows</a></li>
<li><a href=#simple-shapes-(rectangles)><span class=secno>4.8.11.1.7 </span>Simple shapes (rectangles)</a></li>
<li><a href=#complex-shapes-(paths)><span class=secno>4.8.11.1.8 </span>Complex shapes (paths)</a></li>
- <li><a href=#focus-management-0><span class=secno>4.8.11.1.9 </span>Focus management</a></li>
- <li><a href=#text-0><span class=secno>4.8.11.1.10 </span>Text</a></li>
- <li><a href=#images><span class=secno>4.8.11.1.11 </span>Images</a></li>
- <li><a href=#pixel-manipulation><span class=secno>4.8.11.1.12 </span>Pixel manipulation</a></li>
- <li><a href=#drawing-model><span class=secno>4.8.11.1.13 </span>Drawing model</a></li>
+ <li><a href=#text-0><span class=secno>4.8.11.1.9 </span>Text</a></li>
+ <li><a href=#images><span class=secno>4.8.11.1.10 </span>Images</a></li>
+ <li><a href=#pixel-manipulation><span class=secno>4.8.11.1.11 </span>Pixel manipulation</a></li>
+ <li><a href=#drawing-model><span class=secno>4.8.11.1.12 </span>Drawing model</a></li>
+ <li><a href=#best-practices><span class=secno>4.8.11.1.13 </span>Best practices</a></li>
<li><a href=#examples><span class=secno>4.8.11.1.14 </span>Examples</a></ol></li>
<li><a href=#color-spaces-and-color-correction><span class=secno>4.8.11.2 </span>Color spaces and color correction</a></li>
<li><a href=#security-with-canvas-elements><span class=secno>4.8.11.3 </span>Security with <code>canvas</code> elements</a></ol></li>
@@ -1424,7 +1424,13 @@
<li><a href=#mdvocabs>Microdata vocabularies</a>
<li><a href=#crossDocumentMessages>Cross-document messaging</a> (also known as Communications)<!--POSTMSG-->
<li><a href=#channel-messaging>Channel messaging</a> (also known as Communications)<!--POSTMSG-->
- </ul><p>The <a href=#forms>forms</a> part of this specification was
+ </ul><p>The specification that covers the Canvas 2D Graphics Context at
+ the W3C does not include all the advice included in the equivalent
+ section in this document, because of <a href=http://lists.w3.org/Archives/Public/public-html/2011Apr/0712.html>the
+ discussion</a> that followed <a href=http://lists.w3.org/Archives/Public/public-html/2011Apr/0271.html>a
+ working gorup decision from April 2011</a>.</p>
+
+ <p>The <a href=#forms>forms</a> part of this specification was
previously published separately in a specification known as Web
Forms 2.</p>
@@ -34162,7 +34168,7 @@ interface <dfn id=texttrackcue>TextTrackCue</dfn> {
<h5 id=2dcontext><span class=secno>4.8.11.1 </span>The 2D context</h5>
- <!-- v2: we're on v4. suggestions for next version are marked v5. -->
+ <!-- v2: we're on v4.1. suggestions for next version are marked v5. -->
@@ -34258,12 +34264,12 @@ interface <dfn id=texttrackcue>TextTrackCue</dfn> {
void <a href=#dom-context-2d-arc title=dom-context-2d-arc>arc</a>(in double x, in double y, in double radius, in double startAngle, in double endAngle, in optional boolean anticlockwise);
void <a href=#dom-context-2d-fill title=dom-context-2d-fill>fill</a>();
void <a href=#dom-context-2d-stroke title=dom-context-2d-stroke>stroke</a>();
+ void <a href=#dom-context-2d-drawosfocusring title=dom-context-2d-drawOSFocusRing>drawOSFocusRing</a>(in <a href=#element>Element</a> element);
+ boolean <a href=#dom-context-2d-drawcustomfocusring title=dom-context-2d-drawCustomFocusRing>drawCustomFocusRing</a>(in <a href=#element>Element</a> element);
+ void <a href=#dom-context-2d-scrollpathintoview title=dom-context-2d-scrollPathIntoView>scrollPathIntoView</a>();
void <a href=#dom-context-2d-clip title=dom-context-2d-clip>clip</a>();
boolean <a href=#dom-context-2d-ispointinpath title=dom-context-2d-isPointInPath>isPointInPath</a>(in double x, in double y);
- // focus management
- boolean <a href=#dom-context-2d-drawfocusring title=dom-context-2d-drawFocusRing>drawFocusRing</a>(in <a href=#element>Element</a> element, in double xCaret, in double yCaret, in optional boolean canDrawCustom);
-
// text
attribute DOMString <a href=#dom-context-2d-font title=dom-context-2d-font>font</a>; // (default 10px sans-serif)
attribute DOMString <a href=#dom-context-2d-textalign title=dom-context-2d-textAlign>textAlign</a>; // "start", "end", "left", "right", "center" (default: "start")
@@ -35578,6 +35584,42 @@ hairline width with transform. ack Shaun Morris.
</dd>
+ <dt><var title="">context</var> . <code title=dom-context-2d-drawOSFocusRing><a href=#dom-context-2d-drawosfocusring>drawOSFocusRing</a></code>(<var title="">element</var>)</dt>
+
+ <dd>
+
+ <p>If the given element is focused, draws a focus ring around the
+ current path, following the platform conventions for focus
+ rings.</p>
+
+ </dd>
+
+ <dt><var title="">shouldDraw</var> = <var title="">context</var> . <code title=dom-context-2d-drawCustomFocusRing><a href=#dom-context-2d-drawcustomfocusring>drawCustomFocusRing</a></code>(<var title="">element</var>)</dt>
+
+ <dd>
+
+ <p>If the given element is focused, and the user has configured
+ his system to draw focus rings in a particular manner (for
+ example, high contrast focus rings), draws a focus ring around the
+ current path and returns false.</p>
+
+ <p>Otherwise, returns true if the given element is focused, and
+ false otherwise. This can thus be used to determine when to draw a
+ focus ring (see <a href=#drawCustomFocusRingExample>the
+ example</a> below).</p>
+
+ </dd>
+
+ <dt><var title="">context</var> . <code title=dom-context-2d-scrollPathIntoView><a href=#dom-context-2d-scrollpathintoview>scrollPathIntoView</a></code>()</dt>
+
+ <dd>
+
+ <p>Scrolls the current path into view. This is especially useful
+ on devices with small screens, where the whole canvas might not be
+ visible at once.</p>
+
+ </dd>
+
<dt><var title="">context</var> . <code title=dom-context-2d-clip><a href=#dom-context-2d-clip>clip</a></code>()</dt>
<dd>
@@ -35780,8 +35822,100 @@ hairline width with transform. ack Shaun Morris.
<p>Zero-length line segments must be pruned before stroking a
path. Empty subpaths must be ignored.</p>
+ <hr><p>The <dfn id=dom-context-2d-drawosfocusring title=dom-context-2d-drawOSFocusRing><code>drawOSFocusRing(<var title="">element</var>)</code></dfn> method, when invoked,
+ must run the following steps:</p>
+
+ <ol><li><p>If <var title="">element</var> is not focused or is not a
+ descendant of the element with whose context the method is
+ associated, then abort these steps.</li>
+
+ <li>
+
+ <p>If the user has requested the use of particular focus rings
+ (e.g. high-contrast focus rings), or if the <var title="">element</var> would have a focus ring drawn around it,
+ then draw a focus ring of the appropriate style along the path,
+ following platform conventions, and abort these steps.</p>
+
+ <p class=note>Some platforms only draw focus rings around
+ elements that have been focused from the keyboard, and not those
+ focused from the mouse. Other platforms simply don't draw focus
+ rings around some elements at all unless relevant accessibility
+ features are enabled. This API is intended to follow these
+ conventions.</p>
+
+ <p>The focus ring should not be subject to the <a href=#shadows title=shadows>shadow effects</a>, the <a href=#dom-context-2d-globalalpha title=dom-context-2d-globalAlpha>global alpha</a>, or the <a href=#dom-context-2d-globalcompositeoperation title=dom-context-2d-globalCompositeOperation>global composition
+ operators</a>, but <em>should</em> be subject to the <a href=#clipping-region title="clipping region">clipping region</a>.</p>
+
+ </li>
+
+ <li>
+
+ <p>Optionally, <a href=#inform>inform the user</a> that the
+ focus is at the location given by the path. User agents may wait
+ until the next time the <a href=#event-loop>event loop</a> reaches its
+ "update the rendering" step to optionally inform the user.</p>
+
+ </li>
+
+ </ol><p>The <dfn id=dom-context-2d-drawcustomfocusring title=dom-context-2d-drawCustomFocusRing><code>drawCustomFocusRing(<var title="">element</var>)</code></dfn> method, when invoked, must run
+ the following steps:</p>
+
+ <ol><li><p>If <var title="">element</var> 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.</li>
+
+ <li>
+
+ <p>If the user has requested the use of particular focus rings
+ (e.g. high-contrast focus rings), then draw a focus ring of the
+ appropriate style along the path, return false, and abort these
+ steps.</p>
+
+ <p>The focus ring should not be subject to the <a href=#shadows title=shadows>shadow effects</a>, the <a href=#dom-context-2d-globalalpha title=dom-context-2d-globalAlpha>global alpha</a>, or the <a href=#dom-context-2d-globalcompositeoperation title=dom-context-2d-globalCompositeOperation>global composition
+ operators</a>, but <em>should</em> be subject to the <a href=#clipping-region title="clipping region">clipping region</a>.</p>
+
+ </li>
+
+ <li>
+
+ <p>Optionally, <a href=#inform>inform the user</a> that the
+ focus is at the location given by the path. User agents may wait
+ until the next time the <a href=#event-loop>event loop</a> reaches its
+ "update the rendering" step to optionally inform the user.</p>
+
+ </li>
+
+ <li><p>Return true.</li>
+
+ </ol><p>The <dfn id=dom-context-2d-scrollpathintoview title=dom-context-2d-scrollPathIntoView><code>scrollPathIntoView()</code></dfn>
+ method, when invoked, must run the following steps:</p>
- <p>The <dfn id=dom-context-2d-clip title=dom-context-2d-clip><code>clip()</code></dfn>
+ <ol><li><p>Let <var title="">notional child</var> be a hypothetical
+ element that is a rendered child of the <code><a href=#the-canvas-element>canvas</a></code> element
+ whose dimensions are exactly the rectangle of the bounding box of
+ the current path.</li>
+
+ <li><p><span title="scroll an element into view">Scroll <var title="">notional child</var> into view</span> with the <var title="">align to top flag</var> set.</p>
+
+ <li><p>Optionally, <a href=#inform>inform the user</a> that the
+ caret and/or selection cover <var title="">the specified
+ rectangle</var> of the canvas. User agents may wait until the next
+ time the <a href=#event-loop>event loop</a> reaches its "update the rendering"
+ step to optionally inform the user.</li>
+
+ </ol><p class=note id=inform>"Inform the user", as used in this
+ section, could mean calling a system accessibility API, which would
+ notify assistive technologies such as magnification tools. To
+ properly drive magnification based on a focus change, a system
+ accessibility API driving a screen magnifier needs the bounds for
+ the newly focused object. The methods above are intended to enable
+ this by allowing the user agent to report the bounding box of the
+ path used to render the focus ring as the bounds of the <var title="">element</var> element passed as an argument, if that
+ element is focused, and the bounding box of the area to which the
+ user agent is scrolling as the bounding box of the current
+ selection.</p>
+
+ <hr><p>The <dfn id=dom-context-2d-clip title=dom-context-2d-clip><code>clip()</code></dfn>
method must create a new <dfn id=clipping-region>clipping region</dfn> by calculating
the intersection of the current clipping region and the area
described by the current path, using the non-zero winding number
@@ -35800,8 +35934,7 @@ hairline width with transform. ack Shaun Morris.
* support ways of resetting the clipping region without save/restore
-->
-
- <p>The <dfn id=dom-context-2d-ispointinpath title=dom-context-2d-isPointInPath><code>isPointInPath(<var title="">x</var>, <var title="">y</var>)</code></dfn> method must
+ <hr><p>The <dfn id=dom-context-2d-ispointinpath title=dom-context-2d-isPointInPath><code>isPointInPath(<var title="">x</var>, <var title="">y</var>)</code></dfn> method must
return true if the point given by the <var title="">x</var> and <var title="">y</var> coordinates passed to the method, when treated as
coordinates in the canvas coordinate space unaffected by the current
transformation, is inside the current path as determined by the
@@ -35813,110 +35946,41 @@ hairline width with transform. ack Shaun Morris.
</div>
- <h6 id=focus-management-0><span class=secno>4.8.11.1.9 </span>Focus management</h6> <!-- a v4 feature -->
-
- <p>When a canvas is interactive, authors should include focusable
- elements in the element's fallback content corresponding to each
- focusable part of the canvas.</p>
-
- <p>To indicate which focusable part of the canvas is currently
- focused, authors should use the <code title=dom-context-2d-drawFocusRing><a href=#dom-context-2d-drawfocusring>drawFocusRing()</a></code> 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 <var title="">x</var> and <var title="">y</var> arguments.</p>
-
- <dl class=domintro><dt><var title="">shouldDraw</var> = <var title="">context</var> . <code title=dom-context-2d-drawFocusRing><a href=#dom-context-2d-drawfocusring>drawFocusRing</a></code>(<var title="">element</var>, <var title="">x</var>, <var title="">y</var>, [ <var title="">canDrawCustom</var> ])</dt>
-
- <dd>
-
- <p>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).</p>
-
- <p>If the <var title="">canDrawCustom</var> 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.)</p>
-
- <p>Returns true if the given element is focused, the <var title="">canDrawCustom</var> argument is true, and the user has
- not configured his system to draw focus rings in a particular
- manner. Otherwise, returns false.</p>
-
- <p>When the method returns true, the author is expected to
- manually draw a focus ring.</p>
-
- </dd>
-
- </dl><div class=impl>
-
- <p>The <dfn id=dom-context-2d-drawfocusring title=dom-context-2d-drawFocusRing><code>drawFocusRing(<var title="">element</var>, <var title="">x</var>, <var title="">y</var>, [<var title="">canDrawCustom</var>])</code></dfn>
- method, when invoked, must run the following steps:</p>
-
- <ol><li><p>If <var title="">element</var> 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.</li>
-
- <li><p>Transform the given point (<var title="">x</var>, <var title="">y</var>) according to the <a href=#transformations title=dom-context-2d-transformation>current transformation
- matrix</a>.</li>
-
- <li><p>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.)</li>
-
- <li>
-
- <p>If the user has requested the use of particular focus rings
- (e.g. high-contrast focus rings), or if the <var title="">canDrawCustom</var> 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.</p>
+ <div class=example id=drawCustomFocusRingExample>
- <p>The focus ring should not be subject to the <a href=#shadows title=shadows>shadow effects</a>, the <a href=#dom-context-2d-globalalpha title=dom-context-2d-globalAlpha>global alpha</a>, or the <a href=#dom-context-2d-globalcompositeoperation title=dom-context-2d-globalCompositeOperation>global composition
- operators</a>, but <em>should</em> be subject to the <a href=#clipping-region title="clipping region">clipping region</a>.</p>
-
- </li>
-
- <li><p>Return true.</li>
-
- </ol></div>
-
- <div class=example>
-
- <p>This <code><a href=#the-canvas-element>canvas</a></code> element has a couple of checkboxes:</p>
+ <p>This <code><a href=#the-canvas-element>canvas</a></code> element has a couple of checkboxes. The
+ path-related commands are highlighted:</p>
<pre>&lt;canvas height=400 width=750&gt;
&lt;label&gt;&lt;input type=checkbox id=showA&gt; Show As&lt;/label&gt;
&lt;label&gt;&lt;input type=checkbox id=showB&gt; Show Bs&lt;/label&gt;
&lt;!-- ... --&gt;
&lt;/canvas&gt;
&lt;script&gt;
- 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) {
+<strong> context.beginPath();
+ context.strokeStyle = 'black';
+ context.rect(x-5, y-5, 10, 10);
+ context.stroke();
+</strong> if (element.checked) {
+<strong> context.fillStyle = 'black';
+ context.fill();
+</strong> }
+ context.fillText(element.labels[0].textContent, x+5, y);
}
- context.fillText(element.labels[0].textContent, x+5, y);
- context.beginPath();
+<strong> context.beginPath();
context.rect(x-7, y-7, 12 + metrics.width+2, 14);
- if (context.drawFocusRing(element, x, y, true)) {
+ if (paint &amp;&amp; context.drawCustomFocusRing(element)) {
context.strokeStyle = 'silver';
context.stroke();
}
- context.restore();
+</strong> context.restore();
}
function drawBase() { /* ... */ }
function drawAs() { /* ... */ }
@@ -35925,8 +35989,8 @@ hairline width with transform. ack Shaun Morris.
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();
@@ -35936,12 +36000,17 @@ hairline width with transform. ack Shaun Morris.
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();
@@ -35957,7 +36026,9 @@ hairline width with transform. ack Shaun Morris.
</div>
- <h6 id=text-0><span class=secno>4.8.11.1.10 </span>Text</h6> <!-- a v3 feature -->
+
+
+ <h6 id=text-0><span class=secno>4.8.11.1.9 </span>Text</h6> <!-- a v3 feature -->
<dl class=domintro><dt><var title="">context</var> . <code title=dom-context-2d-font><a href=#dom-context-2d-font>font</a></code> [ = <var title="">value</var> ]</dt>
@@ -36465,7 +36536,7 @@ v5DVT (also check for '- -' bits in the part above) --><p>The <dfn id=dom-contex
- <h6 id=images><span class=secno>4.8.11.1.11 </span>Images</h6>
+ <h6 id=images><span class=secno>4.8.11.1.10 </span>Images</h6>
<p>To draw images onto the canvas, the <dfn id=dom-context-2d-drawimage title=dom-context-2d-drawImage><code>drawImage</code></dfn> method
can be used.</p>
@@ -36606,7 +36677,7 @@ v5DVT (also check for '- -' bits in the part above) --><p>The <dfn id=dom-contex
- <h6 id=pixel-manipulation><span class=secno>4.8.11.1.12 </span><dfn>Pixel manipulation</dfn></h6>
+ <h6 id=pixel-manipulation><span class=secno>4.8.11.1.11 </span><dfn>Pixel manipulation</dfn></h6>
<dl class=domintro><dt><var title="">imagedata</var> = <var title="">context</var> . <code title=dom-context-2d-createImageData><a href=#dom-context-2d-createimagedata>createImageData</a></code>(<var title="">sw</var>, <var title="">sh</var>)</dt>
@@ -36965,7 +37036,7 @@ function AddCloud(data, x, y) { ... }</pre>
<div class=impl>
- <h6 id=drawing-model><span class=secno>4.8.11.1.13 </span><dfn>Drawing model</dfn></h6>
+ <h6 id=drawing-model><span class=secno>4.8.11.1.12 </span><dfn>Drawing model</dfn></h6>
<p>When a shape or image is painted, user agents must follow these
steps, in the order given (or act as if they do):</p>
@@ -36996,6 +37067,68 @@ function AddCloud(data, x, y) { ... }</pre>
</ol></div>
+ <h6 id=best-practices><span class=secno>4.8.11.1.13 </span>Best practices</h6>
+
+ <p><i>This section is non-normative.</i></p>
+
+ <p>When a canvas is interactive, authors should include focusable
+ elements in the element's fallback content corresponding to each
+ focusable part of the canvas, as in the <a href=#drawCustomFocusRingExample>example above</a>.</p>
+
+ <p>To indicate which focusable part of the canvas is currently
+ focused, authors should use the <code title=dom-context-2d-drawOSFocusRing><a href=#dom-context-2d-drawosfocusring>drawOSFocusRing()</a></code> 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.</p>
+
+ <p>Authors should avoid implementing text editing controls using the
+ <code><a href=#the-canvas-element>canvas</a></code> element. Doing so has a large number of
+ disadvantages:</p>
+
+ <ul><li>Mouse placement of the caret has to be reimplemented.</li>
+
+ <li>Keyboard movement of the caret has to be reimplemented (possibly across lines, for multiline text input).</li>
+
+ <li>Scrolling of the text field has to be implemented (horizontally for long lines, vertically for multiline input).</li>
+
+ <li>Native features such as copy-and-paste have to be reimplemented.</li>
+
+ <li>Native features such as spell-checking have to be reimplemented.</li>
+
+ <li>Native features such as drag-and-drop have to be reimplemented.</li>
+
+ <li>Native features such as page-wide text search have to be reimplemented.</li>
+
+ <li>Native features specific to the user, for example custom text
+ services, have to be reimplemented. This is close to impossible
+ since each user might have different services installed, and there
+ is an unbounded set of possible such services.</li>
+
+ <li>Bidirectional text editing has to be reimplemented.</li>
+
+ <li>For multiline text editing, line wrapping has to be implemented for all relevant languages.</li>
+
+ <li>Text selection has to be reimplemented.</li>
+
+ <li>Dragging of bidirectional text selections has to be reimplemented.</li>
+
+ <li>Platform-native keyboard shortcuts have to be reimplemented.</li>
+
+ <li>Platform-native input method editors (IMEs) have to be reimplemented.</li>
+
+ <li>Undo and redo functionality has to be reimplemented.</li>
+
+ <li>Accessibility features such as magnification following the
+ caret or selection have to be reimplemented.</li>
+
+ </ul><p>This is a huge amount of work, and authors are most strongly
+ encouraged to avoid doing any of it by instead using the
+ <code><a href=#the-input-element>input</a></code> element, the <code><a href=#the-textarea-element>textarea</a></code> element, or
+ the <code title=attr-contenteditable><a href=#attr-contenteditable>contenteditable</a></code>
+ attribute.</p>
+
+
<h6 id=examples><span class=secno>4.8.11.1.14 </span>Examples</h6>
<p><i>This section is non-normative.</i></p>
View
377 source
@@ -176,6 +176,14 @@
<li><a href="#crossDocumentMessages">Cross-document messaging</a> (also known as Communications)<!--POSTMSG-->
<li><a href="#channel-messaging">Channel messaging</a> (also known as Communications)<!--POSTMSG-->
</ul>
+
+ <p>The specification that covers the Canvas 2D Graphics Context at
+ the W3C does not include all the advice included in the equivalent
+ section in this document, because of <a
+ href="http://lists.w3.org/Archives/Public/public-html/2011Apr/0712.html">the
+ discussion</a> that followed <a
+ href="http://lists.w3.org/Archives/Public/public-html/2011Apr/0271.html">a
+ working gorup decision from April 2011</a>.</p>
<p>The <a href="#forms">forms</a> part of this specification was
previously published separately in a specification known as Web
@@ -37675,7 +37683,7 @@ interface <dfn>TextTrackCue</dfn> {
<h5 id="2dcontext">The 2D context</h5>
- <!-- v2: we're on v4. suggestions for next version are marked v5. -->
+ <!-- v2: we're on v4.1. suggestions for next version are marked v5. -->
<!--START 2dcontext-->
@@ -37776,12 +37784,12 @@ interface <dfn>TextTrackCue</dfn> {
void <span title="dom-context-2d-arc">arc</span>(in double x, in double y, in double radius, in double startAngle, in double endAngle, in optional boolean anticlockwise);
void <span title="dom-context-2d-fill">fill</span>();
void <span title="dom-context-2d-stroke">stroke</span>();
+ void <span title="dom-context-2d-drawOSFocusRing">drawOSFocusRing</span>(in <span>Element</span> element);
+ boolean <span title="dom-context-2d-drawCustomFocusRing">drawCustomFocusRing</span>(in <span>Element</span> element);
+ void <span title="dom-context-2d-scrollPathIntoView">scrollPathIntoView</span>();
void <span title="dom-context-2d-clip">clip</span>();
boolean <span title="dom-context-2d-isPointInPath">isPointInPath</span>(in double x, in double y);
- // focus management
- boolean <span title="dom-context-2d-drawFocusRing">drawFocusRing</span>(in <span>Element</span> element, in double xCaret, in double yCaret, in optional boolean canDrawCustom);
-
// text
attribute DOMString <span title="dom-context-2d-font">font</span>; // (default 10px sans-serif)
attribute DOMString <span title="dom-context-2d-textAlign">textAlign</span>; // "start", "end", "left", "right", "center" (default: "start")
@@ -39346,6 +39354,42 @@ hairline width with transform. ack Shaun Morris.
</dd>
+ <dt><var title="">context</var> . <code title="dom-context-2d-drawOSFocusRing">drawOSFocusRing</code>(<var title="">element</var>)</dt>
+
+ <dd>
+
+ <p>If the given element is focused, draws a focus ring around the
+ current path, following the platform conventions for focus
+ rings.</p>
+
+ </dd>
+
+ <dt><var title="">shouldDraw</var> = <var title="">context</var> . <code title="dom-context-2d-drawCustomFocusRing">drawCustomFocusRing</code>(<var title="">element</var>)</dt>
+
+ <dd>
+
+ <p>If the given element is focused, and the user has configured
+ his system to draw focus rings in a particular manner (for
+ example, high contrast focus rings), draws a focus ring around the
+ current path and returns false.</p>
+
+ <p>Otherwise, returns true if the given element is focused, and
+ false otherwise. This can thus be used to determine when to draw a
+ focus ring (see <a href="#drawCustomFocusRingExample">the
+ example</a> below).</p>
+
+ </dd>
+
+ <dt><var title="">context</var> . <code title="dom-context-2d-scrollPathIntoView">scrollPathIntoView</code>()</dt>
+
+ <dd>
+
+ <p>Scrolls the current path into view. This is especially useful
+ on devices with small screens, where the whole canvas might not be
+ visible at once.</p>
+
+ </dd>
+
<dt><var title="">context</var> . <code title="dom-context-2d-clip">clip</code>()</dt>
<dd>
@@ -39611,118 +39655,70 @@ hairline width with transform. ack Shaun Morris.
<p>Zero-length line segments must be pruned before stroking a
path. Empty subpaths must be ignored.</p>
-
- <p>The <dfn title="dom-context-2d-clip"><code>clip()</code></dfn>
- method must create a new <dfn>clipping region</dfn> by calculating
- the intersection of the current clipping region and the area
- described by the current path, using the non-zero winding number
- rule. Open subpaths must be implicitly closed when computing the
- clipping region, without affecting the actual subpaths. The new
- clipping region replaces the current clipping region.</p>
-
- <p>When the context is initialized, the clipping region must be set
- to the rectangle with the top left corner at (0,0) and the width and
- height of the coordinate space.</p>
-
- <!-- v5
- Jordan OSETE suggests:
- * support ways of extending the clipping region (union instead of intersection)
- - also "add", "subtract", "replace", "intersect" and "xor"
- * support ways of resetting the clipping region without save/restore
- -->
-
+ <hr>
<p>The <dfn
- title="dom-context-2d-isPointInPath"><code>isPointInPath(<var
- title="">x</var>, <var title="">y</var>)</code></dfn> method must
- return true if the point given by the <var title="">x</var> and <var
- title="">y</var> coordinates passed to the method, when treated as
- coordinates in the canvas coordinate space unaffected by the current
- transformation, is inside the current path as determined by the
- 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.</p>
-
- </div>
-
-
- <h6>Focus management</h6> <!-- a v4 feature -->
-
- <p>When a canvas is interactive, authors should include focusable
- elements in the element's fallback content corresponding to each
- focusable part of the canvas.</p>
+ title="dom-context-2d-drawOSFocusRing"><code>drawOSFocusRing(<var
+ title="">element</var>)</code></dfn> method, when invoked,
+ must run the following steps:</p>
- <p>To indicate which focusable part of the canvas is currently
- focused, authors should use the <code
- title="dom-context-2d-drawFocusRing">drawFocusRing()</code> 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 <var title="">x</var> and <var
- title="">y</var> arguments.</p>
+ <ol>
- <dl class="domintro">
+ <li><p>If <var title="">element</var> is not focused or is not a
+ descendant of the element with whose context the method is
+ associated, then abort these steps.</p></li>
- <dt><var title="">shouldDraw</var> = <var title="">context</var> . <code title="dom-context-2d-drawFocusRing">drawFocusRing</code>(<var title="">element</var>, <var title="">x</var>, <var title="">y</var>, [ <var title="">canDrawCustom</var> ])</dt>
+ <li>
- <dd>
+ <p>If the user has requested the use of particular focus rings
+ (e.g. high-contrast focus rings), or if the <var
+ title="">element</var> would have a focus ring drawn around it,
+ then draw a focus ring of the appropriate style along the path,
+ following platform conventions, and abort these steps.</p>
- <p>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).</p>
+ <p class="note">Some platforms only draw focus rings around
+ elements that have been focused from the keyboard, and not those
+ focused from the mouse. Other platforms simply don't draw focus
+ rings around some elements at all unless relevant accessibility
+ features are enabled. This API is intended to follow these
+ conventions.</p>
- <p>If the <var title="">canDrawCustom</var> 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.)</p>
+ <p>The focus ring should not be subject to the <span
+ title="shadows">shadow effects</span>, the <span
+ title="dom-context-2d-globalAlpha">global alpha</span>, or the <span
+ title="dom-context-2d-globalCompositeOperation">global composition
+ operators</span>, but <em>should</em> be subject to the <span
+ title="clipping region">clipping region</span>.</p>
- <p>Returns true if the given element is focused, the <var
- title="">canDrawCustom</var> argument is true, and the user has
- not configured his system to draw focus rings in a particular
- manner. Otherwise, returns false.</p>
+ </li>
- <p>When the method returns true, the author is expected to
- manually draw a focus ring.</p>
+ <li>
- </dd>
+ <p>Optionally, <a href="#inform">inform the user</a> that the
+ focus is at the location given by the path. User agents may wait
+ until the next time the <span>event loop</span> reaches its
+ "update the rendering" step to optionally inform the user.</p>
- </dl>
+ </li>
- <div class="impl">
+ </ol>
<p>The <dfn
- title="dom-context-2d-drawFocusRing"><code>drawFocusRing(<var
- title="">element</var>, <var title="">x</var>, <var
- title="">y</var>, [<var title="">canDrawCustom</var>])</code></dfn>
- method, when invoked, must run the following steps:</p>
+ title="dom-context-2d-drawCustomFocusRing"><code>drawCustomFocusRing(<var
+ title="">element</var>)</code></dfn> method, when invoked, must run
+ the following steps:</p>
<ol>
<li><p>If <var title="">element</var> 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.</p></li>
- <li><p>Transform the given point (<var title="">x</var>, <var
- title="">y</var>) according to the <span
- title="dom-context-2d-transformation">current transformation
- matrix</span>.</p></li>
-
- <li><p>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.)</p></li>
-
<li>
<p>If the user has requested the use of particular focus rings
- (e.g. high-contrast focus rings), or if the <var
- title="">canDrawCustom</var> 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
+ (e.g. high-contrast focus rings), then draw a focus ring of the
+ appropriate style along the path, return false, and abort these
steps.</p>
<p>The focus ring should not be subject to the <span
@@ -39734,44 +39730,128 @@ hairline width with transform. ack Shaun Morris.
</li>
+ <li>
+
+ <p>Optionally, <a href="#inform">inform the user</a> that the
+ focus is at the location given by the path. User agents may wait
+ until the next time the <span>event loop</span> reaches its
+ "update the rendering" step to optionally inform the user.</p>
+
+ </li>
+
<li><p>Return true.</p></li>
</ol>
+ <p>The <dfn
+ title="dom-context-2d-scrollPathIntoView"><code>scrollPathIntoView()</code></dfn>
+ method, when invoked, must run the following steps:</p>
+
+ <ol>
+
+ <li><p>Let <var title="">notional child</var> be a hypothetical
+ element that is a rendered child of the <code>canvas</code> element
+ whose dimensions are exactly the rectangle of the bounding box of
+ the current path.</p></li>
+
+ <li><p><span title="scroll an element into view">Scroll <var
+ title="">notional child</var> into view</span> with the <var
+ title="">align to top flag</var> set.</p>
+
+ <li><p>Optionally, <a href="#inform">inform the user</a> that the
+ caret and/or selection cover <var title="">the specified
+ rectangle</var> of the canvas. User agents may wait until the next
+ time the <span>event loop</span> reaches its "update the rendering"
+ step to optionally inform the user.</p></li>
+
+ </ol>
+
+ <p class="note" id="inform">"Inform the user", as used in this
+ section, could mean calling a system accessibility API, which would
+ notify assistive technologies such as magnification tools. To
+ properly drive magnification based on a focus change, a system
+ accessibility API driving a screen magnifier needs the bounds for
+ the newly focused object. The methods above are intended to enable
+ this by allowing the user agent to report the bounding box of the
+ path used to render the focus ring as the bounds of the <var
+ title="">element</var> element passed as an argument, if that
+ element is focused, and the bounding box of the area to which the
+ user agent is scrolling as the bounding box of the current
+ selection.</p>
+
+ <hr>
+
+ <p>The <dfn title="dom-context-2d-clip"><code>clip()</code></dfn>
+ method must create a new <dfn>clipping region</dfn> by calculating
+ the intersection of the current clipping region and the area
+ described by the current path, using the non-zero winding number
+ rule. Open subpaths must be implicitly closed when computing the
+ clipping region, without affecting the actual subpaths. The new
+ clipping region replaces the current clipping region.</p>
+
+ <p>When the context is initialized, the clipping region must be set
+ to the rectangle with the top left corner at (0,0) and the width and
+ height of the coordinate space.</p>
+
+ <!-- v5
+ Jordan OSETE suggests:
+ * support ways of extending the clipping region (union instead of intersection)
+ - also "add", "subtract", "replace", "intersect" and "xor"
+ * support ways of resetting the clipping region without save/restore
+ -->
+
+ <hr>
+
+ <p>The <dfn
+ title="dom-context-2d-isPointInPath"><code>isPointInPath(<var
+ title="">x</var>, <var title="">y</var>)</code></dfn> method must
+ return true if the point given by the <var title="">x</var> and <var
+ title="">y</var> coordinates passed to the method, when treated as
+ coordinates in the canvas coordinate space unaffected by the current
+ transformation, is inside the current path as determined by the
+ 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.</p>
+
</div>
- <div class="example">
- <p>This <code>canvas</code> element has a couple of checkboxes:</p>
+ <div class="example" id="drawCustomFocusRingExample">
+
+ <p>This <code>canvas</code> element has a couple of checkboxes. The
+ path-related commands are highlighted:</p>
<pre>&lt;canvas height=400 width=750>
&lt;label>&lt;input type=checkbox id=showA> Show As&lt;/label>
&lt;label>&lt;input type=checkbox id=showB> Show Bs&lt;/label>
&lt;!-- ... -->
&lt;/canvas>
&lt;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) {
+<strong> context.beginPath();
+ context.strokeStyle = 'black';
+ context.rect(x-5, y-5, 10, 10);
+ context.stroke();
+</strong> if (element.checked) {
+<strong> context.fillStyle = 'black';
+ context.fill();
+</strong> }
+ context.fillText(element.labels[0].textContent, x+5, y);
}
- context.fillText(element.labels[0].textContent, x+5, y);
- context.beginPath();
+<strong> context.beginPath();
context.rect(x-7, y-7, 12 + metrics.width+2, 14);
- if (context.drawFocusRing(element, x, y, true)) {
+ if (paint && context.drawCustomFocusRing(element)) {
context.strokeStyle = 'silver';
context.stroke();
}
- context.restore();
+</strong> context.restore();
}
function drawBase() { /* ... */ }
function drawAs() { /* ... */ }
@@ -39780,8 +39860,8 @@ hairline width with transform. ack Shaun Morris.
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();
@@ -39791,12 +39871,17 @@ hairline width with transform. ack Shaun Morris.
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();
@@ -39812,6 +39897,8 @@ hairline width with transform. ack Shaun Morris.
</div>
+
+
<h6>Text</h6> <!-- a v3 feature -->
<dl class="domintro">
@@ -41074,6 +41161,74 @@ function AddCloud(data, x, y) { ... }</pre>
</div>
+ <h6>Best practices</h6>
+
+ <!--END dev-html--><p><i>This section is non-normative.</i></p><!--START dev-html-->
+
+ <p>When a canvas is interactive, authors should include focusable
+ elements in the element's fallback content corresponding to each
+ focusable part of the canvas, as in the <a
+ href="#drawCustomFocusRingExample">example above</a>.</p>
+
+ <p>To indicate which focusable part of the canvas is currently
+ focused, authors should use the <code
+ title="dom-context-2d-drawOSFocusRing">drawOSFocusRing()</code> 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.</p>
+
+ <p>Authors should avoid implementing text editing controls using the
+ <code>canvas</code> element. Doing so has a large number of
+ disadvantages:</p>
+
+ <ul>
+
+ <li>Mouse placement of the caret has to be reimplemented.</li>
+
+ <li>Keyboard movement of the caret has to be reimplemented (possibly across lines, for multiline text input).</li>
+
+ <li>Scrolling of the text field has to be implemented (horizontally for long lines, vertically for multiline input).</li>
+
+ <li>Native features such as copy-and-paste have to be reimplemented.</li>
+
+ <li>Native features such as spell-checking have to be reimplemented.</li>
+
+ <li>Native features such as drag-and-drop have to be reimplemented.</li>
+
+ <li>Native features such as page-wide text search have to be reimplemented.</li>
+
+ <li>Native features specific to the user, for example custom text
+ services, have to be reimplemented. This is close to impossible
+ since each user might have different services installed, and there
+ is an unbounded set of possible such services.</li>
+
+ <li>Bidirectional text editing has to be reimplemented.</li>
+
+ <li>For multiline text editing, line wrapping has to be implemented for all relevant languages.</li>
+
+ <li>Text selection has to be reimplemented.</li>
+
+ <li>Dragging of bidirectional text selections has to be reimplemented.</li>
+
+ <li>Platform-native keyboard shortcuts have to be reimplemented.</li>
+
+ <li>Platform-native input method editors (IMEs) have to be reimplemented.</li>
+
+ <li>Undo and redo functionality has to be reimplemented.</li>
+
+ <li>Accessibility features such as magnification following the
+ caret or selection have to be reimplemented.</li>
+
+ </ul>
+
+ <p>This is a huge amount of work, and authors are most strongly
+ encouraged to avoid doing any of it by instead using the
+ <code>input</code> element, the <code>textarea</code> element, or
+ the <code title="attr-contenteditable">contenteditable</code>
+ attribute.</p>
+
+
<h6>Examples</h6>
<!--END dev-html--><p><i>This section is non-normative.</i></p><!--START dev-html-->

0 comments on commit 7a8cca3

Please sign in to comment.