Skip to content

Commit b2877ac

Browse files
committed
relative absolute URL conversion helpers
1 parent f27187b commit b2877ac

File tree

1 file changed

+176
-5
lines changed

1 file changed

+176
-5
lines changed

src/brix/util/DomTools.hx

100644100755
+176-5
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,172 @@ class DomTools
2929
/**
3030
* Call a calback later. This is useful sometimes when dealing with layout, because it needs time to be redrawn
3131
* @param callbackFunction The callback function to be called in the next frame
32+
* @param frames Optional - number of frames to skip, default is 1
3233
*/
33-
static public function doLater(callbackFunction:Void->Void)
34+
static public function doLater(callbackFunction:Void->Void, frames:Int=1)
3435
{
3536
#if js
36-
haxe.Timer.delay(callbackFunction, Math.round(200));
37+
// interval between frames in ms
38+
var frameInterval = 200;
39+
haxe.Timer.delay(callbackFunction, frames*frameInterval);
3740
#elseif (flash || nme)
38-
haxe.Timer.delay(callbackFunction, 1);
41+
haxe.Timer.delay(callbackFunction, frames);
3942
#else
4043
callbackFunction();
4144
#end
4245
}
46+
/**
47+
* convert into relative url
48+
*/
49+
static public function abs2rel(url:String, base:Null<String>=null):String
50+
{
51+
// store the initial value of url
52+
var initialUrl = url;
53+
54+
// default value for base is the document
55+
if (base == null)
56+
{
57+
base = getBaseUrl();
58+
}
59+
60+
// **
61+
// remove http
62+
var idx = base.indexOf("://");
63+
// check that we have absolute urls
64+
if (idx == -1)
65+
{
66+
trace("Warning, could not make URL relative because base URL is relative and should be absolute - could not find pattern \"://\" in "+base+". Now returns "+initialUrl);
67+
return initialUrl;
68+
}
69+
else
70+
{
71+
base = base.substr(idx+3);
72+
}
73+
var idx = url.indexOf("://");
74+
// check that we have absolute urls
75+
if (idx == -1)
76+
{
77+
trace("Warning, could not make URL relative because it is relative already - could not find pattern \"://\". Now returns "+initialUrl);
78+
return initialUrl;
79+
}
80+
else
81+
{
82+
url = url.substr(idx+3);
83+
}
84+
85+
86+
// split base url
87+
var baseArray = base.split("/");
88+
// split url
89+
var urlArray = url.split("/");
90+
91+
// check that there is a common domain name
92+
if (baseArray[0] != urlArray[0])
93+
{
94+
trace("Warning, could not make URL relative because the url is absolute external url - "+urlArray[0]+" != "+baseArray[0]+". Now returns initial URL "+initialUrl);
95+
// the url is absolute external url
96+
return initialUrl;
97+
}
98+
99+
// **
100+
// find the common parts in both base and url
101+
var diffIdx = 0;
102+
for (idx in 0...baseArray.length)
103+
{
104+
if (urlArray.length < idx || baseArray[idx] != urlArray[idx]){
105+
//trace("abs2rel found differenciation idx = "+idx+" ("+urlArray[idx]+" != "+baseArray[idx]+")");
106+
// at this point, URLs are different
107+
diffIdx = idx;
108+
break;
109+
}
110+
}
111+
// **
112+
// build the final result
113+
var resUrl = "";
114+
// add "../"
115+
if (baseArray.length>diffIdx+1)
116+
{
117+
for (idx in diffIdx...baseArray.length-1){
118+
resUrl += "../";
119+
}
120+
}
121+
// add everything after the common part
122+
for (idx in diffIdx...urlArray.length){
123+
resUrl += urlArray[idx];
124+
// only if it is not the file name
125+
if (idx != urlArray.length-1)
126+
{
127+
resUrl += "/";
128+
}
129+
}
130+
return resUrl;
131+
132+
133+
// remove path to the publication folder
134+
/* var pubUrl = "publications/";
135+
var idxPubFolder = url.indexOf(pubUrl);
136+
if (idxPubFolder >= 0){
137+
// remove all the common parts
138+
url = url.substr(idxPubFolder + pubUrl.length);
139+
// remove publication name if it is the current publication or add the relative path "../"
140+
var pubUrl = PublicationModel.getInstance().currentName + "/";
141+
var idxPubFolder = url.indexOf(pubUrl);
142+
if (idxPubFolder >= 0){
143+
// remove all the common parts
144+
url = url.substr(idxPubFolder + pubUrl.length);
145+
}
146+
else{
147+
// add the relative path to publication folder
148+
url = "../"+url;
149+
}
150+
}
151+
return url;
152+
*/ }
153+
/**
154+
* convert into absolute url
155+
* duplicated from cocktail.core.history.History
156+
*
157+
* handle the .. in relative urls, take the base tag into account
158+
* todo: do it right like described here http://dev.w3.org/html5/spec/single-page.html#fallback-base-url
159+
*/
160+
static public function rel2abs(url:String, base:Null<String>=null):String
161+
{
162+
// default value for base is the document
163+
// todo: do it right like described here (with case of iframe abd about:blank) http://dev.w3.org/html5/spec/single-page.html#fallback-base-url
164+
if (base == null)
165+
{
166+
base = getBaseUrl();
167+
}
168+
// replace all "\" by "/" in url
169+
url = StringTools.replace(url, "\\", "/");
170+
171+
// add base to url if needed
172+
var idxBase = url.indexOf("://");
173+
if (idxBase == -1)
174+
{
175+
url = base+url;
176+
}
177+
178+
// resolve the ".."
179+
var urlArray = url.split("/");
180+
var absoluteUrlArray = new Array();
181+
for (idx in 0...urlArray.length)
182+
{
183+
// check if this is a ".."
184+
if (urlArray[idx]==".."){
185+
// removes the last element of the final array
186+
absoluteUrlArray.pop();
187+
}
188+
else{
189+
// add the path element to the final array
190+
absoluteUrlArray.push(urlArray[idx]);
191+
}
192+
}
193+
url = absoluteUrlArray.join("/");
194+
195+
// return the absolute url
196+
return url;
197+
}
43198
/**
44199
* Search for all children elements of the given element that have the given attribute with the given value. Note that you should
45200
* avoid to use any non standard methods like this one to select elements as it's much less efficient than the standard ones
@@ -240,6 +395,7 @@ class DomTools
240395
*/
241396
static public function hasClass(element:HtmlDom, className:String, ?orderedClassName:Bool=false):Bool
242397
{
398+
// trace(haxe.Stack.toString(haxe.Stack.callStack()));
243399
if (element.className == null || element.className.trim() == "" || className == null || className.trim() == "") return false;
244400

245401
if (orderedClassName)
@@ -387,7 +543,6 @@ class DomTools
387543
* Get the html page base tag
388544
*/
389545
public static function getBaseTag():Null<String>{
390-
var head = Lib.document.getElementsByTagName("head")[0];
391546
var baseNodes = Lib.document.getElementsByTagName("base");
392547
if (baseNodes.length > 0){
393548
return baseNodes[0].getAttribute("href");
@@ -404,6 +559,8 @@ class DomTools
404559
// browse all tags in the head section and check if it a base tag is already set
405560
var head = Lib.document.getElementsByTagName("head")[0];
406561
var baseNodes = Lib.document.getElementsByTagName("base");
562+
trace("set base tag "+href+" -> "+DomTools.rel2abs(href));
563+
href = DomTools.rel2abs(href);
407564
if (baseNodes.length > 0){
408565
trace("Warning: base tag already set in the head section. Current value (\""+baseNodes[0].getAttribute("href")+"\") will be replaced by \""+href+"\"");
409566
baseNodes[0].setAttribute("href", href);
@@ -418,5 +575,19 @@ class DomTools
418575
head.appendChild(node);
419576
}
420577
}
421-
578+
/**
579+
* compute the base url of the document
580+
* handle base tag if any, otherwise take the documentlocation
581+
*/
582+
public static function getBaseUrl():String
583+
{
584+
var base = getBaseTag();
585+
// defaults to the document location
586+
if (base == null)
587+
{
588+
// todo: use location
589+
base = Lib.window.location.href;
590+
}
591+
return base;
592+
}
422593
}

0 commit comments

Comments
 (0)