Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTMLCollection.namedItem() vs supported property names #104

Closed
ArkadiuszMichalski opened this issue Nov 5, 2015 · 10 comments
Closed

HTMLCollection.namedItem() vs supported property names #104

ArkadiuszMichalski opened this issue Nov 5, 2015 · 10 comments

Comments

@ArkadiuszMichalski
Copy link
Contributor

At the beginning, in supported property names definition I see this:
"2.1. If element has an ID which is neither the empty string nor is in result, append element’s ID to result." << why this " empty string" exist here? We operate on ID (as concept, not id attribute) so it's possible that ID will ever be empty string?

Second is about how this two definitions handle attribute name (for element in not HTML namespce), this is intentional? I see that Firefox and Chrome have different behaviour. In the middle I also try check IE11 but this browser has other problem (when we create element inside script it produces different results) so focus only Firefox and Chrome.

Firefox - works the same for HTMLCollection.namedItem() and [], treat all elements in the same way, without paying attention to the HTML namespace for element with name attribute.

Chrome - works the same for HTMLCollection.namedItem() and [], treat all elements in the same way, paying attention to the HTML namespace for element with name attribute.

And spec:
https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem
HTMLCollection.namedItem() - without paying attention to the HTML namespace for element with name attribute

https://dom.spec.whatwg.org/#dom-htmlcollection-item
Supported property names - paying attention to the HTML namespace for element with name attribute

It concerns only name attribute (content attribute), id attribute (content attribute) works correct in Firefox and Chrome (as we have in DOM).

@annevk
Copy link
Member

annevk commented Nov 5, 2015

@bzbarsky (I hate asking you every time, if there's someone better, please let me know), it seems we should change Gecko to check the namespace for the name attribute, no?

@ArkadiuszMichalski
Copy link
Contributor Author

Me again, this is small test case:

<!DOCTYPE html>
<html>
<body>
    <div id="contener">
        <p name="test">P1 (name="test") in DIV.</p>
        <p id="test">P2 (id="test") in DIV.</p>
        <p id="Test">P3 (id="Test") in DIV.</p>
        <p name="Test">P4 (name="Test") in DIV.</p>
    </div>
    <script>

            var contener = document.getElementById("contener");

            var newP = document.createElementNS("", "P");
            newP.setAttribute("name", "TEST");
            newP.textContent = "New P in DIV without namespace and created inside script.";
            contener.insertBefore(newP, contener.firstChild);

            var collection = contener.children;
            console.log("collection.length: " + collection.length);
            console.log("collection.hasOwnProperty('TEST'): " + collection.hasOwnProperty('TEST'));
            if (collection.namedItem('TEST')){
                console.log("collection.namedItem('TEST').textContent: " + collection.namedItem('TEST').textContent);
            }
            if (collection['TEST']){
                console.log("collection['TEST'].textContent: " + collection['TEST'].textContent);
            }
            console.log(collection);

    </script>
</body>
</html>

Firefox 45:
collection.length: 5
collection.hasOwnProperty('TEST'): true
collection.namedItem('TEST').textContent: New P in DIV without namespace and created inside script.
collection['TEST'].textContent: New P in DIV without namespace and created inside script.

Chrome 48:
collection.length: 5
collection.hasOwnProperty('TEST'): false

IE 11:
collection.length: 5
collection.hasOwnProperty('TEST'): false
collection.namedItem('TEST').textContent: P2 (id="test") in DIV. << "TEST" != "test"

I try research Web IDL to see what is corelation beetwen method and supported property names (if we use getter in IDL definition for method) but still have some question:

  1. This supported property names should always be listed in DevTools when we inspect collection? For HTMLCollection I see they are, but only for elements in HTML namespace with name attribute. But in the other site, for NameNodeMap, I don't see this supported property names in DevTools, I ask because supported property indices are always display.
  2. Checking obj.hasOwnProperty() when passing as argument one of supported property names should always return true or not? I ask because see strange behaviour, especially for NameNodeMap.hasOwnProperty(), when browsers usually do not pay attention to size characters, and sometimes Firefox and Chrome product different result so I can't determine what's going on.

@bzbarsky
Copy link

bzbarsky commented Nov 5, 2015

@annevk Not sure who would be better. Maybe @Ms2ger in some cases. Maybe Olli, but not sure what his Github account is.

I had not realized that the handling of the "name" attribute in HTMLCollection.namedItem and HTMLCollection's supported names list was different in the spec. In Gecko, these are aliases for each other. And both have ignored the namespace of the element, for both name and id, since forever. I don't think it would be a problem to check for HTML elements before checking the name.

Hilariously, Gecko does check for HTML (though with some "XXX, is this part of the spec stable" comments) if you ask the object for its supported names directly. So for example:

<script>
  var parent = document.createElement("div")
  var child = document.createElementNS("", "x");
  child.setAttribute("name", "a");
  parent.appendChild(child);
  var child = document.createElement("y");
  child.setAttribute("name", "b");
  parent.appendChild(child);
  var kids = parent.children;
  console.log(Object.getOwnPropertyNames(kids)+"");
  console.log(kids.hasOwnProperty("a"));
  console.log(kids.hasOwnProperty("b"));
</script>

logs, in Gecko:

0,1,b
true
true

In Chrome it logs:

0,1,b
false
true

which is at least self-consistent. In Safari it logs:

0,1,constructor,length
false
true

so it's got a buggy getOwnPropertyNames situation too. Anyway, always checking for HTML before doing the name thing in HTMLCollection makes sense to me.

@ArkadiuszMichalski as far as your questions go:

  1. There is no spec for what devtools should do. In practice, devtools end up using something like for-in enumeration or Object.getOwnPropertyNames to do their work. So in Firefox, in my testcase, if I type kids. in the console, "b" appears in the completion list and "a" does not. For NamedNodeMap, still in Gecko, looks like the code dates back to when there was no way to make the supported names non-enumerable but we wanted them non-enumerable on NamedNodeMap, so we just claim to not have any when asked directly. Should get fixed. I filed https://bugzilla.mozilla.org/show_bug.cgi?id=1222079 and looks like Chrome at least has a similar bug.
  2. obj.hasOwnProperty should return true if http://heycam.github.io/webidl/#dfn-named-property-visibility returns true for the given property name (or if the property was directly defined on the object, of course). This may not be true for all supported property names, per that algorithm, but the ones for which hasOwnProperty returns false are also the ones for which [] access should not invoke the named getter.

@bzbarsky
Copy link

bzbarsky commented Nov 5, 2015

Oh, and @annevk if/when the spec gets updated here please file a bug on Gecko to deal with this? Esp. if there are wpt tests too.. ;)

