Re: [whatwg] resize events on elements

2015-02-23 Thread David Flanagan
Yes, please! At a minimum I'd like to see this as a custom element
lifecycle callback, but a more general resize event of some sort also seems
like it would be useful. I've wanted this the most often when working with
the canvas element.

This seems like the sort of thing that would have been proposed many times
before. Is there history here? Good reasons that we do not already have a
resize event?

If not done carefully, I fear that the introduction of a resize event will
allow infinite layout loop bugs or a more benign situation where a user
change in browser window size causes a ripple effect where many
resize-sensitive components adjust their layout, affecting other
components, and everything takes a while to settle down at the new size.

I'd also note that unlike regular events that propagate up the tree, resize
notifications need to propagate down the tree from container elements to
their children.

  David

On Mon, Feb 23, 2015 at 9:34 PM, Tab Atkins Jr. jackalm...@gmail.com
wrote:

 On Mon, Feb 23, 2015 at 8:16 PM, Ryosuke Niwa rn...@apple.com wrote:
  On Feb 23, 2015, at 5:40 PM, Dean Jackson d...@apple.com wrote:
  At the recent Houdini meeting there was a vague agreement between the
 browser engines on adding a way for elements to be notified when their size
 changes. We've run into a number of scenarios where this is extremely
 useful, and is otherwise difficult or annoying (e.g. checking your size on
 a timer).
 
  The idea was to allow the resize event on elements. I don't really care
 what the solution is, so maybe someone here can come up with a better idea
 (size observers?). And of course there are a lot of details to be worked
 out.
 
  I would like it be an async event on an element although we might want
 it to fire earlier than setTimeout(~, 0) to avoid FOC (maybe the same
 timing as rAF?).  I don't think end-of-microtask makes sense as that may
 force too many layouts.

 Yeah, you almost certainly want to tie it to rAF timing.

 ~TJ



[whatwg] Proposal: downsample while decoding image blobs in createImageBitmap()

2013-12-17 Thread David Flanagan
. In a photo gallery app,
for example, we need to know how big the original is so that we know
how far we can allow the user to zoom in to the image. It is possible
to determine this by parsing the image file ourselves in JavaScript,
but it would be much more convenient if the web platform provided a
way to determine the full size of an image without having to decode
the entire thing at the cost of 4 bytes per pixel.  Therefore I
propose that the ImageBitmap include fullWidth and fullHeight
properties that specify the full size of the ImageBitmapSource from
which it was derived.  I suspect (but do not have an explicit use case
for) that it might also be helpful to include the sx, sy,
sw, and sh arguments that are passed to createImageBitmap on the
returned ImageBitmap.

5) Once a large image is decoded and downsampled into a smaller
ImageBitmap, the only thing that we can do with that ImageBitmap is to
copy it into a Canvas, either for display to the end user (as an
alternative to an img) or for re-encoding with Canvas.toBlob() (when
creating thumbnails for large images). The motivation for this
downsampling feature is memory use. But having to copy an ImageBitmap
into a canvas in order to use it immediately doubles the amount of
memory required. So for this reason, I also want to propose that
ImageBitmap have a transferToCanvas() method akin to the
transferToImageBitmap() and transferToImage() methods proposed at
http://wiki.whatwg.org/wiki/WorkerCanvas.  transferToCanvas would
transfer the image data into a new Canvas object and would neuter the
ImageBitmap so that it could no longer be used.

6) Finally, because image data can take up so much memory, I would
like to propose that ImageBitmap have a release() method to explicitly
free the memory that holds the decoded image when that decoded image
data is no longer needed. This gives web applications more precise
control over memory allocation without having to wait for garbage
collection.

  David Flanagan
  FirefoxOS developer, Mozilla



Re: [whatwg] Proposal: downsample while decoding image blobs in createImageBitmap()

2013-12-17 Thread David Flanagan

On 12/17/13 8:36 PM, Rik Cabanier wrote:

Hi David,

is there a reason why you are completely decoding the image when you 
create the imageBitmap? [1]
I assume that that is the intent of calling createImageBitmap() on a 
blob. Since JPEG decoding probably takes significantly longer than 
blocking on memory access, I assume that lazy decoding is not really 
allowed.


But that misses my point. On the devices I'm concerned with I can never 
completely decode the image whether it is deferred or not.  If I decode 
at full size, apps running in the background are likely to be killed 
because of low memory. I need the ability to do the downsampling during 
the decoding process, so that there is never the memory impact of 
holding the entire full-size image in memory.


If you detect a situation where this operation causes excessive memory 
consumption, you could hold on to the compressed data URL and defer 
decoding until the point where it is actually needed.
Since exhausting VM will create undue latency, this workaround 
follows the spirit of the spec.


If you really want to have the downsampled bits in memory, you could 
create a canvas and draw your image into it.
I can't do that because I don't have (and cannot have) a full-size 
decoded image.  I've got a blob that is a JPEG encoded 5 megapixel 
image.  And I want to end up with a decoded 320x480 image.  And I want 
to get from A to B without ever allocating 20mb and decoding the image 
at full size.


snip


6) Finally, because image data can take up so much memory, I would
like to propose that ImageBitmap have a release() method to explicitly
free the memory that holds the decoded image when that decoded image
data is no longer needed. This gives web applications more precise
control over memory allocation without having to wait for garbage
collection.


There was an email thread on adding this to canvas [2], it seems 
reasonable to add it to imageBitmap as well.


1: 
http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-createimagebitmap
2: 
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2013-July/040165.html
Thanks for this link.  It looks like the January message quoted in this 
July message is requesting exactly the same feature as I am for 
discarding or releasing ImageBitmaps.


  David


Re: [whatwg] Proposal: downsample while decoding image blobs in createImageBitmap()

2013-12-17 Thread David Flanagan

On 12/17/13 10:55 PM, Rik Cabanier wrote:




On Tue, Dec 17, 2013 at 9:36 PM, David Flanagan dflana...@mozilla.com 
mailto:dflana...@mozilla.com wrote:


On 12/17/13 8:36 PM, Rik Cabanier wrote:

Hi David,

is there a reason why you are completely decoding the image when
you create the imageBitmap? [1]

I assume that that is the intent of calling createImageBitmap() on
a blob. Since JPEG decoding probably takes significantly longer
than blocking on memory access, I assume that lazy decoding is not
really allowed.


No, nothing in the spec says that you *must* decode the bits:

The exact judgement of what is undue latency of this is left up to
the implementer, but in general if making use of the bitmap
requires network I/O, or even local disk I/O, then the latency is
probably undue; whereas if it only requires a blocking read from a
GPU or system RAM, the latency is probably acceptable.


In your case, things are reversed. Allocating system ram will kill 
performance and cause undue latency. Reading the JPEG image on the fly 
from a Flash disk will be less disruptive and faster.


But that misses my point. On the devices I'm concerned with I can
never completely decode the image whether it is deferred or not. 
If I decode at full size, apps running in the background are

likely to be killed because of low memory. I need the ability to
do the downsampling during the decoding process, so that there is
never the memory impact of holding the entire full-size image in
memory.



If you detect a situation where this operation causes excessive
memory consumption, you could hold on to the compressed data URL
and defer decoding until the point where it is actually needed.
Since exhausting VM will create undue latency, this workaround
follows the spirit of the spec.

If you really want to have the downsampled bits in memory, you
could create a canvas and draw your image into it.

I can't do that because I don't have (and cannot have) a full-size
decoded image.  I've got a blob that is a JPEG encoded 5 megapixel
image.  And I want to end up with a decoded 320x480 image.  And I
want to get from A to B without ever allocating 20mb and decoding
the image at full size


The downsampling happens *during* the drawimage of the imageBitmap 
into the canvas. At no point do you have to allocate 20mb.



Ah. I see what you're saying now.  My first reaction was that's 
brilliant!.  Unfortunately, my second reaction was that drawImage() 
would then block on the image decoding, and unless this was being done 
in a Worker, I'm almost certain that would be an unacceptable 
performance hit. (One of my use cases is scanning an SD card for 
hundreds of images and generating thumbnails for each of them.  If doing 
this used drawImage() calls that blocked the main thread, my UI would be 
completely non-responsive.)


I also suspect that adding an async version of drawImage() to the canvas 
API is a non-starter because that API is pretty fundamentally synchronous.


  David


[whatwg] Add EXIF metadata support in Canvas.toBlob?

2013-06-07 Thread David Flanagan
If the second argument to Canvas.toBlob() and Canvas.toBlobHD() is 
image/jpeg, then these methods support a third argument to specify 
JPEG compression level.


