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
|
||||
* 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"]};
|
||||
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.parse = function(url,filter) {
|
||||
xrfragment_URI.parseFragment = function(url,filter) {
|
||||
var store = { };
|
||||
if(url == null || url.indexOf("#") == -1) {
|
||||
return store;
|
||||
|
@ -1192,6 +1196,232 @@ xrfragment_URI.template = function(uri,vars) {
|
|||
parts[1] = frag;
|
||||
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) {
|
||||
this.floats = [];
|
||||
this.shift = [];
|
||||
|
@ -1302,6 +1532,7 @@ haxe_Template.hxKeepArrayIterator = new haxe_iterators_ArrayIterator([]);
|
|||
xrfragment_Parser.error = "";
|
||||
xrfragment_Parser.debug = false;
|
||||
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.PROP_BIND = 2;
|
||||
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.match(/#/) ) url = `#${url}`
|
||||
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 isNode = node_or_model && node_or_model.children
|
||||
|
||||
|
@ -1756,24 +1987,6 @@ xrf.reset = () => {
|
|||
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) => {
|
||||
object.isXRF = true // mark for easy deletion when replacing scene
|
||||
xrf.scene.add(object)
|
||||
|
@ -1784,42 +1997,52 @@ xrf.hasNoMaterial = (mesh) => {
|
|||
const hasMaterialName = mesh.material && mesh.material.name.length > 0
|
||||
return mesh.geometry && !hasMaterialName && !hasTexture
|
||||
}
|
||||
xrf.navigator = {}
|
||||
xrf.navigator = {URI:{}}
|
||||
|
||||
xrf.navigator.to = (url,flags,loader,data) => {
|
||||
if( !url ) throw 'xrf.navigator.to(..) no url given'
|
||||
let {urlObj,dir,file,hash,ext} = xrf.navigator.origin = xrf.parseUrl(url)
|
||||
let hashChange = (!file && hash) || !data && xrf.model.file == file
|
||||
let hasPos = String(hash).match(/pos=/)
|
||||
|
||||
let 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) => {
|
||||
xrf
|
||||
.emit('navigate', {url,loader,data})
|
||||
.then( () => {
|
||||
|
||||
if( ext && !loader ){
|
||||
const Loader = xrf.loaders[ext]
|
||||
const Loader = xrf.loaders[fileExt]
|
||||
|
||||
if( fileExt && !loader ){
|
||||
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 ){
|
||||
hashbus.pub( url, xrf.model, flags ) // eval local URI XR fragments
|
||||
xrf.navigator.updateHash(hash) // which don't require
|
||||
return resolve(xrf.model) // positional navigation
|
||||
if( xrf.model && !fileChange && hashChange && !hasPos ){
|
||||
evalFragment()
|
||||
return resolve(xrf.model) // positional navigation
|
||||
}
|
||||
|
||||
xrf
|
||||
.emit('navigateLoading', {url,loader,data})
|
||||
.then( () => {
|
||||
if( hashChange && hasPos ){ // we're already loaded
|
||||
hashbus.pub( url, xrf.model, flags ) // and eval local URI XR fragments
|
||||
xrf.navigator.updateHash(hash)
|
||||
if( (!fileChange || !file) && hashChange && hasPos ){ // we're already loaded
|
||||
evalFragment()
|
||||
xrf.emit('navigateLoaded',{url})
|
||||
return resolve(xrf.model)
|
||||
}
|
||||
|
@ -1829,17 +2052,20 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
xrf.reset()
|
||||
|
||||
// force relative path for files which dont include protocol or relative path
|
||||
if( dir ) dir = dir[0] == '.' || dir.match("://") ? dir : `.${dir}`
|
||||
url = url.replace(dir,"")
|
||||
loader = loader || new Loader().setPath( dir )
|
||||
if( directory ) directory = directory[0] == '.' || directory.match("://") ? directory : `.${directory}`
|
||||
|
||||
loader = loader || new Loader().setPath( URI.URN )
|
||||
const onLoad = (model) => {
|
||||
|
||||
model.file = file
|
||||
model.file = URI.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
|
||||
|
||||
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) )
|
||||
|
||||
|
@ -1850,14 +2076,13 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||
}
|
||||
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
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
|
||||
|
||||
xrf.add( model.scene )
|
||||
if( hash ) xrf.navigator.updateHash(hash)
|
||||
if( fragment ) xrf.navigator.updateHash(fragment)
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
resolve(model)
|
||||
}
|
||||
|
@ -1866,7 +2091,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
loader.parse(data, "", onLoad )
|
||||
}else{
|
||||
try{
|
||||
loader.load(url, onLoad )
|
||||
loader.load(file, onLoad )
|
||||
}catch(e){
|
||||
console.error(e)
|
||||
xrf.emit('navigateError',{url})
|
||||
|
@ -1880,9 +2105,12 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
xrf.navigator.init = () => {
|
||||
if( xrf.navigator.init.inited ) return
|
||||
|
||||
xrf.navigator.URI = xrfragment.URI.parse(document.location.href)
|
||||
|
||||
window.addEventListener('popstate', function (event){
|
||||
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
||||
xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
|
||||
//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) => {
|
||||
let {url} = opts
|
||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||
let {fileExt} = xrfragment.URI.parse(url)
|
||||
|
||||
// handle http links
|
||||
if( url.match(/^http/) && !xrf.loaders[ext] ){
|
||||
if( url.match(/^http/) && !xrf.loaders[fileExt] ){
|
||||
let inIframe
|
||||
try { inIframe = window.self !== window.top; } catch (e) { inIframe = true; }
|
||||
return inIframe ? window.parent.postMessage({ url }, '*') : window.open( url, '_blank')
|
||||
|
@ -1931,7 +2159,7 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
|||
|
||||
xrf.navigator.updateHash = (hash,opts) => {
|
||||
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
|
||||
document.location.hash = hash
|
||||
xrf.navigator.updateHash.active = false
|
||||
|
@ -1942,6 +2170,23 @@ xrf.navigator.pushState = (file,hash) => {
|
|||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${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
|
||||
|
@ -1993,7 +2238,6 @@ xrf.frag.href = function(v, opts){
|
|||
.emit('href',{click:true,mesh,xrf:v}) // let all listeners agree
|
||||
.then( () => {
|
||||
|
||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(v.string)
|
||||
const isLocal = v.string[0] == '#'
|
||||
const hasPos = isLocal && v.string.match(/pos=/)
|
||||
const flags = isLocal ? xrf.XRF.PV_OVERRIDE : undefined
|
||||
|
@ -2153,6 +2397,32 @@ xrf.frag.pos = function(v, opts){
|
|||
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) => {
|
||||
// set the player to position 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
|
||||
|
||||
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.isPortal = xrf.frag.src.renderAsPortal(mesh)
|
||||
opts.isSRC = mesh.isSRC = true
|
||||
|
@ -2294,7 +2564,7 @@ xrf.frag.src.externalSRC = (url,frag,opts) => {
|
|||
fetch(url, { method: 'HEAD' })
|
||||
.then( (res) => {
|
||||
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(/\.(frag|fs|glsl)$/) ) 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 {mesh,src,camera,THREE} = opts
|
||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||
let frag = xrf.URI.parse( url )
|
||||
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let frag = URL.XRF
|
||||
|
||||
xrf.init.audio()
|
||||
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.audio = { set: (mediafragment,v) => mesh.media.audio[mediafragment] = v }
|
||||
|
||||
let finalUrl = url.replace(/#.*/,'')
|
||||
if( xrf.debug != undefined ) console.log("GET "+finalUrl)
|
||||
let finalUrl = URL.URN + URL.file
|
||||
if( xrf.debug > 0 ) console.log("GET "+finalUrl)
|
||||
audioLoader.load( finalUrl, function( 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 ){
|
||||
return new Promise( async (resolve,reject) => {
|
||||
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 {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){
|
||||
let {mesh,THREE} = opts
|
||||
|
||||
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let frag = URL.XRF
|
||||
|
||||
let isFragmentShader = /\.(fs|frag|glsl)$/
|
||||
let isVertexShader = /\.(vs|vert)$/
|
||||
|
||||
let shaderReqs = []
|
||||
let shaderCode = {}
|
||||
let shader = {
|
||||
fragment: { code: '', url: url.match( isFragmentShader ) ? url : '' },
|
||||
vertex: { code: '', url: url.match( isVertexShader ) ? url : '' }
|
||||
fragment: { code: '', url: url.match( isFragmentShader ) ? URL.URN + URL.file : '' },
|
||||
vertex: { code: '', url: url.match( isVertexShader ) ? URL.URN + URL.file : '' }
|
||||
}
|
||||
|
||||
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 ){
|
||||
return new Promise( (resolve,reject) => {
|
||||
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
|
||||
|
||||
const Loader = xrf.loaders[ext]
|
||||
const Loader = xrf.loaders[fileExt]
|
||||
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
||||
if( !dir.match("://") ){ // force relative path
|
||||
dir = dir.substr(0,2) == './' ? dir : `./${dir}`
|
||||
loader = new Loader().setPath( dir )
|
||||
}else{
|
||||
loader = new Loader()
|
||||
}
|
||||
loader = new Loader().setPath( URN )
|
||||
|
||||
loader.load(url, (model) => {
|
||||
loader.load(file, (model) => {
|
||||
model.isSRC = true
|
||||
resolve(model)
|
||||
})
|
||||
|
@ -3435,7 +3705,7 @@ xrf.frag.src.type['gltf'] = function( url, opts ){
|
|||
let loadHTML = (mimetype) => function(url,opts){
|
||||
let {mesh,src,camera} = opts
|
||||
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")
|
||||
}
|
||||
|
||||
|
@ -3452,6 +3722,8 @@ htmlMimeTypes.map( (mimetype) => xrf.frag.src.type[ mimetype ] = loadHTML(mimet
|
|||
xrf.frag.src.type['image/png'] = function(url,opts){
|
||||
let {mesh,THREE} = opts
|
||||
let restrictTo3DBoundingBox = mesh.geometry
|
||||
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let frag = URL.XRF
|
||||
|
||||
mesh.material = new xrf.THREE.MeshBasicMaterial({
|
||||
map: null,
|
||||
|
@ -3495,7 +3767,7 @@ xrf.frag.src.type['image/png'] = function(url,opts){
|
|||
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 {mesh,src,camera} = opts
|
||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||
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 || {}
|
||||
|
||||
|
@ -3725,7 +3997,7 @@ let loadVideo = (mimetype) => function(url,opts){
|
|||
},false)
|
||||
})
|
||||
|
||||
video.src = url
|
||||
video.src = URL.URN + URL.file
|
||||
video.speed = 1.0
|
||||
video.looping = false
|
||||
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
|
||||
// will break teleporting and other stuff
|
||||
// overriding this is easier then adding updateMatrixWorld() everywhere else
|
||||
|
@ -4280,7 +4563,7 @@ AFRAME.registerComponent('pressable', {
|
|||
this.el.emit('click');
|
||||
this.pressed = setTimeout( () => {
|
||||
this.el.emit('pressedended');
|
||||
this.pressed = null
|
||||
this.pressed = false
|
||||
},300)
|
||||
}
|
||||
}
|
||||
|
@ -4438,8 +4721,10 @@ window.AFRAME.registerComponent('xrf-button', {
|
|||
this.el.addEventListener('mouseenter', (e) => this.onMouseEnter(e) );
|
||||
this.el.addEventListener('mouseleave', (e) => this.onMouseLeave(e) );
|
||||
|
||||
let cb = new Function(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() {
|
||||
|
@ -4611,6 +4896,8 @@ window.AFRAME.registerComponent('xrf-get', {
|
|||
var el = this.el;
|
||||
var meshname = this.data.name || this.data;
|
||||
|
||||
if( !meshname || typeof meshname != 'string' ) return
|
||||
|
||||
this.el.addEventListener('update', (evt) => {
|
||||
|
||||
setTimeout( () => {
|
||||
|
@ -4647,7 +4934,8 @@ window.AFRAME.registerComponent('xrf-get', {
|
|||
this.el.object3D.child = mesh // keep reference (because .children will be empty)
|
||||
|
||||
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)
|
||||
|
||||
})
|
||||
|
|
|
@ -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"]};
|
||||
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.parse = function(url,filter) {
|
||||
xrfragment_URI.parseFragment = function(url,filter) {
|
||||
var store = { };
|
||||
if(url == null || url.indexOf("#") == -1) {
|
||||
return store;
|
||||
|
@ -1187,6 +1191,232 @@ xrfragment_URI.template = function(uri,vars) {
|
|||
parts[1] = frag;
|
||||
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) {
|
||||
this.floats = [];
|
||||
this.shift = [];
|
||||
|
@ -1297,6 +1527,7 @@ haxe_Template.hxKeepArrayIterator = new haxe_iterators_ArrayIterator([]);
|
|||
xrfragment_Parser.error = "";
|
||||
xrfragment_Parser.debug = false;
|
||||
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.PROP_BIND = 2;
|
||||
xrfragment_XRF.QUERY_OPERATOR = 4;
|
||||
|
|
|
@ -2899,10 +2899,19 @@ __xrfragment_Parser.getMetaData = function()
|
|||
do return meta 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
|
||||
__xrfragment_URI.__name__ = true
|
||||
__xrfragment_URI.parse = function(url,filter)
|
||||
__xrfragment_URI.parseFragment = function(url,filter)
|
||||
local store = _hx_e();
|
||||
local tmp;
|
||||
if (url ~= nil) then
|
||||
|
@ -3063,6 +3072,374 @@ __xrfragment_URI.template = function(uri,vars)
|
|||
parts[1] = frag;
|
||||
do return parts:join("#") 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)
|
||||
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._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.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
|
||||
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]
|
||||
loader = new Loader().setPath( dir )
|
||||
notify('exporting scene<br><br>please wait..')
|
||||
|
@ -760,29 +760,8 @@ window.frontend = (opts) => new Proxy({
|
|||
},
|
||||
|
||||
updateHashPosition(randomize){
|
||||
// *TODO* this should be part of the XRF Threejs framework
|
||||
if( typeof THREE == 'undefined' ) THREE = xrf.THREE
|
||||
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(/#&/,'')
|
||||
}
|
||||
const pos = xrf.frag.pos.get()
|
||||
xrf.navigator.URI.hash.pos = `${pos.x},${pos.y},${pos.z}`
|
||||
this.copyToClipboard( window.location.href );
|
||||
},
|
||||
|
||||
|
@ -802,8 +781,9 @@ window.frontend = (opts) => new Proxy({
|
|||
document.location.hash += `&meet=${network.meetingLink}`
|
||||
}
|
||||
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
|
||||
if( opts.linkonly ) return url
|
||||
this.copyToClipboard( url )
|
||||
|
|
|
@ -316,7 +316,7 @@
|
|||
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)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -489,7 +489,7 @@ chatComponent = {
|
|||
div.classList.add.apply(div.classList, opts.class.concat(["envelope"]))
|
||||
}
|
||||
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'
|
||||
if( frag.pos ) opts.pos = frag.pos.string
|
||||
msg.classList.add('self')
|
||||
|
|
|
@ -260,7 +260,7 @@ window.trystero = (opts) => new Proxy({
|
|||
let isTeleport = href.match(/(pos=|http:)/)
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -2303,11 +2303,33 @@ xrfragment_Parser._hx_class = xrfragment_Parser
|
|||
|
||||
class xrfragment_URI:
|
||||
_hx_class_name = "xrfragment.URI"
|
||||
__slots__ = ()
|
||||
_hx_statics = ["__meta__", "parse", "template"]
|
||||
__slots__ = ("url", "source", "scheme", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "fileExt", "query", "fragment", "hash", "XRF", "URN")
|
||||
_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
|
||||
def parse(url,_hx_filter):
|
||||
def parseFragment(url,_hx_filter):
|
||||
store = _hx_AnonObject({})
|
||||
tmp = None
|
||||
if (url is not None):
|
||||
|
@ -2362,6 +2384,230 @@ class xrfragment_URI:
|
|||
frag = StringTools.replace(frag,"null","")
|
||||
python_internal_ArrayImpl._set(parts, 1, frag)
|
||||
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
|
||||
|
||||
|
||||
|
@ -2496,6 +2742,7 @@ python_Boot.prefixLength = len("_hx_")
|
|||
xrfragment_Parser.error = ""
|
||||
xrfragment_Parser.debug = False
|
||||
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.IMMUTABLE = 1
|
||||
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
|
||||
* 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"]};
|
||||
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.parse = function(url,filter) {
|
||||
xrfragment_URI.parseFragment = function(url,filter) {
|
||||
var store = { };
|
||||
if(url == null || url.indexOf("#") == -1) {
|
||||
return store;
|
||||
|
@ -1192,6 +1196,232 @@ xrfragment_URI.template = function(uri,vars) {
|
|||
parts[1] = frag;
|
||||
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) {
|
||||
this.floats = [];
|
||||
this.shift = [];
|
||||
|
@ -1302,6 +1532,7 @@ haxe_Template.hxKeepArrayIterator = new haxe_iterators_ArrayIterator([]);
|
|||
xrfragment_Parser.error = "";
|
||||
xrfragment_Parser.debug = false;
|
||||
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.PROP_BIND = 2;
|
||||
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.match(/#/) ) url = `#${url}`
|
||||
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 isNode = node_or_model && node_or_model.children
|
||||
|
||||
|
@ -1756,24 +1987,6 @@ xrf.reset = () => {
|
|||
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) => {
|
||||
object.isXRF = true // mark for easy deletion when replacing scene
|
||||
xrf.scene.add(object)
|
||||
|
@ -1784,42 +1997,52 @@ xrf.hasNoMaterial = (mesh) => {
|
|||
const hasMaterialName = mesh.material && mesh.material.name.length > 0
|
||||
return mesh.geometry && !hasMaterialName && !hasTexture
|
||||
}
|
||||
xrf.navigator = {}
|
||||
xrf.navigator = {URI:{}}
|
||||
|
||||
xrf.navigator.to = (url,flags,loader,data) => {
|
||||
if( !url ) throw 'xrf.navigator.to(..) no url given'
|
||||
let {urlObj,dir,file,hash,ext} = xrf.navigator.origin = xrf.parseUrl(url)
|
||||
let hashChange = (!file && hash) || !data && xrf.model.file == file
|
||||
let hasPos = String(hash).match(/pos=/)
|
||||
|
||||
let 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) => {
|
||||
xrf
|
||||
.emit('navigate', {url,loader,data})
|
||||
.then( () => {
|
||||
|
||||
if( ext && !loader ){
|
||||
const Loader = xrf.loaders[ext]
|
||||
const Loader = xrf.loaders[fileExt]
|
||||
|
||||
if( fileExt && !loader ){
|
||||
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 ){
|
||||
hashbus.pub( url, xrf.model, flags ) // eval local URI XR fragments
|
||||
xrf.navigator.updateHash(hash) // which don't require
|
||||
return resolve(xrf.model) // positional navigation
|
||||
if( xrf.model && !fileChange && hashChange && !hasPos ){
|
||||
evalFragment()
|
||||
return resolve(xrf.model) // positional navigation
|
||||
}
|
||||
|
||||
xrf
|
||||
.emit('navigateLoading', {url,loader,data})
|
||||
.then( () => {
|
||||
if( hashChange && hasPos ){ // we're already loaded
|
||||
hashbus.pub( url, xrf.model, flags ) // and eval local URI XR fragments
|
||||
xrf.navigator.updateHash(hash)
|
||||
if( (!fileChange || !file) && hashChange && hasPos ){ // we're already loaded
|
||||
evalFragment()
|
||||
xrf.emit('navigateLoaded',{url})
|
||||
return resolve(xrf.model)
|
||||
}
|
||||
|
@ -1829,17 +2052,20 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
xrf.reset()
|
||||
|
||||
// force relative path for files which dont include protocol or relative path
|
||||
if( dir ) dir = dir[0] == '.' || dir.match("://") ? dir : `.${dir}`
|
||||
url = url.replace(dir,"")
|
||||
loader = loader || new Loader().setPath( dir )
|
||||
if( directory ) directory = directory[0] == '.' || directory.match("://") ? directory : `.${directory}`
|
||||
|
||||
loader = loader || new Loader().setPath( URI.URN )
|
||||
const onLoad = (model) => {
|
||||
|
||||
model.file = file
|
||||
model.file = URI.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
|
||||
|
||||
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) )
|
||||
|
||||
|
@ -1850,14 +2076,13 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||
}
|
||||
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
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
|
||||
|
||||
xrf.add( model.scene )
|
||||
if( hash ) xrf.navigator.updateHash(hash)
|
||||
if( fragment ) xrf.navigator.updateHash(fragment)
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
resolve(model)
|
||||
}
|
||||
|
@ -1866,7 +2091,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
loader.parse(data, "", onLoad )
|
||||
}else{
|
||||
try{
|
||||
loader.load(url, onLoad )
|
||||
loader.load(file, onLoad )
|
||||
}catch(e){
|
||||
console.error(e)
|
||||
xrf.emit('navigateError',{url})
|
||||
|
@ -1880,9 +2105,12 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
xrf.navigator.init = () => {
|
||||
if( xrf.navigator.init.inited ) return
|
||||
|
||||
xrf.navigator.URI = xrfragment.URI.parse(document.location.href)
|
||||
|
||||
window.addEventListener('popstate', function (event){
|
||||
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
||||
xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
|
||||
//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) => {
|
||||
let {url} = opts
|
||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||
let {fileExt} = xrfragment.URI.parse(url)
|
||||
|
||||
// handle http links
|
||||
if( url.match(/^http/) && !xrf.loaders[ext] ){
|
||||
if( url.match(/^http/) && !xrf.loaders[fileExt] ){
|
||||
let inIframe
|
||||
try { inIframe = window.self !== window.top; } catch (e) { inIframe = true; }
|
||||
return inIframe ? window.parent.postMessage({ url }, '*') : window.open( url, '_blank')
|
||||
|
@ -1931,7 +2159,7 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
|||
|
||||
xrf.navigator.updateHash = (hash,opts) => {
|
||||
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
|
||||
document.location.hash = hash
|
||||
xrf.navigator.updateHash.active = false
|
||||
|
@ -1942,6 +2170,23 @@ xrf.navigator.pushState = (file,hash) => {
|
|||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${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
|
||||
|
@ -1993,7 +2238,6 @@ xrf.frag.href = function(v, opts){
|
|||
.emit('href',{click:true,mesh,xrf:v}) // let all listeners agree
|
||||
.then( () => {
|
||||
|
||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(v.string)
|
||||
const isLocal = v.string[0] == '#'
|
||||
const hasPos = isLocal && v.string.match(/pos=/)
|
||||
const flags = isLocal ? xrf.XRF.PV_OVERRIDE : undefined
|
||||
|
@ -2153,6 +2397,32 @@ xrf.frag.pos = function(v, opts){
|
|||
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) => {
|
||||
// set the player to position 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
|
||||
|
||||
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.isPortal = xrf.frag.src.renderAsPortal(mesh)
|
||||
opts.isSRC = mesh.isSRC = true
|
||||
|
@ -2294,7 +2564,7 @@ xrf.frag.src.externalSRC = (url,frag,opts) => {
|
|||
fetch(url, { method: 'HEAD' })
|
||||
.then( (res) => {
|
||||
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(/\.(frag|fs|glsl)$/) ) 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 {mesh,src,camera,THREE} = opts
|
||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||
let frag = xrf.URI.parse( url )
|
||||
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let frag = URL.XRF
|
||||
|
||||
xrf.init.audio()
|
||||
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.audio = { set: (mediafragment,v) => mesh.media.audio[mediafragment] = v }
|
||||
|
||||
let finalUrl = url.replace(/#.*/,'')
|
||||
if( xrf.debug != undefined ) console.log("GET "+finalUrl)
|
||||
let finalUrl = URL.URN + URL.file
|
||||
if( xrf.debug > 0 ) console.log("GET "+finalUrl)
|
||||
audioLoader.load( finalUrl, function( 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 ){
|
||||
return new Promise( async (resolve,reject) => {
|
||||
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 {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){
|
||||
let {mesh,THREE} = opts
|
||||
|
||||
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let frag = URL.XRF
|
||||
|
||||
let isFragmentShader = /\.(fs|frag|glsl)$/
|
||||
let isVertexShader = /\.(vs|vert)$/
|
||||
|
||||
let shaderReqs = []
|
||||
let shaderCode = {}
|
||||
let shader = {
|
||||
fragment: { code: '', url: url.match( isFragmentShader ) ? url : '' },
|
||||
vertex: { code: '', url: url.match( isVertexShader ) ? url : '' }
|
||||
fragment: { code: '', url: url.match( isFragmentShader ) ? URL.URN + URL.file : '' },
|
||||
vertex: { code: '', url: url.match( isVertexShader ) ? URL.URN + URL.file : '' }
|
||||
}
|
||||
|
||||
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 ){
|
||||
return new Promise( (resolve,reject) => {
|
||||
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
|
||||
|
||||
const Loader = xrf.loaders[ext]
|
||||
const Loader = xrf.loaders[fileExt]
|
||||
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
||||
if( !dir.match("://") ){ // force relative path
|
||||
dir = dir.substr(0,2) == './' ? dir : `./${dir}`
|
||||
loader = new Loader().setPath( dir )
|
||||
}else{
|
||||
loader = new Loader()
|
||||
}
|
||||
loader = new Loader().setPath( URN )
|
||||
|
||||
loader.load(url, (model) => {
|
||||
loader.load(file, (model) => {
|
||||
model.isSRC = true
|
||||
resolve(model)
|
||||
})
|
||||
|
@ -3435,7 +3705,7 @@ xrf.frag.src.type['gltf'] = function( url, opts ){
|
|||
let loadHTML = (mimetype) => function(url,opts){
|
||||
let {mesh,src,camera} = opts
|
||||
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")
|
||||
}
|
||||
|
||||
|
@ -3452,6 +3722,8 @@ htmlMimeTypes.map( (mimetype) => xrf.frag.src.type[ mimetype ] = loadHTML(mimet
|
|||
xrf.frag.src.type['image/png'] = function(url,opts){
|
||||
let {mesh,THREE} = opts
|
||||
let restrictTo3DBoundingBox = mesh.geometry
|
||||
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let frag = URL.XRF
|
||||
|
||||
mesh.material = new xrf.THREE.MeshBasicMaterial({
|
||||
map: null,
|
||||
|
@ -3495,7 +3767,7 @@ xrf.frag.src.type['image/png'] = function(url,opts){
|
|||
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 {mesh,src,camera} = opts
|
||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||
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 || {}
|
||||
|
||||
|
@ -3725,7 +3997,7 @@ let loadVideo = (mimetype) => function(url,opts){
|
|||
},false)
|
||||
})
|
||||
|
||||
video.src = url
|
||||
video.src = URL.URN + URL.file
|
||||
video.speed = 1.0
|
||||
video.looping = false
|
||||
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
|
||||
* 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"]};
|
||||
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.parse = function(url,filter) {
|
||||
xrfragment_URI.parseFragment = function(url,filter) {
|
||||
var store = { };
|
||||
if(url == null || url.indexOf("#") == -1) {
|
||||
return store;
|
||||
|
@ -1192,6 +1196,232 @@ xrfragment_URI.template = function(uri,vars) {
|
|||
parts[1] = frag;
|
||||
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) {
|
||||
this.floats = [];
|
||||
this.shift = [];
|
||||
|
@ -1302,6 +1532,7 @@ haxe_Template.hxKeepArrayIterator = new haxe_iterators_ArrayIterator([]);
|
|||
xrfragment_Parser.error = "";
|
||||
xrfragment_Parser.debug = false;
|
||||
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.PROP_BIND = 2;
|
||||
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.match(/#/) ) url = `#${url}`
|
||||
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 isNode = node_or_model && node_or_model.children
|
||||
|
||||
|
@ -1756,24 +1987,6 @@ xrf.reset = () => {
|
|||
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) => {
|
||||
object.isXRF = true // mark for easy deletion when replacing scene
|
||||
xrf.scene.add(object)
|
||||
|
@ -1784,42 +1997,52 @@ xrf.hasNoMaterial = (mesh) => {
|
|||
const hasMaterialName = mesh.material && mesh.material.name.length > 0
|
||||
return mesh.geometry && !hasMaterialName && !hasTexture
|
||||
}
|
||||
xrf.navigator = {}
|
||||
xrf.navigator = {URI:{}}
|
||||
|
||||
xrf.navigator.to = (url,flags,loader,data) => {
|
||||
if( !url ) throw 'xrf.navigator.to(..) no url given'
|
||||
let {urlObj,dir,file,hash,ext} = xrf.navigator.origin = xrf.parseUrl(url)
|
||||
let hashChange = (!file && hash) || !data && xrf.model.file == file
|
||||
let hasPos = String(hash).match(/pos=/)
|
||||
|
||||
let 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) => {
|
||||
xrf
|
||||
.emit('navigate', {url,loader,data})
|
||||
.then( () => {
|
||||
|
||||
if( ext && !loader ){
|
||||
const Loader = xrf.loaders[ext]
|
||||
const Loader = xrf.loaders[fileExt]
|
||||
|
||||
if( fileExt && !loader ){
|
||||
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 ){
|
||||
hashbus.pub( url, xrf.model, flags ) // eval local URI XR fragments
|
||||
xrf.navigator.updateHash(hash) // which don't require
|
||||
return resolve(xrf.model) // positional navigation
|
||||
if( xrf.model && !fileChange && hashChange && !hasPos ){
|
||||
evalFragment()
|
||||
return resolve(xrf.model) // positional navigation
|
||||
}
|
||||
|
||||
xrf
|
||||
.emit('navigateLoading', {url,loader,data})
|
||||
.then( () => {
|
||||
if( hashChange && hasPos ){ // we're already loaded
|
||||
hashbus.pub( url, xrf.model, flags ) // and eval local URI XR fragments
|
||||
xrf.navigator.updateHash(hash)
|
||||
if( (!fileChange || !file) && hashChange && hasPos ){ // we're already loaded
|
||||
evalFragment()
|
||||
xrf.emit('navigateLoaded',{url})
|
||||
return resolve(xrf.model)
|
||||
}
|
||||
|
@ -1829,17 +2052,20 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
xrf.reset()
|
||||
|
||||
// force relative path for files which dont include protocol or relative path
|
||||
if( dir ) dir = dir[0] == '.' || dir.match("://") ? dir : `.${dir}`
|
||||
url = url.replace(dir,"")
|
||||
loader = loader || new Loader().setPath( dir )
|
||||
if( directory ) directory = directory[0] == '.' || directory.match("://") ? directory : `.${directory}`
|
||||
|
||||
loader = loader || new Loader().setPath( URI.URN )
|
||||
const onLoad = (model) => {
|
||||
|
||||
model.file = file
|
||||
model.file = URI.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
|
||||
|
||||
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) )
|
||||
|
||||
|
@ -1850,14 +2076,13 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
if( !model.isSRC ){
|
||||
model.scene.traverse( (mesh) => xrf.parseModel.metadataInMesh(mesh,model) )
|
||||
}
|
||||
|
||||
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
|
||||
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
|
||||
|
||||
xrf.add( model.scene )
|
||||
if( hash ) xrf.navigator.updateHash(hash)
|
||||
if( fragment ) xrf.navigator.updateHash(fragment)
|
||||
xrf.emit('navigateLoaded',{url,model})
|
||||
resolve(model)
|
||||
}
|
||||
|
@ -1866,7 +2091,7 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
loader.parse(data, "", onLoad )
|
||||
}else{
|
||||
try{
|
||||
loader.load(url, onLoad )
|
||||
loader.load(file, onLoad )
|
||||
}catch(e){
|
||||
console.error(e)
|
||||
xrf.emit('navigateError',{url})
|
||||
|
@ -1880,9 +2105,12 @@ xrf.navigator.to = (url,flags,loader,data) => {
|
|||
xrf.navigator.init = () => {
|
||||
if( xrf.navigator.init.inited ) return
|
||||
|
||||
xrf.navigator.URI = xrfragment.URI.parse(document.location.href)
|
||||
|
||||
window.addEventListener('popstate', function (event){
|
||||
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
||||
xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
|
||||
//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) => {
|
||||
let {url} = opts
|
||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||
let {fileExt} = xrfragment.URI.parse(url)
|
||||
|
||||
// handle http links
|
||||
if( url.match(/^http/) && !xrf.loaders[ext] ){
|
||||
if( url.match(/^http/) && !xrf.loaders[fileExt] ){
|
||||
let inIframe
|
||||
try { inIframe = window.self !== window.top; } catch (e) { inIframe = true; }
|
||||
return inIframe ? window.parent.postMessage({ url }, '*') : window.open( url, '_blank')
|
||||
|
@ -1931,7 +2159,7 @@ xrf.navigator.setupNavigateFallbacks = () => {
|
|||
|
||||
xrf.navigator.updateHash = (hash,opts) => {
|
||||
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
|
||||
document.location.hash = hash
|
||||
xrf.navigator.updateHash.active = false
|
||||
|
@ -1942,6 +2170,23 @@ xrf.navigator.pushState = (file,hash) => {
|
|||
window.history.pushState({},`${file}#${hash}`, document.location.pathname + `?${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
|
||||
|
@ -1993,7 +2238,6 @@ xrf.frag.href = function(v, opts){
|
|||
.emit('href',{click:true,mesh,xrf:v}) // let all listeners agree
|
||||
.then( () => {
|
||||
|
||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(v.string)
|
||||
const isLocal = v.string[0] == '#'
|
||||
const hasPos = isLocal && v.string.match(/pos=/)
|
||||
const flags = isLocal ? xrf.XRF.PV_OVERRIDE : undefined
|
||||
|
@ -2153,6 +2397,32 @@ xrf.frag.pos = function(v, opts){
|
|||
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) => {
|
||||
// set the player to position 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
|
||||
|
||||
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.isPortal = xrf.frag.src.renderAsPortal(mesh)
|
||||
opts.isSRC = mesh.isSRC = true
|
||||
|
@ -2294,7 +2564,7 @@ xrf.frag.src.externalSRC = (url,frag,opts) => {
|
|||
fetch(url, { method: 'HEAD' })
|
||||
.then( (res) => {
|
||||
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(/\.(frag|fs|glsl)$/) ) 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 {mesh,src,camera,THREE} = opts
|
||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||
let frag = xrf.URI.parse( url )
|
||||
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let frag = URL.XRF
|
||||
|
||||
xrf.init.audio()
|
||||
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.audio = { set: (mediafragment,v) => mesh.media.audio[mediafragment] = v }
|
||||
|
||||
let finalUrl = url.replace(/#.*/,'')
|
||||
if( xrf.debug != undefined ) console.log("GET "+finalUrl)
|
||||
let finalUrl = URL.URN + URL.file
|
||||
if( xrf.debug > 0 ) console.log("GET "+finalUrl)
|
||||
audioLoader.load( finalUrl, function( 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 ){
|
||||
return new Promise( async (resolve,reject) => {
|
||||
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 {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){
|
||||
let {mesh,THREE} = opts
|
||||
|
||||
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let frag = URL.XRF
|
||||
|
||||
let isFragmentShader = /\.(fs|frag|glsl)$/
|
||||
let isVertexShader = /\.(vs|vert)$/
|
||||
|
||||
let shaderReqs = []
|
||||
let shaderCode = {}
|
||||
let shader = {
|
||||
fragment: { code: '', url: url.match( isFragmentShader ) ? url : '' },
|
||||
vertex: { code: '', url: url.match( isVertexShader ) ? url : '' }
|
||||
fragment: { code: '', url: url.match( isFragmentShader ) ? URL.URN + URL.file : '' },
|
||||
vertex: { code: '', url: url.match( isVertexShader ) ? URL.URN + URL.file : '' }
|
||||
}
|
||||
|
||||
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 ){
|
||||
return new Promise( (resolve,reject) => {
|
||||
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
|
||||
|
||||
const Loader = xrf.loaders[ext]
|
||||
const Loader = xrf.loaders[fileExt]
|
||||
if( !Loader ) throw 'xrfragment: no loader passed to xrfragment for extension .'+ext
|
||||
if( !dir.match("://") ){ // force relative path
|
||||
dir = dir.substr(0,2) == './' ? dir : `./${dir}`
|
||||
loader = new Loader().setPath( dir )
|
||||
}else{
|
||||
loader = new Loader()
|
||||
}
|
||||
loader = new Loader().setPath( URN )
|
||||
|
||||
loader.load(url, (model) => {
|
||||
loader.load(file, (model) => {
|
||||
model.isSRC = true
|
||||
resolve(model)
|
||||
})
|
||||
|
@ -3435,7 +3705,7 @@ xrf.frag.src.type['gltf'] = function( url, opts ){
|
|||
let loadHTML = (mimetype) => function(url,opts){
|
||||
let {mesh,src,camera} = opts
|
||||
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")
|
||||
}
|
||||
|
||||
|
@ -3452,6 +3722,8 @@ htmlMimeTypes.map( (mimetype) => xrf.frag.src.type[ mimetype ] = loadHTML(mimet
|
|||
xrf.frag.src.type['image/png'] = function(url,opts){
|
||||
let {mesh,THREE} = opts
|
||||
let restrictTo3DBoundingBox = mesh.geometry
|
||||
let URL = xrfragment.URI.toAbsolute( xrf.navigator.URI, url )
|
||||
let frag = URL.XRF
|
||||
|
||||
mesh.material = new xrf.THREE.MeshBasicMaterial({
|
||||
map: null,
|
||||
|
@ -3495,7 +3767,7 @@ xrf.frag.src.type['image/png'] = function(url,opts){
|
|||
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 {mesh,src,camera} = opts
|
||||
let {urlObj,dir,file,hash,ext} = xrf.parseUrl(url)
|
||||
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 || {}
|
||||
|
||||
|
@ -3725,7 +3997,7 @@ let loadVideo = (mimetype) => function(url,opts){
|
|||
},false)
|
||||
})
|
||||
|
||||
video.src = url
|
||||
video.src = URL.URN + URL.file
|
||||
video.speed = 1.0
|
||||
video.looping = false
|
||||
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 meshname = this.data.name || this.data;
|
||||
|
||||
if( !meshname || typeof meshname != 'string' ) return
|
||||
|
||||
this.el.addEventListener('update', (evt) => {
|
||||
|
||||
setTimeout( () => {
|
||||
|
@ -46,7 +48,8 @@ window.AFRAME.registerComponent('xrf-get', {
|
|||
this.el.object3D.child = mesh // keep reference (because .children will be empty)
|
||||
|
||||
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)
|
||||
|
||||
})
|
||||
|
|
|
@ -110,7 +110,7 @@ xrf.navigator.init = () => {
|
|||
|
||||
window.addEventListener('popstate', function (event){
|
||||
if( !xrf.navigator.updateHash.active ){ // ignore programmatic hash updates (causes infinite recursion)
|
||||
xrf.navigator.to( document.location.search.substr(1) + document.location.hash )
|
||||
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 }
|
||||
|
||||
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 ) {
|
||||
|
||||
sound.setBuffer( buffer );
|
||||
|
|
|
@ -401,6 +401,8 @@ class URI {
|
|||
|
||||
resultURI.port = url.port;
|
||||
|
||||
resultURI.source = newUrl;
|
||||
|
||||
if (newURI.scheme != null)
|
||||
{
|
||||
resultURI.scheme = newURI.scheme;
|
||||
|
|
|
@ -33,7 +33,7 @@ createScene = (noadd) => {
|
|||
|
||||
filterScene = (URI,opts) => {
|
||||
opts = opts || {}
|
||||
frag = xrf.URI.parse(URI)
|
||||
frag = xrf.URI.parse(URI).XRF
|
||||
var {a,b,c,d,extembed,scene} = createScene()
|
||||
xrf.filter.scene({...opts,scene,frag})
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ console.assert = ((assert) => (a,b) => {
|
|||
/*
|
||||
* 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'})
|
||||
|
||||
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'})
|
||||
|
||||
|
|
Loading…
Reference in New Issue