Re: [admin] Should WebApps' HTML Templates spec be published as a WG Note?

2014-03-12 Thread Rafael Weinstein
SGTM


On Tue, Mar 11, 2014 at 9:38 AM, Yves Lafon yla...@w3.org wrote:

 On Fri, 7 Mar 2014, Arthur Barstow wrote:

  On 2/27/14 12:10 PM, ext Arthur Barstow wrote:

 On 2/27/14 11:41 AM, ext Rafael Weinstein wrote:

 What do you recommend?

 It seems a little heavy-handed to kill it or gut it. What about putting
 a big-red warning at the top that it has been merged to HTML and no longer
 has normative weight.


 I don't have a strong preference now and would like to hear from others.
 The above do have different +/-.

 I think the principle of least surprise (`follow your nose`) indicates
 navigating to the ED would redirect to the HTML spec. It seems like the
 worst case scenario is for the contents of the ED to be inconsistent with
 HTML.


 Rafael, All - having received no additional feedback and only voices of
 support for publishing a WG Note, the main questions seem to be: 1) whether
 the Note should be gutted (f.ex. see [1]) or not; 2) should the ED be
 gutted too.

 Although I agree gutting the Note would be a bit heavy-handed as you
 say, it does eliminate the possibility of the contents being different than
 HTMLWG's version. As such, I prefer gutting both the Note and the ED and
 adding a prominent warning plus a link to HTML. For example, borrowing from
 [1], adding something like to the Status of This Document section:

 [[
 strongWork on this document has been discontinued and it should not be
 referenced or used as a basis for implementation. The features previously
 specified in this document are now specified in a href=
 http://www.w3.org/TR/html5/scripting-1.html#the-template-element
 HTML5/a./strong
 ]]

 WDYT?


 SGTM, not gutting it has a higher risk of people looking at the wrong doc.

 --
 Baroula que barouleras, au tiéu toujou t'entourneras.

 ~~Yves




Re: [admin] Should WebApps' HTML Templates spec be published as a WG Note?

2014-03-12 Thread Rafael Weinstein
On Wed, Mar 12, 2014 at 8:48 AM, Arthur Barstow art.bars...@nokia.comwrote:

 On 3/12/14 10:27 AM, ext Rafael Weinstein wrote:

 SGTM


 On Tue, Mar 11, 2014 at 9:38 AM, Yves Lafon yla...@w3.org mailto:
 yla...@w3.org wrote:

 On Fri, 7 Mar 2014, Arthur Barstow wrote:

 On 2/27/14 12:10 PM, ext Arthur Barstow wrote:

 [[
 strongWork on this document has been discontinued and it
 should not be referenced or used as a basis for
 implementation. The features previously specified in this
 document are now specified in a
 href=http://www.w3.org/TR/html5/scripting-1.html#the-
 template-elementHTML5/a./strong
 ]]

 WDYT?


 SGTM, not gutting it has a higher risk of people looking at the
 wrong doc.



 OK, then unless I hear otherwise, at the end of this week I'll create a
 draft WG Note that is gutted and includes the info above (and put the draft
 Note in https://dvcs.w3.org/hg/webcomponents/file/default/
 publish/template/). I'll target a publication of March 18.

 Rafael - I will plan to update the ED too so please let me know if you
 prefer to do that.


Go for it. Thanks for getting this cleaned up.



 -Thanks, ArtB





Re: [admin] Should WebApps' HTML Templates spec be published as a WG Note?

2014-02-27 Thread Rafael Weinstein
What do you recommend?

It seems a little heavy-handed to kill it or gut it. What about putting a
big-red warning at the top that it has been merged to HTML and no longer
has normative weight.


On Thu, Feb 27, 2014 at 7:27 AM, Arthur Barstow art.bars...@nokia.comwrote:

 On 2/26/14 9:43 AM, ext Arthur Barstow wrote:

 Hi Robin, Dimitri, All,

 Since HTML Templates is now part of HTML5, to help avoid confusion, I
 think WebApps' last TR of the spec ([html-templates]) should be replaced
 with a WG Note that clearly indicates WebApps' work on the standalone spec
 has stopped and the feature is now part of HTML5. (The Note could also be
 void of any technical substance as DAP recently did f.ex. [contacts-api]).


 Dimitri, Rafael, Tony - there is also a question about the contents of the
 HTML Templates [ED]. What are you planning to do with it (delete it; remove
 the guts and link to HTML(5); something else)?

 -Art

 [ED] http://dvcs.w3.org/hg/webcomponents/raw-file/tip/
 spec/templates/index.html




 WDYT? Any objections?

 (If we agree to publish a WG Note, I'll create it).

 -Thanks, AB

 [html-templates] http://www.w3.org/TR/html-templates/
 [contacts-api] http://www.w3.org/TR/contacts-api/







Re: [admin] Should WebApps' HTML Templates spec be published as a WG Note?

2014-02-26 Thread Rafael Weinstein
No objections. It may be useful to mention in the note that the Template
spec was merged to HTML (as opposed to simply becoming a concern of HTML,
which might raise the question did HTML do something different than what
this spec used to say?).


On Wed, Feb 26, 2014 at 12:25 PM, Ryosuke Niwa rn...@apple.com wrote:

 Sounds great to me.

 On Feb 26, 2014, at 6:43 AM, Arthur Barstow art.bars...@nokia.com wrote:

  Hi Robin, Dimitri, All,
 
  Since HTML Templates is now part of HTML5, to help avoid confusion, I
 think WebApps' last TR of the spec ([html-templates]) should be replaced
 with a WG Note that clearly indicates WebApps' work on the standalone spec
 has stopped and the feature is now part of HTML5. (The Note could also be
 void of any technical substance as DAP recently did f.ex. [contacts-api]).
 
  WDYT? Any objections?
 
  (If we agree to publish a WG Note, I'll create it).
 
  -Thanks, AB
 
  [html-templates] http://www.w3.org/TR/html-templates/
  [contacts-api] http://www.w3.org/TR/contacts-api/
 
 





Re: Extending Mutation Observers to address use cases of

2014-02-12 Thread Rafael Weinstein
I pushed the Web Components folks about exactly this issue (why aren't
these callbacks just MutationObservers?) early last year. They convinced me
(and I remain convinced) that these signals should be Custom Element
callbacks and not Mutation Observer records

Here's the logic that convinced me: Custom Element are a *strongly coupled
concern*, while Mutation Observers *allow for* multiple decoupled concerns
to peacefully co-exist.

In a certain sense, you can extend the argument that CE callbacks should be
MO records, and you arrive at the conclusion that you don't need Custom
Elements at all -- that everything can be implemented with Mutation
Observers. But the point of Custom Elements is two fold:

1) To allow implementation of Elements by user-space code in roughly the
same model as privileged code.
2) To explain the platform.

Put another way: the *implementation* of an element simply needs to be
privileged in some respects. For custom elements, this means

a) There can only be one. I.e., we don't allow multiple registration of the
same element: Primary behavior is the domain of custom elements, secondary
behavior is the domain of Mutation Observers
b) Callbacks need to fire ASAP. It's important that the implementation of
an element get a chance to respond to events before other concerns so that
it can create a synchronously consistent abstraction

To my mind, Custom Elements callbacks really *should* be fully sync (yes,
including firing createdCallback during parse), but various technical and
security constraints make that impossible.

In short, Custom Elements and Mutation Observers are servicing very
different needs. Custom Elements are privileged, but limited and singular
(I can only react to changes in myself and I'm the only responding party),
while Mutation Observers are unprivileged, pervasive and multiple (I get to
respond to anything in the document, and there are likely other parties
doing work in the same place I am).

Therefore, it is neither a good idea to make Custom Elements more async,
nor a good idea to make Mutation Observers more sync.

---

One final note. UNRELATED to custom elements' implementation.

I think there's an argument to be made that Mutation Observers *should* be
extended to allow for observation of trees which include DOM reachable
through shadowRoots. The motivation for this would be to allow existing
de-coupled concerns to operate faithfully in the presence of custom
elements implemented with shadowDOM. The obvious concern here is that
de-coupled code may interfere with the implementation of elements, but
that's no more true with custom elements than it is today, and shadowRoot
is imperatively public, it's consistent to allow MutationObservers to
continue to fully observe a document.

However, I don't think there's any rush to do this. Just something to think
about for a post-shadowDOM world.


On Wed, Feb 12, 2014 at 4:49 AM, Olli Pettay olli.pet...@helsinki.fiwrote:

 On 02/12/2014 04:27 AM, Ryosuke Niwa wrote:


  On Feb 11, 2014, at 6:06 PM, Bjoern Hoehrmann derhoe...@gmx.net wrote:

 * Olli Pettay wrote:

 We could add some scheduling thing to mutation observers. By default
 we'd use microtask, since that tends to be good for various performance
 reasons, but normal tasks or nanotasks could be possible too.


 Right, we need some sort of a switch.  I'm not certain if we want to add
 it as a per-observation option or a global switch when we create an
 observer. My guy feeling is that we want the latter.  It would be weird
 for some mutation records to be delivered earlier than others to the same
 observer.


 Yeah, I was thinking per observer.
 Something like

 var m = new MutationObserver(callback, { interval: task} );
 m.observe(document, { childList: true, subtree: true});


 Some devtools devs have asked for adding 'interval: nanotask' thing
 I was thinking to add such thing only for addons and such in Gecko,
 because it brings
 back some of the performance problems Mutation Events have.
 But if web components stuff would be less special with such option,
 perhaps it should be enabled for all.




 -Olli



  I'd like to know exact semantics requirements before start jumping into
 details though.

  This sounds like adding a switch that would dynamically invalidate
 assumptions mutation observers might make, which sounds like a bad idea.
 Could
 you elaborate?


 I don't really follow what the problem is. Could you elaborate on what
 you see as a problem?

 - R. Niwa






Re: [webcomponents] Auto-creating shadow DOM for custom elements

2013-12-07 Thread Rafael Weinstein
On Sat, Dec 7, 2013 at 3:01 PM, Brian Di Palma off...@gmail.com wrote:

 From your email it seems you can still achieve everything you can with
 custom elements when not using
 them, it would just involve more code/boilerplate.

 So custom elements without shadow dom or templates are syntactic sugar


No. Custom elements (even without templates  shadowdom) creates a
mechanism where the implementation of elements can *reliably* be bound to
all instances of that element.

Angular depends on having access to all html so it can compile it (Domenics
example of innerHTML shows the counter example). DOM inside the shadow will
be undiscoverable by Angular -- and even Mutation Observers (to Ryosuke's
point earlier).

A central goal here is *composability* of elements. E.g:
-I can author components without needing to require that consumers of them
use a particular framework
-I can author a page which is comprised of the best-of-breed components
(full stop). Not best-of-breed components designed to work within X
framework.


 they don't enable
 functionality that is impossible currently?

 They make it much nicer and I really like it but I can manage without
 it and not be too stressed.

 Much like classes in ES6, they're great sugar but we've been able to
 do classes in JS since forever.

 I'm sure Brick is great and it looks lovely but no one in my work
 place is excited about it.
 Web Components in it's entirety though is a different matter and we
 are looking forward to them.

 Splitting it up into separate specs is good, but it's clear they
 combine with each other.
 Making it easy and painless to combine them seems like common sense.

 On Sat, Dec 7, 2013 at 10:37 PM, Domenic Denicola
 dome...@domenicdenicola.com wrote:
  From: Brian Di Palma [mailto:off...@gmail.com]
 
  Are they appreciatively more powerful then just building Angular
 directives though?
 
  Do they enable any functionality that you could not access without the
 custom elements spec?
 
  Yes. There are at least two major benefits that I can see:
 
  1) They allow you to create new HTMLElement-derived interfaces which are
 associated with the custom elements, so that you can do e.g.
 `document.querySelector(x-flipbox).toggle()` or
 `document.querySelector(x-flipbox).flipped` and so on.
 
  2) They alert the parser of this new element, so that if you do
 `document.body.innerHTML =
 x-flipboxdivFront/divdivBack/div/x-flipbox`, this will be
 appropriately parsed so as to create a new flipbox with the associated
 behavior and interface.
 
  This effectively allows you to use the web's native widget abstraction,
 e.g. elements, instead of inventing your own. With something like jQuery UI
 or Angular, you need to access properties and methods through arcane
 invocations, e.g.
 
  $(document.querySelector(.my-slider)).slider(option, disabled,
 false);
 
  instead of
 
  document.querySelector(.my-slider).disabled = false;
 
  And if you add new elements via innerHTML, you'll have to do
 
  $(elementThatHadItsInnerHTMLChanged).find(.make-me-a-slider).slider();
 
  to add the slider behavior, since there is no parser hook.
 
  (As for the Angular comparison, Angular tries to push you toward
 manipulating controllers and $scope objects, and never touching the DOM or
 DOM-esque widgets directly, so it's hard to really make such a comparison.
 Angular, more so than Polymer, seems to me like a good unifying cowpath to
 pave in the future.)




Re: [webcomponents] Auto-creating shadow DOM for custom elements

2013-12-07 Thread Rafael Weinstein
On Sat, Dec 7, 2013 at 6:56 PM, Ryosuke Niwa rn...@apple.com wrote:


  On Dec 7, 2013, at 3:53 PM, Rafael Weinstein rafa...@google.com wrote:
 
  The issue is that being an element and having shadow DOM -- or any
 display DOM, for that matter -- are orthogonal concerns.
 
  There are lots of c++ HTML elements that have no display DOM. Polymer
 already has an even larger number.

 While that's true in browser implementations, there is very little authors
 can do with a plain element without any shadow content it since JavaScript
 can't implement it's own style model (i.e. creating a custom frame object
 in Gecko / render object in WebKit/Blink) or paint code in JavaScript.

 If the only customization author has to do is adding some CSS, then we
 don't need custom element hook at all.


I'm was thinking about elements whose purpose isn't presentational. For
example, link or script in html, or polymer-ajax in polymer.


 It's true that mutation observers wouldn't run immediately after innerHTML
 if authors wanted to add some JS properties but we could fix that issue in
 some other way; e.g. by delivering mutation records every time we run a
 parser.

 - R. Niwa



Re: [webcomponents] HTML Imports

2013-12-04 Thread Rafael Weinstein
On Wed, Dec 4, 2013 at 10:37 AM, Dimitri Glazkov dglaz...@chromium.orgwrote:

 On Wed, Dec 4, 2013 at 9:56 AM, Dimitri Glazkov dglaz...@chromium.orgwrote:

 On Wed, Dec 4, 2013 at 4:32 AM, Anne van Kesteren ann...@annevk.nlwrote:

 On Wed, Dec 4, 2013 at 9:21 AM, Brian Di Palma off...@gmail.com wrote:
  I would say though that I get the feeling that Web Components seems a
  specification that seems really pushed/rushed and I worry that might
  lead to some poor design decisions whose side effects will be felt by
  developers in the future.

 I very much share this sentiment.


 It's a very reasonable and normal worry to have. I lose sleep over this
 worry all the time. The trick that helps me is balancing it out with the
 sadness of the geological timescale that it takes for Web platform to
 advance.


 Just to help visualize the geological timescale, the work on Web
 Components began in late 2010 (
 http://wiki.whatwg.org/index.php?title=Component_Model_Use_Casesoldid=5631),
 and was chartered in this WG over 2 years ago (
 http://www.w3.org/2008/webapps/wiki/CharterChanges#Additions_Agreed).

 To clarify my previous email: Web Components is an extremely hard problem
 with lots of constraints, and a concern would be that we miss some bits is
 totally fair. Qualifying this work as pushed/rushed probably ain't.


I'd like to make an aside about having respect for one-another's work.

Dimitri, Alex, Dominic, Scott, Elliot and many others have put massive time
into this problem over the course of many years now, and my view is that
the design has evolved and accommodated a dizzying number of challenges and
constraints.

What this is attempting is big  scary is fair. I haven't had time to
digest the design is fair. I have the following specific issues is fair.
This work is rushed is always understood as an indictment.

I've seen too many talented people vote with their feet and decide life
will be less frustrating working on a closed system. Let's remember we're
all on the same team.

AFAICT, evolving the web is fundamentally an exercise in not letting
perfect be the enemy of good. I have no doubt Web Components is imperfect,
but from what I can tell, it is *extremely* good.

Also, go hug your mother.




 :DG



Re: [webcomponents] HTML Imports

2013-10-07 Thread Rafael Weinstein
On Mon, Oct 7, 2013 at 3:24 AM, James Graham ja...@hoppipolla.co.uk wrote:

 On 06/10/13 17:25, Dimitri Glazkov wrote:

  And, if the script is executed against the global/window object of
 the main document, can and should you be able to access the imported
 document?


 You can and you should. HTML Imports are effectively #include for the Web.


 Yes, that sounds like a good description of the problem :) It is rather
 noticable that no one making programming languages today replicates the
 #include mechanism, and I think html-imports has some of the same design
 flaws that makes #include unpopular.


 I think authors will find it very hard to write code in an environment
 where simple functions like document.getElementById don't actually work on
 the document containing the script, but on some other document that

they can't see. It also seems that the design requires you to be super
 careful about having side effects; if the author happens to have a
 non-idempotent action in a document that is imported, then things will
 break in the relatively

uncommon case where a single document is imported more than once.


We have an orthogonal mechanism for preventing side-effects: The HTML
Template Element. Imports do not prevent side-effects implicitly. This is
Good. Authors have control over the semantics they need. Want to include
some DOM -- use imports, need some fragment of that to not have side
effects -- put it in a template.



 Overall it feels like html imports has been designed as an over general
 mechanism to address certain narrow use cases and, in so doing, has handed
 authors a footgun. Whilst I don't doubt it is usable by the highly
 competent people who are working at the bleeding edge on polyfilling
 components, the rest of the population can't be expected to understand the
 implemetation details that seem to have led the design in this direction. I
 think it would be useful to go right back to use cases here and work out if
 we can't design something better.




Re: should mutation observers be able to observe work done by the html parser

2013-09-16 Thread Rafael Weinstein
Yup. Not sure where this is in W3C DOM, but 12.2.5.1 Creating and inserting
nodes (http://www.whatwg.org/specs/web-apps/current-work/)

...

DOM mutation events must not fire for changes caused by the UA parsing the
document. This includes the parsing of any content inserted using
document.write() and document.writeln() calls. [DOMEVENTS]

However, mutation observers do fire, as required by the DOM specification.

...


On Mon, Sep 16, 2013 at 8:13 AM, Brian Kardell bkard...@gmail.com wrote:

 was therw ever agreement on this old topic?
 http://lists.w3.org/Archives/Public/public-webapps/2012JulSep/0618.htmlwhether
  by de facto implementation or spec agreements?  I am not seeing
 anything in the draft but maybe i am missing it...



Re: [webcomponents]: Platonic form of custom elements declarative syntax

2013-04-10 Thread Rafael Weinstein
FWIW, I think it's a design mistake to make element registration a
concern of template.

I'd be more persuaded by the developer ergonomics argument if this was
a cost that was incurred with the usage of custom elements, but it's
not. It's only incurred with the element definition.

Separately, I may have missed it, but it seems to me that allowing
custom elements to stamp out light DOM is a new semantic, that isn't
obviously solving a problem which is either identified, or related to
web components. Did I miss earlier discussion about this?

On Wed, Apr 10, 2013 at 12:40 PM, Scott Miles sjmi...@google.com wrote:
 No, strictly ergonomic. Less nesting and less characters (less nesting is
 more important IMO).

 I would also argue that there is less cognitive load on the author then the
 more explicit factoring, but I believe this is subjective.

 Scott


 On Wed, Apr 10, 2013 at 12:36 PM, Rafael Weinstein rafa...@google.com
 wrote:

 On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.com
 wrote:
  Dear Webappsonites,
 
  There's been a ton of thinking on what the custom elements declarative
  syntax must look like. Here, I present something has near-ideal
  developer ergonomics at the expense of terrible sins in other areas.
  Consider it to be beacon, rather than a concrete proposal.
 
  First, let's cleanse your palate. Forget about the element element
  and what goes inside of it. Eat some parsley.
 
  == Templates Bound to Tags ==
 
  Instead, suppose you only have a template:
 
  template
  divYay!/div
  /template
 
  Templates are good for stamping things out, right? So let's invent a
  way to _bind_ a template to a _tag_. When the browser sees a tag to
  which the template is bound, it stamps the template out. Like so:
 
  1) Define a template and bind it to a tag name:
 
  template bindtotagname=my-yay
  divYay!/div
  /template
 
  2) Whenever my-yay is seen by the parser or
  createElement/NS(my-yay) is called, the template is stamped out to
  produce:
 
  my-yay
  divYay!/div
  /my-yay
 
  Cool! This is immediately useful for web developers. They can
  transform any markup into something they can use.
 
  Behind the scenes: the presence of boundtotagname triggers a call to
  document.register, and the argument is a browser-generated prototype
  object whose readyCallback takes the template and appends it to
  this.
 
  == Organic Shadow Trees  ==
 
  But what if they also wanted to employ encapsulation boundaries,
  leaving initial markup structure intact? No problem, much-maligned
  shadowroot to the rescue:
 
  1) Define a template with a shadow tree and bind it to a tag name:
 
  template bindtotagname=my-yay
  shadowroot
  divYay!/div
  /shadowroot
  /template
 
  2) For each my-yay created, the template is stamped out to create a
  shadow root and populate it.
 
  Super-cool! Note, how the developer doesn't have to know anything
  about Shadow DOM to build custom elements (er, template-bound tags).
  Shadow trees are just an option.
 
  Behind the scenes: exactly the same as the first scenario.
 
  == Declarative Meets Imperative ==
 
  Now, the developer wants to add some APIs to my-yay. Sure, no problem:
 
  template bindtotagname=my-yay
  shadowroot
  divYay!/div
  /shadowroot
  script runwhenbound
  // runs right after document.register is triggered
  this.register(ExactSyntaxTBD);
  script
  /template
 
  So-cool-it-hurts! We built a fully functional custom element, taking
  small steps from an extremely simple concept to the full-blown thing.
 
  In the process, we also saw a completely decoupled shadow DOM from
  custom elements in both imperative and declarative forms, achieving
  singularity. Well, or at least a high degree of consistence.
 
  == Problems ==
 
  There are severe issues.
 
  The shadowroot is turning out to be super-magical.
 
  The bindtotagname attribute will need to be also magical, to be
  consistent with how document.register could be used.
 
  The stamping out, after clearly specified, may raise eyebrows and
  turn out to be unintuitive.
 
  Templates are supposed to be inert, but the whole script
  runwhenbound thing is strongly negating this. There's probably more
  that I can't remember now.

 The following expresses the same semantics:

 element tagname=my-yay
   template
 shadowroot
   divYay!/div
 /shadowroot
   /template
   script runwhenbound
   /script
 /element

 I get that your proposal is fewer characters to type. Are there other
 advantages?

 
  == Plea ==
 
  However, I am hopeful that you smart folk will look at this, see the
  light, tweak the idea just a bit and hit the homerun. See the light,
  dammit!
 
  :DG





Re: [webcomponents]: Platonic form of custom elements declarative syntax

2013-04-10 Thread Rafael Weinstein
On Wed, Apr 10, 2013 at 2:45 PM, Rafael Weinstein rafa...@google.com wrote:
 FWIW, I think it's a design mistake to make element registration a
 concern of template.

Sorry. I over-stated my conviction here. Let me walk that back: I'm
not yet hearing sufficient justification for making element
registration a concern of template


 I'd be more persuaded by the developer ergonomics argument if this was
 a cost that was incurred with the usage of custom elements, but it's
 not. It's only incurred with the element definition.

 Separately, I may have missed it, but it seems to me that allowing
 custom elements to stamp out light DOM is a new semantic, that isn't
 obviously solving a problem which is either identified, or related to
 web components. Did I miss earlier discussion about this?

 On Wed, Apr 10, 2013 at 12:40 PM, Scott Miles sjmi...@google.com wrote:
 No, strictly ergonomic. Less nesting and less characters (less nesting is
 more important IMO).

 I would also argue that there is less cognitive load on the author then the
 more explicit factoring, but I believe this is subjective.

 Scott


 On Wed, Apr 10, 2013 at 12:36 PM, Rafael Weinstein rafa...@google.com
 wrote:

 On Wed, Apr 10, 2013 at 11:47 AM, Dimitri Glazkov dglaz...@google.com
 wrote:
  Dear Webappsonites,
 
  There's been a ton of thinking on what the custom elements declarative
  syntax must look like. Here, I present something has near-ideal
  developer ergonomics at the expense of terrible sins in other areas.
  Consider it to be beacon, rather than a concrete proposal.
 
  First, let's cleanse your palate. Forget about the element element
  and what goes inside of it. Eat some parsley.
 
  == Templates Bound to Tags ==
 
  Instead, suppose you only have a template:
 
  template
  divYay!/div
  /template
 
  Templates are good for stamping things out, right? So let's invent a
  way to _bind_ a template to a _tag_. When the browser sees a tag to
  which the template is bound, it stamps the template out. Like so:
 
  1) Define a template and bind it to a tag name:
 
  template bindtotagname=my-yay
  divYay!/div
  /template
 
  2) Whenever my-yay is seen by the parser or
  createElement/NS(my-yay) is called, the template is stamped out to
  produce:
 
  my-yay
  divYay!/div
  /my-yay
 
  Cool! This is immediately useful for web developers. They can
  transform any markup into something they can use.
 
  Behind the scenes: the presence of boundtotagname triggers a call to
  document.register, and the argument is a browser-generated prototype
  object whose readyCallback takes the template and appends it to
  this.
 
  == Organic Shadow Trees  ==
 
  But what if they also wanted to employ encapsulation boundaries,
  leaving initial markup structure intact? No problem, much-maligned
  shadowroot to the rescue:
 
  1) Define a template with a shadow tree and bind it to a tag name:
 
  template bindtotagname=my-yay
  shadowroot
  divYay!/div
  /shadowroot
  /template
 
  2) For each my-yay created, the template is stamped out to create a
  shadow root and populate it.
 
  Super-cool! Note, how the developer doesn't have to know anything
  about Shadow DOM to build custom elements (er, template-bound tags).
  Shadow trees are just an option.
 
  Behind the scenes: exactly the same as the first scenario.
 
  == Declarative Meets Imperative ==
 
  Now, the developer wants to add some APIs to my-yay. Sure, no problem:
 
  template bindtotagname=my-yay
  shadowroot
  divYay!/div
  /shadowroot
  script runwhenbound
  // runs right after document.register is triggered
  this.register(ExactSyntaxTBD);
  script
  /template
 
  So-cool-it-hurts! We built a fully functional custom element, taking
  small steps from an extremely simple concept to the full-blown thing.
 
  In the process, we also saw a completely decoupled shadow DOM from
  custom elements in both imperative and declarative forms, achieving
  singularity. Well, or at least a high degree of consistence.
 
  == Problems ==
 
  There are severe issues.
 
  The shadowroot is turning out to be super-magical.
 
  The bindtotagname attribute will need to be also magical, to be
  consistent with how document.register could be used.
 
  The stamping out, after clearly specified, may raise eyebrows and
  turn out to be unintuitive.
 
  Templates are supposed to be inert, but the whole script
  runwhenbound thing is strongly negating this. There's probably more
  that I can't remember now.

 The following expresses the same semantics:

 element tagname=my-yay
   template
 shadowroot
   divYay!/div
 /shadowroot
   /template
   script runwhenbound
   /script
 /element

 I get that your proposal is fewer characters to type. Are there other
 advantages?

 
  == Plea ==
 
  However, I am hopeful that you smart folk will look at this, see the
  light, tweak the idea just a bit and hit the homerun. See the light,
  dammit

Re: [webcomponents]: Re-imagining shadow root as Element

2013-03-18 Thread Rafael Weinstein
FWIW (and I'm not sure if this is good or bad) it would be consistent
with the template element if

-shadowroot serialized by default with innerHTML
-shadowroot, when parsed is lifted and pushed onto the parent
element's shadowroot stack
-appendChild(shadowroot) doesn't throw, but doesn't do what you
probably want (e.g. shadowroot is simply display:none if not
attached to a host). (I imagine there would be imperative API on
element, so that the correct imperative operation was to directly push
a new shadowroot() onto an element, rather than using appendChild.

Of course, if serialization round-tripping is non-lossy, this raises
the question about implicit shadow roots (i.e. the element is
registered and *creates* its shadowroots whenever it is created).

On Mon, Mar 18, 2013 at 2:38 PM, Scott Miles sjmi...@google.com wrote:
 Sorry if I'm clobbering this thread, I promise to stop after this, but I
 solved my own mental model. Namely, I decide to treat shadowroot like
 outerHTML.

 If I define (pseudo):

 div id=A
   shadowroot
  span id=B
 shadowroot
...

 The A.innerHTML == span id=Bshadowroot...

 I don't see A's shadowroot, because it's really part of it's outer-ness.
 It's part of what makes A, it's not part of A's content.

 Now I can send A's innerHTML to B with no problem. Or roundtrip A's content
 with no problem.

 I realize I've broken several standard laws, but in any event it seems
 consistent to itself.



 On Mon, Mar 18, 2013 at 2:08 PM, Scott Miles sjmi...@google.com wrote:

 Ok, well obviously, there are times when you don't want the shadowroot
 to be in innerHTML, so I was correct that I was grossly over simplifying. I
 guess this is where the second kind of innHTML accessor comes in. Sorry!

 It's still A though. :)


 On Mon, Mar 18, 2013 at 2:05 PM, Scott Miles sjmi...@google.com wrote:

 I'm already on the record with A, but I have a question about
 'lossiness'.

 With my web developer hat on, I wonder why I can't say:

 div id=foo
   shadowroot
 shadow stuff
   /shadowroot

   light stuff

 /div


 and then have the value of #foo.innerHTML still be

   shadowroot
  shadow stuff
   /shadowroot

   lightstuff

 I understand that for DOM, there is a wormhole there and the reality of
 what this means is new and frightening; but as a developer it seems to be
 perfectly fine as a mental model.

 We web devs like to grossly oversimplify things. :)

 Scott

 On Mon, Mar 18, 2013 at 1:53 PM, Dimitri Glazkov dglaz...@google.com
 wrote:

 Last Friday, still energized after the productive Mozilla/Google
 meeting, a few of us (cc'd) dug into Shadow DOM. And boy, did that go
 south quickly! But let's start from the top.

 We puzzled over the the similarity of two seemingly disconnected
 problems:

 a) ShadowRoot is a DocumentFragment and not an Element, and
 b) there is no declarative way to specify shadow trees.

 The former is well-known (see

 http://lists.w3.org/Archives/Public/public-webapps/2013JanMar/thread.html#msg356).

 The latter came into view very early as a philosophical problem
 (provide declarative syntax for new imperative APIs) and much later as
 a practical problem: many modern apps use a freeze-drying
 performance technique where they load as-rendered HTML content of a
 page on immediately (so that the user sees content immediately), and
 only later re-hydrate it with script. With shadow DOM, the lack of
 declarative syntax means that the content will not appear
 as-rendered until the script starts running, thus ruining the whole
 point of freeze-drying.

 We intentionally stayed away from the arguments like well, with
 custom elements, all of this happens without script. We did this
 precisely because we wanted to understand what all of this happens
 actually means.

 Trapped between these two problems, we caved in and birthed a new
 element. Let's call it shadowroot (Second Annual Naming Contest
 begins in 3.. 2.. ).

 This element _is_ the ShadowRoot. It's deliciously strange. When you
 do div.appendChild(document.createElement('shadowroot')), the DOM:

 0) opens a magic wormhole to the land of rainbows and unicorns (aka
 the Gates of Hell)
 1) adds shadowroot at the top of div's shadow tree stack

 This behavior has three implications:

 i) You can now have detached ShadowRoots. This is mostly harmless. In
 fact, being able to prepare ShadowRoot instances before adding them to
 a host seems like a good thing.

 ii) ShadowRoot never appears as a child of an element. This is desired
 original behavior.

 iii) Parsing HTML with shadowroot in it results in loss of data when
 round-tripping. This is hard to swallow, but one can explain it as a
 distinction between two trees: a document tree and a composed tree.
 When you invoke innerHTML, you get a document tree. When you invoke
 (yet to be invented) innerComposedHTML, you get composed tree.

 Alternatively, we could just make appendChild/insertBefore/etc. throw
 and make special rules for 

Re: [webcomponents]: Making Shadow DOM Subtrees Traversable

2013-03-06 Thread Rafael Weinstein
So the two camps in the this argument seem to be arguing largely
philosophical views.

It's clear that Mozilla has experienced pain via plugins having access
to browser internals.

I'm curious if jQuery or others have experienced feeling restricted
because apps are depending on internals by way of having access to
them via monkey-patching

It seems to me like if public-by-default was a design mistake on the
web, it'd be pretty clearly in evidence already. Is it?

On Tue, Feb 26, 2013 at 1:08 PM, Boris Zbarsky bzbar...@mit.edu wrote:
 On 2/26/13 3:56 PM, Dominic Cooney wrote:

 One more thought occurs to me: It is easier to add public shadows in a
 subsequent revision of the spec than it is to take public shadows away.


 Yes, indeed.  That's one of the main reasons I'd like it to be the initial
 default...

 I would certainly be completely against shipping anything that does not
 provide private shadows at all, of course.

 -Boris




Re: [webcomponents] Making the shadow root an Element

2013-02-22 Thread Rafael Weinstein
On Tue, Feb 19, 2013 at 11:42 PM, Jonas Sicking jo...@sicking.cc wrote:

 On Tue, Feb 19, 2013 at 12:24 PM, Rafael Weinstein rafa...@google.com
 wrote:
  On Mon, Feb 18, 2013 at 12:06 PM, Jonas Sicking jo...@sicking.cc
 wrote:
 
  On Mon, Feb 18, 2013 at 1:48 AM, Anne van Kesteren ann...@annevk.nl
  wrote:
   On Sat, Feb 16, 2013 at 5:23 PM, Dimitri Glazkov dglaz...@google.com
 
   wrote:
   We were thinking of adding innerHTML to DocumentFragments anyway...
   right, Anne?
  
   Well I thought so, but that plan didn't work out at the end of the
 day.
  
   https://www.w3.org/Bugs/Public/show_bug.cgi?id=14694#c7
  
   So given that consensus still putting it on ShadowRoot strikes me like
   a bad idea (as I think I've said somewhere in a bug). The same goes
   for various other members of ShadowRoot.
 
  I don't think there's a consensus really. JS authors were very vocal
  about needing this ability. Does anyone have a link to the strong
  case against adding explicit API for DF.innerHTML from Hixie that
  that comment refers to?
 
 
  Unfortunately that comment referred to an IRC discussion that took place
  last June on #whatwg.
 
  IIRC, Hixie's position was that adding more explicit API for innerHTML
 is a
  moral hazard because it encourages an anti-pattern. (Also IIRC), Anne and
  Henri both sided with Hixie at the time and the DF.innerHTML got left in
 a
  ditch.

 The discouraging that we're currently doing doesn't seem terribly
 effective. Developers seem to just grab/create a random element and
 set .innerHTML on that.

 So I think the current state of affairs is just doing a disservice to
 everyone, including ourselves.


I agree, and this was my position at the time, FWIW.



 / Jonas



Re: [webcomponents] Making the shadow root an Element

2013-02-19 Thread Rafael Weinstein
On Mon, Feb 18, 2013 at 12:06 PM, Jonas Sicking jo...@sicking.cc wrote:

 On Mon, Feb 18, 2013 at 1:48 AM, Anne van Kesteren ann...@annevk.nl
 wrote:
  On Sat, Feb 16, 2013 at 5:23 PM, Dimitri Glazkov dglaz...@google.com
 wrote:
  We were thinking of adding innerHTML to DocumentFragments anyway...
 right, Anne?
 
  Well I thought so, but that plan didn't work out at the end of the day.
 
  https://www.w3.org/Bugs/Public/show_bug.cgi?id=14694#c7
 
  So given that consensus still putting it on ShadowRoot strikes me like
  a bad idea (as I think I've said somewhere in a bug). The same goes
  for various other members of ShadowRoot.

 I don't think there's a consensus really. JS authors were very vocal
 about needing this ability. Does anyone have a link to the strong
 case against adding explicit API for DF.innerHTML from Hixie that
 that comment refers to?


Unfortunately that comment referred to an IRC discussion that took place
last June on #whatwg.

IIRC, Hixie's position was that adding more explicit API for innerHTML is a
moral hazard because it encourages an anti-pattern. (Also IIRC), Anne and
Henri both sided with Hixie at the time and the DF.innerHTML got left in a
ditch.

It's also worth pointing out that if it was decided to have innerHTML on DF
and on ShadowRoot, they would likely have subtly different semantics:

-DF.innerHTML would parse exactly the way template.innerHTML does (using
the 'implied context parsing).
-SR.innerHTML would use its host as the context element and the output
would be as if the input *had been* applied to host.innerHTML, then
lifted out and attached to the SR.

(I believe the later currently the case for ShadowRoot).



 / Jonas




Re: document.register and ES6

2013-02-05 Thread Rafael Weinstein
On Tue, Feb 5, 2013 at 3:25 PM, Boris Zbarsky bzbar...@mit.edu wrote:

 On 2/5/13 11:01 PM, Erik Arvidsson wrote:

 On Tue, Feb 5, 2013 at 5:28 PM, Boris Zbarsky bzbar...@mit.edu wrote:

 So in particular this allows creation of uninitialized instances in
 some
 sense, yes?


 Depends how much logic is put in the constructor vs @@create. For DOM
 Elements I think we want to put *all* the logic in create.


 OK, I can live with that as long as the only arguments are things like for
 Image.  We'll have to be pretty careful about how we define our Element
 subclass constructors in the future, though...

 And there are knock-on effects on all other objects in WebIDL.  See below.


  This won't work right given how HTMLButtonElement is currently defined in
 WebIDL.  Need to fix that at the very least.


 Yes, but for document.register I think we can get away without
 changing this.


 No, you can't.  You really need to get WebIDL fixed here.


  We might need to add no op call methods to these
 functions


 They already have [[Call]].  What they don't have is a custom
 [[Construct]].  Which means that they end up invoking the [[Construct]]
 defined in ES5 section 13.2.2, which in step 8 calls the [[Call]] and if
 that returns an object (which the WebIDL [[Call]] does) throws away the
 object that [[construct]] just created and returns the object [[Call]]
 returned.

 And you can't no-op the [[Call]] because web pages, afaik, use things like:

   var myImage = Image();

 and

   var xhr = XMLHttpRequest();

 just like they use Date() and Object() and Array().  The above is
 supported for DOM constructors in at least Gecko and Presto, though
 apparently not Chrome or Safari; I don't have IE to test right now.  But
 the point is that right now those constructors are not particularly weird
 in Gecko and Presto, and I'm not entirely happy making them _more_ weird.

 Maybe the fact that Chrome and Safari don't support this means that we can
 in fact redefine the [[Construct]] to create the right sort of object and
 then invoke [[Call]] which will actually initialize the object.  But that
 brings us back to being able to create partially-initialized objects for
 all IDL interfaces, not just elements

 Perhaps we need to define an IDL annotation for interfaces that opt in to
 this split between [[Call]] and [[Construct]] and then have elements opt in
 to it?


  but that seems like the right thing to do anyway. The WebIDL
 interface constructors are already strange as they are


 Not in Gecko and Presto as far as I can tell...  Certainly not any
 stranger than Date or Array.


  and I doubt anyone would object to making them less strange.


 I have no problem with less strange, but you're proposing more strange.
  Again, as far as I can tell.


  What happens if the same function is registered for several different tag
 names, in terms of what happens with the [[Construct]]?


 I vote for throwing. We could allow the tag name to be used as an
 alias but I don't really understand the use case you have in mind
 here.


 I don't have a use case.  What I have is an edge case that I can see
 implementations doing random non-interoperable crap for if we don't define
 it.

 Throwing sounds fine to me.


  Define, please.  How does one determine this, in a rendering engine
 implementation?  I certainly have no way to tell, in Gecko, when I'm
 entering script, offhand


 I was told this is needed for mutation observers that are queued up
 during parse. I'll let Dimitri or Rafael chime in with details.


 Ah, OK.  Defining this stuff to happen at end of microtask or whatever it
 is that normally triggers mutation observers makes a lot more sense than
 before entering script.  ;)


http://www.whatwg.org/specs/web-apps/current-work/#parsing-main-incdata

The first thing that happens upon encoutering /script is performing a
microtask check point.

I think Arv is suggesting that running custom element constructors would be
included in this work.


 Thanks,
 Boris




Re: Review of the template spec

2013-01-24 Thread Rafael Weinstein
Note that the spec has moved to FPWD, all of the comments Henri raised have
been addressed and WebKit TOT now contains a full implementation including
tests.

On Fri, Dec 21, 2012 at 1:31 PM, Rafael Weinstein rafa...@google.comwrote:



 On Fri, Dec 14, 2012 at 2:58 PM, Jonas Sicking jo...@sicking.cc wrote:

 On Fri, Dec 14, 2012 at 1:32 AM, Simon Pieters sim...@opera.com wrote:
  On Fri, 14 Dec 2012 00:04:20 +0100, Jonas Sicking jo...@sicking.cc
 wrote:
 
  On Tue, Dec 11, 2012 at 5:00 AM, Henri Sivonen hsivo...@iki.fi
 wrote:
 
  1. If DOCUMENT does not have a browsing context, Let TEMPLATE
 CONTENTS
  OWNER be DOCUMENT and abort these steps.
  2. Otherwise, Let TEMPLATE CONTENTS OWNER be a new Document node that
  does not have a browsing context.
 
 
  Is there a big win from this inconsistency? Why not always have a
  separate doc as the template contents owner?


 My goal was to *only* have one separate doc per normal doc. Consider the
 following:

 body
   div id=a
   template id=1
 div id=b
 template id=2
   div id=c
 template
   /template
 /body

 The if document does not have a browsing context part is needed by
 template 2 so its contents can be owned by the same document as template
 1's contents. I.e. for each document with a browsing context, there is a
 single (lazily created) template contents owner which is shared by all
 templates reachable from the main document's documentElement.

 I'm open to other ways of accomplishing the same thing, but like Jonas,
 I'm mainly concerned here with minimizing the number of extra documents
 which need to be constructed to owner template contents.


 
 
  Or why not always use the owner document of the template element?
 
 
  I think that would cause things like img elements to load.


 Correct. Remember that we've already agreed that the mechanism for
 template contents inertness is that the content document fragment (and
 all of its descendants) are owned by a document which does not have a
 browsing context.



 True. Though I wonder if that can be solved in other ways. Should be
 relatively easy to fix in Gecko, though I don't know about other
 implementations of course.

 Seems unfortunate to add the wonkyness of separate owner documents
 just to overcome this hurdle.



 / Jonas





Re: [html-templates] Typos

2013-01-03 Thread Rafael Weinstein
Thanks so much! Filed as
https://www.w3.org/Bugs/Public/show_bug.cgi?id=20563

On Wed, Jan 2, 2013 at 11:33 AM, Jens O. Meiert j...@meiert.com wrote:

 Hi,

 I noticed the following typos in the HTML Templates draft [1]:

 * Under “Definitions,” “If DOCUMENT does not have a browsing context,
 Let…” (should be “let”).

 * Same section, “the stack of open elements is said be have” (seems to
 miss “to”).

 * Sometimes the word ”html” is used in lowercase, but not always
 referring to the standard. It would be good to check for correct use
 in the document, and to use capitals for references to the standard,
 and a monospace font for references to the element.

 * Inconsistent spelling of “insertion mode”. Headings, even for those
 whose levels don’t use title case, seem to always say “Insertion
 Mode,” while the copy following it says “insertion mode.” This seems
 inconsistent either when it comes to the headings (as they’re not all
 or completely using title case) or the copy (which should then also
 refer to “Insertion Mode”).

 HTH, best,
  Jens.


 [1]
 http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html

 --
 Jens O. Meiert
 http://meiert.com/en/




Re: Review of the template spec

2012-12-21 Thread Rafael Weinstein
Thanks for reviewing this (and sorry for the delay -- I was on vacation,
and blissfully unable to read email).

I'm happy (and a little surprised) that there's no comment here about the
HTML parser changes. Is that because it all looks good, or because you
didn't dig that deep into it yet?

The XML/XSLT/XDM stuff is missing only because we didn't have time to get
to it yet. It's next on my priority list now that I'm back. The spec bugs
for describing the additional semantics are included inline below.

Also, FYI: Although we've landed code for the current spec in WebKit and
Chrome Canary, it's behind a compile flag, only enabled for the Chromium
port and will not go to beta or release until the spec is reasonably
settled (including the XML/XSLT/XDM stuff).

On Tue, Dec 11, 2012 at 5:00 AM, Henri Sivonen hsivo...@iki.fi wrote:

 I reviewed
 http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#dfn-template
 . Sorry about the delay.

 Comments:

 XML parsing isn’t covered. (Should have the wormhole per the
 discussion at TPAC.)


https://www.w3.org/Bugs/Public/show_bug.cgi?id=19889





 XSLT output isn’t covered. (When an XSLT program trying to generate a
 template element with children, the children should go through the
 wormhole.)


 Interaction with the DOM to XDM mapping isn’t covered per discussion
 at TPAC. (Expected template contents not to appear in the XDM when
 invoking the XPath DOM API (for consistency with querySelectorAll) but
 expected them to appear in the XDM when an XSLT transformation is
 being processed (to avoid precluding use cases).)


https://www.w3.org/Bugs/Public/show_bug.cgi?id=20483



  1. If DOCUMENT does not have a browsing context, Let TEMPLATE CONTENTS
 OWNER be DOCUMENT and abort these steps.
  2. Otherwise, Let TEMPLATE CONTENTS OWNER be a new Document node that
 does not have a browsing context.

 Is there a big win from this inconsistency? Why not always have a
 separate doc as the template contents owner?

 Do we trust the platform never to introduce a way to plant a document
 that does not have a browsing context into a browsing context?
 (Unlikely, but do we really want to make the bet?)




 --
 Henri Sivonen
 hsivo...@iki.fi
 http://hsivonen.iki.fi/



Re: Review of the template spec

2012-12-21 Thread Rafael Weinstein
On Fri, Dec 14, 2012 at 2:58 PM, Jonas Sicking jo...@sicking.cc wrote:

 On Fri, Dec 14, 2012 at 1:32 AM, Simon Pieters sim...@opera.com wrote:
  On Fri, 14 Dec 2012 00:04:20 +0100, Jonas Sicking jo...@sicking.cc
 wrote:
 
  On Tue, Dec 11, 2012 at 5:00 AM, Henri Sivonen hsivo...@iki.fi wrote:
 
  1. If DOCUMENT does not have a browsing context, Let TEMPLATE CONTENTS
  OWNER be DOCUMENT and abort these steps.
  2. Otherwise, Let TEMPLATE CONTENTS OWNER be a new Document node that
  does not have a browsing context.
 
 
  Is there a big win from this inconsistency? Why not always have a
  separate doc as the template contents owner?


My goal was to *only* have one separate doc per normal doc. Consider the
following:

body
  div id=a
  template id=1
div id=b
template id=2
  div id=c
template
  /template
/body

The if document does not have a browsing context part is needed by
template 2 so its contents can be owned by the same document as template
1's contents. I.e. for each document with a browsing context, there is a
single (lazily created) template contents owner which is shared by all
templates reachable from the main document's documentElement.

I'm open to other ways of accomplishing the same thing, but like Jonas, I'm
mainly concerned here with minimizing the number of extra documents which
need to be constructed to owner template contents.


 
 
  Or why not always use the owner document of the template element?
 
 
  I think that would cause things like img elements to load.


Correct. Remember that we've already agreed that the mechanism for template
contents inertness is that the content document fragment (and all of its
descendants) are owned by a document which does not have a browsing context.



 True. Though I wonder if that can be solved in other ways. Should be
 relatively easy to fix in Gecko, though I don't know about other
 implementations of course.

 Seems unfortunate to add the wonkyness of separate owner documents
 just to overcome this hurdle.



 / Jonas



Scheduling multiple types of end-of-(micro)task work

2012-10-18 Thread Rafael Weinstein
CSS Regions regionLayoutUpdate brings up an issue I think we need to
get ahead of:

  https://www.w3.org/Bugs/Public/show_bug.cgi?id=16391

For context:

Mutation Observers are currently spec'd in DOM4

http://dom.spec.whatwg.org/#mutation-observers

and delivery timing is defined in HTML


http://www.whatwg.org/specs/web-apps/current-work/#perform-a-microtask-checkpoint

The timing here is described as a microtask checkpoint and is
conceptually deliver all pending mutation records immediately after
any script invocation exits.

TC-39 has recently approved Object.observe

http://wiki.ecmascript.org/doku.php?id=harmony:observe

for inclusion in ECMAScript. It is conceptually modeled on Mutation
Observers, and delivers all pending change records immediately
*before* the last script stack frame exits.

Additionally, although I've seen various discussion of dispatching DOM
Events with the microtask timing, CSS regionLayoutUpdate is the first
I'm aware of to attempt it

http://dev.w3.org/csswg/css3-regions/#region-flow-layout-events

[I think this is wrong, and I'm hoping this email can help nail down
what will work better].

---

Strawman:

I'd like to propose a mental model for how these types of work get
scheduled. Note that my guiding principles are consistent with the
original design of the the end-of-(micro)task timing:

-Observers should be delivered to async, but soon

-Best efforts should be made to prevent future events from running in
a world where pending observer work has not yet been completed.


Delivery cycles:

1) Script (Object.observe) delivery. This is conceptually identical to
Mutation Observers.

http://wiki.ecmascript.org/doku.php?id=harmony:observe#deliverallchangerecords

2) DOM (Mutation Observers) delivery.

http://dom.spec.whatwg.org/#mutation-observers

3) End-of-task queue.

This would be a new construct. Conceptually it would be a task queue
like other task queues, except that its purpose is to schedule
end-of-task work. Running it causes events to be dispatched in order
until the queue is empty.


Scheduling:

A) Immediately before any script invocation returns to the browser
(after the last stack frame exits), run (1). This can be purely a
concern of the script engine and spec'd independent of HTML  DOM4.

B) Immediately after any script invocation returns to the browser
(microtask checkpoint), run (2). Note that delivering to each observer
creates a new script invocation, at the end of which, (1) will run
again because of (A).

C) Immediately before the UA completes the current task, run (2). This
is necessary incase DOM changes have occurred outside of a script
context (e.g. an input event triggered a change), and is already
implemented as part of DOM Mutation Observers.

D) Run (3). Note that each script invocation terminates in running (1)
because of (A), then (2) because of (B).



Re: Scheduling multiple types of end-of-(micro)task work

2012-10-18 Thread Rafael Weinstein
On Thu, Oct 18, 2012 at 2:51 PM, Olli Pettay olli.pet...@helsinki.fi wrote:
 On 10/19/2012 12:08 AM, Rafael Weinstein wrote:

 CSS Regions regionLayoutUpdate brings up an issue I think we need to
 get ahead of:

https://www.w3.org/Bugs/Public/show_bug.cgi?id=16391

 For context:
 
 Mutation Observers are currently spec'd in DOM4

  http://dom.spec.whatwg.org/#mutation-observers

 and delivery timing is defined in HTML


 http://www.whatwg.org/specs/web-apps/current-work/#perform-a-microtask-checkpoint

 The timing here is described as a microtask checkpoint and is
 conceptually deliver all pending mutation records immediately after
 any script invocation exits.

 TC-39 has recently approved Object.observe

  http://wiki.ecmascript.org/doku.php?id=harmony:observe


 (Not sure how that will work with native objects.)

I assume you mean host objects (e.g. HTMLElement). The Object.observe
doesn't say anything about host objects, so unless the wrapper
property actually changes (e.g myElem.myExpando = 'newValue'), it
won't be observable. The goal of this mechanism wasn't to observe
changes to host objects.





 for inclusion in ECMAScript. It is conceptually modeled on Mutation
 Observers, and delivers all pending change records immediately
 *before* the last script stack frame exits.

 Additionally, although I've seen various discussion of dispatching DOM
 Events with the microtask timing, CSS regionLayoutUpdate is the first
 I'm aware of to attempt it

  http://dev.w3.org/csswg/css3-regions/#region-flow-layout-events



 Could you explain why microtasks are good for this case?
 I would have expected something bound to animation frame callback handling,
 or perhaps just tasks (but before next layout flush or something).

I can't. I don't know enough about CSS Regions. I'm bringing this up
now because I've seen multiple instances of people *considering*
microtask timing for Event dispatch, but this is the first time
someone is trying it.



 -Olli





 [I think this is wrong, and I'm hoping this email can help nail down
 what will work better].

 ---

 Strawman:

 I'd like to propose a mental model for how these types of work get
 scheduled. Note that my guiding principles are consistent with the
 original design of the the end-of-(micro)task timing:

 -Observers should be delivered to async, but soon

 -Best efforts should be made to prevent future events from running in
 a world where pending observer work has not yet been completed.


 Delivery cycles:

 1) Script (Object.observe) delivery. This is conceptually identical to
 Mutation Observers.


 http://wiki.ecmascript.org/doku.php?id=harmony:observe#deliverallchangerecords

 2) DOM (Mutation Observers) delivery.

 http://dom.spec.whatwg.org/#mutation-observers

 3) End-of-task queue.

 This would be a new construct. Conceptually it would be a task queue
 like other task queues, except that its purpose is to schedule
 end-of-task work. Running it causes events to be dispatched in order
 until the queue is empty.


 Scheduling:

 A) Immediately before any script invocation returns to the browser
 (after the last stack frame exits), run (1). This can be purely a
 concern of the script engine and spec'd independent of HTML  DOM4.

 B) Immediately after any script invocation returns to the browser
 (microtask checkpoint), run (2). Note that delivering to each observer
 creates a new script invocation, at the end of which, (1) will run
 again because of (A).

 C) Immediately before the UA completes the current task, run (2). This
 is necessary incase DOM changes have occurred outside of a script
 context (e.g. an input event triggered a change), and is already
 implemented as part of DOM Mutation Observers.

 D) Run (3). Note that each script invocation terminates in running (1)
 because of (A), then (2) because of (B).





Re: Should MutationObservers be able to observe work done by the HTML parser?

2012-06-30 Thread Rafael Weinstein
On Fri, Jun 29, 2012 at 6:14 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Fri, Jun 29, 2012 at 8:25 PM, Adam Klein ad...@chromium.org wrote:
 On Fri, Jun 29, 2012 at 2:44 AM, Jonas Sicking jo...@sicking.cc wrote:

 All in all I think that as soon as we introduce exceptions to when
 MutationObserver callbacks fire we change the API from being a
 reliable way to track DOM mutations to a unreliable way where all
 callers have to be aware of exceptions and deal with them in other
 ways. I.e. it feels like it significantly reduces the value of
 MutationObservers.

 And so far I don't see any good arguments made for making that
 reduction in value. Did I miss any arguments other then the randomness
 argument?


 Performance was one concern that's come up in discussing this with Ojan and
 Rafael. Imagine a MutationObserver attached to the document near the top of
 the page. Now we need to create basically one MutationRecord per node
 inserted (because the parser operates in a depth-first sort of order). I'm
 not at all sure this is a show-stopper (we might be able to introduce some
 new MutationRecord type that could compactly represent parser-style
 operation), but it definitely seems worrisome, especially given that one of
 the common uses for MutationObservers is extensions which might run on many
 (all?) pages.

 Hmm.. is there actually anything requiring that nodes are inserted one
 at a time? Internally in mozilla we do insert nodes one at a time, but
 the notifications we send out to the various subsystems make it seem
 like nodes are inserted in big chunks. This has previously been to

Are the chunks arbitrarily shaped fragments? I.e. is their any
restriction on their shape other than a tree?

 give us good performance from the layout engine which benefits from
 getting notified by large chunks being inserted rather than nodes
 being inserted one at a time. The MutationObserver implementation
 hangs off of the same notification system and thus also sees nodes as
 being inserted in big chunks.

 / Jonas




Re: [webcomponents] HTML Parsing and the template element

2012-06-26 Thread Rafael Weinstein
I think I'm not understanding the implications of your argument.

You're making a principled argument about future pitfalls. Can you
help me get my head around it by way of example?

Perhaps:
-pitfalls developers fall into
-further dangerous points along the slippery slope you think this
opens up (you mentioned pandoras box)


On Fri, Jun 15, 2012 at 4:04 AM, Henri Sivonen hsivo...@iki.fi wrote:
 On Thu, Jun 14, 2012 at 11:48 PM, Ian Hickson i...@hixie.ch wrote:
 Does anyone object to me adding template, content, and shadow to
 the HTML parser spec next week?

 I don't object to adding them if they create normal child elements in
 the DOM. I do object if template has a null firstChild and the new
 property that leads to a fragment that belongs to a different owner
 document.

 (My non-objection to creating normal children in the DOM should not be
 read as a commitment to support templates Gecko.)


 --
 Henri Sivonen
 hsivo...@iki.fi
 http://hsivonen.iki.fi/




Re: Proposal: Document.parse() [AKA: Implied Context Parsing]

2012-06-16 Thread Rafael Weinstein
E4H doesn't address all the use cases of Document.parse().

It doesn't solve the problem of existing templating libraries
constructing DOM fragments from processed templates.

E4H (or something similar) would be great, but I think it's a mistake
to make it mutually exclusive with Document.parse().

