removed += from spec + added / root-selector to spec

This commit is contained in:
Leon van Kammen 2023-06-20 14:59:25 +02:00
parent b01d0e57d9
commit e3cf693fa7
11 changed files with 154 additions and 111 deletions

View File

@ -265,7 +265,7 @@ xrfragment_Parser.parse = function(key,value,resultMap) {
var xrfragment_Query = $hx_exports["xrfragment"]["Query"] = function(str) {
this.isNumber = new EReg("^[0-9\\.]+$","");
this.isClass = new EReg("^[-]?class$","");
this.isAddition = new EReg("^\\+","");
this.isRoot = new EReg("^/","");
this.isExclude = new EReg("^-","");
this.isProp = new EReg("^.*:[><=!]?","");
this.q = { };
@ -329,9 +329,6 @@ xrfragment_Query.prototype = {
if(_gthis.isExclude.match(k)) {
oper = "!=";
k = HxOverrides.substr(k,1,null);
} else if(_gthis.isAddition.match(k)) {
oper = "+=";
k = HxOverrides.substr(k,1,null);
} else {
v = HxOverrides.substr(v,oper.length,null);
}
@ -353,6 +350,12 @@ xrfragment_Query.prototype = {
}
return;
} else {
if(_gthis.isRoot.match(k)) {
str = HxOverrides.substr(k,1,null);
filter["root"] = true;
} else if(filter["root"] == true) {
Reflect.deleteField(filter,"root");
}
filter["id"] = _gthis.isExclude.match(str) ? false : true;
var key = _gthis.isExclude.match(str) ? HxOverrides.substr(str,1,null) : str;
q[key] = filter;
@ -1066,7 +1069,7 @@ xrf.frag.href = function(v, opts){
quat: new THREE.Quaternion()
}
// detect equirectangular image
let texture = mesh.material.map
let texture = mesh.material && mesh.material.map ? mesh.material.map : null
if( texture && texture.source.data.height == texture.source.data.width/2 ){
texture.mapping = THREE.ClampToEdgeWrapping
texture.needsUpdate = true
@ -1113,7 +1116,7 @@ xrf.frag.href = function(v, opts){
`,
});
mesh.material.needsUpdate = true
}else mesh.material = mesh.material.clone()
}else if( mesh.material){ mesh.material = mesh.material.clone() }
let click = mesh.userData.XRF.href.exec = (e) => {
xrf
@ -1128,8 +1131,10 @@ xrf.frag.href = function(v, opts){
let selected = (state) => () => {
if( mesh.selected == state ) return // nothing changed
if( mesh.material.uniforms ) mesh.material.uniforms.selected.value = state
else mesh.material.color.r = mesh.material.color.g = mesh.material.color.b = state ? 2.0 : 1.0
if( mesh.material ){
if( mesh.material.uniforms ) mesh.material.uniforms.selected.value = state
else mesh.material.color.r = mesh.material.color.g = mesh.material.color.b = state ? 2.0 : 1.0
}
// update mouse cursor
if( !renderer.domElement.lastCursor )
renderer.domElement.lastCursor = renderer.domElement.style.cursor
@ -1181,11 +1186,12 @@ const doPredefinedView = (opts) => {
const selectionOfInterest = (frag,scene,mesh) => {
let id = frag.string
// Selection of Interest if predefined_view matches object name
if(!id) return id // important: ignore empty strings
if( mesh.selection ){
scene.remove(mesh.selection)
delete mesh.selection
}
// Selection of Interest if predefined_view matches object name
if( id == mesh.name || id.substr(1) == mesh.userData.class ){
xrf.emit('selection',{...opts,frag})
.then( () => {
@ -1202,9 +1208,10 @@ const doPredefinedView = (opts) => {
}
const predefinedView = (frag,scene,mesh) => {
let id = frag.string
if( mesh.userData[`#${id}`] ){
let frag = xrf.URI.parse( mesh.userData[id], xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.EMBEDDED )
let id = frag.string
if( !id ) return // prevent empty matches
if( mesh.userData[`#${id}`] ){ // get alias
frag = xrf.URI.parse( mesh.userData[`#${id}`], xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.EMBEDDED )
for ( let k in frag ){
let opts = {frag, model, camera: xrf.camera, scene: xrf.scene, renderer: xrf.renderer, THREE: xrf.THREE }
xrf.emit('predefinedView',{...opts,frag})
@ -1271,14 +1278,14 @@ xrf.frag.q = function(v, opts){
target.mesh.rotation.set(0,0,0)
}
}
// remove negative selectors
let remove = []
// hide negative selectors
let negative = []
v.scene.traverse( (mesh) => {
for ( let i in v.query ) {
if( mesh.name == i && v.query[i].id === false ) remove.push(mesh)
if( mesh.name == i && v.query[i].id === false ) negative.push(mesh)
}
})
remove.map( (mesh) => mesh.parent.remove( mesh ) )
negative.map( (mesh) => mesh.visible = false )
}
const showHide = () => {
@ -1326,7 +1333,7 @@ xrf.frag.src = function(v, opts){
xrf.eval.fragment(i, Object.assign(opts,{frag, model,scene}))
}
if( frag.q.query ){
let srcScene = frag.q.scene
let srcScene = frag.q.scene // three/xrf/q.js initializes .scene
if( !srcScene || !srcScene.visible ) return
console.log(" └ inserting "+i+" (srcScene)")
srcScene.position.set(0,0,0)
@ -1334,6 +1341,7 @@ xrf.frag.src = function(v, opts){
srcScene.traverse( (m) => {
if( m.userData && (m.userData.src || m.userData.href) ) return ;//delete m.userData.src // prevent infinite recursion
xrf.eval.mesh(m,{scene,recursive:true})
m.name = mesh.name+"."+m.name // prefix meshname so predefined views don't affect objectnames anymore
})
if( srcScene.visible ) src.add( srcScene )
}

11
dist/xrfragment.js vendored
View File

@ -265,7 +265,7 @@ xrfragment_Parser.parse = function(key,value,resultMap) {
var xrfragment_Query = $hx_exports["xrfragment"]["Query"] = function(str) {
this.isNumber = new EReg("^[0-9\\.]+$","");
this.isClass = new EReg("^[-]?class$","");
this.isAddition = new EReg("^\\+","");
this.isRoot = new EReg("^/","");
this.isExclude = new EReg("^-","");
this.isProp = new EReg("^.*:[><=!]?","");
this.q = { };
@ -329,9 +329,6 @@ xrfragment_Query.prototype = {
if(_gthis.isExclude.match(k)) {
oper = "!=";
k = HxOverrides.substr(k,1,null);
} else if(_gthis.isAddition.match(k)) {
oper = "+=";
k = HxOverrides.substr(k,1,null);
} else {
v = HxOverrides.substr(v,oper.length,null);
}
@ -353,6 +350,12 @@ xrfragment_Query.prototype = {
}
return;
} else {
if(_gthis.isRoot.match(k)) {
str = HxOverrides.substr(k,1,null);
filter["root"] = true;
} else if(filter["root"] == true) {
Reflect.deleteField(filter,"root");
}
filter["id"] = _gthis.isExclude.match(str) ? false : true;
var key = _gthis.isExclude.match(str) ? HxOverrides.substr(str,1,null) : str;
q[key] = filter;

71
dist/xrfragment.lua vendored
View File

@ -1633,7 +1633,7 @@ end
__xrfragment_Query.super = function(self,str)
self.isNumber = EReg.new("^[0-9\\.]+$", "");
self.isClass = EReg.new("^[-]?class$", "");
self.isAddition = EReg.new("^\\+", "");
self.isRoot = EReg.new("^/", "");
self.isExclude = EReg.new("^-", "");
self.isProp = EReg.new("^.*:[><=!]?", "");
self.q = _hx_e();
@ -1852,42 +1852,22 @@ __xrfragment_Query.prototype.parse = function(self,str,recurse)
end;
k = __lua_lib_luautf8_Utf8.sub(k, pos + 1, pos + len);
else
if (_gthis.isAddition:match(k)) then
oper = "+=";
local pos = 1;
local len = nil;
if ((len == nil) or (len > (pos + __lua_lib_luautf8_Utf8.len(k)))) then
len = __lua_lib_luautf8_Utf8.len(k);
else
if (len < 0) then
len = __lua_lib_luautf8_Utf8.len(k) + len;
end;
end;
if (pos < 0) then
pos = __lua_lib_luautf8_Utf8.len(k) + pos;
end;
if (pos < 0) then
pos = 0;
end;
k = __lua_lib_luautf8_Utf8.sub(k, pos + 1, pos + len);
local pos = __lua_lib_luautf8_Utf8.len(oper);
local len = nil;
if ((len == nil) or (len > (pos + __lua_lib_luautf8_Utf8.len(v)))) then
len = __lua_lib_luautf8_Utf8.len(v);
else
local pos = __lua_lib_luautf8_Utf8.len(oper);
local len = nil;
if ((len == nil) or (len > (pos + __lua_lib_luautf8_Utf8.len(v)))) then
len = __lua_lib_luautf8_Utf8.len(v);
else
if (len < 0) then
len = __lua_lib_luautf8_Utf8.len(v) + len;
end;
if (len < 0) then
len = __lua_lib_luautf8_Utf8.len(v) + len;
end;
if (pos < 0) then
pos = __lua_lib_luautf8_Utf8.len(v) + pos;
end;
if (pos < 0) then
pos = 0;
end;
v = __lua_lib_luautf8_Utf8.sub(v, pos + 1, pos + len);
end;
if (pos < 0) then
pos = __lua_lib_luautf8_Utf8.len(v) + pos;
end;
if (pos < 0) then
pos = 0;
end;
v = __lua_lib_luautf8_Utf8.sub(v, pos + 1, pos + len);
end;
if (__lua_lib_luautf8_Utf8.len(oper) == 0) then
oper = "=";
@ -1909,6 +1889,29 @@ __xrfragment_Query.prototype.parse = function(self,str,recurse)
end;
do return end;
else
if (_gthis.isRoot:match(k)) then
local pos = 1;
local len = nil;
if ((len == nil) or (len > (pos + __lua_lib_luautf8_Utf8.len(k)))) then
len = __lua_lib_luautf8_Utf8.len(k);
else
if (len < 0) then
len = __lua_lib_luautf8_Utf8.len(k) + len;
end;
end;
if (pos < 0) then
pos = __lua_lib_luautf8_Utf8.len(k) + pos;
end;
if (pos < 0) then
pos = 0;
end;
str = __lua_lib_luautf8_Utf8.sub(k, pos + 1, pos + len);
filter.root = true;
else
if (Reflect.field(filter, "root") == true) then
Reflect.deleteField(filter, "root");
end;
end;
local value = (function()
local _hx_7
if (_gthis.isExclude:match(str)) then

View File

@ -265,7 +265,7 @@ xrfragment_Parser.parse = function(key,value,resultMap) {
var xrfragment_Query = $hx_exports["xrfragment"]["Query"] = function(str) {
this.isNumber = new EReg("^[0-9\\.]+$","");
this.isClass = new EReg("^[-]?class$","");
this.isAddition = new EReg("^\\+","");
this.isRoot = new EReg("^/","");
this.isExclude = new EReg("^-","");
this.isProp = new EReg("^.*:[><=!]?","");
this.q = { };
@ -329,9 +329,6 @@ xrfragment_Query.prototype = {
if(_gthis.isExclude.match(k)) {
oper = "!=";
k = HxOverrides.substr(k,1,null);
} else if(_gthis.isAddition.match(k)) {
oper = "+=";
k = HxOverrides.substr(k,1,null);
} else {
v = HxOverrides.substr(v,oper.length,null);
}
@ -353,6 +350,12 @@ xrfragment_Query.prototype = {
}
return;
} else {
if(_gthis.isRoot.match(k)) {
str = HxOverrides.substr(k,1,null);
filter["root"] = true;
} else if(filter["root"] == true) {
Reflect.deleteField(filter,"root");
}
filter["id"] = _gthis.isExclude.match(str) ? false : true;
var key = _gthis.isExclude.match(str) ? HxOverrides.substr(str,1,null) : str;
q[key] = filter;

21
dist/xrfragment.py vendored
View File

@ -1338,14 +1338,14 @@ class xrfragment_Parser:
class xrfragment_Query:
_hx_class_name = "xrfragment.Query"
__slots__ = ("str", "q", "isProp", "isExclude", "isAddition", "isClass", "isNumber")
_hx_fields = ["str", "q", "isProp", "isExclude", "isAddition", "isClass", "isNumber"]
__slots__ = ("str", "q", "isProp", "isExclude", "isRoot", "isClass", "isNumber")
_hx_fields = ["str", "q", "isProp", "isExclude", "isRoot", "isClass", "isNumber"]
_hx_methods = ["toObject", "expandAliases", "get", "parse", "test", "testProperty"]
def __init__(self,_hx_str):
self.isNumber = EReg("^[0-9\\.]+$","")
self.isClass = EReg("^[-]?class$","")
self.isAddition = EReg("^\\+","")
self.isRoot = EReg("^/","")
self.isExclude = EReg("^-","")
self.isProp = EReg("^.*:[><=!]?","")
self.q = _hx_AnonObject({})
@ -1409,13 +1409,7 @@ class xrfragment_Query:
oper = "!="
k = HxString.substr(k,1,None)
else:
_this = _gthis.isAddition
_this.matchObj = python_lib_Re.search(_this.pattern,k)
if (_this.matchObj is not None):
oper = "+="
k = HxString.substr(k,1,None)
else:
v = HxString.substr(v,len(oper),None)
v = HxString.substr(v,len(oper),None)
if (len(oper) == 0):
oper = "="
_this = _gthis.isClass
@ -1438,6 +1432,13 @@ class xrfragment_Query:
setattr(q,(("_hx_" + k) if ((k in python_Boot.keywords)) else (("_hx_" + k) if (((((len(k) > 2) and ((ord(k[0]) == 95))) and ((ord(k[1]) == 95))) and ((ord(k[(len(k) - 1)]) != 95)))) else k)),_hx_filter)
return
else:
_this = _gthis.isRoot
_this.matchObj = python_lib_Re.search(_this.pattern,k)
if (_this.matchObj is not None):
_hx_str = HxString.substr(k,1,None)
setattr(_hx_filter,(("_hx_" + "root") if (("root" in python_Boot.keywords)) else (("_hx_" + "root") if (((((len("root") > 2) and ((ord("root"[0]) == 95))) and ((ord("root"[1]) == 95))) and ((ord("root"[(len("root") - 1)]) != 95)))) else "root")),True)
elif (Reflect.field(_hx_filter,"root") == True):
Reflect.deleteField(_hx_filter,"root")
_this = _gthis.isExclude
_this.matchObj = python_lib_Re.search(_this.pattern,_hx_str)
value = (False if ((_this.matchObj is not None)) else True)

View File

@ -265,7 +265,7 @@ xrfragment_Parser.parse = function(key,value,resultMap) {
var xrfragment_Query = $hx_exports["xrfragment"]["Query"] = function(str) {
this.isNumber = new EReg("^[0-9\\.]+$","");
this.isClass = new EReg("^[-]?class$","");
this.isAddition = new EReg("^\\+","");
this.isRoot = new EReg("^/","");
this.isExclude = new EReg("^-","");
this.isProp = new EReg("^.*:[><=!]?","");
this.q = { };
@ -329,9 +329,6 @@ xrfragment_Query.prototype = {
if(_gthis.isExclude.match(k)) {
oper = "!=";
k = HxOverrides.substr(k,1,null);
} else if(_gthis.isAddition.match(k)) {
oper = "+=";
k = HxOverrides.substr(k,1,null);
} else {
v = HxOverrides.substr(v,oper.length,null);
}
@ -353,6 +350,12 @@ xrfragment_Query.prototype = {
}
return;
} else {
if(_gthis.isRoot.match(k)) {
str = HxOverrides.substr(k,1,null);
filter["root"] = true;
} else if(filter["root"] == true) {
Reflect.deleteField(filter,"root");
}
filter["id"] = _gthis.isExclude.match(str) ? false : true;
var key = _gthis.isExclude.match(str) ? HxOverrides.substr(str,1,null) : str;
q[key] = filter;
@ -1066,7 +1069,7 @@ xrf.frag.href = function(v, opts){
quat: new THREE.Quaternion()
}
// detect equirectangular image
let texture = mesh.material.map
let texture = mesh.material && mesh.material.map ? mesh.material.map : null
if( texture && texture.source.data.height == texture.source.data.width/2 ){
texture.mapping = THREE.ClampToEdgeWrapping
texture.needsUpdate = true
@ -1113,7 +1116,7 @@ xrf.frag.href = function(v, opts){
`,
});
mesh.material.needsUpdate = true
}else mesh.material = mesh.material.clone()
}else if( mesh.material){ mesh.material = mesh.material.clone() }
let click = mesh.userData.XRF.href.exec = (e) => {
xrf
@ -1128,8 +1131,10 @@ xrf.frag.href = function(v, opts){
let selected = (state) => () => {
if( mesh.selected == state ) return // nothing changed
if( mesh.material.uniforms ) mesh.material.uniforms.selected.value = state
else mesh.material.color.r = mesh.material.color.g = mesh.material.color.b = state ? 2.0 : 1.0
if( mesh.material ){
if( mesh.material.uniforms ) mesh.material.uniforms.selected.value = state
else mesh.material.color.r = mesh.material.color.g = mesh.material.color.b = state ? 2.0 : 1.0
}
// update mouse cursor
if( !renderer.domElement.lastCursor )
renderer.domElement.lastCursor = renderer.domElement.style.cursor
@ -1181,11 +1186,12 @@ const doPredefinedView = (opts) => {
const selectionOfInterest = (frag,scene,mesh) => {
let id = frag.string
// Selection of Interest if predefined_view matches object name
if(!id) return id // important: ignore empty strings
if( mesh.selection ){
scene.remove(mesh.selection)
delete mesh.selection
}
// Selection of Interest if predefined_view matches object name
if( id == mesh.name || id.substr(1) == mesh.userData.class ){
xrf.emit('selection',{...opts,frag})
.then( () => {
@ -1202,9 +1208,10 @@ const doPredefinedView = (opts) => {
}
const predefinedView = (frag,scene,mesh) => {
let id = frag.string
if( mesh.userData[`#${id}`] ){
let frag = xrf.URI.parse( mesh.userData[id], xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.EMBEDDED )
let id = frag.string
if( !id ) return // prevent empty matches
if( mesh.userData[`#${id}`] ){ // get alias
frag = xrf.URI.parse( mesh.userData[`#${id}`], xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.EMBEDDED )
for ( let k in frag ){
let opts = {frag, model, camera: xrf.camera, scene: xrf.scene, renderer: xrf.renderer, THREE: xrf.THREE }
xrf.emit('predefinedView',{...opts,frag})
@ -1271,14 +1278,14 @@ xrf.frag.q = function(v, opts){
target.mesh.rotation.set(0,0,0)
}
}
// remove negative selectors
let remove = []
// hide negative selectors
let negative = []
v.scene.traverse( (mesh) => {
for ( let i in v.query ) {
if( mesh.name == i && v.query[i].id === false ) remove.push(mesh)
if( mesh.name == i && v.query[i].id === false ) negative.push(mesh)
}
})
remove.map( (mesh) => mesh.parent.remove( mesh ) )
negative.map( (mesh) => mesh.visible = false )
}
const showHide = () => {
@ -1326,7 +1333,7 @@ xrf.frag.src = function(v, opts){
xrf.eval.fragment(i, Object.assign(opts,{frag, model,scene}))
}
if( frag.q.query ){
let srcScene = frag.q.scene
let srcScene = frag.q.scene // three/xrf/q.js initializes .scene
if( !srcScene || !srcScene.visible ) return
console.log(" └ inserting "+i+" (srcScene)")
srcScene.position.set(0,0,0)
@ -1334,6 +1341,7 @@ xrf.frag.src = function(v, opts){
srcScene.traverse( (m) => {
if( m.userData && (m.userData.src || m.userData.href) ) return ;//delete m.userData.src // prevent infinite recursion
xrf.eval.mesh(m,{scene,recursive:true})
m.name = mesh.name+"."+m.name // prefix meshname so predefined views don't affect objectnames anymore
})
if( srcScene.visible ) src.add( srcScene )
}

View File

@ -265,7 +265,7 @@ xrfragment_Parser.parse = function(key,value,resultMap) {
var xrfragment_Query = $hx_exports["xrfragment"]["Query"] = function(str) {
this.isNumber = new EReg("^[0-9\\.]+$","");
this.isClass = new EReg("^[-]?class$","");
this.isAddition = new EReg("^\\+","");
this.isRoot = new EReg("^/","");
this.isExclude = new EReg("^-","");
this.isProp = new EReg("^.*:[><=!]?","");
this.q = { };
@ -329,9 +329,6 @@ xrfragment_Query.prototype = {
if(_gthis.isExclude.match(k)) {
oper = "!=";
k = HxOverrides.substr(k,1,null);
} else if(_gthis.isAddition.match(k)) {
oper = "+=";
k = HxOverrides.substr(k,1,null);
} else {
v = HxOverrides.substr(v,oper.length,null);
}
@ -353,6 +350,12 @@ xrfragment_Query.prototype = {
}
return;
} else {
if(_gthis.isRoot.match(k)) {
str = HxOverrides.substr(k,1,null);
filter["root"] = true;
} else if(filter["root"] == true) {
Reflect.deleteField(filter,"root");
}
filter["id"] = _gthis.isExclude.match(str) ? false : true;
var key = _gthis.isExclude.match(str) ? HxOverrides.substr(str,1,null) : str;
q[key] = filter;
@ -1066,7 +1069,7 @@ xrf.frag.href = function(v, opts){
quat: new THREE.Quaternion()
}
// detect equirectangular image
let texture = mesh.material.map
let texture = mesh.material && mesh.material.map ? mesh.material.map : null
if( texture && texture.source.data.height == texture.source.data.width/2 ){
texture.mapping = THREE.ClampToEdgeWrapping
texture.needsUpdate = true
@ -1113,7 +1116,7 @@ xrf.frag.href = function(v, opts){
`,
});
mesh.material.needsUpdate = true
}else mesh.material = mesh.material.clone()
}else if( mesh.material){ mesh.material = mesh.material.clone() }
let click = mesh.userData.XRF.href.exec = (e) => {
xrf
@ -1128,8 +1131,10 @@ xrf.frag.href = function(v, opts){
let selected = (state) => () => {
if( mesh.selected == state ) return // nothing changed
if( mesh.material.uniforms ) mesh.material.uniforms.selected.value = state
else mesh.material.color.r = mesh.material.color.g = mesh.material.color.b = state ? 2.0 : 1.0
if( mesh.material ){
if( mesh.material.uniforms ) mesh.material.uniforms.selected.value = state
else mesh.material.color.r = mesh.material.color.g = mesh.material.color.b = state ? 2.0 : 1.0
}
// update mouse cursor
if( !renderer.domElement.lastCursor )
renderer.domElement.lastCursor = renderer.domElement.style.cursor
@ -1181,11 +1186,12 @@ const doPredefinedView = (opts) => {
const selectionOfInterest = (frag,scene,mesh) => {
let id = frag.string
// Selection of Interest if predefined_view matches object name
if(!id) return id // important: ignore empty strings
if( mesh.selection ){
scene.remove(mesh.selection)
delete mesh.selection
}
// Selection of Interest if predefined_view matches object name
if( id == mesh.name || id.substr(1) == mesh.userData.class ){
xrf.emit('selection',{...opts,frag})
.then( () => {
@ -1202,9 +1208,10 @@ const doPredefinedView = (opts) => {
}
const predefinedView = (frag,scene,mesh) => {
let id = frag.string
if( mesh.userData[`#${id}`] ){
let frag = xrf.URI.parse( mesh.userData[id], xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.EMBEDDED )
let id = frag.string
if( !id ) return // prevent empty matches
if( mesh.userData[`#${id}`] ){ // get alias
frag = xrf.URI.parse( mesh.userData[`#${id}`], xrf.XRF.NAVIGATOR | xrf.XRF.PV_OVERRIDE | xrf.XRF.EMBEDDED )
for ( let k in frag ){
let opts = {frag, model, camera: xrf.camera, scene: xrf.scene, renderer: xrf.renderer, THREE: xrf.THREE }
xrf.emit('predefinedView',{...opts,frag})
@ -1271,14 +1278,14 @@ xrf.frag.q = function(v, opts){
target.mesh.rotation.set(0,0,0)
}
}
// remove negative selectors
let remove = []
// hide negative selectors
let negative = []
v.scene.traverse( (mesh) => {
for ( let i in v.query ) {
if( mesh.name == i && v.query[i].id === false ) remove.push(mesh)
if( mesh.name == i && v.query[i].id === false ) negative.push(mesh)
}
})
remove.map( (mesh) => mesh.parent.remove( mesh ) )
negative.map( (mesh) => mesh.visible = false )
}
const showHide = () => {
@ -1326,7 +1333,7 @@ xrf.frag.src = function(v, opts){
xrf.eval.fragment(i, Object.assign(opts,{frag, model,scene}))
}
if( frag.q.query ){
let srcScene = frag.q.scene
let srcScene = frag.q.scene // three/xrf/q.js initializes .scene
if( !srcScene || !srcScene.visible ) return
console.log(" └ inserting "+i+" (srcScene)")
srcScene.position.set(0,0,0)
@ -1334,6 +1341,7 @@ xrf.frag.src = function(v, opts){
srcScene.traverse( (m) => {
if( m.userData && (m.userData.src || m.userData.href) ) return ;//delete m.userData.src // prevent infinite recursion
xrf.eval.mesh(m,{scene,recursive:true})
m.name = mesh.name+"."+m.name // prefix meshname so predefined views don't affect objectnames anymore
})
if( srcScene.visible ) src.add( srcScene )
}

View File

@ -16,7 +16,8 @@ class Test {
static public function main():Void {
test( Spec.load("src/spec/url.json") );
test( Spec.load("src/spec/query.class.json") );
test( Spec.load("src/spec/query.selectors.json") );
test( Spec.load("src/spec/query.root.json") );
test( Spec.load("src/spec/query.rules.json") );
//test( Spec.load("src/spec/tmp.json") );
if( errors > 1 ) trace("\n-----\n[ ] "+errors+" errors :/");
@ -43,6 +44,10 @@ class Test {
if( item.expect.fn == "equal.xy" ) valid = equalXY(res,item);
if( item.expect.fn == "equal.xyz" ) valid = equalXYZ(res,item);
if( item.expect.fn == "equal.multi" ) valid = equalMulti(res, item);
if( item.expect.fn == "testQueryRoot" ){
if( !item.expect.out ) valid = !q.get()[ item.expect.input[0] ].root;
else valid = item.expect.out == q.get()[ item.expect.input[0] ].root;
}
var ok:String = valid ? "[ ] " : "[ ] ";
trace( ok + item.fn + ": '" + item.data + "'" + (item.label ? " (" + (item.label?item.label:item.expect.fn) +")" : ""));
if( !valid ) errors += 1;

2
src/spec/query.root.json Normal file
View File

@ -0,0 +1,2 @@
[
]

View File

@ -10,5 +10,7 @@
{"fn":"query","data":".foo -.foo bar:>5 .foo", "expect":{ "fn":"testProperty","input":["class","foo"],"out":true},"label":"class:foo"},
{"fn":"query","data":".foo -.foo .foo", "expect":{ "fn":"testProperty","input":["class","foo"],"out":true},"label":"class:foo"},
{"fn":"query","data":".foo -.foo .foo", "expect":{ "fn":"testProperty","input":["id","foo"],"out":false},"label":"!id:foo"},
{"fn":"query","data":"foo -foo foo", "expect":{ "fn":"testProperty","input":["id","foo"],"out":true},"label":"id:foo?"}
{"fn":"query","data":"foo -foo foo", "expect":{ "fn":"testProperty","input":["id","foo"],"out":true},"label":"id:foo?"},
{"fn":"query","data":"/foo", "expect":{ "fn":"testQueryRoot","input":["foo"],"out":true},"label":"foo should be root-only"},
{"fn":"query","data":"/foo foo", "expect":{ "fn":"testQueryRoot","input":["foo"],"out":false},"label":"foo should recursively selected"}
]

View File

@ -44,7 +44,7 @@ class Query {
private var q:haxe.DynamicAccess<Dynamic> = {};
private var isProp:EReg = ~/^.*:[><=!]?/;
private var isExclude:EReg = ~/^-/;
private var isAddition:EReg = ~/^\+/;
private var isRoot:EReg = ~/^\//;
private var isClass:EReg = ~/^[-]?class$/;
private var isNumber:EReg = ~/^[0-9\.]+$/;
@ -89,13 +89,9 @@ class Query {
if( str.indexOf("<=") != -1 ) oper = "<=";
if( isExclude.match(k) ){
oper = "!=";
k = k.substr(1); // convert "-foo" into "foo"
}else if( isAddition.match(k) ){
oper = "+=";
k = k.substr(1); // convert "+foo" into "foo"
k = k.substr(1); // convert "-foo" into "foo"
}else v = v.substr(oper.length); // change ">=foo" into "foo" (strip operator)
if( oper.length == 0 ) oper = "=";
if( isClass.match(k) ){
filter[ prefix+ k ] = oper != "!=";
q.set(v,filter);
@ -108,6 +104,10 @@ class Query {
}
return;
}else{ // id
if( isRoot.match(k) ){
str = k.substr(1); // convert "/foo" to "foo"
filter[ "root" ] = true;
}else if( filter[ "root" ] == true ) filter.remove("root"); // undo root-only
filter[ "id" ] = isExclude.match(str) ? false: true;
q.set( (isExclude.match(str) ? str.substr(1) : str ) ,filter );
}