Re: [webcomponents]: Of weird script elements and Benadryl

Dimitri, Web-Component-Companions,

Is it possible to create an HTMLElement-inheriting object for the custom
element in question in a defined way when the parser hits the <element>
tag, so that the developer can just refer to the object within the <script>
tag? Here's what I mean:

<element tagname="x-foo">
  <template>...</template>
  <script>
      HTMLXFooElement.prototype.bar = function(){...}
      HTMLXFooElement.prototype.readyCallback = function(){...}
  </script>
</element>

Benefits:

   - The script tag need only execute once to define the prototype
   - No new scoping behavior or attributes are needed for the script tag
   - Allows developers to extend the prototype of their custom element as
   they normally would any other script block
   - All code that needs to run when an instance of the custom element is
   created, happens in the callbacks - as expected/intended.

Requirements:

   - We would need to specify the HTMLElement-inherited object name, but
   this seems just fine. I would envision the specification sounding something
   like this: "Global element object names shall be generated using the
   declared tag name. The name shall start with 'HTML', followed by a camel
   cased version of the user-declared tag name (x-foo --> XFoo), with
   'Element' appended"
   - The newly generated global element object name would need to be
   inserted into the global scope prior to parsing script tags within the
   <element> tag.

Thoughts?



Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Fri, Apr 12, 2013 at 1:25 PM, Rick Waldron <waldron.rick@gmail.com>wrote:

>
>
>
> On Fri, Apr 12, 2013 at 3:30 PM, Dimitri Glazkov <dglazkov@google.com>wrote:
>
>> ... or "How the heck do we initialize custom elements in declarative
>> syntax?"
>>
>> There were good questions raised about the nature of <script> element
>> in the "platonic form" thread. Consider this syntax:
>>
>> <element name="foo-bar">
>>     <script> ...</script>
>>     <template> ... </template>
>> </element>
>>
>> The way <element> should work is like this:
>> a) when </element> is seen
>> b) generate a constructor for this element
>>
>
> Based on what? Is this more magic? What if a constructor is provided?
>
> Here are a few use case, followed by a proposed set of semantics:
>
>
> Given the following custom element:
>
>   <element name="foo-bar">
>     <template></template>
>   [
>     <script>
>       class FooBar {}
>     </script>
>   ]
>   </element>
>
> The braces are used to illustrate that the script tag is optional, so it
> might also look like:
>
>   <element name="foo-bar">
>     <template></template>
>   </element>
>
>
> OR
>   <!-- elsewhere in the document -->
>   <script>
>     class FooBar {}
>   </script>
>
> OR
>   (in a remote src file)
>   class FooBar {}
>
> OR
>   (in a module)
>   module CustomElements {
>     export class FooBar {}
>   }
>
>   (that's later imported)
>   import { FooBar } from "CustomElements";
>
>
>
> (None of the following is precise, just a basic idea that works with every
> example I've given above)
>
>
> Script tags inside <element> are treated the same way as any script tag in
> an HTML document would be treated.
>
>
> [[ConvertName]] is an imaginary operation the does the following:
>   Let _converted_ be the result of
>     1. replacing the first character of argument _val_ with same character
> converted to ASCII uppercase
>     2. replacing each U+002D (HYPHEN-MINUS character '-') that is followed
> by a lowercase ASCII letter, by removing the U+002D and converting the
> lowercase letter that followed with the same uppercase ASCII character.
>   Return _converted_.
>
>
> For each <element>
>   Parse <template> (I don't know what happens here, so just play along)
>   Let _val_ be the value of the **name** attribute of <element>
>   Let _name_ be the result of calling [[ConvertName]] with the argument
> _val_
>   Let _ctor_ be the result of calling Get([[Global]], _name_)
>   If _ctor_ is undefined
>     - Create a new class whose Identifier is _name_ which extends from
> HTMLElement
>       (This is just an assumption, replace with whatever makes the most
> sense)
>   Call document.register with arguments _val_ and _ctor_
>
>
>
>> b) run document.register
>> c) run initialization code
>>
>>  As I see it, the problem is twofold:
>>
>> 1) The <script> element timing is weird. Since <script> is
>> initialization code, it has to run after the </element> is seen. This
>> is already contrary to a typical <script> element expectations.
>>
>> 2) The <script> element needs a way to refer to the custom element
>> prototype it is initializing. Enclosing it in a function and calling
>> it with <element> as |this| seemed like a simplest thing to do, but
>> Rick and John had allergic reactions and had to be hospitalized.
>>
>
> Please don't trivialize valid concerns—it wasn't just John and I, Erik and
> Allen echo'ed the same.
>
>
>>
>> So far, I haven't seen any other workable alternatives. TC39 peeps and
>> others, help me find them.
>>
>
> see above.
>
>
>>
>> :DG<
>>
>
>
> Rick
>
>

Received on Friday, 12 April 2013 21:03:02 UTC