On Tue, Jun 5, 2012 at 11:24 PM, Ian Hickson i...@hixie.ch wrote:
 On Mon, 4 Jun 2012, Adam Barth wrote:
 
    http://www.hixie.ch/specs/e4h/strawman
 
  Who wants to be first to implement it?

 Doesn't e4h have the same security problems as e4x?

 As written it did, yes (specifically, if you can inject content into an
 XML file you can cause it to run JS under your control in your origin with
 content from the other origin). However, as Anne and you have said, it's
 easy to fix, either by using an XML-incompatible syntax or using CORS to
 disable it. Since we have to disable it in Workers anyway, I'd go with
 disabling it when there's no CORS. Strawman has been updated accordingly.


 On Tue, 5 Jun 2012, Anne van Kesteren wrote:

 A (bigger?) problem with E4H/H4E is that TC39 does not like it:
 http://lists.w3.org/Archives/Public/public-script-coord/2011OctDec/thread.html#msg33

 What matters is what implementors want to do.

The TC-39 spec process isn't the problem here. TC-39 is composed of
implementors, and they are clearly stating a preference for quasis.


 --
 Ian Hickson               U+1047E                )\._.,--,'``.    fL
 http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [webcomponents] HTML Parsing and the template element

2012-06-11 Thread Rafael Weinstein
On Mon, Jun 11, 2012 at 3:13 PM, Henri Sivonen hsivo...@iki.fi wrote:
 On Thu, Jun 7, 2012 at 8:35 PM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 Just saying that querySelector/All doesn't match elements in a
 template (unless the scope is inside the template already) would work,
 but it means that we have to make sure that all future similar APIs
 also pay attention to this.

 I think that would be preferable compared to opening the Pandora's box
 of breaking the correspondence between the markup of the DOM tree.
 Besides, we'd need something like this for the XML case anyway if the
 position the spec takes is that it shies away from changing the
 correspondence between XML source and the DOM.

 In general, I think the willingness to break the correspondence
 between the source and the DOM should be the same for both HTML and
 XML serializations. If you believe that it's not legitimate to break
 the correspondence between XML source and the DOM, it would be logical
 to treat radical changes to the correspondence between HTML source and
 the DOM as equally suspect.

I think looking at this as whether we are breaking the correspondance
between source and DOM may not be helpful -- because it's likely to
be a matter of opinion. I'd like to suggest that we look at more
precise issues.

There are several axes of presence for elements WRT to a Document:

-serialization: do the elements appear in the serialization of the
Document, as delivered to the client and if the client re-serializes
via innerHTML, etc...
-DOM traversal: do the elements appear via traversing the document's
childNodes hierarchy
-querySelector*, get*by*, etc: are the element's returned via various
document-level query mechanisms
-CSS: are the element's considered for matching any present or future
document-level selectors

The goal of the template element is this: the page author would like
a declarative mechanism to author DOM fragments which are not in use
as of page construction, but are readily available to be used when
needed. Further, the author would like to be able to declare the
fragments inline, at the location in the document where they should be
placed, if  when they are needed.

Thus, template require that its contents be present for only
serialization, and not for DOM traversal, querySelector*/etc..., or
CSS.

Also, it may be helpful to think about this in terms of classical
object systems. Currently we only have instances. What we need is a
classes. Native app windowing systems don't force you to create an
instance of every window or dialog that your app may ever need and
place it off screen until it's needed. They allow for the notion of
declaring what the window or dialog will be and delay creating any UI
resources (HWNDs, buttons, drag targets, etc..) until the app creates
an instance.


 I worry that if we take the position here that it's okay to change
 your correspondence between the source and the DOM in order to
 optimize for a real or perceived need, it will open the floodgates for
 all sorts of arguments that we can make the parser generate whatever
 data structures regardless of what the input looks like and we'll end
 up in a world of pain. It's bad enough that isindex is a parser macro.

 --
 Henri Sivonen
 hsivo...@iki.fi
 http://hsivonen.iki.fi/



Re: Implied Context Parsing (DocumentFragment.innerHTML, or similar) proposal details to be sorted out

2012-06-08 Thread Rafael Weinstein
Yehuda,

Can you help clarify here whether jQuery's behavior is intentional
(i.e. use cases drive the need for executability), or if it's a
side-effect of the implementation?

On Fri, Jun 1, 2012 at 1:27 PM, Ryosuke Niwa rn...@webkit.org wrote:
 On Thu, May 31, 2012 at 7:55 AM, Henri Sivonen hsivo...@iki.fi wrote:

 On Sat, May 19, 2012 at 6:29 AM, Ryosuke Niwa rn...@webkit.org wrote:
  There appears to be a consensus to use document.parse (which is fine
  with
  me), so I would like to double-check which behavior we're picking. IMO,
  the
  only sane choice is to unset the already-started flag since doing
  otherwise
  implies script elements parsed by document.parse won't be executed when
  inserted into a document.

 I was expecting document.parse() to make scripts unexecutable. Are
 there use cases for creating executable scripts using this facility?


 jQuery appears to let script elements run: http://jsfiddle.net/kB8Fp/2/

 Also, we're talking about using the same algorithm for template element.
 I would like script elements inside my template to run.

 - Ryosuke




Re: Proposal: Document.parse() [AKA: Implied Context Parsing]

2012-06-04 Thread Rafael Weinstein
Just to be clear: what you are objecting to is the addition of formal
API for this.

You're generally supportive of adding a template element whose
contents would parse the way we're discussing here -- and given that,
a webdev could trivially polyfil Document.parse().

I.e. you're ok with the approach of the parser picking a context
element based on the contents of markup, but against giving webdevs
the impression that innerHTML is good practice, by adding more API in
that direction?

Put another way, though you're not happy with adding the API, you
willing to set that aside and help spec the parser changes required
for both this and template element (assuming the remaining issues
with template can be agreed upon)?

FWIW, I agree with Hixie in principle, but disagree in practice. I
think innerHTML is generally to be avoided, but I feel that adding
Document.parse() improves the situation by making some current uses
(which aren't likely to go away) less hacky. Also, I'm not as worried
with webdevs taking the wrong message from us adding API. My feeling
is that they just do what works best for them and don't think much
about what we are or are not encouraging.

Also, I'm highly supportive of the goal of allowing HTML literals in
script. I fully agree that better load (compile) time feedback would
be beneficial to authors here.

On Mon, Jun 4, 2012 at 3:47 PM, Ian Hickson i...@hixie.ch wrote:
 On Fri, 25 May 2012, Rafael Weinstein wrote:

 Now's the time to raise objections to UA's adding support for this
 feature.

 For the record, I very much object to Document.parse(). I think it's a
 terrible API. We should IMHO resolve the use case of generate a DOM tree
 from script using a much more robust solution that has compile-time
 syntax checking and so forth, rather than relying on the super-hacky
 concatenate a bunch of strings and then parse them solution that authors
 are forced to use today.

 innerHTML and document.write() are abominations unto computer science, and
 we are doing nobody any favours by continuing the platform down this road.
 They lead to programming styles that are rife with injection bugs (XSS),
 they are extremely difficult to debug and maintain, and they are terribly
 complicated to implement compared to more structured alternatives. The
 core reasons for these problems, IMHO, are two-fold:

  1. Lack of compile-time syntax checking, which leads to typos not being
    caught and thus programmer intent not being faithfully represented,
    and
  2. Putting markup syntax and data at the same level, instead of having
    separating them as with other features in JS.

 For example, this kind of bug is easy to introduce and hard to spot or
 debug:

   var heading = 'h1Hello/h1';
   // ...
   div.innerHTML = 'h1' + heading + '/h1';

 Even worse are things like typos:

   tr.innerHTML = 'td' + c1 + '/tdtd' + c2 + '/tddt' + c3 + '/td;

 Compile-time syntax checking makes this a non-issue. Making data variables
 be qualitatively different than the syntax also solves problems, e.g.:

   var title = I hate /p tags.;
   // ...
   div.innerHTML = 'pToday's topic is: ' + title + '/p'; // oops, not 
 escaped


 There have been several alternative proposals; my personal favourite is
 Anne's E4H solution, basically E4X but simplified just for HTML, which
 I've written a strawman spec for here:

   http://www.hixie.ch/specs/e4h/strawman

 I'm happy to write a more serious spec for this if this is something
 anyone is interested in implementing. The above examples become much
 easier to debug. The first one results in very ugly markup visible in the
 output of the page rather than in the weird spacing:

   var heading = 'h1Hello/h1';
   // ...
   div.appendChild(h1{heading}/h1);

 The second results in a compile-time syntax error so would be caught even
 before the code is reviewed:

   tr.appendChild(td{c1}/tdtd{c2}/tddt{c3}/td/);

 The third becomes a non-issue because you don't need to escape text to
 avoid it from being mistaken for markup [1]:

   var title = I hate /p tags.;
   // ...
   div.innerHTML = pToday's topic is: {title}/p;


 Other proposed solutions include Element.create(), which is less verbose
 than the DOM but still more verbose than innerHTML or E4H; and
 quasistrings, which still suffer from lack of compile-time checking and
 mix markup with data, but at least would be more structured than raw
 strings and could offer better injection protection.


 [1] (This is not the same as auto-escaping strings in other contexts. For
 example, E4H doesn't propose to have CSS literals, so a string embedded in
 a style= attribute wouldn't be automagically safe.)

 --
 Ian Hickson               U+1047E                )\._.,--,'``.    fL
 http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [webcomponents] HTML Parsing and the template element

2012-06-04 Thread Rafael Weinstein
On Mon, Jun 4, 2012 at 3:50 PM, Ian Hickson i...@hixie.ch wrote:
 On Mon, 4 Jun 2012, Tab Atkins Jr. wrote:
 
  [...] We could do this by having the parser insert a fake node into
  the stack of open elements just for this purpose, I think. That is,
  when switching insertion mode in response to the first start tag
  inside the template insertion mode, also insert something into the
  stack so that the next time we reset, we reset correctly. We need to
  do that in a way that doesn't match end tags, though... Maybe we have
  to introduce a new kind of thing we push on the stack, which doesn't
  get matched by anything but the reset algorithm?

 A template context?  Sets the context for the rest of parsing, and
 gets popped by a /template returning to its matching template.

 Yeah, something like that could work. We'd have to make sure we defined it
 as happening when /template was popped, but if we force that to only
 ever happen when we see a literal /template (which the proposal seems
 to, though I haven't verified that) that might work ok.

So the most straight-forward way I saw to approach this (implemented
here: https://bugs.webkit.org/show_bug.cgi?id=86031) was to make the
context element become a stack of context elements.

The idea is that each level of nested template opens a new fragment
parsing context, with a coinciding context element which is initially
unknown.

E.g. from you example above:

template tbody /tbody template /template tr /template

-When the first template element is encountered, the parser switches
into ImpliedContext insertion mode and pushes an unknown element on
the stack of context elements which is associated with the current
template element
-When the tbody is encountered, it replaces the unknown element with
a table context element
-When the inner template is encountered, it pushes another unknown
context element onto the stack of context elements
-When the inner /template is encountered, the template is popped
from the stack of open elements and the unknown element is popped from
the stack of context elements. The reset insertion mode appropriately
algorithm is run -- which now examines the current context element
(associated with the first template which is the current element)
which is table and sets the insertion mode to InTable.



  The proposal here doesn't support SVG (or MathML, but SVG seems more
  important for template). Short of hard-coding a list of SVG
  elements, which seems really bad for forwards compatibility, I don't
  have a good proposal for dealing with this. I suppose we could go back
  to having an attribute on template, this time setting the context at
  a more coarse level of just HTML vs SVG vs MathML; that's more likely
  to be understood by authors than what I was suggesting before (in
  table body, etc).

 It doesn't require any more hard-coding than HTML needs in order to
 create proper elements instead of HTMLUnknownElements.  You have to know
 the list of valid HTML elements to produce a proper DOM, and update that
 as you add more, even if the rest of parser is unchanged. This is the
 same thing, except it needs the list of valid SVG and MathML elements.

 I agree that it's the same. I don't think having a hard-coded list of HTML
 elements is a good thing either, it's got the same forward-compatibility
 problems. Unfortunately in the case of the existing lists we had no choice
 because UAs already had them. Here, we have a choice.

 --
 Ian Hickson               U+1047E                )\._.,--,'``.    fL
 http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Proposal: Document.parse() [AKA: Implied Context Parsing]

2012-05-25 Thread Rafael Weinstein
Ok, so from consensus on earlier threads, here's the full API  semantics.

Now's the time to raise objections to UA's adding support for this feature.

-

1) The Document interface is extended to include a new method:

DocumentFragment parse (DOMString markup);

which:
-Invokes the fragment parsing algorithm with markup and an empty
context element,
-Unmarks all scripts in the returned fragment node as already started
-Returns the fragment node

2) The fragment parsing algorithm's context element is now optional.

It's behavior is similar to the case of a known context element, but
the tokenizer is simply set to the data state

3) Resetting the insertion appropriately now sets the mode to Implied
Context if parsing a fragment and no context element is set, and
aborts.

4) A new Implied Context insertion mode is defined which

-Ignores doctype, end tag tokens
-Handles comment  character tokens as if in body
-Handles the following start tags as if in body (which is as if in
head): style, script, link, meta
-Handles any other start tag by selecting a context element, resetting
the insertion mode appropriately and reprocessing the token.

5) A new selecting a context element algorithm is defined which
takes a start tag as input and outputs an element. The element's
identity is as follows:

-If start tag is tbody, thead, tfoot, caption or colgroup
  return table
-if start tag is tr,
  return tbody
-if start tag is col
  return colgroup
-if start tag is td or td
  return tr
-if start tag is head or body
  return html
-if start tag is rp or rt
  return ruby

-if start tag is a defined SVG localName (case insensitive)
  return svg

-if start tag is a defined MathML localName (case insensitive)
  return math

-otherwise, return body



Re: Proposal: Document.parse() [AKA: Implied Context Parsing]

2012-05-25 Thread Rafael Weinstein
On Fri, May 25, 2012 at 12:32 AM, Simon Pieters sim...@opera.com wrote:
 On Fri, 25 May 2012 09:01:43 +0200, Rafael Weinstein rafa...@google.com
 wrote:

 Ok, so from consensus on earlier threads, here's the full API  semantics.

 Now's the time to raise objections to UA's adding support for this
 feature.

 -

 1) The Document interface is extended to include a new method:

 DocumentFragment parse (DOMString markup);

 which:
 -Invokes the fragment parsing algorithm with markup and an empty
 context element,
 -Unmarks all scripts in the returned fragment node as already started
 -Returns the fragment node

 2) The fragment parsing algorithm's context element is now optional.

 It's behavior is similar to the case of a known context element, but
 the tokenizer is simply set to the data state

 3) Resetting the insertion appropriately now sets the mode to Implied
 Context if parsing a fragment and no context element is set, and
 aborts.

 4) A new Implied Context insertion mode is defined which

 -Ignores doctype, end tag tokens
 -Handles comment  character tokens as if in body
 -Handles the following start tags as if in body (which is as if in
 head): style, script, link, meta
 -Handles any other start tag by selecting a context element, resetting
 the insertion mode appropriately and reprocessing the token.

 5) A new selecting a context element algorithm is defined which
 takes a start tag as input and outputs an element. The element's
 identity is as follows:

 -If start tag is tbody, thead, tfoot, caption or colgroup
  return table
 -if start tag is tr,
  return tbody
 -if start tag is col
  return colgroup
 -if start tag is td or td
  return tr
 -if start tag is head or body
  return html
 -if start tag is rp or rt
  return ruby


 I think ruby is better handled by always making rp and rt generate
 implied end tags in the fragment case (maybe even when parsing normally,
 too). Making the context element ruby still doesn't make rt parse right,
 because the spec currently looks for ruby on the *stack* (and the context
 element isn't on the stack).

 Also, the ruby base is allowed to include markup, so this would fail:

 ruby.appendChild(document.parse('spanfoo/spanrtbarrtbaz'));



 -if start tag is a defined SVG localName (case insensitive)
  return svg


 Except those that conflict with HTML?

Yes. Thank you. Item 5 should be:

5) A new selecting a context element algorithm is defined which
takes a start tag as input and outputs an element. The element's
identity is as follows:

-If start tag is tbody, thead, tfoot, caption or colgroup
 return table
-if start tag is tr,
 return tbody
-if start tag is col
 return colgroup
-if start tag is td or td
 return tr
-if start tag is head or body
 return html
-if start tag is rp or rt
 return ruby

-if start tag is a defined HTML localName (case insensitive)
 return body

-if start tag is a defined SVG localName (case insensitive)
 return svg

-if start tag is a defined MathML localName (case insensitive)
 return math

-otherwise, return body




 -if start tag is a defined MathML localName (case insensitive)
  return math


 (Making the context element svg or math doesn't do anything currently:
 https://www.w3.org/Bugs/Public/show_bug.cgi?id=16635 )

 -otherwise, return body



 --
 Simon Pieters
 Opera Software



Re: Implied Context Parsing (DocumentFragment.innerHTML, or similar) proposal details to be sorted out

2012-05-24 Thread Rafael Weinstein
This seems sensible. I've updated the WebKit patch to do exactly this:

https://bugs.webkit.org/show_bug.cgi?id=84646

It appears that the details of the proposal are now sorted out. I'll
start a new thread describing the full API  semantics.

On Fri, May 18, 2012 at 8:29 PM, Ryosuke Niwa rn...@webkit.org wrote:
 Not that I want to start another bike-shedding, there is one clear
 distinction between innerHTML and createDocumentFragment, which is that
 innerHTML sets already-started flag on parsed script elements
 but createDocumentFragment does not (or rather it unsets it after the
 fragment parsing algorithm has ran).
 See http://html5.org/specs/dom-parsing.html#dom-range-createcontextualfragment

 There appears to be a consensus to use document.parse (which is fine with
 me), so I would like to double-check which behavior we're picking. IMO, the
 only sane choice is to unset the already-started flag since doing otherwise
 implies script elements parsed by document.parse won't be executed when
 inserted into a document.

 While we can change the behavior for template elements, I would rather have
 the same behavior between all 3 APIs (createDocumentFragment, parse, and
 template element) and let innerHTML be the outlier for legacy reasons.

 (Note: I intend to fix the bug in WebKit that already-started flag isn't
 unmarked in createDocumentFragment).

 - Ryosuke




Re: Implied Context Parsing (DocumentFragment.innerHTML, or similar) proposal details to be sorted out

2012-05-17 Thread Rafael Weinstein
On Wed, May 16, 2012 at 4:52 PM, Rafael Weinstein rafa...@google.com wrote:
 On Wed, May 16, 2012 at 4:49 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Wed, May 16, 2012 at 4:29 PM, Rafael Weinstein rafa...@google.com wrote:
 Ok. I think I'm convinced on all points.

 I've uploaded a webkit patch which implements what we've agreed on here:

 https://bugs.webkit.org/show_bug.cgi?id=84646

 I'm happy to report that this patch is nicer than the queued-token
 approach. Good call, Henri.

 On Tue, May 15, 2012 at 9:39 PM, Yehuda Katz wyc...@gmail.com wrote:

 Yehuda Katz
 (ph) 718.877.1325


 On Tue, May 15, 2012 at 6:46 AM, Henri Sivonen hsivo...@iki.fi wrote:

 On Fri, May 11, 2012 at 10:04 PM, Rafael Weinstein rafa...@google.com
 wrote:
  Issue 1: How to handle tokens which precede the first start tag
 
  Options:
  a) Queue them, and then later run them through tree construction once
  the implied context element has been picked
 
  b) Create a new insertion like waiting for context element, which
  probably ignores end tags and doctype and inserts character tokens and
  comments. Once the implied context element is picked, reset the
  insertion mode appropriately, and procede normally.

 I prefer b).


 I like b as well. I assume it means that the waiting for context element
 insertion mode would keep scanning until the ambiguity was resolved, and
 then enter the appropriate insertion mode. Am I misunderstanding?

 I think what Yehuda is getting at here is that there are a handful of
 tags which are allowed to appear anywhere, so it doesn't make sense to
 resolve the ambiguity based on their identity.

 I talked with Tab about this, and happily, that set seems to be
 style, script, meta,  link. Happily, because this means that
 the new ImpliedContext insertion mode can handle start tags as
 follows (code from the above patch)

 if (token.name() == styleTag
    || token.name() == scriptTag
    || token.name() == metaTag
    || token.name() == linkTag) {
    processStartTagForInHead(token); // process following the rules
 for the in head insertion mode
    return;
 }

 m_fragmentContext.setContextTag(getImpliedContextTag(token.name()));
 set the context element
 resetInsertionModeAppropriately(); reset the insertion mode appropriately
 processStartTag(token); // reprocess the token

 So if I understand things correctly, that would mean that:

 document.parse(parsed as textscriptparsed as script
 content/scripttrtdtable content/td/tr);

 would return a fragment like:
 #fragment
  #text parsed as text
  script
    #text parsed as script content
  tr
    td
      #text table content

Note that I added an explicit test case for this:

#data
parse as textscriptparse as
spanscript/span/scripttrtdtable content/td/tr
#errors
#document-fragment
#document
| parse as text
| script
|   parse as spanscript/span
| tr
|   td
| table content



 Is this correct? The important part here is that the contents of the
 script element is parsed according to the rules which normally apply
 when parsing scripts?

 (That of course leaves the terrible situation that script parsing is
 vastly different in HTML and SVG, but that's a bad problem that
 already exists)

 Yes. Exactly.


 / Jonas



Re: Implied Context Parsing (DocumentFragment.innerHTML, or similar) proposal details to be sorted out

2012-05-16 Thread Rafael Weinstein
Ok. I think I'm convinced on all points.

I've uploaded a webkit patch which implements what we've agreed on here:

https://bugs.webkit.org/show_bug.cgi?id=84646

I'm happy to report that this patch is nicer than the queued-token
approach. Good call, Henri.

On Tue, May 15, 2012 at 9:39 PM, Yehuda Katz wyc...@gmail.com wrote:

 Yehuda Katz
 (ph) 718.877.1325


 On Tue, May 15, 2012 at 6:46 AM, Henri Sivonen hsivo...@iki.fi wrote:

 On Fri, May 11, 2012 at 10:04 PM, Rafael Weinstein rafa...@google.com
 wrote:
  Issue 1: How to handle tokens which precede the first start tag
 
  Options:
  a) Queue them, and then later run them through tree construction once
  the implied context element has been picked
 
  b) Create a new insertion like waiting for context element, which
  probably ignores end tags and doctype and inserts character tokens and
  comments. Once the implied context element is picked, reset the
  insertion mode appropriately, and procede normally.

 I prefer b).


 I like b as well. I assume it means that the waiting for context element
 insertion mode would keep scanning until the ambiguity was resolved, and
 then enter the appropriate insertion mode. Am I misunderstanding?

I think what Yehuda is getting at here is that there are a handful of
tags which are allowed to appear anywhere, so it doesn't make sense to
resolve the ambiguity based on their identity.

I talked with Tab about this, and happily, that set seems to be
style, script, meta,  link. Happily, because this means that
the new ImpliedContext insertion mode can handle start tags as
follows (code from the above patch)

if (token.name() == styleTag
|| token.name() == scriptTag
|| token.name() == metaTag
|| token.name() == linkTag) {
processStartTagForInHead(token); // process following the rules
for the in head insertion mode
return;
}

m_fragmentContext.setContextTag(getImpliedContextTag(token.name()));
set the context element
resetInsertionModeAppropriately(); reset the insertion mode appropriately
processStartTag(token); // reprocess the token




 I'm assuming the use case for this stuff isn't that authors throw
 random stuff at the API and then insert the result somewhere. I expect
 authors to pass string literals or somewhat cooked string literals to
 the API knowing where they're going to insert the result but not
 telling the insertion point to the API as a matter of convenience.

 If you know you are planning to insert stuff as a child of tbody,
 don't start your string literal with stuff that would tokenize as
 characters!

 (Firefox currently does not have the capability to queue tokens.
 Speculative parsing in Firefox is not based on queuing tokens. See
 https://developer.mozilla.org/en/Gecko/HTML_parser_threading for the
 details.)

  Issue 2: How to infer a non-HTML implied context element
 
  Options:
  a) By tagName alone. When multiple namespaces match, prefer HTML, and
  then either SVG or MathML (possibly on a per-tagName basis)
 
  b) Also inspect attributes for tagNames which may be in multiple
  namespaces

 AFAICT, the case where this really matters (if my assumptions about
 use cases are right) is a. (Fragment parsing makes scripts useless
 anyway by setting their already started flag, authors probably
 shouldn't be adding styles by parsing style, both HTML and SVG
 font are considered harmful and cross-browser support Content MathML
 is far off in the horizon.)

 So I prefer a) possibly with a-specific elaborations if we can come
 up with some. Generic solutions seem to involve more complexity. For
 example, if we supported a generic attribute for forcing SVG
 interpretation, would it put us on a slippery slope to support it when
 it appears on tokens that aren't the first start tag token in a
 contextless fragment parse?

  Issue 3: What form does the API take
 
  a) Document.innerHTML
 
  b) document.parse()
 
  c) document.createDocumentFragment()

 I prefer b) because:
  * It doesn't involve creating the fragment as a separate step.
  * It doesn't need to be foolishly consistent with the HTML vs. XML
 design errors of innerHTML.
  * It's shorted than document.createDocumentFragment().
  * Unlike innerHTML, it is a method, so we can add more arguments
 later (or right away) to refine its behavior.

 --
 Henri Sivonen
 hsivo...@iki.fi
 http://hsivonen.iki.fi/





Re: Implied Context Parsing (DocumentFragment.innerHTML, or similar) proposal details to be sorted out

2012-05-16 Thread Rafael Weinstein
On Wed, May 16, 2012 at 4:49 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Wed, May 16, 2012 at 4:29 PM, Rafael Weinstein rafa...@google.com wrote:
 Ok. I think I'm convinced on all points.

 I've uploaded a webkit patch which implements what we've agreed on here:

 https://bugs.webkit.org/show_bug.cgi?id=84646

 I'm happy to report that this patch is nicer than the queued-token
 approach. Good call, Henri.

 On Tue, May 15, 2012 at 9:39 PM, Yehuda Katz wyc...@gmail.com wrote:

 Yehuda Katz
 (ph) 718.877.1325


 On Tue, May 15, 2012 at 6:46 AM, Henri Sivonen hsivo...@iki.fi wrote:

 On Fri, May 11, 2012 at 10:04 PM, Rafael Weinstein rafa...@google.com
 wrote:
  Issue 1: How to handle tokens which precede the first start tag
 
  Options:
  a) Queue them, and then later run them through tree construction once
  the implied context element has been picked
 
  b) Create a new insertion like waiting for context element, which
  probably ignores end tags and doctype and inserts character tokens and
  comments. Once the implied context element is picked, reset the
  insertion mode appropriately, and procede normally.

 I prefer b).


 I like b as well. I assume it means that the waiting for context element
 insertion mode would keep scanning until the ambiguity was resolved, and
 then enter the appropriate insertion mode. Am I misunderstanding?

 I think what Yehuda is getting at here is that there are a handful of
 tags which are allowed to appear anywhere, so it doesn't make sense to
 resolve the ambiguity based on their identity.

 I talked with Tab about this, and happily, that set seems to be
 style, script, meta,  link. Happily, because this means that
 the new ImpliedContext insertion mode can handle start tags as
 follows (code from the above patch)

 if (token.name() == styleTag
    || token.name() == scriptTag
    || token.name() == metaTag
    || token.name() == linkTag) {
    processStartTagForInHead(token); // process following the rules
 for the in head insertion mode
    return;
 }

 m_fragmentContext.setContextTag(getImpliedContextTag(token.name()));
 set the context element
 resetInsertionModeAppropriately(); reset the insertion mode appropriately
 processStartTag(token); // reprocess the token

 So if I understand things correctly, that would mean that:

 document.parse(parsed as textscriptparsed as script
 content/scripttrtdtable content/td/tr);

 would return a fragment like:
 #fragment
  #text parsed as text
  script
    #text parsed as script content
  tr
    td
      #text table content

 Is this correct? The important part here is that the contents of the
 script element is parsed according to the rules which normally apply
 when parsing scripts?

 (That of course leaves the terrible situation that script parsing is
 vastly different in HTML and SVG, but that's a bad problem that
 already exists)

