Re: [whatwg] resize events on elements
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()
. 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()
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()
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?
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
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.
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.
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
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
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
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
§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?
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?
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?
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
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?
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?
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
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
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
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
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
§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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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)
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
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
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
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
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
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
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
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
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
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
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
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
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?
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
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
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
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
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?
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
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
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
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
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
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
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
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
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