|
|
(One intermediate revision by the same user not shown) |
Line 1: |
Line 1: |
| | [[User:Rolandsteiner|RolandSteiner]] This may be obsoleted by the Proxy approach for isolation. |
| | |
| = Overview = | | = Overview = |
|
| |
|
Line 14: |
Line 16: |
| * Not component-specific, could be used for workers, <code><iframes></code>, intents | | * Not component-specific, could be used for workers, <code><iframes></code>, intents |
| * Same definitions can be used cross-language (not limited to JavaScript) | | * Same definitions can be used cross-language (not limited to JavaScript) |
|
| |
| = Example =
| |
|
| |
| The following could be the IDL declaration for a contact in a contact list. User-defined names MUST start with an upper case letter.
| |
|
| |
| <idl name="Contact" type="object">
| |
| <property name="firstName" type="string" optional/>
| |
| <property name="lastName" type="string" optional/>
| |
| <property name="name" type="string" get="getName"/>
| |
| <property name="phone" type="string" optional/>
| |
| <property name="email" type="string" optional/>
| |
| </idl>
| |
|
| |
| The contact list itself can make use of this type:
| |
|
| |
| <idl name="ContactList" type="interface">
| |
| <function name="addContact" type="unsigned long"> <!-- returns index -->
| |
| <param name="contact" type="Contact" throws="OUT_OF_BOUNDS_EXCEPTION"/>
| |
| <param name="index" type="unsigned integer" optional/>
| |
| </function>
| |
| <function name="removeContact" type="unsigned long" throws="OUT_OF_BOUNDS_EXCEPTION"> <!-- requires index, throws if out of bounds -->
| |
| <param name="index" type="unsigned integer">
| |
| </function>
| |
| <function name="clear" type="void"/>
| |
| <property name="selectedIndex" type="unsigned integer" get set throws="OUT_OF_BOUNDS_EXCEPTION"/>
| |
| </idl>
| |
|
| |
| Also, setting up a user-defined event to communicate between a contact and a contact list:
| |
|
| |
| <idl name="ContactSelectedEvent" type="event">
| |
| <property name="index" type="unsigned integer"/>
| |
| </idl>
| |
|
| |
| Using the above types, we declare a component that implements a single contact:
| |
|
| |
| <element name="x-contact" class="ContactElement">
| |
| <implements idl="Contact"/>
| |
| <events>
| |
| <listen type="click"/>
| |
| <emit type="ContactSelectedEvent"/>
| |
| <events>
| |
| <script type="javascript">
| |
| function onclick() { dispatchEvent(new ContactSelectedEvent()); }
| |
| get name() { var s = ""; if (firstName) s = firstName; if (s && lastName) s += " "; if (lastName) s += lastName; return lastName; }
| |
| </script>
| |
| <template>
| |
| <div>
| |
| ... nicely formatted contact here ...
| |
| </div>
| |
| </template>
| |
| </element>
| |
|
| |
| ... and an element that handles the whole list:
| |
|
| |
| <element name="x-contactlist" class="ContactListElement">
| |
| <implements idl="ContactList"/>
| |
| <events>
| |
| <listen type="ContactSelectedEvent"/>
| |
| <events>
| |
| <script type="javascript">
| |
| function onContactSelectedEvent(evt) {
| |
| }
| |
| function addContact(contact, index) {
| |
| appendChild(new ContactElement());
| |
| }
| |
| function removeContact(index) {
| |
| ...
| |
| }
| |
| function clear(evt) {
| |
| ...
| |
| }
| |
| </script>
| |
| <template>
| |
| <div>
| |
| ... nicely formatted contact list here, consisting of <x-contact> elements ...
| |
| </div>
| |
| </template>
| |
| </element>
| |
|
| |
| <span style="color: darkred">'''ISSUE:'''</span> Avoid the complexity of [https://developer.mozilla.org/en/XBL/XBL_1.0_Reference/Elements#handler XBL1's <code>handler</code> element]!
| |
|
| |
| == Conversion Example ==
| |
|
| |
| The above could be converted to the following boilerplate by the browser, in the case of confined components:
| |
|
| |
| === Document side ===
| |
|
| |
| class Contact
| |
| {
| |
| firstName: null,
| |
| lastName: null,
| |
| phone: null,
| |
| email: null,
| |
| }
| |
|
| |
| class ContactElement
| |
| {
| |
| constructor() {
| |
| HTMLElement.call(this);
| |
| addEventListener('click', onclick);
| |
| }
| |
| function addContact(contact, index) { /* native implementation, calling addContact on the shadow tree, return value is deferred */ }
| |
| function removeContact(index) { /* native implementation, calling removeContact on the shadow tree */ }
| |
| function clear() { /* native implementation, calling clear on the shadow tree */ }
| |
| get selectedIndex() { /* native implementation, calling the getter for selectedIndex on the shadow tree, return value is deferred */ }
| |
| set selectedIndex(value) { /* native implementation, calling the setter for selectedIndex on the shadow tree */ }
| |
| }
| |
| Element.register('x-contact', ContactElement);
| |
|
| |
|
| |
| class ContactListElement
| |
| {
| |
| constructor() {
| |
| HTMLElement.call(this);
| |
| }
| |
| function addContact(contact, index) { /* native implementation, calling addContact on the shadow tree, return value is deferred */ }
| |
| function removeContact(index) { /* native implementation, calling removeContact on the shadow tree */ }
| |
| function clear() { /* native implementation, calling clear on the shadow tree */ }
| |
| get selectedIndex() { /* native implementation, calling the getter for selectedIndex on the shadow tree, return value is deferred */ }
| |
| set selectedIndex(value) { /* native implementation, calling the setter for selectedIndex on the shadow tree */ }
| |
| }
| |
| Element.register('x-contact', ContactElement);
| |