@ArkadiuszMichalski
Copy link
Contributor Author

Thx @bzbarsky, now it is more understandable, I had to finally ask:)
BTW, now I see (by using my example from #104 (comment)) that Chrome has more errors, it treats ID with higher priority than name attribute around all elements. So in DevTools for this named properties we see:

Chrome:
Test: p#Test << this is <p id="Test">P3 (id="Test") in DIV.</p>
test: p#test << this is <p id="test">P2 (id="test") in DIV.</p>

Firefox:
Test:<p#Test> << this is <p id="Test">P3 (id="Test") in DIV.</p>
test:<p> << this is <p name="test">P1 (name="test") in DIV.</p>

IE11:
This browser totally do not pay attention to the name attribiute in other elements that img, a, applet, area, embed and other from HTML that have defined name. But for this elements ID and name have the same priority (but comparing argument and value is in case insensitive manner).

Maybe for someone with the Chrome team this ifnos will be useful.

@annevk
Copy link
Member

annevk commented Nov 11, 2015

@ArkadiuszMichalski would you be interested in working on https://github.com/w3c/web-platform-tests for these? It seems you already have some tests written, just need to wrap them in the JavaScript framework.

@annevk annevk closed this as completed in eda3dcd Nov 11, 2015
@annevk
Copy link
Member

annevk commented Nov 11, 2015

I filed https://bugzilla.mozilla.org/show_bug.cgi?id=1223716 against Gecko.

@ArkadiuszMichalski
Copy link
Contributor Author

@annevk not anytime soon, firstly I must read and learned how do this correctly, but when it happens I'll write them a little more for DOM, especially those where current browsers work differently. But if the matter is urgent then feel free to use all of my examples that I put here.

@bzbarsky
Copy link

I added some web platform tests in the Gecko patch, for what it's worth.

@annevk
Copy link
Member

annevk commented Nov 12, 2015

@ArkadiuszMichalski alright, not a problem. If you have any questions feel free to drop by on https://wiki.whatwg.org/wiki/IRC. We're happy to help.

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

No branches or pull requests

3 participants