The spec 
(http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#a-serialization-of-the-bitmap-as-a-file) 
says:
A future version of this specification will probably define other 
parameters to be passed to these methods to allow authors to more 
carefully control compression settings, image metadata, etc.
I would like to propose the addition of a fourth argument (for the JPEG 
case only) that would specify EXIF metadata to be included in the JPEG 
blob.  (I have not tried yet, but I'm assuming that we could define some 
suitable JSON serialization format for EXIF data. If not, then even 
allowing a binary blob of EXIF data as the fourth argument would be 
helpful.)


The use case for this feature is image editing applications, like the 
Gallery app on FirefoxOS devices. Whenever that app crops or edits a 
photo it encodes the edited photo with Canvas.toBlob(), and the process 
strips all metadata from the photo.  Reading EXIF data from a JPEG blob 
is relatively straightforward can can be done with JavaScript, but 
inserting EXIF data into an existing blob is much harder: this is a task 
that is best done when the JPEG blob is being created, which means that 
it is a feature that belongs in toBlob and can not be done efficiently 
with an external library.


[A related, but perhaps too ambitious, proposal is to allow direct 
read/write access to EXIF metadata via HTMLImageElement.  The primary 
use case for read access is to enable web apps to trivially determine 
when, where, and how a photo was taken and also to determine authorship 
and copyright information for an image.  The primary use case for write 
access might be for selectively stripping metadata. It would be nice to 
be able to protect user privacy with code as simple as |delete 
image.metadata.geolocation| for example.]


David Flanagan


Re: [whatwg] !DOCTYPE htmlbodytablemathmifoo/mi/math/table

2011-12-12 Thread David Flanagan
I think this is the same problem I reported here: 
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-October/033533.html
See Hixie's response to that message.  I think this is a known problem, though 
I don't know if a bug has been filed on it.

David

- Original Message -
From: Adam Barth w...@adambarth.com
To: whatwg whatwg@lists.whatwg.org
Cc: Henri Sivonen hsivo...@iki.fi
Sent: Monday, December 12, 2011 6:23:23 PM
Subject: [whatwg] !DOCTYPE 
htmlbodytablemathmifoo/mi/math/table

I'm trying to understand how the HTML parsing spec handles the following case:

!DOCTYPE htmlbodytablemathmifoo/mi/math/table

According to the html5lib test data, we should parse that as follows:

| !DOCTYPE html
| html
|   head
|   body
| math math
|   math mi
| foo
| table

However, I'm not sure whether that's what the spec actually does.

Consider point at which we parse the f character token (from foo).
 The insertion mode will be in table.  The spec will execute as
follows:

- If the current node is a MathML text integration point and the
token is a character token
  * Process the token according to the rules given in the section
corresponding to the current insertion mode in HTML content.

- A character token
  * Let the pending table character tokens be an empty list of tokens.
  * Let the original insertion mode be the current insertion mode.
  * Switch the insertion mode to in table text and reprocess the token.

- Any other character token
  * Append the character token to the pending table character tokens list.

... the o and o will be processed similarly and end up in the
pending table character tokens list.

Now, consider the /mi token.  We're still at a MathML text
integration point, but the current token is neither a start token
(with certain names) nor a character token, so we process the token
according to the rules given in the section for parsing tokens in
foreign content.

- Any other end tag
  * Run these steps:
...

The net result of which is popping the stack of open elements, but not
flushing out the pending table character tokens list.  The list will
eventually be flushed when we process the /table token, resulting
these character tokens getting foster parented:

| !DOCTYPE html
| html
|   head
|   body
| math math
|   math mi
| foo
| table

Thanks,
Adam


Re: [whatwg] document.write(\r): the spec doesn't say how to handle it.

2011-11-03 Thread David Flanagan

On 11/3/11 4:21 AM, Henri Sivonen wrote:

On Thu, Nov 3, 2011 at 1:57 AM, David Flanagandflana...@mozilla.com  wrote:

Firefox, Chrome and Safari all seem to do the right thing: wait for the next
character before tokenizing the CR.

See http://software.hixie.ch/utilities/js/live-dom-viewer/saved/1247

I hadn't used the live dom viewer before.  That's really useful!


Firefox tokenizes the CR immediately, emits an LF and then skips over
the next character if it is an LF. When I designed the solution
Firefox uses, I believed it was more correct and more compatible with
legacy than whatever the spec said at the time.
I'm having a Duh! moment... I currently wait for the next character, but 
what you describe is also works, and allows the document.write() spec to 
make sense.



Chrome seems to wait for the next character before tokenizing the CR.


And I think this means that the description of document.write needs to be 
changed.

All along, I've felt thought that having U+ and CRLF handling as a
stream preprocessing step was bogus and both should happen upon
tokenization. So far, I've managed to convince Hixie about U+
handling.
Each tokenizer state would have to add a rule for CR that said  emit 
LF, save the current tokenizer state, and set the tokenizer state to 
after CR state.  Actually, tokenizer states that already have a rule 
for LF or whitespace would have to integrate this CR rule into that 
rule.  Then new after CR state would have two rules. On LF it would skip 
the character and restore the saved state.  On anything else it would 
push the character back and restore the saved state.



Similarly, what should the tokenizer do if the document.write emits half of
a UTF-16 surrogate pair as the last character?

The parser operates on UTF-16 code units, so a lone surrogate is emitted.


The spec seems pretty unambiguous that it operates on codepoints (though 
I implemented mine using 16-bit code units). §13.2.1:  The input to the 
HTML parsing process consists of a stream of Unicode code points.  Also 
§13.2.2.3 includes a list of codepoints beyond the BMP that are parse 
errors.  And finally, the tests in 
http://code.google.com/p/html5lib/source/browse/testdata/tokenizer/unicodeCharsProblematic.test 
require unpaired surrogates to be converted to the U+FFFD replacement 
character.  (Though my experience is that modifying my tokenizer to pass 
those tests causes other tests to fail, which makes me wonder whether 
unpaired surrogates are only supposed to be replaced in some but not all 
tokenizer states)

Thanks, Henri!

David


[whatwg] document.write(\r): the spec doesn't say how to handle it.

2011-11-02 Thread David Flanagan
The spec for document.write() 
http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-document-write 
says: ... have the tokenizer process the characters that were inserted, 
one at a time, processing resulting tokens as they are emitted, and 
stopping when the tokenizer reaches the insertion point...


But what happens if the last character written by document.write() is a 
carriage return?


The HTML parsing spec says that CR followed by LF is ignored but CR 
followed by anything else is converted to LF.  So if the last character 
is CR, then the tokenizer can't process all characters up to the 
insertion point because it needs to lookahead at the next character, right?


Firefox, Chrome and Safari all seem to do the right thing: wait for the 
next character before tokenizing the CR.  And I think this means that 
the description of document.write needs to be changed.  (Opera, on the 
other hand, just gets this wrong and emits a CR character).


Similarly, what should the tokenizer do if the document.write emits half 
of a UTF-16 surrogate pair as the last character?


David


Re: [whatwg] When a script element's child nodes are changed

2011-10-28 Thread David Flanagan
I'm replying to my own post because I've tested it and found that 
browsers are not interoperable on this point, so we really do need to 
clarify this in the spec.


First of all, the following code obviously runs the specified code and 
displays an alert:


var s0 = document.createElement(script);
document.head.appendChild(s0);
var t0 = document.createTextNode(alert('added a text node child'););
s0.appendChild(t0);

All browsers do that correctly.  The case I'm interested in is this one:

var s1 = document.createElement(script);
var t1 = document.createTextNode();
s1.appendChild(t1);
document.head.appendChild(s1);
t1.appendData(alert('changed text node data'););

Firefox runs this script and Chrome, Safari and Opera do not. (I don't 
have a windows installation, so I haven't tested IE)


Step 4 of the prepare a script algorithm says:  If the element has no 
|src 
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#attr-script-src| 
attribute, and its child nodes, if any, consist only of comment nodes 
and empty text nodes 
http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#text-node, 
then the user agent must abort these steps at this point. The script is 
not executed.  So when the script is added to the document, it has only 
an empty text node, and it does not execute, and (this is the important 
part) it does not get its already started flag set.  So it should still 
be runnable.


One thing that is supposed to trigger script execution is the script 
element is in a Document and its child nodes are changed.   My original 
point in this post was that child nodes are changed isn't specific 
enough.  The most obvious interpretation to me would be a child is 
inserted or deleted.  Firefox has a more sophisticated interpretation 
that seems to boil down to when the value of the text idl attribute 
changes.  Is Firefox correct here?


We're not done yet, though.  If I comment out the appendData() call in 
the code above and replace it with this line:


s1.appendChild(document.createTextNode(alert('then added a new 
text node');));


Firefox now runs this new script.  But Chrome, Safari and Opera still 
don't run it.  So the issue here isn't that the other browsers differ 
from Firefox on the interpretation of child nodes are changed.  
Apparently the other browsers are marking the script with the empty text 
node as already started, and aren't allowing it to run when a change 
happens later.   And this isn't just limited to the empty text node 
case.  If I change that empty text node into a div element, or to a 
comment, Firefox still (correctly) runs a script inserted later, and the 
other browsers still (incorrectly) fail to run it.


Frankly, from an implementation standpoint, having to do what the spec 
says (and what Firefox does) seems unnecessarily complex.  One way to 
simplify things and to bring Chrome, Safari and Opera into compliance 
would be to change step 4 of the prepare a script algorithm so that it 
only aborts if the script tag has no children at all.  If it has 
children then the already_started flag would be set, and the script 
would never run again even if those children do not define any script 
content.


Making this change would also simplify that second trigger for preparing 
the script.  Instead of a vague its child nodes are changed, the spec 
could just say a child is inserted.


David

On 10/27/11 4:03 PM, David Flanagan wrote:

§4.3.1 The Script Element says:


When a |script 
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element| 
element that is not marked as being parser-inserted 
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#parser-inserted 
experiences one of the events listed in the following list, the user 
agent must synchronously prepare 
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#prepare-a-script 
the |script 
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element| 
element:


  * The |script
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element|
element gets inserted into a document
http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#insert-an-element-into-a-document.
  * The |script
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element|
element is in a |Document|
http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#in-a-document
and its child nodes are changed.
  * The |script
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element|
element is in a |Document|
http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#in-a-document
and has a |src
http://www.whatwg.org/specs/web-apps/current-work/multipage

Re: [whatwg] When a script element's child nodes are changed

2011-10-28 Thread David Flanagan

On 10/28/11 12:03 PM, Bjoern Hoehrmann wrote:

* David Flanagan wrote:

All browsers do that correctly.  The case I'm interested in is this one:

 var s1 = document.createElement(script);
 var t1 = document.createTextNode();
 s1.appendChild(t1);
 document.head.appendChild(s1);
 t1.appendData(alert('changed text node data'););

Firefox runs this script and Chrome, Safari and Opera do not. (I don't
have a windows installation, so I haven't tested IE)

In IE9 standards mode IE9 displays the alert.

Thanks, Bjoern. That makes it a lot harder for me to argue that the spec 
should change to match Chrome, Safari and Opera... But can we at least 
change  when child nodes change to something like when the text IDL 
attribute changes from the empty string to a non-empty string?


David


We're not done yet, though.  If I comment out the appendData() call in
the code above and replace it with this line:

 s1.appendChild(document.createTextNode(alert('then added a new
text node');));

As above, IE9 displays the alert.




[whatwg] Inserting a DocumentFragment of multiple text nodes into a script element

2011-10-28 Thread David Flanagan
Here's another ambiguity about the child nodes are changed trigger for 
executing a script element.

What is the correct behavior for the following code?

script
window.onload = test;

function test() {
var s = document.createElement(script);
document.head.appendChild(s);

var f = document.createDocumentFragment();

f.appendChild(document.createTextNode(alert(document.scripts[1].text);));

f.appendChild(document.createTextNode(alert(2);));
f.appendChild(document.createTextNode(alert(3);));

s.appendChild(f);

alert(s.text);
}
/script

In Firefox, the code in all three text nodes runs, so there are 4 alerts 
in total, and the first and the fourth display the same text: the 
concatenation of the three text nodes.


In Chrome, Safari and Opera (I can't test on IE), only the first text 
node is run as a script. There are two alerts.  The first displays the 
content of the first text node, and the second alert displays the 
concatenation of all three text nodes.


I would guess that Firefox's behavior is correct here, because DOM4 
specifies the algorithm for DocumentFragment insertion without using 
recursion. But its not really specified clearly there either.  Does the 
HTML spec need a clarifying note on this point?  (I also plan to raise 
this issue on the www-dom mailing list)


David


On 10/28/11 12:07 PM, David Flanagan wrote:

On 10/28/11 12:03 PM, Bjoern Hoehrmann wrote:

* David Flanagan wrote:
All browsers do that correctly.  The case I'm interested in is this 
one:


 var s1 = document.createElement(script);
 var t1 = document.createTextNode();
 s1.appendChild(t1);
 document.head.appendChild(s1);
 t1.appendData(alert('changed text node data'););

Firefox runs this script and Chrome, Safari and Opera do not. (I don't
have a windows installation, so I haven't tested IE)

In IE9 standards mode IE9 displays the alert.

Thanks, Bjoern. That makes it a lot harder for me to argue that the 
spec should change to match Chrome, Safari and Opera... But can we at 
least change  when child nodes change to something like when the 
text IDL attribute changes from the empty string to a non-empty string?


David




[whatwg] When a script element's child nodes are changed

2011-10-27 Thread David Flanagan

§4.3.1 The Script Element says:


When a |script 
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element| 
element that is not marked as being parser-inserted 
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#parser-inserted 
experiences one of the events listed in the following list, the user 
agent must synchronously prepare 
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#prepare-a-script 
the |script 
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element| 
element:


  * The |script

http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element|
element gets inserted into a document

http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#insert-an-element-into-a-document.
  * The |script

http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element|
element is in a |Document|

http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#in-a-document
and its child nodes are changed.
  * The |script

http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element|
element is in a |Document|

http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#in-a-document
and has a |src

http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#attr-script-src|
attribute set where previously the element had no such attribute.

Bullet point 2 seems ambiguous to me.  Does it mean only that the list 
of children changes, or does it mean that any change to any child node 
also causes the script to be prepared?  In particular, if a script with 
no src attribute whose only child is an empty text node is inserted into 
the document, the prepare() algorithm will abort before the 
already_started flag is set.  Later, if I do 
script.firstChild.insertData(jscode) does that trigger script execution?


I haven't tried it out yet to see what browsers do, but I think that the 
spec should be clarified to make it explicit.


David


Re: [whatwg] NUL characters in CDATA?

2011-10-24 Thread David Flanagan
I'm responding to my own email here...  Please disregard this thread: 
the bug was in my code, not the tests or the spec.  (The tokenizer 
leaves the NUL characters in CDATA sections, but when those characters 
are inserted into foreign content (as they always are) the NUL 
characters are transformed as the tests expect. My code wasn't doing the 
transformation correctly.)


David

On 10/14/11 9:19 PM, David Flanagan wrote:

The HTML parsing spec says this about tokenizing CDATA sections:

Consume every character up to the next occurrence of the three 
character sequence U+005D RIGHT SQUARE BRACKET U+005D RIGHT SQUARE 
BRACKET U+003E GREATER-THAN SIGN (|]]|), or the end of the file 
(EOF), whichever comes first. Emit a series of character tokens 
consisting of all the characters consumed except the matching three 
character sequence at the end (if one was found before the end of the 
file).
By my reading, if there are NUL \u characters in the input inside 
a CDATA section they will be left unchanged.


But the html5lib test suite includes this test case 
testdata/tree-construction/plain-text-unsafe.dat:


#data
svg![CDATA[\ufiller\utext\u]]
#errors
#document
| html
| head
| body
| svg svg
|   \uFFFDfiller\uFFFDtext\uFFFD

In order to copy this test into my email window, I had to change the 
non-printing characters to Unicode \u escapes, but this is the basic 
test data and it seems to contradict the spec.


Which is right?  Should the spec be modified so that the CDATA section 
state is like the bogus comment state and includes the text  with any 
U+ NULL characters replaced by U+FFFD REPLACEMENT CHARACTER 
characters.?


Thanks,

David




Re: [whatwg] Another bug in the HTML parsing spec?

2011-10-18 Thread David Flanagan

On 10/17/11 5:47 PM, Ian Hickson wrote:

On Mon, 17 Oct 2011, David Flanagan wrote:

In the HTML spec, The rules for parsing tokens in foreign content
include an algorithm for any other end tag.  This is the algorithm at
the very end of
http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html.

I think there are some problems with this algorithm and would appreciate
any insight anyone has:

1) Step 3 includes an instruction to jump to the last step in the list
of steps.  But the last step begins Otherwise, which sounds like it is
an else clause.  Jumping into an else clause is confusing enough that I
wonder if there is an error in the algorithm wording.

Yeah, that's bogus. The last step it's referring to has been removed (it
used to reset the insertion mode). I've fixed the spec.

Thanks.  With that change, my problem #3 below goes away, as you suspected.

2) I can't get all of the parser tests from html5lib to pass with this
algorithm as it is currently written.  In particular, there are 5 tests in
testdata/tree-construction/tests9.dat of this basic form:

!DOCTYPE htmlbodytablemathmifoo/mi/math/table

As the spec is written, themi  tag is a text integration point, so the foo
text token is handled like regular content, not like foreign content.

Oh, my, yeah, that's all kinds of wrong. The text node should be handled
as if it was in the in body mode, not as if it was in table. I'll have
to study this closer.

I think this broke when we moved away from using an insertion mode for
foreign content.

Here's my current workaround:

In 13.2.5, in the rules for whether to use the current insertion mode or 
to insert the token as foreign content, if the token is being inserted 
because the current node is a math (or HTML, but I'm not sure about 
that) integration point, then first set a text_integration_mode flag, 
then invoke the current insertion mode, then clear the flag.


And in the in table insertion mode, when a character token is inserted, 
and the text_integration_mode flag is set, then just process the token 
using in body mode, and otherwise follow the directions that are there now.


I'm not sure that is the best way to fix the spec, but it works for me, 
in the sense that my parser now passes the tests.


David


Henri, do you know how Gecko gets this right currently?



The workaround I've found (I'm not confident that this is the correct
workaround) is to change step 3 of the algorithm so that it only pops
the stack if there is no pending table text.  Another potential
workaround is to use the existence of pending table text as a condition
for sending tokens to the regular insertion mode rather than treating
them as foreign content.

We shouldn't be ending up with pending table text here at all. It should
go straight into the mi element.



3) In this set of tests
http://code.google.com/p/html5lib/source/browse/testdata/tree-construction/webkit01.dat
there is this test:

mathmrowmrowmn1/mn/mrowmia/mi/mrow/math

When the first/mrow  tag is parsed, it is handled as foreign content,
and gets popped off the stack in step 3. Then, the token is reprocessed
in body mode.  It is treated in the any other end tag case.  Since the
top of the stack happens to be another mrow tag, that one gets popped
too.  (Other tests don't fail here because they don't happen to have two
of the same tags on the stack).  This means that themi  element ends
up as a child of themath  element instead of the outermrow  element.

That should be fixed with the updated spec text now, right?





[whatwg] Another bug in the HTML parsing spec?

2011-10-17 Thread David Flanagan
In the HTML spec, The rules for parsing tokens in foreign content 
include an algorithm for any other end tag.  This is the algorithm at 
the very end of 
http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html. 



I think there are some problems with this algorithm and would appreciate 
any insight anyone has:


1) Step 3 includes an instruction to jump to the last step in the list 
of steps.  But the last step begins Otherwise, which sounds like it is 
an else clause.  Jumping into an else clause is confusing enough that I 
wonder if there is an error in the algorithm wording.


2) I can't get all of the parser tests from html5lib to pass with this 
algorithm as it is currently written.  In particular, there are 5 tests 
in testdata/tree-construction/tests9.dat of this basic form:


!DOCTYPE htmlbodytablemathmifoo/mi/math/table

As the spec is written, the mi tag is a text integration point, so the 
foo text token is handled like regular content, not like foreign 
content.  And since it is in a table, it isn't inserted right away but 
is stored as pending table text.  Then, when the /mi tag is processed, 
it is processed as foreign content, going through the algorithm I'm 
talking about here.  That pops it off the stack, and then reprocesses 
the /mi tag as regular content.  This causes the pending table text to 
be inserted, but since the mi has already been popped off the stack, 
the text gets inserted into the math element instead of the mi element.


The workaround I've found (I'm not confident that this is the correct 
workaround) is to change step 3 of the algorithm so that it only pops 
the stack if there is no pending table text.  Another potential 
workaround is to use the existence of pending table text as a condition 
for sending tokens to the regular insertion mode rather than treating 
them as foreign content.


3) In this set of tests 
http://code.google.com/p/html5lib/source/browse/testdata/tree-construction/webkit01.dat 
there is this test:


mathmrowmrowmn1/mn/mrowmia/mi/mrow/math

When the first /mrow tag is parsed, it is handled as foreign content, 
and gets popped off the stack in step 3. Then, the token is reprocessed 
in body mode.  It is treated in the any other end tag case.  Since the 
top of the stack happens to be another mrow tag, that one gets popped 
too.  (Other tests don't fail here because they don't happen to have two 
of the same tags on the stack).  This means that the mi element ends 
up as a child of the math element instead of the outer mrow element.


David Flanagan


[whatwg] Error in HTML parsing spec

2011-10-14 Thread David Flanagan
The Anything else case of the in_table insertion mode of the HTML 
parsing spec reads:
Process the token using the rules for the in body insertion mode, 
except that if the current node is a table, tbody, tfoot, thead, or tr 
element, then, whenever a node would be inserted into the current 
node, it must instead be foster parented.
I think that this is actually incorrect (or at least very misleading) as 
it is worded.  In order to get correct parsing results, it appears that 
you have to do this:


Process the token using the rules for the in body insertion mode, 
except that whenever a node would be inserted into the current node and 
the current node is a table, tbody, tfoot, thead, or tr element, then 
the node to be inserted must instead be foster parented.


As the spec is currently worded, we are directed to check once whether 
the current node is a table, table section or table row, and then 
proceed to use the rules for the in body mode.  In fact, however, it is 
necessary to check whether the current node is a table, section or row 
each time a node is to be inserted.  This came up for me when a text 
node is being inserted into a table when there is an active formatting 
element that gets reconstructed and foster parented.  My reading of the 
current spec text said that the text node should also be foster parented 
(because I only checked whether the current node was a table once), and 
the text node ended up as a sibling of the active formatting element 
rather than a child of that element.


David


[whatwg] NUL characters in CDATA?

2011-10-14 Thread David Flanagan

The HTML parsing spec says this about tokenizing CDATA sections:

Consume every character up to the next occurrence of the three 
character sequence U+005D RIGHT SQUARE BRACKET U+005D RIGHT SQUARE 
BRACKET U+003E GREATER-THAN SIGN (|]]|), or the end of the file 
(EOF), whichever comes first. Emit a series of character tokens 
consisting of all the characters consumed except the matching three 
character sequence at the end (if one was found before the end of the 
file).
By my reading, if there are NUL \u characters in the input inside a 
CDATA section they will be left unchanged.


But the html5lib test suite includes this test case 
testdata/tree-construction/plain-text-unsafe.dat:


#data
svg![CDATA[\ufiller\utext\u]]
#errors
#document
| html
| head
| body
| svg svg
|   \uFFFDfiller\uFFFDtext\uFFFD

In order to copy this test into my email window, I had to change the 
non-printing characters to Unicode \u escapes, but this is the basic 
test data and it seems to contradict the spec.


Which is right?  Should the spec be modified so that the CDATA section 
state is like the bogus comment state and includes the text  with any 
U+ NULL characters replaced by U+FFFD REPLACEMENT CHARACTER 
characters.?


Thanks,

David


[whatwg] HTML parsing: act as if...had been seen using what insertion mode?

2011-10-07 Thread David Flanagan
The HTML parsing algorithm frequently includes directions like act as 
if an end tag with the tag name 'p' had been seen.


Suppose the insertion mode is in caption mode.  It tells me to process 
a token using the rules for in body mode.  Then, while processing a 
token using those rules, I need to act as if a /p tag or /option tag 
had been seen.  My question: what insertion mode do I use to process 
that synthetic end tag?


Perhaps the spec could be modified to add a definition for act as if 
along with the definition for using the rules for.


David


[whatwg] Question about the bookmark in the adoption agency algorithm

2011-10-06 Thread David Flanagan
I'm trying to implement the HTML parser's adoption agency algorithm and 
am puzzled by this step:
Let a bookmark note the position of the formatting element in the list 
of active formatting elements 
http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#list-of-active-formatting-elements 
relative to the elements on either side of it in the list.
The metaphor of a bookmark is such that it marks a position between two 
pages (or list elements in this case), and I'm having trouble with the 
phrase the elements on either side of it: I don't understand how this 
bookmark can mark the position of one element relative to both the 
element before and the element after.  That would require two 
bookmarks!  My guess, from the other steps that involve the bookmark is 
that it is supposed to mark the position after the formatting element, 
but I'm hoping that someone can confirm that for me.


The second time the bookmark is mentioned it is to be moved  
immediately after the new node.  This is a bookmark position that I can 
understand. And the final time the bookmark is mentioned, it is to  
insert the new element into the list...at the position of the 
aforementioned bookmark. Like a cursor in text, a bookmark works as an 
insertion position, so I get this part.


I think that the first mention of the bookmark in the spec should be 
clarified so that it is clear whether the bookmark marks the position 
before the formatting element or the position after the formatting element.


Finally, I assume that the reason this algorithm uses a bookmark 
metaphor in the first place is that simply storing a numeric index into 
the list is not sufficient--that intervening insertions or deletions 
would make maintaining that index overly complicated.  I'm guessing, 
therefore that the most straightforward implemenation of the algorithm 
is to actually insert a special-purpose bookmark object onto the list 
(like the scope markers in the stack).  Anyone who has implemented it 
care to comment?


Thanks!

David



Re: [whatwg] [html5] scope chain for event handlers specified via content attributes

2011-09-09 Thread David Flanagan

On 9/8/11 6:30 PM, Boris Zbarsky wrote:

On 9/8/11 8:23 PM, David Flanagan wrote:

function(event) {
with(event.target.ownerDocument) {
with(event.target.form || {}) {
with(event.target) {
alert(x);
}
}
}
}


This is almost exactly how Chrome implements it.  It's all sorts of 
buggy.  See http://code.google.com/p/chromium/issues/detail?id=80911


So Chrome's but has to do with the fact that the form property is 
spoofable.  That seems easy enough to fix even with this kind of dynamic 
scope chain that allows the scope to match the current position of the 
element in the document, rather that a static scope that matches the 
position the element had when the event handler attribute was set.


On the other hand, I suppose I could see a lexical scoping argument: 
when event handler content attributes are set in an HTML document, we 
might want them to have consistent lexical scope based on where they 
appear in the document, even if they are later moved.  In the same way 
that closures retain their lexical scope even when returned or passed 
into another scope.


I don't think I'm really persuaded by that argument, but on further 
testing I see that Opera uses static scope, just as Firefox and Safari 
do (my test doesn't work in IE, and I don't care enough to figure out 
why).  So Chrome is the outlier here: the spec matches the majority of 
the browsers, and I'll just accept that it is correct.


Thanks for helping to clarify this, Boris.

David


But §7.1.6.1 says that the scope chain should be initialized statically
when the content attribute string is converted to a function. I'd like
to check that that is intentional


It's what most UAs implement, I believe... and doesn't suffer from the 
sorts of issues mentioned in the bug report above.



since it causes counter-intiuitive
(to me) behavior if an element moves between forms or moves between
documents after the event handler attribute is set.


So it does.  Of course people should ideally not be using this syntax 
to start with, so it's mostly there for legacy pages that don't often 
do this sort of thing.



My results: Firefox and Safari create the scope chain statically: when
an element moves between forms, the scope chain remains the same.
Chrome's scope chain is dynamic and resolves identifiers against the
element's new form. Chrome's behavior seems more sensible to me. Is it
correct?


As implemented, no, in my opinion.  See above.


(When an element moves from one document to another (via adoptNode())
firefox uses dynamic scope (perhaps because it is re-creating the
function?)


What actually happens in this case in Firefox internally is that the 
parent (in the JS_GetParent) sense of the element's JS reflection is 
changed.  This was done because origin determination for JS objects 
depended on the scope chain, since Spidermonkey didn't offer any other 
good way to do it.


With ongoing changes to Spidermonkey, this implementation detail may 
change, and then we may be able to preserve static scope in general, 
maybe.


In any case, the behavior there is definitely an artifact of 
implementation details, and not intentional.



In Chrome and Safari, the event handler stops working when
the element is moved from one document to another, so the test doesn't
succeed there.)


It's worth testing Opera and various IE versions here too.

-Boris






[whatwg] [html5] scope chain for event handlers specified via content attributes

2011-09-08 Thread David Flanagan
I've always assumed that if I do e.setAttribute(onclick, alert(x)), 
the resulting event handler function is (or works like) this:


function(event) {
with(event.target.ownerDocument) {
with(event.target.form || {}) {
with(event.target) {
alert(x);
}
}
}
}

That is, I'd expect the scope chain to be created dynamically for each 
invocation of the function.


But §7.1.6.1 says that the scope chain should be initialized statically 
when the content attribute string is converted to a function.  I'd like 
to check that that is intentional, since it causes counter-intiuitive 
(to me) behavior if an element moves between forms or moves between 
documents after the event handler attribute is set.


I've put some test code here:  http://pastebin.mozilla.org/1326758

My results:  Firefox and Safari create the scope chain statically: when 
an element moves between forms, the scope chain remains the same.  
Chrome's scope chain is dynamic and resolves identifiers against the 
element's new form.  Chrome's behavior seems more sensible to me. Is it 
correct?


(When an element moves from one document to another (via adoptNode()) 
firefox uses dynamic scope (perhaps because it is re-creating the 
function?).  In Chrome and Safari, the event handler stops working when 
the element is moved from one document to another, so the test doesn't 
succeed there.)


