Raynos/DOM-shim

Implement HTMLInputElement.prototype.labels & tests

Opened this issue · 19 comments

eventually, won't be done for a while.

We really should work on a single shim project together ;) much more efficient

I would be glad to.
But it's difficult to me due to my main project. But I am start implement some new features right now (from HTMLInputElement.prototype.labels and Implement HTMLLabelElement.prototype.control).

Is this thread stable, or I need to Fork Dev version?

This thread is stable, but I'm going to restructure the entire thing for increased modularity.

One of the aims of the DOM-shim is to be able to just package EventTarget or just package HTMLFormElement and the dependencies work themself out.

Since the full CSSOM/DOM/DOMEvents/HTML/XHR shim will come into 50kb gzipped.

I plan to have it refactored in a stable state end of next weekend.

Of course any additions added to the current project can be ported by me to the new format.

Here's some code from our project at work. Has a jQuery dependency and returns an array instead of a NodeList but might be helpful. Not that this is too hard anyway.

Remember that you need it for more than just HTMLInputElement, you need textareas and selects as well. We were lazy and added it to HTMLElement.

if (!("labels" in document.createElement("input"))) {
  Object.defineProperty(HTMLElement.prototype, "labels", {
    enumerable: true,
    get: function () {
      var labelsFromId = this.id ?
        Array.from(document.querySelectorAll("label[for='" + this.id + "']")) :
        [];

      // TODO: can we eliminate jQuery here?
      var parentLabel = jQuery(this).closest("label");

      if (parentLabel.length === 0) {
        return labelsFromId;
      } else {
        return parentLabel.toArray().concat(labelsFromId);
      }
    }
  });
}
var parentLabel = this.parentNode
while (parentLabel && parentLabel.tagName !== "LABEL") parentLabel = parentLabel.parentNode

closest is a simple while (not_condition) walk_parent_tree()

As an aside it's pretty cool to see you use the ES6 shim (Array.from)

Strange behavior in different browsers in which is implemented this feature

Try this https://github.com/termi1uc1/ES5-DOM-SHIM/blob/master/tests/new/HTMLInputElement.labels.html
in Opera 11.61 and Chrome
Opera: 2, 3
Chrome: 2, 1

Spec say: "... NodeList object associated with them that represents the list of label elements, in tree order, whose labeled control is the element in question"

I am confused

Too early you closed this issue

And one question:
Is it necessary to implement "lablels" in separate
HTMLInputElement.prototype
HTMLButtonElement.prototype
HTMLKeygenElement.prototype
HTMLMeterElement.prototype
HTMLOutputElement.prototype
HTMLProgressElement.prototype
HTMLTextAreaElement.prototype
HTMLSelectElement.prototype
files?

Or it will be not bad if implement it in HTMLElement.prototype ?

You've got duplicate ids what do you expect?

I think opera grabs the last element with id if you reference it as window and chrome grab the first element with said id.

Also note duplicate ids is invalid HTML and thus undefined behaviour.

I would personally implement them as

[HTMLInputElement, ... ].forEach( function (constructor) {
   defineProperty(constructor.prototype, "labels",  { ... });
});

As for closing, I seemed to have cloased and commented by accident.

Re: "You've got duplicate ids what do you expect?"
Bad example: "i1" and "l1" is very similar.
Rename it to "input1" and "label1".
So, no duplication, same confusing result.

I think the reason chrome and opera differ is that chrome says "return all labels for this element" and opera says "return all labels for the form that this element belongs to"

It may be an issue with the lack of <form> try adding one.

The same sh*t :(

I think we need to chose wich implementation is right and bugfixing other implementation

Details:
Chrome return all labels for this element without "control" property
Opera just return all labels for this element

I am asked https://twitter.com/#!/ODevRel_ru . He promised check it out

Webkit do it right. There is a bug in Opera https://twitter.com/statuses/162234890039988224

Can't understand how to pull "labels" in your style guide.
https://github.com/termi1uc1/DOM-shim/commit/88a5f3b48d2b3e2b4e8ed58fa69658a2d8f3ff94
We need something like this:

["Input", "Button", "Keygen", "Meter", "Output", "Progress", "TextArea", "Select"].forEach(
  function(name) {
    var protoName = "HTML" + name + "Element",
      proto = window[protoName] && window[protoName].prototype;

    //If browser don't support one of this element type, we need to shim it for all elements
    if(!proto)proto = Element.prototype;// || Node;

    var el = document.createElement(proto.toUpperCase());
    if(!("labels" in el))
      Object.defineProperty(proto, "labels", __shim__)
})

How to do this using M8 ?

In case your not aware you should not type m8 code seperately. You should use node build.js to build the lib/dom-shim.js file from the interfaces.

As for how this would be done, ideally you would create 8 new interface files "HTMLInputElement", "HTMLButtonElement", etc and add them to the interfaces folder.

However I'm going to restructure everything shortly so I'm not sure what the ideal option is.

For now just cheat and add it to HTMLElement and make a new interface file for HTMLElement.

Ready to pull request "+ Implement HTML*Element.labels" as soon as you accept/reject my previous request