diff --git a/source/Ox.UI/js/Core/URL.js b/source/Ox.UI/js/Core/URL.js index 6ec997f3..f6f013fd 100644 --- a/source/Ox.UI/js/Core/URL.js +++ b/source/Ox.UI/js/Core/URL.js @@ -44,13 +44,217 @@ Ox.URL URL controller typeA Views for type "typeA" list <[s]> List views for this type item <[s]> Item views for this type + + > !!Ox.test.url.parse('/', function(o) { Ox.test(o, Ox.test.result['/']); }) + true + > !!Ox.test.url.parse('/faq#1', function(o) { Ox.test(o, Ox.test.result['/faq#1']); }) + true + > !!Ox.test.url.parse('/cities', function(o) { Ox.test(o, Ox.test.result['/cities']); }) + true + > !!Ox.test.url.parse('/map', function(o) { Ox.test(o, Ox.test.result['/map']); }) + true + > !!Ox.test.url.parse('/-45,-90,45,90', function(o) { Ox.test(o, Ox.test.result['/-45,-90,45,90']); }) + true + > !!Ox.test.url.parse('/@New%20York', function(o) { Ox.test(o, Ox.test.result['/@New%20York']); }) + true + > !!Ox.test.url.parse('/name', function(o) { Ox.test(o, Ox.test.result['/name']); }) + true + > !!Ox.test.url.parse('/-name,population', function(o) { Ox.test(o, Ox.test.result['/-name,population']); }) + true + > !!Ox.test.url.parse('/2342', function(o) { Ox.test(o, Ox.test.result['/2342']); }) + true + > !!Ox.test.url.parse('/2342/map', function(o) { Ox.test(o, Ox.test.result['/2342/map']); }) + true + > !!Ox.test.url.parse('/2342/name', function(o) { Ox.test(o, Ox.test.result['/2342/name']); }) + true + > !!Ox.test.url.parse('/foo', function(o) { Ox.test(o, Ox.test.result['/foo']); }) + true + > !!Ox.test.url.parse('/population=1000,2000', function(o) { Ox.test(o, Ox.test.result['/population=1000,2000']); }) + true + > !!Ox.test.url.parse('/population>0&(name=a*|name=*z)', function(o) { Ox.test(o, Ox.test.result['/population>0&(name=a*|name=*z)']); }) + true + > !!Ox.test.url.parse('/#a?k=v&l=w', function(o) { Ox.test(o, Ox.test.result['/#a?k=v&l=w']); }) + true @*/ /* -example.com[/page] +example.com[/page][#hash] or -example.com[/type][/item][/view][/span][/sort][/find] +example.com[/type][/item][/view][/span][/sort][/find][#hash] page Special page, like "about" or "contact" type Section a.k.a. item type, like "movies", "edits", "texts" etc. @@ -69,6 +273,7 @@ find Query, like a=x or a=x&b=y or a=x&(b=y|c=z). A query object has the form object has the form {key: '', value: '' or ['', ''], operator: ''} (comparison operator) or {conditions: [], operator: ''} (logical operator). Condition strings can be more than just "k=v", see below. +hash Anchor and/or query, like 'a' or '?k=v' or 'a?k=v&l=w'. String Key Value Operator v * v = any text or string contains or any number is @@ -158,7 +363,11 @@ Ox.URL = function(options) { views: {} }, options); - Ox.Log('Core', 'Ox.URL options', self.options) + if (Ox.every(self.options.findKeys, function(findKey) { + return findKey.id != '*'; + })) { + self.options.findKeys.push({id: '*', type: 'string'}); + } self.previousTitle = ''; self.previousURL = ''; @@ -207,6 +416,13 @@ Ox.URL = function(options) { }).join(find.operator); } + function constructHash(hash) { + return (hash.anchor || '') + + hash.query ? '?' + hash.query.map(function(query) { + return encodeValue(query.key) + '=' + encodeValue(query.value); + }) : ''; + } + function constructLocation(location) { return location.join(','); } @@ -262,7 +478,8 @@ Ox.URL = function(options) { parts.push(constructFind(state.find)); } } - return '/' + Ox.filter(parts).join('/'); + return '/' + Ox.filter(parts).join('/') + + (state.hash ? '#' + constructHash(state.hash) : ''); } function constructValue(str, key) { @@ -407,6 +624,23 @@ Ox.URL = function(options) { return find; } + function parseHash(str) { + var split = str.split('?'); + return Ox.extend({ + anchor: decodeValue(split[0]) + }, split[1] ? { + query: split[1].split('&').filter(function(kv) { + return kv.indexOf('=') > -1; + }).map(function(kv) { + var split = kv.split('='); + return { + key: decodeValue(split[0]), + value: decodeValue(split[1]) + }; + }) + } : {}); + } + function parseLocation(str) { return str.split(',').map(function(str, i) { return Ox.limit(parseInt(str, 10), -90 * (i + 1), 90 * (i + 1)); @@ -441,9 +675,9 @@ Ox.URL = function(options) { function parseURL(str, callback) { // fixme: removing trailing slash makes it impossible to search for '/' - str = str.replace(/(^\/|\/$)/g, ''); - var parts = str.split('/'), - state = {}; + var split = str.split('#'), + parts = split.shift().replace(/(^\/|\/$)/g, '').split('/'), + state = split.length ? {hash: parseHash(split.join('#'))} : {}; if (parts[0] == '') { // empty URL callback(state); @@ -479,6 +713,9 @@ Ox.URL = function(options) { }); } } else { + state.item = ''; + // set to default view + state.view = self.options.views[state.type].list[0]; callback(state); } }