Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: pkg/pathos/lib/path.dart

Issue 15967012: Make pathos run in the browser. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Bug fix. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/pathos/README.md ('k') | pkg/pathos/test/pathos_dart2js_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// A comprehensive, cross-platform path manipulation library. 5 /// A comprehensive, cross-platform path manipulation library.
6 /// 6 ///
7 /// ## Installing ## 7 /// ## Installing ##
8 /// 8 ///
9 /// Use [pub][] to install this package. Add the following to your 9 /// Use [pub][] to install this package. Add the following to your
10 /// `pubspec.yaml` file. 10 /// `pubspec.yaml` file.
11 /// 11 ///
12 /// dependencies: 12 /// dependencies:
13 /// pathos: any 13 /// pathos: any
14 /// 14 ///
15 /// Then run `pub install`. 15 /// Then run `pub install`.
16 /// 16 ///
17 /// For more information, see the 17 /// For more information, see the
18 /// [pathos package on pub.dartlang.org][pkg]. 18 /// [pathos package on pub.dartlang.org][pkg].
19 /// 19 ///
20 /// [pub]: http://pub.dartlang.org 20 /// [pub]: http://pub.dartlang.org
21 /// [pkg]: http://pub.dartlang.org/packages/pathos 21 /// [pkg]: http://pub.dartlang.org/packages/pathos
22 library path; 22 library path;
23 23
24 import 'dart:io' as io; 24 import 'dart:mirrors';
25 25
26 /// An internal builder for the current OS so we can provide a straight 26 /// An internal builder for the current OS so we can provide a straight
27 /// functional interface and not require users to create one. 27 /// functional interface and not require users to create one.
28 final _builder = new Builder(); 28 final _builder = new Builder();
29 29
30 /** 30 /**
31 * Inserts [length] elements in front of the [list] and fills them with the 31 * Inserts [length] elements in front of the [list] and fills them with the
32 * [fillValue]. 32 * [fillValue].
33 */ 33 */
34 void _growListFront(List list, int length, fillValue) => 34 void _growListFront(List list, int length, fillValue) =>
35 list.insertAll(0, new List.filled(length, fillValue)); 35 list.insertAll(0, new List.filled(length, fillValue));
36 36
37 /// If we're running in the server-side Dart VM, this will return a
38 /// [LibraryMirror] that gives access to the `dart:io` library.
39 ///
40 /// If `dart:io` is not available, this returns null.
41 LibraryMirror get _io {
42 try {
43 return currentMirrorSystem().libraries[Uri.parse('dart:io')];
ahe 2013/06/12 21:47:52 You shouldn't need to wrap this in a catch block.
nweiz 2013/06/12 22:20:08 At least when I wrote this, dart2js's MirrorSystem
ahe 2013/06/12 22:24:57 Doh! I'll add that. I have focused on adding wha
44 } catch (_) {
45 return null;
46 }
47 }
48
49 // TODO(nweiz): when issue 6490 or 6943 are fixed, make this work under dart2js.
50 /// If we're running in Dartium, this will return a [LibraryMirror] that gives
51 /// access to the `dart:html` library.
52 ///
53 /// If `dart:html` is not available, this returns null.
54 LibraryMirror get _html {
55 try {
56 return currentMirrorSystem().libraries[Uri.parse('dart:html')];
ahe 2013/06/12 21:47:52 dart2js will not include the code for 'dart:html'
nweiz 2013/06/12 22:20:08 I'll keep this in mind. Right now this code only w
57 } catch (_) {
58 return null;
59 }
60 }
61
37 /// Gets the path to the current working directory. 62 /// Gets the path to the current working directory.
38 String get current => io.Directory.current.path; 63 ///
64 /// In the browser, this means the current URL. When using dart2js, this
65 /// currently returns `.` due to technical constraints. In the future, it will
66 /// return the current URL.
67 String get current {
68 if (_io != null) {
69 return _io.classes[const Symbol('Directory')]
70 .getField(const Symbol('current')).reflectee.path;
71 } else if (_html != null) {
72 return _html.getField(const Symbol('window'))
73 .reflectee.location.href;
74 } else {
75 return '.';
76 }
77 }
39 78
40 /// Gets the path separator for the current platform. On Mac and Linux, this 79 /// Gets the path separator for the current platform. On Mac and Linux, this
41 /// is `/`. On Windows, it's `\`. 80 /// is `/`. On Windows, it's `\`.
42 String get separator => _builder.separator; 81 String get separator => _builder.separator;
43 82
44 /// Converts [path] to an absolute path by resolving it relative to the current 83 /// Converts [path] to an absolute path by resolving it relative to the current
45 /// working directory. If [path] is already an absolute path, just returns it. 84 /// working directory. If [path] is already an absolute path, just returns it.
46 /// 85 ///
47 /// path.absolute('foo/bar.txt'); // -> /your/current/dir/foo/bar.txt 86 /// path.absolute('foo/bar.txt'); // -> /your/current/dir/foo/bar.txt
48 String absolute(String path) => join(current, path); 87 String absolute(String path) => join(current, path);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 /// Returns the root of [path], if it's absolute, or the empty string if it's 136 /// Returns the root of [path], if it's absolute, or the empty string if it's
98 /// relative. 137 /// relative.
99 /// 138 ///
100 /// // Unix 139 /// // Unix
101 /// path.rootPrefix('path/to/foo'); // -> '' 140 /// path.rootPrefix('path/to/foo'); // -> ''
102 /// path.rootPrefix('/path/to/foo'); // -> '/' 141 /// path.rootPrefix('/path/to/foo'); // -> '/'
103 /// 142 ///
104 /// // Windows 143 /// // Windows
105 /// path.rootPrefix(r'path\to\foo'); // -> '' 144 /// path.rootPrefix(r'path\to\foo'); // -> ''
106 /// path.rootPrefix(r'C:\path\to\foo'); // -> r'C:\' 145 /// path.rootPrefix(r'C:\path\to\foo'); // -> r'C:\'
146 ///
147 /// // URL
148 /// path.rootPrefix('path/to/foo'); // -> ''
149 /// path.rootPrefix('http://dartlang.org/path/to/foo');
150 /// // -> 'http://dartlang.org'
107 String rootPrefix(String path) => _builder.rootPrefix(path); 151 String rootPrefix(String path) => _builder.rootPrefix(path);
108 152
109 /// Returns `true` if [path] is an absolute path and `false` if it is a 153 /// Returns `true` if [path] is an absolute path and `false` if it is a
110 /// relative path. 154 /// relative path.
111 /// 155 ///
112 /// On POSIX systems, absolute paths start with a `/` (forward slash). On 156 /// On POSIX systems, absolute paths start with a `/` (forward slash). On
113 /// Windows, an absolute path starts with `\\`, or a drive letter followed by 157 /// Windows, an absolute path starts with `\\`, or a drive letter followed by
114 /// `:/` or `:\`. For URLs, absolute paths either start with a protocol and 158 /// `:/` or `:\`. For URLs, absolute paths either start with a protocol and
115 /// optional hostname (e.g. `http://dartlang.org`, `file://`) or with a `/`. 159 /// optional hostname (e.g. `http://dartlang.org`, `file://`) or with a `/`.
116 /// 160 ///
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 /// path.split('path/../foo'); // -> ['path', '..', 'foo'] 224 /// path.split('path/../foo'); // -> ['path', '..', 'foo']
181 /// 225 ///
182 /// If [path] is absolute, the root directory will be the first element in the 226 /// If [path] is absolute, the root directory will be the first element in the
183 /// array. Example: 227 /// array. Example:
184 /// 228 ///
185 /// // Unix 229 /// // Unix
186 /// path.split('/path/to/foo'); // -> ['/', 'path', 'to', 'foo'] 230 /// path.split('/path/to/foo'); // -> ['/', 'path', 'to', 'foo']
187 /// 231 ///
188 /// // Windows 232 /// // Windows
189 /// path.split(r'C:\path\to\foo'); // -> [r'C:\', 'path', 'to', 'foo'] 233 /// path.split(r'C:\path\to\foo'); // -> [r'C:\', 'path', 'to', 'foo']
234 ///
235 /// // Browser
236 /// path.split('http://dartlang.org/path/to/foo');
237 /// // -> ['http://dartlang.org', 'path', 'to', 'foo']
190 List<String> split(String path) => _builder.split(path); 238 List<String> split(String path) => _builder.split(path);
191 239
192 /// Normalizes [path], simplifying it by handling `..`, and `.`, and 240 /// Normalizes [path], simplifying it by handling `..`, and `.`, and
193 /// removing redundant path separators whenever possible. 241 /// removing redundant path separators whenever possible.
194 /// 242 ///
195 /// path.normalize('path/./to/..//file.text'); // -> 'path/file.txt' 243 /// path.normalize('path/./to/..//file.text'); // -> 'path/file.txt'
196 String normalize(String path) => _builder.normalize(path); 244 String normalize(String path) => _builder.normalize(path);
197 245
198 /// Attempts to convert [path] to an equivalent relative path from the current 246 /// Attempts to convert [path] to an equivalent relative path from the current
199 /// directory. 247 /// directory.
200 /// 248 ///
201 /// // Given current directory is /root/path: 249 /// // Given current directory is /root/path:
202 /// path.relative('/root/path/a/b.dart'); // -> 'a/b.dart' 250 /// path.relative('/root/path/a/b.dart'); // -> 'a/b.dart'
203 /// path.relative('/root/other.dart'); // -> '../other.dart' 251 /// path.relative('/root/other.dart'); // -> '../other.dart'
204 /// 252 ///
205 /// If the [from] argument is passed, [path] is made relative to that instead. 253 /// If the [from] argument is passed, [path] is made relative to that instead.
206 /// 254 ///
207 /// path.relative('/root/path/a/b.dart', 255 /// path.relative('/root/path/a/b.dart',
208 /// from: '/root/path'); // -> 'a/b.dart' 256 /// from: '/root/path'); // -> 'a/b.dart'
209 /// path.relative('/root/other.dart', 257 /// path.relative('/root/other.dart',
210 /// from: '/root/path'); // -> '../other.dart' 258 /// from: '/root/path'); // -> '../other.dart'
211 /// 259 ///
212 /// Since there is no relative path from one drive letter to another on Windows, 260 /// Since there is no relative path from one drive letter to another on Windows,
213 /// this will return an absolute path in that case. 261 /// or from one hostname to another for URLs, this will return an absolute path
262 /// in those cases.
214 /// 263 ///
264 /// // Windows
215 /// path.relative(r'D:\other', from: r'C:\home'); // -> 'D:\other' 265 /// path.relative(r'D:\other', from: r'C:\home'); // -> 'D:\other'
266 ///
267 /// // URL
268 /// path.relative('http://dartlang.org', from: 'http://pub.dartlang.org');
269 /// // -> 'http://dartlang.org'
216 String relative(String path, {String from}) => 270 String relative(String path, {String from}) =>
217 _builder.relative(path, from: from); 271 _builder.relative(path, from: from);
218 272
219 /// Removes a trailing extension from the last part of [path]. 273 /// Removes a trailing extension from the last part of [path].
220 /// 274 ///
221 /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' 275 /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
222 String withoutExtension(String path) => _builder.withoutExtension(path); 276 String withoutExtension(String path) => _builder.withoutExtension(path);
223 277
224 /// Validates that there are no non-null arguments following a null one and 278 /// Validates that there are no non-null arguments following a null one and
225 /// throws an appropriate [ArgumentError] on failure. 279 /// throws an appropriate [ArgumentError] on failure.
(...skipping 19 matching lines...) Expand all
245 } 299 }
246 300
247 /// An instantiable class for manipulating paths. Unlike the top-level 301 /// An instantiable class for manipulating paths. Unlike the top-level
248 /// functions, this lets you explicitly select what platform the paths will use. 302 /// functions, this lets you explicitly select what platform the paths will use.
249 class Builder { 303 class Builder {
250 /// Creates a new path builder for the given style and root directory. 304 /// Creates a new path builder for the given style and root directory.
251 /// 305 ///
252 /// If [style] is omitted, it uses the host operating system's path style. If 306 /// If [style] is omitted, it uses the host operating system's path style. If
253 /// [root] is omitted, it defaults to the current working directory. If [root] 307 /// [root] is omitted, it defaults to the current working directory. If [root]
254 /// is relative, it is considered relative to the current working directory. 308 /// is relative, it is considered relative to the current working directory.
309 ///
310 /// On the browser, the path style is [Style.url]. In Dartium, [root] defaults
311 /// to the current URL. When using dart2js, it currently defaults to `.` due
312 /// to technical constraints.
255 factory Builder({Style style, String root}) { 313 factory Builder({Style style, String root}) {
256 if (style == null) { 314 if (style == null) {
257 if (io.Platform.operatingSystem == 'windows') { 315 if (_io == null) {
316 style = Style.url;
317 } else if (_io.classes[const Symbol('Platform')]
318 .getField(const Symbol('operatingSystem')).reflectee == 'windows') {
258 style = Style.windows; 319 style = Style.windows;
259 } else { 320 } else {
260 style = Style.posix; 321 style = Style.posix;
261 } 322 }
262 } 323 }
263 324
264 if (root == null) root = current; 325 if (root == null) root = current;
265 326
266 return new Builder._(style, root); 327 return new Builder._(style, root);
267 } 328 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 /// Returns the root of [path], if it's absolute, or an empty string if it's 401 /// Returns the root of [path], if it's absolute, or an empty string if it's
341 /// relative. 402 /// relative.
342 /// 403 ///
343 /// // Unix 404 /// // Unix
344 /// builder.rootPrefix('path/to/foo'); // -> '' 405 /// builder.rootPrefix('path/to/foo'); // -> ''
345 /// builder.rootPrefix('/path/to/foo'); // -> '/' 406 /// builder.rootPrefix('/path/to/foo'); // -> '/'
346 /// 407 ///
347 /// // Windows 408 /// // Windows
348 /// builder.rootPrefix(r'path\to\foo'); // -> '' 409 /// builder.rootPrefix(r'path\to\foo'); // -> ''
349 /// builder.rootPrefix(r'C:\path\to\foo'); // -> r'C:\' 410 /// builder.rootPrefix(r'C:\path\to\foo'); // -> r'C:\'
411 ///
412 /// // URL
413 /// builder.rootPrefix('path/to/foo'); // -> ''
414 /// builder.rootPrefix('http://dartlang.org/path/to/foo');
415 /// // -> 'http://dartlang.org'
350 String rootPrefix(String path) { 416 String rootPrefix(String path) {
351 var root = _parse(path).root; 417 var root = _parse(path).root;
352 return root == null ? '' : root; 418 return root == null ? '' : root;
353 } 419 }
354 420
355 /// Returns `true` if [path] is an absolute path and `false` if it is a 421 /// Returns `true` if [path] is an absolute path and `false` if it is a
356 /// relative path. 422 /// relative path.
357 /// 423 ///
358 /// On POSIX systems, absolute paths start with a `/` (forward slash). On 424 /// On POSIX systems, absolute paths start with a `/` (forward slash). On
359 /// Windows, an absolute path starts with `\\`, or a drive letter followed by 425 /// Windows, an absolute path starts with `\\`, or a drive letter followed by
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 609
544 // If the path is still relative and `from` is absolute, we're unable to 610 // If the path is still relative and `from` is absolute, we're unable to
545 // find a path from `from` to `path`. 611 // find a path from `from` to `path`.
546 if (this.isRelative(path) && this.isAbsolute(from)) { 612 if (this.isRelative(path) && this.isAbsolute(from)) {
547 throw new ArgumentError('Unable to find a path to "$path" from "$from".'); 613 throw new ArgumentError('Unable to find a path to "$path" from "$from".');
548 } 614 }
549 615
550 var fromParsed = _parse(from)..normalize(); 616 var fromParsed = _parse(from)..normalize();
551 var pathParsed = _parse(path)..normalize(); 617 var pathParsed = _parse(path)..normalize();
552 618
619 if (fromParsed.parts.length > 0 && fromParsed.parts[0] == '.') {
620 return pathParsed.toString();
621 }
622
553 // If the root prefixes don't match (for example, different drive letters 623 // If the root prefixes don't match (for example, different drive letters
554 // on Windows), then there is no relative path, so just return the absolute 624 // on Windows), then there is no relative path, so just return the absolute
555 // one. In Windows, drive letters are case-insenstive and we allow 625 // one. In Windows, drive letters are case-insenstive and we allow
556 // calculation of relative paths, even if a path has not been normalized. 626 // calculation of relative paths, even if a path has not been normalized.
557 if (fromParsed.root != pathParsed.root && 627 if (fromParsed.root != pathParsed.root &&
558 ((fromParsed.root == null || pathParsed.root == null) || 628 ((fromParsed.root == null || pathParsed.root == null) ||
559 fromParsed.root.toLowerCase().replaceAll('/', '\\') != 629 fromParsed.root.toLowerCase().replaceAll('/', '\\') !=
560 pathParsed.root.toLowerCase().replaceAll('/', '\\'))) { 630 pathParsed.root.toLowerCase().replaceAll('/', '\\'))) {
561 return pathParsed.toString(); 631 return pathParsed.toString();
562 } 632 }
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 // doesn't count. 931 // doesn't count.
862 if (lastDot <= 0) return [file, '']; 932 if (lastDot <= 0) return [file, ''];
863 933
864 return [file.substring(0, lastDot), file.substring(lastDot)]; 934 return [file.substring(0, lastDot), file.substring(lastDot)];
865 } 935 }
866 936
867 _ParsedPath clone() => new _ParsedPath( 937 _ParsedPath clone() => new _ParsedPath(
868 style, root, isRootRelative, 938 style, root, isRootRelative,
869 new List.from(parts), new List.from(separators)); 939 new List.from(parts), new List.from(separators));
870 } 940 }
OLDNEW
« no previous file with comments | « pkg/pathos/README.md ('k') | pkg/pathos/test/pathos_dart2js_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698