David


[whatwg] enumerated attributes: needs 1:1 mapping from conforming values to states

2011-08-31 Thread David Flanagan

The HTML spec says:
If a reflecting IDL attribute is a |DOMString| attribute whose content 
attribute is an enumerated attribute 
http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#enumerated-attribute, 
and the IDL attribute is limited to only known values, then, on 
getting, the IDL attribute must return the conforming value associated 
with the state the attribute is in (in its canonical case),

And also says:
The keywords are each defined to map to a particular /state/ (several 
keywords might map to the same state, in which case some of the 
keywords are synonyms of each other; additionally, some of the 
keywords can be said to be non-conforming, and are only in the 
specification for historical reasons).
I assume that if there are multiple keywords that map to the same state, 
only one of those keywords will be conforming.  But I think that needs 
to be clarified in the last-quoted text above.


   David


[whatwg] relationship between Document and HTMLDocument

2011-08-09 Thread David Flanagan

§3.1.1 includes the following:

interface HTMLDocument { ... };
Document implements HTMLDocument;

If I'm reading WebIDL correctly, this means that this expression must be 
false:


   document instanceof HTMLDocument

And also that this code will have no visible effect on the document object:

HTMLDocument.prototype.foo = function() { ... }

Furthermore, if I want to monkeypatch a method like getElementsByName() 
that is defined by HTML, the correct place to do that is on 
Document.prototype, not HTMLDocument.prototype


Currently, of course (tested in FF, Chrome and Safari), browsers treat 
HTMLDocument as if it were declared like this:


interface HTMLDocument : Document { ... };

This means that in the current generation of browsers:

   document instanceof HTMLDocument// = true
   HTMLDocument.prototype.foo = function() {...}  // affects document
   Document.prototype.getElementsByName // undefined; can't monkeypatch it

I would guess (but have no data) that web compatibility will make these 
behaviors difficult to change.


I assume that the use of an implements declaration rather than direct 
inheritance is done to create a clean boundary between the DOM spec and 
the HTML spec.  But it seems to me that this clean boundary does not 
reflect messy reality.


Ian: any chance you'd change HTML to specify that HTMLDocument is a 
regular subclass of Document?


Anne: that would probably mean that you'd have to change the DOM spec to 
say that DOMImplementation.create*Document() creates an HTMLDocument 
even though your spec does not define that interface...


David



Re: [whatwg] relationship between Document and HTMLDocument

2011-08-09 Thread David Flanagan

On 8/9/11 8:53 AM, Boris Zbarsky wrote:

On 8/9/11 11:18 AM, David Flanagan wrote:

I assume that the use of an implements declaration rather than direct
inheritance is done to create a clean boundary between the DOM spec and
the HTML spec.


Or just to reflect Ian's belief that all documents should implement 
all document intefaces.


In particular, the current spec text (which indeed does not match 
either older DOM specs or current implementations) requires all 
Document objects to implement the HTMLDocument interface.  I don't 
believe that's the case in current UAs, fwiw...


-Boris
Yes, that is the case in FF and Chrome, at least.  I didn't bring that 
up because my intuition is that browsers could make that change (adding 
HTMLDocument members to non-HTML documents) without as much web 
compatibility impact.


David


Re: [whatwg] relationship between Document and HTMLDocument

2011-08-09 Thread David Flanagan

On 8/9/11 12:53 PM, Ian Hickson wrote:

On Tue, 9 Aug 2011, David Flanagan wrote:

�3.1.1 includes the following:

interface HTMLDocument { ... };
Document implements HTMLDocument;

If I'm reading WebIDL correctly, this means that this expression must be
false:

document instanceof HTMLDocument

And also that this code will have no visible effect on the document object:

 HTMLDocument.prototype.foo = function() { ... }

Furthermore, if I want to monkeypatch a method like getElementsByName() that
is defined by HTML, the correct place to do that is on Document.prototype, not
HTMLDocument.prototype

Currently, of course (tested in FF, Chrome and Safari), browsers treat
HTMLDocument as if it were declared like this:

 interface HTMLDocument : Document { ... };

This means that in the current generation of browsers:

document instanceof HTMLDocument// =  true
HTMLDocument.prototype.foo = function() {...}  // affects document
Document.prototype.getElementsByName // undefined; can't monkeypatch it

I would guess (but have no data) that web compatibility will make these
behaviors difficult to change.

Possibly. I think an alternative is to make the HTML spec just add all the
members to Document, and then define window.HTMLDocument as returning the
Document interface object. This would make instanceof and monkeypatching
work as today.

So you'd declare HTMLDocument with the [NoInterfaceObject] extended 
attribute and then add attribute HTMLDocument to the Window interface?  
That changes HTMLDocument from non-enumerable to enumerable, but that 
seems unlikely to be a compatibility issue.  That works for me, I think.


David


Re: [whatwg] relationship between Document and HTMLDocument

2011-08-09 Thread David Flanagan

On 8/9/11 1:58 PM, Ian Hickson wrote:

On Tue, 9 Aug 2011, David Flanagan wrote:

Possibly. I think an alternative is to make the HTML spec just add all
the members to Document, and then define window.HTMLDocument as
returning the Document interface object. This would make instanceof
and monkeypatching work as today.

So you'd declare HTMLDocument with the [NoInterfaceObject] extended
attribute and then add attribute HTMLDocument to the Window interface?

That would have the same effect, but what I had in mind was actually to
change the HTML spec to not define an HTMLDocument interface, instead
renaming it to Document and adding the 'partial' WebIDL modifier.

We'd also have to do this for SVGDocument and other document objects;
before doing this it would be good to see if it's something that is
generally agreeable to everyone.


Is the partial keyword a brand-new feature of WebIDL?  I didn't see them 
discussed on public-script-coord at all...  A partial interface sounds 
like it would work to me.

That changes HTMLDocument from non-enumerable to enumerable, but that
seems unlikely to be a compatibility issue.  That works for me, I think.

Could you elaborate on this? I'm not sure what you mean exactly.

The HTMLDocument interface object is current (at least in FF, and per 
the WebIDL spec) non-enumerable.  It doesn't show up in for/in loops on 
the window.  If the HTML spec were to add an attribute to the Window 
object to define the HTMLDocument property, WebIDL would make that 
property enumerable.  It would also change from a data property to an 
accessor property.


I'm not arguing that these changes would be a problem, just noting 
them.  The much bigger change, of course, is that HTMLDocument would be 
=== Document.


[whatwg] DataTransfer.files tri-specification conflict

2011-02-19 Thread David Flanagan

1) HTML5 says this about DataTransfer.files:


The files attribute must return a live FileList sequence consisting of File 
objects representing the files found by the following steps. The same object 
must be returned each time. Furthermore, for a given FileList object and a 
given underlying file, the same File object must be used each time.


2) The FileAPI spec defines FileList as a sequenceFile

3) The Web IDL spec says this about sequences:


The sequenceT type is a parameterized type whose values are (possibly 
zero-length) sequences of values of type T. Sequences are always passed by value. In 
language bindings where a sequence is represented by an object of some kind, passing 
a sequence to a user agent implemented object will not result in a reference to the 
sequence being kept by that object. Similarly, any sequence returned from a user 
agent implemented object will be a copy and modifications made to it will not be 
visible to the object.


Doesn't WebIDL pass-by-value requirement conflict with the HTML5 
always-return-the-same-object requirement?


David


Re: [whatwg] Why are media event handlers defined on HTMLElement instead of HTMLMediaElement

2011-02-15 Thread David Flanagan

On 02/15/2011 12:44 PM, Philip Jägenstedt wrote:

On Tue, 15 Feb 2011 19:13:26 +0100, David Flanagan
da...@davidflanagan.com wrote:

What about Document and Window? What's the justification for defining
the media event handler attributes on those objects?


Huh, it is on Window, I hadn't seen that before. They were added in
http://html5.org/r/3005 but I can't say I understand why.

I can't see it on Document in Web DOM Core, though, am I missing something?



Sorry, I meant HTMLDocument:

http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#documents

Looks like they were added to HTMLDocument in the same change set.

David


[whatwg] Why are media event handlers defined on HTMLElement instead of HTMLMediaElement

2011-02-14 Thread David Flanagan
The draft specification defines 20+ medial event handler IDL attributes 
on HTMLElement.  These events are non-bubbling and are always targeted 
at audio and video tags, so I wonder if they wouldn't be better 
defined on HTMLMediaElement instead.


David


[whatwg] HTMLElement.onreadystatechange

2011-02-14 Thread David Flanagan
The spec says that every HTMLElement has an onreadystatechange idl 
attribute.  But then it never says anything about firing 
readystatechange events at elements, only at the Document.


Can it be removed from HTMLElement, or does it need to be there for web 
compatibility?


David


Re: [whatwg] Drag-and-drop feedback

2011-01-31 Thread David Flanagan

Ian,

I love the new dropzone attribute.  Nice work.  Here is one nit, and a 
couple of questions


nit: One of your old examples near the beginning of the DnD section 
involves class=dragzone, which seems confusing now that you've added 
an attribute with the same zone.  Maybe change that class to droppable?


Q1) Say I want to create a library to emulate dropzone today, because it 
is just so much nicer than all the dragenter and dragleave stuff.  In 
order to do this right, I need to be able to tell if the browser already 
supports dropzone. Will it work to test (dropzone in 
document.createElement('div'))?


I see the spec says:


The dropzone attribute must reflect the content attribute of the same name.


But I'm not certain that that means a property must exist if the 
attribute does not.


Q2) If I understand correctly, the dropzone attribute means that we no 
longer *have* to write dragenter and dragleave handlers.  But every 
useful dropzone I've seen in practice provides some kind of feedback 
(changes background color, e.g.) when it is armed and ready to accept 
a drop.  Is there any mechanism for doing this?  If not, then that 
really diminishes the value of dropzone.  I can't see how I'd write 
dragenter and dragleave handlers to change the background color of the 
element and also rely on the dropzone attribute, since it seems to be 
processed after dragenter/leave are triggered...


One approach would be to define dropzone_activate and 
dropzone_deactivate events to handle this case.  A better solution might 
be to define a :dropzone-active CSS pseudo class, if you can coordinate 
that with the CSS folks...


David


[whatwg] structured clone algorithm should be defined for primitive values

2011-01-28 Thread David Flanagan

Ian,

The structured clone algorithm is currently defined only for object 
inputs and doesn't say what should happen when a primitive value is 
passed to it.  (The internal structured cloning algorithm handles 
primitives, but the outer level one does not.)


Browser implementations allow primitives such as strings to be passed to 
History.pushState(), window.postMessage() and other methods that 
reference the structured clone algorithm.


I think you can fix this by changing object to value in four places:


When a user agent is required to obtain a structured clone of an object [change 
this to value],
it must run the following algorithm, which either returns a separate 
object [value],

or throws an exception.


Let input be the object [value] being cloned.

Let memory be an association list of pairs of objects, initially empty. This is 
used to handle duplicate references. In each pair of objects, one is called the 
source object and the other the destination object.

Let output be the object [value] resulting from calling the internal structured 
cloning algorithm with input and memory.



David

David


Re: [whatwg] File API Streaming Blobs

2011-01-25 Thread David Flanagan

On 01/24/2011 04:24 AM, Anne van Kesteren wrote:

(I removed the Chromium related list as I am not subscribed there.)

On Fri, 21 Jan 2011 21:35:53 +0100, Adam Malcontenti-Wilson
adman@gmail.com wrote:

XHR2 is one part of the APIs required for my use case as that is the
easiest way to download for example a music file. However, while
downloading, there's no way to pipe the download(ing) blob to the
HTML5 Audio element as to play Audio it requires an object URL, and an
object URL can (currently) only point to a static Blob, as well as the
fact that a Blob cannot be appended. This would be important for
listening streaming audio that needs to be processed in JavaScript or
cached to persistant storage using the Filesystem APIs without having
to wait for the entire file to be downloaded into an ArrayBuffer or
Blob.


There is a plan of allowing direct assigning to IDL attributes besides
creating URLs.

I.e. being able to do:

audio.src = blob

(The src content attribute would then be something like about:objecturl.)

I am not sure if that API should work differently from creating URLs and
assigning those, but we could consider it.


I don't see the point of that, if all it does is save one call to 
URL.createObjectURL() (and also one call to revokeObjectURL())?


In any case, making this behave differently than the URL API seems like 
a bad idea.





My suggestion was for another alternative version of Blob and/or
createObjectUrl that mimicks how a HTTP request can be parsed and (in
the case of audio or video) start playing before it has finished
downloading (e.g. got to the content-length or had a connection close)
by pushing content when it is appended to the blob and then the
virtual connection can be closed when the Blob has finished being
built by calling a close() function. I've also thought of other
alternatives, but I'd make sure that there isn't already a way to do
this with the current (specified) APIs, and I think this has the most
other use cases as any data that takes a while to process can be
streamed to the user or other parts of the browser.


Is there actually a good reason for the URL API to have behave in this way?



