Implement HTMLInputElement.prototype.labels & tests #35

Open
termi opened this Issue Jan 24, 2012 · 19 comments

3 participants

@Raynos
Owner

eventually, won't be done for a while.

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

@termi
Collaborator

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?

@Raynos
Owner

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.

@domenic

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);
      }
    }
  });
}
@Raynos Raynos closed this Jan 24, 2012
@Raynos
Owner
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)

@termi
Collaborator

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

@termi
Collaborator

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 ?

@Raynos
Owner

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.

@Raynos
Owner

I would personally implement them as

[HTMLInputElement, ... ].forEach( function (constructor) {
   defineProperty(constructor.prototype, "labels",  { ... });
});
@Raynos Raynos reopened this Jan 25, 2012
@Raynos
Owner

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

@termi
Collaborator

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.

@Raynos
Owner

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.

@termi
Collaborator

The same sh*t :(

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

@termi
Collaborator

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

@termi
Collaborator

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

@termi
Collaborator

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

@termi
Collaborator

Can't understand how to pull "labels" in your style guide.
termi1uc1/DOM-shim@88a5f3b
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 ?

@Raynos
Owner

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.

@termi
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment