work in progress [might break]
This commit is contained in:
parent
885c41f9b3
commit
36e48a521d
14
src/Test.hx
14
src/Test.hx
|
@ -1,5 +1,6 @@
|
|||
import xrfragment.Filter;
|
||||
import xrfragment.URI;
|
||||
import xrfragment.URL;
|
||||
import xrfragment.XRF;
|
||||
|
||||
class Spec {
|
||||
|
@ -44,6 +45,8 @@ class Test {
|
|||
if( item.expect.fn == "testPropertyAssign" ) valid = res.exists(item.expect.input) && item.expect.out == res.get(item.expect.input).is( XRF.PROP_BIND) ;
|
||||
if( item.expect.fn == "testBrowserOverride" ) valid = item.expect.out == (URI.parse(item.data,XRF.NAVIGATOR)).exists(item.expect.input);
|
||||
if( item.expect.fn == "testEmbedOverride" ) valid = item.expect.out == (URI.parse(item.data,XRF.METADATA)).exists(item.expect.input);
|
||||
if( item.expect.fn == "testURL" ) testURL( item.data, item.expect.input, item.expect.out );
|
||||
|
||||
if( item.expect.fn == "equal.string" ) valid = res.get(item.expect.input) && item.expect.out == res.get(item.expect.input).string;
|
||||
if( item.expect.fn == "equal.x" ) valid = equalX(res,item);
|
||||
if( item.expect.fn == "equal.xy" ) valid = equalXY(res,item);
|
||||
|
@ -53,6 +56,7 @@ class Test {
|
|||
if( item.expect.fn == "equal.mediafragmentS") valid = equalMediaFragment(res,item,"s");
|
||||
if( item.expect.fn == "testFilterRoot" ) valid = res.exists(item.expect.input[0]) && res.get(item.expect.input[0]).filter.get().root == item.expect.out;
|
||||
if( item.expect.fn == "testFilterDeep" ) valid = res.exists(item.expect.input[0]) && res.get(item.expect.input[0]).filter.get().deep == item.expect.out;
|
||||
|
||||
var ok:String = valid ? "[ ✔ ] " : "[ ❌] ";
|
||||
trace( ok + item.fn + ": '" + item.data + "'" + (item.label ? " (" + (item.label?item.label:item.expect.fn) +")" : ""));
|
||||
if( !valid ) errors += 1;
|
||||
|
@ -79,11 +83,11 @@ class Test {
|
|||
else return res.get( key ).floats[ Std.parseInt(item.expect.input) ] == Std.parseFloat(item.expect.out);
|
||||
}
|
||||
|
||||
static public function testUrl():Void {
|
||||
var Uri = xrfragment.URI;
|
||||
var url:String = "http://foo.com?foo=1#bar=flop&a=1,2&b=c|d|1,2,3";
|
||||
trace(url);
|
||||
trace( Uri.parse(url,0) );
|
||||
static public function testURL( url:String, attr:String, output:String): Bool {
|
||||
var URL = xrfragment.URL;
|
||||
var url = URL.parse(url,false);
|
||||
if( attr == 'scheme' && url.scheme == output ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static public function testFilter():Void {
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
{"fn":"url","data":"http://foo.com?foo=1#mypredefinedview", "expect":{ "fn":"testPredefinedView", "input":"mypredefinedview","out":true},"label":"test predefined view executed"},
|
||||
{"fn":"url","data":"http://foo.com?foo=1#mypredefinedview&another", "expect":{ "fn":"testPredefinedView", "input":"another","out":true},"label":"test predefined view executed (multiple)"},
|
||||
{"fn":"url","data":"http://foo.com?foo=1#mypredefinedview&another", "expect":{ "fn":"testPredefinedView", "input":"mypredefinedview","out":true},"label":"test predefined view executed (multiple)"},
|
||||
{"fn":"url","data":"http://foo.com?foo=1#mycustom=foo", "expect":{ "fn":"testParsed", "input":"mycustom","out":true},"label":"test custom property"}
|
||||
{"fn":"url","data":"http://foo.com?foo=1#mycustom=foo", "expect":{ "fn":"testParsed", "input":"mycustom","out":true},"label":"test custom property"},
|
||||
{"fn":"url","data":"http://foo.com?foo=1#mycustom=foo", "expect":{ "fn":"testURL", "input":"scheme","out":"https://"},"label":"test URL scheme"}
|
||||
]
|
||||
|
|
|
@ -26,6 +26,9 @@ import xrfragment.XRF;
|
|||
@:expose // <- makes the class reachable from plain JavaScript
|
||||
@:keep // <- avoids accidental removal by dead code elimination
|
||||
class URI {
|
||||
|
||||
public static var fragment:haxe.DynamicAccess<Dynamic>;
|
||||
|
||||
@:keep
|
||||
public static function parse(url:String,filter:Int):haxe.DynamicAccess<Dynamic> {
|
||||
var store:haxe.DynamicAccess<Dynamic> = {}; // 1. store key/values into a associative array or dynamic object
|
||||
|
|
|
@ -0,0 +1,328 @@
|
|||
package xrfragment;
|
||||
|
||||
import xrfragment.URI;
|
||||
|
||||
/*
|
||||
* Cocktail, HTML rendering engine
|
||||
* http://haxe.org/com/libs/cocktail
|
||||
*
|
||||
* Copyright (c) Silex Labs
|
||||
* Cocktail is available under the MIT license
|
||||
* http://www.silexlabs.org/labs/cocktail-licensing/
|
||||
* https://github.com/haxecocktail/cocktail-url/blob/master/cocktail/url/URL.hx
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parse and serialize an URL.
|
||||
*
|
||||
* note : parts of the implementation originate from
|
||||
* here : http://haxe.org/doc/snip/uri_parser,
|
||||
* some part of the URL have been renamed to match
|
||||
* w3c spec
|
||||
*
|
||||
* @author Yannick Dominguez
|
||||
*/
|
||||
class URL
|
||||
{
|
||||
/**
|
||||
* URL parts names
|
||||
*/
|
||||
private static var _parts : Array<String> = ["source", "scheme", "authority", "userInfo", "user",
|
||||
"password","host","port","relative","path","directory","file","query","fragment"];
|
||||
|
||||
/**
|
||||
* URL parts
|
||||
*/
|
||||
public var url : String;
|
||||
public var source : String;
|
||||
public var scheme : String;
|
||||
public var authority : String;
|
||||
public var userInfo : String;
|
||||
public var user : String;
|
||||
public var password : String;
|
||||
public var host : String;
|
||||
public var port : String;
|
||||
public var relative : String;
|
||||
public var path : String;
|
||||
public var directory : String;
|
||||
public var file : String;
|
||||
public var query : String;
|
||||
public var browserMode: Bool;
|
||||
public var fragment : String;
|
||||
public var hash : haxe.DynamicAccess<Dynamic>;
|
||||
|
||||
/**
|
||||
* class constructor
|
||||
*/
|
||||
public function new( )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string url and return a typed
|
||||
* object from it.
|
||||
*
|
||||
* note : implementation originate from here :
|
||||
* http://haxe.org/doc/snip/uri_parser
|
||||
*/
|
||||
public static function parse(stringUrl:String, browserMode:Bool ):URL
|
||||
{
|
||||
|
||||
// The almighty regexp (courtesy of http://blog.stevenlevithan.com/archives/parseuri)
|
||||
var r : EReg = ~/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
|
||||
|
||||
// Match the regexp to the url
|
||||
r.match(stringUrl);
|
||||
|
||||
var url:URL = new URL();
|
||||
url.browserMode = browserMode;
|
||||
|
||||
// Use reflection to set each part
|
||||
for (i in 0..._parts.length)
|
||||
{
|
||||
Reflect.setField(url, _parts[i], r.matched(i));
|
||||
}
|
||||
|
||||
//hack for relative url with only a file
|
||||
if (isRelative(url) == true)
|
||||
{
|
||||
if (url.directory == null && url.host != null)
|
||||
{
|
||||
url.file = url.host;
|
||||
if( !url.browserMode ) url.host = null;
|
||||
}
|
||||
}
|
||||
|
||||
if( url.fragment.length > 0 ){
|
||||
url.hash = xrfragment.URI.parse( url.fragment, 0 );
|
||||
}else url.hash = {};
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize an URL object into an
|
||||
* URL string
|
||||
*/
|
||||
public static function toString(url:URL):String
|
||||
{
|
||||
var result:String = "";
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* takes 2 urls and return a new url which is the result
|
||||
* of appending the second url to the first.
|
||||
*
|
||||
* if the first url points to a file, the file is removed
|
||||
* and the appended url is added after the last directory
|
||||
*
|
||||
* only the query string and fragment of the appended url are used
|
||||
*/
|
||||
public static function appendURL(url:URL, appendedURL:URL):URL
|
||||
{
|
||||
if (isRelative(url) == true)
|
||||
{
|
||||
return appendToRelativeURL(url, appendedURL);
|
||||
}
|
||||
else
|
||||
{
|
||||
return appendToAbsoluteURL(url, appendedURL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return wether the url is relative (true)
|
||||
* or absolute (false)
|
||||
*/
|
||||
public static function isRelative(url:URL):Bool
|
||||
{
|
||||
return url.scheme == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* append the appended url to a relative url
|
||||
*/
|
||||
private static function appendToRelativeURL(url:URL, appendedURL:URL):URL
|
||||
{
|
||||
//when relative url parsed, if it contains only a file (ex : "style.css")
|
||||
//then it will store it in the host attribute. So if the url has no directory
|
||||
//then only the appended url content is returned, as this method replace the file
|
||||
//part of the base url anyway
|
||||
if (url.directory == null || url.host == null)
|
||||
{
|
||||
return cloneURL(appendedURL, url.browserMode);
|
||||
}
|
||||
|
||||
var resultURL:URL = new URL();
|
||||
resultURL.host = url.host;
|
||||
resultURL.directory = url.directory;
|
||||
|
||||
if (appendedURL.host != null)
|
||||
{
|
||||
resultURL.directory += appendedURL.host;
|
||||
}
|
||||
|
||||
if (appendedURL.directory != null)
|
||||
{
|
||||
var directory = appendedURL.directory;
|
||||
if (appendedURL.host == null)
|
||||
{
|
||||
//remove the initial '/' char if no host, as already present
|
||||
//in base url
|
||||
resultURL.directory += directory.substr(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
resultURL.directory += directory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (appendedURL.file != null)
|
||||
{
|
||||
resultURL.file = appendedURL.file;
|
||||
}
|
||||
|
||||
resultURL.path = resultURL.directory + resultURL.file;
|
||||
|
||||
if (appendedURL.query != null)
|
||||
{
|
||||
resultURL.query = appendedURL.query;
|
||||
}
|
||||
|
||||
if (appendedURL.fragment != null)
|
||||
{
|
||||
resultURL.fragment = appendedURL.fragment;
|
||||
}
|
||||
|
||||
return resultURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* append the appended url to an absolute url
|
||||
*/
|
||||
private static function appendToAbsoluteURL(url:URL, appendedURL:URL):URL
|
||||
{
|
||||
var resultURL:URL = new URL();
|
||||
|
||||
if (url.scheme != null)
|
||||
{
|
||||
resultURL.scheme = url.scheme;
|
||||
}
|
||||
|
||||
if (url.host != null)
|
||||
{
|
||||
resultURL.host = url.host;
|
||||
}
|
||||
|
||||
var directory:String = "";
|
||||
if (url.directory != null)
|
||||
{
|
||||
directory = url.directory;
|
||||
}
|
||||
|
||||
if (appendedURL.host != null)
|
||||
{
|
||||
appendedURL.directory += appendedURL.host;
|
||||
}
|
||||
|
||||
if (appendedURL.directory != null)
|
||||
{
|
||||
directory += appendedURL.directory;
|
||||
}
|
||||
|
||||
resultURL.directory = directory;
|
||||
|
||||
if (appendedURL.file != null)
|
||||
{
|
||||
resultURL.file = appendedURL.file;
|
||||
}
|
||||
|
||||
resultURL.path = resultURL.directory + resultURL.file;
|
||||
|
||||
if (appendedURL.query != null)
|
||||
{
|
||||
resultURL.query = appendedURL.query;
|
||||
}
|
||||
|
||||
if (appendedURL.fragment != null)
|
||||
{
|
||||
resultURL.fragment = appendedURL.fragment;
|
||||
}
|
||||
|
||||
return resultURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* clone the provided url
|
||||
*/
|
||||
private static function cloneURL(url:URL, browserMode:Bool):URL
|
||||
{
|
||||
var clonedURL:URL = new URL();
|
||||
|
||||
clonedURL.url = url.url;
|
||||
clonedURL.source = url.source;
|
||||
clonedURL.scheme = url.scheme;
|
||||
clonedURL.authority = url.authority;
|
||||
clonedURL.userInfo = url.userInfo;
|
||||
clonedURL.password = url.password;
|
||||
clonedURL.host = url.host;
|
||||
clonedURL.port = url.port;
|
||||
clonedURL.relative = url.relative;
|
||||
clonedURL.path = url.path;
|
||||
clonedURL.directory = url.directory;
|
||||
clonedURL.file = url.file;
|
||||
clonedURL.query = url.query;
|
||||
clonedURL.browserMode = browserMode;
|
||||
clonedURL.fragment = url.fragment;
|
||||
|
||||
return clonedURL;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue