102 lines
5.3 KiB
Haxe
102 lines
5.3 KiB
Haxe
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright (c) 2023 Leon van Kammen/NLNET
|
|
package xrfragment;
|
|
|
|
import xrfragment.XRF;
|
|
|
|
@:expose // <- makes the class reachable from plain JavaScript
|
|
@:keep // <- avoids accidental removal by dead code elimination
|
|
class Parser {
|
|
public static var error:String = "";
|
|
public static var debug:Bool = false;
|
|
|
|
@:keep
|
|
public static function parse(key:String,value:String,store:haxe.DynamicAccess<Dynamic>,?index:Int):Bool {
|
|
// here we define allowed characteristics & datatypes for each fragment (stored as bitmasked int for performance purposes)
|
|
var Frag:Map<String, Int> = new Map<String, Int>();
|
|
|
|
Frag.set("#", XRF.IMMUTABLE | XRF.T_PREDEFINED_VIEW | XRF.PV_EXECUTE );
|
|
Frag.set("src", XRF.T_URL );
|
|
Frag.set("href", XRF.T_URL | XRF.T_PREDEFINED_VIEW );
|
|
Frag.set("tag", XRF.IMMUTABLE | XRF.T_STRING );
|
|
|
|
// spatial category: query selector / object manipulation
|
|
Frag.set("pos", XRF.PV_OVERRIDE | XRF.T_VECTOR3 | XRF.T_STRING | XRF.METADATA | XRF.NAVIGATOR );
|
|
Frag.set("rot", XRF.QUERY_OPERATOR | XRF.PV_OVERRIDE | XRF.T_VECTOR3 | XRF.METADATA | XRF.NAVIGATOR );
|
|
|
|
// category: media fragments
|
|
Frag.set("t", XRF.PV_OVERRIDE | XRF.T_FLOAT | XRF.T_VECTOR2 | XRF.NAVIGATOR | XRF.METADATA);
|
|
Frag.set("s", XRF.PV_OVERRIDE | XRF.T_MEDIAFRAG );
|
|
Frag.set("loop", XRF.PV_OVERRIDE | XRF.T_PREDEFINED_VIEW );
|
|
Frag.set("uv", XRF.T_VECTOR2 | XRF.T_MEDIAFRAG );
|
|
|
|
// category: author / metadata
|
|
Frag.set("namespace", XRF.IMMUTABLE | XRF.T_STRING );
|
|
Frag.set("SPDX", XRF.IMMUTABLE | XRF.T_STRING );
|
|
Frag.set("unit", XRF.IMMUTABLE | XRF.T_STRING );
|
|
Frag.set("description", XRF.IMMUTABLE | XRF.T_STRING );
|
|
|
|
/**
|
|
* # Spec
|
|
*
|
|
* > version 1.0.0 [](https://github.com/coderofsalvation/xrfragment/actions) generated by `make doc` @ $(date +"%Y-%m-%dT%H:%M:%S%z")
|
|
*
|
|
* In case your programming language has no parser ([check here](https://github.com/coderofsalvation/xrfragment/tree/main/dist)) you can [crosscompile it](https://github.com/coderofsalvation/xrfragment/blob/main/build.hxml), or roll your own `Parser.parse(k,v,store)` using the spec:
|
|
*/
|
|
|
|
// 1. requirement: receive arguments: key (string), value (string), store (writable associative array/object)
|
|
|
|
var keyStripped:String = XRF.operators.replace( key, '' );
|
|
|
|
// dynamic fragments cases: predefined views & assign/binds
|
|
var isPVDynamic:Bool = key.length > 0 && !Frag.exists(key);
|
|
if( isPVDynamic ){ // 1. add key(values) to store as [predefined view](predefined_view) or dynamic assignment
|
|
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_DYNAMICKEY, v.flags );
|
|
if( !Frag.exists(key) ) v.flags = XRF.set( XRF.CUSTOMFRAG, v.flags );
|
|
if( value.length == 0 ) v.flags = XRF.set( XRF.T_DYNAMICKEYVALUE, v.flags );
|
|
store.set( keyStripped, v );
|
|
return true;
|
|
}
|
|
|
|
// regular fragments:
|
|
var v:XRF = new XRF(key, Frag.get(key), index);
|
|
if( Frag.exists(key) ){ // 1. check if fragment is official XR Fragment
|
|
if( !v.validate(value) ){ // 1. guess the type of the value (string,int,float,x,y,z,color,args,query)
|
|
trace("⚠ fragment '"+key+"' has incompatible value ("+value+")");// 1. don't add to store if value-type is incorrect
|
|
return false;
|
|
}
|
|
store.set( keyStripped, v); // 1. if valid, add to store
|
|
if( debug ) trace("✔ "+key+": "+v.string);
|
|
}else{ // 1. expose (but mark) non-offical fragments too
|
|
if( Std.isOfType(value, String) ) v.guessType(v,value);
|
|
v.flags = XRF.set( XRF.CUSTOMFRAG, v.flags );
|
|
store.set( keyStripped ,v);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@:keep
|
|
public static function getMetaData(): Dynamic {
|
|
var meta:Dynamic = {
|
|
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;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* > icanhazcode? yes, see [Parser.hx](https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Parser.hx)
|
|
*
|
|
* # Tests
|
|
*
|
|
* the spec is tested with [JSON unittests](./../src/spec) consumed by [Test.hx](./../src/Test.hx) to cross-test all languages.
|
|
*/
|
|
|