Yes. Exactly.


 / Jonas



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-05-11 Thread Rafael Weinstein
On Fri, May 11, 2012 at 12:13 AM, Ojan Vafai o...@chromium.org wrote:
 On Thu, May 10, 2012 at 9:28 PM, Rafael Weinstein rafa...@google.com
 wrote:

 On Thu, May 10, 2012 at 4:19 PM, Ian Hickson i...@hixie.ch wrote:
  On Thu, 10 May 2012, Rafael Weinstein wrote:
  On Thu, May 10, 2012 at 4:01 PM, Ian Hickson i...@hixie.ch wrote:
   On Fri, 11 May 2012, Tab Atkins Jr. wrote:
  
   But ok, let's assume that the use case is create an element and its
   subtree so that you can insert dynamically generated parts of an
   application during runtime, e.g. inserting images in a dynamically
   generated gallery [...]
 
  [...[ but here's one that comes to mind which is valid markup: What's
  the output for this
 
  myDocFrag.innerHTML = optionOneoptiontwooptionthree;
 
  My proposal would return a single option element with the value One.
 
  But the example here suggests a different use case. There are presumably
  three elements there, not one. If this is a use case we want to address,
  then let's go back to the use cases again: what is the problem we are
  trying to solve? When would you create a document fragment of some
  options, instead of just creating a select with options?

 BTW, for example

 In handlerbars,

 select
  {{# each optionListThatComeInPairs }}
    option{{ firstThingInPair }}
    option{{ secondThingInPair }}
  {{/ each }}
 /select

 Or equivalently, in MDV

 select
  template iterate=optionsListThatComeInPairs
    option{{ firstThingInPair }}
    option{{ secondThingInPair }}
  /template
 /select


 To clarify, this doesn't suffer from the string concatenation problem that
 Ian was worried about, right? {{ firstThingInPair }} is inserted as a
 string, not HTML, right? Similarly, if you had 'data-foo={{ attributeValue
 }}', it would be escaped appropriately so as to avoid any possibility of
 XSS?

Correct. In the first example, handlebars will escape the script
before doing innerHTML, and MDV doesn't invoke the parser, it assigns
the Text node's textContent.


 Ojan



Re: History Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-05-11 Thread Rafael Weinstein
It was wrong for me to editorialize about SVG and MathML -- and
punish was very poor word choice. I apologize to anyone who was
insulted. It certainly wasn't my intent.

I should have just said that I'm frustrated with the world we've
arrived in WRT HTML vs XML and left it at that.

On Fri, May 11, 2012 at 3:07 AM, Charles McCathieNevile
cha...@opera.com wrote:
 On Fri, 11 May 2012 10:55:27 +0200, Henri Sivonen hsivo...@iki.fi wrote:

 On Wed, May 9, 2012 at 7:45 PM, Rafael Weinstein rafa...@google.com
 wrote:

 I'm very much of a like mike with Henri here, in that I'm frustrated
 with the situation we're currently in WRT SVG  MathML  parsing
 foreign content in HTML, etc... In particular, I'm tempted to feel
 like SVG and MathML made this bed for themselves and they should now
 have to sleep in it.


 I think that characterization is unfair to MathML.  The math working
 group tried hard to avoid local name collisions with HTML.  They
 didn't want to play namespace games.  As I understand it, they were
 forced into a different namespace by W3C strategy tax arising from the
 NAMESPACE ALL THE THINGS! attitude.


 Actually, I think even that is an unfair characterisation. At the time both
 these technologies were developed (mid-late 90s) everyone assumed that XML
 was the path of the future for everything, and that de-crentralised
 extensibility was a critical requirement for a powerful web platform.

 Given that scenario, it is unclear whether there is a better approach. The
 current HTML approach of if it is important it will get into the mainline
 spec effectively breaks the key extensibility assumption. Leading
 implementors like Adobe, SodiPodi and Inkscape all introduced namespaced
 content all over the SVG map - in many cases doing things that active SVG WG
 members thought were excessive. Likewise Microsoft Office (at the time
 probably as widespread as web browsers in general) introduced namespaced
 content all over HTML (IE didn't support XHTML).

 Seven years later, both of those assumptions came under attack from the
 nascent WHAT-WG approach to updating HTML - but unlike the case for HTML,
 where the market leader had clearly resisted implementing XHTML, SVG in
 particular was backed by a number of XML-happy engines. It was several more
 years before SVG and MathML were incorporated into HTML in a way that
 clearly made sense.

 Punishing people, or even ridiculing them, for using XML in the late 90s,
 seems counter-productive at best. Outside HTML even Microsoft - who were one
 of the big creative forces behind XML - were pushing it everywhere, it was
 considered de riguer for making the mobile web a possibility outside Opera
 (which supported it anyway, but didn't require it), and it had, and still
 has, huge deployment. It just failed on the web browser platform, for
 reasons that are far easier to see in hindsight than they were at the time.

 cheers

 Chaals

 --
 Charles 'chaals' McCathieNevile  Opera Software, Standards Group
    je parle français -- hablo español -- jeg kan noen norsk
 http://my.opera.com/chaals       Try Opera: http://www.opera.com



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-05-11 Thread Rafael Weinstein
It feels like we're making progress here. It seems as though there are
basically two camps:

1) We shouldn't attempt to solve this problem. E.g. an explicit
context element should be required for fragment parsing.
2) The basic idea of inferring a context element is workable and there
are details to be worked out.

I suggest that we suspend for a bit the question of camp 1 vs 2 and
just focus on the best possible (i.e. mutually agreeable) solution for
camp 2. It goes without saying, that I'd really appreciate feedback in
this direction from folks who are in camp #1 -- I'm looking at you,
Hixie -- even if you hate this idea, you still have to help =-P.

Once we have a complete proposal written down, then we can decide
whether it's worth doing or not.

Now, WRT camp #2, there seem to be three issues to resolve

1) What is done with tokens which precede the first start tag?
2) What is the mechanism (if any) for handling SVG  MathML elements?
3) What is the form of the API (e.g. DocumentFragment.innerHTML,
document.parse(), etc...).

I'm actually encouraged because, while I have preferences WRT the
above, I think all the permutations would solve the use cases we have.

I'll start a new thread whose purpose is to sort out an agreeable
proposal for the behavior of camp #2.

On Fri, May 11, 2012 at 5:39 AM, Scott González
scott.gonza...@gmail.com wrote:
 On Fri, May 11, 2012 at 7:13 AM, Henri Sivonen hsivo...@iki.fi wrote:

 However, I'm not strongly opposed to adding innerHTML to
 DocumentFragment if we also add a method on Document that parses a
 string using the HTML parser regardless of the HTMLness flag of the
 document and returns a DocumentFragment (or has an optional extra
 argument for forcing XML parsing explicitly).


 Just a side note, but at least parsing XML seems to be fairly sane today. I
 haven't really done any testing around this, but it seems like this would
 get you parsing of arbitrary XML fragments, including leading and trailing
 text nodes:

 (new DOMParser).parseFromString( x + string + /x, text/xml
 ).documentElement.childNodes

 Obviously this is overly verbose compared to document.parse( string, flag ).



Implied Context Parsing (DocumentFragment.innerHTML, or similar) proposal details to be sorted out

2012-05-11 Thread Rafael Weinstein
Ok,

So from the previous threads, there are appear to be three issues to
resolve, and I'll list the options that I've noted.

I'll follow up with my perspective of pros/cons and ask others to do
the same. Please point out options or issues that I've missed.


Issue 1: How to handle tokens which precede the first start tag

Options:
a) Queue them, and then later run them through tree construction once
the implied context element has been picked

b) Create a new insertion like waiting for context element, which
probably ignores end tags and doctype and inserts character tokens and
comments. Once the implied context element is picked, reset the
insertion mode appropriately, and procede normally.


---
Issue 2: How to infer a non-HTML implied context element

Options:
a) By tagName alone. When multiple namespaces match, prefer HTML, and
then either SVG or MathML (possibly on a per-tagName basis)

b) Also inspect attributes for tagNames which may be in multiple namespaces

c) Allow for inline name spacing of elements which would normally
inherit the proper namespace from svg or math

d) Somewhat orthogonal, but later allow for template to have an
optional context attribute (e.g. template context=svg), which
explicitly picks a context element.

e) Some combination of the above.

---
Issue 3: What form does the API take

a) Document.innerHTML

b) document.parse()

c) document.createDocumentFragment()



Re: Implied Context Parsing (DocumentFragment.innerHTML, or similar) proposal details to be sorted out

2012-05-11 Thread Rafael Weinstein
Ok, so I have some preferences, but they are *mild* preferences and
any permutation of the options below is acceptable to me.

On Fri, May 11, 2012 at 12:04 PM, Rafael Weinstein rafa...@google.com wrote:
 Ok,

 So from the previous threads, there are appear to be three issues to
 resolve, and I'll list the options that I've noted.

 I'll follow up with my perspective of pros/cons and ask others to do
 the same. Please point out options or issues that I've missed.

 
 Issue 1: How to handle tokens which precede the first start tag

 Options:
 a) Queue them, and then later run them through tree construction once
 the implied context element has been picked

I like option (a) because you always get identical output for any
input relative to if you had applied it via innerHTML to the
appropriate implied context element. E.g.

myHTMLElement.innerHTML = foobodybar;
myDocumentFragment.innerHTML = foobodybar;

myHTMLElement.innerHTML == myDocumentFragment.innerHTML; // true;

Also, most browsers are already speculatively tokenizing ahead for
resource preloading purposes, so the implementation complexity isn't
especially daunting.


 b) Create a new insertion like waiting for context element, which
 probably ignores end tags and doctype and inserts character tokens and
 comments. Once the implied context element is picked, reset the
 insertion mode appropriately, and procede normally.


 ---
 Issue 2: How to infer a non-HTML implied context element

 Options:
 a) By tagName alone. When multiple namespaces match, prefer HTML, and
 then either SVG or MathML (possibly on a per-tagName basis)

 b) Also inspect attributes for tagNames which may be in multiple namespaces

 c) Allow for inline name spacing of elements which would normally
 inherit the proper namespace from svg or math

 d) Somewhat orthogonal, but later allow for template to have an
 optional context attribute (e.g. template context=svg), which
 explicitly picks a context element.

 e) Some combination of the above.

I have a mild preference for not getting to fancy here. I'll mostly
stay out of this and let those who know more about SVG and MathML sort
it out, but I'll just note that the main concern cited for needing
this to work is with web components, and there I think Hixie's idea of
a declarative context element (e.g. option (d)) above is a nice
addition and might alleviate the need to get fancy.


 ---
 Issue 3: What form does the API take

 a) Document.innerHTML

 b) document.parse()

 c) document.createDocumentFragment()

I'm torn here between (a)  (b). I like the familiarity of (a), but
agree with Henri's point of about the namespace of the owner document
being a downside. I don't like (c) for stylistic reasons.



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-05-10 Thread Rafael Weinstein
On Thu, May 10, 2012 at 4:01 PM, Ian Hickson i...@hixie.ch wrote:
 On Fri, 11 May 2012, Tab Atkins Jr. wrote:

 The innerHTML API is convenient.  It lets you set the entire descendant
 tree of an element, creating elements and giving them attributes, in a
 single call, using the same syntax you'd use if you were writing it in
 HTML (module some extra quote-escaping maybe).

 [...]

 I'll go ahead and anticipate your response of they should just use the
 Element.create() API

 That would indeed be my response.


 while Element.create() is great, it solves a different use-case.  Being
 able to construct DOM from raw HTML is easy to read and write and
 understand, particularly when it's a static fragment (or a concatenation
 of mostly static fragments), while Element.create() requires a
 translation into a JS API with a much different syntax. Element.create()
 is much more readable and writable when you're making some DOM out of a
 *lot* of dynamic information.

 In other words, this:

 $(div class=fooimg src=+foosrc+/div)

 is a lot easier than:

 Element.create(div, {class: foo}, [ Element.create(img, {src: foosrc}) 
 ]);

 So, that's the use-case for this API.

 The idea of building elements using string concatenation is a security
 disaster. What if foosrc above contains ' onclick=...' ?

 But ok, let's assume that the use case is create an element and its
 subtree so that you can insert dynamically generated parts of an
 application during runtime, e.g. inserting images in a dynamically
 generated gallery, and security by damned.

 If we're going to do that, then we don't need any lookahead at all. We
 should support literally that: parsing one element and its descendants. We
 determine what element is being generatd by looking at the top of the
 string (div ... - it's a div, tr ... - it's a tr, etc), and we
 parse until that element is popped from the stack or the end of the string
 is reached. This avoids all the problems with doing magical lookahead.

This was more or less Yehuda's original proposal. If we can make this
work, I think it also solves the problem and would be acceptable. My
sense is that this solution probably introduces more complexity into
the parser and it's output isn't any superior.

Anne pointed out that accomplishing this isn't straightforward. I
forget what his examples were (I think they had to do with poorly
formed markup), but here's one that comes to mind which is valid
markup: What's the output for this

myDocFrag.innerHTML = optionOneoptiontwooptionthree;



 But I'm very skeptical about creating new APIs to encourage authors to use
 injection-prone, non-type-checked, direct string manipulation in script to
 generate DOM trees.

 --
 Ian Hickson               U+1047E                )\._.,--,'``.    fL
 http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-05-10 Thread Rafael Weinstein
On Thu, May 10, 2012 at 4:27 PM, Scott González
scott.gonza...@gmail.com wrote:
 On Thu, May 10, 2012 at 7:15 PM, Rafael Weinstein rafa...@google.com
 wrote:

 On Thu, May 10, 2012 at 4:01 PM, Ian Hickson i...@hixie.ch wrote:
  If we're going to do that, then we don't need any lookahead at all. We
  should support literally that: parsing one element and its descendants.
  We
  determine what element is being generatd by looking at the top of the
  string (div ... - it's a div, tr ... - it's a tr, etc), and we
  parse until that element is popped from the stack or the end of the
  string
  is reached. This avoids all the problems with doing magical lookahead.

 This was more or less Yehuda's original proposal. If we can make this
 work, I think it also solves the problem and would be acceptable. My
 sense is that this solution probably introduces more complexity into
 the parser and it's output isn't any superior.


 Yehuda has actually been complaining about this limitation for quite a
 while. I know that he would not consider this a full solution.

Ah, sorry. I didn't quite understand Hixie's proposal. I retract my
statement -- this isn't a workable solution.

Also, I'm curious why it's ok to peak at the first few characters of
the string, and not ok to peak at the token stream until we see the
first start tag?



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-05-10 Thread Rafael Weinstein
On Thu, May 10, 2012 at 4:58 PM, Ian Hickson i...@hixie.ch wrote:
 On Thu, 10 May 2012, Rafael Weinstein wrote:

 Also, I'm curious why it's ok to peak at the first few characters of the
 string, and not ok to peak at the token stream until we see the first
 start tag?

 Because it's predictable and easy to debug. When you're dealing with a
 weird effect caused by some accidental markup hundreds of lines down a
 string, it's really hard to work out what's going on. When the effect is
 caused by the very first thing in the string, it's much easier to notice
 it. (You see this kind problem sometimes on Web pages where text/plain
 files are sent as text/html, or text files are slightly augmented with
 HTML without properly escaping everything -- they render fine until they
 get to something that accidentally looks like markup, and the parser does
 its stuff, and you wonder why half of the 100-page document is bold.)

In the abstract, I actually agree with you, but this happens to be a
case when this is effectively never going to be a problem. Just have a
look at *any* templating langauge. Any time you see some kind of
conditional, or loop construct, look at it's contents and imagine that
that's what'll be passed to innerHTML here.

99.9% of the time it's going to either be all character tokens, or
whitespace followed by a start tag.

You're letting an non-existent problem kill a perfectly useful proposal.

I'm not a huge fan of everything jQuery does either, but regardless of
it's objective goodness, it has already done the test by offering
this functionality. The kind of bug your describing hasn't been
observed at all. Someone with more jQuery-cred correct me if I'm
wrong.


 --
 Ian Hickson               U+1047E                )\._.,--,'``.    fL
 http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-05-10 Thread Rafael Weinstein
On Thu, May 10, 2012 at 5:03 PM, Ian Hickson i...@hixie.ch wrote:
 On Fri, 11 May 2012, Tab Atkins Jr. wrote:

 For something like this:

 $(pExample +exnum+:/ppimg src=+exsrc+).appendTo(container);

 Can we really not come up with anything better? It makes me really sad to
 think that the best we can do here is to go from a nice structured
 environment, concatenate our data together into a string, and then reparse
 the string back into structured data to add it to the DOM.

 I understand that people do this kind of thing all the time, but I've
 always at least assumed that everyone agreed that it was a necessarily
 evil because the alternatives were even worse. I had hope when we were
 discussing Element.create() that maybe we were finally coming up with a
 workable alternative, but as far as I can tell that never went anywhere
 and now we're actually talking about adding APIs to _support_ string-based
 DOM tree generation as if it's an actually sane way of writing code.

 Am I really the only one here who thinks this is horrifying?

I find it horrifying, and I'll venture that Yehuda and the author of
every other templating mechanism does as well -- at least in the sense
that all of our goal is to generally remove the *need* for page
authors to have to use innerHTML, by declaring how their views should
be composed, rather than doing it imperatively.

Libraries exist at a higher leverage point and if *they* do the right
thing, then a greater number of authors are protected. Adding this,
makes it easier for libraries (and if I get my way, the platform
itself) to do this right so that authors can stop constructing DOM
imperatively altogether.


 --
 Ian Hickson               U+1047E                )\._.,--,'``.    fL
 http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-05-10 Thread Rafael Weinstein
On Thu, May 10, 2012 at 4:19 PM, Ian Hickson i...@hixie.ch wrote:
 On Thu, 10 May 2012, Rafael Weinstein wrote:
 On Thu, May 10, 2012 at 4:01 PM, Ian Hickson i...@hixie.ch wrote:
  On Fri, 11 May 2012, Tab Atkins Jr. wrote:
 
  But ok, let's assume that the use case is create an element and its
  subtree so that you can insert dynamically generated parts of an
  application during runtime, e.g. inserting images in a dynamically
  generated gallery [...]

 [...[ but here's one that comes to mind which is valid markup: What's
 the output for this

 myDocFrag.innerHTML = optionOneoptiontwooptionthree;

 My proposal would return a single option element with the value One.

 But the example here suggests a different use case. There are presumably
 three elements there, not one. If this is a use case we want to address,
 then let's go back to the use cases again: what is the problem we are
 trying to solve? When would you create a document fragment of some
 options, instead of just creating a select with options?

BTW, for example

In handlerbars,

select
  {{# each optionListThatComeInPairs }}
option{{ firstThingInPair }}
option{{ secondThingInPair }}
  {{/ each }}
/select

Or equivalently, in MDV

select
  template iterate=optionsListThatComeInPairs
option{{ firstThingInPair }}
option{{ secondThingInPair }}
  /template
/select


 --
 Ian Hickson               U+1047E                )\._.,--,'``.    fL
 http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-05-09 Thread Rafael Weinstein
I'm very much of a like mike with Henri here, in that I'm frustrated
with the situation we're currently in WRT SVG  MathML  parsing
foreign content in HTML, etc... In particular, I'm tempted to feel
like SVG and MathML made this bed for themselves and they should now
have to sleep in it.

However, on balance, I'm in favor of this magic (picking the correct
namespace based on the first element's tagName) for the following
three reasons:

*Not doing so means that using template to declare web components
that do super awesome SVG stuff much more cumbersome.

*Doing so doesn't negatively impact HTML.

*SVG mostly working (modulo a few overlapping tagNames), is preferable
to not working at all (and there's not really a problem with MathML).

Much as I dislike it, parsing foreign content is kind of already gross
magic, and it seems to me like this behavior is in keeping with what's
already there. Moreover, not including it kind of punishes the wrong
people, by making webdevs sleep in the bed that SVG and MathML made.
I.e. It would make my life easier, but at the expense of webdevs.

On Wed, May 9, 2012 at 12:52 AM, Henri Sivonen hsivo...@iki.fi wrote:
 On Tue, Apr 24, 2012 at 6:39 AM, Rafael Weinstein rafa...@google.com wrote:
 What doesn't appear to be controversial is the parser changes which
 would allow the template element to have arbitrary top-level content
 elements.

 It's not controversial as long as an HTML context is assumed.  I think
 it is still controversial for SVG and MathML elements that aren't
 wrapped in an svg or math element.

 I'd like to propose that we add DocumentFragment.innerHTML which
 parses markup into elements without a context element.

 Why should the programmer first create a document fragment and then
 set a property on it? Why not introduce four methods on Document that
 return a DocumentFragment: document.parseFragmentHTML (parses like
 template.innerHTML), document.parseFragementSVG (parses like
 svg.innerHTML), document.parseFragmentMathML (parses like
 math.innerHTML) and document.parseFragmentXML (parses like innerHTML
 in the XML mode without namespace context)? This would avoid magic for
 distinguishing HTML a and SVG a.

 On Thu, Apr 26, 2012 at 8:23 PM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 (In my dreams, we just merge SVG into the HTML namespace, and then
 this step disappears.)

 In retrospect, it would have been great if Namespaces in XML had never
 been introduced and SVG, MathML and HTML shared a single namespace.
 However, at this point trying to merge the namespaces would lead to
 chameleon namespaces which are evil and more trouble than fixing the
 historical mistake is worth.  I feel very strongly that vendors and
 the W3C should stay away from turning SVG into a chameleon namespace.
 SVG is way more established them CSS gradients or Flexbox in terms of
 what kind of changes are acceptable.

 See http://lists.w3.org/Archives/Public/www-archive/2009Feb/0065.html
 as well as various XML experiences from non-browser contexts.

 --
 Henri Sivonen
 hsivo...@iki.fi
 http://hsivonen.iki.fi/



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-05-09 Thread Rafael Weinstein
On Wed, May 9, 2012 at 12:51 PM, Ian Hickson i...@hixie.ch wrote:
 On Wed, 9 May 2012, Jonas Sicking wrote:

 I think having to provide a context every wherewhere you want to
 parse HTML is creating very bad developer ergonomics.

 You wouldn't have to provide it everywhere. The vast majority of the time,
 the default body context is fine.

But the whole point of DocumentFragment.innerHTML is that you'd need
to inspect the markup in order to know the context fragment. body
may be fine 98%, but the use cases that motivated this feature need to
know 100% of the time if it needs to be something else.



 I think the proposals here, and the fact that jQuery has implemented
 context-free HTML parsing, proves that it is technically possible.

 I don't think look-ahead and magically determining the parse mode from a
 preparse of the string is really a sane solution. It doesn't handle all
 cases (e.g. it doesn't handle the style example I gave), and it results
 in very weird results (very bad developer ergonomics) for cases like
 1GB of text followed by caption vs 1GB of text followed by coption
 (where the former loses the text and the latter does not).

For me, both of these examples fall squarely in the I can live with
that bucket. I'll try again to persuade everyone that we not let
perfect be the enemy of good. =-)


 --
 Ian Hickson               U+1047E                )\._.,--,'``.    fL
 http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-05-09 Thread Rafael Weinstein
On Wed, May 9, 2012 at 1:32 PM, Rafael Weinstein rafa...@google.com wrote:
 On Wed, May 9, 2012 at 12:51 PM, Ian Hickson i...@hixie.ch wrote:
 On Wed, 9 May 2012, Jonas Sicking wrote:

 I think having to provide a context every wherewhere you want to
 parse HTML is creating very bad developer ergonomics.

 You wouldn't have to provide it everywhere. The vast majority of the time,
 the default body context is fine.

 But the whole point of DocumentFragment.innerHTML is that you'd need
 to inspect the markup in order to know the context fragment. body
 may be fine 98%, but the use cases that motivated this feature need to
 know 100% of the time if it needs to be something else.



 I think the proposals here, and the fact that jQuery has implemented
 context-free HTML parsing, proves that it is technically possible.

 I don't think look-ahead and magically determining the parse mode from a
 preparse of the string is really a sane solution. It doesn't handle all
 cases (e.g. it doesn't handle the style example I gave), and it results
 in very weird results (very bad developer ergonomics) for cases like
 1GB of text followed by caption vs 1GB of text followed by coption
 (where the former loses the text and the latter does not).

BTW, This does not appear to be the case in webkit, gecko or IE8.

t = document.createElement('table');

neither of

t.innerHTML = 'foocaptionbar/caption'
t.innerHTML = 'foocoptionbar/coption

discard foo.


 For me, both of these examples fall squarely in the I can live with
 that bucket. I'll try again to persuade everyone that we not let
 perfect be the enemy of good. =-)


 --
 Ian Hickson               U+1047E                )\._.,--,'``.    fL
 http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [webcomponents] Custom Elements Spec

2012-05-07 Thread Rafael Weinstein
Is it worth separating the issues of fallback behavior and extracting
element semantics?

It strikes me as unlikely that in practice components *can* be used if
you need to target legacy browsers, and that fallback won't mean much
unless legacy browsers are specifically targeted because proper
behavior will involve different control flow paths (hooking up the
right events, etc..).

Sorry, if I'm making a leap here or just being stupid. It seems like
if you remove the legacy UAs issue, it opens up a bunch of other
options for extracting semantics (e.g. for indexing or accessibility).

On Fri, May 4, 2012 at 12:29 PM, Ian Hickson i...@hixie.ch wrote:
 On Fri, 4 May 2012, Marat Tanalin | tanalin.com wrote:
 
  So what happens in browsers that don't support components? Or in
  search engines or other data analysis tools that are trying to extract
  the semantics from the page?

 Elements with custom tag-names would have EXACTLY SAME semantic (as for
 core HTML5 semantics) meaning as a common container (SPAN or DIV) with a
 class. No more and no less.

 If it's purely stylistic, then using div and not having semantics is
 fine. Stylistic components should just be invoked from the CSS layer.

 Components that are not purely stylistic, e,g, things like form controls
 or data (tables or graphical), need to have fallback semantics. Those are
 the ones that appear in the markup.

 --
 Ian Hickson               U+1047E                )\._.,--,'``.    fL
 http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'




Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-04-30 Thread Rafael Weinstein
On Thu, Apr 26, 2012 at 1:33 AM, Anne van Kesteren ann...@opera.com wrote:
 On Thu, 26 Apr 2012 10:05:28 +0200, Ryosuke Niwa rn...@webkit.org wrote:

 Also, I think Anne convinced me that it's better to deduce the insertion
 mode from the first element than inventing a new insertion mode (I've
 asked him to post his reasoning).


 1) You cannot look at various elements and make a decision. E.g. if your
 first element is plaintext there will not be any other elements.

 2) Defining a new top-level insertion mode while retaining compatible
 behavior might be an interesting exercise in parser complexity, but it's not
 clear there is a benefit (use cases?) and feasibility has not been
 demonstrated (consider handling ptdp, trptd, ...). The more we
 can define in terms of the existing parser, the better it is for developers.
 The behavior will be more predictable and there will be less quirks to
 learn.

 FWIW, https://www.w3.org/Bugs/Public/show_bug.cgi?id=14694 is the bug on the

I've updated this bug with the current proposal.

 DOM Parsing spec, I don't think there's a bug on the HTML spec (other than
 https://www.w3.org/Bugs/Public/show_bug.cgi?id=16635 for SVG/MathML), but I

There aren't any parser changes required. DocumentFragment.innerHTML
can still provide the fragment case with a context element and
procede normally. It's not obvious to me what bug to open against
HTML.

Anne, can we move forward with this?

Also, note that a webkit patch which implements implied context is
here: https://bugs.webkit.org/show_bug.cgi?id=84646

 might be mistaken.


 --
 Anne van Kesteren
 http://annevankesteren.nl/



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-04-30 Thread Rafael Weinstein
On Mon, Apr 30, 2012 at 6:51 PM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 On Mon, Apr 30, 2012 at 5:43 PM, Anne van Kesteren ann...@opera.com wrote:
 I personally think it would be better if HTML kept defining all entry points
 to the HTML parser. And at least conceptually this is a new insertion mode I
 think contrary to what you suggest in
 http://lists.w3.org/Archives/Public/public-webapps/2012AprJun/0334.html as
 only insertion modes handle emitted tokens. And although I guess it does not
 matter here for now, given that the tree builder can change the behavior of
 the tokenizer decoupling them seems rather odd to me.

 This is simply invoking the fragment parsing algorithm that's already
 defined in DOMParsing, but intelligently supplying a context element.
 There's no need to worry about emitting tokens or anything, except
 insofar as DOMParsing already has to worry about that.

I think Anne's concern is that in order to find the first start tag,
the tokenizer must be used. In this case, the tokenizer would be used
absent of a parser. I'm actually ok with that because the tokenizer is
not a risk of changing states (it starts in the DATA state and stops
searching on the first start tag, so for this use it can't change
state), but I understand the conceptual novelty.

We can put this in the parser spec, but I'm not yet convinced it
deserves a new insertion mode. UA's may implement it that way, so as
to avoid duplication of some tokenization work, but it seems cleaner
to describe it as running the tokenizer to look ahead to the first
start tag.


 The Any other * tagName design also seems somewhat fragile to me. I think
 those lists need to be explicit and coordinated. We should at least put some
 checks in place to make sure we are not introducing more overlapping element
 names in the future.

 I'm fine with that, as long as implementations are okay with updating
 their lists of elements as the underlying languages (SVG and MathML)
 change.  This *will* potentially cause a behavior difference, as
 elements that previously parsed as HTMLUnknownElement instead parse as
 some specific SVG or MathML element.

 ~TJ



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-04-26 Thread Rafael Weinstein
Henri,

Does this address the concerns you raised earlier?

On Thu, Apr 26, 2012 at 10:23 AM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 On Thu, Apr 26, 2012 at 1:26 AM, Simon Pieters sim...@opera.com wrote:
 On Wed, 25 Apr 2012 21:39:53 +0200, Rafael Weinstein rafa...@google.com
 wrote:
 Any other HTML tagName = HTMLBodyElement

 Isn't this one redundant with the last step?

 No, this captures known HTML tagnames, so that HTML can lay claim on
 the few tags that overlap with SVG.  The last step just captures any
 remaining tags that fell through the cracks, so they can become
 HTMLUnknownElements.


 Any other SVG tagName = SVGElement
 Any other MathML tagName = MathElement

 What are these two, exactly? The parser currently doesn't have a list of
 SVG/MathML tag names, and the SVG WG didn't like it when it was proposed to
 use a fixed list of SVG tag names for parsing SVG in text/html, IIRC.

 We don't need a specific list in the spec, but each browser would need
 one, constructed from whatever elements they currently understand.

 (In my dreams, we just merge SVG into the HTML namespace, and then
 this step disappears.)


 Also note that innerHTML on non-HTML elements currently always parses in the
 in body insertion mode. I'd like to see that fixed before we try to
 support foreign content in contextless innerHTML.

 https://www.w3.org/Bugs/Public/show_bug.cgi?id=16635

 Yes, that needs to be fixed.  As Ms2ger said yesterday in IRC, the
 DOMParsing spec already handles this appropriately, but HTML needs a a
 fix, since the former hooks into the latter.

 ~TJ



Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-04-25 Thread Rafael Weinstein
Ok, so from the thread that Yehuda started last year,

There seem to be three issues:

1) Interop (e.g. WRT IE)
2) Defining the behavior for all elements
3) HTML vs SVG vs MathML

I think what Yehuda outlined earlier is basically right, and I have a
proposal which accomplishes everything he wants in a different way and
also addresses the three concerns above. My approach here is to not
let perfect be the enemy of good.

DocumentFragment.innerHTML has the following behavior. It picks an
*implied context element* based on the tagName of the first start tag
token which appears in the html provided. It then operates per the
fragment case of the spec, using the implied context element as the
context element.

Here's the approach for picking the implied context element:

Let the first start tag token imply the context element. The start tag
= implied context element is as follows:

caption, colgroup, thead, tbody, tfoot = HTMLTableElement
tr = HTMLTableBodyElement
col = HTMLColGroupElement
td, th = HTMLTableRowElement
head, body = HTMLHTMLElement
rp, rt = HTMLRubyElement
Any other HTML tagName = HTMLBodyElement
Any other SVG tagName = SVGElement
Any other MathML tagName = MathElement
Any other tagName = HTMLBodyElement

Note a few things about this:

*Because this is basically a pre-processing step to the existing
fragment case, the changes to the parser spec are purely additive (no
new insertion modes or other parser changes needed).

*It addresses (1) by only adding new parsing behavior to new API
(implicitly retaining compat)

*It explains (2)

*The only problem with (3) is the SVG style, script, a  font tags.
Here HTML wins and I think that's fine. This problem is inherent to
the SVG 1.1 spec and we shouldn't let it wreak more havoc on HTML.

*This doesn't attempt to do anything clever with sequences of markup
that contain conflicting top-level nodes (e.g. df.innerHTML =
'tdFoo/tdg/g';). There's nothing clever to be done, and IMO,
attempting to be clever is a mistake.


Here's how some of the examples from the previous thread would be
parsed. I've tested these by simply inspecting the output of innerHTML
applied to the implied context element from the example.

On Thu, Nov 10, 2011 at 3:43 AM, Henri Sivonen hsivo...@iki.fi wrote:
 What about SVG and MathML elements?

 I totally sympathize that this is a problem with tr, but developing
 a complete solution that works sensibly even when you do stuff like
 frag.innerHTML = head/head

head
body

 frag.innerHTML = headdiv/div/head

head
body
  div

 frag.innerHTML = frameset/frameseta!-- b --

a
!-- b --

 frag.innerHTML = htmlbodyfoo/htmlbartr/tr

foobar

 frag.innerHTML = htmlbodyfoo/htmltr/tr

foo

 frag.innerHTML = div/divtr/tr

div

 frag.innerHTML = tr/trdiv/div

tbody
  tr
div

 frag.innerHTML = gpath//g

g
  path

[Note that innerHTML doesn't work presently on SVGElements in WebKit
or Gecko, but this last example would result if it did]


On Tue, Apr 24, 2012 at 5:26 AM, Rafael Weinstein rafa...@google.com wrote:
 No, I hadn't. Let me digest this thread. Much of what I'm implicitly
 asking has already been discussed. I'll repost if I have anything to
 add here. Apologies for the noise.

 On Mon, Apr 23, 2012 at 10:32 PM, Ryosuke Niwa rn...@webkit.org wrote:
 Have you looked
 at http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/0663.html ?

 On Mon, Apr 23, 2012 at 8:39 PM, Rafael Weinstein rafa...@google.com
 wrote:

 The main points of contention in the discussion about the template element
 are

 1) By what mechanism are its content elements 'inert'
 2) Do template contents reside in the document, or outside of it

 What doesn't appear to be controversial is the parser changes which
 would allow the template element to have arbitrary top-level content
 elements.

 I'd like to propose that we add DocumentFragment.innerHTML which
 parses markup into elements without a context element. This has come
 up in the past, and is in itself a useful feature. The problem it
 solves is allowing templating systems to create DOM from markup
 without having to sniff the content and only innerHTML on an
 appropriate parent element (Yehuda can speak more to this).

 The parser changes required for this are a subset of the changes that
 Dimitri uncovered here:

 http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html

 And I've uploaded a webkit patch which implements them here:

 https://bugs.webkit.org/show_bug.cgi?id=84646

 I'm hoping this is a sensible way to make progress. Thoughts?





Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-04-25 Thread Rafael Weinstein
On Wed, Apr 25, 2012 at 12:39 PM, Rafael Weinstein rafa...@google.com wrote:
 Ok, so from the thread that Yehuda started last year,

 There seem to be three issues:

 1) Interop (e.g. WRT IE)
 2) Defining the behavior for all elements
 3) HTML vs SVG vs MathML

 I think what Yehuda outlined earlier is basically right, and I have a
 proposal which accomplishes everything he wants in a different way and
 also addresses the three concerns above. My approach here is to not
 let perfect be the enemy of good.

 DocumentFragment.innerHTML has the following behavior. It picks an
 *implied context element* based on the tagName of the first start tag
 token which appears in the html provided. It then operates per the
 fragment case of the spec, using the implied context element as the
 context element.

 Here's the approach for picking the implied context element:

 Let the first start tag token imply the context element. The start tag
 = implied context element is as follows:

 caption, colgroup, thead, tbody, tfoot = HTMLTableElement
 tr = HTMLTableBodyElement
 col = HTMLColGroupElement
 td, th = HTMLTableRowElement
 head, body = HTMLHTMLElement
 rp, rt = HTMLRubyElement
 Any other HTML tagName = HTMLBodyElement
 Any other SVG tagName = SVGElement
 Any other MathML tagName = MathElement
 Any other tagName = HTMLBodyElement

 Note a few things about this:

 *Because this is basically a pre-processing step to the existing
 fragment case, the changes to the parser spec are purely additive (no
 new insertion modes or other parser changes needed).

 *It addresses (1) by only adding new parsing behavior to new API
 (implicitly retaining compat)

 *It explains (2)

 *The only problem with (3) is the SVG style, script, a  font tags.
 Here HTML wins and I think that's fine. This problem is inherent to
 the SVG 1.1 spec and we shouldn't let it wreak more havoc on HTML.

 *This doesn't attempt to do anything clever with sequences of markup
 that contain conflicting top-level nodes (e.g. df.innerHTML =
 'tdFoo/tdg/g';). There's nothing clever to be done, and IMO,
 attempting to be clever is a mistake.


 Here's how some of the examples from the previous thread would be
 parsed. I've tested these by simply inspecting the output of innerHTML
 applied to the implied context element from the example.

 On Thu, Nov 10, 2011 at 3:43 AM, Henri Sivonen hsivo...@iki.fi wrote:
 What about SVG and MathML elements?

 I totally sympathize that this is a problem with tr, but developing
 a complete solution that works sensibly even when you do stuff like
 frag.innerHTML = head/head

 head
 body

 frag.innerHTML = headdiv/div/head

 head
 body
  div

 frag.innerHTML = frameset/frameseta!-- b --

 a
 !-- b --

 frag.innerHTML = htmlbodyfoo/htmlbartr/tr

 foobar

 frag.innerHTML = htmlbodyfoo/htmltr/tr

 foo

 frag.innerHTML = div/divtr/tr

 div

 frag.innerHTML = tr/trdiv/div

 tbody
  tr
 div

Sorry, this should have been just

tr


 frag.innerHTML = gpath//g

 g
  path

 [Note that innerHTML doesn't work presently on SVGElements in WebKit
 or Gecko, but this last example would result if it did]


 On Tue, Apr 24, 2012 at 5:26 AM, Rafael Weinstein rafa...@google.com wrote:
 No, I hadn't. Let me digest this thread. Much of what I'm implicitly
 asking has already been discussed. I'll repost if I have anything to
 add here. Apologies for the noise.

 On Mon, Apr 23, 2012 at 10:32 PM, Ryosuke Niwa rn...@webkit.org wrote:
 Have you looked
 at http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/0663.html ?

 On Mon, Apr 23, 2012 at 8:39 PM, Rafael Weinstein rafa...@google.com
 wrote:

 The main points of contention in the discussion about the template element
 are

 1) By what mechanism are its content elements 'inert'
 2) Do template contents reside in the document, or outside of it

 What doesn't appear to be controversial is the parser changes which
 would allow the template element to have arbitrary top-level content
 elements.

 I'd like to propose that we add DocumentFragment.innerHTML which
 parses markup into elements without a context element. This has come
 up in the past, and is in itself a useful feature. The problem it
 solves is allowing templating systems to create DOM from markup
 without having to sniff the content and only innerHTML on an
 appropriate parent element (Yehuda can speak more to this).

 The parser changes required for this are a subset of the changes that
 Dimitri uncovered here:

 http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html

 And I've uploaded a webkit patch which implements them here:

 https://bugs.webkit.org/show_bug.cgi?id=84646

 I'm hoping this is a sensible way to make progress. Thoughts?





Re: [webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-04-24 Thread Rafael Weinstein
No, I hadn't. Let me digest this thread. Much of what I'm implicitly
asking has already been discussed. I'll repost if I have anything to
add here. Apologies for the noise.

On Mon, Apr 23, 2012 at 10:32 PM, Ryosuke Niwa rn...@webkit.org wrote:
 Have you looked
 at http://lists.w3.org/Archives/Public/public-webapps/2011OctDec/0663.html ?

 On Mon, Apr 23, 2012 at 8:39 PM, Rafael Weinstein rafa...@google.com
 wrote:

 The main points of contention in the discussion about the template element
 are

 1) By what mechanism are its content elements 'inert'
 2) Do template contents reside in the document, or outside of it

 What doesn't appear to be controversial is the parser changes which
 would allow the template element to have arbitrary top-level content
 elements.

 I'd like to propose that we add DocumentFragment.innerHTML which
 parses markup into elements without a context element. This has come
 up in the past, and is in itself a useful feature. The problem it
 solves is allowing templating systems to create DOM from markup
 without having to sniff the content and only innerHTML on an
 appropriate parent element (Yehuda can speak more to this).

 The parser changes required for this are a subset of the changes that
 Dimitri uncovered here:

 http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html

 And I've uploaded a webkit patch which implements them here:

 https://bugs.webkit.org/show_bug.cgi?id=84646

 I'm hoping this is a sensible way to make progress. Thoughts?





Re: [webcomponents] HTML Parsing and the template element

2012-04-23 Thread Rafael Weinstein
Yes. I think this issue is a distraction.

Using the script tag for encoding opaque text contents is a hack, but
it works as well as it can. AFAIC, The main drawback is that the
contents cannot contain the string /script. This will be the case
for any new element we came up with for this purpose.

If someone has an idea for how to do better than this and why it's
worth doing, please speak up.

Part of the point of parsing the template contents as HTML is exactly
so that template contents can contain subtemplates. It's a universal
feature of templating systems and needs to be well supported.

On Mon, Apr 23, 2012 at 4:11 PM, Ryosuke Niwa rn...@webkit.org wrote:
 Why don't we just use script elements for that then?


 On Mon, Apr 23, 2012 at 3:52 PM, Yuval Sadan sadan.yu...@gmail.com wrote:

 You musn't forget what we're not planning for. Templates can be great for
 so many applications - generating code (JSON, Javascript), generating
 plain-text or otherwise formatted (markdown, restructured text, etc.)
 content and much more. I don't think templates should be parsed by DOM
 unless explicitly requested. The simplest scenario should also be supported
 imho, that is script type=text/html/script-ish markup with access to
 textContent.


 On Thu, Apr 19, 2012 at 1:56 AM, Rafael Weinstein rafa...@google.com
 wrote:

 On Wed, Apr 18, 2012 at 2:54 PM, Dimitri Glazkov dglaz...@chromium.org
 wrote:
  On Wed, Apr 18, 2012 at 2:31 PM, James Graham jgra...@opera.com
  wrote:
  On Wed, 18 Apr 2012, Dimitri Glazkov wrote:
 
  Wouldn't it make more sense to host the template contents as normal
  descendants of the template element and to make templating APIs
  accept
  either template elements or document fragments as template input?
   Or
  to make the template elements have a cloneAsFragment() method if the
  template fragment is designed to be cloned as the first step anyway?
 
  When implementing this, making embedded content inert is probably
  the
  most time-consuming part and just using a document fragment as a
  wrapper isn't good enough anyway, since for example img elements
  load
  their src even when not inserted into the DOM tree. Currently, Gecko
  can make imbedded content inert on a per-document basis.  This
  capability is used for documents returned by XHR, createDocument and
  createHTMLDocument. It looks like the template proposal will involve
  computing inertness from the ancestor chain (template ancestor or
  DocumentFragment marked as inert as an ancestor).  It's unclear to
  me
  what the performance impact will be.
 
 
  Right, ancestor-based inertness is exactly what we avoid with
  sticking
  the parsed contents into a document fragment from an inert
  document.
  Otherwise, things get hairy quick.
 
 
  I am also pretty scared of tokenising stuff like it is markup but then
  sticking it into a different document. It seems like very surprising
  behaviour. Have you considered (and this may be a very bad idea)
  exposing
  the markup inside the template as a text node, but exposing the
  corresponding DOM as an IDL attribute on the HTMLTemplateElement (or
  whatever it's called) interface?
 
  This seems like a neat idea -- though I haven't thought about this in
  depth yet.

 I think there are two orthogonal issues here:

 1) Are the contents of the template element (a) parsed, context-free
 in a separate document which lacks a browsing context, or (b) simply
 processed as text.
 2) Where are the contents of the template element put.

 (I'm separating these because James' proposal is about the second, not
 the first).

 I think there's a disconnect here between what seems strange to us a
 UA implementors and what isn't strange at all to webdevs. In a way,
 the goal here is exactly to create a mechanism which is strange in
 this way.

 Effective, every web app that does client-side templating is totally
 used to this idea: E.g. I want to ship fragments of DOM structures
 inside my document to the client, but have those fragments exist
 *outside* the DOM constructed for that document for all practical
 purposes (rendering, traversal, resource loading, selector matching,
 etc...).

 This goal of this feature is provide webdevs with a supported
 mechanism to do this which lacks the pitfalls of the available hacks.

 Assuming (1) is uncontroversially (a), then the idea to re-serialize
 the parsed content and append it is a text child to the template
 element would resolve our worry about the contents living outside the
 DOM being strange, but it has the downside that nearly all uses will
 immediately re-parse.

 [Dimitri addressed the problem with (1) being (b) earlier in the
 thread, if anyone is interested].

 
  :DG






[webcomponents] Template element parser changes = Proposal for adding DocumentFragment.innerHTML

2012-04-23 Thread Rafael Weinstein
The main points of contention in the discussion about the template element are

1) By what mechanism are its content elements 'inert'
2) Do template contents reside in the document, or outside of it

What doesn't appear to be controversial is the parser changes which
would allow the template element to have arbitrary top-level content
elements.

I'd like to propose that we add DocumentFragment.innerHTML which
parses markup into elements without a context element. This has come
up in the past, and is in itself a useful feature. The problem it
solves is allowing templating systems to create DOM from markup
without having to sniff the content and only innerHTML on an
appropriate parent element (Yehuda can speak more to this).

The parser changes required for this are a subset of the changes that
Dimitri uncovered here:

http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html

And I've uploaded a webkit patch which implements them here:

https://bugs.webkit.org/show_bug.cgi?id=84646

I'm hoping this is a sensible way to make progress. Thoughts?



Re: [webcomponents] HTML Parsing and the template element

2012-04-18 Thread Rafael Weinstein
On Wed, Apr 18, 2012 at 9:32 AM, Dimitri Glazkov dglaz...@chromium.org wrote:
 On Wed, Apr 18, 2012 at 7:49 AM, Henri Sivonen hsivo...@iki.fi wrote:
 On Tue, Apr 3, 2012 at 1:21 AM, Dimitri Glazkov dglaz...@chromium.org 
 wrote:
 Perhaps lost among other updates was the fact that I've gotten the
 first draft of HTML Templates spec out:

 http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html

 Once parsed, the template contents must not be in the document tree.

 That's surprising, radical and weird.  Why are the template contents
 hosted in a document fragment that the template element points to
 using a non-child property?  Why aren't the template contents simply
 hosted as a subtree rooted at the template element?

 In terms of weirdness, this is not much different from the textarea,
 script, or xmp. It does change the existing behavior, so anyone using
 a template tag today will suddenly find no child nodes -- that part
 _is_ a bit surprising.

 However, moving this into a separate document fragment allows us to
 easily define the boundaries of intertness. If you look at the spec,
 the document fragment is indeed created from a separate document is
 inert (like createHTMLDocument case):
 http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#dfn-template-contents-initialization.


 This also breaks the natural mapping between XML source and the DOM in
 the XML case.

 True.

I've created a bug against the spec to make clear that the XML parser
will be unchanged WRT the template element.

https://www.w3.org/Bugs/Public/show_bug.cgi?id=16787



 This weirdness also requires a special case to the serialization algorithm.

 True.


 If the document fragment wasn't there and the contents of the template
 were simply children of template element, the parsing algorithm
 changes would look rather sensible.

 Great!


 Wouldn't it make more sense to host the template contents as normal
 descendants of the template element and to make templating APIs accept
 either template elements or document fragments as template input?  Or
 to make the template elements have a cloneAsFragment() method if the
 template fragment is designed to be cloned as the first step anyway?

 When implementing this, making embedded content inert is probably the
 most time-consuming part and just using a document fragment as a
 wrapper isn't good enough anyway, since for example img elements load
 their src even when not inserted into the DOM tree. Currently, Gecko
 can make imbedded content inert on a per-document basis.  This
 capability is used for documents returned by XHR, createDocument and
 createHTMLDocument. It looks like the template proposal will involve
 computing inertness from the ancestor chain (template ancestor or
 DocumentFragment marked as inert as an ancestor).  It's unclear to me
 what the performance impact will be.

 Right, ancestor-based inertness is exactly what we avoid with sticking
 the parsed contents into a document fragment from an inert document.
 Otherwise, things get hairy quick.

 :DG


 --
 Henri Sivonen
 hsivo...@iki.fi
 http://hsivonen.iki.fi/



Re: [webcomponents] HTML Parsing and the template element

2012-04-04 Thread Rafael Weinstein
On Mon, Apr 2, 2012 at 3:21 PM, Dimitri Glazkov dglaz...@chromium.org wrote:
 On Wed, Feb 8, 2012 at 11:25 PM, Henri Sivonen hsivo...@iki.fi wrote:
 On Thu, Feb 9, 2012 at 12:00 AM, Dimitri Glazkov dglaz...@chromium.org 
 wrote:
 == IDEA 1: Keep template contents parsing in the tokenizer ==

 Not this!

 Here's why:
 Making something look like markup but then not tokenizing it as markup
 is confusing. The confusion leads to authors not having a clear mental
 model of what's going on and where stuff ends. Trying to make things
 just work for authors leads to even more confusing here be dragons
 solutions. Check out
 http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#script-data-double-escaped-dash-dash-state

 Making something that looks like markup but isn't tokenized as markup
 also makes the delta between HTML and XHTML greater. Some people may
 be ready to throw XHTML under the bus completely at this point, but
 this also goes back to the confusion point. Apart from namespaces, the
 mental model you can teach for XML is remarkably sane. Whenever HTML
 deviates from it, it's a complication in the understandability of
 HTML.

 Also, multi-level parsing is in principle bad for perf. (How bad
 really? Dunno.) I *really* don't want to end up writing a single-pass
 parser that has to be black-box indishtinguishable from something
 that's defined as a multi-pass parser.

 (There might be a longer essay about how this sucks in the public-html
 archives, since the SVG WG proposed something like this at one point,
 too.)

 == IDEA 2: Just tweak insertion modes ==

 I think a DWIM insertion mode that switches to another mode and
 reprocesses the token upon the first start tag token *without* trying
 to return to the DWIM insertion mode when the matching end tag is seen
 for the start tag that switched away from the DWIM mode is something
 that might be worth pursuing. If we do it, I think we should make it
 work for a fragment parsing API that doesn't require context beyound
 assuming HTML, too. (I think we shouldn't try to take the DWIM so far
 that a contextless API would try to guess HTML vs. SVG vs. MathML.)

 Just to connect the threads. A few weeks back, I posted an update
 about the HTML Templates spec:
 http://lists.w3.org/Archives/Public/public-webapps/2012JanMar/1171.html

 Perhaps lost among other updates was the fact that I've gotten the
 first draft of HTML Templates spec out:

 http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html

 The draft is roughly two parts: motivation for the spec and deltas to
 HTML specification to allow serialization and parsing of the
 template element. To be honest, after finishing the draft, I
 wondered if we should just merge the whole thing into the HTML
 specification.

 As a warm-up exercise for the draft, I first implemented the changes
 to tree construction algorithm here in WebKit
 (https://bugs.webkit.org/show_bug.cgi?id=78734). The patch
 (https://bugs.webkit.org/attachment.cgi?id=128579action=review)
 includes new parsing tests, and should be fairly intuitive to read to
 those familiar with the test format.

 The interesting bit here is that all parser changes are additive: we
 are only adding what effectively are extensions points -- well, that
 and a new contextless parsing mode for when inside of the template
 tag.

I think the task previously was to show how dramatic the changes to
the parser would need to be. Talking to Dimitri, it sounds to me like
they turned out to be less open-heart-surgery and more quick
outpatient procedure. Adam, Hixie, Henri, how do you guys feel about
the invasiveness of the parser changes that Dimitri has turned out
here?


 The violation of the Degrade Gracefully principle and tearing the
 parser spec open right when everybody converged on the spec worry me,
 though. I'm still hoping for a design that doesn't require parser
 changes at all and that doesn't blow up in legacy browsers (even
 better if the results in legacy browsers were sane enough to serve as
 input for a polyfill).

 I agree with your concern. It's bugging me too -- that's why I am not
 being an arrogant jerk yelling at people and trying to shove this
 through. In general, it's difficult to justify making changes to
 anything that's stable -- especially considering how long and painful
 the road to getting stable was. However, folks like Yehuda, Erik, and
 Rafael spent years tackling this problem, and I tend to trust their
 steady hand... hands?

I don't think there's an option to degrade gracefully here. My
personal feeling is that even if it's years before browsers reliably
support this and developers can use it without needing to be careful
until then, there's a long term view here which is the sooner me put
this into the spec, the sooner that day will arrive.

Also, I like this approach because it addresses the inert DOM use case
as well as the context-free parsing use case.


 :DG



Re: [webcomponents] HTML Parsing and the template element

2012-02-08 Thread Rafael Weinstein
[This time from the right email]

On Wed, Feb 8, 2012 at 2:10 PM, Adam Barth w...@adambarth.com wrote:
 Re-using the generic raw text element parsing algorithm would be the
 simplest change to the parser.  Do you have a concrete example of
 where nested template declarations are required?  For example,
 rather than including nested templates, you might instead consider
 referencing other template elements by id.

Referencing templates rather than including sub-templates inline is
certainly a solution. In fact, it's a common feature of templating
systems. It's useful when a single component is used in multiple
disparate or random places throughout the page.

However, it's worth backing up here and thinking about what templating is.

Templating is about convenience and maintainability of pages  -- Not
about any core capability. Templating is useful and near ubiquitous
because it makes it easy to think about authoring your page.

Web pages are highly complex and often deeply nested repeating tree
structures. You can certainly de-construct the page into some sort of
templating-4th-normal-form and dump each component at the top level
of the document.

However, doing this abandons the largely coherent structure of
template, e.g. where table rows are defined in the context of the
table in which they are used, etc... -- which is sort of the idea of
templating -- that you get to describe your page in more or less the
way that it will be rendered.


 Adam


 On Wed, Feb 8, 2012 at 2:00 PM, Dimitri Glazkov dglaz...@chromium.org wrote:
 Hello folks!

 You may be familiar with the work around the template element, or a
 way to declare document fragments in HTML (see
 http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-November/033868.html
 for some background).

 In trying to understand how this newfangled beast would work, I
 started researching HTML parsing, and--oh boy was I ever sorry! Err..
 I mean.. --and investigating how the contents of the template
 element could be parsed.

 So far, I have two ideas. Both introduce changes to HTML parsing
 algorithm. Both have flaws, and I thought the best thing to do would
 be to share the data with the experts and seek their opinions. Those
 of you cc'd -- you're the designated experts :)

 == IDEA 1: Keep template contents parsing in the tokenizer ==

 PRO: if we could come up with a way to perceive the stuff between
 template and /template as a character stream, we enable a set of
 use cases where the template contents does not need to be a complete
 HTML subtree. For example, I could define a template that sets up a
 start of a table, then a few that provide repetition patterns for
 rows/cells, and then one to close out a table:

 template id=headtablecaptionNyan-nyan/captionthead ...
 tbody/template
 template id=rowtrtemplatetd ... /td/template/tr/template
 template id=foot/tbody/table/template

 Then I could slam these templates together with some API and produce
 an arbitrary set of tables.

 PRO: Since the template contents are parsed as string, we create
 opportunities for performance optimizations at the UA level. If a
 bunch of templates is declared, but only a handful is used, we could
 parse template contents on demand, thus reducing the churn of DOM
 elements.

 CON: Tokenizer needs to be really smart and will start looking a lot
 like a specialized parser. At first glance, template behaves much
 like a textarea -- any tags inside will just be treated as
 characters. It works until you realize that templates sometimes need
 to be nested. Any use case that involves building a
 larger-than-one-dimensional data representation (like tables) will
 involve nested templates. This makes things rather tricky. I made an
 attempt of sketching this out here:
 http://dvcs.w3.org/hg/webcomponents/raw-file/a28e16cc4167/spec/templates/index.html#parsing.
 As you can see, this adds a largish set of new states to tokenizer.
 And it is still incomplete, breaking in cases like
 templatescriptalert('template is
 awesome!');/script/template.

 It could be argued that--while pursuing the tokenizer algorithm
 perfection--we could just stop at some point of complexity and issue a
 stern warning for developers to not get too crazy, because stuff will
 break -- akin to including /script string in your Javascript code.

 == IDEA 2: Just tweak insertion modes ==

 PRO: It's a lot less intrusive to the parser -- just adjust insertion
 modes to allow template tags in places where they would ordinary be
 ignored or foster-parented, and add a new insertion for template
 contents to let all tags in. I made a quick sketch here:
 http://dvcs.w3.org/hg/webcomponents/raw-file/c96f051ca008/spec/templates/index.html#parsing
 (Note: more massaging is needed to make it really work)

 CON: You can't address fun partial-tree scenarios.

 Which idea appeals to you? Perhaps you have better ideas? Please share.

 :DG



Re: [webcomponents] HTML Parsing and the template element

2012-02-08 Thread Rafael Weinstein
Here's a real-world example, that's probably relatively simple
compared to high traffic web pages (i.e. amazon or facebook)

http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/template/api_template.html?revision=120962content-type=text%2Fplain

that produces each page of the chrome extensions API doc, e.g.

http://code.google.com/chrome/extensions/contextMenus.html

This uses jstemplate. Do a search in the first link. Every time you
see jsdisplay or jsselect, think template.

On Wed, Feb 8, 2012 at 2:36 PM, Adam Barth w...@adambarth.com wrote:
 On Wed, Feb 8, 2012 at 2:20 PM, Erik Arvidsson a...@chromium.org wrote:
 On Wed, Feb 8, 2012 at 14:10, Adam Barth w...@adambarth.com wrote:
 ... Do you have a concrete example of
 where nested template declarations are required?

 When working with tree like structures it is comment to use recursive 
 templates.

 http://code.google.com/p/mdv/source/browse/use_cases/tree.html

 I'm not sure I fully understand how templates work, so please forgive
 me if I'm butchering it, but here's how I could imagine changing that
 example:

 === Original ===

 ul class=tree
  template iterate id=t1
    li class={{ children | toggle('has-children') }}{{name}}
      ul
        template ref=t1 iterate=children/template
      /ul
    /li
  /template
 /ul

 === Changed ===

 ul class=tree
  template iterate id=t1
    li class={{ children | toggle('has-children') }}{{name}}
      ul
        template-reference ref=t1 iterate=children/template-reference
      /ul
    /li
  /template
 /ul

 (Obviously you'd want a snappier name than template-reference to
 reference another template element.)

 I looked at the other examples in the same directory and I didn't see
 any other examples of nested template declarations.

 Adam



Re: [webcomponents] HTML Parsing and the template element

2012-02-08 Thread Rafael Weinstein
On Wed, Feb 8, 2012 at 3:16 PM, Adam Barth w...@adambarth.com wrote:
 On Wed, Feb 8, 2012 at 2:47 PM, Rafael Weinstein rafa...@chromium.org wrote:
 Here's a real-world example, that's probably relatively simple
 compared to high traffic web pages (i.e. amazon or facebook)

 http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/template/api_template.html?revision=120962content-type=text%2Fplain

 that produces each page of the chrome extensions API doc, e.g.

 http://code.google.com/chrome/extensions/contextMenus.html

 This uses jstemplate. Do a search in the first link. Every time you
 see jsdisplay or jsselect, think template.

 It's a bit hard for me to understand that example because I don't know
 how jstemplate works.

Sorry. This example wasn't really meant to be understood so much as
observed for:

1) A general feel for levels of nesting.
2) That the nested components are defined where they are used.
3) How complex the templating already is, even given that templates
can be nested.
3) Imagine what this page might look like if each nested component was
pulled out and put somewhere else (possibly the top level).


 I'm just suggesting that rather than trying to jam a square peg
 (template) into a round hole (the HTML parser), there might be a way
 of reshaping both the peg and the hole into an octagon.

