1

From the custom elements page, I see that to extend an element you do:

var XFooButtonPrototype = Object.create(HTMLButtonElement.prototype);
XFooButtonPrototype.createdCallback = function() {
  this.textContent = "I'm an x-foo button!";
};

var XFooButton = document.registerElement('x-foo-button', {
  prototype: XFooButtonPrototype,
  extends: 'button'
});

Then later in the guide it says that you can make an element by writing either:

<x-foo></x-foo>

Or:

<button is="x-foo-button"></button>

Questions:

  • Why is it important to specify extends: 'button' when the element is obviously_ inheriting from HTMLButtonElement (since it has HTMLButtonElement.prototype in its proto chain)

  • How is the link between button and x-foo-button established? Does x-foo-button become a possible option of button in terms of is="x-foo-button" thanks to that extends: 'button' ? What happens "internally", so to speak?

  • Why would you pick <button is="x-foo-button"></button> over <x-foo></x-foo>...?

[ADDENDUM]

Polymer saves us from this duplication:

MyInput = Polymer({
  is: 'my-input',
  extends: 'input',
  created: function() {
    this.style.border = '1px solid red';
  }
});

If extends is there, Polymer will put the right prototype in the chain with Object.getPrototypeOf(document.createElement(tag));. So, corollary question:

  • Why the duplication in the first place? If there is an extends, shouldn't the browser automatically do this?
2
  • I don't think both of the syntaxes you mentioned are interchangeable. Under using a custom element section wiki states that : If you've used extends to create a custom element that derives from an existing DOM element (e.g. something other than HTMLElement), use the is syntax Commented Dec 1, 2015 at 8:55
  • Ta, posted an answer. Thanks a million for the comment! Commented Dec 2, 2015 at 3:26

2 Answers 2

4

You totally misunderstood how extending web components work.

Create simple elements

First of all, this is how you register a new element:

var XFoo = document.registerElement('x-foo', {
  prototype: Object.create(HTMLElement.prototype)
});

To create an element you can do one of these:

<x-foo></x-foo>

var xFoo = new XFoo();
document.body.appendChild(xFoo);

var xFoo = document.createElement( 'x-foo')
document.body.appendChild(xFoo);

Create extended elements

This is how you extend an existing element:

var XFooButton = document.registerElement('x-foo-button', {
  prototype: Object.create(HTMLButtonElement.prototype),
  extends: 'button'
});

To create one you can do one of these:

<button is="x-foo-button"></button>

var xFooButton = new XFooButton();
document.body.appendChild(xFoo);

var xFooButton = document.createElement('button', 'x-foo-button');
document.body.appendChild(xFooButton);

Note that in case of extended custom elements, when registering them you have to specify both the prototype (set to HTMLButtonElement.prototype rather than HTMLElement.prototype), and the extended tag's name (extends: 'button').

Also, when you create an extended element using markup or createElement(), you need to also specify the basic element (button) and the extended one (x-foo-button),

(Note: I am aware I am answering myself)

Sign up to request clarification or add additional context in comments.

3 Comments

Maybe the "is" syntax will be deprecated
I heard they are trying to come up with something better than the "is" syntax, but couldn't, so far.
@Merc, the Web Platform WG on their mailing-list: lists.w3.org/Archives/Public/public-webapps/2015AprJun/…
0

I think its Importent to Say here:

WARNING DEPRECATED Browser API METHOD Here in this Question a .registerElement is Used it got Replaced by .defineElement and the Api has changed

current way to define a element

class AppDrawer extends HTMLElement {
  constructor() {
    super()
    this.innerHTML = '<h1>UH</h1>'    
  }
}

window.customElements.define('app-drawer', AppDrawer);

// Or use an anonymous class if you don't want a named constructor in current scope.

window.customElements.define('app-drawer-noname', class extends HTMLElement {
  constructor() {
    super()
    this.innerHTML = '<h1>UH AH</h1>'    
  }
});
Example - defining a mobile drawer panel, < app - drawer >:
Example usage:
<app-drawer></app-drawer>
<app-drawer-noname></app-drawer-noname>

```

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.