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

setAttributeNode and setAttributeNodeNS can be an aliases #117

Closed
foolip opened this issue Nov 23, 2015 · 13 comments
Closed

setAttributeNode and setAttributeNodeNS can be an aliases #117

foolip opened this issue Nov 23, 2015 · 13 comments

Comments

@foolip
Copy link
Member

foolip commented Nov 23, 2015

Another thing I found when investigating https://code.google.com/p/chromium/issues/detail?id=502301

In Blink/WebKit, setAttributeNode and setAttributeNodeNS are simply aliases. This means that there is no namespace and local name flag, and a case-insensitive search for an existing attribute is always done, for HTML documents. (Per spec it would be lowercasing attr.localName instead.)

An ad-hoc test, where Edge behaves like Blink/WebKit, while Gecko is the only engine to end up with two attributes:
http://software.hixie.ch/utilities/js/live-dom-viewer/saved/3761

What the spec says is probably web compatible, but with some strangeness:

  1. As of Make createAttribute() lowercase the input in HTML documents #75, createAttribute will lowercase the input, so also lowercasing attr.localName is unlikely to be needed for compat.
  2. By doing get an attribute by name and removing the found attribute, there can still be more attributes by the same name, so no interesting invariant is upheld: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/3762

So what to do?

My proposal is to make setAttributeNode do the equivalent of getAttributeNodeNS(attr.namespaceURI, attr.localName) with no lowercasing or case-insensitive lookup. setAttributeNodeNS would be an exact alias, and we could consider removing it. Usage is super low.

CC @bzbarsky @Ms2ger

@bzbarsky
Copy link

So the basic proposal is that setAttributeNode have the behavior setAttributeNodeNS currently does, right?

I guess that would be OK with me, generally speaking.

Is it true that this change of behavior only matters in cases when someone previously set an attribute via setAttribute (or perhaps setAttributeNode using a different Attr) and now is trying to reset the same attribute, but using a different case, using setAttributeNode? Or are any other cases affected?

@foolip
Copy link
Member Author

foolip commented Nov 23, 2015

Yes, keeping only the setAttributeNodeNS behavior sums it up nicely.

Only setAttributeNode calls where the Attr object has a non-lowercase localName would be affected, and you can get those from createAttributeNS or cloning attributes from a non-HTML element/document. Then the risk would be that the code depends on other attributes being removed, e.g. by calling getAttribute and assuming it will return the new attribute's value.

This all seems similar in risk to making createAttribute lowercase its input, i.e. a bit far-fetched.

@ArkadiuszMichalski
Copy link
Contributor

So this change will automaticaly apply to NamedNodeMap.setNamedItem(), who share the same algorithm "set an attribute"? Usage for them is slightly higher (https://www.chromestatus.com/metrics/feature/timeline/popularity/307), but still close to 0.

@foolip
Copy link
Member Author

foolip commented Nov 23, 2015

Good catch, setNamedItem and setNamedItemNS are indeed aliases of setAttributeNode and setAttributeNodeNS in Blink. I've checked and there aren't any other internal uses.

Usage is actually lower than for setAttributeNode, here are the counters for all four APIs:

@annevk annevk closed this as completed in a0042ff Nov 24, 2015
@annevk
Copy link
Member

annevk commented Nov 24, 2015

@foolip
Copy link
Member Author

foolip commented Nov 24, 2015

I have reviewed the spec change, LGTM!

@bzbarsky
Copy link

bzbarsky commented Dec 3, 2015

This needs web platform tests, right?

@foolip
Copy link
Member Author

foolip commented Dec 3, 2015

Yep. I was hoping to use wpt, updating as needed, when implementing the new Attr model in Blink, but I've paused that work waiting for #116 (mostly an excuse, it need not really block since it's so corner-case-y)

@bzbarsky
Copy link

bzbarsky commented Dec 3, 2015

OK. Gecko has some tests for this stuff, but they're pretty messy and might not test all the current edge cases (not least because they have had to evolve with spec changes, which removed old edge cases while adding new ones) so I'm not 100% sure about moving the to wpt as-is...

@foolip
Copy link
Member Author

foolip commented Dec 3, 2015

Yeah, those tests look like they need updating. Looks like testGetAttribute() is checking that an attribute with localName 'AA' will replace an attribute with localName 'aa', but I guess that's a known issue?

@bzbarsky
Copy link

bzbarsky commented Dec 3, 2015

Looks like testGetAttribute() is checking that an attribute with localName 'AA' will replace an attribute with localName 'aa'

Right, since that's what setAttributeNode used to do.

@foolip
Copy link
Member Author

foolip commented Dec 3, 2015

Ha, I'd already purged that from my memory and was surprised all over again :)

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

4 participants