release v0.5.2
This commit is contained in:
parent
45b46f788c
commit
6ad8f146c7
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* v0.5.1 generated at Tue Mar 19 10:04:25 AM UTC 2024
|
* v0.5.1 generated at Tue Apr 16 12:47:01 PM UTC 2024
|
||||||
* https://xrfragment.org
|
* https://xrfragment.org
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -1138,9 +1138,13 @@ xrfragment_Parser.getMetaData = function() {
|
||||||
var meta = { title : ["title","og:title","dc.title"], description : ["aria-description","og:description","dc.description"], author : ["author","dc.creator"], publisher : ["publisher","dc.publisher"], website : ["og:site_name","og:url","dc.publisher"], license : ["SPDX","dc.rights"]};
|
var meta = { title : ["title","og:title","dc.title"], description : ["aria-description","og:description","dc.description"], author : ["author","dc.creator"], publisher : ["publisher","dc.publisher"], website : ["og:site_name","og:url","dc.publisher"], license : ["SPDX","dc.rights"]};
|
||||||
return meta;
|
return meta;
|
||||||
};
|
};
|
||||||
var xrfragment_URI = $hx_exports["xrfragment"]["URI"] = function() { };
|
var xrfragment_URI = $hx_exports["xrfragment"]["URI"] = function() {
|
||||||
|
this.XRF = { };
|
||||||
|
this.hash = { };
|
||||||
|
this.fragment = "";
|
||||||
|
};
|
||||||
xrfragment_URI.__name__ = true;
|
xrfragment_URI.__name__ = true;
|
||||||
xrfragment_URI.parse = function(url,filter) {
|
xrfragment_URI.parseFragment = function(url,filter) {
|
||||||
var store = { };
|
var store = { };
|
||||||
if(url == null || url.indexOf("#") == -1) {
|
if(url == null || url.indexOf("#") == -1) {
|
||||||
return store;
|
return store;
|
||||||
|
@ -1192,6 +1196,232 @@ xrfragment_URI.template = function(uri,vars) {
|
||||||
parts[1] = frag;
|
parts[1] = frag;
|
||||||
return parts.join("#");
|
return parts.join("#");
|
||||||
};
|
};
|
||||||
|
xrfragment_URI.parse = function(stringUrl,flags) {
|
||||||
|
var r = new EReg("^(?:(?![^:@]+:[^:@/]*@)([^:/?#.]+):)?(?://)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:/?#]*)(?::(\\d*))?)(((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[?#]|$)))*/?)?([^?#/]*))(?:\\?([^#]*))?(?:#(.*))?)","");
|
||||||
|
if(stringUrl.indexOf("://") == -1 && stringUrl.charAt(0) != "/") {
|
||||||
|
stringUrl = "/" + stringUrl;
|
||||||
|
}
|
||||||
|
r.match(stringUrl);
|
||||||
|
var url = new xrfragment_URI();
|
||||||
|
var _g = 0;
|
||||||
|
var _g1 = xrfragment_URI._parts.length;
|
||||||
|
while(_g < _g1) {
|
||||||
|
var i = _g++;
|
||||||
|
url[xrfragment_URI._parts[i]] = r.matched(i);
|
||||||
|
}
|
||||||
|
if(xrfragment_URI.isRelative(url) == true) {
|
||||||
|
if(url.directory == null && url.host != null) {
|
||||||
|
url.file = url.host;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url.hash = { };
|
||||||
|
if(url.fragment != null && url.fragment.length > 0) {
|
||||||
|
url.XRF = xrfragment_URI.parseFragment("#" + url.fragment,flags);
|
||||||
|
var key;
|
||||||
|
var _g = 0;
|
||||||
|
var _g1 = Reflect.fields(url.XRF);
|
||||||
|
while(_g < _g1.length) {
|
||||||
|
var key = _g1[_g];
|
||||||
|
++_g;
|
||||||
|
var v = url.XRF[key];
|
||||||
|
url.hash[key] = v["string"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xrfragment_URI.computeVars(url);
|
||||||
|
return url;
|
||||||
|
};
|
||||||
|
xrfragment_URI.computeVars = function(url) {
|
||||||
|
var r_r = new RegExp("//","g".split("u").join(""));
|
||||||
|
if(url.directory != null && url.directory.indexOf("//") != -1) {
|
||||||
|
url.directory = url.directory.replace(r_r,"/");
|
||||||
|
}
|
||||||
|
if(url.path != null && url.path.indexOf("//") != -1) {
|
||||||
|
url.path = url.path.replace(r_r,"/");
|
||||||
|
}
|
||||||
|
if(url.file != null && url.file.indexOf("//") != -1) {
|
||||||
|
url.file = url.file.replace(r_r,"/");
|
||||||
|
}
|
||||||
|
url.URN = url.scheme + "://" + url.host;
|
||||||
|
if(url.port != null) {
|
||||||
|
url.URN += ":" + url.port;
|
||||||
|
}
|
||||||
|
url.URN += url.directory;
|
||||||
|
if(url.file != null) {
|
||||||
|
var parts = url.file.split(".");
|
||||||
|
if(parts.length > 1) {
|
||||||
|
url.fileExt = parts.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xrfragment_URI.toString = function(url) {
|
||||||
|
var result = "";
|
||||||
|
if(url.scheme != null) {
|
||||||
|
result += url.scheme + "://";
|
||||||
|
}
|
||||||
|
if(url.user != null) {
|
||||||
|
result += url.user + ":";
|
||||||
|
}
|
||||||
|
if(url.password != null) {
|
||||||
|
result += url.password + "@";
|
||||||
|
}
|
||||||
|
if(url.host != null) {
|
||||||
|
result += url.host;
|
||||||
|
}
|
||||||
|
if(url.port != null) {
|
||||||
|
result += ":" + url.port;
|
||||||
|
}
|
||||||
|
if(url.directory != null) {
|
||||||
|
result += url.directory;
|
||||||
|
}
|
||||||
|
if(url.file != null) {
|
||||||
|
result += url.file;
|
||||||
|
}
|
||||||
|
if(url.query != null) {
|
||||||
|
result += "?" + url.query;
|
||||||
|
}
|
||||||
|
if(url.fragment != null) {
|
||||||
|
result += "#" + url.fragment;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
xrfragment_URI.appendURI = function(url,appendedURI) {
|
||||||
|
if(xrfragment_URI.isRelative(url) == true) {
|
||||||
|
return xrfragment_URI.appendToRelativeURI(url,appendedURI);
|
||||||
|
} else {
|
||||||
|
return xrfragment_URI.appendToAbsoluteURI(url,appendedURI);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xrfragment_URI.isRelative = function(url) {
|
||||||
|
return url.scheme == null;
|
||||||
|
};
|
||||||
|
xrfragment_URI.appendToRelativeURI = function(url,appendedURI) {
|
||||||
|
if(url.directory == null || url.host == null) {
|
||||||
|
return xrfragment_URI.cloneURI(appendedURI);
|
||||||
|
}
|
||||||
|
var resultURI = new xrfragment_URI();
|
||||||
|
resultURI.host = url.host;
|
||||||
|
resultURI.directory = url.directory;
|
||||||
|
if(appendedURI.host != null) {
|
||||||
|
resultURI.directory += appendedURI.host;
|
||||||
|
}
|
||||||
|
if(appendedURI.directory != null) {
|
||||||
|
var directory = appendedURI.directory;
|
||||||
|
if(appendedURI.host == null) {
|
||||||
|
resultURI.directory += HxOverrides.substr(directory,1,null);
|
||||||
|
} else {
|
||||||
|
resultURI.directory += directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(appendedURI.file != null) {
|
||||||
|
resultURI.file = appendedURI.file;
|
||||||
|
}
|
||||||
|
resultURI.path = resultURI.directory + resultURI.file;
|
||||||
|
if(appendedURI.query != null) {
|
||||||
|
resultURI.query = appendedURI.query;
|
||||||
|
}
|
||||||
|
if(appendedURI.fragment != null) {
|
||||||
|
resultURI.fragment = appendedURI.fragment;
|
||||||
|
}
|
||||||
|
return resultURI;
|
||||||
|
};
|
||||||
|
xrfragment_URI.appendToAbsoluteURI = function(url,appendedURI) {
|
||||||
|
var resultURI = new xrfragment_URI();
|
||||||
|
if(url.scheme != null) {
|
||||||
|
resultURI.scheme = url.scheme;
|
||||||
|
}
|
||||||
|
if(url.host != null) {
|
||||||
|
resultURI.host = url.host;
|
||||||
|
}
|
||||||
|
var directory = "";
|
||||||
|
if(url.directory != null) {
|
||||||
|
directory = url.directory;
|
||||||
|
}
|
||||||
|
if(appendedURI.host != null) {
|
||||||
|
appendedURI.directory += appendedURI.host;
|
||||||
|
}
|
||||||
|
if(appendedURI.directory != null) {
|
||||||
|
directory += appendedURI.directory;
|
||||||
|
}
|
||||||
|
resultURI.directory = directory;
|
||||||
|
if(appendedURI.file != null) {
|
||||||
|
resultURI.file = appendedURI.file;
|
||||||
|
}
|
||||||
|
resultURI.path = resultURI.directory + resultURI.file;
|
||||||
|
if(appendedURI.query != null) {
|
||||||
|
resultURI.query = appendedURI.query;
|
||||||
|
}
|
||||||
|
if(appendedURI.fragment != null) {
|
||||||
|
resultURI.fragment = appendedURI.fragment;
|
||||||
|
}
|
||||||
|
return resultURI;
|
||||||
|
};
|
||||||
|
xrfragment_URI.toAbsolute = function(url,newUrl) {
|
||||||
|
var newURI = xrfragment_URI.parse(newUrl,0);
|
||||||
|
var resultURI = new xrfragment_URI();
|
||||||
|
resultURI.port = url.port;
|
||||||
|
resultURI.source = newUrl;
|
||||||
|
if(newURI.scheme != null) {
|
||||||
|
resultURI.scheme = newURI.scheme;
|
||||||
|
} else {
|
||||||
|
resultURI.scheme = url.scheme;
|
||||||
|
}
|
||||||
|
if(newURI.host != null && newURI.host.length > 0) {
|
||||||
|
resultURI.host = newURI.host;
|
||||||
|
resultURI.port = null;
|
||||||
|
resultURI.fragment = null;
|
||||||
|
resultURI.hash = { };
|
||||||
|
resultURI.XRF = { };
|
||||||
|
if(newURI.port != null) {
|
||||||
|
resultURI.port = newURI.port;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resultURI.host = url.host;
|
||||||
|
}
|
||||||
|
var directory = "";
|
||||||
|
if(url.directory != null) {
|
||||||
|
directory = url.directory;
|
||||||
|
}
|
||||||
|
if(newURI.directory != null) {
|
||||||
|
if(newUrl.charAt(0) != "/" && newUrl.indexOf("://") == -1) {
|
||||||
|
directory += newURI.directory;
|
||||||
|
} else {
|
||||||
|
directory = newURI.directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultURI.directory = directory;
|
||||||
|
if(newURI.file != null) {
|
||||||
|
resultURI.file = newURI.file;
|
||||||
|
}
|
||||||
|
resultURI.path = resultURI.directory + resultURI.file;
|
||||||
|
if(newURI.query != null) {
|
||||||
|
resultURI.query = newURI.query;
|
||||||
|
}
|
||||||
|
if(newURI.fragment != null) {
|
||||||
|
resultURI.fragment = newURI.fragment;
|
||||||
|
}
|
||||||
|
resultURI.hash = newURI.hash;
|
||||||
|
resultURI.XRF = newURI.XRF;
|
||||||
|
xrfragment_URI.computeVars(resultURI);
|
||||||
|
return resultURI;
|
||||||
|
};
|
||||||
|
xrfragment_URI.cloneURI = function(url) {
|
||||||
|
var clonedURI = new xrfragment_URI();
|
||||||
|
clonedURI.url = url.url;
|
||||||
|
clonedURI.source = url.source;
|
||||||
|
clonedURI.scheme = url.scheme;
|
||||||
|
clonedURI.authority = url.authority;
|
||||||
|
clonedURI.userInfo = url.userInfo;
|
||||||
|
clonedURI.password = url.password;
|
||||||
|
clonedURI.host = url.host;
|
||||||
|
clonedURI.port = url.port;
|
||||||
|
clonedURI.relative = url.relative;
|
||||||
|
clonedURI.path = url.path;
|
||||||
|
clonedURI.directory = url.directory;
|
||||||
|
clonedURI.file = url.file;
|
||||||
|
clonedURI.query = url.query;
|
||||||
|
clonedURI.fragment = url.fragment;
|
||||||
|
return clonedURI;
|
||||||
|
};
|
||||||
var xrfragment_XRF = $hx_exports["xrfragment"]["XRF"] = function(_fragment,_flags,_index) {
|
var xrfragment_XRF = $hx_exports["xrfragment"]["XRF"] = function(_fragment,_flags,_index) {
|
||||||
this.floats = [];
|
this.floats = [];
|
||||||
this.shift = [];
|
this.shift = [];
|
||||||
|
@ -1302,6 +1532,7 @@ haxe_Template.hxKeepArrayIterator = new haxe_iterators_ArrayIterator([]);
|
||||||
xrfragment_Parser.error = "";
|
xrfragment_Parser.error = "";
|
||||||
xrfragment_Parser.debug = false;
|
xrfragment_Parser.debug = false;
|
||||||
xrfragment_URI.__meta__ = { statics : { template : { keep : null}}};
|
xrfragment_URI.__meta__ = { statics : { template : { keep : null}}};
|
||||||
|
xrfragment_URI._parts = ["source","scheme","authority","userInfo","user","password","host","port","relative","path","directory","file","query","fragment"];
|
||||||
xrfragment_XRF.IMMUTABLE = 1;
|
xrfragment_XRF.IMMUTABLE = 1;
|
||||||
xrfragment_XRF.PROP_BIND = 2;
|
xrfragment_XRF.PROP_BIND = 2;
|
||||||
xrfragment_XRF.QUERY_OPERATOR = 4;
|
xrfragment_XRF.QUERY_OPERATOR = 4;
|
||||||
|
@ -1589,7 +1820,7 @@ let pub = function( url, node_or_model, flags ){ // evaluate fragments in url
|
||||||
if( !url ) return
|
if( !url ) return
|
||||||
if( !url.match(/#/) ) url = `#${url}`
|
if( !url.match(/#/) ) url = `#${url}`
|
||||||
let { THREE, camera } = xrf
|
let { THREE, camera } = xrf
|
||||||
let frag = xrf.URI.parse( url, flags )
|
let frag = xrf.URI.parse( url, flags ).XRF
|
||||||
let fromNode = node_or_model != xrf.model
|
let fromNode = node_or_model != xrf.model
|
||||||
let isNode = node_or_model && node_or_model.children
|
let isNode = node_or_model && node_or_model.children
|
||||||
|
|
||||||
|
@ -1756,24 +1987,6 @@ xrf.reset = () => {
|
||||||
xrf.layers = 0
|
xrf.layers = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
xrf.parseUrl = (url) => {
|
|
||||||
let urlExHash = url.replace(/#.*/,'')
|
|
||||||
let urlObj,file
|
|
||||||
let store = {}
|
|
||||||
try{
|
|
||||||
urlObj = new URL( urlExHash.match(/:\/\//) ? urlExHash : String(`https://fake.com/${url}`).replace(/\/\//,'/') )
|
|
||||||
file = urlObj.pathname.substring(urlObj.pathname.lastIndexOf('/') + 1);
|
|
||||||
let search = urlObj.search.substr(1).split("&")
|
|
||||||
for( let i in search ) store[ (search[i].split("=")[0]) ] = search[i].split("=")[1] || ''
|
|
||||||
}catch(e){ }
|
|
||||||
let hashmap = url.match("#") ? url.replace(/.*#/,'').split("&") : []
|
|
||||||
for( let i in hashmap ) store[ (hashmap[i].split("=")[0]) ] = hashmap[i].split("=")[1] || ''
|
|
||||||
let dir = url.substring(0, url.lastIndexOf('/') + 1)
|
|
||||||
const hash = url.match(/#/) ? url.replace(/.*#/,'') : ''
|
|
||||||
const ext = file.split('.').pop()
|
|
||||||
return {urlObj,dir,file,hash,ext,store}
|
|
||||||
}
|
|
||||||
|
|
||||||
xrf.add = (object) => {
|
xrf.add = (object) => {
|
||||||
object.isXRF = true // mark for easy deletion when replacing scene
|
object.isXRF = true // mark for easy deletion when replacing scene
|
||||||
xrf.scene.add(object)
|
xrf.scene.add(object)
|
||||||
|
@ -1784,42 +1997,52 @@ xrf.hasNoMaterial = (mesh) => {
|
||||||
const hasMaterialName = mesh.material && mesh.material.name.length > 0
|
const hasMaterialName = mesh.material && mesh.material.name.length > 0
|
||||||
return mesh.geometry && !hasMaterialName && !hasTexture
|
return mesh.geometry && !hasMaterialName && !hasTexture
|
||||||
}
|
}
|
||||||
xrf.navigator = {}
|
xrf.navigator = {URI:{}}
|
||||||
|
|
||||||
xrf.navigator.to = (url,flags,loader,data) => {
|
xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
if( !url ) throw 'xrf.navigator.to(..) no url given'
|
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 URI = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
URI.hash = xrf.navigator.reactifyHash(URI.hash)
|
||||||
|
let fileChange = URI.URN + URI.file != xrf.navigator.URI.URN + xrf.navigator.URI.file
|
||||||
|
let external = URI.URN != document.location.origin + document.location.pathname
|
||||||
|
let hasPos = URI.hash.pos
|
||||||
|
let hashChange = String(xrf.navigator.URI.fragment||"") != String(URI.fragment||"")
|
||||||
|
let hashbus = xrf.hashbus
|
||||||
|
xrf.navigator.URI = URI
|
||||||
|
let {directory,file,fragment,fileExt} = URI;
|
||||||
|
|
||||||
let hashbus = xrf.hashbus
|
const evalFragment = () => {
|
||||||
|
if( URI.fragment ){
|
||||||
|
hashbus.pub( URI.fragment, xrf.model, flags ) // eval local URI XR fragments
|
||||||
|
xrf.navigator.updateHash(fragment) // which don't require
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise( (resolve,reject) => {
|
return new Promise( (resolve,reject) => {
|
||||||
xrf
|
xrf
|
||||||
.emit('navigate', {url,loader,data})
|
.emit('navigate', {url,loader,data})
|
||||||
.then( () => {
|
.then( () => {
|
||||||
|
|
||||||
if( ext && !loader ){
|
const Loader = xrf.loaders[fileExt]
|
||||||
const Loader = xrf.loaders[ext]
|
|
||||||
|
if( fileExt && !loader ){
|
||||||
if( !Loader ) return resolve()
|
if( !Loader ) return resolve()
|
||||||
loader = loader || new Loader().setPath( dir )
|
loader = loader || new Loader().setPath( URI.URN )
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !hash && !file && !ext ) return resolve(xrf.model) // nothing we can do here
|
if( !URI.fragment && !URI.file && !URI.fileExt ) return resolve(xrf.model) // nothing we can do here
|
||||||
|
|
||||||
if( hashChange && !hasPos ){
|
if( xrf.model && !fileChange && hashChange && !hasPos ){
|
||||||
hashbus.pub( url, xrf.model, flags ) // eval local URI XR fragments
|
evalFragment()
|
||||||
xrf.navigator.updateHash(hash) // which don't require
|
return resolve(xrf.model) // positional navigation
|
||||||
return resolve(xrf.model) // positional navigation
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xrf
|
xrf
|
||||||
.emit('navigateLoading', {url,loader,data})
|
.emit('navigateLoading', {url,loader,data})
|
||||||
.then( () => {
|
.then( () => {
|
||||||
if( hashChange && hasPos ){ // we're already loaded
|
if( (!fileChange || !file) && hashChange && hasPos ){ // we're already loaded
|
||||||
hashbus.pub( url, xrf.model, flags ) // and eval local URI XR fragments
|
evalFragment()
|
||||||
xrf.navigator.updateHash(hash)
|
|
||||||
xrf.emit('navigateLoaded',{url})
|
xrf.emit('navigateLoaded',{url})
|
||||||
return resolve(xrf.model)
|
return resolve(xrf.model)
|
||||||
}
|
}
|
||||||
|
@ -1829,17 +2052,20 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
xrf.reset()
|
xrf.reset()
|
||||||
|
|
||||||
// force relative path for files which dont include protocol or relative path
|
// force relative path for files which dont include protocol or relative path
|
||||||
if( dir ) dir = dir[0] == '.' || dir.match("://") ? dir : `.${dir}`
|
if( directory ) directory = directory[0] == '.' || directory.match("://") ? directory : `.${directory}`
|
||||||
url = url.replace(dir,"")
|
|
||||||
loader = loader || new Loader().setPath( dir )
|
loader = loader || new Loader().setPath( URI.URN )
|
||||||
const onLoad = (model) => {
|
const onLoad = (model) => {
|
||||||
|
|
||||||
model.file = file
|
model.file = URI.file
|
||||||
// only change url when loading *another* file
|
// only change url when loading *another* file
|
||||||
if( xrf.model ) xrf.navigator.pushState( `${dir}${file}`, hash )
|
if( xrf.model ){
|
||||||
|
xrf.navigator.pushState( external ? URI.URN + URI.file : URI.file, fragment )
|
||||||
|
}
|
||||||
|
//if( xrf.model ) xrf.navigator.pushState( `${ document.location.pathname != URI.directory ? URI.directory: ''}${URI.file}`, fragment )
|
||||||
xrf.model = model
|
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) )
|
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||||
|
|
||||||
|
@ -1847,17 +2073,16 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
xrf.XRWG.generate({model,scene:model.scene})
|
xrf.XRWG.generate({model,scene:model.scene})
|
||||||
|
|
||||||
// spec: 2. init metadata inside model for non-SRC data
|
// spec: 2. init metadata inside model for non-SRC data
|
||||||
if( !model.isSRC ){
|
if( !model.isSRC ){
|
||||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||||
}
|
}
|
||||||
|
|
||||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||||
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URL (https://xrfragment.org/#predefined_view)
|
// spec: predefined view(s) & objects-of-interest-in-XRWG from URI (https://xrfragment.org/#predefined_view)
|
||||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||||
|
|
||||||
xrf.add( model.scene )
|
xrf.add( model.scene )
|
||||||
if( hash ) xrf.navigator.updateHash(hash)
|
if( fragment ) xrf.navigator.updateHash(fragment)
|
||||||
xrf.emit('navigateLoaded',{url,model})
|
xrf.emit('navigateLoaded',{url,model})
|
||||||
resolve(model)
|
resolve(model)
|
||||||
}
|
}
|
||||||
|
@ -1866,7 +2091,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
loader.parse(data, "", onLoad )
|
loader.parse(data, "", onLoad )
|
||||||
}else{
|
}else{
|
||||||
try{
|
try{
|
||||||
loader.load(url, onLoad )
|
loader.load(file, onLoad )
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.error(e)
|
console.error(e)
|
||||||
xrf.emit('navigateError',{url})
|
xrf.emit('navigateError',{url})
|
||||||
|
@ -1880,9 +2105,12 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
xrf.navigator.init = () => {
|
xrf.navigator.init = () => {
|
||||||
if( xrf.navigator.init.inited ) return
|
if( xrf.navigator.init.inited ) return
|
||||||
|
|
||||||
|
xrf.navigator.URI = xrfragment.URI.parse(document.location.href)
|
||||||
|
|
||||||
window.addEventListener('popstate', function (event){
|
window.addEventListener('popstate', function (event){
|
||||||
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
||||||
xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
|
//xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
|
||||||
|
xrf.navigator.to( document.location.href.replace(/\?/,'') )
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1908,10 +2136,10 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
||||||
|
|
||||||
xrf.addEventListener('navigate', (opts) => {
|
xrf.addEventListener('navigate', (opts) => {
|
||||||
let {url} = opts
|
let {url} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let {fileExt} = xrfragment.URI.parse(url)
|
||||||
|
|
||||||
// handle http links
|
// handle http links
|
||||||
if( url.match(/^http/) && !xrf.loaders[ext] ){
|
if( url.match(/^http/) && !xrf.loaders[fileExt] ){
|
||||||
let inIframe
|
let inIframe
|
||||||
try { inIframe = window.self !== window.top; } catch (e) { inIframe = true; }
|
try { inIframe = window.self !== window.top; } catch (e) { inIframe = true; }
|
||||||
return inIframe ? window.parent.postMessage({ url }, '*') : window.open( url, '_blank')
|
return inIframe ? window.parent.postMessage({ url }, '*') : window.open( url, '_blank')
|
||||||
|
@ -1931,7 +2159,7 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
||||||
|
|
||||||
xrf.navigator.updateHash = (hash,opts) => {
|
xrf.navigator.updateHash = (hash,opts) => {
|
||||||
if( hash.replace(/^#/,'') == document.location.hash.substr(1) || hash.match(/\|/) ) return // skip unnecesary pushState triggers
|
if( hash.replace(/^#/,'') == document.location.hash.substr(1) || hash.match(/\|/) ) return // skip unnecesary pushState triggers
|
||||||
console.log(`URL: ${document.location.search.substr(1)}#${hash}`)
|
console.log(`URI: ${document.location.search.substr(1)}#${hash}`)
|
||||||
xrf.navigator.updateHash.active = true // important to prevent recursion
|
xrf.navigator.updateHash.active = true // important to prevent recursion
|
||||||
document.location.hash = hash
|
document.location.hash = hash
|
||||||
xrf.navigator.updateHash.active = false
|
xrf.navigator.updateHash.active = false
|
||||||
|
@ -1942,6 +2170,23 @@ xrf.navigator.pushState = (file,hash) => {
|
||||||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
||||||
xrf.emit('pushState', {file, hash} )
|
xrf.emit('pushState', {file, hash} )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xrf.navigator.reactifyHash = ( obj ) => {
|
||||||
|
return new Proxy(obj,{
|
||||||
|
get(me,k) { return me[k] },
|
||||||
|
set(me,k,v){
|
||||||
|
me[k] = v
|
||||||
|
xrf.navigator.to( "#" + this.toString(me) )
|
||||||
|
},
|
||||||
|
toString(me){
|
||||||
|
let parts = []
|
||||||
|
Object.keys(me).map( (k) => {
|
||||||
|
parts.push( me[k] ? `${k}=${encodeURIComponent(me[k])}` : k )
|
||||||
|
})
|
||||||
|
return parts.join('&')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* navigation, portals & mutations
|
* navigation, portals & mutations
|
||||||
|
@ -1993,7 +2238,6 @@ xrf.frag.href = function(v, opts){
|
||||||
.emit('href',{click:true,mesh,xrf:v}) // let all listeners agree
|
.emit('href',{click:true,mesh,xrf:v}) // let all listeners agree
|
||||||
.then( () => {
|
.then( () => {
|
||||||
|
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(v.string)
|
|
||||||
const isLocal = v.string[0] == '#'
|
const isLocal = v.string[0] == '#'
|
||||||
const hasPos = isLocal && v.string.match(/pos=/)
|
const hasPos = isLocal && v.string.match(/pos=/)
|
||||||
const flags = isLocal ? xrf.XRF.PV_OVERRIDE : undefined
|
const flags = isLocal ? xrf.XRF.PV_OVERRIDE : undefined
|
||||||
|
@ -2153,6 +2397,32 @@ xrf.frag.pos = function(v, opts){
|
||||||
camera.updateMatrixWorld()
|
camera.updateMatrixWorld()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xrf.frag.pos.get = function(precision,randomize){
|
||||||
|
if( !precision ) precision = 2;
|
||||||
|
if( typeof THREE == 'undefined' ) THREE = xrf.THREE
|
||||||
|
let radToDeg = THREE.MathUtils.radToDeg
|
||||||
|
let toDeg = (x) => x / (Math.PI / 180)
|
||||||
|
let camera = xrf.camera
|
||||||
|
if( randomize ){
|
||||||
|
camera.position.x += Math.random()/10
|
||||||
|
camera.position.z += Math.random()/10
|
||||||
|
}
|
||||||
|
|
||||||
|
// *TODO* add camera direction
|
||||||
|
let direction = new xrf.THREE.Vector3()
|
||||||
|
camera.getWorldDirection(direction)
|
||||||
|
const pitch = Math.asin(direction.y);
|
||||||
|
const yaw = Math.atan2(direction.x, direction.z);
|
||||||
|
const pitchInDegrees = pitch * 180 / Math.PI;
|
||||||
|
const yawInDegrees = yaw * 180 / Math.PI;
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: String(camera.position.x.toFixed(2)),
|
||||||
|
y: String(camera.position.y.toFixed(2)),
|
||||||
|
z: String(camera.position.z.toFixed(2)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xrf.addEventListener('reset', (opts) => {
|
xrf.addEventListener('reset', (opts) => {
|
||||||
// set the player to position 0,0,0
|
// set the player to position 0,0,0
|
||||||
xrf.camera.position.set(0,0,0)
|
xrf.camera.position.set(0,0,0)
|
||||||
|
@ -2207,7 +2477,7 @@ xrf.frag.src = function(v, opts){
|
||||||
if( mesh.isSRC ) return // only embed src once
|
if( mesh.isSRC ) return // only embed src once
|
||||||
|
|
||||||
let url = xrf.frag.src.expandURI( mesh, v.string )
|
let url = xrf.frag.src.expandURI( mesh, v.string )
|
||||||
let srcFrag = opts.srcFrag = xrfragment.URI.parse(url)
|
let srcFrag = opts.srcFrag = xrfragment.URI.parse(url).XRF
|
||||||
opts.isLocal = v.string[0] == '#'
|
opts.isLocal = v.string[0] == '#'
|
||||||
opts.isPortal = xrf.frag.src.renderAsPortal(mesh)
|
opts.isPortal = xrf.frag.src.renderAsPortal(mesh)
|
||||||
opts.isSRC = mesh.isSRC = true
|
opts.isSRC = mesh.isSRC = true
|
||||||
|
@ -2294,7 +2564,7 @@ xrf.frag.src.externalSRC = (url,frag,opts) => {
|
||||||
fetch(url, { method: 'HEAD' })
|
fetch(url, { method: 'HEAD' })
|
||||||
.then( (res) => {
|
.then( (res) => {
|
||||||
let mimetype = res.headers.get('Content-type')
|
let mimetype = res.headers.get('Content-type')
|
||||||
if(xrf.debug != undefined ) console.log("HEAD "+url+" => "+mimetype)
|
if(xrf.debug > 0 ) console.log("HEAD "+url+" => "+mimetype)
|
||||||
if( url.replace(/#.*/,'').match(/\.(gltf|glb)$/) ) mimetype = 'gltf'
|
if( url.replace(/#.*/,'').match(/\.(gltf|glb)$/) ) mimetype = 'gltf'
|
||||||
if( url.replace(/#.*/,'').match(/\.(frag|fs|glsl)$/) ) mimetype = 'x-shader/x-fragment'
|
if( url.replace(/#.*/,'').match(/\.(frag|fs|glsl)$/) ) mimetype = 'x-shader/x-fragment'
|
||||||
if( url.replace(/#.*/,'').match(/\.(vert|vs)$/) ) mimetype = 'x-shader/x-fragment'
|
if( url.replace(/#.*/,'').match(/\.(vert|vs)$/) ) mimetype = 'x-shader/x-fragment'
|
||||||
|
@ -3195,8 +3465,8 @@ xrf.addEventListener('render', (opts) => {
|
||||||
|
|
||||||
let loadAudio = (mimetype) => function(url,opts){
|
let loadAudio = (mimetype) => function(url,opts){
|
||||||
let {mesh,src,camera,THREE} = opts
|
let {mesh,src,camera,THREE} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
let frag = xrf.URI.parse( url )
|
let frag = URL.XRF
|
||||||
|
|
||||||
xrf.init.audio()
|
xrf.init.audio()
|
||||||
let isPositionalAudio = !(mesh.position.x == 0 && mesh.position.y == 0 && mesh.position.z == 0)
|
let isPositionalAudio = !(mesh.position.x == 0 && mesh.position.y == 0 && mesh.position.z == 0)
|
||||||
|
@ -3207,8 +3477,8 @@ let loadAudio = (mimetype) => function(url,opts){
|
||||||
mesh.media = mesh.media || {}
|
mesh.media = mesh.media || {}
|
||||||
mesh.media.audio = { set: (mediafragment,v) => mesh.media.audio[mediafragment] = v }
|
mesh.media.audio = { set: (mediafragment,v) => mesh.media.audio[mediafragment] = v }
|
||||||
|
|
||||||
let finalUrl = url.replace(/#.*/,'')
|
let finalUrl = URL.URN + URL.file
|
||||||
if( xrf.debug != undefined ) console.log("GET "+finalUrl)
|
if( xrf.debug > 0 ) console.log("GET "+finalUrl)
|
||||||
audioLoader.load( finalUrl, function( buffer ) {
|
audioLoader.load( finalUrl, function( buffer ) {
|
||||||
|
|
||||||
sound.setBuffer( buffer );
|
sound.setBuffer( buffer );
|
||||||
|
@ -3318,7 +3588,8 @@ audioMimeTypes.map( (mimetype) => xrf.frag.src.type[ mimetype ] = loadAudio(mim
|
||||||
xrf.frag.src.type['fbx'] = function( url, opts ){
|
xrf.frag.src.type['fbx'] = function( url, opts ){
|
||||||
return new Promise( async (resolve,reject) => {
|
return new Promise( async (resolve,reject) => {
|
||||||
let {mesh,src} = opts
|
let {mesh,src} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let frag = URL.XRF
|
||||||
let loader
|
let loader
|
||||||
|
|
||||||
let {THREE} = await import('https://unpkg.com/three@0.161.0/build/three.module.js')
|
let {THREE} = await import('https://unpkg.com/three@0.161.0/build/three.module.js')
|
||||||
|
@ -3346,14 +3617,17 @@ xrf.frag.src.type['fbx'] = function( url, opts ){
|
||||||
xrf.frag.src.type['x-shader/x-fragment'] = function(url,opts){
|
xrf.frag.src.type['x-shader/x-fragment'] = function(url,opts){
|
||||||
let {mesh,THREE} = opts
|
let {mesh,THREE} = opts
|
||||||
|
|
||||||
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let frag = URL.XRF
|
||||||
|
|
||||||
let isFragmentShader = /\.(fs|frag|glsl)$/
|
let isFragmentShader = /\.(fs|frag|glsl)$/
|
||||||
let isVertexShader = /\.(vs|vert)$/
|
let isVertexShader = /\.(vs|vert)$/
|
||||||
|
|
||||||
let shaderReqs = []
|
let shaderReqs = []
|
||||||
let shaderCode = {}
|
let shaderCode = {}
|
||||||
let shader = {
|
let shader = {
|
||||||
fragment: { code: '', url: url.match( isFragmentShader ) ? url : '' },
|
fragment: { code: '', url: url.match( isFragmentShader ) ? URL.URN + URL.file : '' },
|
||||||
vertex: { code: '', url: url.match( isVertexShader ) ? url : '' }
|
vertex: { code: '', url: url.match( isVertexShader ) ? URL.URN + URL.file : '' }
|
||||||
}
|
}
|
||||||
|
|
||||||
var onShaderLoaded = ((args) => (type, status, code) => {
|
var onShaderLoaded = ((args) => (type, status, code) => {
|
||||||
|
@ -3412,19 +3686,15 @@ xrf.frag.src.type['x-shader/x-vertex'] = xrf.frag.src.type['x-shader/x-fragmen
|
||||||
xrf.frag.src.type['gltf'] = function( url, opts ){
|
xrf.frag.src.type['gltf'] = function( url, opts ){
|
||||||
return new Promise( (resolve,reject) => {
|
return new Promise( (resolve,reject) => {
|
||||||
let {mesh,src} = opts
|
let {mesh,src} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let {directory,file,fileExt,URN} = URL;
|
||||||
let loader
|
let loader
|
||||||
|
|
||||||
const Loader = xrf.loaders[ext]
|
const Loader = xrf.loaders[fileExt]
|
||||||
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
||||||
if( !dir.match("://") ){ // force relative path
|
loader = new Loader().setPath( URN )
|
||||||
dir = dir.substr(0,2) == './' ? dir : `./${dir}`
|
|
||||||
loader = new Loader().setPath( dir )
|
|
||||||
}else{
|
|
||||||
loader = new Loader()
|
|
||||||
}
|
|
||||||
|
|
||||||
loader.load(url, (model) => {
|
loader.load(file, (model) => {
|
||||||
model.isSRC = true
|
model.isSRC = true
|
||||||
resolve(model)
|
resolve(model)
|
||||||
})
|
})
|
||||||
|
@ -3435,7 +3705,7 @@ xrf.frag.src.type['gltf'] = function( url, opts ){
|
||||||
let loadHTML = (mimetype) => function(url,opts){
|
let loadHTML = (mimetype) => function(url,opts){
|
||||||
let {mesh,src,camera} = opts
|
let {mesh,src,camera} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||||
let frag = xrf.URI.parse( url )
|
let frag = xrf.URI.parse( url ).XRF
|
||||||
console.warn("todo: html viewer for src not implemented")
|
console.warn("todo: html viewer for src not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3452,6 +3722,8 @@ htmlMimeTypes.map( (mimetype) => xrf.frag.src.type[ mimetype ] = loadHTML(mimet
|
||||||
xrf.frag.src.type['image/png'] = function(url,opts){
|
xrf.frag.src.type['image/png'] = function(url,opts){
|
||||||
let {mesh,THREE} = opts
|
let {mesh,THREE} = opts
|
||||||
let restrictTo3DBoundingBox = mesh.geometry
|
let restrictTo3DBoundingBox = mesh.geometry
|
||||||
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let frag = URL.XRF
|
||||||
|
|
||||||
mesh.material = new xrf.THREE.MeshBasicMaterial({
|
mesh.material = new xrf.THREE.MeshBasicMaterial({
|
||||||
map: null,
|
map: null,
|
||||||
|
@ -3495,7 +3767,7 @@ xrf.frag.src.type['image/png'] = function(url,opts){
|
||||||
renderImage(texture)
|
renderImage(texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
new THREE.TextureLoader().load( url, onLoad, null, console.error );
|
new THREE.TextureLoader().load( URL.URN + URL.file, onLoad, null, console.error );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3701,9 +3973,9 @@ xrf.portalNonEuclidian.stencilRef = 1
|
||||||
|
|
||||||
let loadVideo = (mimetype) => function(url,opts){
|
let loadVideo = (mimetype) => function(url,opts){
|
||||||
let {mesh,src,camera} = opts
|
let {mesh,src,camera} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
|
||||||
const THREE = xrf.THREE
|
const THREE = xrf.THREE
|
||||||
let frag = xrf.URI.parse( url )
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let frag = URL.XRF
|
||||||
|
|
||||||
mesh.media = mesh.media || {}
|
mesh.media = mesh.media || {}
|
||||||
|
|
||||||
|
@ -3725,7 +3997,7 @@ let loadVideo = (mimetype) => function(url,opts){
|
||||||
},false)
|
},false)
|
||||||
})
|
})
|
||||||
|
|
||||||
video.src = url
|
video.src = URL.URN + URL.file
|
||||||
video.speed = 1.0
|
video.speed = 1.0
|
||||||
video.looping = false
|
video.looping = false
|
||||||
video.set = (mediafragment,v) => {
|
video.set = (mediafragment,v) => {
|
||||||
|
@ -4161,6 +4433,17 @@ AFRAME.registerComponent('movement-controls', {
|
||||||
|
|
||||||
}())
|
}())
|
||||||
});
|
});
|
||||||
|
AFRAME.components['hand-tracking-controls'].Component.prototype.onModelLoaded = function(onModelLoaded){
|
||||||
|
return function(e){
|
||||||
|
onModelLoaded.apply(this);
|
||||||
|
// re-attach children
|
||||||
|
([...this.el.children]).map( (c) => {
|
||||||
|
if( c.object3D ){
|
||||||
|
this.el.object3D.getObjectByName("wrist").add(c.object3D)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}(AFRAME.components['hand-tracking-controls'].Component.prototype.onModelLoaded)
|
||||||
// look-controls turns off autoUpdateMatrix (of player) which
|
// look-controls turns off autoUpdateMatrix (of player) which
|
||||||
// will break teleporting and other stuff
|
// will break teleporting and other stuff
|
||||||
// overriding this is easier then adding updateMatrixWorld() everywhere else
|
// overriding this is easier then adding updateMatrixWorld() everywhere else
|
||||||
|
@ -4280,7 +4563,7 @@ AFRAME.registerComponent('pressable', {
|
||||||
this.el.emit('click');
|
this.el.emit('click');
|
||||||
this.pressed = setTimeout( () => {
|
this.pressed = setTimeout( () => {
|
||||||
this.el.emit('pressedended');
|
this.el.emit('pressedended');
|
||||||
this.pressed = null
|
this.pressed = false
|
||||||
},300)
|
},300)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4438,8 +4721,10 @@ window.AFRAME.registerComponent('xrf-button', {
|
||||||
this.el.addEventListener('mouseenter', (e) => this.onMouseEnter(e) );
|
this.el.addEventListener('mouseenter', (e) => this.onMouseEnter(e) );
|
||||||
this.el.addEventListener('mouseleave', (e) => this.onMouseLeave(e) );
|
this.el.addEventListener('mouseleave', (e) => this.onMouseLeave(e) );
|
||||||
|
|
||||||
|
let cb = new Function(this.data.action)
|
||||||
|
|
||||||
if( this.data.action ){
|
if( this.data.action ){
|
||||||
this.el.addEventListener('click', new Function(this.data.action) )
|
this.el.addEventListener('click', AFRAME.utils.throttle(cb, 500 ) )
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bindMethods: function() {
|
bindMethods: function() {
|
||||||
|
@ -4611,6 +4896,8 @@ window.AFRAME.registerComponent('xrf-get', {
|
||||||
var el = this.el;
|
var el = this.el;
|
||||||
var meshname = this.data.name || this.data;
|
var meshname = this.data.name || this.data;
|
||||||
|
|
||||||
|
if( !meshname || typeof meshname != 'string' ) return
|
||||||
|
|
||||||
this.el.addEventListener('update', (evt) => {
|
this.el.addEventListener('update', (evt) => {
|
||||||
|
|
||||||
setTimeout( () => {
|
setTimeout( () => {
|
||||||
|
@ -4647,7 +4934,8 @@ window.AFRAME.registerComponent('xrf-get', {
|
||||||
this.el.object3D.child = mesh // keep reference (because .children will be empty)
|
this.el.object3D.child = mesh // keep reference (because .children will be empty)
|
||||||
|
|
||||||
if( !this.el.id ) this.el.setAttribute("id",`xrf-${mesh.name}`)
|
if( !this.el.id ) this.el.setAttribute("id",`xrf-${mesh.name}`)
|
||||||
}else console.warn("xrf-get ignore: "+JSON.stringify(this.data))
|
}
|
||||||
|
|
||||||
}, evt && evt.timeout ? evt.timeout: 500)
|
}, evt && evt.timeout ? evt.timeout: 500)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -1133,9 +1133,13 @@ xrfragment_Parser.getMetaData = function() {
|
||||||
var meta = { title : ["title","og:title","dc.title"], description : ["aria-description","og:description","dc.description"], author : ["author","dc.creator"], publisher : ["publisher","dc.publisher"], website : ["og:site_name","og:url","dc.publisher"], license : ["SPDX","dc.rights"]};
|
var meta = { title : ["title","og:title","dc.title"], description : ["aria-description","og:description","dc.description"], author : ["author","dc.creator"], publisher : ["publisher","dc.publisher"], website : ["og:site_name","og:url","dc.publisher"], license : ["SPDX","dc.rights"]};
|
||||||
return meta;
|
return meta;
|
||||||
};
|
};
|
||||||
var xrfragment_URI = $hx_exports["xrfragment"]["URI"] = function() { };
|
var xrfragment_URI = $hx_exports["xrfragment"]["URI"] = function() {
|
||||||
|
this.XRF = { };
|
||||||
|
this.hash = { };
|
||||||
|
this.fragment = "";
|
||||||
|
};
|
||||||
xrfragment_URI.__name__ = true;
|
xrfragment_URI.__name__ = true;
|
||||||
xrfragment_URI.parse = function(url,filter) {
|
xrfragment_URI.parseFragment = function(url,filter) {
|
||||||
var store = { };
|
var store = { };
|
||||||
if(url == null || url.indexOf("#") == -1) {
|
if(url == null || url.indexOf("#") == -1) {
|
||||||
return store;
|
return store;
|
||||||
|
@ -1187,6 +1191,232 @@ xrfragment_URI.template = function(uri,vars) {
|
||||||
parts[1] = frag;
|
parts[1] = frag;
|
||||||
return parts.join("#");
|
return parts.join("#");
|
||||||
};
|
};
|
||||||
|
xrfragment_URI.parse = function(stringUrl,flags) {
|
||||||
|
var r = new EReg("^(?:(?![^:@]+:[^:@/]*@)([^:/?#.]+):)?(?://)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:/?#]*)(?::(\\d*))?)(((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[?#]|$)))*/?)?([^?#/]*))(?:\\?([^#]*))?(?:#(.*))?)","");
|
||||||
|
if(stringUrl.indexOf("://") == -1 && stringUrl.charAt(0) != "/") {
|
||||||
|
stringUrl = "/" + stringUrl;
|
||||||
|
}
|
||||||
|
r.match(stringUrl);
|
||||||
|
var url = new xrfragment_URI();
|
||||||
|
var _g = 0;
|
||||||
|
var _g1 = xrfragment_URI._parts.length;
|
||||||
|
while(_g < _g1) {
|
||||||
|
var i = _g++;
|
||||||
|
url[xrfragment_URI._parts[i]] = r.matched(i);
|
||||||
|
}
|
||||||
|
if(xrfragment_URI.isRelative(url) == true) {
|
||||||
|
if(url.directory == null && url.host != null) {
|
||||||
|
url.file = url.host;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url.hash = { };
|
||||||
|
if(url.fragment != null && url.fragment.length > 0) {
|
||||||
|
url.XRF = xrfragment_URI.parseFragment("#" + url.fragment,flags);
|
||||||
|
var key;
|
||||||
|
var _g = 0;
|
||||||
|
var _g1 = Reflect.fields(url.XRF);
|
||||||
|
while(_g < _g1.length) {
|
||||||
|
var key = _g1[_g];
|
||||||
|
++_g;
|
||||||
|
var v = url.XRF[key];
|
||||||
|
url.hash[key] = v["string"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xrfragment_URI.computeVars(url);
|
||||||
|
return url;
|
||||||
|
};
|
||||||
|
xrfragment_URI.computeVars = function(url) {
|
||||||
|
var r_r = new RegExp("//","g".split("u").join(""));
|
||||||
|
if(url.directory != null && url.directory.indexOf("//") != -1) {
|
||||||
|
url.directory = url.directory.replace(r_r,"/");
|
||||||
|
}
|
||||||
|
if(url.path != null && url.path.indexOf("//") != -1) {
|
||||||
|
url.path = url.path.replace(r_r,"/");
|
||||||
|
}
|
||||||
|
if(url.file != null && url.file.indexOf("//") != -1) {
|
||||||
|
url.file = url.file.replace(r_r,"/");
|
||||||
|
}
|
||||||
|
url.URN = url.scheme + "://" + url.host;
|
||||||
|
if(url.port != null) {
|
||||||
|
url.URN += ":" + url.port;
|
||||||
|
}
|
||||||
|
url.URN += url.directory;
|
||||||
|
if(url.file != null) {
|
||||||
|
var parts = url.file.split(".");
|
||||||
|
if(parts.length > 1) {
|
||||||
|
url.fileExt = parts.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xrfragment_URI.toString = function(url) {
|
||||||
|
var result = "";
|
||||||
|
if(url.scheme != null) {
|
||||||
|
result += url.scheme + "://";
|
||||||
|
}
|
||||||
|
if(url.user != null) {
|
||||||
|
result += url.user + ":";
|
||||||
|
}
|
||||||
|
if(url.password != null) {
|
||||||
|
result += url.password + "@";
|
||||||
|
}
|
||||||
|
if(url.host != null) {
|
||||||
|
result += url.host;
|
||||||
|
}
|
||||||
|
if(url.port != null) {
|
||||||
|
result += ":" + url.port;
|
||||||
|
}
|
||||||
|
if(url.directory != null) {
|
||||||
|
result += url.directory;
|
||||||
|
}
|
||||||
|
if(url.file != null) {
|
||||||
|
result += url.file;
|
||||||
|
}
|
||||||
|
if(url.query != null) {
|
||||||
|
result += "?" + url.query;
|
||||||
|
}
|
||||||
|
if(url.fragment != null) {
|
||||||
|
result += "#" + url.fragment;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
xrfragment_URI.appendURI = function(url,appendedURI) {
|
||||||
|
if(xrfragment_URI.isRelative(url) == true) {
|
||||||
|
return xrfragment_URI.appendToRelativeURI(url,appendedURI);
|
||||||
|
} else {
|
||||||
|
return xrfragment_URI.appendToAbsoluteURI(url,appendedURI);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xrfragment_URI.isRelative = function(url) {
|
||||||
|
return url.scheme == null;
|
||||||
|
};
|
||||||
|
xrfragment_URI.appendToRelativeURI = function(url,appendedURI) {
|
||||||
|
if(url.directory == null || url.host == null) {
|
||||||
|
return xrfragment_URI.cloneURI(appendedURI);
|
||||||
|
}
|
||||||
|
var resultURI = new xrfragment_URI();
|
||||||
|
resultURI.host = url.host;
|
||||||
|
resultURI.directory = url.directory;
|
||||||
|
if(appendedURI.host != null) {
|
||||||
|
resultURI.directory += appendedURI.host;
|
||||||
|
}
|
||||||
|
if(appendedURI.directory != null) {
|
||||||
|
var directory = appendedURI.directory;
|
||||||
|
if(appendedURI.host == null) {
|
||||||
|
resultURI.directory += HxOverrides.substr(directory,1,null);
|
||||||
|
} else {
|
||||||
|
resultURI.directory += directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(appendedURI.file != null) {
|
||||||
|
resultURI.file = appendedURI.file;
|
||||||
|
}
|
||||||
|
resultURI.path = resultURI.directory + resultURI.file;
|
||||||
|
if(appendedURI.query != null) {
|
||||||
|
resultURI.query = appendedURI.query;
|
||||||
|
}
|
||||||
|
if(appendedURI.fragment != null) {
|
||||||
|
resultURI.fragment = appendedURI.fragment;
|
||||||
|
}
|
||||||
|
return resultURI;
|
||||||
|
};
|
||||||
|
xrfragment_URI.appendToAbsoluteURI = function(url,appendedURI) {
|
||||||
|
var resultURI = new xrfragment_URI();
|
||||||
|
if(url.scheme != null) {
|
||||||
|
resultURI.scheme = url.scheme;
|
||||||
|
}
|
||||||
|
if(url.host != null) {
|
||||||
|
resultURI.host = url.host;
|
||||||
|
}
|
||||||
|
var directory = "";
|
||||||
|
if(url.directory != null) {
|
||||||
|
directory = url.directory;
|
||||||
|
}
|
||||||
|
if(appendedURI.host != null) {
|
||||||
|
appendedURI.directory += appendedURI.host;
|
||||||
|
}
|
||||||
|
if(appendedURI.directory != null) {
|
||||||
|
directory += appendedURI.directory;
|
||||||
|
}
|
||||||
|
resultURI.directory = directory;
|
||||||
|
if(appendedURI.file != null) {
|
||||||
|
resultURI.file = appendedURI.file;
|
||||||
|
}
|
||||||
|
resultURI.path = resultURI.directory + resultURI.file;
|
||||||
|
if(appendedURI.query != null) {
|
||||||
|
resultURI.query = appendedURI.query;
|
||||||
|
}
|
||||||
|
if(appendedURI.fragment != null) {
|
||||||
|
resultURI.fragment = appendedURI.fragment;
|
||||||
|
}
|
||||||
|
return resultURI;
|
||||||
|
};
|
||||||
|
xrfragment_URI.toAbsolute = function(url,newUrl) {
|
||||||
|
var newURI = xrfragment_URI.parse(newUrl,0);
|
||||||
|
var resultURI = new xrfragment_URI();
|
||||||
|
resultURI.port = url.port;
|
||||||
|
resultURI.source = newUrl;
|
||||||
|
if(newURI.scheme != null) {
|
||||||
|
resultURI.scheme = newURI.scheme;
|
||||||
|
} else {
|
||||||
|
resultURI.scheme = url.scheme;
|
||||||
|
}
|
||||||
|
if(newURI.host != null && newURI.host.length > 0) {
|
||||||
|
resultURI.host = newURI.host;
|
||||||
|
resultURI.port = null;
|
||||||
|
resultURI.fragment = null;
|
||||||
|
resultURI.hash = { };
|
||||||
|
resultURI.XRF = { };
|
||||||
|
if(newURI.port != null) {
|
||||||
|
resultURI.port = newURI.port;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resultURI.host = url.host;
|
||||||
|
}
|
||||||
|
var directory = "";
|
||||||
|
if(url.directory != null) {
|
||||||
|
directory = url.directory;
|
||||||
|
}
|
||||||
|
if(newURI.directory != null) {
|
||||||
|
if(newUrl.charAt(0) != "/" && newUrl.indexOf("://") == -1) {
|
||||||
|
directory += newURI.directory;
|
||||||
|
} else {
|
||||||
|
directory = newURI.directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultURI.directory = directory;
|
||||||
|
if(newURI.file != null) {
|
||||||
|
resultURI.file = newURI.file;
|
||||||
|
}
|
||||||
|
resultURI.path = resultURI.directory + resultURI.file;
|
||||||
|
if(newURI.query != null) {
|
||||||
|
resultURI.query = newURI.query;
|
||||||
|
}
|
||||||
|
if(newURI.fragment != null) {
|
||||||
|
resultURI.fragment = newURI.fragment;
|
||||||
|
}
|
||||||
|
resultURI.hash = newURI.hash;
|
||||||
|
resultURI.XRF = newURI.XRF;
|
||||||
|
xrfragment_URI.computeVars(resultURI);
|
||||||
|
return resultURI;
|
||||||
|
};
|
||||||
|
xrfragment_URI.cloneURI = function(url) {
|
||||||
|
var clonedURI = new xrfragment_URI();
|
||||||
|
clonedURI.url = url.url;
|
||||||
|
clonedURI.source = url.source;
|
||||||
|
clonedURI.scheme = url.scheme;
|
||||||
|
clonedURI.authority = url.authority;
|
||||||
|
clonedURI.userInfo = url.userInfo;
|
||||||
|
clonedURI.password = url.password;
|
||||||
|
clonedURI.host = url.host;
|
||||||
|
clonedURI.port = url.port;
|
||||||
|
clonedURI.relative = url.relative;
|
||||||
|
clonedURI.path = url.path;
|
||||||
|
clonedURI.directory = url.directory;
|
||||||
|
clonedURI.file = url.file;
|
||||||
|
clonedURI.query = url.query;
|
||||||
|
clonedURI.fragment = url.fragment;
|
||||||
|
return clonedURI;
|
||||||
|
};
|
||||||
var xrfragment_XRF = $hx_exports["xrfragment"]["XRF"] = function(_fragment,_flags,_index) {
|
var xrfragment_XRF = $hx_exports["xrfragment"]["XRF"] = function(_fragment,_flags,_index) {
|
||||||
this.floats = [];
|
this.floats = [];
|
||||||
this.shift = [];
|
this.shift = [];
|
||||||
|
@ -1297,6 +1527,7 @@ haxe_Template.hxKeepArrayIterator = new haxe_iterators_ArrayIterator([]);
|
||||||
xrfragment_Parser.error = "";
|
xrfragment_Parser.error = "";
|
||||||
xrfragment_Parser.debug = false;
|
xrfragment_Parser.debug = false;
|
||||||
xrfragment_URI.__meta__ = { statics : { template : { keep : null}}};
|
xrfragment_URI.__meta__ = { statics : { template : { keep : null}}};
|
||||||
|
xrfragment_URI._parts = ["source","scheme","authority","userInfo","user","password","host","port","relative","path","directory","file","query","fragment"];
|
||||||
xrfragment_XRF.IMMUTABLE = 1;
|
xrfragment_XRF.IMMUTABLE = 1;
|
||||||
xrfragment_XRF.PROP_BIND = 2;
|
xrfragment_XRF.PROP_BIND = 2;
|
||||||
xrfragment_XRF.QUERY_OPERATOR = 4;
|
xrfragment_XRF.QUERY_OPERATOR = 4;
|
||||||
|
|
|
@ -2899,10 +2899,19 @@ __xrfragment_Parser.getMetaData = function()
|
||||||
do return meta end;
|
do return meta end;
|
||||||
end
|
end
|
||||||
|
|
||||||
__xrfragment_URI.new = {}
|
__xrfragment_URI.new = function()
|
||||||
|
local self = _hx_new(__xrfragment_URI.prototype)
|
||||||
|
__xrfragment_URI.super(self)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
__xrfragment_URI.super = function(self)
|
||||||
|
self.XRF = _hx_e();
|
||||||
|
self.hash = _hx_e();
|
||||||
|
self.fragment = "";
|
||||||
|
end
|
||||||
_hx_exports["xrfragment"]["URI"] = __xrfragment_URI
|
_hx_exports["xrfragment"]["URI"] = __xrfragment_URI
|
||||||
__xrfragment_URI.__name__ = true
|
__xrfragment_URI.__name__ = true
|
||||||
__xrfragment_URI.parse = function(url,filter)
|
__xrfragment_URI.parseFragment = function(url,filter)
|
||||||
local store = _hx_e();
|
local store = _hx_e();
|
||||||
local tmp;
|
local tmp;
|
||||||
if (url ~= nil) then
|
if (url ~= nil) then
|
||||||
|
@ -3063,6 +3072,374 @@ __xrfragment_URI.template = function(uri,vars)
|
||||||
parts[1] = frag;
|
parts[1] = frag;
|
||||||
do return parts:join("#") end;
|
do return parts:join("#") end;
|
||||||
end
|
end
|
||||||
|
__xrfragment_URI.parse = function(stringUrl,flags)
|
||||||
|
local r = EReg.new("^(?:(?![^:@]+:[^:@/]*@)([^:/?#.]+):)?(?://)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:/?#]*)(?::(\\d*))?)(((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[?#]|$)))*/?)?([^?#/]*))(?:\\?([^#]*))?(?:#(.*))?)", "");
|
||||||
|
local startIndex = nil;
|
||||||
|
if (startIndex == nil) then
|
||||||
|
startIndex = 1;
|
||||||
|
else
|
||||||
|
startIndex = startIndex + 1;
|
||||||
|
end;
|
||||||
|
local r1 = __lua_lib_luautf8_Utf8.find(stringUrl, "://", startIndex, true);
|
||||||
|
if (((function()
|
||||||
|
local _hx_1
|
||||||
|
if ((r1 ~= nil) and (r1 > 0)) then
|
||||||
|
_hx_1 = r1 - 1; else
|
||||||
|
_hx_1 = -1; end
|
||||||
|
return _hx_1
|
||||||
|
end )() == -1) and (__lua_lib_luautf8_Utf8.sub(stringUrl, 1, 1) ~= "/")) then
|
||||||
|
stringUrl = Std.string("/") .. Std.string(stringUrl);
|
||||||
|
end;
|
||||||
|
r:match(stringUrl);
|
||||||
|
local url = __xrfragment_URI.new();
|
||||||
|
local _g = 0;
|
||||||
|
local _g1 = __xrfragment_URI._parts.length;
|
||||||
|
while (_g < _g1) do
|
||||||
|
_g = _g + 1;
|
||||||
|
local i = _g - 1;
|
||||||
|
url[__xrfragment_URI._parts[i]] = r:matched(i);
|
||||||
|
end;
|
||||||
|
if (__xrfragment_URI.isRelative(url) == true) then
|
||||||
|
if ((url.directory == nil) and (url.host ~= nil)) then
|
||||||
|
url.file = url.host;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
url.hash = _hx_e();
|
||||||
|
if ((url.fragment ~= nil) and (__lua_lib_luautf8_Utf8.len(url.fragment) > 0)) then
|
||||||
|
url.XRF = __xrfragment_URI.parseFragment(Std.string("#") .. Std.string(url.fragment), flags);
|
||||||
|
local key;
|
||||||
|
local _g = 0;
|
||||||
|
local _g1 = Reflect.fields(url.XRF);
|
||||||
|
while (_g < _g1.length) do
|
||||||
|
local key = _g1[_g];
|
||||||
|
_g = _g + 1;
|
||||||
|
local v = Reflect.field(url.XRF, key);
|
||||||
|
local this1 = url.hash;
|
||||||
|
local value = Reflect.field(v, "string");
|
||||||
|
this1[key] = value;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
__xrfragment_URI.computeVars(url);
|
||||||
|
do return url end;
|
||||||
|
end
|
||||||
|
__xrfragment_URI.computeVars = function(url)
|
||||||
|
local r = EReg.new("//", "g");
|
||||||
|
local tmp;
|
||||||
|
if (url.directory ~= nil) then
|
||||||
|
local _this = url.directory;
|
||||||
|
local startIndex = nil;
|
||||||
|
if (startIndex == nil) then
|
||||||
|
startIndex = 1;
|
||||||
|
else
|
||||||
|
startIndex = startIndex + 1;
|
||||||
|
end;
|
||||||
|
local r = __lua_lib_luautf8_Utf8.find(_this, "//", startIndex, true);
|
||||||
|
tmp = (function()
|
||||||
|
local _hx_1
|
||||||
|
if ((r ~= nil) and (r > 0)) then
|
||||||
|
_hx_1 = r - 1; else
|
||||||
|
_hx_1 = -1; end
|
||||||
|
return _hx_1
|
||||||
|
end )() ~= -1;
|
||||||
|
else
|
||||||
|
tmp = false;
|
||||||
|
end;
|
||||||
|
if (tmp) then
|
||||||
|
url.directory = r:replace(url.directory, "/");
|
||||||
|
end;
|
||||||
|
local tmp;
|
||||||
|
if (url.path ~= nil) then
|
||||||
|
local _this = url.path;
|
||||||
|
local startIndex = nil;
|
||||||
|
if (startIndex == nil) then
|
||||||
|
startIndex = 1;
|
||||||
|
else
|
||||||
|
startIndex = startIndex + 1;
|
||||||
|
end;
|
||||||
|
local r = __lua_lib_luautf8_Utf8.find(_this, "//", startIndex, true);
|
||||||
|
tmp = (function()
|
||||||
|
local _hx_2
|
||||||
|
if ((r ~= nil) and (r > 0)) then
|
||||||
|
_hx_2 = r - 1; else
|
||||||
|
_hx_2 = -1; end
|
||||||
|
return _hx_2
|
||||||
|
end )() ~= -1;
|
||||||
|
else
|
||||||
|
tmp = false;
|
||||||
|
end;
|
||||||
|
if (tmp) then
|
||||||
|
url.path = r:replace(url.path, "/");
|
||||||
|
end;
|
||||||
|
local tmp;
|
||||||
|
if (url.file ~= nil) then
|
||||||
|
local _this = url.file;
|
||||||
|
local startIndex = nil;
|
||||||
|
if (startIndex == nil) then
|
||||||
|
startIndex = 1;
|
||||||
|
else
|
||||||
|
startIndex = startIndex + 1;
|
||||||
|
end;
|
||||||
|
local r = __lua_lib_luautf8_Utf8.find(_this, "//", startIndex, true);
|
||||||
|
tmp = (function()
|
||||||
|
local _hx_3
|
||||||
|
if ((r ~= nil) and (r > 0)) then
|
||||||
|
_hx_3 = r - 1; else
|
||||||
|
_hx_3 = -1; end
|
||||||
|
return _hx_3
|
||||||
|
end )() ~= -1;
|
||||||
|
else
|
||||||
|
tmp = false;
|
||||||
|
end;
|
||||||
|
if (tmp) then
|
||||||
|
url.file = r:replace(url.file, "/");
|
||||||
|
end;
|
||||||
|
url.URN = Std.string(Std.string(url.scheme) .. Std.string("://")) .. Std.string(url.host);
|
||||||
|
if (url.port ~= nil) then
|
||||||
|
local url1 = url;
|
||||||
|
url1.URN = Std.string(url1.URN) .. Std.string((Std.string(":") .. Std.string(url.port)));
|
||||||
|
end;
|
||||||
|
local url1 = url;
|
||||||
|
url1.URN = Std.string(url1.URN) .. Std.string(url.directory);
|
||||||
|
if (url.file ~= nil) then
|
||||||
|
local _this = url.file;
|
||||||
|
local idx = 1;
|
||||||
|
local ret = _hx_tab_array({}, 0);
|
||||||
|
while (idx ~= nil) do
|
||||||
|
local newidx = 0;
|
||||||
|
if (__lua_lib_luautf8_Utf8.len(".") > 0) then
|
||||||
|
newidx = __lua_lib_luautf8_Utf8.find(_this, ".", idx, true);
|
||||||
|
else
|
||||||
|
if (idx >= __lua_lib_luautf8_Utf8.len(_this)) then
|
||||||
|
newidx = nil;
|
||||||
|
else
|
||||||
|
newidx = idx + 1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if (newidx ~= nil) then
|
||||||
|
local match = __lua_lib_luautf8_Utf8.sub(_this, idx, newidx - 1);
|
||||||
|
ret:push(match);
|
||||||
|
idx = newidx + __lua_lib_luautf8_Utf8.len(".");
|
||||||
|
else
|
||||||
|
ret:push(__lua_lib_luautf8_Utf8.sub(_this, idx, __lua_lib_luautf8_Utf8.len(_this)));
|
||||||
|
idx = nil;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
local parts = ret;
|
||||||
|
if (parts.length > 1) then
|
||||||
|
url.fileExt = parts:pop();
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
__xrfragment_URI.toString = function(url)
|
||||||
|
local result = "";
|
||||||
|
if (url.scheme ~= nil) then
|
||||||
|
result = Std.string(result) .. Std.string((Std.string(url.scheme) .. Std.string("://")));
|
||||||
|
end;
|
||||||
|
if (url.user ~= nil) then
|
||||||
|
result = Std.string(result) .. Std.string((Std.string(url.user) .. Std.string(":")));
|
||||||
|
end;
|
||||||
|
if (url.password ~= nil) then
|
||||||
|
result = Std.string(result) .. Std.string((Std.string(url.password) .. Std.string("@")));
|
||||||
|
end;
|
||||||
|
if (url.host ~= nil) then
|
||||||
|
result = Std.string(result) .. Std.string(url.host);
|
||||||
|
end;
|
||||||
|
if (url.port ~= nil) then
|
||||||
|
result = Std.string(result) .. Std.string((Std.string(":") .. Std.string(url.port)));
|
||||||
|
end;
|
||||||
|
if (url.directory ~= nil) then
|
||||||
|
result = Std.string(result) .. Std.string(url.directory);
|
||||||
|
end;
|
||||||
|
if (url.file ~= nil) then
|
||||||
|
result = Std.string(result) .. Std.string(url.file);
|
||||||
|
end;
|
||||||
|
if (url.query ~= nil) then
|
||||||
|
result = Std.string(result) .. Std.string((Std.string("?") .. Std.string(url.query)));
|
||||||
|
end;
|
||||||
|
if (url.fragment ~= nil) then
|
||||||
|
result = Std.string(result) .. Std.string((Std.string("#") .. Std.string(url.fragment)));
|
||||||
|
end;
|
||||||
|
do return result end;
|
||||||
|
end
|
||||||
|
__xrfragment_URI.appendURI = function(url,appendedURI)
|
||||||
|
if (__xrfragment_URI.isRelative(url) == true) then
|
||||||
|
do return __xrfragment_URI.appendToRelativeURI(url, appendedURI) end;
|
||||||
|
else
|
||||||
|
do return __xrfragment_URI.appendToAbsoluteURI(url, appendedURI) end;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
__xrfragment_URI.isRelative = function(url)
|
||||||
|
do return url.scheme == nil end;
|
||||||
|
end
|
||||||
|
__xrfragment_URI.appendToRelativeURI = function(url,appendedURI)
|
||||||
|
if ((url.directory == nil) or (url.host == nil)) then
|
||||||
|
do return __xrfragment_URI.cloneURI(appendedURI) end;
|
||||||
|
end;
|
||||||
|
local resultURI = __xrfragment_URI.new();
|
||||||
|
resultURI.host = url.host;
|
||||||
|
resultURI.directory = url.directory;
|
||||||
|
if (appendedURI.host ~= nil) then
|
||||||
|
local resultURI = resultURI;
|
||||||
|
resultURI.directory = Std.string(resultURI.directory) .. Std.string(appendedURI.host);
|
||||||
|
end;
|
||||||
|
if (appendedURI.directory ~= nil) then
|
||||||
|
local directory = appendedURI.directory;
|
||||||
|
if (appendedURI.host == nil) then
|
||||||
|
local resultURI = resultURI;
|
||||||
|
local pos = 1;
|
||||||
|
local len = nil;
|
||||||
|
if ((len == nil) or (len > (pos + __lua_lib_luautf8_Utf8.len(directory)))) then
|
||||||
|
len = __lua_lib_luautf8_Utf8.len(directory);
|
||||||
|
else
|
||||||
|
if (len < 0) then
|
||||||
|
len = __lua_lib_luautf8_Utf8.len(directory) + len;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if (pos < 0) then
|
||||||
|
pos = __lua_lib_luautf8_Utf8.len(directory) + pos;
|
||||||
|
end;
|
||||||
|
if (pos < 0) then
|
||||||
|
pos = 0;
|
||||||
|
end;
|
||||||
|
resultURI.directory = Std.string(resultURI.directory) .. Std.string(__lua_lib_luautf8_Utf8.sub(directory, pos + 1, pos + len));
|
||||||
|
else
|
||||||
|
local resultURI = resultURI;
|
||||||
|
resultURI.directory = Std.string(resultURI.directory) .. Std.string(directory);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if (appendedURI.file ~= nil) then
|
||||||
|
resultURI.file = appendedURI.file;
|
||||||
|
end;
|
||||||
|
resultURI.path = Std.string(resultURI.directory) .. Std.string(resultURI.file);
|
||||||
|
if (appendedURI.query ~= nil) then
|
||||||
|
resultURI.query = appendedURI.query;
|
||||||
|
end;
|
||||||
|
if (appendedURI.fragment ~= nil) then
|
||||||
|
resultURI.fragment = appendedURI.fragment;
|
||||||
|
end;
|
||||||
|
do return resultURI end;
|
||||||
|
end
|
||||||
|
__xrfragment_URI.appendToAbsoluteURI = function(url,appendedURI)
|
||||||
|
local resultURI = __xrfragment_URI.new();
|
||||||
|
if (url.scheme ~= nil) then
|
||||||
|
resultURI.scheme = url.scheme;
|
||||||
|
end;
|
||||||
|
if (url.host ~= nil) then
|
||||||
|
resultURI.host = url.host;
|
||||||
|
end;
|
||||||
|
local directory = "";
|
||||||
|
if (url.directory ~= nil) then
|
||||||
|
directory = url.directory;
|
||||||
|
end;
|
||||||
|
if (appendedURI.host ~= nil) then
|
||||||
|
local appendedURI1 = appendedURI;
|
||||||
|
appendedURI1.directory = Std.string(appendedURI1.directory) .. Std.string(appendedURI.host);
|
||||||
|
end;
|
||||||
|
if (appendedURI.directory ~= nil) then
|
||||||
|
directory = Std.string(directory) .. Std.string(appendedURI.directory);
|
||||||
|
end;
|
||||||
|
resultURI.directory = directory;
|
||||||
|
if (appendedURI.file ~= nil) then
|
||||||
|
resultURI.file = appendedURI.file;
|
||||||
|
end;
|
||||||
|
resultURI.path = Std.string(resultURI.directory) .. Std.string(resultURI.file);
|
||||||
|
if (appendedURI.query ~= nil) then
|
||||||
|
resultURI.query = appendedURI.query;
|
||||||
|
end;
|
||||||
|
if (appendedURI.fragment ~= nil) then
|
||||||
|
resultURI.fragment = appendedURI.fragment;
|
||||||
|
end;
|
||||||
|
do return resultURI end;
|
||||||
|
end
|
||||||
|
__xrfragment_URI.toAbsolute = function(url,newUrl)
|
||||||
|
local newURI = __xrfragment_URI.parse(newUrl, 0);
|
||||||
|
local resultURI = __xrfragment_URI.new();
|
||||||
|
resultURI.port = url.port;
|
||||||
|
resultURI.source = newUrl;
|
||||||
|
if (newURI.scheme ~= nil) then
|
||||||
|
resultURI.scheme = newURI.scheme;
|
||||||
|
else
|
||||||
|
resultURI.scheme = url.scheme;
|
||||||
|
end;
|
||||||
|
if ((newURI.host ~= nil) and (__lua_lib_luautf8_Utf8.len(newURI.host) > 0)) then
|
||||||
|
resultURI.host = newURI.host;
|
||||||
|
resultURI.port = nil;
|
||||||
|
resultURI.fragment = nil;
|
||||||
|
resultURI.hash = _hx_e();
|
||||||
|
resultURI.XRF = _hx_e();
|
||||||
|
if (newURI.port ~= nil) then
|
||||||
|
resultURI.port = newURI.port;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
resultURI.host = url.host;
|
||||||
|
end;
|
||||||
|
local directory = "";
|
||||||
|
if (url.directory ~= nil) then
|
||||||
|
directory = url.directory;
|
||||||
|
end;
|
||||||
|
if (newURI.directory ~= nil) then
|
||||||
|
local tmp;
|
||||||
|
if (__lua_lib_luautf8_Utf8.sub(newUrl, 1, 1) ~= "/") then
|
||||||
|
local startIndex = nil;
|
||||||
|
if (startIndex == nil) then
|
||||||
|
startIndex = 1;
|
||||||
|
else
|
||||||
|
startIndex = startIndex + 1;
|
||||||
|
end;
|
||||||
|
local r = __lua_lib_luautf8_Utf8.find(newUrl, "://", startIndex, true);
|
||||||
|
tmp = (function()
|
||||||
|
local _hx_1
|
||||||
|
if ((r ~= nil) and (r > 0)) then
|
||||||
|
_hx_1 = r - 1; else
|
||||||
|
_hx_1 = -1; end
|
||||||
|
return _hx_1
|
||||||
|
end )() == -1;
|
||||||
|
else
|
||||||
|
tmp = false;
|
||||||
|
end;
|
||||||
|
if (tmp) then
|
||||||
|
directory = Std.string(directory) .. Std.string(newURI.directory);
|
||||||
|
else
|
||||||
|
directory = newURI.directory;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
resultURI.directory = directory;
|
||||||
|
if (newURI.file ~= nil) then
|
||||||
|
resultURI.file = newURI.file;
|
||||||
|
end;
|
||||||
|
resultURI.path = Std.string(resultURI.directory) .. Std.string(resultURI.file);
|
||||||
|
if (newURI.query ~= nil) then
|
||||||
|
resultURI.query = newURI.query;
|
||||||
|
end;
|
||||||
|
if (newURI.fragment ~= nil) then
|
||||||
|
resultURI.fragment = newURI.fragment;
|
||||||
|
end;
|
||||||
|
resultURI.hash = newURI.hash;
|
||||||
|
resultURI.XRF = newURI.XRF;
|
||||||
|
__xrfragment_URI.computeVars(resultURI);
|
||||||
|
do return resultURI end;
|
||||||
|
end
|
||||||
|
__xrfragment_URI.cloneURI = function(url)
|
||||||
|
local clonedURI = __xrfragment_URI.new();
|
||||||
|
clonedURI.url = url.url;
|
||||||
|
clonedURI.source = url.source;
|
||||||
|
clonedURI.scheme = url.scheme;
|
||||||
|
clonedURI.authority = url.authority;
|
||||||
|
clonedURI.userInfo = url.userInfo;
|
||||||
|
clonedURI.password = url.password;
|
||||||
|
clonedURI.host = url.host;
|
||||||
|
clonedURI.port = url.port;
|
||||||
|
clonedURI.relative = url.relative;
|
||||||
|
clonedURI.path = url.path;
|
||||||
|
clonedURI.directory = url.directory;
|
||||||
|
clonedURI.file = url.file;
|
||||||
|
clonedURI.query = url.query;
|
||||||
|
clonedURI.fragment = url.fragment;
|
||||||
|
do return clonedURI end;
|
||||||
|
end
|
||||||
|
__xrfragment_URI.prototype = _hx_e();
|
||||||
|
|
||||||
|
__xrfragment_URI.prototype.__class__ = __xrfragment_URI
|
||||||
|
|
||||||
__xrfragment_XRF.new = function(_fragment,_flags,_index)
|
__xrfragment_XRF.new = function(_fragment,_flags,_index)
|
||||||
local self = _hx_new(__xrfragment_XRF.prototype)
|
local self = _hx_new(__xrfragment_XRF.prototype)
|
||||||
|
@ -3281,6 +3658,8 @@ local _hx_static_init = function()
|
||||||
|
|
||||||
__xrfragment_URI.__meta__ = _hx_o({__fields__={statics=true},statics=_hx_o({__fields__={template=true},template=_hx_o({__fields__={keep=true},keep=nil})})});
|
__xrfragment_URI.__meta__ = _hx_o({__fields__={statics=true},statics=_hx_o({__fields__={template=true},template=_hx_o({__fields__={keep=true},keep=nil})})});
|
||||||
|
|
||||||
|
__xrfragment_URI._parts = _hx_tab_array({[0]="source", "scheme", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "fragment"}, 14);
|
||||||
|
|
||||||
__xrfragment_XRF.IMMUTABLE = 1;
|
__xrfragment_XRF.IMMUTABLE = 1;
|
||||||
|
|
||||||
__xrfragment_XRF.PROP_BIND = 2;
|
__xrfragment_XRF.PROP_BIND = 2;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -750,7 +750,7 @@ window.frontend = (opts) => new Proxy({
|
||||||
|
|
||||||
// load original scene and overwrite with updates
|
// load original scene and overwrite with updates
|
||||||
let url = document.location.search.replace(/\?/,'')
|
let url = document.location.search.replace(/\?/,'')
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.navigator.origin = xrf.parseUrl(url)
|
let {urlObj,dir,file,hash,ext} = xrf.navigator.origin = xrf.URI.parse(url)
|
||||||
const Loader = xrf.loaders[ext]
|
const Loader = xrf.loaders[ext]
|
||||||
loader = new Loader().setPath( dir )
|
loader = new Loader().setPath( dir )
|
||||||
notify('exporting scene<br><br>please wait..')
|
notify('exporting scene<br><br>please wait..')
|
||||||
|
@ -760,29 +760,8 @@ window.frontend = (opts) => new Proxy({
|
||||||
},
|
},
|
||||||
|
|
||||||
updateHashPosition(randomize){
|
updateHashPosition(randomize){
|
||||||
// *TODO* this should be part of the XRF Threejs framework
|
const pos = xrf.frag.pos.get()
|
||||||
if( typeof THREE == 'undefined' ) THREE = xrf.THREE
|
xrf.navigator.URI.hash.pos = `${pos.x},${pos.y},${pos.z}`
|
||||||
let radToDeg = THREE.MathUtils.radToDeg
|
|
||||||
let toDeg = (x) => x / (Math.PI / 180)
|
|
||||||
let camera = document.querySelector('[camera]').object3D.parent // *TODO* fix for threejs
|
|
||||||
camera.position.x += Math.random()/10
|
|
||||||
camera.position.z += Math.random()/10
|
|
||||||
|
|
||||||
// *TODO* add camera direction
|
|
||||||
let direction = new xrf.THREE.Vector3()
|
|
||||||
camera.getWorldDirection(direction)
|
|
||||||
const pitch = Math.asin(direction.y);
|
|
||||||
const yaw = Math.atan2(direction.x, direction.z);
|
|
||||||
const pitchInDegrees = pitch * 180 / Math.PI;
|
|
||||||
const yawInDegrees = yaw * 180 / Math.PI;
|
|
||||||
|
|
||||||
let lastPos = `pos=${camera.position.x.toFixed(2)},${camera.position.y.toFixed(2)},${camera.position.z.toFixed(2)}`
|
|
||||||
let newHash = document.location.hash.replace(/[&]?(pos|rot)=[0-9\.-]+,[0-9\.-]+,[0-9\.-]+/,'')
|
|
||||||
if( lastPos != "pos=" ){
|
|
||||||
newHash += `&${lastPos}`
|
|
||||||
document.location.hash = newHash.replace(/&&/,'&')
|
|
||||||
.replace(/#&/,'')
|
|
||||||
}
|
|
||||||
this.copyToClipboard( window.location.href );
|
this.copyToClipboard( window.location.href );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -802,8 +781,9 @@ window.frontend = (opts) => new Proxy({
|
||||||
document.location.hash += `&meet=${network.meetingLink}`
|
document.location.hash += `&meet=${network.meetingLink}`
|
||||||
}
|
}
|
||||||
if( !document.location.hash.match(/pos=/) && (network.posName || network.pos) ){
|
if( !document.location.hash.match(/pos=/) && (network.posName || network.pos) ){
|
||||||
document.location.hash += `&pos=${ network.posName || network.pos }`
|
xrf.navigator.URI.hash.pos = network.posName || network.pos
|
||||||
}
|
}else frontend.updateHashPosition()
|
||||||
|
|
||||||
let url = window.location.href
|
let url = window.location.href
|
||||||
if( opts.linkonly ) return url
|
if( opts.linkonly ) return url
|
||||||
this.copyToClipboard( url )
|
this.copyToClipboard( url )
|
||||||
|
|
|
@ -316,7 +316,7 @@
|
||||||
this.ydoc.scene.set('href',document.location.hash )
|
this.ydoc.scene.set('href',document.location.hash )
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
let hashvars = xrf.URI.parse( document.location.hash )
|
let hashvars = xrf.URI.parse( document.location.hash ).XRF
|
||||||
if( hashvars.meet ) this.parseLink(hashvars.meet.string)
|
if( hashvars.meet ) this.parseLink(hashvars.meet.string)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -489,7 +489,7 @@ chatComponent = {
|
||||||
div.classList.add.apply(div.classList, opts.class.concat(["envelope"]))
|
div.classList.add.apply(div.classList, opts.class.concat(["envelope"]))
|
||||||
}
|
}
|
||||||
if( !msg.className.match(/(info|guide|ui)/) ){
|
if( !msg.className.match(/(info|guide|ui)/) ){
|
||||||
let frag = xrf.URI.parse(document.location.hash)
|
let frag = xrf.URI.parse(document.location.hash).XRF
|
||||||
opts.from = 'you'
|
opts.from = 'you'
|
||||||
if( frag.pos ) opts.pos = frag.pos.string
|
if( frag.pos ) opts.pos = frag.pos.string
|
||||||
msg.classList.add('self')
|
msg.classList.add('self')
|
||||||
|
|
|
@ -260,7 +260,7 @@ window.trystero = (opts) => new Proxy({
|
||||||
let isTeleport = href.match(/(pos=|http:)/)
|
let isTeleport = href.match(/(pos=|http:)/)
|
||||||
if( isLocal && !isTeleport && this.href.send ) this.href.send({href})
|
if( isLocal && !isTeleport && this.href.send ) this.href.send({href})
|
||||||
})
|
})
|
||||||
let hashvars = xrf.URI.parse( document.location.hash )
|
let hashvars = xrf.URI.parse( document.location.hash ).XRF
|
||||||
if( hashvars.meet ) this.parseLink(hashvars.meet.string)
|
if( hashvars.meet ) this.parseLink(hashvars.meet.string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2303,11 +2303,33 @@ xrfragment_Parser._hx_class = xrfragment_Parser
|
||||||
|
|
||||||
class xrfragment_URI:
|
class xrfragment_URI:
|
||||||
_hx_class_name = "xrfragment.URI"
|
_hx_class_name = "xrfragment.URI"
|
||||||
__slots__ = ()
|
__slots__ = ("url", "source", "scheme", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "fileExt", "query", "fragment", "hash", "XRF", "URN")
|
||||||
_hx_statics = ["__meta__", "parse", "template"]
|
_hx_fields = ["url", "source", "scheme", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "fileExt", "query", "fragment", "hash", "XRF", "URN"]
|
||||||
|
_hx_statics = ["__meta__", "_parts", "parseFragment", "template", "parse", "computeVars", "toString", "appendURI", "isRelative", "appendToRelativeURI", "appendToAbsoluteURI", "toAbsolute", "cloneURI"]
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.URN = None
|
||||||
|
self.query = None
|
||||||
|
self.fileExt = None
|
||||||
|
self.file = None
|
||||||
|
self.directory = None
|
||||||
|
self.path = None
|
||||||
|
self.relative = None
|
||||||
|
self.port = None
|
||||||
|
self.host = None
|
||||||
|
self.password = None
|
||||||
|
self.user = None
|
||||||
|
self.userInfo = None
|
||||||
|
self.authority = None
|
||||||
|
self.scheme = None
|
||||||
|
self.source = None
|
||||||
|
self.url = None
|
||||||
|
self.XRF = _hx_AnonObject({})
|
||||||
|
self.hash = _hx_AnonObject({})
|
||||||
|
self.fragment = ""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def parse(url,_hx_filter):
|
def parseFragment(url,_hx_filter):
|
||||||
store = _hx_AnonObject({})
|
store = _hx_AnonObject({})
|
||||||
tmp = None
|
tmp = None
|
||||||
if (url is not None):
|
if (url is not None):
|
||||||
|
@ -2362,6 +2384,230 @@ class xrfragment_URI:
|
||||||
frag = StringTools.replace(frag,"null","")
|
frag = StringTools.replace(frag,"null","")
|
||||||
python_internal_ArrayImpl._set(parts, 1, frag)
|
python_internal_ArrayImpl._set(parts, 1, frag)
|
||||||
return "#".join([python_Boot.toString1(x1,'') for x1 in parts])
|
return "#".join([python_Boot.toString1(x1,'') for x1 in parts])
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse(stringUrl,flags):
|
||||||
|
r = EReg("^(?:(?![^:@]+:[^:@/]*@)([^:/?#.]+):)?(?://)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:/?#]*)(?::(\\d*))?)(((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[?#]|$)))*/?)?([^?#/]*))(?:\\?([^#]*))?(?:#(.*))?)","")
|
||||||
|
startIndex = None
|
||||||
|
if ((((stringUrl.find("://") if ((startIndex is None)) else HxString.indexOfImpl(stringUrl,"://",startIndex))) == -1) and (((("" if ((0 >= len(stringUrl))) else stringUrl[0])) != "/"))):
|
||||||
|
stringUrl = ("/" + ("null" if stringUrl is None else stringUrl))
|
||||||
|
r.matchObj = python_lib_Re.search(r.pattern,stringUrl)
|
||||||
|
url = xrfragment_URI()
|
||||||
|
_g = 0
|
||||||
|
_g1 = len(xrfragment_URI._parts)
|
||||||
|
while (_g < _g1):
|
||||||
|
i = _g
|
||||||
|
_g = (_g + 1)
|
||||||
|
field = python_internal_ArrayImpl._get(xrfragment_URI._parts, i)
|
||||||
|
value = r.matchObj.group(i)
|
||||||
|
setattr(url,(("_hx_" + field) if ((field in python_Boot.keywords)) else (("_hx_" + field) if (((((len(field) > 2) and ((ord(field[0]) == 95))) and ((ord(field[1]) == 95))) and ((ord(field[(len(field) - 1)]) != 95)))) else field)),value)
|
||||||
|
if (xrfragment_URI.isRelative(url) == True):
|
||||||
|
if ((url.directory is None) and ((url.host is not None))):
|
||||||
|
url.file = url.host
|
||||||
|
url.hash = _hx_AnonObject({})
|
||||||
|
if ((url.fragment is not None) and ((len(url.fragment) > 0))):
|
||||||
|
url.XRF = xrfragment_URI.parseFragment(("#" + HxOverrides.stringOrNull(url.fragment)),flags)
|
||||||
|
key = None
|
||||||
|
_g = 0
|
||||||
|
_g1 = python_Boot.fields(url.XRF)
|
||||||
|
while (_g < len(_g1)):
|
||||||
|
key = (_g1[_g] if _g >= 0 and _g < len(_g1) else None)
|
||||||
|
_g = (_g + 1)
|
||||||
|
v = Reflect.field(url.XRF,key)
|
||||||
|
this1 = url.hash
|
||||||
|
value = Reflect.field(v,"string")
|
||||||
|
setattr(this1,(("_hx_" + key) if ((key in python_Boot.keywords)) else (("_hx_" + key) if (((((len(key) > 2) and ((ord(key[0]) == 95))) and ((ord(key[1]) == 95))) and ((ord(key[(len(key) - 1)]) != 95)))) else key)),value)
|
||||||
|
xrfragment_URI.computeVars(url)
|
||||||
|
return url
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def computeVars(url):
|
||||||
|
r = EReg("//","g")
|
||||||
|
tmp = None
|
||||||
|
if (url.directory is not None):
|
||||||
|
_this = url.directory
|
||||||
|
startIndex = None
|
||||||
|
tmp = (((_this.find("//") if ((startIndex is None)) else HxString.indexOfImpl(_this,"//",startIndex))) != -1)
|
||||||
|
else:
|
||||||
|
tmp = False
|
||||||
|
if tmp:
|
||||||
|
url.directory = r.replace(url.directory,"/")
|
||||||
|
tmp = None
|
||||||
|
if (url.path is not None):
|
||||||
|
_this = url.path
|
||||||
|
startIndex = None
|
||||||
|
tmp = (((_this.find("//") if ((startIndex is None)) else HxString.indexOfImpl(_this,"//",startIndex))) != -1)
|
||||||
|
else:
|
||||||
|
tmp = False
|
||||||
|
if tmp:
|
||||||
|
url.path = r.replace(url.path,"/")
|
||||||
|
tmp = None
|
||||||
|
if (url.file is not None):
|
||||||
|
_this = url.file
|
||||||
|
startIndex = None
|
||||||
|
tmp = (((_this.find("//") if ((startIndex is None)) else HxString.indexOfImpl(_this,"//",startIndex))) != -1)
|
||||||
|
else:
|
||||||
|
tmp = False
|
||||||
|
if tmp:
|
||||||
|
url.file = r.replace(url.file,"/")
|
||||||
|
url.URN = ((HxOverrides.stringOrNull(url.scheme) + "://") + HxOverrides.stringOrNull(url.host))
|
||||||
|
if (url.port is not None):
|
||||||
|
url.URN = (HxOverrides.stringOrNull(url.URN) + HxOverrides.stringOrNull(((":" + HxOverrides.stringOrNull(url.port)))))
|
||||||
|
url.URN = (HxOverrides.stringOrNull(url.URN) + HxOverrides.stringOrNull(url.directory))
|
||||||
|
if (url.file is not None):
|
||||||
|
_this = url.file
|
||||||
|
parts = _this.split(".")
|
||||||
|
if (len(parts) > 1):
|
||||||
|
url.fileExt = (None if ((len(parts) == 0)) else parts.pop())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def toString(url):
|
||||||
|
result = ""
|
||||||
|
if (url.scheme is not None):
|
||||||
|
result = (("null" if result is None else result) + HxOverrides.stringOrNull(((HxOverrides.stringOrNull(url.scheme) + "://"))))
|
||||||
|
if (url.user is not None):
|
||||||
|
result = (("null" if result is None else result) + HxOverrides.stringOrNull(((HxOverrides.stringOrNull(url.user) + ":"))))
|
||||||
|
if (url.password is not None):
|
||||||
|
result = (("null" if result is None else result) + HxOverrides.stringOrNull(((HxOverrides.stringOrNull(url.password) + "@"))))
|
||||||
|
if (url.host is not None):
|
||||||
|
result = (("null" if result is None else result) + HxOverrides.stringOrNull(url.host))
|
||||||
|
if (url.port is not None):
|
||||||
|
result = (("null" if result is None else result) + HxOverrides.stringOrNull(((":" + HxOverrides.stringOrNull(url.port)))))
|
||||||
|
if (url.directory is not None):
|
||||||
|
result = (("null" if result is None else result) + HxOverrides.stringOrNull(url.directory))
|
||||||
|
if (url.file is not None):
|
||||||
|
result = (("null" if result is None else result) + HxOverrides.stringOrNull(url.file))
|
||||||
|
if (url.query is not None):
|
||||||
|
result = (("null" if result is None else result) + HxOverrides.stringOrNull((("?" + HxOverrides.stringOrNull(url.query)))))
|
||||||
|
if (url.fragment is not None):
|
||||||
|
result = (("null" if result is None else result) + HxOverrides.stringOrNull((("#" + HxOverrides.stringOrNull(url.fragment)))))
|
||||||
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def appendURI(url,appendedURI):
|
||||||
|
if (xrfragment_URI.isRelative(url) == True):
|
||||||
|
return xrfragment_URI.appendToRelativeURI(url,appendedURI)
|
||||||
|
else:
|
||||||
|
return xrfragment_URI.appendToAbsoluteURI(url,appendedURI)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def isRelative(url):
|
||||||
|
return (url.scheme is None)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def appendToRelativeURI(url,appendedURI):
|
||||||
|
if ((url.directory is None) or ((url.host is None))):
|
||||||
|
return xrfragment_URI.cloneURI(appendedURI)
|
||||||
|
resultURI = xrfragment_URI()
|
||||||
|
resultURI.host = url.host
|
||||||
|
resultURI.directory = url.directory
|
||||||
|
if (appendedURI.host is not None):
|
||||||
|
resultURI.directory = (HxOverrides.stringOrNull(resultURI.directory) + HxOverrides.stringOrNull(appendedURI.host))
|
||||||
|
if (appendedURI.directory is not None):
|
||||||
|
directory = appendedURI.directory
|
||||||
|
if (appendedURI.host is None):
|
||||||
|
resultURI.directory = (HxOverrides.stringOrNull(resultURI.directory) + HxOverrides.stringOrNull(HxString.substr(directory,1,None)))
|
||||||
|
else:
|
||||||
|
resultURI.directory = (HxOverrides.stringOrNull(resultURI.directory) + ("null" if directory is None else directory))
|
||||||
|
if (appendedURI.file is not None):
|
||||||
|
resultURI.file = appendedURI.file
|
||||||
|
resultURI.path = (HxOverrides.stringOrNull(resultURI.directory) + HxOverrides.stringOrNull(resultURI.file))
|
||||||
|
if (appendedURI.query is not None):
|
||||||
|
resultURI.query = appendedURI.query
|
||||||
|
if (appendedURI.fragment is not None):
|
||||||
|
resultURI.fragment = appendedURI.fragment
|
||||||
|
return resultURI
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def appendToAbsoluteURI(url,appendedURI):
|
||||||
|
resultURI = xrfragment_URI()
|
||||||
|
if (url.scheme is not None):
|
||||||
|
resultURI.scheme = url.scheme
|
||||||
|
if (url.host is not None):
|
||||||
|
resultURI.host = url.host
|
||||||
|
directory = ""
|
||||||
|
if (url.directory is not None):
|
||||||
|
directory = url.directory
|
||||||
|
if (appendedURI.host is not None):
|
||||||
|
appendedURI.directory = (HxOverrides.stringOrNull(appendedURI.directory) + HxOverrides.stringOrNull(appendedURI.host))
|
||||||
|
if (appendedURI.directory is not None):
|
||||||
|
directory = (("null" if directory is None else directory) + HxOverrides.stringOrNull(appendedURI.directory))
|
||||||
|
resultURI.directory = directory
|
||||||
|
if (appendedURI.file is not None):
|
||||||
|
resultURI.file = appendedURI.file
|
||||||
|
resultURI.path = (HxOverrides.stringOrNull(resultURI.directory) + HxOverrides.stringOrNull(resultURI.file))
|
||||||
|
if (appendedURI.query is not None):
|
||||||
|
resultURI.query = appendedURI.query
|
||||||
|
if (appendedURI.fragment is not None):
|
||||||
|
resultURI.fragment = appendedURI.fragment
|
||||||
|
return resultURI
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def toAbsolute(url,newUrl):
|
||||||
|
newURI = xrfragment_URI.parse(newUrl,0)
|
||||||
|
resultURI = xrfragment_URI()
|
||||||
|
resultURI.port = url.port
|
||||||
|
resultURI.source = newUrl
|
||||||
|
if (newURI.scheme is not None):
|
||||||
|
resultURI.scheme = newURI.scheme
|
||||||
|
else:
|
||||||
|
resultURI.scheme = url.scheme
|
||||||
|
if ((newURI.host is not None) and ((len(newURI.host) > 0))):
|
||||||
|
resultURI.host = newURI.host
|
||||||
|
resultURI.port = None
|
||||||
|
resultURI.fragment = None
|
||||||
|
resultURI.hash = _hx_AnonObject({})
|
||||||
|
resultURI.XRF = _hx_AnonObject({})
|
||||||
|
if (newURI.port is not None):
|
||||||
|
resultURI.port = newURI.port
|
||||||
|
else:
|
||||||
|
resultURI.host = url.host
|
||||||
|
directory = ""
|
||||||
|
if (url.directory is not None):
|
||||||
|
directory = url.directory
|
||||||
|
if (newURI.directory is not None):
|
||||||
|
tmp = None
|
||||||
|
if ((("" if ((0 >= len(newUrl))) else newUrl[0])) != "/"):
|
||||||
|
startIndex = None
|
||||||
|
tmp = (((newUrl.find("://") if ((startIndex is None)) else HxString.indexOfImpl(newUrl,"://",startIndex))) == -1)
|
||||||
|
else:
|
||||||
|
tmp = False
|
||||||
|
if tmp:
|
||||||
|
directory = (("null" if directory is None else directory) + HxOverrides.stringOrNull(newURI.directory))
|
||||||
|
else:
|
||||||
|
directory = newURI.directory
|
||||||
|
resultURI.directory = directory
|
||||||
|
if (newURI.file is not None):
|
||||||
|
resultURI.file = newURI.file
|
||||||
|
resultURI.path = (HxOverrides.stringOrNull(resultURI.directory) + HxOverrides.stringOrNull(resultURI.file))
|
||||||
|
if (newURI.query is not None):
|
||||||
|
resultURI.query = newURI.query
|
||||||
|
if (newURI.fragment is not None):
|
||||||
|
resultURI.fragment = newURI.fragment
|
||||||
|
resultURI.hash = newURI.hash
|
||||||
|
resultURI.XRF = newURI.XRF
|
||||||
|
xrfragment_URI.computeVars(resultURI)
|
||||||
|
return resultURI
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def cloneURI(url):
|
||||||
|
clonedURI = xrfragment_URI()
|
||||||
|
clonedURI.url = url.url
|
||||||
|
clonedURI.source = url.source
|
||||||
|
clonedURI.scheme = url.scheme
|
||||||
|
clonedURI.authority = url.authority
|
||||||
|
clonedURI.userInfo = url.userInfo
|
||||||
|
clonedURI.password = url.password
|
||||||
|
clonedURI.host = url.host
|
||||||
|
clonedURI.port = url.port
|
||||||
|
clonedURI.relative = url.relative
|
||||||
|
clonedURI.path = url.path
|
||||||
|
clonedURI.directory = url.directory
|
||||||
|
clonedURI.file = url.file
|
||||||
|
clonedURI.query = url.query
|
||||||
|
clonedURI.fragment = url.fragment
|
||||||
|
return clonedURI
|
||||||
|
|
||||||
xrfragment_URI._hx_class = xrfragment_URI
|
xrfragment_URI._hx_class = xrfragment_URI
|
||||||
|
|
||||||
|
|
||||||
|
@ -2496,6 +2742,7 @@ python_Boot.prefixLength = len("_hx_")
|
||||||
xrfragment_Parser.error = ""
|
xrfragment_Parser.error = ""
|
||||||
xrfragment_Parser.debug = False
|
xrfragment_Parser.debug = False
|
||||||
xrfragment_URI.__meta__ = _hx_AnonObject({'statics': _hx_AnonObject({'template': _hx_AnonObject({'keep': None})})})
|
xrfragment_URI.__meta__ = _hx_AnonObject({'statics': _hx_AnonObject({'template': _hx_AnonObject({'keep': None})})})
|
||||||
|
xrfragment_URI._parts = ["source", "scheme", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "fragment"]
|
||||||
xrfragment_XRF.__meta__ = _hx_AnonObject({'statics': _hx_AnonObject({'toDict': _hx_AnonObject({'keep': None})})})
|
xrfragment_XRF.__meta__ = _hx_AnonObject({'statics': _hx_AnonObject({'toDict': _hx_AnonObject({'keep': None})})})
|
||||||
xrfragment_XRF.IMMUTABLE = 1
|
xrfragment_XRF.IMMUTABLE = 1
|
||||||
xrfragment_XRF.PROP_BIND = 2
|
xrfragment_XRF.PROP_BIND = 2
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* v0.5.1 generated at Tue Mar 19 10:04:25 AM UTC 2024
|
* v0.5.1 generated at Tue Apr 16 12:47:01 PM UTC 2024
|
||||||
* https://xrfragment.org
|
* https://xrfragment.org
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -1138,9 +1138,13 @@ xrfragment_Parser.getMetaData = function() {
|
||||||
var meta = { title : ["title","og:title","dc.title"], description : ["aria-description","og:description","dc.description"], author : ["author","dc.creator"], publisher : ["publisher","dc.publisher"], website : ["og:site_name","og:url","dc.publisher"], license : ["SPDX","dc.rights"]};
|
var meta = { title : ["title","og:title","dc.title"], description : ["aria-description","og:description","dc.description"], author : ["author","dc.creator"], publisher : ["publisher","dc.publisher"], website : ["og:site_name","og:url","dc.publisher"], license : ["SPDX","dc.rights"]};
|
||||||
return meta;
|
return meta;
|
||||||
};
|
};
|
||||||
var xrfragment_URI = $hx_exports["xrfragment"]["URI"] = function() { };
|
var xrfragment_URI = $hx_exports["xrfragment"]["URI"] = function() {
|
||||||
|
this.XRF = { };
|
||||||
|
this.hash = { };
|
||||||
|
this.fragment = "";
|
||||||
|
};
|
||||||
xrfragment_URI.__name__ = true;
|
xrfragment_URI.__name__ = true;
|
||||||
xrfragment_URI.parse = function(url,filter) {
|
xrfragment_URI.parseFragment = function(url,filter) {
|
||||||
var store = { };
|
var store = { };
|
||||||
if(url == null || url.indexOf("#") == -1) {
|
if(url == null || url.indexOf("#") == -1) {
|
||||||
return store;
|
return store;
|
||||||
|
@ -1192,6 +1196,232 @@ xrfragment_URI.template = function(uri,vars) {
|
||||||
parts[1] = frag;
|
parts[1] = frag;
|
||||||
return parts.join("#");
|
return parts.join("#");
|
||||||
};
|
};
|
||||||
|
xrfragment_URI.parse = function(stringUrl,flags) {
|
||||||
|
var r = new EReg("^(?:(?![^:@]+:[^:@/]*@)([^:/?#.]+):)?(?://)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:/?#]*)(?::(\\d*))?)(((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[?#]|$)))*/?)?([^?#/]*))(?:\\?([^#]*))?(?:#(.*))?)","");
|
||||||
|
if(stringUrl.indexOf("://") == -1 && stringUrl.charAt(0) != "/") {
|
||||||
|
stringUrl = "/" + stringUrl;
|
||||||
|
}
|
||||||
|
r.match(stringUrl);
|
||||||
|
var url = new xrfragment_URI();
|
||||||
|
var _g = 0;
|
||||||
|
var _g1 = xrfragment_URI._parts.length;
|
||||||
|
while(_g < _g1) {
|
||||||
|
var i = _g++;
|
||||||
|
url[xrfragment_URI._parts[i]] = r.matched(i);
|
||||||
|
}
|
||||||
|
if(xrfragment_URI.isRelative(url) == true) {
|
||||||
|
if(url.directory == null && url.host != null) {
|
||||||
|
url.file = url.host;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url.hash = { };
|
||||||
|
if(url.fragment != null && url.fragment.length > 0) {
|
||||||
|
url.XRF = xrfragment_URI.parseFragment("#" + url.fragment,flags);
|
||||||
|
var key;
|
||||||
|
var _g = 0;
|
||||||
|
var _g1 = Reflect.fields(url.XRF);
|
||||||
|
while(_g < _g1.length) {
|
||||||
|
var key = _g1[_g];
|
||||||
|
++_g;
|
||||||
|
var v = url.XRF[key];
|
||||||
|
url.hash[key] = v["string"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xrfragment_URI.computeVars(url);
|
||||||
|
return url;
|
||||||
|
};
|
||||||
|
xrfragment_URI.computeVars = function(url) {
|
||||||
|
var r_r = new RegExp("//","g".split("u").join(""));
|
||||||
|
if(url.directory != null && url.directory.indexOf("//") != -1) {
|
||||||
|
url.directory = url.directory.replace(r_r,"/");
|
||||||
|
}
|
||||||
|
if(url.path != null && url.path.indexOf("//") != -1) {
|
||||||
|
url.path = url.path.replace(r_r,"/");
|
||||||
|
}
|
||||||
|
if(url.file != null && url.file.indexOf("//") != -1) {
|
||||||
|
url.file = url.file.replace(r_r,"/");
|
||||||
|
}
|
||||||
|
url.URN = url.scheme + "://" + url.host;
|
||||||
|
if(url.port != null) {
|
||||||
|
url.URN += ":" + url.port;
|
||||||
|
}
|
||||||
|
url.URN += url.directory;
|
||||||
|
if(url.file != null) {
|
||||||
|
var parts = url.file.split(".");
|
||||||
|
if(parts.length > 1) {
|
||||||
|
url.fileExt = parts.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xrfragment_URI.toString = function(url) {
|
||||||
|
var result = "";
|
||||||
|
if(url.scheme != null) {
|
||||||
|
result += url.scheme + "://";
|
||||||
|
}
|
||||||
|
if(url.user != null) {
|
||||||
|
result += url.user + ":";
|
||||||
|
}
|
||||||
|
if(url.password != null) {
|
||||||
|
result += url.password + "@";
|
||||||
|
}
|
||||||
|
if(url.host != null) {
|
||||||
|
result += url.host;
|
||||||
|
}
|
||||||
|
if(url.port != null) {
|
||||||
|
result += ":" + url.port;
|
||||||
|
}
|
||||||
|
if(url.directory != null) {
|
||||||
|
result += url.directory;
|
||||||
|
}
|
||||||
|
if(url.file != null) {
|
||||||
|
result += url.file;
|
||||||
|
}
|
||||||
|
if(url.query != null) {
|
||||||
|
result += "?" + url.query;
|
||||||
|
}
|
||||||
|
if(url.fragment != null) {
|
||||||
|
result += "#" + url.fragment;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
xrfragment_URI.appendURI = function(url,appendedURI) {
|
||||||
|
if(xrfragment_URI.isRelative(url) == true) {
|
||||||
|
return xrfragment_URI.appendToRelativeURI(url,appendedURI);
|
||||||
|
} else {
|
||||||
|
return xrfragment_URI.appendToAbsoluteURI(url,appendedURI);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xrfragment_URI.isRelative = function(url) {
|
||||||
|
return url.scheme == null;
|
||||||
|
};
|
||||||
|
xrfragment_URI.appendToRelativeURI = function(url,appendedURI) {
|
||||||
|
if(url.directory == null || url.host == null) {
|
||||||
|
return xrfragment_URI.cloneURI(appendedURI);
|
||||||
|
}
|
||||||
|
var resultURI = new xrfragment_URI();
|
||||||
|
resultURI.host = url.host;
|
||||||
|
resultURI.directory = url.directory;
|
||||||
|
if(appendedURI.host != null) {
|
||||||
|
resultURI.directory += appendedURI.host;
|
||||||
|
}
|
||||||
|
if(appendedURI.directory != null) {
|
||||||
|
var directory = appendedURI.directory;
|
||||||
|
if(appendedURI.host == null) {
|
||||||
|
resultURI.directory += HxOverrides.substr(directory,1,null);
|
||||||
|
} else {
|
||||||
|
resultURI.directory += directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(appendedURI.file != null) {
|
||||||
|
resultURI.file = appendedURI.file;
|
||||||
|
}
|
||||||
|
resultURI.path = resultURI.directory + resultURI.file;
|
||||||
|
if(appendedURI.query != null) {
|
||||||
|
resultURI.query = appendedURI.query;
|
||||||
|
}
|
||||||
|
if(appendedURI.fragment != null) {
|
||||||
|
resultURI.fragment = appendedURI.fragment;
|
||||||
|
}
|
||||||
|
return resultURI;
|
||||||
|
};
|
||||||
|
xrfragment_URI.appendToAbsoluteURI = function(url,appendedURI) {
|
||||||
|
var resultURI = new xrfragment_URI();
|
||||||
|
if(url.scheme != null) {
|
||||||
|
resultURI.scheme = url.scheme;
|
||||||
|
}
|
||||||
|
if(url.host != null) {
|
||||||
|
resultURI.host = url.host;
|
||||||
|
}
|
||||||
|
var directory = "";
|
||||||
|
if(url.directory != null) {
|
||||||
|
directory = url.directory;
|
||||||
|
}
|
||||||
|
if(appendedURI.host != null) {
|
||||||
|
appendedURI.directory += appendedURI.host;
|
||||||
|
}
|
||||||
|
if(appendedURI.directory != null) {
|
||||||
|
directory += appendedURI.directory;
|
||||||
|
}
|
||||||
|
resultURI.directory = directory;
|
||||||
|
if(appendedURI.file != null) {
|
||||||
|
resultURI.file = appendedURI.file;
|
||||||
|
}
|
||||||
|
resultURI.path = resultURI.directory + resultURI.file;
|
||||||
|
if(appendedURI.query != null) {
|
||||||
|
resultURI.query = appendedURI.query;
|
||||||
|
}
|
||||||
|
if(appendedURI.fragment != null) {
|
||||||
|
resultURI.fragment = appendedURI.fragment;
|
||||||
|
}
|
||||||
|
return resultURI;
|
||||||
|
};
|
||||||
|
xrfragment_URI.toAbsolute = function(url,newUrl) {
|
||||||
|
var newURI = xrfragment_URI.parse(newUrl,0);
|
||||||
|
var resultURI = new xrfragment_URI();
|
||||||
|
resultURI.port = url.port;
|
||||||
|
resultURI.source = newUrl;
|
||||||
|
if(newURI.scheme != null) {
|
||||||
|
resultURI.scheme = newURI.scheme;
|
||||||
|
} else {
|
||||||
|
resultURI.scheme = url.scheme;
|
||||||
|
}
|
||||||
|
if(newURI.host != null && newURI.host.length > 0) {
|
||||||
|
resultURI.host = newURI.host;
|
||||||
|
resultURI.port = null;
|
||||||
|
resultURI.fragment = null;
|
||||||
|
resultURI.hash = { };
|
||||||
|
resultURI.XRF = { };
|
||||||
|
if(newURI.port != null) {
|
||||||
|
resultURI.port = newURI.port;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resultURI.host = url.host;
|
||||||
|
}
|
||||||
|
var directory = "";
|
||||||
|
if(url.directory != null) {
|
||||||
|
directory = url.directory;
|
||||||
|
}
|
||||||
|
if(newURI.directory != null) {
|
||||||
|
if(newUrl.charAt(0) != "/" && newUrl.indexOf("://") == -1) {
|
||||||
|
directory += newURI.directory;
|
||||||
|
} else {
|
||||||
|
directory = newURI.directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultURI.directory = directory;
|
||||||
|
if(newURI.file != null) {
|
||||||
|
resultURI.file = newURI.file;
|
||||||
|
}
|
||||||
|
resultURI.path = resultURI.directory + resultURI.file;
|
||||||
|
if(newURI.query != null) {
|
||||||
|
resultURI.query = newURI.query;
|
||||||
|
}
|
||||||
|
if(newURI.fragment != null) {
|
||||||
|
resultURI.fragment = newURI.fragment;
|
||||||
|
}
|
||||||
|
resultURI.hash = newURI.hash;
|
||||||
|
resultURI.XRF = newURI.XRF;
|
||||||
|
xrfragment_URI.computeVars(resultURI);
|
||||||
|
return resultURI;
|
||||||
|
};
|
||||||
|
xrfragment_URI.cloneURI = function(url) {
|
||||||
|
var clonedURI = new xrfragment_URI();
|
||||||
|
clonedURI.url = url.url;
|
||||||
|
clonedURI.source = url.source;
|
||||||
|
clonedURI.scheme = url.scheme;
|
||||||
|
clonedURI.authority = url.authority;
|
||||||
|
clonedURI.userInfo = url.userInfo;
|
||||||
|
clonedURI.password = url.password;
|
||||||
|
clonedURI.host = url.host;
|
||||||
|
clonedURI.port = url.port;
|
||||||
|
clonedURI.relative = url.relative;
|
||||||
|
clonedURI.path = url.path;
|
||||||
|
clonedURI.directory = url.directory;
|
||||||
|
clonedURI.file = url.file;
|
||||||
|
clonedURI.query = url.query;
|
||||||
|
clonedURI.fragment = url.fragment;
|
||||||
|
return clonedURI;
|
||||||
|
};
|
||||||
var xrfragment_XRF = $hx_exports["xrfragment"]["XRF"] = function(_fragment,_flags,_index) {
|
var xrfragment_XRF = $hx_exports["xrfragment"]["XRF"] = function(_fragment,_flags,_index) {
|
||||||
this.floats = [];
|
this.floats = [];
|
||||||
this.shift = [];
|
this.shift = [];
|
||||||
|
@ -1302,6 +1532,7 @@ haxe_Template.hxKeepArrayIterator = new haxe_iterators_ArrayIterator([]);
|
||||||
xrfragment_Parser.error = "";
|
xrfragment_Parser.error = "";
|
||||||
xrfragment_Parser.debug = false;
|
xrfragment_Parser.debug = false;
|
||||||
xrfragment_URI.__meta__ = { statics : { template : { keep : null}}};
|
xrfragment_URI.__meta__ = { statics : { template : { keep : null}}};
|
||||||
|
xrfragment_URI._parts = ["source","scheme","authority","userInfo","user","password","host","port","relative","path","directory","file","query","fragment"];
|
||||||
xrfragment_XRF.IMMUTABLE = 1;
|
xrfragment_XRF.IMMUTABLE = 1;
|
||||||
xrfragment_XRF.PROP_BIND = 2;
|
xrfragment_XRF.PROP_BIND = 2;
|
||||||
xrfragment_XRF.QUERY_OPERATOR = 4;
|
xrfragment_XRF.QUERY_OPERATOR = 4;
|
||||||
|
@ -1589,7 +1820,7 @@ let pub = function( url, node_or_model, flags ){ // evaluate fragments in url
|
||||||
if( !url ) return
|
if( !url ) return
|
||||||
if( !url.match(/#/) ) url = `#${url}`
|
if( !url.match(/#/) ) url = `#${url}`
|
||||||
let { THREE, camera } = xrf
|
let { THREE, camera } = xrf
|
||||||
let frag = xrf.URI.parse( url, flags )
|
let frag = xrf.URI.parse( url, flags ).XRF
|
||||||
let fromNode = node_or_model != xrf.model
|
let fromNode = node_or_model != xrf.model
|
||||||
let isNode = node_or_model && node_or_model.children
|
let isNode = node_or_model && node_or_model.children
|
||||||
|
|
||||||
|
@ -1756,24 +1987,6 @@ xrf.reset = () => {
|
||||||
xrf.layers = 0
|
xrf.layers = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
xrf.parseUrl = (url) => {
|
|
||||||
let urlExHash = url.replace(/#.*/,'')
|
|
||||||
let urlObj,file
|
|
||||||
let store = {}
|
|
||||||
try{
|
|
||||||
urlObj = new URL( urlExHash.match(/:\/\//) ? urlExHash : String(`https://fake.com/${url}`).replace(/\/\//,'/') )
|
|
||||||
file = urlObj.pathname.substring(urlObj.pathname.lastIndexOf('/') + 1);
|
|
||||||
let search = urlObj.search.substr(1).split("&")
|
|
||||||
for( let i in search ) store[ (search[i].split("=")[0]) ] = search[i].split("=")[1] || ''
|
|
||||||
}catch(e){ }
|
|
||||||
let hashmap = url.match("#") ? url.replace(/.*#/,'').split("&") : []
|
|
||||||
for( let i in hashmap ) store[ (hashmap[i].split("=")[0]) ] = hashmap[i].split("=")[1] || ''
|
|
||||||
let dir = url.substring(0, url.lastIndexOf('/') + 1)
|
|
||||||
const hash = url.match(/#/) ? url.replace(/.*#/,'') : ''
|
|
||||||
const ext = file.split('.').pop()
|
|
||||||
return {urlObj,dir,file,hash,ext,store}
|
|
||||||
}
|
|
||||||
|
|
||||||
xrf.add = (object) => {
|
xrf.add = (object) => {
|
||||||
object.isXRF = true // mark for easy deletion when replacing scene
|
object.isXRF = true // mark for easy deletion when replacing scene
|
||||||
xrf.scene.add(object)
|
xrf.scene.add(object)
|
||||||
|
@ -1784,42 +1997,52 @@ xrf.hasNoMaterial = (mesh) => {
|
||||||
const hasMaterialName = mesh.material && mesh.material.name.length > 0
|
const hasMaterialName = mesh.material && mesh.material.name.length > 0
|
||||||
return mesh.geometry && !hasMaterialName && !hasTexture
|
return mesh.geometry && !hasMaterialName && !hasTexture
|
||||||
}
|
}
|
||||||
xrf.navigator = {}
|
xrf.navigator = {URI:{}}
|
||||||
|
|
||||||
xrf.navigator.to = (url,flags,loader,data) => {
|
xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
if( !url ) throw 'xrf.navigator.to(..) no url given'
|
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 URI = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
URI.hash = xrf.navigator.reactifyHash(URI.hash)
|
||||||
|
let fileChange = URI.URN + URI.file != xrf.navigator.URI.URN + xrf.navigator.URI.file
|
||||||
|
let external = URI.URN != document.location.origin + document.location.pathname
|
||||||
|
let hasPos = URI.hash.pos
|
||||||
|
let hashChange = String(xrf.navigator.URI.fragment||"") != String(URI.fragment||"")
|
||||||
|
let hashbus = xrf.hashbus
|
||||||
|
xrf.navigator.URI = URI
|
||||||
|
let {directory,file,fragment,fileExt} = URI;
|
||||||
|
|
||||||
let hashbus = xrf.hashbus
|
const evalFragment = () => {
|
||||||
|
if( URI.fragment ){
|
||||||
|
hashbus.pub( URI.fragment, xrf.model, flags ) // eval local URI XR fragments
|
||||||
|
xrf.navigator.updateHash(fragment) // which don't require
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise( (resolve,reject) => {
|
return new Promise( (resolve,reject) => {
|
||||||
xrf
|
xrf
|
||||||
.emit('navigate', {url,loader,data})
|
.emit('navigate', {url,loader,data})
|
||||||
.then( () => {
|
.then( () => {
|
||||||
|
|
||||||
if( ext && !loader ){
|
const Loader = xrf.loaders[fileExt]
|
||||||
const Loader = xrf.loaders[ext]
|
|
||||||
|
if( fileExt && !loader ){
|
||||||
if( !Loader ) return resolve()
|
if( !Loader ) return resolve()
|
||||||
loader = loader || new Loader().setPath( dir )
|
loader = loader || new Loader().setPath( URI.URN )
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !hash && !file && !ext ) return resolve(xrf.model) // nothing we can do here
|
if( !URI.fragment && !URI.file && !URI.fileExt ) return resolve(xrf.model) // nothing we can do here
|
||||||
|
|
||||||
if( hashChange && !hasPos ){
|
if( xrf.model && !fileChange && hashChange && !hasPos ){
|
||||||
hashbus.pub( url, xrf.model, flags ) // eval local URI XR fragments
|
evalFragment()
|
||||||
xrf.navigator.updateHash(hash) // which don't require
|
return resolve(xrf.model) // positional navigation
|
||||||
return resolve(xrf.model) // positional navigation
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xrf
|
xrf
|
||||||
.emit('navigateLoading', {url,loader,data})
|
.emit('navigateLoading', {url,loader,data})
|
||||||
.then( () => {
|
.then( () => {
|
||||||
if( hashChange && hasPos ){ // we're already loaded
|
if( (!fileChange || !file) && hashChange && hasPos ){ // we're already loaded
|
||||||
hashbus.pub( url, xrf.model, flags ) // and eval local URI XR fragments
|
evalFragment()
|
||||||
xrf.navigator.updateHash(hash)
|
|
||||||
xrf.emit('navigateLoaded',{url})
|
xrf.emit('navigateLoaded',{url})
|
||||||
return resolve(xrf.model)
|
return resolve(xrf.model)
|
||||||
}
|
}
|
||||||
|
@ -1829,17 +2052,20 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
xrf.reset()
|
xrf.reset()
|
||||||
|
|
||||||
// force relative path for files which dont include protocol or relative path
|
// force relative path for files which dont include protocol or relative path
|
||||||
if( dir ) dir = dir[0] == '.' || dir.match("://") ? dir : `.${dir}`
|
if( directory ) directory = directory[0] == '.' || directory.match("://") ? directory : `.${directory}`
|
||||||
url = url.replace(dir,"")
|
|
||||||
loader = loader || new Loader().setPath( dir )
|
loader = loader || new Loader().setPath( URI.URN )
|
||||||
const onLoad = (model) => {
|
const onLoad = (model) => {
|
||||||
|
|
||||||
model.file = file
|
model.file = URI.file
|
||||||
// only change url when loading *another* file
|
// only change url when loading *another* file
|
||||||
if( xrf.model ) xrf.navigator.pushState( `${dir}${file}`, hash )
|
if( xrf.model ){
|
||||||
|
xrf.navigator.pushState( external ? URI.URN + URI.file : URI.file, fragment )
|
||||||
|
}
|
||||||
|
//if( xrf.model ) xrf.navigator.pushState( `${ document.location.pathname != URI.directory ? URI.directory: ''}${URI.file}`, fragment )
|
||||||
xrf.model = model
|
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) )
|
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||||
|
|
||||||
|
@ -1847,17 +2073,16 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
xrf.XRWG.generate({model,scene:model.scene})
|
xrf.XRWG.generate({model,scene:model.scene})
|
||||||
|
|
||||||
// spec: 2. init metadata inside model for non-SRC data
|
// spec: 2. init metadata inside model for non-SRC data
|
||||||
if( !model.isSRC ){
|
if( !model.isSRC ){
|
||||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||||
}
|
}
|
||||||
|
|
||||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||||
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URL (https://xrfragment.org/#predefined_view)
|
// spec: predefined view(s) & objects-of-interest-in-XRWG from URI (https://xrfragment.org/#predefined_view)
|
||||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||||
|
|
||||||
xrf.add( model.scene )
|
xrf.add( model.scene )
|
||||||
if( hash ) xrf.navigator.updateHash(hash)
|
if( fragment ) xrf.navigator.updateHash(fragment)
|
||||||
xrf.emit('navigateLoaded',{url,model})
|
xrf.emit('navigateLoaded',{url,model})
|
||||||
resolve(model)
|
resolve(model)
|
||||||
}
|
}
|
||||||
|
@ -1866,7 +2091,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
loader.parse(data, "", onLoad )
|
loader.parse(data, "", onLoad )
|
||||||
}else{
|
}else{
|
||||||
try{
|
try{
|
||||||
loader.load(url, onLoad )
|
loader.load(file, onLoad )
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.error(e)
|
console.error(e)
|
||||||
xrf.emit('navigateError',{url})
|
xrf.emit('navigateError',{url})
|
||||||
|
@ -1880,9 +2105,12 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
xrf.navigator.init = () => {
|
xrf.navigator.init = () => {
|
||||||
if( xrf.navigator.init.inited ) return
|
if( xrf.navigator.init.inited ) return
|
||||||
|
|
||||||
|
xrf.navigator.URI = xrfragment.URI.parse(document.location.href)
|
||||||
|
|
||||||
window.addEventListener('popstate', function (event){
|
window.addEventListener('popstate', function (event){
|
||||||
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
||||||
xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
|
//xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
|
||||||
|
xrf.navigator.to( document.location.href.replace(/\?/,'') )
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1908,10 +2136,10 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
||||||
|
|
||||||
xrf.addEventListener('navigate', (opts) => {
|
xrf.addEventListener('navigate', (opts) => {
|
||||||
let {url} = opts
|
let {url} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let {fileExt} = xrfragment.URI.parse(url)
|
||||||
|
|
||||||
// handle http links
|
// handle http links
|
||||||
if( url.match(/^http/) && !xrf.loaders[ext] ){
|
if( url.match(/^http/) && !xrf.loaders[fileExt] ){
|
||||||
let inIframe
|
let inIframe
|
||||||
try { inIframe = window.self !== window.top; } catch (e) { inIframe = true; }
|
try { inIframe = window.self !== window.top; } catch (e) { inIframe = true; }
|
||||||
return inIframe ? window.parent.postMessage({ url }, '*') : window.open( url, '_blank')
|
return inIframe ? window.parent.postMessage({ url }, '*') : window.open( url, '_blank')
|
||||||
|
@ -1931,7 +2159,7 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
||||||
|
|
||||||
xrf.navigator.updateHash = (hash,opts) => {
|
xrf.navigator.updateHash = (hash,opts) => {
|
||||||
if( hash.replace(/^#/,'') == document.location.hash.substr(1) || hash.match(/\|/) ) return // skip unnecesary pushState triggers
|
if( hash.replace(/^#/,'') == document.location.hash.substr(1) || hash.match(/\|/) ) return // skip unnecesary pushState triggers
|
||||||
console.log(`URL: ${document.location.search.substr(1)}#${hash}`)
|
console.log(`URI: ${document.location.search.substr(1)}#${hash}`)
|
||||||
xrf.navigator.updateHash.active = true // important to prevent recursion
|
xrf.navigator.updateHash.active = true // important to prevent recursion
|
||||||
document.location.hash = hash
|
document.location.hash = hash
|
||||||
xrf.navigator.updateHash.active = false
|
xrf.navigator.updateHash.active = false
|
||||||
|
@ -1942,6 +2170,23 @@ xrf.navigator.pushState = (file,hash) => {
|
||||||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
||||||
xrf.emit('pushState', {file, hash} )
|
xrf.emit('pushState', {file, hash} )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xrf.navigator.reactifyHash = ( obj ) => {
|
||||||
|
return new Proxy(obj,{
|
||||||
|
get(me,k) { return me[k] },
|
||||||
|
set(me,k,v){
|
||||||
|
me[k] = v
|
||||||
|
xrf.navigator.to( "#" + this.toString(me) )
|
||||||
|
},
|
||||||
|
toString(me){
|
||||||
|
let parts = []
|
||||||
|
Object.keys(me).map( (k) => {
|
||||||
|
parts.push( me[k] ? `${k}=${encodeURIComponent(me[k])}` : k )
|
||||||
|
})
|
||||||
|
return parts.join('&')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* navigation, portals & mutations
|
* navigation, portals & mutations
|
||||||
|
@ -1993,7 +2238,6 @@ xrf.frag.href = function(v, opts){
|
||||||
.emit('href',{click:true,mesh,xrf:v}) // let all listeners agree
|
.emit('href',{click:true,mesh,xrf:v}) // let all listeners agree
|
||||||
.then( () => {
|
.then( () => {
|
||||||
|
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(v.string)
|
|
||||||
const isLocal = v.string[0] == '#'
|
const isLocal = v.string[0] == '#'
|
||||||
const hasPos = isLocal && v.string.match(/pos=/)
|
const hasPos = isLocal && v.string.match(/pos=/)
|
||||||
const flags = isLocal ? xrf.XRF.PV_OVERRIDE : undefined
|
const flags = isLocal ? xrf.XRF.PV_OVERRIDE : undefined
|
||||||
|
@ -2153,6 +2397,32 @@ xrf.frag.pos = function(v, opts){
|
||||||
camera.updateMatrixWorld()
|
camera.updateMatrixWorld()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xrf.frag.pos.get = function(precision,randomize){
|
||||||
|
if( !precision ) precision = 2;
|
||||||
|
if( typeof THREE == 'undefined' ) THREE = xrf.THREE
|
||||||
|
let radToDeg = THREE.MathUtils.radToDeg
|
||||||
|
let toDeg = (x) => x / (Math.PI / 180)
|
||||||
|
let camera = xrf.camera
|
||||||
|
if( randomize ){
|
||||||
|
camera.position.x += Math.random()/10
|
||||||
|
camera.position.z += Math.random()/10
|
||||||
|
}
|
||||||
|
|
||||||
|
// *TODO* add camera direction
|
||||||
|
let direction = new xrf.THREE.Vector3()
|
||||||
|
camera.getWorldDirection(direction)
|
||||||
|
const pitch = Math.asin(direction.y);
|
||||||
|
const yaw = Math.atan2(direction.x, direction.z);
|
||||||
|
const pitchInDegrees = pitch * 180 / Math.PI;
|
||||||
|
const yawInDegrees = yaw * 180 / Math.PI;
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: String(camera.position.x.toFixed(2)),
|
||||||
|
y: String(camera.position.y.toFixed(2)),
|
||||||
|
z: String(camera.position.z.toFixed(2)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xrf.addEventListener('reset', (opts) => {
|
xrf.addEventListener('reset', (opts) => {
|
||||||
// set the player to position 0,0,0
|
// set the player to position 0,0,0
|
||||||
xrf.camera.position.set(0,0,0)
|
xrf.camera.position.set(0,0,0)
|
||||||
|
@ -2207,7 +2477,7 @@ xrf.frag.src = function(v, opts){
|
||||||
if( mesh.isSRC ) return // only embed src once
|
if( mesh.isSRC ) return // only embed src once
|
||||||
|
|
||||||
let url = xrf.frag.src.expandURI( mesh, v.string )
|
let url = xrf.frag.src.expandURI( mesh, v.string )
|
||||||
let srcFrag = opts.srcFrag = xrfragment.URI.parse(url)
|
let srcFrag = opts.srcFrag = xrfragment.URI.parse(url).XRF
|
||||||
opts.isLocal = v.string[0] == '#'
|
opts.isLocal = v.string[0] == '#'
|
||||||
opts.isPortal = xrf.frag.src.renderAsPortal(mesh)
|
opts.isPortal = xrf.frag.src.renderAsPortal(mesh)
|
||||||
opts.isSRC = mesh.isSRC = true
|
opts.isSRC = mesh.isSRC = true
|
||||||
|
@ -2294,7 +2564,7 @@ xrf.frag.src.externalSRC = (url,frag,opts) => {
|
||||||
fetch(url, { method: 'HEAD' })
|
fetch(url, { method: 'HEAD' })
|
||||||
.then( (res) => {
|
.then( (res) => {
|
||||||
let mimetype = res.headers.get('Content-type')
|
let mimetype = res.headers.get('Content-type')
|
||||||
if(xrf.debug != undefined ) console.log("HEAD "+url+" => "+mimetype)
|
if(xrf.debug > 0 ) console.log("HEAD "+url+" => "+mimetype)
|
||||||
if( url.replace(/#.*/,'').match(/\.(gltf|glb)$/) ) mimetype = 'gltf'
|
if( url.replace(/#.*/,'').match(/\.(gltf|glb)$/) ) mimetype = 'gltf'
|
||||||
if( url.replace(/#.*/,'').match(/\.(frag|fs|glsl)$/) ) mimetype = 'x-shader/x-fragment'
|
if( url.replace(/#.*/,'').match(/\.(frag|fs|glsl)$/) ) mimetype = 'x-shader/x-fragment'
|
||||||
if( url.replace(/#.*/,'').match(/\.(vert|vs)$/) ) mimetype = 'x-shader/x-fragment'
|
if( url.replace(/#.*/,'').match(/\.(vert|vs)$/) ) mimetype = 'x-shader/x-fragment'
|
||||||
|
@ -3195,8 +3465,8 @@ xrf.addEventListener('render', (opts) => {
|
||||||
|
|
||||||
let loadAudio = (mimetype) => function(url,opts){
|
let loadAudio = (mimetype) => function(url,opts){
|
||||||
let {mesh,src,camera,THREE} = opts
|
let {mesh,src,camera,THREE} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
let frag = xrf.URI.parse( url )
|
let frag = URL.XRF
|
||||||
|
|
||||||
xrf.init.audio()
|
xrf.init.audio()
|
||||||
let isPositionalAudio = !(mesh.position.x == 0 && mesh.position.y == 0 && mesh.position.z == 0)
|
let isPositionalAudio = !(mesh.position.x == 0 && mesh.position.y == 0 && mesh.position.z == 0)
|
||||||
|
@ -3207,8 +3477,8 @@ let loadAudio = (mimetype) => function(url,opts){
|
||||||
mesh.media = mesh.media || {}
|
mesh.media = mesh.media || {}
|
||||||
mesh.media.audio = { set: (mediafragment,v) => mesh.media.audio[mediafragment] = v }
|
mesh.media.audio = { set: (mediafragment,v) => mesh.media.audio[mediafragment] = v }
|
||||||
|
|
||||||
let finalUrl = url.replace(/#.*/,'')
|
let finalUrl = URL.URN + URL.file
|
||||||
if( xrf.debug != undefined ) console.log("GET "+finalUrl)
|
if( xrf.debug > 0 ) console.log("GET "+finalUrl)
|
||||||
audioLoader.load( finalUrl, function( buffer ) {
|
audioLoader.load( finalUrl, function( buffer ) {
|
||||||
|
|
||||||
sound.setBuffer( buffer );
|
sound.setBuffer( buffer );
|
||||||
|
@ -3318,7 +3588,8 @@ audioMimeTypes.map( (mimetype) => xrf.frag.src.type[ mimetype ] = loadAudio(mim
|
||||||
xrf.frag.src.type['fbx'] = function( url, opts ){
|
xrf.frag.src.type['fbx'] = function( url, opts ){
|
||||||
return new Promise( async (resolve,reject) => {
|
return new Promise( async (resolve,reject) => {
|
||||||
let {mesh,src} = opts
|
let {mesh,src} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let frag = URL.XRF
|
||||||
let loader
|
let loader
|
||||||
|
|
||||||
let {THREE} = await import('https://unpkg.com/three@0.161.0/build/three.module.js')
|
let {THREE} = await import('https://unpkg.com/three@0.161.0/build/three.module.js')
|
||||||
|
@ -3346,14 +3617,17 @@ xrf.frag.src.type['fbx'] = function( url, opts ){
|
||||||
xrf.frag.src.type['x-shader/x-fragment'] = function(url,opts){
|
xrf.frag.src.type['x-shader/x-fragment'] = function(url,opts){
|
||||||
let {mesh,THREE} = opts
|
let {mesh,THREE} = opts
|
||||||
|
|
||||||
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let frag = URL.XRF
|
||||||
|
|
||||||
let isFragmentShader = /\.(fs|frag|glsl)$/
|
let isFragmentShader = /\.(fs|frag|glsl)$/
|
||||||
let isVertexShader = /\.(vs|vert)$/
|
let isVertexShader = /\.(vs|vert)$/
|
||||||
|
|
||||||
let shaderReqs = []
|
let shaderReqs = []
|
||||||
let shaderCode = {}
|
let shaderCode = {}
|
||||||
let shader = {
|
let shader = {
|
||||||
fragment: { code: '', url: url.match( isFragmentShader ) ? url : '' },
|
fragment: { code: '', url: url.match( isFragmentShader ) ? URL.URN + URL.file : '' },
|
||||||
vertex: { code: '', url: url.match( isVertexShader ) ? url : '' }
|
vertex: { code: '', url: url.match( isVertexShader ) ? URL.URN + URL.file : '' }
|
||||||
}
|
}
|
||||||
|
|
||||||
var onShaderLoaded = ((args) => (type, status, code) => {
|
var onShaderLoaded = ((args) => (type, status, code) => {
|
||||||
|
@ -3412,19 +3686,15 @@ xrf.frag.src.type['x-shader/x-vertex'] = xrf.frag.src.type['x-shader/x-fragmen
|
||||||
xrf.frag.src.type['gltf'] = function( url, opts ){
|
xrf.frag.src.type['gltf'] = function( url, opts ){
|
||||||
return new Promise( (resolve,reject) => {
|
return new Promise( (resolve,reject) => {
|
||||||
let {mesh,src} = opts
|
let {mesh,src} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let {directory,file,fileExt,URN} = URL;
|
||||||
let loader
|
let loader
|
||||||
|
|
||||||
const Loader = xrf.loaders[ext]
|
const Loader = xrf.loaders[fileExt]
|
||||||
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
||||||
if( !dir.match("://") ){ // force relative path
|
loader = new Loader().setPath( URN )
|
||||||
dir = dir.substr(0,2) == './' ? dir : `./${dir}`
|
|
||||||
loader = new Loader().setPath( dir )
|
|
||||||
}else{
|
|
||||||
loader = new Loader()
|
|
||||||
}
|
|
||||||
|
|
||||||
loader.load(url, (model) => {
|
loader.load(file, (model) => {
|
||||||
model.isSRC = true
|
model.isSRC = true
|
||||||
resolve(model)
|
resolve(model)
|
||||||
})
|
})
|
||||||
|
@ -3435,7 +3705,7 @@ xrf.frag.src.type['gltf'] = function( url, opts ){
|
||||||
let loadHTML = (mimetype) => function(url,opts){
|
let loadHTML = (mimetype) => function(url,opts){
|
||||||
let {mesh,src,camera} = opts
|
let {mesh,src,camera} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||||
let frag = xrf.URI.parse( url )
|
let frag = xrf.URI.parse( url ).XRF
|
||||||
console.warn("todo: html viewer for src not implemented")
|
console.warn("todo: html viewer for src not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3452,6 +3722,8 @@ htmlMimeTypes.map( (mimetype) => xrf.frag.src.type[ mimetype ] = loadHTML(mimet
|
||||||
xrf.frag.src.type['image/png'] = function(url,opts){
|
xrf.frag.src.type['image/png'] = function(url,opts){
|
||||||
let {mesh,THREE} = opts
|
let {mesh,THREE} = opts
|
||||||
let restrictTo3DBoundingBox = mesh.geometry
|
let restrictTo3DBoundingBox = mesh.geometry
|
||||||
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let frag = URL.XRF
|
||||||
|
|
||||||
mesh.material = new xrf.THREE.MeshBasicMaterial({
|
mesh.material = new xrf.THREE.MeshBasicMaterial({
|
||||||
map: null,
|
map: null,
|
||||||
|
@ -3495,7 +3767,7 @@ xrf.frag.src.type['image/png'] = function(url,opts){
|
||||||
renderImage(texture)
|
renderImage(texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
new THREE.TextureLoader().load( url, onLoad, null, console.error );
|
new THREE.TextureLoader().load( URL.URN + URL.file, onLoad, null, console.error );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3701,9 +3973,9 @@ xrf.portalNonEuclidian.stencilRef = 1
|
||||||
|
|
||||||
let loadVideo = (mimetype) => function(url,opts){
|
let loadVideo = (mimetype) => function(url,opts){
|
||||||
let {mesh,src,camera} = opts
|
let {mesh,src,camera} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
|
||||||
const THREE = xrf.THREE
|
const THREE = xrf.THREE
|
||||||
let frag = xrf.URI.parse( url )
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let frag = URL.XRF
|
||||||
|
|
||||||
mesh.media = mesh.media || {}
|
mesh.media = mesh.media || {}
|
||||||
|
|
||||||
|
@ -3725,7 +3997,7 @@ let loadVideo = (mimetype) => function(url,opts){
|
||||||
},false)
|
},false)
|
||||||
})
|
})
|
||||||
|
|
||||||
video.src = url
|
video.src = URL.URN + URL.file
|
||||||
video.speed = 1.0
|
video.speed = 1.0
|
||||||
video.looping = false
|
video.looping = false
|
||||||
video.set = (mediafragment,v) => {
|
video.set = (mediafragment,v) => {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* v0.5.1 generated at Tue Mar 19 10:04:25 AM UTC 2024
|
* v0.5.1 generated at Tue Apr 16 12:47:01 PM UTC 2024
|
||||||
* https://xrfragment.org
|
* https://xrfragment.org
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -1138,9 +1138,13 @@ xrfragment_Parser.getMetaData = function() {
|
||||||
var meta = { title : ["title","og:title","dc.title"], description : ["aria-description","og:description","dc.description"], author : ["author","dc.creator"], publisher : ["publisher","dc.publisher"], website : ["og:site_name","og:url","dc.publisher"], license : ["SPDX","dc.rights"]};
|
var meta = { title : ["title","og:title","dc.title"], description : ["aria-description","og:description","dc.description"], author : ["author","dc.creator"], publisher : ["publisher","dc.publisher"], website : ["og:site_name","og:url","dc.publisher"], license : ["SPDX","dc.rights"]};
|
||||||
return meta;
|
return meta;
|
||||||
};
|
};
|
||||||
var xrfragment_URI = $hx_exports["xrfragment"]["URI"] = function() { };
|
var xrfragment_URI = $hx_exports["xrfragment"]["URI"] = function() {
|
||||||
|
this.XRF = { };
|
||||||
|
this.hash = { };
|
||||||
|
this.fragment = "";
|
||||||
|
};
|
||||||
xrfragment_URI.__name__ = true;
|
xrfragment_URI.__name__ = true;
|
||||||
xrfragment_URI.parse = function(url,filter) {
|
xrfragment_URI.parseFragment = function(url,filter) {
|
||||||
var store = { };
|
var store = { };
|
||||||
if(url == null || url.indexOf("#") == -1) {
|
if(url == null || url.indexOf("#") == -1) {
|
||||||
return store;
|
return store;
|
||||||
|
@ -1192,6 +1196,232 @@ xrfragment_URI.template = function(uri,vars) {
|
||||||
parts[1] = frag;
|
parts[1] = frag;
|
||||||
return parts.join("#");
|
return parts.join("#");
|
||||||
};
|
};
|
||||||
|
xrfragment_URI.parse = function(stringUrl,flags) {
|
||||||
|
var r = new EReg("^(?:(?![^:@]+:[^:@/]*@)([^:/?#.]+):)?(?://)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:/?#]*)(?::(\\d*))?)(((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[?#]|$)))*/?)?([^?#/]*))(?:\\?([^#]*))?(?:#(.*))?)","");
|
||||||
|
if(stringUrl.indexOf("://") == -1 && stringUrl.charAt(0) != "/") {
|
||||||
|
stringUrl = "/" + stringUrl;
|
||||||
|
}
|
||||||
|
r.match(stringUrl);
|
||||||
|
var url = new xrfragment_URI();
|
||||||
|
var _g = 0;
|
||||||
|
var _g1 = xrfragment_URI._parts.length;
|
||||||
|
while(_g < _g1) {
|
||||||
|
var i = _g++;
|
||||||
|
url[xrfragment_URI._parts[i]] = r.matched(i);
|
||||||
|
}
|
||||||
|
if(xrfragment_URI.isRelative(url) == true) {
|
||||||
|
if(url.directory == null && url.host != null) {
|
||||||
|
url.file = url.host;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url.hash = { };
|
||||||
|
if(url.fragment != null && url.fragment.length > 0) {
|
||||||
|
url.XRF = xrfragment_URI.parseFragment("#" + url.fragment,flags);
|
||||||
|
var key;
|
||||||
|
var _g = 0;
|
||||||
|
var _g1 = Reflect.fields(url.XRF);
|
||||||
|
while(_g < _g1.length) {
|
||||||
|
var key = _g1[_g];
|
||||||
|
++_g;
|
||||||
|
var v = url.XRF[key];
|
||||||
|
url.hash[key] = v["string"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xrfragment_URI.computeVars(url);
|
||||||
|
return url;
|
||||||
|
};
|
||||||
|
xrfragment_URI.computeVars = function(url) {
|
||||||
|
var r_r = new RegExp("//","g".split("u").join(""));
|
||||||
|
if(url.directory != null && url.directory.indexOf("//") != -1) {
|
||||||
|
url.directory = url.directory.replace(r_r,"/");
|
||||||
|
}
|
||||||
|
if(url.path != null && url.path.indexOf("//") != -1) {
|
||||||
|
url.path = url.path.replace(r_r,"/");
|
||||||
|
}
|
||||||
|
if(url.file != null && url.file.indexOf("//") != -1) {
|
||||||
|
url.file = url.file.replace(r_r,"/");
|
||||||
|
}
|
||||||
|
url.URN = url.scheme + "://" + url.host;
|
||||||
|
if(url.port != null) {
|
||||||
|
url.URN += ":" + url.port;
|
||||||
|
}
|
||||||
|
url.URN += url.directory;
|
||||||
|
if(url.file != null) {
|
||||||
|
var parts = url.file.split(".");
|
||||||
|
if(parts.length > 1) {
|
||||||
|
url.fileExt = parts.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xrfragment_URI.toString = function(url) {
|
||||||
|
var result = "";
|
||||||
|
if(url.scheme != null) {
|
||||||
|
result += url.scheme + "://";
|
||||||
|
}
|
||||||
|
if(url.user != null) {
|
||||||
|
result += url.user + ":";
|
||||||
|
}
|
||||||
|
if(url.password != null) {
|
||||||
|
result += url.password + "@";
|
||||||
|
}
|
||||||
|
if(url.host != null) {
|
||||||
|
result += url.host;
|
||||||
|
}
|
||||||
|
if(url.port != null) {
|
||||||
|
result += ":" + url.port;
|
||||||
|
}
|
||||||
|
if(url.directory != null) {
|
||||||
|
result += url.directory;
|
||||||
|
}
|
||||||
|
if(url.file != null) {
|
||||||
|
result += url.file;
|
||||||
|
}
|
||||||
|
if(url.query != null) {
|
||||||
|
result += "?" + url.query;
|
||||||
|
}
|
||||||
|
if(url.fragment != null) {
|
||||||
|
result += "#" + url.fragment;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
xrfragment_URI.appendURI = function(url,appendedURI) {
|
||||||
|
if(xrfragment_URI.isRelative(url) == true) {
|
||||||
|
return xrfragment_URI.appendToRelativeURI(url,appendedURI);
|
||||||
|
} else {
|
||||||
|
return xrfragment_URI.appendToAbsoluteURI(url,appendedURI);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xrfragment_URI.isRelative = function(url) {
|
||||||
|
return url.scheme == null;
|
||||||
|
};
|
||||||
|
xrfragment_URI.appendToRelativeURI = function(url,appendedURI) {
|
||||||
|
if(url.directory == null || url.host == null) {
|
||||||
|
return xrfragment_URI.cloneURI(appendedURI);
|
||||||
|
}
|
||||||
|
var resultURI = new xrfragment_URI();
|
||||||
|
resultURI.host = url.host;
|
||||||
|
resultURI.directory = url.directory;
|
||||||
|
if(appendedURI.host != null) {
|
||||||
|
resultURI.directory += appendedURI.host;
|
||||||
|
}
|
||||||
|
if(appendedURI.directory != null) {
|
||||||
|
var directory = appendedURI.directory;
|
||||||
|
if(appendedURI.host == null) {
|
||||||
|
resultURI.directory += HxOverrides.substr(directory,1,null);
|
||||||
|
} else {
|
||||||
|
resultURI.directory += directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(appendedURI.file != null) {
|
||||||
|
resultURI.file = appendedURI.file;
|
||||||
|
}
|
||||||
|
resultURI.path = resultURI.directory + resultURI.file;
|
||||||
|
if(appendedURI.query != null) {
|
||||||
|
resultURI.query = appendedURI.query;
|
||||||
|
}
|
||||||
|
if(appendedURI.fragment != null) {
|
||||||
|
resultURI.fragment = appendedURI.fragment;
|
||||||
|
}
|
||||||
|
return resultURI;
|
||||||
|
};
|
||||||
|
xrfragment_URI.appendToAbsoluteURI = function(url,appendedURI) {
|
||||||
|
var resultURI = new xrfragment_URI();
|
||||||
|
if(url.scheme != null) {
|
||||||
|
resultURI.scheme = url.scheme;
|
||||||
|
}
|
||||||
|
if(url.host != null) {
|
||||||
|
resultURI.host = url.host;
|
||||||
|
}
|
||||||
|
var directory = "";
|
||||||
|
if(url.directory != null) {
|
||||||
|
directory = url.directory;
|
||||||
|
}
|
||||||
|
if(appendedURI.host != null) {
|
||||||
|
appendedURI.directory += appendedURI.host;
|
||||||
|
}
|
||||||
|
if(appendedURI.directory != null) {
|
||||||
|
directory += appendedURI.directory;
|
||||||
|
}
|
||||||
|
resultURI.directory = directory;
|
||||||
|
if(appendedURI.file != null) {
|
||||||
|
resultURI.file = appendedURI.file;
|
||||||
|
}
|
||||||
|
resultURI.path = resultURI.directory + resultURI.file;
|
||||||
|
if(appendedURI.query != null) {
|
||||||
|
resultURI.query = appendedURI.query;
|
||||||
|
}
|
||||||
|
if(appendedURI.fragment != null) {
|
||||||
|
resultURI.fragment = appendedURI.fragment;
|
||||||
|
}
|
||||||
|
return resultURI;
|
||||||
|
};
|
||||||
|
xrfragment_URI.toAbsolute = function(url,newUrl) {
|
||||||
|
var newURI = xrfragment_URI.parse(newUrl,0);
|
||||||
|
var resultURI = new xrfragment_URI();
|
||||||
|
resultURI.port = url.port;
|
||||||
|
resultURI.source = newUrl;
|
||||||
|
if(newURI.scheme != null) {
|
||||||
|
resultURI.scheme = newURI.scheme;
|
||||||
|
} else {
|
||||||
|
resultURI.scheme = url.scheme;
|
||||||
|
}
|
||||||
|
if(newURI.host != null && newURI.host.length > 0) {
|
||||||
|
resultURI.host = newURI.host;
|
||||||
|
resultURI.port = null;
|
||||||
|
resultURI.fragment = null;
|
||||||
|
resultURI.hash = { };
|
||||||
|
resultURI.XRF = { };
|
||||||
|
if(newURI.port != null) {
|
||||||
|
resultURI.port = newURI.port;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resultURI.host = url.host;
|
||||||
|
}
|
||||||
|
var directory = "";
|
||||||
|
if(url.directory != null) {
|
||||||
|
directory = url.directory;
|
||||||
|
}
|
||||||
|
if(newURI.directory != null) {
|
||||||
|
if(newUrl.charAt(0) != "/" && newUrl.indexOf("://") == -1) {
|
||||||
|
directory += newURI.directory;
|
||||||
|
} else {
|
||||||
|
directory = newURI.directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultURI.directory = directory;
|
||||||
|
if(newURI.file != null) {
|
||||||
|
resultURI.file = newURI.file;
|
||||||
|
}
|
||||||
|
resultURI.path = resultURI.directory + resultURI.file;
|
||||||
|
if(newURI.query != null) {
|
||||||
|
resultURI.query = newURI.query;
|
||||||
|
}
|
||||||
|
if(newURI.fragment != null) {
|
||||||
|
resultURI.fragment = newURI.fragment;
|
||||||
|
}
|
||||||
|
resultURI.hash = newURI.hash;
|
||||||
|
resultURI.XRF = newURI.XRF;
|
||||||
|
xrfragment_URI.computeVars(resultURI);
|
||||||
|
return resultURI;
|
||||||
|
};
|
||||||
|
xrfragment_URI.cloneURI = function(url) {
|
||||||
|
var clonedURI = new xrfragment_URI();
|
||||||
|
clonedURI.url = url.url;
|
||||||
|
clonedURI.source = url.source;
|
||||||
|
clonedURI.scheme = url.scheme;
|
||||||
|
clonedURI.authority = url.authority;
|
||||||
|
clonedURI.userInfo = url.userInfo;
|
||||||
|
clonedURI.password = url.password;
|
||||||
|
clonedURI.host = url.host;
|
||||||
|
clonedURI.port = url.port;
|
||||||
|
clonedURI.relative = url.relative;
|
||||||
|
clonedURI.path = url.path;
|
||||||
|
clonedURI.directory = url.directory;
|
||||||
|
clonedURI.file = url.file;
|
||||||
|
clonedURI.query = url.query;
|
||||||
|
clonedURI.fragment = url.fragment;
|
||||||
|
return clonedURI;
|
||||||
|
};
|
||||||
var xrfragment_XRF = $hx_exports["xrfragment"]["XRF"] = function(_fragment,_flags,_index) {
|
var xrfragment_XRF = $hx_exports["xrfragment"]["XRF"] = function(_fragment,_flags,_index) {
|
||||||
this.floats = [];
|
this.floats = [];
|
||||||
this.shift = [];
|
this.shift = [];
|
||||||
|
@ -1302,6 +1532,7 @@ haxe_Template.hxKeepArrayIterator = new haxe_iterators_ArrayIterator([]);
|
||||||
xrfragment_Parser.error = "";
|
xrfragment_Parser.error = "";
|
||||||
xrfragment_Parser.debug = false;
|
xrfragment_Parser.debug = false;
|
||||||
xrfragment_URI.__meta__ = { statics : { template : { keep : null}}};
|
xrfragment_URI.__meta__ = { statics : { template : { keep : null}}};
|
||||||
|
xrfragment_URI._parts = ["source","scheme","authority","userInfo","user","password","host","port","relative","path","directory","file","query","fragment"];
|
||||||
xrfragment_XRF.IMMUTABLE = 1;
|
xrfragment_XRF.IMMUTABLE = 1;
|
||||||
xrfragment_XRF.PROP_BIND = 2;
|
xrfragment_XRF.PROP_BIND = 2;
|
||||||
xrfragment_XRF.QUERY_OPERATOR = 4;
|
xrfragment_XRF.QUERY_OPERATOR = 4;
|
||||||
|
@ -1589,7 +1820,7 @@ let pub = function( url, node_or_model, flags ){ // evaluate fragments in url
|
||||||
if( !url ) return
|
if( !url ) return
|
||||||
if( !url.match(/#/) ) url = `#${url}`
|
if( !url.match(/#/) ) url = `#${url}`
|
||||||
let { THREE, camera } = xrf
|
let { THREE, camera } = xrf
|
||||||
let frag = xrf.URI.parse( url, flags )
|
let frag = xrf.URI.parse( url, flags ).XRF
|
||||||
let fromNode = node_or_model != xrf.model
|
let fromNode = node_or_model != xrf.model
|
||||||
let isNode = node_or_model && node_or_model.children
|
let isNode = node_or_model && node_or_model.children
|
||||||
|
|
||||||
|
@ -1756,24 +1987,6 @@ xrf.reset = () => {
|
||||||
xrf.layers = 0
|
xrf.layers = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
xrf.parseUrl = (url) => {
|
|
||||||
let urlExHash = url.replace(/#.*/,'')
|
|
||||||
let urlObj,file
|
|
||||||
let store = {}
|
|
||||||
try{
|
|
||||||
urlObj = new URL( urlExHash.match(/:\/\//) ? urlExHash : String(`https://fake.com/${url}`).replace(/\/\//,'/') )
|
|
||||||
file = urlObj.pathname.substring(urlObj.pathname.lastIndexOf('/') + 1);
|
|
||||||
let search = urlObj.search.substr(1).split("&")
|
|
||||||
for( let i in search ) store[ (search[i].split("=")[0]) ] = search[i].split("=")[1] || ''
|
|
||||||
}catch(e){ }
|
|
||||||
let hashmap = url.match("#") ? url.replace(/.*#/,'').split("&") : []
|
|
||||||
for( let i in hashmap ) store[ (hashmap[i].split("=")[0]) ] = hashmap[i].split("=")[1] || ''
|
|
||||||
let dir = url.substring(0, url.lastIndexOf('/') + 1)
|
|
||||||
const hash = url.match(/#/) ? url.replace(/.*#/,'') : ''
|
|
||||||
const ext = file.split('.').pop()
|
|
||||||
return {urlObj,dir,file,hash,ext,store}
|
|
||||||
}
|
|
||||||
|
|
||||||
xrf.add = (object) => {
|
xrf.add = (object) => {
|
||||||
object.isXRF = true // mark for easy deletion when replacing scene
|
object.isXRF = true // mark for easy deletion when replacing scene
|
||||||
xrf.scene.add(object)
|
xrf.scene.add(object)
|
||||||
|
@ -1784,42 +1997,52 @@ xrf.hasNoMaterial = (mesh) => {
|
||||||
const hasMaterialName = mesh.material && mesh.material.name.length > 0
|
const hasMaterialName = mesh.material && mesh.material.name.length > 0
|
||||||
return mesh.geometry && !hasMaterialName && !hasTexture
|
return mesh.geometry && !hasMaterialName && !hasTexture
|
||||||
}
|
}
|
||||||
xrf.navigator = {}
|
xrf.navigator = {URI:{}}
|
||||||
|
|
||||||
xrf.navigator.to = (url,flags,loader,data) => {
|
xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
if( !url ) throw 'xrf.navigator.to(..) no url given'
|
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 URI = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
URI.hash = xrf.navigator.reactifyHash(URI.hash)
|
||||||
|
let fileChange = URI.URN + URI.file != xrf.navigator.URI.URN + xrf.navigator.URI.file
|
||||||
|
let external = URI.URN != document.location.origin + document.location.pathname
|
||||||
|
let hasPos = URI.hash.pos
|
||||||
|
let hashChange = String(xrf.navigator.URI.fragment||"") != String(URI.fragment||"")
|
||||||
|
let hashbus = xrf.hashbus
|
||||||
|
xrf.navigator.URI = URI
|
||||||
|
let {directory,file,fragment,fileExt} = URI;
|
||||||
|
|
||||||
let hashbus = xrf.hashbus
|
const evalFragment = () => {
|
||||||
|
if( URI.fragment ){
|
||||||
|
hashbus.pub( URI.fragment, xrf.model, flags ) // eval local URI XR fragments
|
||||||
|
xrf.navigator.updateHash(fragment) // which don't require
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise( (resolve,reject) => {
|
return new Promise( (resolve,reject) => {
|
||||||
xrf
|
xrf
|
||||||
.emit('navigate', {url,loader,data})
|
.emit('navigate', {url,loader,data})
|
||||||
.then( () => {
|
.then( () => {
|
||||||
|
|
||||||
if( ext && !loader ){
|
const Loader = xrf.loaders[fileExt]
|
||||||
const Loader = xrf.loaders[ext]
|
|
||||||
|
if( fileExt && !loader ){
|
||||||
if( !Loader ) return resolve()
|
if( !Loader ) return resolve()
|
||||||
loader = loader || new Loader().setPath( dir )
|
loader = loader || new Loader().setPath( URI.URN )
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !hash && !file && !ext ) return resolve(xrf.model) // nothing we can do here
|
if( !URI.fragment && !URI.file && !URI.fileExt ) return resolve(xrf.model) // nothing we can do here
|
||||||
|
|
||||||
if( hashChange && !hasPos ){
|
if( xrf.model && !fileChange && hashChange && !hasPos ){
|
||||||
hashbus.pub( url, xrf.model, flags ) // eval local URI XR fragments
|
evalFragment()
|
||||||
xrf.navigator.updateHash(hash) // which don't require
|
return resolve(xrf.model) // positional navigation
|
||||||
return resolve(xrf.model) // positional navigation
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xrf
|
xrf
|
||||||
.emit('navigateLoading', {url,loader,data})
|
.emit('navigateLoading', {url,loader,data})
|
||||||
.then( () => {
|
.then( () => {
|
||||||
if( hashChange && hasPos ){ // we're already loaded
|
if( (!fileChange || !file) && hashChange && hasPos ){ // we're already loaded
|
||||||
hashbus.pub( url, xrf.model, flags ) // and eval local URI XR fragments
|
evalFragment()
|
||||||
xrf.navigator.updateHash(hash)
|
|
||||||
xrf.emit('navigateLoaded',{url})
|
xrf.emit('navigateLoaded',{url})
|
||||||
return resolve(xrf.model)
|
return resolve(xrf.model)
|
||||||
}
|
}
|
||||||
|
@ -1829,17 +2052,20 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
xrf.reset()
|
xrf.reset()
|
||||||
|
|
||||||
// force relative path for files which dont include protocol or relative path
|
// force relative path for files which dont include protocol or relative path
|
||||||
if( dir ) dir = dir[0] == '.' || dir.match("://") ? dir : `.${dir}`
|
if( directory ) directory = directory[0] == '.' || directory.match("://") ? directory : `.${directory}`
|
||||||
url = url.replace(dir,"")
|
|
||||||
loader = loader || new Loader().setPath( dir )
|
loader = loader || new Loader().setPath( URI.URN )
|
||||||
const onLoad = (model) => {
|
const onLoad = (model) => {
|
||||||
|
|
||||||
model.file = file
|
model.file = URI.file
|
||||||
// only change url when loading *another* file
|
// only change url when loading *another* file
|
||||||
if( xrf.model ) xrf.navigator.pushState( `${dir}${file}`, hash )
|
if( xrf.model ){
|
||||||
|
xrf.navigator.pushState( external ? URI.URN + URI.file : URI.file, fragment )
|
||||||
|
}
|
||||||
|
//if( xrf.model ) xrf.navigator.pushState( `${ document.location.pathname != URI.directory ? URI.directory: ''}${URI.file}`, fragment )
|
||||||
xrf.model = model
|
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) )
|
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
|
||||||
|
|
||||||
|
@ -1847,17 +2073,16 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
xrf.XRWG.generate({model,scene:model.scene})
|
xrf.XRWG.generate({model,scene:model.scene})
|
||||||
|
|
||||||
// spec: 2. init metadata inside model for non-SRC data
|
// spec: 2. init metadata inside model for non-SRC data
|
||||||
if( !model.isSRC ){
|
if( !model.isSRC ){
|
||||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||||
}
|
}
|
||||||
|
|
||||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||||
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
xrf.frag.defaultPredefinedViews({model,scene:model.scene})
|
||||||
// spec: predefined view(s) & objects-of-interest-in-XRWG from URL (https://xrfragment.org/#predefined_view)
|
// spec: predefined view(s) & objects-of-interest-in-XRWG from URI (https://xrfragment.org/#predefined_view)
|
||||||
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
let frag = xrf.hashbus.pub( url, model) // and eval URI XR fragments
|
||||||
|
|
||||||
xrf.add( model.scene )
|
xrf.add( model.scene )
|
||||||
if( hash ) xrf.navigator.updateHash(hash)
|
if( fragment ) xrf.navigator.updateHash(fragment)
|
||||||
xrf.emit('navigateLoaded',{url,model})
|
xrf.emit('navigateLoaded',{url,model})
|
||||||
resolve(model)
|
resolve(model)
|
||||||
}
|
}
|
||||||
|
@ -1866,7 +2091,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
loader.parse(data, "", onLoad )
|
loader.parse(data, "", onLoad )
|
||||||
}else{
|
}else{
|
||||||
try{
|
try{
|
||||||
loader.load(url, onLoad )
|
loader.load(file, onLoad )
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.error(e)
|
console.error(e)
|
||||||
xrf.emit('navigateError',{url})
|
xrf.emit('navigateError',{url})
|
||||||
|
@ -1880,9 +2105,12 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
||||||
xrf.navigator.init = () => {
|
xrf.navigator.init = () => {
|
||||||
if( xrf.navigator.init.inited ) return
|
if( xrf.navigator.init.inited ) return
|
||||||
|
|
||||||
|
xrf.navigator.URI = xrfragment.URI.parse(document.location.href)
|
||||||
|
|
||||||
window.addEventListener('popstate', function (event){
|
window.addEventListener('popstate', function (event){
|
||||||
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
||||||
xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
|
//xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
|
||||||
|
xrf.navigator.to( document.location.href.replace(/\?/,'') )
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1908,10 +2136,10 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
||||||
|
|
||||||
xrf.addEventListener('navigate', (opts) => {
|
xrf.addEventListener('navigate', (opts) => {
|
||||||
let {url} = opts
|
let {url} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let {fileExt} = xrfragment.URI.parse(url)
|
||||||
|
|
||||||
// handle http links
|
// handle http links
|
||||||
if( url.match(/^http/) && !xrf.loaders[ext] ){
|
if( url.match(/^http/) && !xrf.loaders[fileExt] ){
|
||||||
let inIframe
|
let inIframe
|
||||||
try { inIframe = window.self !== window.top; } catch (e) { inIframe = true; }
|
try { inIframe = window.self !== window.top; } catch (e) { inIframe = true; }
|
||||||
return inIframe ? window.parent.postMessage({ url }, '*') : window.open( url, '_blank')
|
return inIframe ? window.parent.postMessage({ url }, '*') : window.open( url, '_blank')
|
||||||
|
@ -1931,7 +2159,7 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
||||||
|
|
||||||
xrf.navigator.updateHash = (hash,opts) => {
|
xrf.navigator.updateHash = (hash,opts) => {
|
||||||
if( hash.replace(/^#/,'') == document.location.hash.substr(1) || hash.match(/\|/) ) return // skip unnecesary pushState triggers
|
if( hash.replace(/^#/,'') == document.location.hash.substr(1) || hash.match(/\|/) ) return // skip unnecesary pushState triggers
|
||||||
console.log(`URL: ${document.location.search.substr(1)}#${hash}`)
|
console.log(`URI: ${document.location.search.substr(1)}#${hash}`)
|
||||||
xrf.navigator.updateHash.active = true // important to prevent recursion
|
xrf.navigator.updateHash.active = true // important to prevent recursion
|
||||||
document.location.hash = hash
|
document.location.hash = hash
|
||||||
xrf.navigator.updateHash.active = false
|
xrf.navigator.updateHash.active = false
|
||||||
|
@ -1942,6 +2170,23 @@ xrf.navigator.pushState = (file,hash) => {
|
||||||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${file}#${hash}` )
|
||||||
xrf.emit('pushState', {file, hash} )
|
xrf.emit('pushState', {file, hash} )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xrf.navigator.reactifyHash = ( obj ) => {
|
||||||
|
return new Proxy(obj,{
|
||||||
|
get(me,k) { return me[k] },
|
||||||
|
set(me,k,v){
|
||||||
|
me[k] = v
|
||||||
|
xrf.navigator.to( "#" + this.toString(me) )
|
||||||
|
},
|
||||||
|
toString(me){
|
||||||
|
let parts = []
|
||||||
|
Object.keys(me).map( (k) => {
|
||||||
|
parts.push( me[k] ? `${k}=${encodeURIComponent(me[k])}` : k )
|
||||||
|
})
|
||||||
|
return parts.join('&')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* navigation, portals & mutations
|
* navigation, portals & mutations
|
||||||
|
@ -1993,7 +2238,6 @@ xrf.frag.href = function(v, opts){
|
||||||
.emit('href',{click:true,mesh,xrf:v}) // let all listeners agree
|
.emit('href',{click:true,mesh,xrf:v}) // let all listeners agree
|
||||||
.then( () => {
|
.then( () => {
|
||||||
|
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(v.string)
|
|
||||||
const isLocal = v.string[0] == '#'
|
const isLocal = v.string[0] == '#'
|
||||||
const hasPos = isLocal && v.string.match(/pos=/)
|
const hasPos = isLocal && v.string.match(/pos=/)
|
||||||
const flags = isLocal ? xrf.XRF.PV_OVERRIDE : undefined
|
const flags = isLocal ? xrf.XRF.PV_OVERRIDE : undefined
|
||||||
|
@ -2153,6 +2397,32 @@ xrf.frag.pos = function(v, opts){
|
||||||
camera.updateMatrixWorld()
|
camera.updateMatrixWorld()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xrf.frag.pos.get = function(precision,randomize){
|
||||||
|
if( !precision ) precision = 2;
|
||||||
|
if( typeof THREE == 'undefined' ) THREE = xrf.THREE
|
||||||
|
let radToDeg = THREE.MathUtils.radToDeg
|
||||||
|
let toDeg = (x) => x / (Math.PI / 180)
|
||||||
|
let camera = xrf.camera
|
||||||
|
if( randomize ){
|
||||||
|
camera.position.x += Math.random()/10
|
||||||
|
camera.position.z += Math.random()/10
|
||||||
|
}
|
||||||
|
|
||||||
|
// *TODO* add camera direction
|
||||||
|
let direction = new xrf.THREE.Vector3()
|
||||||
|
camera.getWorldDirection(direction)
|
||||||
|
const pitch = Math.asin(direction.y);
|
||||||
|
const yaw = Math.atan2(direction.x, direction.z);
|
||||||
|
const pitchInDegrees = pitch * 180 / Math.PI;
|
||||||
|
const yawInDegrees = yaw * 180 / Math.PI;
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: String(camera.position.x.toFixed(2)),
|
||||||
|
y: String(camera.position.y.toFixed(2)),
|
||||||
|
z: String(camera.position.z.toFixed(2)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xrf.addEventListener('reset', (opts) => {
|
xrf.addEventListener('reset', (opts) => {
|
||||||
// set the player to position 0,0,0
|
// set the player to position 0,0,0
|
||||||
xrf.camera.position.set(0,0,0)
|
xrf.camera.position.set(0,0,0)
|
||||||
|
@ -2207,7 +2477,7 @@ xrf.frag.src = function(v, opts){
|
||||||
if( mesh.isSRC ) return // only embed src once
|
if( mesh.isSRC ) return // only embed src once
|
||||||
|
|
||||||
let url = xrf.frag.src.expandURI( mesh, v.string )
|
let url = xrf.frag.src.expandURI( mesh, v.string )
|
||||||
let srcFrag = opts.srcFrag = xrfragment.URI.parse(url)
|
let srcFrag = opts.srcFrag = xrfragment.URI.parse(url).XRF
|
||||||
opts.isLocal = v.string[0] == '#'
|
opts.isLocal = v.string[0] == '#'
|
||||||
opts.isPortal = xrf.frag.src.renderAsPortal(mesh)
|
opts.isPortal = xrf.frag.src.renderAsPortal(mesh)
|
||||||
opts.isSRC = mesh.isSRC = true
|
opts.isSRC = mesh.isSRC = true
|
||||||
|
@ -2294,7 +2564,7 @@ xrf.frag.src.externalSRC = (url,frag,opts) => {
|
||||||
fetch(url, { method: 'HEAD' })
|
fetch(url, { method: 'HEAD' })
|
||||||
.then( (res) => {
|
.then( (res) => {
|
||||||
let mimetype = res.headers.get('Content-type')
|
let mimetype = res.headers.get('Content-type')
|
||||||
if(xrf.debug != undefined ) console.log("HEAD "+url+" => "+mimetype)
|
if(xrf.debug > 0 ) console.log("HEAD "+url+" => "+mimetype)
|
||||||
if( url.replace(/#.*/,'').match(/\.(gltf|glb)$/) ) mimetype = 'gltf'
|
if( url.replace(/#.*/,'').match(/\.(gltf|glb)$/) ) mimetype = 'gltf'
|
||||||
if( url.replace(/#.*/,'').match(/\.(frag|fs|glsl)$/) ) mimetype = 'x-shader/x-fragment'
|
if( url.replace(/#.*/,'').match(/\.(frag|fs|glsl)$/) ) mimetype = 'x-shader/x-fragment'
|
||||||
if( url.replace(/#.*/,'').match(/\.(vert|vs)$/) ) mimetype = 'x-shader/x-fragment'
|
if( url.replace(/#.*/,'').match(/\.(vert|vs)$/) ) mimetype = 'x-shader/x-fragment'
|
||||||
|
@ -3195,8 +3465,8 @@ xrf.addEventListener('render', (opts) => {
|
||||||
|
|
||||||
let loadAudio = (mimetype) => function(url,opts){
|
let loadAudio = (mimetype) => function(url,opts){
|
||||||
let {mesh,src,camera,THREE} = opts
|
let {mesh,src,camera,THREE} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
let frag = xrf.URI.parse( url )
|
let frag = URL.XRF
|
||||||
|
|
||||||
xrf.init.audio()
|
xrf.init.audio()
|
||||||
let isPositionalAudio = !(mesh.position.x == 0 && mesh.position.y == 0 && mesh.position.z == 0)
|
let isPositionalAudio = !(mesh.position.x == 0 && mesh.position.y == 0 && mesh.position.z == 0)
|
||||||
|
@ -3207,8 +3477,8 @@ let loadAudio = (mimetype) => function(url,opts){
|
||||||
mesh.media = mesh.media || {}
|
mesh.media = mesh.media || {}
|
||||||
mesh.media.audio = { set: (mediafragment,v) => mesh.media.audio[mediafragment] = v }
|
mesh.media.audio = { set: (mediafragment,v) => mesh.media.audio[mediafragment] = v }
|
||||||
|
|
||||||
let finalUrl = url.replace(/#.*/,'')
|
let finalUrl = URL.URN + URL.file
|
||||||
if( xrf.debug != undefined ) console.log("GET "+finalUrl)
|
if( xrf.debug > 0 ) console.log("GET "+finalUrl)
|
||||||
audioLoader.load( finalUrl, function( buffer ) {
|
audioLoader.load( finalUrl, function( buffer ) {
|
||||||
|
|
||||||
sound.setBuffer( buffer );
|
sound.setBuffer( buffer );
|
||||||
|
@ -3318,7 +3588,8 @@ audioMimeTypes.map( (mimetype) => xrf.frag.src.type[ mimetype ] = loadAudio(mim
|
||||||
xrf.frag.src.type['fbx'] = function( url, opts ){
|
xrf.frag.src.type['fbx'] = function( url, opts ){
|
||||||
return new Promise( async (resolve,reject) => {
|
return new Promise( async (resolve,reject) => {
|
||||||
let {mesh,src} = opts
|
let {mesh,src} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let frag = URL.XRF
|
||||||
let loader
|
let loader
|
||||||
|
|
||||||
let {THREE} = await import('https://unpkg.com/three@0.161.0/build/three.module.js')
|
let {THREE} = await import('https://unpkg.com/three@0.161.0/build/three.module.js')
|
||||||
|
@ -3346,14 +3617,17 @@ xrf.frag.src.type['fbx'] = function( url, opts ){
|
||||||
xrf.frag.src.type['x-shader/x-fragment'] = function(url,opts){
|
xrf.frag.src.type['x-shader/x-fragment'] = function(url,opts){
|
||||||
let {mesh,THREE} = opts
|
let {mesh,THREE} = opts
|
||||||
|
|
||||||
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let frag = URL.XRF
|
||||||
|
|
||||||
let isFragmentShader = /\.(fs|frag|glsl)$/
|
let isFragmentShader = /\.(fs|frag|glsl)$/
|
||||||
let isVertexShader = /\.(vs|vert)$/
|
let isVertexShader = /\.(vs|vert)$/
|
||||||
|
|
||||||
let shaderReqs = []
|
let shaderReqs = []
|
||||||
let shaderCode = {}
|
let shaderCode = {}
|
||||||
let shader = {
|
let shader = {
|
||||||
fragment: { code: '', url: url.match( isFragmentShader ) ? url : '' },
|
fragment: { code: '', url: url.match( isFragmentShader ) ? URL.URN + URL.file : '' },
|
||||||
vertex: { code: '', url: url.match( isVertexShader ) ? url : '' }
|
vertex: { code: '', url: url.match( isVertexShader ) ? URL.URN + URL.file : '' }
|
||||||
}
|
}
|
||||||
|
|
||||||
var onShaderLoaded = ((args) => (type, status, code) => {
|
var onShaderLoaded = ((args) => (type, status, code) => {
|
||||||
|
@ -3412,19 +3686,15 @@ xrf.frag.src.type['x-shader/x-vertex'] = xrf.frag.src.type['x-shader/x-fragmen
|
||||||
xrf.frag.src.type['gltf'] = function( url, opts ){
|
xrf.frag.src.type['gltf'] = function( url, opts ){
|
||||||
return new Promise( (resolve,reject) => {
|
return new Promise( (resolve,reject) => {
|
||||||
let {mesh,src} = opts
|
let {mesh,src} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let {directory,file,fileExt,URN} = URL;
|
||||||
let loader
|
let loader
|
||||||
|
|
||||||
const Loader = xrf.loaders[ext]
|
const Loader = xrf.loaders[fileExt]
|
||||||
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
||||||
if( !dir.match("://") ){ // force relative path
|
loader = new Loader().setPath( URN )
|
||||||
dir = dir.substr(0,2) == './' ? dir : `./${dir}`
|
|
||||||
loader = new Loader().setPath( dir )
|
|
||||||
}else{
|
|
||||||
loader = new Loader()
|
|
||||||
}
|
|
||||||
|
|
||||||
loader.load(url, (model) => {
|
loader.load(file, (model) => {
|
||||||
model.isSRC = true
|
model.isSRC = true
|
||||||
resolve(model)
|
resolve(model)
|
||||||
})
|
})
|
||||||
|
@ -3435,7 +3705,7 @@ xrf.frag.src.type['gltf'] = function( url, opts ){
|
||||||
let loadHTML = (mimetype) => function(url,opts){
|
let loadHTML = (mimetype) => function(url,opts){
|
||||||
let {mesh,src,camera} = opts
|
let {mesh,src,camera} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||||
let frag = xrf.URI.parse( url )
|
let frag = xrf.URI.parse( url ).XRF
|
||||||
console.warn("todo: html viewer for src not implemented")
|
console.warn("todo: html viewer for src not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3452,6 +3722,8 @@ htmlMimeTypes.map( (mimetype) => xrf.frag.src.type[ mimetype ] = loadHTML(mimet
|
||||||
xrf.frag.src.type['image/png'] = function(url,opts){
|
xrf.frag.src.type['image/png'] = function(url,opts){
|
||||||
let {mesh,THREE} = opts
|
let {mesh,THREE} = opts
|
||||||
let restrictTo3DBoundingBox = mesh.geometry
|
let restrictTo3DBoundingBox = mesh.geometry
|
||||||
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let frag = URL.XRF
|
||||||
|
|
||||||
mesh.material = new xrf.THREE.MeshBasicMaterial({
|
mesh.material = new xrf.THREE.MeshBasicMaterial({
|
||||||
map: null,
|
map: null,
|
||||||
|
@ -3495,7 +3767,7 @@ xrf.frag.src.type['image/png'] = function(url,opts){
|
||||||
renderImage(texture)
|
renderImage(texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
new THREE.TextureLoader().load( url, onLoad, null, console.error );
|
new THREE.TextureLoader().load( URL.URN + URL.file, onLoad, null, console.error );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3701,9 +3973,9 @@ xrf.portalNonEuclidian.stencilRef = 1
|
||||||
|
|
||||||
let loadVideo = (mimetype) => function(url,opts){
|
let loadVideo = (mimetype) => function(url,opts){
|
||||||
let {mesh,src,camera} = opts
|
let {mesh,src,camera} = opts
|
||||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
|
||||||
const THREE = xrf.THREE
|
const THREE = xrf.THREE
|
||||||
let frag = xrf.URI.parse( url )
|
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||||
|
let frag = URL.XRF
|
||||||
|
|
||||||
mesh.media = mesh.media || {}
|
mesh.media = mesh.media || {}
|
||||||
|
|
||||||
|
@ -3725,7 +3997,7 @@ let loadVideo = (mimetype) => function(url,opts){
|
||||||
},false)
|
},false)
|
||||||
})
|
})
|
||||||
|
|
||||||
video.src = url
|
video.src = URL.URN + URL.file
|
||||||
video.speed = 1.0
|
video.speed = 1.0
|
||||||
video.looping = false
|
video.looping = false
|
||||||
video.set = (mediafragment,v) => {
|
video.set = (mediafragment,v) => {
|
||||||
|
|
22
index.html
22
index.html
File diff suppressed because one or more lines are too long
|
@ -10,6 +10,8 @@ window.AFRAME.registerComponent('xrf-get', {
|
||||||
var el = this.el;
|
var el = this.el;
|
||||||
var meshname = this.data.name || this.data;
|
var meshname = this.data.name || this.data;
|
||||||
|
|
||||||
|
if( !meshname || typeof meshname != 'string' ) return
|
||||||
|
|
||||||
this.el.addEventListener('update', (evt) => {
|
this.el.addEventListener('update', (evt) => {
|
||||||
|
|
||||||
setTimeout( () => {
|
setTimeout( () => {
|
||||||
|
@ -46,7 +48,8 @@ window.AFRAME.registerComponent('xrf-get', {
|
||||||
this.el.object3D.child = mesh // keep reference (because .children will be empty)
|
this.el.object3D.child = mesh // keep reference (because .children will be empty)
|
||||||
|
|
||||||
if( !this.el.id ) this.el.setAttribute("id",`xrf-${mesh.name}`)
|
if( !this.el.id ) this.el.setAttribute("id",`xrf-${mesh.name}`)
|
||||||
}else console.warn("xrf-get ignore: "+JSON.stringify(this.data))
|
}
|
||||||
|
|
||||||
}, evt && evt.timeout ? evt.timeout: 500)
|
}, evt && evt.timeout ? evt.timeout: 500)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -110,7 +110,7 @@ xrf.navigator.init = () => {
|
||||||
|
|
||||||
window.addEventListener('popstate', function (event){
|
window.addEventListener('popstate', function (event){
|
||||||
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
||||||
xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
|
xrf.navigator.to( document.location.href.replace(/\?/,'') )
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ let loadAudio = (mimetype) => function(url,opts){
|
||||||
mesh.media.audio = { set: (mediafragment,v) => mesh.media.audio[mediafragment] = v }
|
mesh.media.audio = { set: (mediafragment,v) => mesh.media.audio[mediafragment] = v }
|
||||||
|
|
||||||
let finalUrl = URL.URN + URL.file
|
let finalUrl = URL.URN + URL.file
|
||||||
if( xrf.debug != undefined ) console.log("GET "+finalUrl)
|
if( xrf.debug > 0 ) console.log("GET "+finalUrl)
|
||||||
audioLoader.load( finalUrl, function( buffer ) {
|
audioLoader.load( finalUrl, function( buffer ) {
|
||||||
|
|
||||||
sound.setBuffer( buffer );
|
sound.setBuffer( buffer );
|
||||||
|
|
|
@ -401,6 +401,8 @@ class URI {
|
||||||
|
|
||||||
resultURI.port = url.port;
|
resultURI.port = url.port;
|
||||||
|
|
||||||
|
resultURI.source = newUrl;
|
||||||
|
|
||||||
if (newURI.scheme != null)
|
if (newURI.scheme != null)
|
||||||
{
|
{
|
||||||
resultURI.scheme = newURI.scheme;
|
resultURI.scheme = newURI.scheme;
|
||||||
|
|
|
@ -33,7 +33,7 @@ createScene = (noadd) => {
|
||||||
|
|
||||||
filterScene = (URI,opts) => {
|
filterScene = (URI,opts) => {
|
||||||
opts = opts || {}
|
opts = opts || {}
|
||||||
frag = xrf.URI.parse(URI)
|
frag = xrf.URI.parse(URI).XRF
|
||||||
var {a,b,c,d,extembed,scene} = createScene()
|
var {a,b,c,d,extembed,scene} = createScene()
|
||||||
xrf.filter.scene({...opts,scene,frag})
|
xrf.filter.scene({...opts,scene,frag})
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ console.assert = ((assert) => (a,b) => {
|
||||||
/*
|
/*
|
||||||
* parser checks
|
* parser checks
|
||||||
*/
|
*/
|
||||||
let frags = xrf.URI.parse('://foo.com/1.gltf#pos=1.0,2.0,3.0&t=0,100')
|
let frags = xrf.URI.parse('://foo.com/1.gltf#pos=1.0,2.0,3.0&t=0,100').XRF
|
||||||
console.assert( frags.t, {frags, reason:'URI.parse(): t needs to be set'})
|
console.assert( frags.t, {frags, reason:'URI.parse(): t needs to be set'})
|
||||||
|
|
||||||
let frag = xrf.URI.parse("#foo=1")
|
let frag = xrf.URI.parse("#foo=1").XRF
|
||||||
console.assert( frag, {reason: 'xrf.URI.parse() should be available'})
|
console.assert( frag, {reason: 'xrf.URI.parse() should be available'})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue