2023-05-23 11:30:39 +02:00
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 Leon van Kammen/NLNET
2023-03-09 22:32:28 +01:00
package xrfragment ;
2023-03-31 12:58:53 +02:00
import xrfragment . Parser ;
2023-04-14 14:45:50 +02:00
import xrfragment . XRF ;
2023-03-31 12:58:53 +02:00
2023-04-02 21:19:03 +02:00
/ * *
2023-06-27 12:15:04 +02:00
* # Spec
2023-04-02 21:22:22 +02:00
*
2023-06-27 12:15:04 +02:00
* > version 1.0 .0 [ ! [ Actions S t a t u s ] ( https : //github.com/coderofsalvation/xrfragment/workflows/test/badge.svg)](https://github.com/coderofsalvation/xrfragment/actions) generated by `make doc` @ $(date +"%Y-%m-%dT%H:%M:%S%z")
*
* # # # XR Fragment URI Grammar
2023-04-06 18:27:49 +02:00
*
* ` ` `
2024-02-14 15:47:34 +00:00
* reserved = gen - delims / sub - delims / xrf - scheme
2023-04-06 18:27:49 +02:00
* gen - delims = " # " / " & "
2023-06-27 12:15:04 +02:00
* sub - delims = " , " / " = "
2024-02-14 15:47:34 +00:00
* xrf - scheme = " x r f : / / "
2023-04-06 18:27:49 +02:00
* ` ` `
2023-04-06 18:29:53 +02:00
*
2023-06-27 12:15:04 +02:00
* In c ase your programming language has no parser ( [ check h e r e ] ( 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:
2023-04-06 18:30:36 +02:00
*
2023-04-02 21:19:03 +02:00
* /
2023-03-30 19:51:32 +02:00
@ : expose // <- makes the class reachable from plain JavaScript
@ : keep // <- avoids accidental removal by dead code elimination
2023-03-31 14:47:54 +02:00
class URI {
2024-03-29 17:36:48 +00:00
public static var fragment: haxe . DynamicAccess < Dynamic > ;
2023-04-02 21:19:03 +02:00
@ : keep
2023-05-04 13:28:12 +02:00
public static function parse ( url : String , filter : Int ) : haxe . DynamicAccess < Dynamic > {
2023-06-27 12:15:04 +02:00
var store: haxe . DynamicAccess < Dynamic > = { } ; // 1. store key/values into a associative array or dynamic object
2023-06-10 14:43:07 +02:00
if ( url == null || url . indexOf ( " # " ) == - 1 ) return store ;
2023-05-04 13:28:12 +02:00
var fragment: Array < String > = url . split ( " # " ) ; // 1. fragment URI starts with `#`
2023-04-02 21:19:03 +02:00
var splitArray: Array < String > = fragment [ 1 ] . split ( ' & ' ) ; // 1. fragments are split by `&`
2023-11-10 18:22:47 +01:00
for ( i in 0 ... splitArray . length ) { // 1. loop thru each fragment
2023-03-31 14:40:24 +02:00
2023-04-02 21:19:03 +02:00
var splitByEqual = splitArray [ i ] . split ( ' = ' ) ; // 1. for each fragment split on `=` to separate key/values
2023-03-31 12:58:53 +02:00
var regexPlus = ~/\+/g ; // 1. fragment-values are urlencoded (space becomes `+` using `encodeUriComponent` e.g.)
2023-03-30 19:51:32 +02:00
var key: String = splitByEqual [ 0 ] ;
2023-04-14 17:37:33 +02:00
var value: String = " " ;
2023-03-30 19:51:32 +02:00
if ( splitByEqual . length > 1 ) {
2024-02-09 18:00:22 +01:00
if ( XRF . isVector . match ( splitByEqual [ 1 ] ) ) value = splitByEqual [ 1 ] ;
e lse value = StringTools . urlDecode ( regexPlus . split ( splitByEqual [ 1 ] ) . join ( " " ) ) ;
2023-03-09 22:32:28 +01:00
}
2023-11-16 14:50:57 +01:00
var ok: Bool = Parser . parse ( key , value , store , i ) ; // 1. for every recognized fragment key/value-pair call [Parser.parse](#%E2%86%AA%20Parser.parse%28k%2Cv%2Cstore%29)
2023-03-30 19:51:32 +02:00
}
2023-05-04 13:28:12 +02:00
if ( filter != null && filter != 0 ) {
for ( key in store . keys ( ) ) {
var xrf: XRF = store . get ( key ) ;
if ( ! xrf . is ( filter ) ) {
store . remove ( key ) ;
2023-04-14 17:37:33 +02:00
}
2023-04-14 14:45:50 +02:00
}
}
2023-05-04 13:28:12 +02:00
return store ;
2023-03-09 22:32:28 +01:00
}
2024-02-08 19:40:43 +01:00
@ keep
public static function template ( uri : String , vars : Dynamic ) : String {
var parts = uri . split ( " # " ) ;
if ( parts . length == 1 ) return uri ; // we only do level1 fragment expansion
var frag = parts [ 1 ] ;
frag = StringTools . replace ( frag , " { " , " : : " ) ;
frag = StringTools . replace ( frag , " } " , " : : " ) ;
frag = new haxe . Template ( frag ) . execute ( vars ) ;
frag = StringTools . replace ( frag , " n u l l " , " " ) ; // *TODO* needs regex to check for [#&]null[&]
parts [ 1 ] = frag ;
return parts . join ( " # " ) ;
}
2024-02-14 15:47:34 +00:00
2023-03-09 22:32:28 +01:00
}
2023-06-27 12:15:04 +02:00
/ * *
* > icanhazcode ? yes , s e e [ U R I . h x ] ( h t t p s : //github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/URI.hx)
*
* # Tests
*
* the spec is tested with [ JSON u n i t t e s t s ] ( . / . . / src / spec ) consumed by [ Test . hx ] ( . / . . / src / Test . hx ) to cross - test all languages .
* /