I get that. Unfortunately, I'm useless on this front because I know
next to nothing about HTML parsing.

All I can offer is an opinion as to how well various declarative
semantics will address the templating use case.

Maybe the best analogy I can give is this: try to imagine if someone
proposed that C looping constructs couldn't contain a body -- only a
function call. e.g.

for (int i = 0; i  count; i++) doMyThing();

You can still write all the same programs, but it'd be an
unfortunately feature to give up.


 Adam


 On Wed, Feb 8, 2012 at 2:36 PM, Adam Barth w...@adambarth.com wrote:
 On Wed, Feb 8, 2012 at 2:20 PM, Erik Arvidsson a...@chromium.org wrote:
 On Wed, Feb 8, 2012 at 14:10, Adam Barth w...@adambarth.com wrote:
 ... Do you have a concrete example of
 where nested template declarations are required?

 When working with tree like structures it is comment to use recursive 
 templates.

 http://code.google.com/p/mdv/source/browse/use_cases/tree.html

 I'm not sure I fully understand how templates work, so please forgive
 me if I'm butchering it, but here's how I could imagine changing that
 example:

 === Original ===

 ul class=tree
  template iterate id=t1
    li class={{ children | toggle('has-children') }}{{name}}
      ul
        template ref=t1 iterate=children/template
      /ul
    /li
  /template
 /ul

 === Changed ===

 ul class=tree
  template iterate id=t1
    li class={{ children | toggle('has-children') }}{{name}}
      ul
        template-reference ref=t1 iterate=children/template-reference
      /ul
    /li
  /template
 /ul

 (Obviously you'd want a snappier name than template-reference to
 reference another template element.)

 I looked at the other examples in the same directory and I didn't see
 any other examples of nested template declarations.

 Adam



Re: Mutation Observers: a replacement for DOM Mutation Events

2011-10-12 Thread Rafael Weinstein
Hi Sean,

I find it hard to reason about cases in the abstract. None of the
examples you list seem concerning to me (i.e. I believe they can be
properly handled), but perhaps it's a failure of my imagination.

Maybe you can provide concrete examples (i.e. with code snippets,
actual instances of use cases, etc...)

On Wed, Oct 12, 2011 at 4:00 AM, Sean Hogan shogu...@westnet.com.au wrote:
 On 12/10/11 3:26 AM, Tab Atkins Jr. wrote:

 On Mon, Oct 10, 2011 at 7:51 PM, Sean Hoganshogu...@westnet.com.au
  wrote:

 On 24/09/11 7:16 AM, Adam Klein wrote:

 - Is free of the faults of the existing Mutation Events mechanism
 (enumerated in detail here:
 http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html)

 A simpler solution that is free from the faults listed in that email
 would
 be to have (at max) one mutation observer for the whole page context. I
 guess this would be called at the end of the task or immediately before
 page
 reflows.

 If a js lib (or multiple libs) want to provide finer grained mutation
 handling then let them work out the details.

 That seems unworkably restrictive.  It's very easy to imagine multiple
 libraries listening for different kinds of things at the same time.
 Libraries would just end up re-implementing event distribution, which
 is something we can avoid by doing it correctly now.

 This proposal doesn't entirely avoid the issue of event distribution. There
 is no equivalent of event.stopPropagation() and hence no way to prevent
 mutation records being delivered to observers. The observers may have to be
 written with this is in mind.

 For example, what if two observers can potentially handle the same mutation
 - which one should handle it?

 Alternatively, some code might respond to an attribute by adding content to
 the DOM. What if there are mutation listeners that could respond to that
 added content? Is it desired that they ignore or handle it?

 Another pattern that doesn't seem to be reliably handled is mutations within
 DOM fragments that are temporarily removed from the document. That is:
 - if the fragment always remains in the document then all mutations can be
 monitored by observers on the document (or document.body), but
 - if the fragment is removed from the document followed by mutation
 observers being called, then  any further mutations won't be delivered to
 the observers, even when the fragment is reinserted into the document.

 The exact behavior in this scenario depends on whether mutations complete
 within one microtask or more than one

 Sean.






Re: DOM Mutation Events Replacement: Findings from implementing net-effect projections

2011-08-17 Thread Rafael Weinstein
On Wed, Aug 17, 2011 at 3:17 AM, Olli Pettay olli.pet...@helsinki.fi wrote:
 On 08/17/2011 04:54 AM, Rafael Weinstein wrote:

 TL;DR;

 1) ObserveSubtree semantics doesn't provide a robust mechanism for
 observing a tree/fragment, and if we don't provide something more
 complete, libraries will likely register observers at every node in
 the document.

 ModificationBatch approach should provide as much information as
 current mutation events.




 2) Not providing position information (e.g childlistIndex) in
 ChildlistChanged mutations means that the algorithmic complexity of
 computing whether/where nodes have moved to doesn't improve vs. having
 to bruce-force compute.

 Yeah, I think we really to provide some position information.
 Adding index is easy (although it can be slow in some implementations,
 but that is implementation specific thing)
 I'll add this to ModificationBatch.


 3) Not providing lastValue for text changes (attribute, textNode,
 etc...) may adversely impact some use cases.

 I agree.





 ---
 Following up on points 6  7 from
 http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html
 ...

 I've prototyped the main net-effect projections that I believe
 various use cases will need. I've published to code to this public
 github repository:

 https://github.com/rafaelw/MutationProjections

 I encourage anyone interested to check my work and make corrections
 and/or suggestions, or create a branch that experiments in any
 direction they see fit.

 ---
 Per point (3) in the email above, we've concluded that mutations
 should be delivered in batches, since any number of mutations can have
 taken place since an observer was notified.

 Also, though it varies, there's generally a hierarchy of expense for
 types of operations done from JS:

   reads/writes on pure JS data  DOM Reads  DOM Writes  External I/O

 Often, an application is willing to do a some amount of work of a less
 expensive operation to avoid doing any work of a more expensive
 operation.

 Thus, a mutation observer is highly motivated, for both correctness
 and performance, to answer the question:

   What is the net-effect of some set of DOM changes that have taken
 place since I last got to run?

 ---
 Depending on the use case, what happened likely means some
 combination of the following:

 1) Reachability: What nodes were added to or removed from the document?

 2) Matching: What nodes stopped or started matching a given pattern?
 This could be arbitrarily complex, but in the use cases discussed,
 this usually means a simple selector.

 3) Parent changes: What nodes are now children of a new parent node?

 4) Movement: What nodes moved to a new position in the document?

 5) Value change: What character/text or attribute nodes changed value
 (for attributes, also, whether the attribute was added or removed)?

 Note that none of the above requires any mechanism of mutation
 observation. All can be computed given the opportunity to inspect the
 DOM at two points in time.

 However, without any information about what happened, the expense of
 answering each of the above questions is roughly proportional to the
 number of nodes in the document. All are roughly linear, except (4)
 Movement, which is roughly quadratic.

 It seems to me that a good goal for any mutation event replacement
 should be that the expense of answering the above projections be
 proportional the number of mutations which actually took place.

 I've implemented the null case (lacking any mutation information)
 for 1, 3  4 here:


 https://github.com/rafaelw/MutationProjections/blob/master/projections.js#L39

 And the same projections, but taking mutation records to improve
 performance here:


 https://github.com/rafaelw/MutationProjections/blob/master/projections.js#L240

 ---
 Observing sets of nodes

 In order to implement the above projections, I prototyped:

   Document.observeOwnedNodes

 I'm not proposing this (yet), but I think it is conceptually the most
 general case (btw, to give credit to Jonas, he pointed out that this
 might be solution to the problem I'm about to describe, though I'm
 pretty sure he meant sometime down the road).

 I'm not quite sure what all the Document.observeOwnedNodes approach
 tries to observe. I assume it should be observing everything, all the
 changes to child nodes and also changes to attributes.
 (currently it handles only elements)
 Is that really needed?

It's not fully implemented in the shim I created, in that it only
reports ChildlistChanged mutations.

It's purpose is to provide a single registration that allows you to be
notified of all changes that happen to all nodes owned by this
document, regardless of whether they are current in the document.




 The problem is that observeSubtree doesn't report anything about what
 happened to a node that was removed from the document, modified, then
 returned to the document. Consider the following case

DOM Mutation Events Replacement: Findings from implementing net-effect projections

2011-08-16 Thread Rafael Weinstein
TL;DR;

1) ObserveSubtree semantics doesn't provide a robust mechanism for
observing a tree/fragment, and if we don't provide something more
complete, libraries will likely register observers at every node in
the document.

2) Not providing position information (e.g childlistIndex) in
ChildlistChanged mutations means that the algorithmic complexity of
computing whether/where nodes have moved to doesn't improve vs. having
to bruce-force compute.

3) Not providing lastValue for text changes (attribute, textNode,
etc...) may adversely impact some use cases.

---
Following up on points 6  7 from
http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html
...

I've prototyped the main net-effect projections that I believe
various use cases will need. I've published to code to this public
github repository:

https://github.com/rafaelw/MutationProjections

I encourage anyone interested to check my work and make corrections
and/or suggestions, or create a branch that experiments in any
direction they see fit.

---
Per point (3) in the email above, we've concluded that mutations
should be delivered in batches, since any number of mutations can have
taken place since an observer was notified.

Also, though it varies, there's generally a hierarchy of expense for
types of operations done from JS:

  reads/writes on pure JS data  DOM Reads  DOM Writes  External I/O

Often, an application is willing to do a some amount of work of a less
expensive operation to avoid doing any work of a more expensive
operation.

Thus, a mutation observer is highly motivated, for both correctness
and performance, to answer the question:

  What is the net-effect of some set of DOM changes that have taken
place since I last got to run?

---
Depending on the use case, what happened likely means some
combination of the following:

1) Reachability: What nodes were added to or removed from the document?

2) Matching: What nodes stopped or started matching a given pattern?
This could be arbitrarily complex, but in the use cases discussed,
this usually means a simple selector.

3) Parent changes: What nodes are now children of a new parent node?

4) Movement: What nodes moved to a new position in the document?

5) Value change: What character/text or attribute nodes changed value
(for attributes, also, whether the attribute was added or removed)?

Note that none of the above requires any mechanism of mutation
observation. All can be computed given the opportunity to inspect the
DOM at two points in time.

However, without any information about what happened, the expense of
answering each of the above questions is roughly proportional to the
number of nodes in the document. All are roughly linear, except (4)
Movement, which is roughly quadratic.

It seems to me that a good goal for any mutation event replacement
should be that the expense of answering the above projections be
proportional the number of mutations which actually took place.

I've implemented the null case (lacking any mutation information)
for 1, 3  4 here:

https://github.com/rafaelw/MutationProjections/blob/master/projections.js#L39

And the same projections, but taking mutation records to improve
performance here:

https://github.com/rafaelw/MutationProjections/blob/master/projections.js#L240

---
Observing sets of nodes

In order to implement the above projections, I prototyped:

  Document.observeOwnedNodes

I'm not proposing this (yet), but I think it is conceptually the most
general case (btw, to give credit to Jonas, he pointed out that this
might be solution to the problem I'm about to describe, though I'm
pretty sure he meant sometime down the road).

The problem is that observeSubtree doesn't report anything about what
happened to a node that was removed from the document, modified, then
returned to the document. Consider the following case:

-Register a subtreeObserver at the root of the document
-Some other code removes an element, appends a new element to it,
modifies an attribute, then returns the node to the document.

Now, in order to properly compute the above projections, we are nearly
back to the null case (matching becomes proportional the number of
descendants of added/removed nodes that we heard about, but everything
else returns to being proportional to the number of nodes in the
document).

You may consider this to be an esoteric case, but imagine the
situation that library authors will be in. They will have two basic
options:

a) Use observeSubtree and explain to their users that they have to be
careful never to modify something outside the tree.
b) Simply register an observer at all nodes in the document.

Picking the second option means that my library works properly and I
don't need my users to be careful. It burns plenty of memory, but
library authors aren't well known for being conservative in that
regard -- especially since its pretty hard for them to quantify the
memory impact of anything.

The danger is 

Re: DOM Mutation Events Replacement: When to deliver mutations

2011-08-11 Thread Rafael Weinstein
Thanks Olli. I think this is now a fairly complete summary of the
issues identified thus far.

It'd be great to get some additional views -- in particular from folks
representing UAs that haven't yet registered any observations or
opinons.

Note: I think what Olli has listed is fair, but I'm concerned that
because of terminology (consistent vs inconsistent semantics),
others may be confused. I'm going to clarify a bit. I believe my
comments should be uncontroversial. Olli (or anyone else), please
correct me if this isn't so.

On Thu, Aug 11, 2011 at 2:02 AM, Olli Pettay olli.pet...@helsinki.fi wrote:
 On 08/11/2011 03:44 AM, Rafael Weinstein wrote:

 Although everyone seems to agree that mutations should be delivered
 after the DOM operations which generated them complete, the question
 remains:

   When, exactly, should mutations be delivered?

 The four options I'm aware of are:

 1) Immediately - i.e. while the operation is underway. [Note: This is
 how current DOM Mutation events work].

 2) Upon completion of the outer-most DOM operation. i.e. Immediately
 before a the lowest-on-the-stack DOM operation returns, but after it
 has done all of its work.

 3) At the end of the current Task. i.e. immediately before the UA is
 about to fetch a new Task to run.

 4) Scheduled as a future Task. i.e. fully async.

 ---

 Discussion:

 Options 1  4 are don't seem to have any proponents that I know of, so
 briefly:

 Option 1, Immediately:

 Pro:
 -It's conceptually the easiest thing to understand. The following *always*
 hold:
   -For calling code: When any DOM operation I make completes, all
 observers will have run.
   -For notified code: If I'm being called, the operation which caused
 this is below me on the stack.

 Con:
 -Because mutations must be delivered for some DOM operations before
 the operation is complete, UAs must tolerate all ways in which script
 may invalidate their assumptions before they do further work.


 Option 4, Scheduled as a future Task:

 Pro:
 -Conceptually easy to understand
 -Easy to implement.

 Con:
 -It's too late. Most use cases for mutation observation require that
 observers run before a paint occurs. E.g. a widget library which
 watches for special attributes. Script may create adiv
 class=FooButton  and an observer will react to this by decorating
 the div as a FooButton. It is unacceptable (creates visual
 artifacts/flickering) to have the div be painted before the widget
 library has decorated it as a FooButton.

 Both of these options appear to be non-starters. Option 1 has been
 shown by experience to be an unreasonable implementation burden for
 UAs. Option 4 clearly doesn't handle properly important use cases.

 ---

 Options 2  3 have proponents. Since I'm one of them (a proponent),
 I'll just summarize the main *pro* arguments for each and invite those
 who wish (including myself), to weigh in with further support or
 criticism in follow-on emails.


 Option 2: Upon completion of the outer-most DOM operation.

 Pro:
 -It's conceptually close to fully synchronous. For simple uses
 (specifically, setting aside the case of making DOM operations within
 a mutation callback), it has the advantages of Option 1, without its
 disadvantages. Because of this, it's similar to the behavior of
 current Mutation Events.

 Pro:
 Semantics are consistent: delivery happens right before the
 outermost DOM operation returns.

This statement is true. When I described Option 2 (perhaps too
harshly) as having inconsistent semantics, I was referrer only to
the expectations of Callers and Observers. To be totally clear:

Parties:

Caller = any code which performers a DOM operation which triggers a mutation.
Observer = any code to whom the mutation is delivered.

Expectations for synchrony:

Caller: When any DOM operation I make completes, all observers will
have been notified.
Observer: If I'm being notified, the Caller which triggered the
mutation is below me on the stack.

Parties:   Caller  Observer
Options
1:Always   Always
2:Sometimes(a) Sometimes(a)
3:Never Never
4:Never Never

(a) True when Caller is run outside of a mutation observer callback.
False when Caller is run inside a mutation observer callback.


 Easier transition from mutation events to the new API.

 Not bound to tasks. Side effects, like problems related
 to spinning event loop are per mutation callback, not
 per whole task.




 Option 3: At the end of the current Task.

 Pro:
 -No code is at risk for having its assumptions invalidated while it is
 trying to do work. All participants (main application script,
 libraries which are implemented using DOM mutation observation) are
 allowed to complete whatever work (DOM operations) they wish before
 another participant starts doing work.



 Con:
 Since the approach is bound to tasks, it is not clear what should happen
 if event loop spins while handling the task. What

Re: DOM Mutation Events Replacement: When to deliver mutations

2011-08-11 Thread Rafael Weinstein
On Thu, Aug 11, 2011 at 9:12 AM, Olli Pettay olli.pet...@helsinki.fi wrote:
 On 08/11/2011 06:13 PM, Rafael Weinstein wrote:

 Con:
 Since the approach is bound to tasks, it is not clear what should happen
 if event loop spins while handling the task. What if some other task
 modifies the DOM[1], when should the mutation callbacks fire?
 Because of this issue, tasks, which may spin event loop, should not
 also modify DOM since that may cause some unexpected result.

 I think the *pro* side of this you listed is more fair. Both Options 2
   3 must answer this question. It's true that because Option 3 is
 later, it sort of has this issue more.

 And it has a lot more. Since for example when handling an event, all
 the listeners for it are called in the same task and if one event
 listener modifies DOM and some other spins event loop, it is hard to
 see what is causing the somewhat unexpected behavior.



 However, what should happen has been defined. In both cases, if
 there are any mutations which are queued for delivery when an inner
 event loop spins up, they are *not* delivered inside the inner event
 loop. In both Options, they are always delivered in the loop which
 queued them.

 But what happens when event loop spins within a task, and some
 inner task causes new mutations?
 We want to notify about mutations in the order they have happened, right?

In general, yes. But I believe the idea is that spinning an inner
event loop is an exception. In that case delivering mutations in the
order they were generated will be broken. To be perfectly precise:
Mutations will be delivered in the order they were generated *for and
within any given event loop*.

There's no question this is unfortunate. The case in which the bad
thing happens is you:

-Made some modifications to the main document
-Used showModalDialog
-Modified the opener document from the event loop of showModalDialog
-Got confused because mutations from within the showModalDialog were
delivered before the mutations made before calling it

I suppose this comes down to judgement. Mine is that it's acceptable
for us to not attempt to improve the outcome in this case.

 So if there are pending mutations to notify, the inner task must just
 queue notifications to the queue of the outermost task.
 This could effectively disable all the mutation callbacks for example when a
 modal dialog (showModalDialog) is open.


 Option 2 has similar problem, but *only* while handling mutation callbacks,
 not during the whole task.



 -Olli





 Callback handling is moved far away from the actual mutation.


 Pro:
 Can batch more, since the callbacks are called later than in
 option 2.


 -Olli


 [1] showModalDialog(javascript:opener.document.body.textContent = '';,
 ,
 );








Re: Mutation events replacement

2011-08-10 Thread Rafael Weinstein
Awesome. Status update on our side:

-Adam has been researching the implementation implications in Webkit
of a few variants of proposals made here -- with the goal of having
enough understanding to start a discussion on webkit-dev.

-I'm composing an email which attempts to summarize the discussion so
far, the points of broad agreement and the remaining points of
divergence -- with the goal of trying to drive to an initial consensus
on the main design points of a replacement.

-I've been experimenting with implementing various net effect
projections that take sequences of mutations as input -- with the
goal of reporting back on the time/space complexity implications for
variants of what information is provided in the mutation records.

Cheers
Rafael

On Wed, Aug 10, 2011 at 12:49 PM, Olli Pettay olli.pet...@helsinki.fi wrote:
 FYI, I'm planning to implement the proposal (using vendor prefixed API)
 so that I can create tryserver builds.
 I'll post the links to builds here later, hopefully in a few days, when
 I find the time to do the actual implementation.


 -Olli


 On 08/04/2011 04:38 PM, Olli Pettay wrote:

 Hi all,

 here is a bit different proposal for mutation events replacement.
 This is using the mostly-sync approach, and batching can make it easier
 to use with several simultaneous script libraries; each one would use
 their own batch.
 For performance reasons it might be useful to have an attribute name
 filter for AttrChange, but such thing could be added later.
 One advantage this approach has is that it doesn't pollute Node API.


 -Olli




 interface Modification {
 /**
 * type is either TextChange, ChildListChange or AttrChange.
 * (More types can be added later if needed.)
 */
 readonly attribute DOMString type;

 /**
 * Target of the change.
 * If an attribute is changed, target is the element,
 * if an element is added or removed, target is the node
 * which was added or removed.
 * If text is changed, target is the CharacterData node which was
 * changed.
 */
 readonly attribute Node target;
 /**
 * parent node of the target right before the change happened,
 * or null.
 */
 readonly attribute Node targetParent;
 /**
 * The node which is batching the change.
 */
 readonly attribute Node currentTarget;

 /**
 * The name of the attribute which was changed, or null.
 */
 readonly attribute DOMString attrName;

 /*
 * The previous value of the attribute or CharacterData node, or null.
 * If a new attribute is added, prevValue is null.
 */
 readonly attribute DOMString prevValue;

 /*
 * The new value of the attribute or CharacterData node, or null.
 * If an attribute is removed, newValue is null.
 */
 readonly attribute DOMString newValue;
 };

 [Callback, NoInterfaceObject]
 interface ModificationCallback {
 void handleBatch(in ModificationBatch aBatch);
 };

 [Constructor(in ModificationCallback aDoneCallback)]
 interface ModificationBatch {
 /**
 * Modifications is non-empty array only while aDoneCallback
 * is called. And while that happens, modifications list doesn't
 * change.
 */
 readonly attribute Modification[] modifications;

 void batchTextChanges(in Node aNode);
 void unbatchTextChanges(in Node aNode);

 void batchChildListChanges(in Node aNode);
 void unbatchChildListChanges(in Node aNode);

 void batchAttrChanges(in Node aNode);
 void unbatchAttrChanges(in Node aNode);

 void batchAll();
 void unbatchAll();
 };

 aDoneCallback is called right before the call which is modifying DOM
 returns. If aDoneCallback modifies DOM, new modifications list will be
 collected
 and callbacks will be called right after the initial aDoneCallback
 returns.
 ModificationBatches are always handled in the order they are *created*.
 Callbacks are never called if modifications list is empty.


 Example 1:
 // log all the attribute changes
 var o = new ModificationBatch(function(b) {
 for (var i = 0; i  b.modifications.length; ++i) {
 var m = b.modifications[i];
 if (m.prevValue == null) {
 console.log(m.attrName +  added);
 } else if (m.newValue == null) {
 console.log(m.attrName +  removed);
 } else {
 console.log(m.attrName +  modified);
 }
 }
 }
 );
 o.batchAttrChanges(document);










DOM Mutation Events Replacement: The Story So Far / Existing Points of Consensus

2011-08-10 Thread Rafael Weinstein
What follows is an attempt to summarize the (relatively recent)
discussions regarding replacing DOM Mutation Events.

My goals here are to:

-Provide a quick primer for those who haven't read all hundred or so emails.
-Reiterate the aspects of a solution which seem to have broad support.
-Identify the main points of divergence which remain.


Problem: DOM Mutation events as currently specified and implemented
are widely viewed as fatally flawed because they are:

(1) Verbose (fire too often)
(2) Slow (because of event propagation -- and because they prevent
certain UA run-time optimizations)
(3) Crashy (have been the source of many crashers for UAs because
script can tear up the world in any way it wishes while a DOM
operation is underway).


Solution:

*Agreed upon design points:

Primarily because of a proposal made by Jonas Sicking in 2009, the
group has been largely in agreement about the following:

(1) The vocabulary of mutations should be more expressive and require
fewer words to adequately describe what happened . For instance, a
single innerHTML assignment which results in removing N nodes and
inserting M nodes should be expressed as a single mutation (e.g. {
mutation: ChildlistChanged, added: [...], removed: [...] } ) -- not
a sequence of mutations, one for each node inserted or removed.

(2) Mutations should avoid the expense of event propagation (mainly
capture  bubble).

(3) Mutations should be delivered to observers after the DOM
operations which generated them complete -- removing the possibility
of having script interfere with their operation. For example, an
execCommand() operation is permitted to make any  all DOM operations
it needs *before* it has to notify any observers of what happened.

Through discussing Jonas's proposal, we observed that in a system
which allows multiple observers that can, themselves, make mutations,
observers will generally need to be tolerant of an arbitrary number of
mutations having occurred before being notified.

Further, there is strong performance motivation for observers to
respond to the net-effect of a set of mutations, rather than acting
immediately in response to each mutation.

Thus:

(4) Observers should be called with the *set* of mutations which has
occurred since they were last called (or since registration), rather
than being called once per mutation. I.e. Deliver mutations in batches
of everything that has happened since the last time I called you -
up till now.

To my understanding, the most recent proposals made by Jonas, Olli
Pettay, Adam Klein and myself all agree on the above four design
points.


*Design points lacking consensus:

(5) When are mutations delivered? There are four options here, only
two of which have proponents.

=I'm going to try to summarize the discussion on this point in a
separate email.

(6) The semantics for expressing interest in sets of nodes
(7) What information is contained in mutation records

=I've done a survey of the main use cases sited and prototyped the
main net-effect projections. I'll summarize my findings in another
email which attempts to layout the main trade-offs I see so far.



DOM Mutation Events Replacement: When to deliver mutations

2011-08-10 Thread Rafael Weinstein
Although everyone seems to agree that mutations should be delivered
after the DOM operations which generated them complete, the question
remains:

  When, exactly, should mutations be delivered?

The four options I'm aware of are:

1) Immediately - i.e. while the operation is underway. [Note: This is
how current DOM Mutation events work].

2) Upon completion of the outer-most DOM operation. i.e. Immediately
before a the lowest-on-the-stack DOM operation returns, but after it
has done all of its work.

3) At the end of the current Task. i.e. immediately before the UA is
about to fetch a new Task to run.

4) Scheduled as a future Task. i.e. fully async.

---

Discussion:

Options 1  4 are don't seem to have any proponents that I know of, so briefly:

Option 1, Immediately:

Pro:
-It's conceptually the easiest thing to understand. The following *always* hold:
  -For calling code: When any DOM operation I make completes, all
observers will have run.
  -For notified code: If I'm being called, the operation which caused
this is below me on the stack.

Con:
-Because mutations must be delivered for some DOM operations before
the operation is complete, UAs must tolerate all ways in which script
may invalidate their assumptions before they do further work.


Option 4, Scheduled as a future Task:

Pro:
-Conceptually easy to understand
-Easy to implement.

