chrome.storage should not be sorting object keys
Reported by
thd...@gmail.com,
Apr 22 2018
|
|||||
Issue description
UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Steps to reproduce the problem:
1. Store some dummy object (you can open any extension background page and enter this):
chrome.storage.local.set({
'obj': {
'k1': 'one',
'k2': 'two',
'k10': 'ten'
}
});
2. Retrieve the data:
chrome.storage.local.get('obj', function(items) {
for (var i in items['obj']) {
console.log(i);
}
});
What is the expected behavior?
It should output the keys in the order in which they were provided:
k1
k2
k10
What went wrong?
It outputs the keys in lexicographic order:
k1
k10
k2
Did this work before? N/A
Does this work in other browsers? Yes
Chrome version: 65.0.3325.181 Channel: n/a
OS Version: 10.0
Flash Version:
This is in regards to the chrome.storage API only, not Chromium, which correctly keeps the object string keys unsorted per the ES6 spec:
http://exploringjs.com/es6/ch_oop-besides-classes.html#_traversal-order-of-properties
> Retrieves the keys of all own properties of an object, in the following order:
> - First, the string keys that are integer indices (what these are is explained in
> the next section), in ascending numeric order.
> - Then all other string keys, **in the order in which they were added to the object**.
> - Lastly, all symbol keys, in the order in which they were added to the object.
If chrome.storage does not follow ES6 by design, then I guess this is not a bug but a feature request: please keep object string keys unsorted to be consistent with Chromium's JS engine.
,
Apr 23 2018
@woxxom it is still confusing to me that when I traverse the same object in Chrome/Firefox I get a different order (unsorted). Are we to expect that because "the order in which for-in traverses properties is not defined" each API can have their own interpretation? My main point is that the behavior is inconsistent between Chrome and chrome.storage.
,
Apr 23 2018
Able to reproduce this issue on reported version 65.0.3325.181, on latest stable 66.0.3359.117 , on latest canary 68.0.3404.0 using Windows 10, Ubuntu 14.04 and Mac 10.13.3. This issue is seen from M-60. Hence considering this issue as Non-Regression and marking as Untriaged. Thanks!
,
Apr 23 2018
,
May 14 2018
ECMAScript specification here is somewhat irrelevant. Serialization/deserialization is outside the bounds of what that covers. In this case, I believe the serialization/deserialization is done by converting the JS value to a base::Value (src/base/values.h) and serializing/deserializing using that somehow (I stopped digging). A JS object is mapped to a base::DictionaryValue which doesn't preserve order. Most web-facing APIs use the HTML-specified structured serialization (https://html.spec.whatwg.org/multipage/structured-data.html#safe-passing-of-structured-data) which is higher fidelity and does preserve ordering. I assume we don't want to invest heavily in this API, and would need to handle backwards compatibility/migration if we did make changes, but I defer to the extensions folks.
,
May 14 2018
Yeah, this is because of the underlying implementation. We do multiple base::Value conversions back-and-forth, which results in sorted keys. Note that we specify any behavior regarding key order in the documentation for the chrome.storage API, so there are no strong guarantees here. I'm not against having a defined structure here, and longer-term we do want to improve our storage capabilities for extensions for better support. However, this probably isn't something we'll try and tackle in the near future. I'm marking this as available, in case anyone wants to pursue it. Note, though, that there be dragons: this is a long and convoluted code path, and trying to preserve order is likely very difficult. |
|||||
►
Sign in to add a comment |
|||||
Comment 1 by viswa.karala@chromium.org
, Apr 23 2018