Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
280 changes: 278 additions & 2 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -68316,6 +68316,7 @@ dictionary <dfn dictionary>AssignedNodesOptions</dfn> {
<dd><span>Global attributes</span></dd>
<dd><code data-x="attr-canvas-width">width</code></dd>
<dd><code data-x="attr-canvas-height">height</code></dd>
<dd><code data-x="attr-canvas-layoutsubtree">layoutsubtree</code></dd>
<dt><span
data-x="concept-element-accessibility-considerations">Accessibility considerations</span>:</dt>
<dd><a href="https://w3c.github.io/html-aria/#el-canvas">For authors</a>.</dd>
Expand Down Expand Up @@ -68424,6 +68425,12 @@ callback <dfn callback>BlobCallback</dfn> = undefined (<span>Blob</span>? blob);
<p>The user agent must use a square pixel density consisting of one pixel of image data per
coordinate space unit for the bitmaps of a <code>canvas</code> and its rendering contexts.</p>

<p>The <dfn element-attr for="canvas"><code
data-x="attr-canvas-layoutsubtree">layoutsubtree</code></dfn> attribute is a <span>boolean
attribute</span>. If present, <span data-x="concept-tree-child">children</span> of the
<data>canvas</data> element are layed out, so that they can be drawn using <code
data-x="dom-context-2d-drawElementImage">drawElementImage()</code>.</p>

<p class="note">A <code>canvas</code> element can be sized arbitrarily by a style sheet, its
bitmap is then subject to the <span>'object-fit'</span> CSS property.</p>

Expand Down Expand Up @@ -68933,6 +68940,8 @@ interface <dfn interface>CanvasRenderingContext2D</dfn> {
<span>CanvasRenderingContext2D</span> includes <span>CanvasDrawPath</span>;
<span>CanvasRenderingContext2D</span> includes <span>CanvasUserInterface</span>;
<span>CanvasRenderingContext2D</span> includes <span>CanvasText</span>;
<span>CanvasRenderingContext2D</span> includes <span>CanvasDrawElementImage</span>;
<span>CanvasRenderingContext2D</span> includes <span>CanvasHitTestRegions</span>;
<span>CanvasRenderingContext2D</span> includes <span>CanvasDrawImage</span>;
<span>CanvasRenderingContext2D</span> includes <span>CanvasImageData</span>;
<span>CanvasRenderingContext2D</span> includes <span>CanvasPathDrawingStyles</span>;
Expand Down Expand Up @@ -69052,6 +69061,29 @@ interface mixin <dfn interface>CanvasText</dfn> {
<span>TextMetrics</span> <span data-x="dom-context-2d-measureText">measureText</span>(DOMString text);
};

interface mixin <dfn interface>CanvasDrawElementImage</dfn> {
// drawing elements
undefined <span data-x="dom-context-2d-drawElementImage">drawElementImage</span>(<span>Element</span> element, unrestricted double x, unrestricted double y);
undefined <span data-x="dom-context-2d-drawElementImage">drawElementImage</span>(<span>Element</span> element, unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h);
};

dictionary <dfn dictionary>CanvasHitTestRect</dfn> {
double <dfn dict-member for="CanvasHitTestRect" data-x="dom-CanvasHitTestRect-x">x</dfn>;
double <dfn dict-member for="CanvasHitTestRect" data-x="dom-CanvasHitTestRect-y">y</dfn>;
double? <dfn dict-member for="CanvasHitTestRect" data-x="dom-CanvasHitTestRect-width">width</dfn>;
double? <dfn dict-member for="CanvasHitTestRect" data-x="dom-CanvasHitTestRect-height">height</dfn>;
};

dictionary <dfn dictionary>CanvasElementHitTestRegion</dfn> {
<span>Element</span> <dfn dict-member for="CanvasElementHitTestRegion" data-x="dom-CanvasElementHitTestRegion-element">element</dfn>;
<span>CanvasHitTestRect</span> <dfn dict-member for="CanvasElementHitTestRegion" data-x="dom-CanvasElementHitTestRegion-rect">rect</dfn>;
};

interface mixin <dfn interface>CanvasHitTestRegions</dfn> {
// hit testing
undefined <span data-x="dom-context-2d-setHitTestRegions">setHitTestRegions</span>(sequence&lt;CanvasElementHitTestRegion> regions);
};

interface mixin <dfn interface>CanvasDrawImage</dfn> {
// drawing images
undefined <span data-x="dom-context-2d-drawImage">drawImage</span>(<span>CanvasImageSource</span> image, unrestricted double dx, unrestricted double dy);
Expand Down Expand Up @@ -73525,6 +73557,234 @@ try {

</div>


<h6>Drawing elements</h6>

<dl class="domintro">
<dt><code data-x=""><var>context</var>.<span subdfn data-x="dom-context-2d-drawElementImage">drawElementImage</span>(<var>element</var>, <var>x</var>, <var>y</var>)</code></dt>
<dt><code data-x=""><var>context</var>.<span data-x="dom-context-2d-drawElementImage">drawElementImage</span>(<var>element</var>, <var>x</var>, <var>y</var>, <var>w</var>, <var>h</var>)</code></dt>

<dd>
<p>Draws the given element onto the canvas. Throws a <code>TypeError</code> if the element isn't
a descendant of the canvas.</p>
</dd>
</dl>

<div w-nodev>

<p>Objects that implement the <code>CanvasDrawElementImage</code> interface have the <dfn method
for="CanvasDrawElementImage"><code
data-x="dom-context-2d-drawElementImage">drawElementImage()</code></dfn> method to draw
elements.</p>

<div algorithm>
<p>The <code data-x="dom-context-2d-drawElementImage">drawElementImage(element, x, y)</code> method,
when invoked, must <span>draw an element</span> with <span>this</span>, <var>element</var>,
<var>x</var>, <var>y</var>.</p>
</div>

<div algorithm>
<p>The <code data-x="dom-context-2d-drawElementImage">drawElementImage(element, x, y, w, h)</code>
method, when invoked, must <span>draw an element</span> with <span>this</span>,
<var>element</var>, <var>x</var>, <var>y</var>, <var>w</var>, and <var>h</var>.</p>
</div>

<div algorithm>
<p>To <dfn>draw an element</dfn>, with a <code>CanvasRenderingContext2D</code> <var>context</var>,
an element <var>element</var>, numbers <var>x</var> and <var>y</var>, and optional numbers
<var>w</var> and <var>h</var>:</p>

<ol>
<li><p>If <var>x</var> or <var>y</var> are infinite or NaN, then return.</p></li>

<li><p>If <var>w</var> and <var>h</var> are given and either are infinite or NaN, then
return.</p></li>

<li><p>Let <var>canvas</var> be the <code>canvas</code> element to which <var>context</var> is
bound.</p></li>

<li><p>If <var>element</var>'s <span>parent</span> is not <var>canvas</var>, then throw a
<code>TypeError</code>.</p></li>

<li><p>If <var>canvas</var> does not have a <code
data-x="attr-canvas-layoutsubtree">layoutsubtree</code> attribute specified, then throw a
<code>TypeError</code>.</p></li>

<li><p>Let <var>borderBox</var> be <var>element</var>'s <span>border box</span>.</p></li>

<li><p>If not given, <var>w</var> and <var>h</var> must default to the width and height of
<var>borderBox</var>.</p></li>

<li><p>If either <var>w</var> or <var>h</var> are zero, then return.</p></li>

<li><p>Paint <var>element</var> to the specified rectangular area without using any
<span>sensitive information</span>. Instead, either paint nothing or use static information that
is the same for all users.</p></li>
</ol>
</div>

<p>When drawing elements to a <code>canvas</code>, no information should be used that isn't
otherwise observable to author code. Such <dfn export>sensitive information</dfn> includes
but isn't limited to:</p>

<ul>
<li><p><span>CORS-cross-origin</span> data</p></li>

<li><p>system colors, themes, or preferences</p></li>

<li><p>spelling and grammar markers</p></li>

<li><p>search text (find-in-page) and text-fragment (fragment url) markers</p></li>

<li><p>visited link information</p></li>

<li><p>form autofill information</p></li>
</ul>

</div>


<h6>Hit testing</h6>

<dl class="domintro">
<dt><code data-x=""><var>context</var>.<span subdfn data-x="dom-context-2d-setHitTestRegions">setHitTestRegions</span>(<var>regions</var>)</code></dt>

<dd>
<p>Sets hit test regions mapping given regions (rectangles) of the canvas to descendants of the
<code>canvas</code> element.</p>
</dd>
</dl>

<div w-nodev>

<p>Objects that implement the <code>CanvasHitTestRegions</code> interface have the <dfn method
for="CanvasHitTestRegions"><code
data-x="dom-context-2d-setHitTestRegions">setHitTestRegions()</code></dfn> method to set up
hit testing regions.</p>

<p>Each <code>canvas</code> element has a <dfn>hit test regions</dfn> <span>list</span> of
<span>hit test region</span> structs, initially empty.</p>

<p>A <dfn>hit test region</dfn> is a <span>struct</span> consisting of an
<dfn data-x="hit-test-region-element">element</dfn> (element),
<dfn data-x="hit-test-region-x">x</dfn> (number),
<dfn data-x="hit-test-region-y">y</dfn> (number),
<dfn data-x="hit-test-region-width">width</dfn> (number), and
<dfn data-x="hit-test-region-height">height</dfn> (number).

<div algorithm>
<p>The <code data-x="dom-context-2d-setHitTestRegions">setHitTestRegions(regions)</code> method,
when invoked, must <span>set hit test regions</span> with <span>this</span> and
<var>regions</var>.</p>

<p>To <dfn>set hit test regions</dfn>, with a <code>CanvasRenderingContext2D</code>
<var>context</var> and a <span>list</span> of <code>CanvasElementHitTestRegion</code>
dictionaries <var>regions</var>:</p>

<ol>
<li><p>Let <var>newRegions</var> be an empty list.</p></li>

<li><p>Let <var>canvas</var> be the <code>canvas</code> element to which <var>this</var> is
bound.</p></li>

<li>
<p>For each <code>CanvasElementHitTestRegion</code> <var>region</var> in <var>regions</var>:</p>

<ol>
<li><p>If <var>region</var>["<code data-x="dom-CanvasElementHitTestRegion-element">element</code>"]
or <var>region</var>["<code data-x="dom-CanvasElementHitTestRegion-element">rect</code>"] do not
exist, then throw a <code>TypeError</code>.</p></li>
<!-- TODO: just make them required -->

<li><p>Let <var>element</var> be <var>region</var>["<code data-x="dom-CanvasElementHitTestRegion-element">element</code>"].</p></li>

<li><p>If <var>element</var>'s <span>parent</span> is not <var>canvas</var>, then throw a <code>TypeError</code>.</p></li>
<!-- TODO: what if the element moves later? -->

<li><p>Let <var>rect</var> be <var>region</var>["<code data-x="dom-CanvasElementHitTestRegion-rect">rect</code>"].</p></li>

<li><p>If <var>rect</var>["<code data-x="dom-CanvasHitTestRect-x">x</code>"] or
<var>rect</var>["<code data-x="dom-CanvasHitTestRect-y">y</code>"] do not exist, then throw a
<code>TypeError</code>.</p></li>
<!-- TODO: just make them required -->

<li><p>Let <var>x</var> be <var>rect</var>["<code data-x="dom-CanvasHitTestRect-x">x</code>"].</p></li>

<li><p>Let <var>y</var> be <var>rect</var>["<code data-x="dom-CanvasHitTestRect-y">y</code>"].</p></li>

<li><p>Let <var>borderBox</var> be <var>element</var>'s <span>border box</span>.</p></li>

<li><p>Let <var>width</var> be <var>rect</var>["<code data-x="dom-CanvasHitTestRect-width">width</code>"]
if it exists, otherwise the width of <var>borderBox</var>.</p></li>

<li><p>Let <var>height</var> be <var>rect</var>["<code data-x="dom-CanvasHitTestRect-height">height</code>"]
if it exists, otherwise the height of <var>borderBox</var>.</p></li>
<!-- TODO: what if the layout changes later? -->

<li><p>If <var>width</var> or <var>height</var> are less than or equal to zero,
<span>continue</span>.</p></li>

<li>
<p>Let <var>newRegion</var> be a <span>hit test region</span> whose
<span data-x="hit-test-region-element">element</span> is <var>element</var>,
<span data-x="hit-test-region-x">x</span> is <var>x</var>,
<span data-x="hit-test-region-y">y</span> is <var>y</var>,
<span data-x="hit-test-region-width">width</span> is <var>width</var>, and
<span data-x="hit-test-region-height">height</span> is <var>height</var>.</p>

<p class="note"><var>x</var>, <var>y</var>, <var>width</var>, and <var>height</var> are
treated as coordinates/lengths in the canvas coordinate space unaffected by the current
transformation.</p>
</li>

<li><p>Append <var>newRegion</var> to <var>newRegions</var>.</p></li>
</ol>
</li>

<li><p>Set <var>canvas</var>'s <span>hit test regions</span> to <var>newRegions</var>.</p></li>
</ol>
</div>

<div algorithm>
<p>When performing hit testing for a <code>canvas</code> element <var>canvas</var> and coordinates
(<var>x</var>, <var>y</var>), run these steps:</p>

<ol>
<li>
<p>For each <span>hit test region</span> <var>region</var> in <var>canvas</var>'s <span>hit test regions</span>:</p>

<ol>
<li><p>Let <var>element</var> be <var>region</var>'s <span data-x="hit-test-region-element">element</span>.</p></li>

<li><p>If <var>element</var>'s <span>parent</span> is not <var>canvas</var>, then <span>continue</span>.</p></li>

<li><p>If (<var>x</var>, <var>y</var>) is not within the rectangle defined by <var>region</var>'s
<span data-x="hit-test-region-x">x</span>, <span data-x="hit-test-region-y">y</span>,
<span data-x="hit-test-region-width">width</span>, and
<span data-x="hit-test-region-height">height</span>, then <span>continue</span>.</p></li>
<!-- TODO: spell out exact test and boundary conditions -->

<li><p>Let <var>elementX</var> and <var>elementY</var> be the corresponding coordinates for
<var>element</var>, translating and scaling the coordinates such that (x, y) is the top left
corner and (x + width, y + height) is the bottom right corner.</p></li>
<!-- TODO: spell out exact mapping -->

<li><p>👋 Act as if (<var>elementX</var>, <var>elementY</var>) of <var>element</var> was hit.</p></li>

<li><p><span>Break</span>.</p></li>
</ol>

<p class="note">Hit testing isn't defined anywhere so there is no spec to modify or monkey patch.
The intention of the above is that things behave as if each element was positioned at the given
region, with all the observable behavior that implies, such as pointer events firing at the
element and propagating like they would for a regular element.</p>
</li>
</ol>
</div>

</div>


<h6>Drawing images</h6>

<p>Objects that implement the <code>CanvasDrawImage</code> interface have the <dfn method
Expand Down Expand Up @@ -146568,8 +146828,18 @@ legend[align=right i] {
<p>A <code>canvas</code> element that <span>represents</span> <span>embedded content</span> is
<span>expected</span> to be treated as a <span>replaced element</span>; the contents of such
elements are the element's bitmap, if any, or else a <span>transparent black</span> bitmap with
the same <span>natural dimensions</span> as the element. Other <code>canvas</code> elements are
<span>expected</span> to be treated as ordinary elements in the rendering model.</p>
the same <span>natural dimensions</span> as the element. A <code>canvas</code> element that
<span>represents</span> <span>embedded content</span> and has a <code
data-x="attr-canvas-layoutsubtree">layoutsubtree</code> attribute specified is additionally
<span>expected</span> to be treated as 👋replaced element with subtree layout👋, where children are
laid out but not rendered. Additionally, children are exposed to assistive technologies (ATs).</p>

<p class="XXX">This needs to be reconciled with the definition of <span
data-x="replaced element">replaced elements</span>, which says that the content of replaced
elements is not considered in the CSS formatting model.</p>

<p>Other <code>canvas</code> elements are <span>expected</span> to be treated as ordinary elements
in the rendering model.</p>

<p>An <code>object</code> element that <span>represents</span> an image, plugin, or its
<span>content navigable</span> is <span>expected</span> to be treated as a <span>replaced
Expand Down Expand Up @@ -146619,6 +146889,7 @@ legend[align=right i] {

<pre><code class="css">@namespace "http://www.w3.org/1999/xhtml";

canvas[layoutsubtree] > * { isolation: isolate !important; contain: strict !important; }
iframe { border: 2px inset; }
<span id="video-object-fit">video { object-fit: contain; }</span></code></pre>

Expand Down Expand Up @@ -153012,6 +153283,11 @@ interface <dfn interface>External</dfn> {
<code data-x="attr-track-label">track</code>
<td> User-visible label
<td> <a href="#attribute-text">Text</a>
<tr>
<th> <code data-x="">layoutsubtree</code>
<td> <code data-x="attr-canvas-layoutsubtree">canvas</code>
<td> Whether to layout descendants
<td> <span>Boolean attribute</span>
<tr>
<th> <code data-x="">lang</code>
<td> <span data-x="attr-lang">HTML elements</span>
Expand Down
Loading