Adam's use case--to be able to download, play and cache audio data at 
the same time--seems like a pretty compelling one.  I think this is 
fundamentally an issue with the Blob API, not the URL API.  Blobs just 
seem like they ought to stream.  When you get a blob in the onprogress 
handler of an XHR2, you ought to be able to fire up a FileReader on it 
and have it automatically read from the blob as the XHR2 writes to the 
blob.  But currently (I think) you have to slice the blob to get only 
the new bytes and start a new FileReader each time onprogress is called. 
 (Or wait for onload, of course.)


Similarly, when you get your first onprogress event for a Blob download, 
you ought to be able to create a URL for that Blob that remains valid 
while the download is in progress.  So you can use that url with an 
audio element, for example.


Also: BlobBuilder seems to me as if it ought to be a streaming API.  It 
feels like it ought to work like this:


   var bb = new BlobBuilder();
   var b1 = bb.getBlob();
   var u1 = URL.createObjectURL(b1);
   bb.append(hello world);
   var b2 = bb.getBlob();
   var u2 = URL.createObjectURL(b2);
   b1 === b2   // They ought to be equal, but they're not
   u1 === u2   // Ought to be equal, but they're not
   bb.close(); // New method: now no more appends are allowed.

David

P.S. This is probably the wrong list for this discussion, isn't it?


Re: [whatwg] File API Streaming Blobs

2011-01-21 Thread David Flanagan

Doesn't the current XHR2 spec address this use case?
Browsers don't seem to implement it yet, but shouldn't something like 
this work for the original poster?


x = new XMLHttpRequest()
x.open(GET, http://my-media-file;);
x.responseType = blob;
x.send();
var nbytes = 0;
x.onprogress = function(e) {
   var blob = x.response.slice(nbytes, e.loaded-nbytes);
   nbytes += blob.size;
   var reader = new FileReader();
   reader.readAsArrayBuffer(blob, function() {
   // process blob content here
});

}

David Flanagan

On 01/21/2011 02:02 AM, Jeremy Orlow wrote:

Would something like this tie in to thedevice  work that's being done
maybe?

-- Forwarded message --
From: Adam Malcontenti-Wilsonadman@gmail.com
Date: Fri, Jan 21, 2011 at 6:21 AM
Subject: [chromium-html5] File API Streaming Blobs
To: Chromium HTML5chromium-ht...@chromium.org


Hi.
I'm trying to make an application which will download media files from
a server and cache them locally, as well as playing them back but I'm
trying to figure out how I could do so without making the user wait
for the entire file to be downloaded, converted to a blob, then
saved.

For example, suppose that I create a new BlobBuilder, append hello,
get the Blob, and then create an object url from that blob, and then
open the object url. Any other text that I append to the BlobBuilder
would not go into the old blob that I created a url for, and hence not
shown making streaming impossible.

Is there any other methods in the spec(s) to implement such
streaming?

If not, perhaps there needs to be yet another object to have a way of
creating a StreamingBlob that doesn't close the virtual connection
to the browser until a close method is called, thereby facilitating
streaming.

Thanks,





[whatwg] ArrayBuffer and the structured clone algorithm

2011-01-07 Thread David Flanagan
The structured clone algorithm currently allows ImageData and Blob 
objects to be cloned but doesn't mention ArrayBuffer.  Is this 
intentional?  I assume there are no security issues involved, since one 
could copy the bytes of an ArrayBuffer into either a Blob or an 
ImageData object in order to clone them.


David


Re: [whatwg] Additional onxxxx event attributes for DOM Level3 Events

2010-11-30 Thread David Flanagan

On 11/30/2010 03:18 PM, Garrett Smith wrote:

On 11/30/10, Ian Hicksoni...@hixie.ch  wrote:

On Mon, 16 Aug 2010, Hajime Morita wrote:


I noticed that some events which are defined in DOM Level3 Events [1]
don't have
associated HTML attributes.
For example, keypress event has associated onkeypress attribute.
But focusin event doesn't have onfocusin attribute.


It does in IE.


Here is a list:

* wheel event

`onmousewheel`? That's in IE.


The wheel event is a different, generalized, version of the 
mousewheel event.  As far as I know, no one has implemented it yet.



* textInput event


Following the convention of lc for event handler properties, `ontextinput`?


Last I checked, the DOM3 spec had changed textInput to textinput. 
Safari and Chrome fire textInput (with a capital I) events but do not 
currently define an attribute for it.



* focusin event
* focusout event


Those are in IE.


* compositionstart event
* compositionupdate event
* compositionend event
* DOMXxxx events


Last I checked, the DOMxxx events were all basically being deprecated in 
D3E.  So it would be bad to standardize attributes for those, I think.


David



I think these events should have associated attributes defined.
DOM mutation events might be better to skip due to its long name and rare
usage.
But it's just a preference and not a strong opinion.



I'm happy to add new event handler attributes, but not to add them just
based on completeness. New features are added based on either use cases
(i.e. problems that authors or users are facing), or compatibility (i.e.
things that browsers already do). If there are specific events for which
event handler attributes would be useful, I encourage you to request those
specifically, describing either the relevant use cases or citing the
existing implementations, as appropriate.



The reason event handler properties are useful is that they can be
detected. A program can make a fair assessment as to whether the
element supports the event handler in question and how to handle the
case where that isn't supported.

That isn't possible with event target; there is no such,
`object.generatesEvent`, nor will there be in D3E, according its
author.

Garrett





Re: [whatwg] Canvas feedback (various threads)

2010-08-12 Thread David Flanagan

Boris Zbarsky wrote:

On 8/11/10 5:42 PM, David Flanagan wrote:

I think that the sentence The transformations must be performed in
reverse order is sufficient to remove the ambiguity in multiplication
order.


It is?  It sounds pretty confusing to me... reverse from what?


I agree that it is confusing.  But Ian had asked whether it is possible 
to implement the spec, as now written, incorrectly.  I suspect that any 
implementation that did transformations wrong would violate the spec 
somewhere.  I still think it is worth clarifying the spec, but by Ian's 
criteria, I suspect it is not strictly necessary.


The right way to specify what happens when composing two transformations 
is to just explicitly say which transformation is applied first, instead 
of talking about the algebraic operations on the matrix representations. 
 In my opinion.


But if you don't talk about the algebraic operations then you haven't 
really defined what a transformation is, have you?





must set the current transformation matrix to the matrix obtained by
postmultiplying the current transformation matrix with this matrix:

a c e
b d f
0 0 1


See, that makes inherent assumptions about row vs column vectors that 
aren't stated anywhere, right?


I suppose it does.  So to be complete, the spec would have to show the 
math required to transform a point (x,y) using the CTM.


Are you suggesting that there is some way that the spec can be written 
generically without any assumptions about row vector or column vector 
format?  Note that the matrix shown above already appears in the current 
version of the transform() method description.  I don't see how to avoid 
picking one form or another unless you want to define a CTM as an array 
of 6 numbers and show the formulas for updating each of those numbers 
without referring to matrix multiplication at all.


David


-Boris





Re: [whatwg] Canvas feedback (various threads)

2010-08-11 Thread David Flanagan

Ian Hickson wrote:

On Mon, 19 Jul 2010, David Flanagan wrote:

Even changing the argument names to neutral a,b,c,d,dx,dy would be
better than what is there currently.


Done.



Thanks



On Mon, 19 Jul 2010, David Flanagan wrote:

While I'm harping on the transform() method, I'd like to point out that
the current spec text must multiply the current transformation matrix
with the matrix described by... is ambiguous because matrix
multiplication is not commutative.  Perhaps an explicit formula that
showed the order would be clearer.

Furthermore, if the descriptions for translate(), scale() and rotate()
were to altered to describe them in terms of transform() that would
tighten things up.


Could you describe what interpretations of the current text would be valid
but would not be compatible with the bulk of existing implementations? I'm
not sure how to fix this exactly. (Graphics is not my area of expertise,
unfortunately. I'm happy to apply any proposed text though!)



I think that the sentence The transformations must be performed in 
reverse order is sufficient to remove the ambiguity in multiplication 
order.  So the spec is correct (but confusing) as it stands, except that 
it doesn't actually say that the CTM is to be replaced with the product 
of the CTM and the new matrix.  It just says multiply them.


I suggest changing the description of transform() from:


must multiply the current transformation matrix with the matrix described by:


To something like this:

must set the current transformation matrix to the matrix obtained by 
postmultiplying the current transformation matrix with this matrix:


a c e
b d f
0 0 1

That is:

 a c e
CTM = CTM *  b d f
 0 0 1

Changing translate(), scale() and rotate() to formally define them in 
terms of transform() would be simple, and the current prose descriptions 
of the methods could then be moved to the non-normative green box.  The 
current descriptions suffer from the use of the word add near the word 
matrix when in fact a matrix multiplication is to be performed, but I 
don't think they can be mis-interpreted as they stands. I'd be happy to 
write new method descriptions if you want to tighten things up in this 
way, however.


David


Re: [whatwg] Canvas: clarification of compositing operations needed

2010-07-29 Thread David Flanagan

James Robinson wrote:
On Wed, Jul 28, 2010 at 2:46 PM, Tab Atkins Jr. jackalm...@gmail.com 
mailto:jackalm...@gmail.com wrote:


On Wed, Jul 28, 2010 at 2:43 PM, David Flanagan
da...@davidflanagan.com mailto:da...@davidflanagan.com wrote:
  Firefox and Chrome disagree about the implementation of the
  destination-atop, source-in, destination-in, and source-out
compositing
  operators.  Test code is attached.


I don't think your attachment made it through. 
 https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html shows 
some of the differences, although it does not cover all cases.


You didn't miss much.  My example was very similar to the one you link to.



The spec is certainly clear but that does not make the behavior it 
specifies good.  I find the spec's behavior pretty bizarre and Microsoft 
has expressed a preference for the Safari/Chrome 
interpretation: http://lists.w3.org/Archives/Public/public-canvas-api/2010AprJun/0046.html - 
although that thread did not get much discussion.  


Thanks for that link.  The thread you reference refers back to an 
earlier thread on this list.  My apologies for not finding it and 
reading it before posting again.


For example, I think
drawing a 20x20 image into a 500x500 canvas without scaling with a 
globalCompositeOperation of 'copy' should result in only the 20x20 
region being cleared out, not the entire canvas.


Yikes!  It hadn't occurred to me that copy should behave that way.  But 
you're right that that is what the spec requires.  Opera does it that 
way.  Firefox, thankfully, does not.


Perhaps independently of the debate over infinite bitmap vs. shape 
extents, we can agree that copy is a special value that means do not 
perform compositing


David


Re: [whatwg] Canvas: clarification of compositing operations needed

2010-07-29 Thread David Flanagan

Tab Atkins Jr. wrote:

On Wed, Jul 28, 2010 at 11:39 PM, David Flanagan
da...@davidflanagan.com wrote:

James Robinson wrote:

For example, I think
drawing a 20x20 image into a 500x500 canvas without scaling with a
globalCompositeOperation of 'copy' should result in only the 20x20 region
being cleared out, not the entire canvas.

Yikes!  It hadn't occurred to me that copy should behave that way.  But
you're right that that is what the spec requires.  Opera does it that way.
 Firefox, thankfully, does not.

Perhaps independently of the debate over infinite bitmap vs. shape extents,
we can agree that copy is a special value that means do not perform
compositing


That value already exists - it's called source-over. 


You've lost me.  Are we disagreeing over the meaning of composite.  It 
seems to me that source-over is clearly doing compositing: the result 
pixel is a blend of the source and destination pixels.



 copy does

some special compositing stuff no matter whether you do global or
local compositing - try using 'copy' when the source has .1 opacity.


The copy operation does not blend pixels: the result pixel is just the 
source pixel.  So when try what you suggest and draw with almost 
transparent pixels using the copy operation, the result is almost 
transparent pixels, regardless of what was under them.  That, to me, 
means that no compositing is being done.  What am I missing here?  What 
kind of special stuff is going on with copy compositing?


I'd argue that copy is the 2nd most important compositing operation 
after source-over. Everyone but Opera violates the spec and treats it 
as a local operation.  If I understand correctly, the reason that the 
spec can't be changed to define compositing as a local operation is that 
vendors can't agree on what local means w.r.t. antialiasing, shadows, 
etc.


But since copy is a really important value, I propose that we sidestep 
the larger issue and explicitly state that when globalCompositeOperation 
is set to copy it means just draw the damn pixels like we used to do 
in the olden days before we got all fancy with alpha channels and 
stuff.  A refinement would be to add a new value none and make copy 
a synonym for none.


David


[whatwg] Canvas: need getTransform() and getInverseTransform() methods

2010-07-28 Thread David Flanagan
The Canvas API has a setTransform() method to set an arbitrary 
transformation matrix, but has no corresponding getTransform() method to 
query the current transformation matrix or even to use the CTM to 
transform a point in the current coordinate system to the default 
coordinate system.  The only way current to achieve this is to replace 
translate(), scale(), and rotate() methods with instrumented versions 
that explicitly keep track of the CTM.


Here are the two use cases that I've run into in which I've needed a way 
to convert from the current coordinates to the device coordinates.


1) The shadowOffsetX,Y properties are not subject to the CTM (except in 
Chrome, which gets it wrong).  This is probably as it should be.  But 
suppose I've written a method draw_scene() that draws a pretty picture 
with shadows.  Now suppose I want to render my scene at high-resolution 
to produce a version suitable for printing with code like this, for example:


var bigcanvas = document.createElement(canvas);
bigcanvas.width = 5*canvas.width;
bigcanvas.height = 5*canvas.height;
var context = bigcanvas.getContext(2d);
context.scale(5,5);
draw_scene(context);
var img = bigcanvas.toDataURL();
window.open(img).print();

In this scenario, I naturally want my shadows to scale along with the 
rest of the picture, so that my high-resolution printable version of the 
scene looks just like the on-screen version.


In order to make this work right, I need some way to transform shadow 
offsets in the current coordinate system into shadow offsets in the 
default coordinate system.  In my draw_scene() method, for example, I 
need to be able to write code like this:


// Set shadow offsets to 5 units in the the current coordinates
var offset0 = c.transformPoint(0,0);
var offset1 = c.transformPoint(5,5);
c.shadowOffsetX = offset1[0]-offset0[0];
c.shadowOffsetY = offset1[1]-offset0[1];

(That code is pretty ugly, but I think it accomplishes what I need. 
Better might be a tranformDimension() method or tranformPoints() that 
can take any number of pairs of x,y coordinates).


2) The second use case I've encountered is when I want to perform some 
kind of drawing operation on a portion of the canvas but first want to 
make a backup copy so I can restore the dirty rectangle later.  To do 
this, I obviously use drawImage() or getImageData() to extract the 
pixels I want to save.  But both of these methods expect the coordinates 
of the source rectangle in the default coordinate system.  If I don't 
have a way to convert from the current coordinates back to default 
coordinates then I end up having to back up the entire canvas rather 
than just a rectangular portion of it.  (As an aside a 
getPathBoundingBox() method would be nice for this scenario, too)


