work in progress [might break]
This commit is contained in:
parent
cd69dcd006
commit
184eae64b0
|
@ -1,39 +1,49 @@
|
|||
xrf.navigator = {}
|
||||
xrf.navigator = {URL:{}}
|
||||
|
||||
xrf.navigator.to = (url,flags,loader,data) => {
|
||||
if( !url ) throw 'xrf.navigator.to(..) no url given'
|
||||
let {urlObj,dir,file,hash,ext} = xrf.navigator.origin = xrf.parseUrl(url)
|
||||
let hashChange = (!file && hash) || !data && xrf.model.file == file
|
||||
let hasPos = String(hash).match(/pos=/)
|
||||
|
||||
let URL = xrfragment.URL.toAbsolute( xrf.navigator.URL, url )
|
||||
console.dir({URL, nav: xrf.navigator.URL})
|
||||
let fileChange = URL.file && URL.file != xrf.navigator.URL.file
|
||||
let hasPos = URL.hash.pos
|
||||
let hashChange = String(xrf.navigator.URL.fragment||"") != String(URL.fragment||"")
|
||||
let hashbus = xrf.hashbus
|
||||
xrf.navigator.URL = URL
|
||||
let {directory,file,fragment,fileExt} = URL;
|
||||
|
||||
let hashbus = xrf.hashbus
|
||||
debugger
|
||||
const evalFragment = () => {
|
||||
if( URL.fragment ){
|
||||
hashbus.pub( URL.fragment, xrf.model, flags ) // eval local URI XR fragments
|
||||
xrf.navigator.updateHash(fragment) // which don't require
|
||||
}
|
||||
}
|
||||
|
||||
return new Promise( (resolve,reject) => {
|
||||
xrf
|
||||
.emit('navigate', {url,loader,data})
|
||||
.then( () => {
|
||||
|
||||
if( ext && !loader ){
|
||||
const Loader = xrf.loaders[ext]
|
||||
console.log("URN: "+URL.URN)
|
||||
if( fileExt && !loader ){
|
||||
const Loader = xrf.loaders[fileExt]
|
||||
if( !Loader ) return resolve()
|
||||
loader = loader || new Loader().setPath( dir )
|
||||
loader = loader || new Loader().setPath( URL.URN )
|
||||
}
|
||||
|
||||
if( !hash && !file && !ext ) return resolve(xrf.model) // nothing we can do here
|
||||
if( !URL.fragment && !URL.file && !URL.fileExt ) return resolve(xrf.model) // nothing we can do here
|
||||
|
||||
if( hashChange && !hasPos ){
|
||||
hashbus.pub( url, xrf.model, flags ) // eval local URI XR fragments
|
||||
xrf.navigator.updateHash(hash) // which don't require
|
||||
return resolve(xrf.model) // positional navigation
|
||||
if( xrf.model && hashChange && !hasPos ){
|
||||
evalFragment()
|
||||
return resolve(xrf.model) // positional navigation
|
||||
}
|
||||
|
||||
xrf
|
||||
.emit('navigateLoading', {url,loader,data})
|
||||
.then( () => {
|
||||
if( hashChange && hasPos ){ // we're already loaded
|
||||
hashbus.pub( url, xrf.model, flags ) // and eval local URI XR fragments
|
||||
xrf.navigator.updateHash(hash)
|
||||
if( !fileChange && hashChange && hasPos ){ // we're already loaded
|
||||
evalFragment()
|
||||
xrf.emit('navigateLoaded',{url})
|
||||
return resolve(xrf.model)
|
||||
}
|
||||
|
@ -43,17 +53,21 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
xrf.reset()
|
||||
|
||||
// force relative path for files which dont include protocol or relative path
|
||||
if( dir ) dir = dir[0] == '.' || dir.match("://") ? dir : `.${dir}`
|
||||
url = url.replace(dir,"")
|
||||
loader = loader || new Loader().setPath( dir )
|
||||
if( directory ) directory = directory[0] == '.' || directory.match("://") ? directory : `.${directory}`
|
||||
|
||||
loader = loader || new Loader().setPath( URL.URN )
|
||||
const onLoad = (model) => {
|
||||
|
||||
model.file = file
|
||||
model.file = URL.file
|
||||
// only change url when loading *another* file
|
||||
if( xrf.model ) xrf.navigator.pushState( `${dir}${file}`, hash )
|
||||
if( xrf.model ){
|
||||
let path = URL.directory != document.location.pathname ? URL.directory : '';
|
||||
xrf.navigator.pushState( `${path}${URL.file}`, fragment )
|
||||
}
|
||||
//if( xrf.model ) xrf.navigator.pushState( `${ document.location.pathname != URL.directory ? URL.directory: ''}${URL.file}`, fragment )
|
||||
xrf.model = model
|
||||
|
||||
if( !model.isXRF ) xrf.parseModel(model,url) // this marks the model as an XRF model
|
||||
if( !model.isXRF ) xrf.parseModel(model,url.replace(directory,"")) // this marks the model as an XRF model
|
||||
|
||||
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||
|
||||
|
@ -71,7 +85,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||
|
||||
xrf.add( model.scene )
|
||||
if( hash ) xrf.navigator.updateHash(hash)
|
||||
if( fragment ) xrf.navigator.updateHash(fragment)
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
resolve(model)
|
||||
}
|
||||
|
@ -80,7 +94,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
loader.parse(data, "", onLoad )
|
||||
}else{
|
||||
try{
|
||||
loader.load(url, onLoad )
|
||||
loader.load(file, onLoad )
|
||||
}catch(e){
|
||||
console.error(e)
|
||||
xrf.emit('navigateError',{url})
|
||||
|
@ -94,6 +108,8 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
xrf.navigator.init = () => {
|
||||
if( xrf.navigator.init.inited ) return
|
||||
|
||||
xrf.navigator.URL = xrfragment.URL.parse(document.location.href)
|
||||
|
||||
window.addEventListener('popstate', function (event){
|
||||
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
||||
xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
|
||||
|
|
|
@ -88,10 +88,10 @@ class Test {
|
|||
|
||||
static public function testURL( _url:String, attr:String, output:String, browserMode: Bool = false): Bool {
|
||||
var URL = xrfragment.URL;
|
||||
var url:URL = URL.parse(_url,true);
|
||||
var url:URL = URL.parse(_url);
|
||||
if( browserMode ){
|
||||
if( browser == null ) browser = url;
|
||||
url = URL.toAbsolute( browser, _url );
|
||||
url = browser = URL.toAbsolute( browser, _url );
|
||||
}
|
||||
var parts:Array<String> = attr.split(".");
|
||||
if( parts.length > 1 && parts[0] == "hash" && url.hash.exists( parts[1]) ){
|
||||
|
|
|
@ -6,5 +6,15 @@
|
|||
{"fn":"url","data":"http://foo.com?foo=1#mycustom=foo", "expect":{ "fn":"testURL", "input":"scheme","out":"http"},"label":"test URL scheme http"},
|
||||
{"fn":"url","data":"http://foo.com/a/b?foo=1#mycustom=foo", "expect":{ "fn":"testURL", "input":"path","out":"/a/b"},"label":"test URL path /a/b"},
|
||||
{"fn":"url","data":"http://foo.com/a/b?foo=1#mycustom=foo", "expect":{ "fn":"testURL", "input":"hash.mycustom","out":"foo"},"label":"test URL hash #mycustom == foo"},
|
||||
{"fn":"url","data":"http://foo.com/a/b?foo=1#mycustom=foo", "expect":{ "fn":"testURLBrowse", "input":"host","out":"foo.com"},"label":"test URLBrowser"}
|
||||
{"fn":"url","data":"http://foo.com/a/b", "expect":{ "fn":"testURL", "input":"path","out":"/a/b"},"label":"test URL path /a/b/"},
|
||||
{"fn":"url","data":"http://foo.com/a/b?foo=1#mycustom=foo", "expect":{ "fn":"testURLBrowse", "input":"host","out":"foo.com"},"label":"test URLBrowser"},
|
||||
{"fn":"url","data":"http://foo.com/a/b?https://foo.com/abc#mycustom=foo", "expect":{ "fn":"testURL", "input":"path","out":"/a/b"},"label":"test URL url-in-query"},
|
||||
{"fn":"url","data":"http://foo.com/a/b?https://foo.com/abc#mycustom=foo", "expect":{ "fn":"testURLBrowse", "input":"path","out":"/a/b"},"label":"test URLBrowser url-in-query"},
|
||||
{"fn":"url","data":"/bar/flop#mycustom=foo", "expect":{ "fn":"testURLBrowse", "input":"host","out":"foo.com"},"label":"test URLBrowser (maintain host)"},
|
||||
{"fn":"url","data":"/bar/flop?foo=1#mycustom=foo", "expect":{ "fn":"testURLBrowse", "input":"query","out":"foo=1"},"label":"test URLBrowser (parse query)"},
|
||||
{"fn":"url","data":"/flop/flap#mycustom=foo", "expect":{ "fn":"testURLBrowse", "input":"path","out":"/flop/flap"},"label":"test URLBrowser (overwrite path)"},
|
||||
{"fn":"url","data":"/bar/flop#mycustom=foo", "expect":{ "fn":"testURLBrowse", "input":"path","out":"/bar/flop"},"label":"test URLBrowser (overwrite path 2)"},
|
||||
{"fn":"url","data":"/bar/flop#mycustom=foo", "expect":{ "fn":"testURLBrowse", "input":"host","out":"foo.com"},"label":"test URLBrowser (maintain host)"},
|
||||
{"fn":"url","data":"c/d?foo=1#mycustom=foo", "expect":{ "fn":"testURLBrowse", "input":"path","out":"/bar/flop/c/d"},"label":"test URLBrowser (append path+query)"},
|
||||
{"fn":"url","data":"a/b#foo=bar", "expect":{ "fn":"testURL", "input":"hash.foo","out":"bar"},"label":"test URL hash #mycustom == foo"}
|
||||
]
|
||||
|
|
|
@ -48,10 +48,12 @@ class URL
|
|||
public var path : String;
|
||||
public var directory : String;
|
||||
public var file : String;
|
||||
public var fileExt : String;
|
||||
public var query : String;
|
||||
public var fragment : String;
|
||||
public var hash : haxe.DynamicAccess<Dynamic>;
|
||||
public var XRF : haxe.DynamicAccess<Dynamic>;
|
||||
public var hash : haxe.DynamicAccess<Dynamic> = {};
|
||||
public var XRF : haxe.DynamicAccess<Dynamic> = {};
|
||||
public var URN : String;
|
||||
|
||||
/**
|
||||
* class constructor
|
||||
|
@ -71,6 +73,10 @@ class URL
|
|||
{
|
||||
// The almighty regexp (courtesy of http://blog.stevenlevithan.com/archives/parseuri)
|
||||
var r : EReg = ~/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
|
||||
|
||||
if( stringUrl.indexOf("://") == -1 && stringUrl.charAt(0) != '/' ){
|
||||
stringUrl = "/" + stringUrl; // workaround for relative urls
|
||||
}
|
||||
|
||||
// Match the regexp to the url
|
||||
r.match(stringUrl);
|
||||
|
@ -93,7 +99,7 @@ class URL
|
|||
}
|
||||
|
||||
url.hash = {};
|
||||
if( url.fragment.length > 0 ){
|
||||
if( url.fragment != null && url.fragment.length > 0 ){
|
||||
url.XRF = xrfragment.URI.parse( "#"+url.fragment, 0 );
|
||||
var key:String;
|
||||
for( key in url.XRF.keys() ){
|
||||
|
@ -101,24 +107,38 @@ class URL
|
|||
url.hash[key] = v.get("string");
|
||||
}
|
||||
}
|
||||
trace("host:"+url.host);
|
||||
trace("path:"+url.path);
|
||||
trace("frag:"+url.fragment);
|
||||
trace("source:"+url.source);
|
||||
trace("scheme:"+url.scheme);
|
||||
trace("authority:"+url.authority);
|
||||
trace("userInfo:"+url.userInfo);
|
||||
trace("user:"+url.user);
|
||||
trace("password:"+url.password);
|
||||
trace("host:"+url.host);
|
||||
trace("port:"+url.port);
|
||||
trace("relative:"+url.relative);
|
||||
trace("path:"+url.path);
|
||||
trace("directory:"+url.directory);
|
||||
trace("file:"+url.file);
|
||||
trace("query:"+url.query);
|
||||
|
||||
computeVars(url);
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
private static function computeVars( url:URL ) {
|
||||
// clean up url
|
||||
var r = ~/\/\//g;
|
||||
if( url.directory != null && url.directory.indexOf("//") != -1 ){
|
||||
url.directory = r.replace(url.directory,"/");
|
||||
}
|
||||
if( url.path != null && url.path.indexOf("//") != -1 ){
|
||||
url.path = r.replace(url.path,"/");
|
||||
}
|
||||
if( url.file != null && url.file.indexOf("//") != -1 ){
|
||||
url.file = r.replace(url.file,"/");
|
||||
}
|
||||
// generate URN
|
||||
url.URN = url.scheme + "://" + url.host;
|
||||
if( url.port != null ) url.URN += ":"+url.port;
|
||||
url.URN += url.directory;
|
||||
|
||||
// extract file extension if any
|
||||
if( url.file != null){
|
||||
var parts:Array<String> = url.file.split(".");
|
||||
if( parts.length > 1 ){
|
||||
url.fileExt = parts.pop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize an URl OBJect into an
|
||||
|
@ -205,19 +225,11 @@ class URL
|
|||
{
|
||||
return url.scheme == null;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
public static function toAbsolute( oldUrl:URL, newUrl:String ) : URL {
|
||||
var newURL:URL = new URL(newUrl);
|
||||
return appendURL( oldUrl, newURL );
|
||||
}
|
||||
|
||||
/**
|
||||
* append the appended url to a relative url
|
||||
*/
|
||||
private static function appendToRelativeURL(url:URL, appendedURL:URL):URL
|
||||
public static function appendToRelativeURL(url:URL, appendedURL:URL):URL
|
||||
{
|
||||
//when relative url parsed, if it contains only a file (ex : "style.css")
|
||||
//then it will store it in the host attribute. So if the url has no directory
|
||||
|
@ -276,7 +288,7 @@ class URL
|
|||
/**
|
||||
* append the appended url to an absolute url
|
||||
*/
|
||||
private static function appendToAbsoluteURL(url:URL, appendedURL:URL):URL
|
||||
public static function appendToAbsoluteURL(url:URL, appendedURL:URL):URL
|
||||
{
|
||||
var resultURL:URL = new URL();
|
||||
|
||||
|
@ -327,6 +339,75 @@ class URL
|
|||
|
||||
return resultURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* append the appended url to an absolute url
|
||||
*/
|
||||
public static function toAbsolute(url:URL, newUrl:String ):URL
|
||||
{
|
||||
var newURL:URL = parse(newUrl);
|
||||
var resultURL:URL = new URL();
|
||||
|
||||
resultURL.port = url.port;
|
||||
|
||||
if (newURL.scheme != null)
|
||||
{
|
||||
resultURL.scheme = newURL.scheme;
|
||||
}else{
|
||||
resultURL.scheme = url.scheme;
|
||||
}
|
||||
|
||||
if (newURL.host != null && newURL.host.length > 0 )
|
||||
{
|
||||
trace("host: "+newURL.host);
|
||||
resultURL.host = newURL.host;
|
||||
resultURL.port = null;
|
||||
if( newURL.port != null ){
|
||||
resultURL.port = newURL.port;
|
||||
}
|
||||
}else{
|
||||
resultURL.host = url.host;
|
||||
}
|
||||
|
||||
var directory:String = "";
|
||||
if (url.directory != null)
|
||||
{
|
||||
directory = url.directory;
|
||||
}
|
||||
|
||||
if (newURL.directory != null)
|
||||
{
|
||||
if( newUrl.charAt(0) != '/' && newUrl.indexOf("://") == -1 ){
|
||||
directory += newURL.directory;
|
||||
}else{
|
||||
directory = newURL.directory;
|
||||
}
|
||||
}
|
||||
|
||||
resultURL.directory = directory;
|
||||
|
||||
if (newURL.file != null)
|
||||
{
|
||||
resultURL.file = newURL.file;
|
||||
}
|
||||
|
||||
resultURL.path = resultURL.directory + resultURL.file;
|
||||
|
||||
if (newURL.query != null)
|
||||
{
|
||||
resultURL.query = newURL.query;
|
||||
}
|
||||
|
||||
if (newURL.fragment != null)
|
||||
{
|
||||
resultURL.fragment = newURL.fragment;
|
||||
}
|
||||
resultURL.hash = newURL.hash;
|
||||
resultURL.XRF = newURL.XRF;
|
||||
computeVars(resultURL);
|
||||
|
||||
return resultURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* clone the provided url
|
||||
|
|
Loading…
Reference in New Issue