18

I have run into what is, to me, some serious weirdness with string behavior in Firefox when using the .normalize() Unicode normalization function.

Here is a demo, view the console in Firefox to see the problem.

Suppose I have a button with an id of "NFKC":

<button id="NFKC">NFKC</button>

Get a reference to that, easy enough:

document.querySelector('#NFKC')
// <button id="NFKC">

Now, since this button has an id of NFKC, which we can get at that string as follows:

document.body.querySelector('#NFKC').id
// "NFKC"

Stick that string in a variable:

var s1 = document.body.querySelector('#NFKC').id

By way of comparison, assign the very same string to a variable directly:

var s2 = 'NFKC'

So of course:

s1 === s2
// true

And:

s1 == s2
// true

Now’s the part where my head explodes.

To normalize a string, you pass one of NFC, NFD, NFKC, or NFKD to .normalize(), like this:

'á'.normalize('NFKC')
// "á"

Of course, depending on the normalization form you choose, you get different codepoints, but whatever.

'á'.normalize('NFC').length == 1
// true
'á'.normalize('NFD').length == 2
// true

But whatever. The point is, pass one of four strings corresponding to normalization forms to .normalize(), and you'll get a normalized string back.

Since we know that s1 (the string we retrieved from the DOM) and s2 are THE SAME STRING (s1 === s2 is true), then obviously we can use either to normalize a string:

'á'.normalize(s2)
"á"
// well yeah, because s2 IS 'NFKC'. 

Naturally, s1 will behave exactly the same way, right?

'á'.normalize(s1)
 // RangeError: form must be one of 'NFC', 'NFD', 'NFKC', or 'NFKD'

Nope.

So the question is: why does it appear that s1 is not equal to s2 as far as .normalize() is concerned, when s1 === s2 is true?

This doesn’t happen in Chrome, the only other browser I’ve tested so far.

UPDATE

This was a bug in Firefox and has been fixed.

  • and your question is? – Daniel A. White Mar 19 '15 at 19:42
  • Why `s1` isn't === `s2`. I will make the question more obvious. –  Mar 19 '15 at 19:43
  • 1
    It might help if you can set up a demo that reproduces the issue. – Bergi Mar 19 '15 at 19:44
  • I will set up a demo that reproduces the issue. –  Mar 19 '15 at 19:45
  • 1
    @Bergi Here's a demo: http://jsfiddle.net/qbxm49h2/1 An error is produced on the last test (`'á'.normalize(s1)`), in FF36. – apsillers Mar 19 '15 at 19:57
  • 2
    @pat I'd say this is clearly not correct behavior; this looks like a pretty clear bug for the FF bug tracker. – apsillers Mar 19 '15 at 20:00
  • 4
    I have added a bug report at https://bugzilla.mozilla.org/show_bug.cgi?id=1145326 –  Mar 19 '15 at 20:14
  • 2
    I found the [C++ implementation of `String.prototype.normalize` for Firefox](https://mxr.mozilla.org/mozilla-central/source/js/src/jsstr.cpp#875). Looks like the problem is related to however `formStr` is set. – apsillers Mar 19 '15 at 20:14
  • 4
    It's not just a DOM issue. These also fail: `var s2 = 'NFKC'.split('').join('');` and `var s2= 'NFKCabc'.replace('abc','');`. But this doesn't: `var s2= 'N'+'F'+'K'+'C';`. Weird. – Rick Hitchcock Mar 19 '15 at 20:33
  • Node.id isn't in the mdn docs, or in the WHATWG [spec](https://dom.spec.whatwg.org/#node) – cdosborn Mar 25 '15 at 04:44
  • @cdosborn: [it is in that very spec](https://dom.spec.whatwg.org/#dom-element-id) as well as [on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/id) – Bergi Mar 25 '15 at 14:57
  • gah.. i was looking at the node api, right you are – cdosborn Mar 25 '15 at 15:25
  • 4
    Could you post your update as an answer and accept it? Congrats on finding this bug BTW! – Nickolay Aug 08 '15 at 20:22

1 Answers1

1

I'm not sure if this will help, but the documentation states that

This is an experimental technology, part of the Harmony (ECMAScript 6) proposal. Because this technology's specification has not stabilized, check the compatibility table for usage in various browsers. Also note that the syntax and behavior of an experimental technology is subject to change in future version of browsers as the spec changes.

And the compatibility table is

Feature         Chrome  Firefox (Gecko) Internet Explorer           Opera   Safari
Basic support   34      31 (31)         11 on Windows 10 Preview    (Yes)   Not supported

However, the last update to this page was Nov 18, 2014.

HeadCode
  • 2,770
  • 1
  • 14
  • 26