OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library uri_extras; | |
6 | |
7 import 'dart:math'; | |
8 | |
9 String relativize(Uri base, Uri uri, bool isWindows) { | |
10 if (!base.path.startsWith('/')) { | |
11 // Also throw an exception if [base] or base.path is null. | |
12 throw new ArgumentError('Expected absolute path: ${base.path}'); | |
13 } | |
14 if (!uri.path.startsWith('/')) { | |
15 // Also throw an exception if [uri] or uri.path is null. | |
16 throw new ArgumentError('Expected absolute path: ${uri.path}'); | |
17 } | |
18 bool equalsNCS(String a, String b) { | |
19 return a.toLowerCase() == b.toLowerCase(); | |
20 } | |
21 | |
22 String normalize(String path) { | |
23 if (isWindows) { | |
24 return path.toLowerCase(); | |
25 } else { | |
26 return path; | |
27 } | |
28 } | |
29 | |
30 if (equalsNCS(base.scheme, 'file') && | |
31 equalsNCS(base.scheme, uri.scheme) && | |
32 base.userInfo == uri.userInfo && | |
33 equalsNCS(base.host, uri.host) && | |
34 base.port == uri.port && | |
35 uri.query == "" && uri.fragment == "") { | |
36 if (normalize(uri.path).startsWith(normalize(base.path))) { | |
37 return uri.path.substring(base.path.lastIndexOf('/') + 1); | |
38 } | |
39 | |
40 List<String> uriParts = uri.path.split('/'); | |
41 List<String> baseParts = base.path.split('/'); | |
42 int common = 0; | |
43 int length = min(uriParts.length, baseParts.length); | |
44 while (common < length && | |
45 normalize(uriParts[common]) == normalize(baseParts[common])) { | |
46 common++; | |
47 } | |
48 if (common == 1 || (isWindows && common == 2)) { | |
49 // The first part will always be an empty string because the | |
50 // paths are absolute. On Windows, we must also consider drive | |
51 // letters or hostnames. | |
52 if (baseParts.length > common + 1) { | |
53 // Avoid using '..' to go to the root, unless we are already there. | |
54 return uri.path; | |
55 } | |
56 } | |
57 StringBuffer sb = new StringBuffer(); | |
58 for (int i = common + 1; i < baseParts.length; i++) { | |
59 sb.write('../'); | |
60 } | |
61 for (int i = common; i < uriParts.length - 1; i++) { | |
62 sb.write('${uriParts[i]}/'); | |
63 } | |
64 sb.write('${uriParts.last}'); | |
65 return sb.toString(); | |
66 } | |
67 return uri.toString(); | |
68 } | |
OLD | NEW |