In addition to the need to be able to transform points and dimensions 
from the current coordinate system to the default coordinate system, 
there is also a related need to be able to transform in the opposite 
direction.  The use case I've thought about is when you want to be able 
to determine the coordinates (in the current system) of the corners of 
the canvas.  That is, I'd like to be able to transform canvas.width and 
canvas.height to the current coordinates.


From an ease-of-specification perspective, the easiest way to enable 
these things would be to add getTransform() and getInverseTransform() 
methods that would return arrays of the 6 matrix elements.


This would be a no-op:

CanvasRenderingContext2D.prototype.setTransform.apply(c,c.getTransform())

And this would be the same as calling setTransform(1,0,0,1,0,0):

CanvasRenderingContext2D.prototype.transform.apply(c,c.getInverseTransform())

getInverseTransform() would throw a suitable exception if the CTM was 
not invertible.


From a programmer usability perspective, perhaps adding methods like 
transformPoints(), transformBoundingBox(), and transformDimensions() 
would be more helpful.  But I'm not sure what the optimal set of such 
methods would be.


David Flanagan


[whatwg] Canvas: clarification of compositing operations needed

2010-07-28 Thread David Flanagan
Firefox and Chrome disagree about the implementation of the 
destination-atop, source-in, destination-in, and source-out compositing 
operators.  Test code is attached.


Chrome doesn't touch any destination pixels that are not underneath the 
source pixels.  Firefox, on the other hand, treats the entire canvas 
(inside the clipping region) as the destination and if you use the 
destination-in operator, for example, will erase any pixels outside of 
whatever you are drawing.


I suspect, based on the reference to an infinite transparent black 
bitmap in 4.8.11.1.13 Drawing model that Firefox gets this right and 
Chrome gets it wrong, but it would be nice to have that confirmed.


I suggest clarifying 4.8.11.1.3 Compositing to mention that the 
compositing operation takes place on all pixels within the clipping 
region, and that some compositing operators clear large portions of the 
canvas.


David








Re: [whatwg] Canvas: clarification of compositing operations needed

2010-07-28 Thread David Flanagan

Tab Atkins Jr. wrote:

On Wed, Jul 28, 2010 at 2:43 PM, David Flanagan da...@davidflanagan.com wrote:

Firefox and Chrome disagree about the implementation of the
destination-atop, source-in, destination-in, and source-out compositing
operators.  Test code is attached.

Chrome doesn't touch any destination pixels that are not underneath the
source pixels.  Firefox, on the other hand, treats the entire canvas (inside
the clipping region) as the destination and if you use the destination-in
operator, for example, will erase any pixels outside of whatever you are
drawing.

I suspect, based on the reference to an infinite transparent black bitmap
in 4.8.11.1.13 Drawing model that Firefox gets this right and Chrome gets it
wrong, but it would be nice to have that confirmed.

I suggest clarifying 4.8.11.1.3 Compositing to mention that the compositing
operation takes place on all pixels within the clipping region, and that
some compositing operators clear large portions of the canvas.


The spec is completely clear on this matter - Firefox is right,
Chrome/Safari are wrong.  They do it wrongly because that's how
CoreGraphics, their graphics library, does things natively.

~TJ



Thanks for the confirmation and the explanation of why webkit gets it 
wrong.


I disagree that the spec is completely clear, however.  In order to 
understand it you have to skip from section 3 on compositing operators 
to section 13 which mentions the infinite bitmap and compositing within 
the clipping region. There is no mention of the relevance of the 
clipping region in the section on compositing which seems like an oversight.


Also, descriptions of the operators cover only transparent and opaque 
pixels; they don't explain how compositing is done for translucent 
pixels, except by oblique reference to the Porter-Duff paper.


David


Re: [whatwg] Canvas stroke alignment

2010-07-20 Thread David Flanagan

Nick wrote:
Canvas would benefit from a way to set stroke alignment. With the only 
available alignment being center, which is not very useful, custom paths 
have to be drawn to mimic inside and outside stroke alignment. That 
workaround may give unwanted transparency on pixels between a path and 
its stroke path once a path goes diagonal or curves.


Having Canvas take care of stroke alignment (center, inside and outside) 
by adding something like strokeAlign can fix these transparency problems 
and makes adding strokes a lot easier and more useful.


--
Nick Stakenburg



Currently for inside alignment, I think you can do this, with no 
computation of custom path:


c.save();
c.clip();
c.lineWidth *= 2;
c.stroke();
c.restore();

Outside alignment is easy if you're also going to fill the path, of 
course.  But if you want to leave the inside of the path untouched you 
could do something like this, I think:


var url = canvas.toDataURL();  // Back up canvas content
var img = document.createElement(img);
img.src = url;
c.save();
c.linewidth *= 2;
c.stroke();
c.clip();
c.drawImage(img, 0, 0);  // Restore original bitmap inside the path
c.restore();

You can't use getImageData()/putImageData() for this, since they ignore 
the clipping region.


Another approach for outside stroke alignment, if you know the 
directionality of your path would be to turn the path inside out by 
drawing an off-screen rectangle around the canvas in the opposite 
direction.  Then the outside of your path becomes the inside of the new 
path and you can use the technique above for inside alignment...


David


[whatwg] Canvas transform() and matrix element notation

2010-07-19 Thread David Flanagan

The spec describes the transform() method as follows:


The transform(m11, m12, m21, m22, dx, dy) method must multiply the current 
transformation matrix with the matrix described by:

m11 m21 dx
m12 m22 dy
0   0   1


The first number in these argument names is the column number and the 
second is the row number.  This surprises me, and I want to check that 
it is not an inadvertent error:


1) Wikipedia says (http://en.wikipedia.org/wiki/Matrix_multiplication) 
that the convention is to list row numbers first


2) Java's java.awt.geom.AffineTransform class also lists the row index 
first, as in the following javadoc excerpt:



[ x']   [  m00  m01  m02  ] [ x ]   [ m00x + m01y + m02 ]
[ y'] = [  m10  m11  m12  ] [ y ] = [ m10x + m11y + m12 ]
[ 1 ]   [   001   ] [ 1 ]   [ 1 ]


It would be nice if this spec was not inconsistent with other usage. 
Even changing the argument names to neutral a,b,c,d,dx,dy would be 
better than what is there currently.


David



[whatwg] Canvas transform() method and matrix multiplication order

2010-07-19 Thread David Flanagan
While I'm harping on the transform() method, I'd like to point out that 
the current spec text must multiply the current transformation matrix 
with the matrix described by... is ambiguous because matrix 
multiplication is not commutative.  Perhaps an explicit formula that 
showed the order would be clearer.


Furthermore, if the descriptions for translate(), scale() and rotate() 
were to altered to describe them in terms of transform() that would 
tighten things up.


David


Re: [whatwg] Canvas isPointInPath() coordinate space

2010-07-15 Thread David Flanagan

Oliver Hunt wrote:

On Jul 14, 2010, at 10:58 PM, David Flanagan wrote:



So here's my question: if I want to do hit-testing as described above, do I 
need to take the mouse coordinates from the event, subtract the offset of the 
canvas, and then divide by 2?  As the spec is written, I think I do have to do 
that division manually.  Is that what is intended?  What if the user has zoomed 
in?  Is it even possible to use isPointInPath() correctly in that case?


isPointInPath works in the context of the canvas -- if you have coordinates 
from an event you will need to transform those from screen coordinates to the 
base coordinate space used by the canvas.  In other words:
1. adjust for the offset of the canvas element relative to the event coordinate 
space
2. adjust for the scale factor between the canvas element and the canvas 
element's context



Thanks for the clarification, Oliver.  Now that getBoundingClientRect() 
is widely implemented and is being standardized, those calculations are 
no longer difficult!


David


[whatwg] Canvas coordinate space units

2010-07-14 Thread David Flanagan
I'm confused by the term coordinate space units as applied to the 
canvas spec.  It does not seem to be defined.


It is used in the definition of the translate() method, for example, and 
seems to imply that coordinate space units are affected by scale() 
operations.


It is used in the definition of the lineWidth attribute as well. 
Chrome, Firefox and Opera all scaled lineWidth and Phillip Taylor's test 
suite expects this behavior as well.


But then in the definition of shadowOffsetX and Y, the spec reads:


Their values are in coordinate space units. They are not affected by the 
current transformation matrix.


The description of isPointInPath() uses similar language:


 when treated as coordinates in the canvas coordinate space unaffected by the 
current transformation,


So which is it?  Are coordinate space units affected by scaling or 
not?  Are lineWidths supposed to be scaled? (Implementations do so 
consistently) Are shadow offset supposed to be scaled? (Chrome does, 
Firefox and Opera do not)


I think a clearer definition of coordinate spaces would be helpful. 
Maybe device space for the underlying pixmap, canvas space for the 
coordinates defined by the width and height attributes of the canvas, 
and user space for the space defined by the current transformation matrix?


David


Re: [whatwg] Canvas coordinate space units

2010-07-14 Thread David Flanagan

Aryeh Gregor wrote:

On Wed, Jul 14, 2010 at 3:03 PM, David Flanagan da...@davidflanagan.com wrote:

I'm confused by the term coordinate space units as applied to the canvas
spec.  It does not seem to be defined.


It seems clear to me.  


Even if clear, it is still undefined.  And the words coordinate space 
are so generic as to be meaningless here.  canvas units or something 
would make more sense.


The 2D context represents a Cartesian plane,

and the units for everything are units within that plane.  One
coordinate space unit might correspond to any number of pixels,
depending:


The intrinsic dimensions of the canvas element equal the size of the
coordinate space, with the numbers interpreted in CSS pixels. However,
the element can be sized arbitrarily by a style sheet. During
rendering, the image is scaled to fit this layout size.

The size of the coordinate space does not necessarily represent the
size of the actual bitmap that the user agent will use internally or
during rendering. On high-definition displays, for instance, the user
agent may internally use a bitmap with two device pixels per unit in
the coordinate space, so that the rendering remains at high quality
throughout.



As an aside, do you think any implementations actually do that?  It 
seems to me that it would cause real problems with drawImage(): images 
would look bad compared to drawn graphics...




It is used in the definition of the translate() method, for example, and
seems to imply that coordinate space units are affected by scale()
operations.


The transformation matrix is referred to in a particular well-defined
way by some methods.  For instance, the rectangle methods say:


The current transformation matrix must be applied to the following
four coordinates, which form the path that must then be closed to get
the specified rectangle: (x, y), (x+w, y), (x+w, y+h), (x, y+h).


This only affects operations where it says so explicitly.  Nothing
that I see says it affects the coordinate space units themselves (if
that even makes sense).


Okay; that makes sense.  Points passed to path definition methods are 
transformed according to the CTM.  I tend to think of transformations as 
affecting the entire coordinate space. But the spec is written with only 
one coordinate space defined, and points are transformed to this space 
as they are added to the path.




It is used in the definition of the lineWidth attribute as well. Chrome,
Firefox and Opera all scaled lineWidth and Phillip Taylor's test suite
expects this behavior as well.


I can't find where it says lineWidth should be scaled . . .


It doesn't. But all implementations do it, as you pretty much be 
expected (otherwise drawings wouldn't scale right). The spec does not 
actually define what it means to stroke a line.  If it did, it would 
probably have to say something like this:


1) Transform all the points in the path using the inverse of the CTM to 
convert them from the canvas coordinate space to the current user 
coordinate space (or some such language).


2) Define rectangles around each straight line segment of the path, 
where each rectangle is lineWidth pixels wide, and connect these 
rectangles with caps, miters and so on.  (this is the part that would be 
a pain to spec, I think)  So now the path has been transformed into a 
set of polygons.


3) Transform those polygons back to the canvas coordinate space using 
the CTM and fill them.


