video & uvscroll now listen to media fragments

This commit is contained in:
Leon van Kammen 2024-02-01 19:10:41 +00:00
parent 774f7fc7ed
commit 0ec1d0dafc
12 changed files with 180 additions and 96 deletions

4
make
View File

@ -53,7 +53,7 @@ server(){
build(){
parser(){
try rm dist/*
try rm dist/xrfragment.*
haxe build.hxml || exit 1
sed -i 's|.*nonlocal .*||g' dist/xrfragment.py
ls -lah dist/*
@ -152,7 +152,7 @@ repos(){
sed -i 's|<script src="https:\/\/aframe.*||g' ../xrfragment-helloworld/index.html
sed -i 's|<script src=".*extras.*||g' ../xrfragment-helloworld/index.html
sed -i 's|<script src=".*blink-controls.*||g' ../xrfragment-helloworld/index.html
sed -i 's|aframe\.js|aframe.all.js|g' ../xrfragment-helloworld/index.html
sed -i 's|aframe\.js|aframe.js|g' ../xrfragment-helloworld/index.html
}
test -z $1 && build

View File

@ -6,7 +6,7 @@ var xrf = {}
xrf.init = function(opts){
opts = opts || {}
xrf.debug = document.location.hostname.match(/^(localhost|[0-9])/) ? true : false
xrf.debug = document.location.hostname.match(/^(localhost|[0-9])/) ? 0 : false
if( !xrf.debug ){
console.log("add #debug=[0-9] to URL to see XR Fragment debuglog")
xrf.debug = parseInt( ( document.location.hash.match(/debug=([0-9])/) || [0,'0'] )[1] )

View File

@ -32,7 +32,7 @@ xrf.addEventListener = function(eventName, callback, opts) {
xrf.emit = function(eventName, data){
if( typeof data != 'object' ) throw 'emit() requires passing objects'
if( xrf.debug && ( !eventName.match(/^render/) || xrf.debug == eventName ) ){
if( xrf.debug && xrf.debug > 1 && ( !eventName.match(/^render/) || xrf.debug == eventName ) ){
let label = String(`xrf.emit('${eventName}')`).padEnd(35," ");
label += data.mesh && data.mesh.name ? '#'+data.mesh.name : ''
console.groupCollapsed(label)

View File

@ -36,7 +36,8 @@ pub.mesh = (mesh,model) => {
pub.fragment = (k, opts ) => { // evaluate one fragment
let frag = opts.frag[k];
if( !opts.skipXRWG && frag.is( xrf.XRF.PV_EXECUTE ) ) pub.XRWG(opts)
let isPVorMediaFrag = frag.is( xrf.XRF.PV_EXECUTE ) || frag.is( xrf.XRF.T_MEDIAFRAG)
if( !opts.skipXRWG && isPVorMediaFrag ) pub.XRWG(opts)
// call native function (xrf/env.js e.g.), or pass it to user decorator
xrf.emit(k,opts)
@ -55,12 +56,11 @@ pub.XRWG = (opts) => {
if( !isSRC ){ // spec : https://xrfragment.org/#src
for ( let i in frag ) {
let v = frag[i]
let id = v.string || v.fragment
let id = v.is( xrf.XRF.T_DYNAMIC ) ? v.fragment : v.string || v.fragment
if( id == '#' || !id ) return
let match = xrf.XRWG.match(id)
if( v.is( xrf.XRF.PV_EXECUTE ) ){
scene.XRF_PV_ORIGIN = v.string
if( v.is( xrf.XRF.PV_EXECUTE ) && !v.is( xrf.XRF.T_DYNAMIC ) ){
// evaluate aliases
match.map( (w) => {
if( w.key == `#${id}` ){

View File

@ -56,12 +56,14 @@ xrf.navigator.to = (url,flags,loader,data) => {
if( !model.isXRF ) xrf.emit('parseModel',{model,url,file}) // loader.load() does this automatically (but not loader.parse)
if(xrf.debug ) model.animations.map( (a) => console.log("anim: "+a.name) )
// spec: 1. generate the XRWG
xrf.XRWG.generate({model,scene:model.scene})
// spec: 2. init metadata inside model for non-SRC data
if( !model.isSRC ){
model.scene.traverse( (mesh) => xrf.hashbus.pub.mesh(mesh,model) )
}
// spec: 1. generate the XRWG
xrf.XRWG.generate({model,scene:model.scene})
// spec: 1. execute the default predefined view '#' (if exist) (https://xrfragment.org/#predefined_view)
xrf.frag.defaultPredefinedViews({model,scene:model.scene})

View File

@ -0,0 +1,37 @@
xrf.mediafragment = {}
xrf.mediafragment.uvscroll = function(mesh,v){
let uv = mesh.geometry.getAttribute("uv")
if( !uv.old ) uv.old = uv.clone()
for( let i = 0; i < uv.count; i++ ){
uv.setXY(i, uv.old.getX(i) + v.x, uv.old.getY(i) + v.y )
}
if( v.speed.length ){
if( mesh.removeUVListener ) mesh.removeUVListener()
mesh.removeUVListener = xrf.addEventListener('render', (opts) => {
let {time} = opts
let speedx = v.speed[0]
let speedy = v.speed.length > 1 ? v.speed[1] : 0;
for( let i = 0; i < uv.count; i++ ){
uv.setXY(i, uv.getX(i) + speedx * time, uv.getY(i) + speedy * time)
}
uv.needsUpdate = true
})
}
uv.needsUpdate = true
}
xrf.addEventListener('dynamicKeyValue', (opts) => {
let {scene,match,v} = opts
if( !v.is( xrf.XRF.T_DYNAMIC ) || v.fragment[0] == '-' ) return
let objname = v.fragment
scene.traverse( (mesh) => {
if( mesh.name == objname ){
if( mesh.video ) return mesh.video.playXRF(v)
//if( mesh.geometry ) return xrf.mediafragment.uvscroll(mesh,v)
}
})
})

View File

@ -1,29 +0,0 @@
xrf.addEventListener('dynamicKeyValue', (opts) => {
let {scene,match,v} = opts
let objname = v.fragment
let autoscroll = v.z > 0 || v.w > 0
scene.traverse( (mesh) => {
if( mesh.name == objname ){
if( !mesh.geometry ) return console.warn(`mesh '${objname}' has no uvcoordinates to offset`)
let uv = mesh.geometry.getAttribute("uv")
if( !uv.old ) uv.old = uv.clone()
for( let i = 0; i < uv.count; i++ ){
uv.setXY(i, uv.old.getX(i) + v.x, uv.old.getY(i) + v.y )
}
if( autoscroll ){
if( mesh.removeUVListener ) mesh.removeUVListener()
mesh.removeUVListener = xrf.addEventListener('render', (opts) => {
let {time} = opts
for( let i = 0; i < uv.count; i++ ){
uv.setXY(i, uv.getX(i) + v.z * time, uv.getY(i) + v.w * time)
}
uv.needsUpdate = true
})
}
uv.needsUpdate = true
}
})
})

View File

@ -15,22 +15,25 @@ let loadVideo = (mimetype) => function(url,opts){
mat.map = texture
mesh.material = mat
// set range
//video.addEventListener('timeupdate', function timeupdate() {
// if (frag.t && video.currentTime < frag.t.y || video.currentTime >= frag.t.z ) {
// video.currentTime = frag.t.y
// }
//},false)
video.addEventListener('timeupdate', function timeupdate() {
if (video.t && video.t.y !== undefined && video.t.y > video.t.x && Math.abs(video.currentTime) >= video.t.y ){
if( video.t.speed.length ) video.currentTime = video.t.x // speed means loop
else video.pause()
}
},false)
})
video.src = url
video.playXRF = (t) => {
video.t = t
if( t.x == 0 ) video.pause()
video.pause()
if( t.x !== undefined && t.x == t.y ) return // stop paused
else{
video.playbackRate = Math.abs( t.x ) // html5 video does not support reverseplay :/
video.currentTime = t.x
video.time = t.x
video.playbackRate = Math.abs( t.speed.length ? t.speed[0] : 1.0 ) // html5 video does not support reverseplay :/
video.play()
}
if( t.y != undefined ) video.time = t.y
}
}
@ -39,9 +42,3 @@ let videoMimeTypes = [
'video/mp4'
]
videoMimeTypes.map( (mimetype) => xrf.frag.src.type[ mimetype ] = loadVideo(mimetype) )
// listen to t XR fragment changes
xrf.addEventListener('t', (opts) => {
let t = opts.frag.t
xrf.scene.traverse( (n) => n.video && (n.video.playXRF(t)) )
})

View File

@ -54,6 +54,7 @@ class Parser {
if( isPVDynamic ){ //|| isPVDefault ){ // 1. add keys without values to store as [predefined view](predefined_view)
var v:XRF = new XRF(key, XRF.PV_EXECUTE | XRF.NAVIGATOR, index );
v.validate(value); // ignore failures (empty values are allowed)
v.flags = XRF.set( XRF.T_DYNAMIC, v.flags );
store.set( keyStripped, v );
return true;
}

View File

@ -33,6 +33,7 @@ class XRF {
public static var T_PREDEFINED_VIEW:Int = 524288;
public static var T_STRING:Int = 1048576;
public static var T_MEDIAFRAG:Int = 2097152;
public static var T_DYNAMIC:Int = 4194304;
// regexes
public static var isColor:EReg = ~/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; // 1. hex colors are detected using regex `/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/`

View File

@ -147,10 +147,7 @@ StringTools.trim = function(s) {
var Test = function() { };
Test.__name__ = true;
Test.main = function() {
Test.test("url.json",[{ fn : "url", expect : { fn : "testPredefinedView", input : "mypredefinedview", out : true}, label : "test predefined view executed", data : "http://foo.com?foo=1#mypredefinedview"},{ fn : "url", expect : { fn : "testPredefinedView", input : "another", out : true}, label : "test predefined view executed (multiple)", data : "http://foo.com?foo=1#mypredefinedview&another"},{ fn : "url", expect : { fn : "testPredefinedView", input : "mypredefinedview", out : true}, label : "test predefined view executed (multiple)", data : "http://foo.com?foo=1#mypredefinedview&another"},{ fn : "url", expect : { fn : "testParsed", input : "mycustom", out : true}, label : "test custom property", data : "http://foo.com?foo=1#mycustom=foo"}]);
Test.test("pos.json",[{ fn : "url", expect : { fn : "equal.string", input : "pos", out : "1.2,2.2"}, label : "equal.string", data : "http://foo.com?foo=1#pos=1.2,2.2"},{ fn : "url", expect : { fn : "equal.xyz", input : "pos", out : "1.2,2.2,3"}, label : "equal.xyz", data : "http://foo.com?foo=1#pos=1.2,2.2,3"},{ fn : "url", expect : { fn : "equal.xyz", input : "pos", out : "1,2,3"}, label : "pos equal.xyz", data : "http://foo.com?foo=1#pos=1,2,3"},{ fn : "url", expect : { fn : "equal.string", input : "pos", out : "world2"}, label : "pos equal.xyz", data : "http://foo.com?foo=1#pos=world2"}]);
Test.test("t.json",[{ fn : "url", expect : { fn : "equal.x", input : "t", out : "1"}, label : "a equal.x", data : "http://foo.com?foo=1#t=1"},{ fn : "url", expect : { fn : "equal.x", input : "t", out : "-1"}, label : "a equal.x", data : "http://foo.com?foo=1#t=-1"},{ fn : "url", expect : { fn : "equal.x", input : "t", out : "-1.02"}, label : "a equal.x", data : "http://foo.com?foo=1#t=-1.02"},{ fn : "url", expect : { fn : "equal.xy", input : "t", out : "1,2"}, label : "a equal.xy", data : "http://foo.com?foo=1#t=1,2,3"},{ fn : "url", expect : { fn : "equal.xyz", input : "t", out : "1,2,3"}, label : "a equal.xyz", data : "http://foo.com?foo=1#t=1,2,3"},{ fn : "url", expect : { fn : "equal.xyz", input : "t", out : "1,-2,3"}, label : "a equal.xyz", data : "http://foo.com?foo=1#t=1,-2,3"},{ fn : "url", expect : { fn : "equal.xy", input : "t", out : "1,100"}, label : "a equal.xy", data : "http://foo.com?foo=1#t=1,100"},{ fn : "url", expect : { fn : "testBrowserOverride", input : "t", out : true}, label : "browser URI can override t (defined in asset)", data : "http://foo.com?foo=1#t=2,500"}]);
Test.test("filter.selectors.json",[{ fn : "url", expect : { fn : "testParsed", input : "myid", out : true}, label : "myid exists", data : "http://foo.com?foo=1#foo*&-sometag&-someid&myid"},{ fn : "url", expect : { fn : "testParsed", input : "tag", out : true}, label : "tag exists", data : "http://foo.com?foo=1#tag=bar"},{ fn : "url", expect : { fn : "testParsed", input : "tag", out : true}, label : "tag exists", data : "http://foo.com?foo=1#-tag=bar"},{ fn : "url", expect : { fn : "testParsed", input : "price", out : true}, label : "filter test", data : "http://foo.com?foo=1#price=>2"},{ fn : "filter", expect : { fn : "testProperty", input : ["tag","bar"], out : true}, data : "tag=bar"},{ fn : "filter", expect : { fn : "testProperty", input : ["tag","foo"], out : false}, data : "-tag=foo"},{ fn : "filter", expect : { fn : "testProperty", input : ["tag","foo"], out : false}, data : "-tag*=foo"},{ fn : "filter", expect : { fn : "testProperty", input : ["tag","3"], out : false}, data : "-tag=>2"},{ fn : "filter", expect : { fn : "testProperty", input : ["price","1"], out : false}, data : "price=>2"},{ fn : "filter", expect : { fn : "testProperty", input : ["price","5"], out : false}, data : "price=<2"},{ fn : "filter", expect : { fn : "testProperty", input : ["price","1"], out : true}, data : "price=<2"},{ fn : "url", expect : { fn : "testFilterDeep", input : ["foo"], out : 1}, label : "foo should be deep", data : "#foo*"},{ fn : "url", expect : { fn : "testFilterDeep", input : ["foo"], out : 2}, label : "foo should be deep incl. embeds", data : "#foo**"}]);
Test.test("t.json",[{ fn : "url", expect : { fn : "equal.x", input : "t", out : "1"}, label : "a equal.x", data : "http://foo.com?foo=1#t=1"},{ fn : "url", expect : { fn : "equal.x", input : "t", out : "-1"}, label : "a equal.x", data : "http://foo.com?foo=1#t=-1"},{ fn : "url", expect : { fn : "equal.x", input : "t", out : "-1.02"}, label : "a equal.x", data : "http://foo.com?foo=1#t=-1.02"},{ fn : "url", expect : { fn : "equal.xy", input : "t", out : "1,2"}, label : "a equal.xy", data : "http://foo.com?foo=1#t=1,2,3"},{ fn : "url", expect : { fn : "equal.xyz", input : "t", out : "1,2,3"}, label : "a equal.xyz", data : "http://foo.com?foo=1#t=1,2,3"},{ fn : "url", expect : { fn : "equal.xyz", input : "t", out : "1,-2,3"}, label : "a equal.xyz", data : "http://foo.com?foo=1#t=1,-2,3"},{ fn : "url", expect : { fn : "equal.xy", input : "t", out : "1,100"}, label : "a equal.xy", data : "http://foo.com?foo=1#t=1,100"},{ fn : "url", expect : { fn : "testBrowserOverride", input : "t", out : true}, label : "browser URI can override t (defined in asset)", data : "http://foo.com?foo=1#t=2,500"},{ fn : "url", expect : { fn : "equal.mediafragment", input : "3", out : "500"}, label : "a equal.mediafragment", data : "http://foo.com?foo=1#t=1,100,400,500*1.2,2.3"},{ fn : "url", expect : { fn : "equal.mediafragmentSpd", input : "1", out : "2.3"}, label : "a equal.mediafragmentSpeed", data : "http://foo.com?foo=1#t=1,100,400,500*1.2,2.3"}]);
if(Test.errors > 1) {
console.log("src/Test.hx:23:","\n-----\n[ ❌] " + Test.errors + " errors :/");
}
@ -211,6 +208,12 @@ Test.test = function(topic,spec) {
if(item.expect.fn == "equal.xyz") {
valid = Test.equalXYZ(res,item);
}
if(item.expect.fn == "equal.mediafragment") {
valid = Test.equalMediaFragment(res,item);
}
if(item.expect.fn == "equal.mediafragmentSpd") {
valid = Test.equalMediaFragmentSpd(res,item);
}
if(item.expect.fn == "testFilterRoot") {
valid = Object.prototype.hasOwnProperty.call(res,item.expect.input[0]) && res[item.expect.input[0]].filter.get().root == item.expect.out;
}
@ -218,7 +221,7 @@ Test.test = function(topic,spec) {
valid = Object.prototype.hasOwnProperty.call(res,item.expect.input[0]) && res[item.expect.input[0]].filter.get().deep == item.expect.out;
}
var ok = valid ? "[ ✔ ] " : "[ ❌] ";
console.log("src/Test.hx:52:",ok + Std.string(item.fn) + ": '" + Std.string(item.data) + "'" + (item.label ? " (" + (item.label ? item.label : item.expect.fn) + ")" : ""));
console.log("src/Test.hx:54:",ok + Std.string(item.fn) + ": '" + Std.string(item.data) + "'" + (item.label ? " (" + (item.label ? item.label : item.expect.fn) + ")" : ""));
if(!valid) {
Test.errors += 1;
}
@ -251,6 +254,20 @@ Test.equalXYZ = function(res,item) {
return false;
}
};
Test.equalMediaFragment = function(res,item) {
if(!item.expect.out && !res[item.expect.input]) {
return true;
} else {
return res["t"].floats[Std.parseInt(item.expect.input)] == Std.parseInt(item.expect.out);
}
};
Test.equalMediaFragmentSpd = function(res,item) {
if(!item.expect.out && !res[item.expect.input]) {
return true;
} else {
return res["t"].speed[Std.parseInt(item.expect.input)] == parseFloat(item.expect.out);
}
};
var haxe_iterators_ArrayIterator = function(array) {
this.current = 0;
this.array = array;
@ -469,10 +486,9 @@ xrfragment_Parser.parse = function(key,value,store,index) {
Frag_h["src"] = xrfragment_XRF.ASSET | xrfragment_XRF.T_URL;
Frag_h["href"] = xrfragment_XRF.ASSET | xrfragment_XRF.T_URL | xrfragment_XRF.T_PREDEFINED_VIEW;
Frag_h["tag"] = xrfragment_XRF.ASSET | xrfragment_XRF.T_STRING;
Frag_h["pos"] = xrfragment_XRF.PV_OVERRIDE | xrfragment_XRF.T_VECTOR3 | xrfragment_XRF.T_STRING | xrfragment_XRF.T_STRING_OBJ | xrfragment_XRF.METADATA | xrfragment_XRF.NAVIGATOR;
Frag_h["pos"] = xrfragment_XRF.PV_OVERRIDE | xrfragment_XRF.T_VECTOR3 | xrfragment_XRF.T_STRING | xrfragment_XRF.METADATA | xrfragment_XRF.NAVIGATOR;
Frag_h["rot"] = xrfragment_XRF.QUERY_OPERATOR | xrfragment_XRF.PV_OVERRIDE | xrfragment_XRF.T_VECTOR3 | xrfragment_XRF.METADATA | xrfragment_XRF.NAVIGATOR;
Frag_h["t"] = xrfragment_XRF.ASSET | xrfragment_XRF.PV_OVERRIDE | xrfragment_XRF.T_FLOAT | xrfragment_XRF.T_VECTOR2 | xrfragment_XRF.T_STRING | xrfragment_XRF.NAVIGATOR | xrfragment_XRF.METADATA;
Frag_h["tv"] = xrfragment_XRF.ASSET | xrfragment_XRF.PV_OVERRIDE | xrfragment_XRF.T_FLOAT | xrfragment_XRF.T_VECTOR2 | xrfragment_XRF.T_VECTOR3 | xrfragment_XRF.NAVIGATOR | xrfragment_XRF.METADATA;
Frag_h["t"] = xrfragment_XRF.ASSET | xrfragment_XRF.PV_OVERRIDE | xrfragment_XRF.T_FLOAT | xrfragment_XRF.T_VECTOR2 | xrfragment_XRF.T_MEDIAFRAG | xrfragment_XRF.NAVIGATOR | xrfragment_XRF.METADATA;
Frag_h["namespace"] = xrfragment_XRF.ASSET | xrfragment_XRF.T_STRING;
Frag_h["SPDX"] = xrfragment_XRF.ASSET | xrfragment_XRF.T_STRING;
Frag_h["unit"] = xrfragment_XRF.ASSET | xrfragment_XRF.T_STRING;
@ -484,6 +500,7 @@ xrfragment_Parser.parse = function(key,value,store,index) {
if(isPVDynamic) {
var v = new xrfragment_XRF(key,xrfragment_XRF.PV_EXECUTE | xrfragment_XRF.NAVIGATOR,index);
v.validate(value);
v.flags = xrfragment_XRF.set(xrfragment_XRF.T_DYNAMIC,v.flags);
store[keyStripped] = v;
return true;
}
@ -544,6 +561,8 @@ xrfragment_URI.parse = function(url,filter) {
return store;
};
var xrfragment_XRF = $hx_exports["xrfragment"]["XRF"] = function(_fragment,_flags,_index) {
this.speed = [];
this.floats = [];
this.fragment = _fragment;
this.flags = _flags;
this.index = _index;
@ -581,18 +600,21 @@ xrfragment_XRF.prototype = {
}
if(str.length > 0) {
if(str.split(",").length > 1) {
var xyzw = str.split(",");
if(xyzw.length > 0) {
v.x = parseFloat(xyzw[0]);
var xyzn = str.split(",");
if(xyzn.length > 0) {
v.x = parseFloat(xyzn[0]);
}
if(xyzw.length > 1) {
v.y = parseFloat(xyzw[1]);
if(xyzn.length > 1) {
v.y = parseFloat(xyzn[1]);
}
if(xyzw.length > 2) {
v.z = parseFloat(xyzw[2]);
if(xyzn.length > 2) {
v.z = parseFloat(xyzn[2]);
}
if(xyzw.length > 3) {
v.w = parseFloat(xyzw[3]);
var _g = 0;
var _g1 = xyzn.length;
while(_g < _g1) {
var i = _g++;
v.floats.push(parseFloat(xyzn[i]));
}
}
if(xrfragment_XRF.isColor.match(str)) {
@ -606,6 +628,19 @@ xrfragment_XRF.prototype = {
v.int = Std.parseInt(str);
v.x = v.int;
}
if(xrfragment_XRF.isMediaFrag.match(str)) {
var speed = str.split("*");
v.speed = [];
if(speed.length > 1) {
var values = speed[1].split(",");
var _g = 0;
var _g1 = values.length;
while(_g < _g1) {
var i = _g++;
v.speed.push(parseFloat(values[i]));
}
}
}
v.filter = new xrfragment_Filter(v.fragment + "=" + v.string);
} else {
v.filter = new xrfragment_Filter(v.fragment);
@ -638,8 +673,8 @@ xrfragment_XRF.T_VECTOR3 = 131072;
xrfragment_XRF.T_URL = 262144;
xrfragment_XRF.T_PREDEFINED_VIEW = 524288;
xrfragment_XRF.T_STRING = 1048576;
xrfragment_XRF.T_STRING_OBJ = 2097152;
xrfragment_XRF.T_STRING_OBJ_PROP = 4194304;
xrfragment_XRF.T_MEDIAFRAG = 2097152;
xrfragment_XRF.T_DYNAMIC = 4194304;
xrfragment_XRF.isColor = new EReg("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$","");
xrfragment_XRF.isInt = new EReg("^[-0-9]+$","");
xrfragment_XRF.isFloat = new EReg("^[-0-9]+\\.[0-9]+$","");
@ -652,6 +687,7 @@ xrfragment_XRF.isProp = new EReg("^.*=[><=]?","");
xrfragment_XRF.isExclude = new EReg("^-","");
xrfragment_XRF.isDeep = new EReg("\\*","");
xrfragment_XRF.isNumber = new EReg("^[0-9\\.]+$","");
xrfragment_XRF.isMediaFrag = new EReg("^[0-9\\.,\\*]+$","");
Test.main();
})({});
var xrfragment = $hx_exports["xrfragment"];

View File

@ -418,14 +418,11 @@ class StringTools:
class Test:
_hx_class_name = "Test"
__slots__ = ()
_hx_statics = ["errors", "main", "test", "equalX", "equalXY", "equalXYZ"]
_hx_statics = ["errors", "main", "test", "equalX", "equalXY", "equalXYZ", "equalMediaFragment", "equalMediaFragmentSpd"]
@staticmethod
def main():
Test.test("url.json",[_hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "testPredefinedView", 'input': "mypredefinedview", 'out': True}), 'label': "test predefined view executed", 'data': "http://foo.com?foo=1#mypredefinedview"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "testPredefinedView", 'input': "another", 'out': True}), 'label': "test predefined view executed (multiple)", 'data': "http://foo.com?foo=1#mypredefinedview&another"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "testPredefinedView", 'input': "mypredefinedview", 'out': True}), 'label': "test predefined view executed (multiple)", 'data': "http://foo.com?foo=1#mypredefinedview&another"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "testParsed", 'input': "mycustom", 'out': True}), 'label': "test custom property", 'data': "http://foo.com?foo=1#mycustom=foo"})])
Test.test("pos.json",[_hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.string", 'input': "pos", 'out': "1.2,2.2"}), 'label': "equal.string", 'data': "http://foo.com?foo=1#pos=1.2,2.2"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.xyz", 'input': "pos", 'out': "1.2,2.2,3"}), 'label': "equal.xyz", 'data': "http://foo.com?foo=1#pos=1.2,2.2,3"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.xyz", 'input': "pos", 'out': "1,2,3"}), 'label': "pos equal.xyz", 'data': "http://foo.com?foo=1#pos=1,2,3"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.string", 'input': "pos", 'out': "world2"}), 'label': "pos equal.xyz", 'data': "http://foo.com?foo=1#pos=world2"})])
Test.test("t.json",[_hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.x", 'input': "t", 'out': "1"}), 'label': "a equal.x", 'data': "http://foo.com?foo=1#t=1"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.x", 'input': "t", 'out': "-1"}), 'label': "a equal.x", 'data': "http://foo.com?foo=1#t=-1"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.x", 'input': "t", 'out': "-1.02"}), 'label': "a equal.x", 'data': "http://foo.com?foo=1#t=-1.02"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.xy", 'input': "t", 'out': "1,2"}), 'label': "a equal.xy", 'data': "http://foo.com?foo=1#t=1,2,3"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.xyz", 'input': "t", 'out': "1,2,3"}), 'label': "a equal.xyz", 'data': "http://foo.com?foo=1#t=1,2,3"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.xyz", 'input': "t", 'out': "1,-2,3"}), 'label': "a equal.xyz", 'data': "http://foo.com?foo=1#t=1,-2,3"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.xy", 'input': "t", 'out': "1,100"}), 'label': "a equal.xy", 'data': "http://foo.com?foo=1#t=1,100"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "testBrowserOverride", 'input': "t", 'out': True}), 'label': "browser URI can override t (defined in asset)", 'data': "http://foo.com?foo=1#t=2,500"})])
Test.test("filter.selectors.json",[_hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "testParsed", 'input': "myid", 'out': True}), 'label': "myid exists", 'data': "http://foo.com?foo=1#foo*&-sometag&-someid&myid"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "testParsed", 'input': "tag", 'out': True}), 'label': "tag exists", 'data': "http://foo.com?foo=1#tag=bar"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "testParsed", 'input': "tag", 'out': True}), 'label': "tag exists", 'data': "http://foo.com?foo=1#-tag=bar"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "testParsed", 'input': "price", 'out': True}), 'label': "filter test", 'data': "http://foo.com?foo=1#price=>2"}), _hx_AnonObject({'fn': "filter", 'expect': _hx_AnonObject({'fn': "testProperty", 'input': ["tag", "bar"], 'out': True}), 'data': "tag=bar"}), _hx_AnonObject({'fn': "filter", 'expect': _hx_AnonObject({'fn': "testProperty", 'input': ["tag", "foo"], 'out': False}), 'data': "-tag=foo"}), _hx_AnonObject({'fn': "filter", 'expect': _hx_AnonObject({'fn': "testProperty", 'input': ["tag", "foo"], 'out': False}), 'data': "-tag*=foo"}), _hx_AnonObject({'fn': "filter", 'expect': _hx_AnonObject({'fn': "testProperty", 'input': ["tag", "3"], 'out': False}), 'data': "-tag=>2"}), _hx_AnonObject({'fn': "filter", 'expect': _hx_AnonObject({'fn': "testProperty", 'input': ["price", "1"], 'out': False}), 'data': "price=>2"}), _hx_AnonObject({'fn': "filter", 'expect': _hx_AnonObject({'fn': "testProperty", 'input': ["price", "5"], 'out': False}), 'data': "price=<2"}), _hx_AnonObject({'fn': "filter", 'expect': _hx_AnonObject({'fn': "testProperty", 'input': ["price", "1"], 'out': True}), 'data': "price=<2"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "testFilterDeep", 'input': ["foo"], 'out': 1}), 'label': "foo should be deep", 'data': "#foo*"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "testFilterDeep", 'input': ["foo"], 'out': 2}), 'label': "foo should be deep incl. embeds", 'data': "#foo**"})])
Test.test("t.json",[_hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.x", 'input': "t", 'out': "1"}), 'label': "a equal.x", 'data': "http://foo.com?foo=1#t=1"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.x", 'input': "t", 'out': "-1"}), 'label': "a equal.x", 'data': "http://foo.com?foo=1#t=-1"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.x", 'input': "t", 'out': "-1.02"}), 'label': "a equal.x", 'data': "http://foo.com?foo=1#t=-1.02"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.xy", 'input': "t", 'out': "1,2"}), 'label': "a equal.xy", 'data': "http://foo.com?foo=1#t=1,2,3"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.xyz", 'input': "t", 'out': "1,2,3"}), 'label': "a equal.xyz", 'data': "http://foo.com?foo=1#t=1,2,3"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.xyz", 'input': "t", 'out': "1,-2,3"}), 'label': "a equal.xyz", 'data': "http://foo.com?foo=1#t=1,-2,3"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.xy", 'input': "t", 'out': "1,100"}), 'label': "a equal.xy", 'data': "http://foo.com?foo=1#t=1,100"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "testBrowserOverride", 'input': "t", 'out': True}), 'label': "browser URI can override t (defined in asset)", 'data': "http://foo.com?foo=1#t=2,500"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.mediafragment", 'input': "3", 'out': "500"}), 'label': "a equal.mediafragment", 'data': "http://foo.com?foo=1#t=1,100,400,500*1.2,2.3"}), _hx_AnonObject({'fn': "url", 'expect': _hx_AnonObject({'fn': "equal.mediafragmentSpd", 'input': "1", 'out': "2.3"}), 'label': "a equal.mediafragmentSpeed", 'data': "http://foo.com?foo=1#t=1,100,400,500*1.2,2.3"})])
if (Test.errors > 1):
print(str((("\n-----\n[ ❌] " + Std.string(Test.errors)) + " errors :/")))
@ -470,6 +467,10 @@ class Test:
valid = Test.equalXY(res,item)
if (Reflect.field(Reflect.field(item,"expect"),"fn") == "equal.xyz"):
valid = Test.equalXYZ(res,item)
if (Reflect.field(Reflect.field(item,"expect"),"fn") == "equal.mediafragment"):
valid = Test.equalMediaFragment(res,item)
if (Reflect.field(Reflect.field(item,"expect"),"fn") == "equal.mediafragmentSpd"):
valid = Test.equalMediaFragmentSpd(res,item)
if (Reflect.field(Reflect.field(item,"expect"),"fn") == "testFilterRoot"):
valid = (python_Boot.hasField(res,HxOverrides.arrayGet(Reflect.field(Reflect.field(item,"expect"),"input"), 0)) and (HxOverrides.eq(Reflect.field(Reflect.field(Reflect.field(Reflect.field(res,HxOverrides.arrayGet(Reflect.field(Reflect.field(item,"expect"),"input"), 0)),"filter"),"get")(),"root"),Reflect.field(Reflect.field(item,"expect"),"out"))))
if (Reflect.field(Reflect.field(item,"expect"),"fn") == "testFilterDeep"):
@ -509,6 +510,20 @@ class Test:
else:
return False
@staticmethod
def equalMediaFragment(res,item):
if ((not Reflect.field(Reflect.field(item,"expect"),"out")) and (not Reflect.field(res,Reflect.field(Reflect.field(item,"expect"),"input")))):
return True
else:
return (HxOverrides.arrayGet(Reflect.field(Reflect.field(res,"t"),"floats"), Std.parseInt(Reflect.field(Reflect.field(item,"expect"),"input"))) == Std.parseInt(Reflect.field(Reflect.field(item,"expect"),"out")))
@staticmethod
def equalMediaFragmentSpd(res,item):
if ((not Reflect.field(Reflect.field(item,"expect"),"out")) and (not Reflect.field(res,Reflect.field(Reflect.field(item,"expect"),"input")))):
return True
else:
return (HxOverrides.arrayGet(Reflect.field(Reflect.field(res,"t"),"speed"), Std.parseInt(Reflect.field(Reflect.field(item,"expect"),"input"))) == Std.parseFloat(Reflect.field(Reflect.field(item,"expect"),"out")))
class haxe_IMap:
_hx_class_name = "haxe.IMap"
@ -1532,8 +1547,8 @@ class xrfragment_Filter:
fails = 0
qualify = 0
def _hx_local_2(expr):
nonlocal conds
nonlocal fails
nonlocal conds
conds = (conds + 1)
fails = (fails + (0 if expr else 1))
return expr
@ -1572,10 +1587,9 @@ class xrfragment_Parser:
Frag.h["src"] = (xrfragment_XRF.ASSET | xrfragment_XRF.T_URL)
Frag.h["href"] = ((xrfragment_XRF.ASSET | xrfragment_XRF.T_URL) | xrfragment_XRF.T_PREDEFINED_VIEW)
Frag.h["tag"] = (xrfragment_XRF.ASSET | xrfragment_XRF.T_STRING)
Frag.h["pos"] = (((((xrfragment_XRF.PV_OVERRIDE | xrfragment_XRF.T_VECTOR3) | xrfragment_XRF.T_STRING) | xrfragment_XRF.T_STRING_OBJ) | xrfragment_XRF.METADATA) | xrfragment_XRF.NAVIGATOR)
Frag.h["pos"] = ((((xrfragment_XRF.PV_OVERRIDE | xrfragment_XRF.T_VECTOR3) | xrfragment_XRF.T_STRING) | xrfragment_XRF.METADATA) | xrfragment_XRF.NAVIGATOR)
Frag.h["rot"] = ((((xrfragment_XRF.QUERY_OPERATOR | xrfragment_XRF.PV_OVERRIDE) | xrfragment_XRF.T_VECTOR3) | xrfragment_XRF.METADATA) | xrfragment_XRF.NAVIGATOR)
Frag.h["t"] = ((((((xrfragment_XRF.ASSET | xrfragment_XRF.PV_OVERRIDE) | xrfragment_XRF.T_FLOAT) | xrfragment_XRF.T_VECTOR2) | xrfragment_XRF.T_STRING) | xrfragment_XRF.NAVIGATOR) | xrfragment_XRF.METADATA)
Frag.h["tv"] = ((((((xrfragment_XRF.ASSET | xrfragment_XRF.PV_OVERRIDE) | xrfragment_XRF.T_FLOAT) | xrfragment_XRF.T_VECTOR2) | xrfragment_XRF.T_VECTOR3) | xrfragment_XRF.NAVIGATOR) | xrfragment_XRF.METADATA)
Frag.h["t"] = ((((((xrfragment_XRF.ASSET | xrfragment_XRF.PV_OVERRIDE) | xrfragment_XRF.T_FLOAT) | xrfragment_XRF.T_VECTOR2) | xrfragment_XRF.T_MEDIAFRAG) | xrfragment_XRF.NAVIGATOR) | xrfragment_XRF.METADATA)
Frag.h["namespace"] = (xrfragment_XRF.ASSET | xrfragment_XRF.T_STRING)
Frag.h["SPDX"] = (xrfragment_XRF.ASSET | xrfragment_XRF.T_STRING)
Frag.h["unit"] = (xrfragment_XRF.ASSET | xrfragment_XRF.T_STRING)
@ -1587,6 +1601,7 @@ class xrfragment_Parser:
if isPVDynamic:
v = xrfragment_XRF(key,(xrfragment_XRF.PV_EXECUTE | xrfragment_XRF.NAVIGATOR),index)
v.validate(value)
v.flags = xrfragment_XRF.set(xrfragment_XRF.T_DYNAMIC,v.flags)
setattr(store,(("_hx_" + keyStripped) if ((keyStripped in python_Boot.keywords)) else (("_hx_" + keyStripped) if (((((len(keyStripped) > 2) and ((ord(keyStripped[0]) == 95))) and ((ord(keyStripped[1]) == 95))) and ((ord(keyStripped[(len(keyStripped) - 1)]) != 95)))) else keyStripped)),v)
return True
v = xrfragment_XRF(key,Frag.h.get(key,None),index)
@ -1652,10 +1667,10 @@ class xrfragment_URI:
class xrfragment_XRF:
_hx_class_name = "xrfragment.XRF"
__slots__ = ("fragment", "flags", "index", "x", "y", "z", "w", "color", "string", "int", "float", "filter", "noXRF")
_hx_fields = ["fragment", "flags", "index", "x", "y", "z", "w", "color", "string", "int", "float", "filter", "noXRF"]
__slots__ = ("fragment", "flags", "index", "x", "y", "z", "floats", "speed", "color", "string", "int", "float", "filter", "noXRF")
_hx_fields = ["fragment", "flags", "index", "x", "y", "z", "floats", "speed", "color", "string", "int", "float", "filter", "noXRF"]
_hx_methods = ["is", "validate", "guessType"]
_hx_statics = ["ASSET", "PROP_BIND", "QUERY_OPERATOR", "PROMPT", "ROUNDROBIN", "NAVIGATOR", "METADATA", "PV_OVERRIDE", "PV_EXECUTE", "T_COLOR", "T_INT", "T_FLOAT", "T_VECTOR2", "T_VECTOR3", "T_URL", "T_PREDEFINED_VIEW", "T_STRING", "T_STRING_OBJ", "T_STRING_OBJ_PROP", "isColor", "isInt", "isFloat", "isVector", "isUrl", "isUrlOrPretypedView", "isString", "operators", "isProp", "isExclude", "isDeep", "isNumber", "set", "unset"]
_hx_statics = ["ASSET", "PROP_BIND", "QUERY_OPERATOR", "PROMPT", "ROUNDROBIN", "NAVIGATOR", "METADATA", "PV_OVERRIDE", "PV_EXECUTE", "T_COLOR", "T_INT", "T_FLOAT", "T_VECTOR2", "T_VECTOR3", "T_URL", "T_PREDEFINED_VIEW", "T_STRING", "T_MEDIAFRAG", "T_DYNAMIC", "isColor", "isInt", "isFloat", "isVector", "isUrl", "isUrlOrPretypedView", "isString", "operators", "isProp", "isExclude", "isDeep", "isNumber", "isMediaFrag", "set", "unset"]
def __init__(self,_fragment,_flags,_index = None):
self.noXRF = None
@ -1664,10 +1679,11 @@ class xrfragment_XRF:
self.int = None
self.string = None
self.color = None
self.w = None
self.z = None
self.y = None
self.x = None
self.speed = list()
self.floats = list()
self.fragment = _fragment
self.flags = _flags
self.index = _index
@ -1692,15 +1708,21 @@ class xrfragment_XRF:
return
if (len(_hx_str) > 0):
if (len(_hx_str.split(",")) > 1):
xyzw = _hx_str.split(",")
if (len(xyzw) > 0):
v.x = Std.parseFloat((xyzw[0] if 0 < len(xyzw) else None))
if (len(xyzw) > 1):
v.y = Std.parseFloat((xyzw[1] if 1 < len(xyzw) else None))
if (len(xyzw) > 2):
v.z = Std.parseFloat((xyzw[2] if 2 < len(xyzw) else None))
if (len(xyzw) > 3):
v.w = Std.parseFloat((xyzw[3] if 3 < len(xyzw) else None))
xyzn = _hx_str.split(",")
if (len(xyzn) > 0):
v.x = Std.parseFloat((xyzn[0] if 0 < len(xyzn) else None))
if (len(xyzn) > 1):
v.y = Std.parseFloat((xyzn[1] if 1 < len(xyzn) else None))
if (len(xyzn) > 2):
v.z = Std.parseFloat((xyzn[2] if 2 < len(xyzn) else None))
_g = 0
_g1 = len(xyzn)
while (_g < _g1):
i = _g
_g = (_g + 1)
_this = v.floats
x = Std.parseFloat((xyzn[i] if i >= 0 and i < len(xyzn) else None))
_this.append(x)
_this = xrfragment_XRF.isColor
_this.matchObj = python_lib_Re.search(_this.pattern,_hx_str)
if (_this.matchObj is not None):
@ -1715,6 +1737,22 @@ class xrfragment_XRF:
if (_this.matchObj is not None):
v.int = Std.parseInt(_hx_str)
v.x = v.int
_this = xrfragment_XRF.isMediaFrag
_this.matchObj = python_lib_Re.search(_this.pattern,_hx_str)
if (_this.matchObj is not None):
speed = _hx_str.split("*")
v.speed = list()
if (len(speed) > 1):
_this = (speed[1] if 1 < len(speed) else None)
values = _this.split(",")
_g = 0
_g1 = len(values)
while (_g < _g1):
i = _g
_g = (_g + 1)
_this = v.speed
x = Std.parseFloat((values[i] if i >= 0 and i < len(values) else None))
_this.append(x)
v.filter = xrfragment_Filter(((HxOverrides.stringOrNull(v.fragment) + "=") + HxOverrides.stringOrNull(v.string)))
else:
v.filter = xrfragment_Filter(v.fragment)
@ -1755,8 +1793,8 @@ xrfragment_XRF.T_VECTOR3 = 131072
xrfragment_XRF.T_URL = 262144
xrfragment_XRF.T_PREDEFINED_VIEW = 524288
xrfragment_XRF.T_STRING = 1048576
xrfragment_XRF.T_STRING_OBJ = 2097152
xrfragment_XRF.T_STRING_OBJ_PROP = 4194304
xrfragment_XRF.T_MEDIAFRAG = 2097152
xrfragment_XRF.T_DYNAMIC = 4194304
xrfragment_XRF.isColor = EReg("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$","")
xrfragment_XRF.isInt = EReg("^[-0-9]+$","")
xrfragment_XRF.isFloat = EReg("^[-0-9]+\\.[0-9]+$","")
@ -1769,5 +1807,6 @@ xrfragment_XRF.isProp = EReg("^.*=[><=]?","")
xrfragment_XRF.isExclude = EReg("^-","")
xrfragment_XRF.isDeep = EReg("\\*","")
xrfragment_XRF.isNumber = EReg("^[0-9\\.]+$","")
xrfragment_XRF.isMediaFrag = EReg("^[0-9\\.,\\*]+$","")
Test.main()