Con:
-It's too late. Most use cases for mutation observation require that
observers run before a paint occurs. E.g. a widget library which
watches for special attributes. Script may create a div
class=FooButton and an observer will react to this by decorating
the div as a FooButton. It is unacceptable (creates visual
artifacts/flickering) to have the div be painted before the widget
library has decorated it as a FooButton.

Both of these options appear to be non-starters. Option 1 has been
shown by experience to be an unreasonable implementation burden for
UAs. Option 4 clearly doesn't handle properly important use cases.

---

Options 2  3 have proponents. Since I'm one of them (a proponent),
I'll just summarize the main *pro* arguments for each and invite those
who wish (including myself), to weigh in with further support or
criticism in follow-on emails.


Option 2: Upon completion of the outer-most DOM operation.

Pro:
-It's conceptually close to fully synchronous. For simple uses
(specifically, setting aside the case of making DOM operations within
a mutation callback), it has the advantages of Option 1, without its
disadvantages. Because of this, it's similar to the behavior of
current Mutation Events.

Option 3: At the end of the current Task.

Pro:
-No code is at risk for having its assumptions invalidated while it is
trying to do work. All participants (main application script,
libraries which are implemented using DOM mutation observation) are
allowed to complete whatever work (DOM operations) they wish before
another participant starts doing work.



Re: DOM Mutation Events Replacement: When to deliver mutations

2011-08-10 Thread Rafael Weinstein
Ok. Being a proponent, here's my further (opinionated) support for
Option 3 and criticism for Option 2.

On Wed, Aug 10, 2011 at 5:44 PM, Rafael Weinstein rafa...@google.com wrote:
 Although everyone seems to agree that mutations should be delivered
 after the DOM operations which generated them complete, the question
 remains:

  When, exactly, should mutations be delivered?

 The four options I'm aware of are:

 1) Immediately - i.e. while the operation is underway. [Note: This is
 how current DOM Mutation events work].

 2) Upon completion of the outer-most DOM operation. i.e. Immediately
 before a the lowest-on-the-stack DOM operation returns, but after it
 has done all of its work.

 3) At the end of the current Task. i.e. immediately before the UA is
 about to fetch a new Task to run.

 4) Scheduled as a future Task. i.e. fully async.

 ---

 Discussion:

 Options 1  4 are don't seem to have any proponents that I know of, so 
 briefly:

 Option 1, Immediately:

 Pro:
 -It's conceptually the easiest thing to understand. The following *always* 
 hold:
  -For calling code: When any DOM operation I make completes, all
 observers will have run.
  -For notified code: If I'm being called, the operation which caused
 this is below me on the stack.

 Con:
 -Because mutations must be delivered for some DOM operations before
 the operation is complete, UAs must tolerate all ways in which script
 may invalidate their assumptions before they do further work.


 Option 4, Scheduled as a future Task:

 Pro:
 -Conceptually easy to understand
 -Easy to implement.

 Con:
 -It's too late. Most use cases for mutation observation require that
 observers run before a paint occurs. E.g. a widget library which
 watches for special attributes. Script may create a div
 class=FooButton and an observer will react to this by decorating
 the div as a FooButton. It is unacceptable (creates visual
 artifacts/flickering) to have the div be painted before the widget
 library has decorated it as a FooButton.

 Both of these options appear to be non-starters. Option 1 has been
 shown by experience to be an unreasonable implementation burden for
 UAs. Option 4 clearly doesn't handle properly important use cases.

 ---

 Options 2  3 have proponents. Since I'm one of them (a proponent),
 I'll just summarize the main *pro* arguments for each and invite those
 who wish (including myself), to weigh in with further support or
 criticism in follow-on emails.


 Option 2: Upon completion of the outer-most DOM operation.

 Pro:
 -It's conceptually close to fully synchronous. For simple uses
 (specifically, setting aside the case of making DOM operations within
 a mutation callback), it has the advantages of Option 1, without its
 disadvantages. Because of this, it's similar to the behavior of
 current Mutation Events.

Con:

-The timing delays delivery just long enough to guarantee that DOM
operations don't have to worry about having their work interfered
with, but encourages application script to leave itself exposed to
exactly the same risk.

-The semantics of delivery are inconsistent. Delivery of mutations is
synchronous if calling operation is performed outside of a mutation
callback and async if performed inside a mutation callback.


 Option 3: At the end of the current Task.

 Pro:
 -No code is at risk for having its assumptions invalidated while it is
 trying to do work. All participants (main application script,
 libraries which are implemented using DOM mutation observation) are
 allowed to complete whatever work (DOM operations) they wish before
 another participant starts doing work.



Pro:
-Creates (and requires use of -- creates a pit of success) a time to
run which is ideal in two ways:

1) Performance: The main script is finished doing its work. The
observer can minimize work by reacting to only the net-effect of what
happened. I.e. not do work in intermediate states which ultimately
become irrelevant. E.g. a widget library which needs to destruct
widgets which are removed from the document. If a widget is removed
but later added elsewhere in the same script event, the library would
prefer to avoid destructing the widget and just allow it to be moved.

2) Correctness: The observer isn't at risk for attempting to act when
the main script has put the DOM (temporarily) in an inconsistent
state. E.g. a templating library which depends upon the value of two
attributes of a single element. If script wishes to change both values
but cannot do so without creating a temporarily nonsensical state, the
library would prefer not to have to react to the nonsensical state and
simply wait for the consistent (final) state.

To be fair to Option 2, it doesn't preclude these (but it isn't
sufficient -- a separate ability to schedule work at the end of the
Task would be required).

Con:
-Behaves quite differently from the current mutation events.



Re: Mutation events replacement

2011-07-22 Thread Rafael Weinstein
On Tue, Jul 19, 2011 at 4:56 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Tue, Jul 19, 2011 at 4:18 PM, Ryosuke Niwa rn...@webkit.org wrote:
 Thanks for the new proposal, Jonas.  I'm very excited about the progress
 we're making towards a saner world!
 On Tue, Jul 19, 2011 at 4:01 PM, Jonas Sicking jo...@sicking.cc wrote:

 [ { target: node1, type: childlist, added: [a, b, c, d], removed: [x, y]
 },
  { target: node1, type: attributes, changed: [class, bgcolor,
 href] },
  { target: node2, type: characterdata },
  { target: node3, type: childlist, added: [r, s, t, x], removed: [z] } ]

 A few things to note here:

 * There is only ever one entry in the array for a given target+type
 pair. If, for example, multiple changes are made to the classlist of a
 given node, these changes are added to the added/removed lists.
 * For childlist changes, you get the full list of which nodes were
 added and removed.

 For editing purposes, it's also crucial to know from/to where nodes are
 removed/inserted.  It seems like adding an offset trivially solves this
 problem without much overhead.

 I'm not really sure how you're expecting to use indexes. Not that once
 one node is removed, the index changes for all other nodes. Can you
 provide a short example code demonstrating how you'd use the index?

It's not really short, but it's more or less the analog of doing a
projection of a set of splice events if emitted by a hypothetical
observable array (startIndex, numDeleted, numAdded). The code is
implemented inside MDV here:

https://code.google.com/p/mdv/source/browse/trunk/model.js#853

The goal of the projection is to produce a new set of splice mutation
records which represent the net effect on the sequence (joining,
collapsing, canceling), such that the new set minimally describes the
changes and could be applied, in order, to a copy of the sequence's
previous state to arrive at the new state.


 * For attributes changes you get a full list of which attributes
 were changed. However you do not get the new and old value of the
 attributes as this could result in significant overhead for attributes
 like style for example.

 Again, it'll be very useful to have old and new values for editing purposes.
  Although I have a reservation as to whether we should do for style or not
 because calling mutation listeners every time script modifies some style
 property will be quite expensive as it requires serializing
 CSSStyleDeclaration.

 * For characterdata you don't get the old or new value of the node.
 We could also simply add the before/after values here as there
 shouldn't be as much serialization overhead involved.

 For editing purposes, seeing old and new value is essential.

 As has been previously mentioned, providing the old value comes with
 significant overhead. For your usecase it seems like this is overhead
 that you'll need to live with, but for many others it might not be.

 We could solve this by making it configurable if you want the old
 values or not. For example by having separate notification types that
 contain before and after values.

 Though note that providing the after-values rarely seems useful as you
 can simply get them as needed from the DOM. As for childlists, the
 only sane solution I can think of would be to provide what the whole
 childlist looked like before modifications started.

 / Jonas




Re: Mutation events replacement

2011-07-07 Thread Rafael Weinstein
On Thu, Jul 7, 2011 at 1:58 PM, Ryosuke Niwa rn...@webkit.org wrote:
 On Thu, Jul 7, 2011 at 12:18 PM, Jonas Sicking jo...@sicking.cc wrote:

 I don't think John J Barton's proposal to fire before mutation
 notifications is doable.

 I concur.  Being synchronous was one of the reasons why the existing DOM
 mutation events don't work.  We shouldn't adding yet-another synchronous
 event here.

 In short before spending more time on this, I'd like to see a
 comprehensive proposal, including a description of the use cases it
 solves and how it solves them. I strongly doubt that this approach is
 practical.

 Totally agreed.

 I really like Rafael's proposal to pass a list of mutations that has
 happened to the notification callbacks. This has the advantage that
 scripts get *all* the changes that has happened at once, making it
 possible to make decisions based on all changes made, rather than
 piece-wise getting the information in separate callbacks. It also has
 the advantage that we can provide much more detailed information
 without having to make multiple calls from C++ to JS which is good for
 performance. For example it seems very doable to provide lists of all
 nodes that has been removed and added while still keeping performance
 reasonable.

 Enthusiastically agreed.

 I'll write up a proposal based on this idea. Others should feel free
 to beat me to it :)

 Nice!  Looking forward to it.

 The main concern that I have with this proposal is that it's so
 different from mutation events that it might not satisfy the same use
 cases. Consider a widget implementation that currently observes the
 DOM using mutation events and makes it possible to write code like:

 myWidgetBackedElement.appendChild(someNode);
 myWidgetBackedElement.someFunction();

 where someFunction depends on state which is updated by the mutation
 event handler. Such a widget implementation is simply not doable with
 these semi-asynchronous callbacks.

 Right.  But on the other hand, if this code were to run inside a mutation
 observer, it won't work in your proposal either.  So the questions is
 whether writing a function that depends on state updated by the mutation
 observer without a mutation observer, and then later calling it inside a
 mutation observer happens frequently enough to annoy developers or not.

 On the other hand, maybe this isn't a big deal. We are definitely
 short on use cases for mutation events in general which is a problem.

Right. Olli  Jonas, I'd really like to understand your thinking about this.

Are we not understanding something about your proposal?

If accommodating the above is a goal, it seems like the only option is
to have mutation events be fully synchronous. I.e. It doesn't seem
acceptable to encourage a widget author to expose an API that depends
on never being called inside a mutation callback and/or prevents it
from being used as a building block for a higher-level abstraction.


 Agreed.  We probably need more real-world use cases.
 - Ryosuke




Re: Mutation events replacement

2011-07-07 Thread Rafael Weinstein
On Thu, Jul 7, 2011 at 3:19 PM, Jonas Sicking jo...@sicking.cc wrote:
 On Thu, Jul 7, 2011 at 2:32 PM, Rafael Weinstein rafa...@google.com wrote:
 On Thu, Jul 7, 2011 at 1:58 PM, Ryosuke Niwa rn...@webkit.org wrote:
 On Thu, Jul 7, 2011 at 12:18 PM, Jonas Sicking jo...@sicking.cc wrote:

 I don't think John J Barton's proposal to fire before mutation
 notifications is doable.

 I concur.  Being synchronous was one of the reasons why the existing DOM
 mutation events don't work.  We shouldn't adding yet-another synchronous
 event here.

 In short before spending more time on this, I'd like to see a
 comprehensive proposal, including a description of the use cases it
 solves and how it solves them. I strongly doubt that this approach is
 practical.

 Totally agreed.

 I really like Rafael's proposal to pass a list of mutations that has
 happened to the notification callbacks. This has the advantage that
 scripts get *all* the changes that has happened at once, making it
 possible to make decisions based on all changes made, rather than
 piece-wise getting the information in separate callbacks. It also has
 the advantage that we can provide much more detailed information
 without having to make multiple calls from C++ to JS which is good for
 performance. For example it seems very doable to provide lists of all
 nodes that has been removed and added while still keeping performance
 reasonable.

 Enthusiastically agreed.

 I'll write up a proposal based on this idea. Others should feel free
 to beat me to it :)

 Nice!  Looking forward to it.

 The main concern that I have with this proposal is that it's so
 different from mutation events that it might not satisfy the same use
 cases. Consider a widget implementation that currently observes the
 DOM using mutation events and makes it possible to write code like:

 myWidgetBackedElement.appendChild(someNode);
 myWidgetBackedElement.someFunction();

 where someFunction depends on state which is updated by the mutation
 event handler. Such a widget implementation is simply not doable with
 these semi-asynchronous callbacks.

 Right.  But on the other hand, if this code were to run inside a mutation
 observer, it won't work in your proposal either.  So the questions is
 whether writing a function that depends on state updated by the mutation
 observer without a mutation observer, and then later calling it inside a
 mutation observer happens frequently enough to annoy developers or not.

 On the other hand, maybe this isn't a big deal. We are definitely
 short on use cases for mutation events in general which is a problem.

 Right. Olli  Jonas, I'd really like to understand your thinking about this.

 Are we not understanding something about your proposal?

 If accommodating the above is a goal, it seems like the only option is
 to have mutation events be fully synchronous. I.e. It doesn't seem
 acceptable to encourage a widget author to expose an API that depends
 on never being called inside a mutation callback and/or prevents it
 from being used as a building block for a higher-level abstraction.

 It's definitely the case that APIs will behave differently inside the
 mutation notification, and that the code example showed above would
 not work from inside the notification.

 Basically I'm asking people to tread carefully inside mutation
 notifications and only do the minimal amount of data gathering.

Heh. We're kind of in violent agreement here. =-)


 So yes, my proposal only solves the usecase outside mutation handlers.
 However this is arguably better than never solving the use case as in
 your proposal. I'm sure people will end up writing buggy code, but
 ideally this will be found and fixed fairly easily as the behavior is
 consistent. We are at least giving people the tools needed to
 implement the synchronous behavior.

Ok. Thanks for clarifying. It's helpful to understand this.

I'm glad there's mostly common ground on the larger issue. The point
of contention is clearly whether accommodating some form of sync
mutation actions is a goal or non-goal.

It occurs to me that the main use case raised in favor of sync
mutation actions is more or less the custom component/widget use case.
This seems to border alot on XBL2. Maybe it's useful to look at it
through that lens?

/me grabs blindly at the air for good ideas about how to come to consensus.


 / Jonas




Re: Mutation events replacement

2011-07-05 Thread Rafael Weinstein
Respond