I'm not trying to suggest that the spec needs to be modified to 
explicitly define how to stroke lines.  But without an explanation of 
the process, the handling of lineWidth is difficult to explain. 
Certainly just saying that lineWidth is measured in coordinate space 
units is not sufficient.  To me, it seems to imply that line width 
should never scale, and I don't think that is intended.


David


But then in the definition of shadowOffsetX and Y, the spec reads:


Their values are in coordinate space units. They are not affected by the
current transformation matrix.

The description of isPointInPath() uses similar language:


 when treated as coordinates in the canvas coordinate space unaffected by
the current transformation,

So which is it?  Are coordinate space units affected by scaling or not?


As far as I can tell, no.  When the transformation matrix is used, it
says so explicitly.  The language you point to for shadowOffset and
isPointInPath is just a reminder.  I think.


 Are lineWidths supposed to be scaled? (Implementations do so consistently)


I don't think they're supposed to be from reading the spec, although I
don't know why not.  Maybe I'm missing something, or maybe this needs
to be clarified.


Are shadow offset supposed to be scaled? (Chrome does, Firefox and Opera do
not)


Doesn't it say explicitly that they shouldn't be?


I think a clearer definition of coordinate spaces would be helpful. Maybe
device space for the underlying pixmap, canvas space for the coordinates
defined

[whatwg] Canvas isPointInPath() coordinate space

2010-07-14 Thread David Flanagan

Here's another coordinate-space related question.

I assume that the intended purpose of isPointInPath() is hit testing. 
You get a click event on a canvas element, extract the mouse coordinates 
from the event object, subtract the canvas position from them, and pass 
them to isPointInPath() to figure out what part of your drawing the user 
has clicked on.


My question has to do with this paragraph from the spec:


The intrinsic dimensions of the canvas element equal the size of the coordinate 
space, with the numbers interpreted in CSS pixels. However, the element can be 
sized arbitrarily by a style sheet. During rendering, the image is scaled to 
fit this layout size.


and this one:


The isPointInPath(x, y) method must return true if the point given by the x and 
y coordinates passed to the method, when treated as coordinates in the canvas 
coordinate space unaffected by the current transformation...


So suppose I'm using this canvas tag:

canvas width=100 height=100 style=width:200px; height:200px/canvas

If I understand the first quoted paragraph above correctly, this canvas 
will have 2 on-screen CSS pixels per coordinate space unit.


So here's my question: if I want to do hit-testing as described above, 
do I need to take the mouse coordinates from the event, subtract the 
offset of the canvas, and then divide by 2?  As the spec is written, I 
think I do have to do that division manually.  Is that what is intended? 
 What if the user has zoomed in?  Is it even possible to use 
isPointInPath() correctly in that case?


David


[whatwg] Window events that bubble?

2010-05-17 Thread David Flanagan
Section 6.5.9 History Traversal defines popstate and hashchange events 
 that are fired on the Window object. It specifies that these events 
*must* bubble.  Where should they bubble to?  What does it mean to 
bubble up from a Window?  These events aren't going across frames, are they?


Is the specification that they must bubble a formality because existing 
implementations set the bubbles property of the Event object to true? 
Or does it actually have some impact on event propagation?


Thanks,

David


Re: [whatwg] Adding ECMAScript 5 array extras to HTMLCollection

2010-04-26 Thread David Flanagan

Erik Arvidsson wrote:

for (var i = 0, length = collection.length; i  length; i++)
// instead of:
for (var i = 0; i  collection.length; i++)


Actually, the former is a problem when the nodelist is modified in the
loop; it may result in collection[i] being undefined.


Even when checking the length in every iteration you can run into
problems. If you remove something earlier in the collection you will
*miss* one item unless you fix the loop iterator.

We should not let these edge cases get in the way of making the DOM
collections feel less foreign to JavaScript.

--
erik



Rather that trying to make DOM collections feel like arrays, how about 
just giving them a toArray() method?  This makes it clear that a 
collection is not an array, but clearly defines a way to obtain an 
array.  Clever implementors might even be able to optimize common 
uses-cases using some kind of copy-on-write strategy so that toArray() 
doesn't involve memory allocation and copying.


Of course, trying to teach programmers when they ought to call toArray() 
and when it is not necessary is another matter.  Perhaps calling the 
method snapshot() and focusing on the live vs. static distinction 
instead of the fake array vs. true array distinction would invite less 
misuse.


Or we can just leave the DOM as it is and get used to calling the 
equivalent of Prototype's $A() function.


David


Re: [whatwg] HTMLCollection and HTMLAllCollection suggestion

2010-04-05 Thread David Flanagan

Perry Smith wrote:


On Apr 3, 2010, at 11:58 PM, David Flanagan wrote:


Perry Smith wrote:
HTMLCollection has a namedItem method that returns either null or one 
object. [1]
HTMLAllCollection has a namedItem method that returns either null, 
one object, or a collection of objects. [2]
I'm a Rails freak and one of the things that they do which I love is 
foo returns an item and foos returns a list of items.  The 
unconscious benefit of this I believe is huge.
My suggestion is to have namedItem always return either null or 1 
object.
And have namedItem*s* always return a collection.  We can debate 
whether it is better to return null or an empty collection.  I prefer 
the latter myself.  Then I can always feed it to an iterator.
[1] 
http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#htmlcollection-0 

[2] 
http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#htmlallcollection-0 



Perry,

But no one actually invokes namedItem()--they just use a regular 
property access expression on an HTMLAllCollection.  namedItem() is 
left over from the strange days when the W3C was specifying Java APIs 
for working with XML instead of JavaScript APIs for HTML!


Hmm.  I was wondering.  The pop up boxes on the side did not have any 
icons in them so I thought no one had implemented them.


Can you give me an example of regular property access expression on an 
HTMLAllCollection ?  I can't figure out what you are referring to.


Thanks,
Perry




Perry,

I think the only HTMLAllCollection is the deprecated document.all.
By regular property access expression, I mean something like:

document.all.foo

or

document.all[foo]

instead of:

document.all.namedItem(foo)

David


Re: [whatwg] HTMLCollection and HTMLAllCollection suggestion

2010-04-03 Thread David Flanagan

Perry Smith wrote:
HTMLCollection has a namedItem method that returns either null or one 
object. [1]


HTMLAllCollection has a namedItem method that returns either null, one 
object, or a collection of objects. [2]


I'm a Rails freak and one of the things that they do which I love is foo 
returns an item and foos returns a list of items.  The unconscious 
benefit of this I believe is huge.


My suggestion is to have namedItem always return either null or 1 object.

And have namedItem*s* always return a collection.  We can debate whether 
it is better to return null or an empty collection.  I prefer the latter 
myself.  Then I can always feed it to an iterator.


[1] 
http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#htmlcollection-0
[2] 
http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#htmlallcollection-0


Perry,

But no one actually invokes namedItem()--they just use a regular 
property access expression on an HTMLAllCollection.  namedItem() is left 
over from the strange days when the W3C was specifying Java APIs for 
working with XML instead of JavaScript APIs for HTML!


David Flanagan


Re: [whatwg] HTML Cookie API

2010-02-24 Thread David Flanagan

Jeremy Orlow wrote:



Also note that the spec currently has the notion of a storage mutex 
which should be taken whenever a script tries to access a cookie (or 
local storage) and is held until the script finishes.  The network stack 
is also supposed to take this lock whenever getting or setting a cookie. 
 No one has implemented the storage mutex or stated any intention of 
doing so because this is basically impossible today.  But, if there were 
an asynchronous API that most people were using, it actually could be 
possible that we'd want to implement such a mutex since cookies would 
then obey run to completion semantics without having serious lock 
contention.




Well if no one is going to implement the storage mutex, then I probably 
need to retract my last message


But yeah.  Definitely any API that touches information spanning tabs 
(and probably even APIs spanning origins within those tabs) really 
should be designed in an async manor from now on.  Otherwise we're just 
digging the whole deeper in terms of forcing ourselves into a single 
threaded world.


J


I worry that this comes down to web developers who want simple APIs vs 
browser implementors who say we can't have them (at least not if we also 
want speed.)


Concurrency issues are not my strong suit, but shouldn't it be possible 
to have safe, synchronous read-only access to cookies (caching volatile 
values like cookies within each thread and then clearing that cache when 
the thread returns to the event loop).  Can't the requirement for a 
mutex or an asynchronous API be limited to setCookie()?


David


[whatwg] global object in onmessage event? Really?

2010-02-13 Thread David Flanagan

Section 9.2.3, step 5 reads:


Create an event that uses the MessageEvent interface, with the event name 
message, which does not bubble, is not cancelable, and has no default action. 
The data attribute must be set to the value of message clone, the origin 
attribute must be set to the Unicode serialization of the origin of the script 
that invoked the method, and the source attribute must be set to the script's 
global object.


Is the source property really supposed to be the global object and not 
the WindowProxy object?  I thought that the point of WindowProxy was 
that you were *never* supposed to be able to obtain a reference to the 
real global object.


David Flanagan


[whatwg] script async and defer attributes questions and confusion

2010-01-20 Thread David Flanagan
I'm trying to understand the async and defer attributes of the script 
tag.  Unfortunately, since script execution is so intimately tied up 
with HTML parsing, section 4.3.1 is particularly hard to make sense of.
I've got 3 questions, and 3 suggested clarifications to the spec. 
Thanks to anyone who can explain these!


First, my questions.  Are the following three statements correct?  (I'm 
only concerned with script tags that actually appear in a document, 
not those inserted or emitted (via document.write()) by another script.):


1) Scripts without async or defer attributes are executed in the order 
in which they appear in the document.  They are executed synchronously, 
which means that the parser must stop parsing the document while they run.


2) Scripts with the defer attribute, but without the async attribute are 
executed in the order in which they appear in the document, but their 
execution is deferred until the document has finished parsing. All these 
scripts will execute before DOMContentLoaded and the load event are 
fired.  A deferred script can assume that the entire DOM tree has been 
constructed and is ready for manipulation--these scripts do not 
generally need to register an onload event handler. A call to 
document.write() within a deferred script will blow away the current 
document and begin a new one.


3) Scripts with the async attribute are executed as their script content 
becomes available over the network, with no guarantee that they will be 
executed in the order in which they appear in the document.  The only 
guarantee is that these scripts will run before the DOMContentLoaded or 
load events are fired. Document parsing may or may not have completed 
when an async script is run, and a call to document.write() from an 
async script will have unpredictable behavior. Though the order of 
execution of async scripts is not predictable, the scripts will always 
appear to run in some serial order without concurrent execution.


Next, I suggest that the following things in the spec be clarified:

1) After describing the async and defer attributes, the spec promises:
The exact processing details for these attributes are described below.
I take this to mean below, somewhere in section 4.3.  In fact, 
however, the exact processing details are scattered throughout the spec, 
and understanding the attributes requires understanding section 9, I 
think. It would be nice to note this.


2) The last sentence of this paragraph:


The second is a flag indicating whether the element was parser-inserted. 
Initially, script elements must have this flag unset. It is set by the HTML parser and is 
used to handle document.write() calls.


made me think that the parser-inserted flag would only be set to true 
for scripts that were emitted through document.write() calls.  That is, 
I thought that the parser-inserted flag would be set only in unusual 
cases rather than in the most common case.  This section should explain 
the meaning of the parser-inserted flag. Instead it describes one of the 
 purposes of the flag, but that purpose is different than the purpose 
for which it is used in this section.


3) The algorithm for running a script adds scripts to the list of 
scripts that will execute as soon as possible.  And 9.2.6 spins the 
event loop until this list is empty.  But I don't see anything in the 
spec that removes items from this list.  That seems like an error in the 
spec, not just a confusing bit.  Furthermore, the fact that this 
mechanism is specified as a list rather than as a set implies some 
kind of sequential execution of the scripts.  But I don't think any 
sequence is meant here.


David Flanagan


Re: [whatwg] Dashed strokes on canvas

2007-05-16 Thread David Flanagan

Ian Hickson wrote:



...which would have to be defined, including error handling logic, 
including how to handle corners, including how to do dot distribution to 
have nice symmetry, etc, etc, etc. It's actually quite complex.




