- From: David Sheets <kosmo.zb@gmail.com>
- Date: Tue, 25 Sep 2012 15:14:26 -0700
- To: Glenn Maynard <glenn@zewt.org>
- Cc: Alexandre Morgaut <Alexandre.Morgaut@4d.com>, whatwg <whatwg@whatwg.org>, "Tab Atkins Jr." <jackalmage@gmail.com>
On Tue, Sep 25, 2012 at 2:13 PM, Glenn Maynard <glenn@zewt.org> wrote: > On Mon, Sep 24, 2012 at 7:18 PM, David Sheets <kosmo.zb@gmail.com> wrote: >> >> Always. The appropriate interface is (string * string?) list. Id est, >> >> an association list of keys and nullable values (null is >> key-without-value and empty string is empty-value). If you prefer to >> not use a nullable value and don't like tuple representations in JS, >> you could use type: string list list >> >> i.e. >> >> >> [["key_without_value"],[""],["key","value"],[],["numbers",1,2,3,4],["",""],["","",""]] > > > This isn't an appropriate interface. It's terrible for 99.9% of use cases, > where you really want dictionary-like access. This is the direct representation of the query string key-value convention. Looking up keys is easy in an association list. Filtering the list retains ordering. Appending to the list is well-defined. Folding into a dictionary is trivial and key merging can be defined according to the author's URL convention. > The right approach is probably to expose the results in an object-like form, > as Tab suggests, but to store the state internally in a list-like format, > with modifications defined in terms of mutations to the list. This sounds more complicated to implement while maintaining invariants. A dictionary with an associated total order is an association list. > That is, parsing "a=1&b=2&a=3" would result in an internal representation > like [('a', '1'), ('b', '2'), ('a', '3')]. When viewed from script, you see > {a: ['1', '3'], 'b': ['2']}. If you serialize it right back to a URL the > internal representation is unchanged, so the original order is preserved. > The mutation algorithms can then do their best to preserve the list as > reasonably as they can (eg. assigning query.a = ['5', '6'] would remove all > 'a' keys, then insert items at the location of the first removed item, or > append if there were none). Why hide the order? >> Is this not already supported by creating a new URL which contains >> only a relative query part? >> >> Like: query = new URL("?a=b&c=d"); query.query["a"] = "x"; >> query.toString() == "?a=x&c=d"; >> >> Why is a new interface necessary? > > > That won't work, since "?a=b&c=d" isn't a valid URL. "?a=b&c=d" is a valid URI reference. @href="?a=b&c=d" is valid. > The invalid flag will > be set, so the change to .query will be a no-op, and .href (presumably what > toString will invoke) would return the original URL, "?a=b&c=d", not > "?a=x&c=d". You'd need to do something like: > > var query = new URL("http://example.com?" + url.hash); > query.query.a = "x"; > url.hash = query.search.slice(1); // remove the leading "?" > > That's awkward, but maybe it's good enough. This is a use case for parsing without composed relative resolution.
Received on Tuesday, 25 September 2012 22:14:56 UTC