On Tue, Jul 5, 2011 at 10:44 AM, Olli Pettay olli.pet...@helsinki.fi wrote:
 On 07/01/2011 02:17 AM, Rafael Weinstein wrote:

 On Thu, Jun 30, 2011 at 4:05 AM, Olli Pettayolli.pet...@helsinki.fi
  wrote:

 On 06/30/2011 12:54 AM, Rafael Weinstein wrote:

 On Wed, Jun 29, 2011 at 7:13 AM, Aryeh Gregorsimetrical+...@gmail.com
  wrote:

 On Tue, Jun 28, 2011 at 5:24 PM, Jonas Sickingjo...@sicking.cc
  wrote:

 This new proposal solves both these by making all the modifications
 first, then firing all the events. Hence the implementation can
 separate implementing the mutating function from the code that sends
 out notifications.

 Conceptually, you simply queue all notifications in a queue as you're
 making modifications to the DOM, then right before returning from the
 function you insert a call like flushAllPendingNotifications(). This
 way you don't have to care at all about what happens when those
 notifications fire.

 So when exactly are these notifications going to be fired?  In
 particular, I hope non-DOM Core specifications are going to have
 precise control over when they're fired.  For instance, execCommand()
 will ideally want to do all its mutations at once and only then fire
 the notifications (which I'm told is how WebKit currently works).  How
 will this work spec-wise?  Will we have hooks to say things like
 remove a node but don't fire the notifications yet, and then have to
 add an extra line someplace saying to fire all the notifications?
 This could be awkward in some cases.  At least personally, I often say
 things like call insertNode(foo) on the range in the middle of a
 long algorithm, and I don't want magic happening at that point just
 because DOM Range fires notifications before returning from
 insertNode.

 Also, even if specs have precise control, I take it the idea is
 authors won't, right?  If a library wants to implement some fancy
 feature and be compatible with users of the library firing these
 notifications, they'd really want to be able to control when
 notifications are fired, just like specs want to.  In practice, the
 only reason this isn't an issue with DOM mutation events is because
 they can say don't use them, and in fact people rarely do use them,
 but that doesn't seem ideal -- it's just saying library authors
 shouldn't bother to be robust.

 In working on Model Driven Views (http://code.google.com/p/mdv), we've
 run into exactly this problem, and have developed an approach we think
 is promising.

 The idea is to more or less take Jonas's proposal, but instead of
 firing callbacks immediately before the outer-most mutation returns,
 mutations are recorded for a given observer and handed to it as an
 in-order sequence at the end of the event.

 What is the advantage comparing to Jonas' proposal?

 You guys did the conceptual heavy lifting WRT this problem. Jonas's
 proposal solves the main problems with current mutation events: (1)
 they fire too often, (2) they are expensive because of event
 propagation, (3) they are crashy WRT some DOM operations.

 If Jonas's proposal is the ultimate solution, I think it's a good
 outcome and a big improvement over existing spec or tearing out
 mutation events. I'm asking the group to consider a few changes which
 I'm hoping are improvements.

 I'll be happy if I fail =-).

 ---

 My concern with Jonas's proposal is that its semantics depend on
 context (inside vs. outside of a mutation notification). I feel like
 this is at least a conceptual problem. That, and I kind of shudder
 imagining trying to explain to a webdev why and when mutation
 notifications are sync vs async.

 The place it seems likely to fall down is when someone designs an
 abstraction using mutation events and depends on them firing
 synchronously -- then they or someone else attempt to use it inside
 another abstraction which uses mutation events. How likely is that? I
 don't even have a guess, but I'm pretty surprised at the crazy things
 people did with current mutation events.

 Our proposal's semantics aren't dependent on context.

 Additionally, our proposal makes it clear that handling a mutation
 notification is an exercise in dealing with an arbitrary number of
 ways the DOM could have changed since you were last called. I.e.
 providing the list of changes.

 In short, I feel like our proposal is just a small tweak on Jonas's.
 It is more direct in its form and API about the actually difficultly
 of being a mutation observer.

 Also, I'll just note a difference in view: We view it as fundamentally
 a bad thing to have more than one actor operating at a time (where
 actor == event handler, or abstraction which observes mutations). It
 seems as though you guys view this as a good thing (i.e. All other
 problems aside, mutation events *should* be synchronous).

 The example I keep using internally is this: an app which uses

 a) A constraint library which manages interactions between form values
 (observes data mutations, makes data

Re: Mutation events replacement

2011-07-05 Thread Rafael Weinstein
On Mon, Jul 4, 2011 at 6:43 PM, Boris Zbarsky bzbar...@mit.edu wrote:
 On 7/4/11 12:28 PM, Ojan Vafai wrote:

 I'm not sure there really is a performance tradeoff. I believe that the
 proposal Rafael put forward should almost always be faster. Storing the
 list of changes and doing a JS callback once, for nearly all use-cases,
 should be faster than frequent, semi-synchronous callbacks.

 That depends on whether your list of changes gets big enough that your start
 swapping, for example.

Just to be clear here (since there's been some discussion of a flag
which would cause fine-grain notifications) -- I don't believe
there's any need to describe *more* mutations. I.e. My proposal is
*not* to record more than one mutation record for a call to innerHTML
which affects more than one element. That case would still be a single
'ChildlistChanged' mutation. This is a key part of Jonas's proposal
that we want to keep: It is (I think) optimally succinct, while still
containing (nearly -- see below) all the bits of information that you
need.

I.e. The set of mutation records during any given event should be more
or less on the order of the number of DOM *operations* -- not affected
nodes. Also note that it seems like the multiple observers can share
the same mutation record (just like multiple event listeners share the
same event object).

The question is how much data is contained in the mutation record.
Here's my sense:

For ChildlistChanged, the potential data to be included:
-Target node*
-Removed nodes*
-Added nodes
-one of nextSibling or previousSibling*

My belief is that including the starred (*) data above would be
sufficient to meet David's test of mirroring a tree *without* a ton of
processing or O(N) memory.

If people think it's worth while seeing example js code that
implements this properly and it'll convince the group that this data
is sufficient, I'll sign up for implementing it.


 The only bit that might be slower is what data you include in the
 mutation list.

 That's one of the things that could get slower, yes.  It's not the only one.

 -The index of the child that changed for ChildListChanged (is this
 actually expensive?)

 It could be.  In Gecko's case it's cheap right now because kids are stored
 in arrays, but WebKit uses doubly linked lists with a cache of some sort for
 indices last I checked.  So for some access patterns this could be pretty
 expensive in WebKit.

 -The old value of an attribute/text node. I know this is expensive in
 Gecko's engine at least.

 This can be expensive in all engines, if they do it right.  Consider having
 to serialize out values of the 'style' attribute (possibly twice) on every
 .style.foo set.  Or having to serialize out path attributes as the SVG DOM
 is mutating paths.  This is not a Gecko-specific issue.

 I'd be fine with excluding that information by default, but having a
 flag you pass at some point saying to include those. That way, only
 sites that need it take the performance hit.

 This would be a lot more palatable to me, yes.  This brings us back to
 having ways to ask for different levels of detail in mutation notifications.

 -Boris





Re: Mutation events replacement

2011-07-05 Thread Rafael Weinstein
On Mon, Jul 4, 2011 at 9:57 AM, Olli Pettay olli.pet...@helsinki.fi wrote:
 On 07/04/2011 07:28 PM, Ojan Vafai wrote:

 Apologies in advance if my comment makes no sense. This is a long
 thread, I tried to digest it all. :)

 On Sat, Jul 2, 2011 at 7:07 AM, Boris Zbarsky bzbar...@mit.edu
 mailto:bzbar...@mit.edu wrote:

    That may be ok, if the use cases that incur this cost are rare and
    the common case can be better served by a different approach.

    Or put another way, if 1% of consumers want the full list because it
    makes them 4x faster and the other 99% don't want the full list, and
    the full list is 3x slower for the browser to build than just
    providing the information the 99% want, what's the right tradeoff?


 I'm not sure there really is a performance tradeoff. I believe that the
 proposal Rafael put forward should almost always be faster. Storing the
 list of changes and doing a JS callback once, for nearly all use-cases,
 should be faster than frequent, semi-synchronous callbacks.

 The only bit that might be slower is what data you include in the
 mutation list. I believe that all the data you'd need is cheap except
 for possibly the following two:
 -The index of the child that changed for ChildListChanged (is this
 actually expensive?)

 You may need more than just an index. element.innerHTML = null removes
 all the child nodes.
 And element.inserBefore(some_document_fragment, element.lastChild)
 may insert several child nodes.
 Depending on whether we want to get notified for each mutation
 or batch the mutations, simple index may or may not be enough.

I think both of these can be a single ChildlistChanged mutation (not
a batch of mutations).



 -The old value of an attribute/text node. I know this is expensive in
 Gecko's engine at least.

 Shouldn't be that slow.

 Mutation listener could easily
 implement old/new value handling itself, especially if it knows which
 attributes it is interested in.




 I'd be fine with excluding that information by default, but having a
 flag you pass at some point saying to include those. That way, only
 sites that need it take the performance hit.

    The numbers above are made up, of course; it would be useful to have
    some hard data on the actual use cases.

    Maybe we need both sorts of APIs: one which generates a fine-grained
    change list and incurs a noticeable DOM mutation performance hit and
    one which batches changes more but doesn't slow the browser down as
    much...

    -Boris








Re: Mutation events replacement

2011-07-05 Thread Rafael Weinstein
On Tue, Jul 5, 2011 at 2:27 PM, Boris Zbarsky bzbar...@mit.edu wrote:
 On 7/5/11 5:21 PM, Rafael Weinstein wrote:

 For ChildlistChanged, the potential data to be included:
 -Target node*
 -Removed nodes*
 -Added nodes
 -one of nextSibling or previousSibling*

 My belief is that including the starred (*) data above would be
 sufficient to meet David's test of mirroring a tree *without* a ton of
 processing or O(N) memory.

 How is that not O(N) memory?

Sorry - that was imprecise. What I meant was: the application script
wouldn't need to maintain more or less it's own copy of the DOM to
know for certain whether a node has effectively been added, removed,
or moved elsewhere in the document.


 -Boris




Re: Mutation events replacement

2011-07-05 Thread Rafael Weinstein
On Tue, Jul 5, 2011 at 2:29 PM, Rafael Weinstein rafa...@google.com wrote:
 On Tue, Jul 5, 2011 at 2:27 PM, Boris Zbarsky bzbar...@mit.edu wrote:
 On 7/5/11 5:21 PM, Rafael Weinstein wrote:

 For ChildlistChanged, the potential data to be included:
 -Target node*
 -Removed nodes*
 -Added nodes
 -one of nextSibling or previousSibling*

 My belief is that including the starred (*) data above would be
 sufficient to meet David's test of mirroring a tree *without* a ton of
 processing or O(N) memory.

Doh! Sorry. Just to note: if you omit Added Nodes, I think you'd need
AddedNodeCount.

Generally speaking, to avoid application script needing to make copies
of wholesale DOM structures, it needs to be given the old data and
the shape of the new data

E.g.:
For ChildlistChanged: removedNodes + addedNodeCount  next/previousSibling.
For AttributeChanged: added/removed/updated + oldValue
For TextChanged: oldValue.

This may be an unreasonable burden for UA's to deliver all the time.
If so, a give me old data flag seems worth considering.

Many use-cases will be aiming to minimize expensive work (typically
creating more DOM or writing to the wire) -- and it'll be tempting to
guarantee that work *has* to be done. Lacking old data, the
application will need to preemptively make a copy of all data that
*could* change.


 How is that not O(N) memory?

 Sorry - that was imprecise. What I meant was: the application script
 wouldn't need to maintain more or less it's own copy of the DOM to
 know for certain whether a node has effectively been added, removed,
 or moved elsewhere in the document.


 -Boris





Re: Mutation events replacement

2011-07-05 Thread Rafael Weinstein
On Tue, Jul 5, 2011 at 2:38 PM, Olli Pettay olli.pet...@helsinki.fi wrote:
 On 07/06/2011 12:18 AM, Olli Pettay wrote:

 On 07/06/2011 12:06 AM, Rafael Weinstein wrote:

 Respond

 On Tue, Jul 5, 2011 at 10:44 AM, Olli Pettayolli.pet...@helsinki.fi
 wrote:

 On 07/01/2011 02:17 AM, Rafael Weinstein wrote:

 On Thu, Jun 30, 2011 at 4:05 AM, Olli Pettayolli.pet...@helsinki.fi
 wrote:

 On 06/30/2011 12:54 AM, Rafael Weinstein wrote:

 On Wed, Jun 29, 2011 at 7:13 AM, Aryeh
 Gregorsimetrical+...@gmail.com
 wrote:

 On Tue, Jun 28, 2011 at 5:24 PM, Jonas Sickingjo...@sicking.cc
 wrote:

 This new proposal solves both these by making all the modifications
 first, then firing all the events. Hence the implementation can
 separate implementing the mutating function from the code that
 sends
 out notifications.

 Conceptually, you simply queue all notifications in a queue as
 you're
 making modifications to the DOM, then right before returning
 from the
 function you insert a call like
 flushAllPendingNotifications(). This
 way you don't have to care at all about what happens when those
 notifications fire.

 So when exactly are these notifications going to be fired? In
 particular, I hope non-DOM Core specifications are going to have
 precise control over when they're fired. For instance, execCommand()
 will ideally want to do all its mutations at once and only then fire
 the notifications (which I'm told is how WebKit currently works).
 How
 will this work spec-wise? Will we have hooks to say things like
 remove a node but don't fire the notifications yet, and then
 have to
 add an extra line someplace saying to fire all the notifications?
 This could be awkward in some cases. At least personally, I often
 say
 things like call insertNode(foo) on the range in the middle of a
 long algorithm, and I don't want magic happening at that point just
 because DOM Range fires notifications before returning from
 insertNode.

 Also, even if specs have precise control, I take it the idea is
 authors won't, right? If a library wants to implement some fancy
 feature and be compatible with users of the library firing these
 notifications, they'd really want to be able to control when
 notifications are fired, just like specs want to. In practice, the
 only reason this isn't an issue with DOM mutation events is because
 they can say don't use them, and in fact people rarely do use
 them,
 but that doesn't seem ideal -- it's just saying library authors
 shouldn't bother to be robust.

 In working on Model Driven Views (http://code.google.com/p/mdv),
 we've
 run into exactly this problem, and have developed an approach we
 think
 is promising.

 The idea is to more or less take Jonas's proposal, but instead of
 firing callbacks immediately before the outer-most mutation returns,
 mutations are recorded for a given observer and handed to it as an
 in-order sequence at the end of the event.

 What is the advantage comparing to Jonas' proposal?

 You guys did the conceptual heavy lifting WRT this problem. Jonas's
 proposal solves the main problems with current mutation events: (1)
 they fire too often, (2) they are expensive because of event
 propagation, (3) they are crashy WRT some DOM operations.

 If Jonas's proposal is the ultimate solution, I think it's a good
 outcome and a big improvement over existing spec or tearing out
 mutation events. I'm asking the group to consider a few changes which
 I'm hoping are improvements.

 I'll be happy if I fail =-).

 ---

 My concern with Jonas's proposal is that its semantics depend on
 context (inside vs. outside of a mutation notification). I feel like
 this is at least a conceptual problem. That, and I kind of shudder
 imagining trying to explain to a webdev why and when mutation
 notifications are sync vs async.

 The place it seems likely to fall down is when someone designs an
 abstraction using mutation events and depends on them firing
 synchronously -- then they or someone else attempt to use it inside
 another abstraction which uses mutation events. How likely is that? I
 don't even have a guess, but I'm pretty surprised at the crazy things
 people did with current mutation events.

 Our proposal's semantics aren't dependent on context.

 Additionally, our proposal makes it clear that handling a mutation
 notification is an exercise in dealing with an arbitrary number of
 ways the DOM could have changed since you were last called. I.e.
 providing the list of changes.

 In short, I feel like our proposal is just a small tweak on Jonas's.
 It is more direct in its form and API about the actually difficultly
 of being a mutation observer.

 Also, I'll just note a difference in view: We view it as fundamentally
 a bad thing to have more than one actor operating at a time (where
 actor == event handler, or abstraction which observes mutations). It
 seems as though you guys view this as a good thing (i.e. All other
 problems aside, mutation events *should* be synchronous

Re: Mutation events replacement

2011-07-05 Thread Rafael Weinstein
On Tue, Jul 5, 2011 at 3:55 PM, Ryosuke Niwa rn...@webkit.org wrote:
 On Tue, Jul 5, 2011 at 3:24 PM, Olli Pettay olli.pet...@helsinki.fi wrote:

 On 07/06/2011 12:48 AM, Rafael Weinstein wrote:

 On Tue, Jul 5, 2011 at 2:38 PM, Olli Pettayolli.pet...@helsinki.fi
  wrote:

 What is the reason to require a new mechanism for async handling? Could
 listeners be handled in a task?Basically, if DOM is mutated during task A, 
 a
 new task, B, is scheduled and all the mutation listeners will be
 called there.

 It's too late by then. Most importantly, visual artifacts of incomplete
 DOM work may have been seen by the user.

 If that is the reason, I don't think it really holds. The script may force
 a layout flush right after DOM mutation and then cause some popup to shows
 up which may cause repainting in the main page.

 Layout is different from paint at least in WebKit.
 But I agree with you that if any observer calls alert, showModalDialog, and
 other APIs that forces repaint, you can't really do anything about it.
  Also, UA vendors can decide to delay the repaint until all mutation
 observers are called in common cases even if they were completely
 asynchronous.

It seems like these are rarified enough cases that visual artifacts
are acceptable collateral damage if you do this. [Put another way, if
you care enough about the visual polish of your app that you will put
energy into avoiding flickr, you probably aren't using alert and
showModalDialog anyway].

Also, it's up to the app when to do it, so it's entirely in its
control (and thus avoid visual artifacts).

Note that this is a problem with both proposals. Work done in (at
least some) mutation observers is delayed. If a sync paint occurs
before it, it's work won't be reflected on the screen.

 - Ryosuke




Re: Mutation events replacement

2011-07-01 Thread Rafael Weinstein
On Fri, Jul 1, 2011 at 12:43 PM, David Flanagan dflana...@mozilla.com wrote:
 On 7/1/11 12:13 PM, Boris Zbarsky wrote:

 On 7/1/11 3:05 PM, David Flanagan wrote:

 I don't think I really explained my use case on this list. See
 https://bugzilla.mozilla.org/show_bug.cgi?id=641821#c23 and
 https://bugzilla.mozilla.org/show_bug.cgi?id=641821#c25

 And https://bugzilla.mozilla.org/show_bug.cgi?id=641821#c26 please

 Yes, that too.  I agree that my use case is different than the one that
 Olli's proposal is addressing.  But Ryosuke asked about my use case :-)

  Similarly, I've found it important to

 be able to distinguish between nodes that are being removed from a
 document tree and nodes that are being moved within the document tree,

 Interesting, given that Gecko's DOM implementation does NOT make such a
 distinction at the moment.  Why did you find this to be important?

 As I see it, the test of sufficiency of set of mutation event is if you can
 use them to mirror a document tree. And in my case I'm trying to do that
 across a process boundary where I can't share nodes--I have to serialize
 everything to a string or something similar.  If I call appendChild() on a
 node that is already in the tree, that removes it from its current parent
 and inserts it into a new parent.  If that generates a remove event and then
 an insert event I'll end up having to completely re-serialize the node (and
 all of its children) to re-insert it from scratch into the mirror tree.  If
 the appendChild() generates a move event then I can simply serialize the
 fact that an existing node has moved.  There are probably ways I could make
 this work without a move event, but that's why I found it useful to make the
 distinction.

To clarify: Are you worried that it isn't possible to detect the move
and avoid serializing the non-novel node without the move
information in the underlying mutationList? Or are you concerned that
detecting this is work and it might be good to just provide the
information and remove the need for the observer to do that work?

Your point about the sufficiency test being mirroring a tree seems
exactly right to me. I may be missing something, but I think move
isn't strictly necessary.


 Implementations will presumably maintain one list of all current
 mutations, and then will have to filter that list to deliver only those
 that match the desired type and desired subtree for which a listener is
 registered.

 That's unclear.  Maintaining this list (if it were done) sounds very
 expensive; in Gecko's case we're more likely to drop on the floor the ones
 which have no registered listeners.

 Sure, but if there were multiple listeners on different subtrees, listening
 for different types of events, would you
 built up a custom mutation list for each one as the mutations were occuring?
  Or build up one master list and then filter it lazily when the events are
 dispatched?

    David

 -Boris






Re: Mutation events replacement

2011-07-01 Thread Rafael Weinstein
On Fri, Jul 1, 2011 at 3:25 PM, David Flanagan dflana...@mozilla.com wrote:
 On 7/1/11 3:06 PM, Olli Pettay wrote:

 On 07/02/2011 12:59 AM, David Flanagan wrote:

 But, and I think this is an interesting but, what happens if a node is
 removed from the document, has its attributes or data or children
 changed and is then re-inserted into the document? If the node has no
 parent when it is changed, no mutation events will be generated, will
 they?

 Sure they are. If the node has listeners, they will get called.

 I'm assuming the listeners are further up the tree.

 To give a concrete example, to a mutation event listener (under Rafael's
 proposal, but maybe yours, too?) on the document, these two sequences of
 operations will be indistinguishable:

 // Generates one event for removing the title text from the head and
 another for
 // inserting it into the body.  (Assume
 document.head.firstChild.firstChild is the text node inside
 // the title tag.
 document.body.appendChild(document.head.firstChild.firstChild);

 // Here we generate the same sequence of mutation events
 var titletext = document.head.firstChild.firstChild.
 titletext.parentNode.removeChild(titletext);  // Generates a remove event
 titletext.data = foobar;                               // Generates a
 mutation event no one sees
 document.body.appendChild(titletext);         // Generates an insert event

 I claim that it is useful to be able to distinguish these two cases with
 some sort of move event.  If moves are treated as remove/insert pairs, then
 listeners have to assume that arbitrary changes could have taken place
 between the two.

If you want to discover mutations to nodes while outside the tree,
then having a single subtree observer isn't sufficient. You'll need an
attribute observer registered on all elements reachable from the root.
I believe this is the same with both proposals.


    David






Re: Mutation events replacement

2011-06-30 Thread Rafael Weinstein
On Thu, Jun 30, 2011 at 4:05 AM, Olli Pettay olli.pet...@helsinki.fi wrote:
 On 06/30/2011 12:54 AM, Rafael Weinstein wrote:

 On Wed, Jun 29, 2011 at 7:13 AM, Aryeh Gregorsimetrical+...@gmail.com
  wrote:

 On Tue, Jun 28, 2011 at 5:24 PM, Jonas Sickingjo...@sicking.cc  wrote:

 This new proposal solves both these by making all the modifications
 first, then firing all the events. Hence the implementation can
 separate implementing the mutating function from the code that sends
 out notifications.

 Conceptually, you simply queue all notifications in a queue as you're
 making modifications to the DOM, then right before returning from the
 function you insert a call like flushAllPendingNotifications(). This
 way you don't have to care at all about what happens when those
 notifications fire.

 So when exactly are these notifications going to be fired?  In
 particular, I hope non-DOM Core specifications are going to have
 precise control over when they're fired.  For instance, execCommand()
 will ideally want to do all its mutations at once and only then fire
 the notifications (which I'm told is how WebKit currently works).  How
 will this work spec-wise?  Will we have hooks to say things like
 remove a node but don't fire the notifications yet, and then have to
 add an extra line someplace saying to fire all the notifications?
 This could be awkward in some cases.  At least personally, I often say
 things like call insertNode(foo) on the range in the middle of a
 long algorithm, and I don't want magic happening at that point just
 because DOM Range fires notifications before returning from
 insertNode.

 Also, even if specs have precise control, I take it the idea is
 authors won't, right?  If a library wants to implement some fancy
 feature and be compatible with users of the library firing these
 notifications, they'd really want to be able to control when
 notifications are fired, just like specs want to.  In practice, the
 only reason this isn't an issue with DOM mutation events is because
 they can say don't use them, and in fact people rarely do use them,
 but that doesn't seem ideal -- it's just saying library authors
 shouldn't bother to be robust.

 In working on Model Driven Views (http://code.google.com/p/mdv), we've
 run into exactly this problem, and have developed an approach we think
 is promising.

 The idea is to more or less take Jonas's proposal, but instead of
 firing callbacks immediately before the outer-most mutation returns,
 mutations are recorded for a given observer and handed to it as an
 in-order sequence at the end of the event.

 What is the advantage comparing to Jonas' proposal?

You guys did the conceptual heavy lifting WRT this problem. Jonas's
proposal solves the main problems with current mutation events: (1)
they fire too often, (2) they are expensive because of event
propagation, (3) they are crashy WRT some DOM operations.

If Jonas's proposal is the ultimate solution, I think it's a good
outcome and a big improvement over existing spec or tearing out
mutation events. I'm asking the group to consider a few changes which
I'm hoping are improvements.

I'll be happy if I fail =-).

---

My concern with Jonas's proposal is that its semantics depend on
context (inside vs. outside of a mutation notification). I feel like
this is at least a conceptual problem. That, and I kind of shudder
imagining trying to explain to a webdev why and when mutation
notifications are sync vs async.

The place it seems likely to fall down is when someone designs an
abstraction using mutation events and depends on them firing
synchronously -- then they or someone else attempt to use it inside
another abstraction which uses mutation events. How likely is that? I
don't even have a guess, but I'm pretty surprised at the crazy things
people did with current mutation events.

Our proposal's semantics aren't dependent on context.

Additionally, our proposal makes it clear that handling a mutation
notification is an exercise in dealing with an arbitrary number of
ways the DOM could have changed since you were last called. I.e.
providing the list of changes.

In short, I feel like our proposal is just a small tweak on Jonas's.
It is more direct in its form and API about the actually difficultly
of being a mutation observer.

Also, I'll just note a difference in view: We view it as fundamentally
a bad thing to have more than one actor operating at a time (where
actor == event handler, or abstraction which observes mutations). It
seems as though you guys view this as a good thing (i.e. All other
problems aside, mutation events *should* be synchronous).

The example I keep using internally is this: an app which uses

a) A constraint library which manages interactions between form values
(observes data mutations, makes data mutations)
b) A templating library (like MDV) which maps data to DOM (observes
both DOM and data mutations, makes both DOM and data mutations)
c) A widget library (like jQuery) which

Re: Mutation events replacement

2011-06-29 Thread Rafael Weinstein
On Wed, Jun 29, 2011 at 7:13 AM, Aryeh Gregor simetrical+...@gmail.com wrote:
 On Tue, Jun 28, 2011 at 5:24 PM, Jonas Sicking jo...@sicking.cc wrote:
 This new proposal solves both these by making all the modifications
 first, then firing all the events. Hence the implementation can
 separate implementing the mutating function from the code that sends
 out notifications.

 Conceptually, you simply queue all notifications in a queue as you're
 making modifications to the DOM, then right before returning from the
 function you insert a call like flushAllPendingNotifications(). This
 way you don't have to care at all about what happens when those
 notifications fire.

 So when exactly are these notifications going to be fired?  In
 particular, I hope non-DOM Core specifications are going to have
 precise control over when they're fired.  For instance, execCommand()
 will ideally want to do all its mutations at once and only then fire
 the notifications (which I'm told is how WebKit currently works).  How
 will this work spec-wise?  Will we have hooks to say things like
 remove a node but don't fire the notifications yet, and then have to
 add an extra line someplace saying to fire all the notifications?
 This could be awkward in some cases.  At least personally, I often say
 things like call insertNode(foo) on the range in the middle of a
 long algorithm, and I don't want magic happening at that point just
 because DOM Range fires notifications before returning from
 insertNode.

 Also, even if specs have precise control, I take it the idea is
 authors won't, right?  If a library wants to implement some fancy
 feature and be compatible with users of the library firing these
 notifications, they'd really want to be able to control when
 notifications are fired, just like specs want to.  In practice, the
 only reason this isn't an issue with DOM mutation events is because
 they can say don't use them, and in fact people rarely do use them,
 but that doesn't seem ideal -- it's just saying library authors
 shouldn't bother to be robust.

In working on Model Driven Views (http://code.google.com/p/mdv), we've
run into exactly this problem, and have developed an approach we think
is promising.

The idea is to more or less take Jonas's proposal, but instead of
firing callbacks immediately before the outer-most mutation returns,
mutations are recorded for a given observer and handed to it as an
in-order sequence at the end of the event.

var observer = window.createMutationObserver(callback);
document.body.addSubtreeChangedObserver(observer);
document.body.addSubtreeAttributeChangedObserver(observer);
...
var div = document.createElement('div');
document.body.appendChild(div);
div.setAttribute('data-foo', 'bar');
div.innerHTML = 'bsomething/b isomething else/i';
div.removeChild(div.childNodes[1]);
...

// mutationList is an array, all the entries added to
// |observer| during the preceding script event
function callback(mutationList) {
// mutationList === [
//  { type: 'ChildlistChanged', target: document.body, inserted: [div] },
//  { type: 'AttributeChanged', target: div, attrName: 'data-foo' },
//  { type: 'ChildlistChanged', target: div, inserted: [b, i] },
//  { type: 'ChildlistChanged', target: div, removed: [i] }
// ];
}


 Maybe this is a stupid question, since I'm not familiar at all with
 the use-cases involved, but why can't we delay firing the
 notifications until the event loop spins?  If we're already delaying
 them such that there are no guarantees about what the DOM will look
 like by the time they fire, it seems like delaying them further
 shouldn't hurt the use-cases too much more.  And then we don't have to
 put further effort into saying exactly when they fire for each method.

Agreed.

For context, after considering this issue, we've tentatively concluded
a few things that don't seem to be widely agreed upon:

1) In terms of when to notify observers: Sync is too soon. Async (add
a Task) is too late.

- The same reasoning for why firing sync callbacks in the middle of
DOM operations is problematic for C++ also applies to application
script. Calling mutation observers synchronously can invalidate the
assumptions of the code which is making the modifications. It's better
to allow one bit of code to finish doing what it needs to and let
mutation observers operate later over the changes.

- Many uses of mutation events would actually *prefer* to not run sync
because the originating code may be making multiple changes which
more or less comprise a transaction. For consistency and
performance, the abstraction which is watching changes would like to
operate on the final state.

- However, typical uses of mutation events do want to operate more or
less in the same event because they are trying to create a new
consistent state. They'd like to run after the application code is
finished, but before paint occurs or the next scheduled event runs.

2) Because the system must allow multiple observers and allow

Re: Model-driven Views

2011-05-06 Thread Rafael Weinstein
Thanks everyone for your consideration.

It sounds like the group wants to proceed by looking first at missing
primitives. Maciej is right that one of them is the ability to declare
inert DOM structures, but my feeling is that it's probably best to
start with the central problem:

-There's no way to observe mutations to JS objects.

Current approaches resort to a number of hacks which create really terrible
artifacts in application code. The ECMA Script Proxy mechanism may be the
best starting point, but there's a related
problem with timing that isn't addressed.

I'll start a thread shortly on this problem detailing our best
understanding, and make an attempt to loop in library authors to get their
view.

On Thu, Apr 28, 2011 at 2:02 AM, Maciej Stachowiak m...@apple.com wrote:

 On Apr 27, 2011, at 6:46 PM, Rafael Weinstein wrote:




 What do you think?


 - Is this something you'd like to be implemented in the browsers,

 Yes.

  and if yes, why? What would be the reasons to not just use script
  libraries (like your prototype).

 FAQ item also coming for this.

 Having heard Rafael's spiel for this previously, I believe there are some
things that templating engines want to do, which are hard to do efficiently
and conveniently using the existing Web platform.

 However, I think it would be better to add primitives to the Web platform
that could be used by the many templating libraries that already exist, at
least as a first step:

 - There is a lot of code built using many of the existing templating
solutions. If we provide primitives that let those libraries become more
efficient, that is a greater immediate payoff than creating a new templating
system, where Web apps would have to be rewritten to take advantage.

 - It seems somewhat hubristic to assume that a newly invented templating
library is so superior to all the already existing solutions that we should
encode its particular design choices into the Web platform immediately.

 - This new templating library doesn't have enough real apps built on it
yet to know if it is a good solution to author problems.

 - Creating APIs is best done incrementally. API is forever, on the Web.

 - Looking at the history of querySelector(), I come to the following
conclusion: when there are already a lot of library-based solutions to a
problem, the best approach is to provide technology that can be used inside
those libraries to improve them; this is more valuable than creating an API
with a primary goal of direct use. querySelector gets used a lot more via
popular JavaScript libraries than directly, and should have paid more
attention to that use case in the first place.

 Perhaps there are novel arguments that will dissuade me from this line of
thinking, but these are my tentative thoughts.

 Regards,
 Maciej




Re: Model-driven Views

2011-05-02 Thread Rafael Weinstein
 opaque to robots on the web. The
data already canonically live in the JS heap.

-Allowing declarative support for separating view  model opens the
way for web-automation to better understand what's going on.


9) We need to lead here and create a pit of success. The current pit
is full of nasty stuff.

-Creating a templating library that mostly works is easy and fun.
Every framework is going to have one and everyone who creates one is
going to make the same XSS mistakes (by use of innerHTML), and finally
discover that it doesn't really work with dynamic applications.

-The web is deeply engrained in the approach of imperative templating.
It's non-obvious to typical webdevs why this approach doesn't have
legs.

-The web has succeeded dramatically by making complex things easy.
Offering support here will raise the bar substantively for what a
novice webdev can achieve. Web applications shouldn't just be the
domain of web ninjas.



On Thu, Apr 28, 2011 at 2:02 AM, Maciej Stachowiak m...@apple.com wrote:

 On Apr 27, 2011, at 6:46 PM, Rafael Weinstein wrote:




 What do you think?


 - Is this something you'd like to be implemented in the browsers,

 Yes.

  and if yes, why? What would be the reasons to not just use script
  libraries (like your prototype).

 FAQ item also coming for this.

 Having heard Rafael's spiel for this previously, I believe there are some 
 things that templating engines want to do, which are hard to do efficiently 
 and conveniently using the existing Web platform.

 However, I think it would be better to add primitives to the Web platform 
 that could be used by the many templating libraries that already exist, at 
 least as a first step:

 - There is a lot of code built using many of the existing templating 
 solutions. If we provide primitives that let those libraries become more 
 efficient, that is a greater immediate payoff than creating a new templating 
 system, where Web apps would have to be rewritten to take advantage.

 - It seems somewhat hubristic to assume that a newly invented templating 
 library is so superior to all the already existing solutions that we should 
 encode its particular design choices into the Web platform immediately.

 - This new templating library doesn't have enough real apps built on it yet 
 to know if it is a good solution to author problems.

 - Creating APIs is best done incrementally. API is forever, on the Web.

 - Looking at the history of querySelector(), I come to the following 
 conclusion: when there are already a lot of library-based solutions to a 
 problem, the best approach is to provide technology that can be used inside 
 those libraries to improve them; this is more valuable than creating an API 
 with a primary goal of direct use. querySelector gets used a lot more via 
 popular JavaScript libraries than directly, and should have paid more 
 attention to that use case in the first place.

 Perhaps there are novel arguments that will dissuade me from this line of 
 thinking, but these are my tentative thoughts.

 Regards,
 Maciej





Re: Model-driven Views

2011-04-27 Thread Rafael Weinstein
Hi Olli,

Thanks very much for taking time to read  digest our design.

I'm going to use this thread to start a FAQ on our project site. Some
of these questions have answers that deserve more detail than is wise
to put in an email =-).

On Wed, Apr 27, 2011 at 8:33 AM, Olli Pettay olli.pet...@helsinki.fi wrote:
 HI Rafael,


 few random comments, or mainly just random questions :)

 On 04/23/2011 03:35 AM, Rafael Weinstein wrote:

 Myself and a few other chromium folks have been working on a design
 for a formalized separation between View and Model in the browser,
 with needs of web applications being the primary motivator.

 Our ideas are implemented as an experimental Javascript library:
 https://code.google.com/p/mdv/ and the basic design is described here:
 http://mdv.googlecode.com/svn/trunk/docs/design_intro.html. It's not
 complete and there are things we're not happy with, but it's
 self-consistent enough that you can start to imagine what a full
 design might look like.

 We hope to get others interested in collecting requirements/use cases
 and fleshing out a good solution.

 Would be good to know what are the use cases you had in mind.

I'm never sure if I'm using the term use case correctly =-).

Our primary motivator is the needs of web applications, but if we can
create a good solution for more static cases in the process it'll be
that much more a win.

By collecting use cases I was thinking more about specific patterns
that emerge in composing views for applications. One very common
example is master/detail.




 We're starting the discussion here because a few people in this group
 from whom we got early feedback felt that it would be most appropriate
 place and, further, that this work bears some relation to XBL.

 Not sure why this had some relation with XBL. Unless you are
 planning to put the template based DOM nodes to anonymous DOM.

I'm creating a FAQ question for this. Will reply again when its ready.




 What do you think?


 - Is this something you'd like to be implemented in the browsers,

Yes.

  and if yes, why? What would be the reasons to not just use script
  libraries (like your prototype).

FAQ item also coming for this.

  If the have-to-change-HTML-parser like parts could be removed,
  this all feels like something for JS + Proxy objects, just like what
  you've done in the prototype.

 - Is there a reason why you have chosen to create yet another
  datastorage like object (although your Model is just a kind of
  proxy)? Couldn't you reuse for example IndexedDB?
  XUL Templates can be bound to sqlite, XML and RDF.

The goal isn't to create a storage mechanism, its to free the
application from directly manipulating the DOM and allow it to operate
on its data. To *say* what it wants to happen to the UI rather than to
do it. If JS objects were directly observable, that would be ideal --
but it seems unlikely that runtime implementors will take the perf
hit.

Allowing bindings to IndexedDB is a cool idea. We should explore that
more. In general, there are a number of things we should consider for
sourcing data.


 - Model looks in many ways like JS-fied and simplified XForms
  model/instance. Have you investigated if there are important use cases
  which XForms can handle (because it has more powerful binding
  mechanism) but MDV can't? Are there plans to extend

I've read the XForms spec, but I don't feel qualified to comment on
use cases that it can better handle. It sounds like you might...? ;-)

  the Path language, or ideas how it could be extended? (XForms has
  extensions to XPath)
  In general I'm not too happy to see yet another
  selector/path language. Would be great if some existing one could
  be reused. Sure, some parts of the proposed language look quite a bit
  like JSON, but there are other parts which are something very
  different.

The goal wasn't to create a path/selector language. The basic idea is
simple JSON dot-notation. The funny syntax you see (../, ./, /) is our
solution to three patterns that come up frequently in templating:

-You're in an iteration, but you need a value which is just above
your head (e.g.
http://mdv.googlecode.com/svn/trunk/capabilities/path_reference_ancestor.html)

-You're down deep in a object graph rendering you're output, but you
need a global value. An example might be composing a URL for an
application which is versioned. You need to grab a global static
path and combine it with some local state (e.g. userId). (e.g.
https://code.google.com/p/mdv/source/browse/trunk/capabilities/path_reference_root.html)

-Needing to refer to *this* value. This happens all the time. (e.g.
http://mdv.googlecode.com/svn/trunk/capabilities/path_reference_this.html)

We considered several other options and couldn't come up with a better
idea. Suggestions very welcome here (and everywhere, in fact).

In general, we're not at all wedded to naming or syntax. Its the
semantics were after.


 - It is not quite clear to me how the Model

Re: Model-driven Views

2011-04-26 Thread Rafael Weinstein
Thank, Nathan.

I hadn't known of Knockout, but it looks pretty great. Conceptually,
its design is very similar to MDV. Notably, the two big items:

-Observable JS object properties and Arrays.
-DOM-based template production (although they work with JQuery
templates which are string-based).

The automatic dependency tracking is interesting. We looked at some
work published by Adobe/Texas AM on declarative property models
(http://parasol.cs.tamu.edu/~jarvi/papers/gpce08.pdf,  a very
unsophisticated example in our use_cases
http://mdv.googlecode.com/svn/trunk/use_cases/property_model.html).

Knockout re-affirms for me that:

-Dynamic web apps increasingly load one or more views as HTML but talk
to their servers via a data API. Having to write lots of imperative
code which shuttles data into  out-of the DOM is a bummer. It's not
especially interesting code and it tends to be error prone. A
declarative approach can do much better.

-There are basically only two approaches to templating: DOM-based
(MDV, Knockout, Angular, JSTemplate)  String-based (JQuery, and a ton
of others). In the video, Steve explains (at about 12:40), indirectly,
that DOM-based is required if you are going to dynamically update your
view: performance. The other reason is DOM-stability.

-In order to get this kind of approach to work, you need some way of
observing when data has changed. There are four options for this that
I know of:

1) Run-time support for direct observation (e.g. Adobe Flex, WPF)
2) Value-holder pattern (e.g. Knockout, Sproutcore)
3) Proxy pattern (e.g. MDV)
4) Dirty checking (e.g. Angular)

The only two options available to webdevs are 2  4, and both
currently require some fairly unnatural contortions.


On Mon, Apr 25, 2011 at 12:26 PM, Nathan Kitchen w...@nathankitchen.com wrote:
 Have you heard of knockout.js? It's an MVVM pattern based on JQuery, if
 you're not aware of it you may be interested to see their approach.
 Official site:
 http://knockoutjs.com/
 Recent MIX event:
 http://channel9.msdn.com/Events/MIX/MIX11/FRM08
 Just FYI as it was related...

 On 23 April 2011 01:35, Rafael Weinstein rafa...@google.com wrote:

 Myself and a few other chromium folks have been working on a design
 for a formalized separation between View and Model in the browser,
 with needs of web applications being the primary motivator.

 Our ideas are implemented as an experimental Javascript library:
 https://code.google.com/p/mdv/ and the basic design is described here:
 http://mdv.googlecode.com/svn/trunk/docs/design_intro.html. It's not
 complete and there are things we're not happy with, but it's
 self-consistent enough that you can start to imagine what a full
 design might look like.

 We hope to get others interested in collecting requirements/use cases
 and fleshing out a good solution.

 We're starting the discussion here because a few people in this group
 from whom we got early feedback felt that it would be most appropriate
 place and, further, that this work bears some relation to XBL.

 What do you think?







Model-driven Views

2011-04-25 Thread Rafael Weinstein
Myself and a few other chromium folks have been working on a design
for a formalized separation between View and Model in the browser,
with needs of web applications being the primary motivator.

Our ideas are implemented as an experimental Javascript library:
https://code.google.com/p/mdv/ and the basic design is described here:
http://mdv.googlecode.com/svn/trunk/docs/design_intro.html. It's not
complete and there are things we're not happy with, but it's
self-consistent enough that you can start to imagine what a full
design might look like.

We hope to get others interested in collecting requirements/use cases
and fleshing out a good solution.

We're starting the discussion here because a few people in this group
from whom we got early feedback felt that it would be most appropriate
place and, further, that this work bears some relation to XBL.

What do you think?