I believe that most of these issues can and should be left to the 
implementation.  If the implementation is allowed to choose whether or 
not to draw shadows, then I think it is fine to allow the implementation 
to choose the minor details of dash rendering.


Anything that isn't specified to the virtual pixel is an error in the 
spec. (The canvas section is especially prone to these given my lack of a 
graphics background.) In theory, the canvas section is supposed to specify 
everything down to the level just before anti-aliasing.


I just want to point out here that optional support for shadows 
contradicts this.


And I think I'm ready to drop this now.  I've posted an entry on my 
(low-readership) blog about the (surprising, I think) fact that there is 
no plan to add support for dashed lines.  Maybe that will generate a few 
more requests for the feature.  Or maybe you're right and no one except 
me really cares about this :-)


Thanks for all your time on this matter,

David Flanagan


Re: [whatwg] Dashed strokes on canvas

2007-05-09 Thread David Flanagan

Ian Hickson wrote:

On Wed, 17 May 2006, David Flanagan wrote:
What surprises me about the omission of dashed lines is that every 
graphics API I'm familiar with (Xlib, PostScript, Java 2D) supports 
dashed lines. Unless there is some important platform out there that 
does not support them in the underlying graphics library, it seems to me 
that it would have been trivial to add dashed lines to the API.


And, I can't think of any simple or efficient way to simulate dashed 
lines without having them in the API.  And while dashed lines may not be 
a high-use feature, I wouldn't say they're infrequently used.  For 
example: when drawing a line chart with multiple lines which is intended 
to be printed on a black-and-white laser printer.


There are many styles that aren't supported -- dashes aren't an exception. 
For example, there's no support for having defined markers repeated around 
the stroke. Similarly, we don't havenative  support for rounded corners, 
or for many shapes (e.g. circles).


Dashes would be trivial to add--it is just a single additional line 
style property. I assert that every possible underlying graphics library 
already supports dashes, and I haven't heard a counter example from you. 
 You support the miterLimit property--something that is hardly ever 
used, but won't support dashed lines, which is a relatively common thing 
to use.  It just seems bizarre.


I believe that dashed lines have universal support in native graphics 
libraries.  Markers around the stroke do not.  Rounded corners are more 
common, but are not universal.  Lack of support for ellipses is a 
shortcoming of the API, and I hope you'll address it, but it does not 
excuse the omission of dashed lines.


You can do dashed lines using paths. 


This is true only in theory. Way too much computation is necessary to 
transform a path into a dashed path.  How do dashes go around corners, 
for example?  Give that *every single platform supports dashes 
natively*, do you really want to argue that people who want dashed lines 
 should compute them in JavaScript?


Writing a method to draw a circle using only the arc and arcTo methods 
is pretty trivial and can be done efficiently.  Defining your own dashed 
path is not.  We really cannot do dashed lines in a Canvas without API 
support.


Without more demand for this feature,

it's not clear that it's worth us putting it into the language.


It is just one more method on CanvasRenderingContext2D.  And the 
implementation would almost certainly be trivial.  You'll see the demand 
for dashed lines when Canvas becomes standardized without it, and people 
start wondering how to do dashes.  It truly seems strange to me that 
this feature has been omitted.




On Sat, 20 May 2006, Peter Hall wrote:
Flash is an example of a platform that does not support dashed lines in 
its drawing API. Dashed lines created in the Flash Authoring tool are 
actually exported into a swf as a series of short curves.


However, this is a huge limitation, when it comes to drawing lines 
dynamically, so I don't think one platform's omission of the feature is 
a good argument anyway.


There apparently isn't much demand for it for Flash either.



I think you're completely misunderstanding Peter's point.  Flash authors 
can use dashed lines whenever they want to.  Because their authoring 
environment does the expensive compilation required to transform their 
paths into dashed paths.  Then their *compiled* SWF files are executed 
on the Flash VM, which supports only a highly restricted set of graphics 
primitives.  Flash is a VM, not an API, and trying to draw dynamic 
graphics (as opposed to pre-compiled graphics) using Flash is expensive 
and tedious.  It is completely inappropriate to compare the Canvas API 
to the Flash API.



It is a reasonable and worthwhile goal to natively support emulation of 
all style attributes that are specifiable in CSS.


Why? CSS' styles are the result of a pretty arbitrary set of decisions in 
committee meetings. (I know, I've been on the CSSWG for ~7 years.)


Okay, if you don't like CSS, how about this argument: it would be 
foolish and obstinate to purposely obstruct compatibility between Canvas 
and SVG-Tiny (see the stroke-dasharray property in 
http://www.w3.org/TR/SVGMobile12/painting.html#StrokeProperties), 
especially over something that is so trivial to add to the specification 
and so trivial to implement.


I really think you're making a mistake here.

  David Flanagan



On Sat, 20 May 2006, Peter Hall wrote:
Correct, it doesn't have stroke styles other than gradients, patterns, 
and solid colours. It was an intentional omission since it was not 
considered a high-use feature. (Similarly, text is not available in 
Canvas; you have to overlay HTML if you want to mix text with the 
graphics.)
May I assume that the inclusion of gradients is solely because they are 
implemented for fills aleady?


Pretty much, I think.





Re: [whatwg] Dashed strokes on canvas

2007-05-09 Thread David Flanagan

Philip,

You have a reasonable point. I still think that an implementation would 
be trivial, but you're right that there is more complexity for the 
specification than simply defining one more method API.  On the other 
hand, I think it is legitimate to take the SVG-Tiny route and leave 
specific rendering details to the implementation.  After all, you're not 
specifying line and curve drawing algorithms down to the pixel, are you?


 There are other missing features that people are actively implementing
 workarounds for, like drawing text, which is a good indicator of
 demand. Are there examples where people are currently fighting against
 the lack of dashed lines?

The problem of layering text on top of a canvas is a solvable one, so 
people are solving it.  I don't think that dashed lines can really be 
worked around. If there is no native support, they're not worth doing. 
To me the killer use-case for dashed lines is this: displaying multiple 
data series in a line chart that will be printed in black-and-white. 
People have been using dashed lines for that since Rene Descartes 
invented the coordinate system!


I come to this from an admittedly theoretical perspective, but the need 
for dashed lines just seems self-evident to me. I assume that the 
omission of dashed lines was simply an oversight in the original Apple 
implementation, and I'm really surprised by the resistance to adding 
this from whatwg.


David

Philip Taylor wrote:

On 09/05/07, David Flanagan [EMAIL PROTECTED] wrote:

Ian Hickson wrote:
 On Wed, 17 May 2006, David Flanagan wrote:
 What surprises me about the omission of dashed lines is that every
 graphics API I'm familiar with (Xlib, PostScript, Java 2D) supports
 dashed lines. Unless there is some important platform out there that
 does not support them in the underlying graphics library, it seems 
to me

 that it would have been trivial to add dashed lines to the API.

 And, I can't think of any simple or efficient way to simulate dashed
 lines without having them in the API.  And while dashed lines may 
not be

 a high-use feature, I wouldn't say they're infrequently used.  For
 example: when drawing a line chart with multiple lines which is 
intended

 to be printed on a black-and-white laser printer.

 There are many styles that aren't supported -- dashes aren't an 
exception.
 For example, there's no support for having defined markers repeated 
around
 the stroke. Similarly, we don't havenative  support for rounded 
corners,

 or for many shapes (e.g. circles).

Dashes would be trivial to add--it is just a single additional line
style property.


I don't think it's entirely trivial to add, to the detail that's
necessary in a specification. The common graphics APIs (at least
Cairo, Quartz and java.awt.Graphics, and any SVG implementation) all
have dashes specified by passing an array of dash lengths (alternating
on/off), so that should be alright as long as you define what units
it's measured in and what happens when you specify an odd number of
values and how errors are handled and what happens if you update the
array later. But after that, what does it do when stroking multiple
subpaths, in terms of offsetting the dashes? When you use strokeRect,
where is offset 0? Does moveTo reset the offset? How does it interact
with lineCap/lineJoin? All the potential issues need test cases too,
and the implementations need to make sure they handle any edge cases
that the underlying graphics library does differently. (SVG Tiny 1.2
appears to skip some of the problems by leaving things undefined and
allowing whatever behaviour the graphics library has.)


 You can do dashed lines using paths.

This is true only in theory. Way too much computation is necessary to
transform a path into a dashed path.


That's particularly a problem for Bezier curves - decomposing them
into fixed-length segments in JS wouldn't be any fun. At least it's
not difficult for straight lines (and someone could write a pure-JS
canvas extension library to provide that kind of feature), but I have
no idea how often people want dashed curves compared to dashed lines.


 Without more demand for this feature,
 it's not clear that it's worth us putting it into the language.

It is just one more method on CanvasRenderingContext2D.  And the
implementation would almost certainly be trivial.  You'll see the demand
for dashed lines when Canvas becomes standardized without it, and people
start wondering how to do dashes.  It truly seems strange to me that
this feature has been omitted.


It's one method plus detailed specification and tests and multiple
implementations and bugs and documentation - none of those are
especially difficult, but all the work adds up, so there has to be
enough justification in order to add a feature.

There are other missing features that people are actively implementing
workarounds for, like drawing text, which is a good indicator of
demand. Are there examples where people are currently

Re: [whatwg] Comments on canvas tag

2006-05-17 Thread David Flanagan
What surprises me about the omission of dashed lines is that every 
graphics API I'm familiar with (Xlib, PostScript, Java 2D) supports 
dashed lines. Unless there is some important platform out there that 
does not support them in the underlying graphics library, it seems to me 
that it would have been trivial to add dashed lines to the API.


And, I can't think of any simple or efficient way to simulate dashed 
lines without having them in the API.  And while dashed lines may not be 
a high-use feature, I wouldn't say they're infrequently used.  For 
example: when drawing a line chart with multiple lines which is intended 
to be printed on a black-and-white laser printer.


David Flanagan

Ian Hickson wrote:

On Fri, 17 Jun 2005, David Flanagan wrote:

Does the canvas tag really have no way to draw dashed and dotted 
lines?  It seems to have everything else.  Is this an oversight in the 
spec?



Correct, it doesn't have stroke styles other than gradients, patterns, and 
solid colours. It was an intentional omission since it was not considered 
a high-use feature. (Similarly, text is not available in Canvas; you have 
to overlay HTML if you want to mix text with the graphics.)






[whatwg] XMLHttpRequest

2005-09-26 Thread David Flanagan

Ian --

Thanks for your comment on my blog, drawing my attention to the WhatWG 
spec for XMLHttpRequest.  I like the fact that you've explicitly stated 
that getResponseHeader/s() and responseText return whatever is available 
so far in readyState 3.


On a related note, your spec is unambiguous that onreadystatechange() is 
never to be called unless readyState actually changes.


It may be myth, but I was under the impression that existing 
implementations might call onreadystatechange repeatedly for state 3, to 
indicate download progress...  This behavior (if it is actually 
implemented) is useful to display a loading... animation and give the 
end user feedback about the status of a long download.


Did you consider this and purposely reject it?  I know that the common 
XMLHttpRequest use case is for small downloads, so this would not be all 
that commonly used...  But if you decide to allow multiple calls to the 
event handler for state 3, I suppose it would be useful to add a 
bytesReceived property to the object...


David Flanagan


[whatwg] XMLHttpRequest readyState==3

2005-09-26 Thread David Flanagan

Ian,

This is a followup to my previous message.

If onreadystatechange is guaranteed to be called only once for 
readyState 3, then I don't see much point in making responseText 
available in this state.  It seems like it will encourage the use of 
window.setTimeout() to poll the responseText property looking for new 
stuff...


If you think that programmers might be interested looking at partial 
responses, then maybe you should call onreadystatechange each time a new 
chunk of the response becomes available.


Furthermore, the ambiguity of the headers is a little problematic.  If 
you query a header and get null in response, you don't know if it is 
because that header was not in the first packet and is yet to come or if 
 it simply does not exist.  I suppose you could check the length of 
responseText to determine whether all headers have been downloaded yet 
or not.  But I'd say that there ought to be some more explicit way to 
determine whether all headers have been received.  If responseText is 
being parsed out and made available on readyState 3, then it seems to me 
that you ought to just go ahead and say that state 3 means that all 
headers have been received and that the response body is being loaded...


Here's something else to think about: if the server's entire response 
arrives in a single packet, can the UA skip state 3 and jump directly to 
state 4?  Or is there a guarantee that onreadystatechange will be 
invoked for each state?


David


[whatwg] Comments on canvas tag

2005-06-21 Thread David Flanagan

Hi,

Does the canvas tag really have no way to draw dashed and dotted 
lines?  It seems to have everything else.  Is this an oversight in the spec?


Also. in 8.1.1.4 of the current-work spec, you've got the rgba() format 
specified with the space comming before the comma.  (Third paragraph). 
I imagine that this is a mistake, right?


The canvas tag looks really sweet.  Thanks!

David