Line data Source code
1 : // Copyright (c) 2013, 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 : import '../characters.dart' as chars;
6 : import '../internal_style.dart';
7 : import '../utils.dart';
8 :
9 : /// The style for URL paths.
10 : class UrlStyle extends InternalStyle {
11 5 : UrlStyle();
12 :
13 : final name = 'url';
14 : final separator = '/';
15 : final separators = const ['/'];
16 :
17 : // Deprecated properties.
18 :
19 : final separatorPattern = new RegExp(r'/');
20 : final needsSeparatorPattern =
21 : new RegExp(r"(^[a-zA-Z][-+.a-zA-Z\d]*://|[^/])$");
22 : final rootPattern = new RegExp(r"[a-zA-Z][-+.a-zA-Z\d]*://[^/]*");
23 : final relativeRootPattern = new RegExp(r"^/");
24 :
25 0 : bool containsSeparator(String path) => path.contains('/');
26 :
27 0 : bool isSeparator(int codeUnit) => codeUnit == chars.SLASH;
28 :
29 : bool needsSeparator(String path) {
30 0 : if (path.isEmpty) return false;
31 :
32 : // A URL that doesn't end in "/" always needs a separator.
33 0 : if (!isSeparator(path.codeUnitAt(path.length - 1))) return true;
34 :
35 : // A URI that's just "scheme://" needs an extra separator, despite ending
36 : // with "/".
37 0 : return path.endsWith("://") && rootLength(path) == path.length;
38 : }
39 :
40 : int rootLength(String path, {bool withDrive: false}) {
41 0 : if (path.isEmpty) return 0;
42 0 : if (isSeparator(path.codeUnitAt(0))) return 1;
43 :
44 0 : for (var i = 0; i < path.length; i++) {
45 0 : var codeUnit = path.codeUnitAt(i);
46 0 : if (isSeparator(codeUnit)) return 0;
47 0 : if (codeUnit == chars.COLON) {
48 0 : if (i == 0) return 0;
49 :
50 : // The root part is up until the next '/', or the full path. Skip ':'
51 : // (and '//' if it exists) and search for '/' after that.
52 0 : if (path.startsWith('//', i + 1)) i += 3;
53 0 : var index = path.indexOf('/', i);
54 0 : if (index <= 0) return path.length;
55 :
56 : // file: URLs sometimes consider Windows drive letters part of the root.
57 : // See https://url.spec.whatwg.org/#file-slash-state.
58 0 : if (!withDrive || path.length < index + 3) return index;
59 0 : if (!path.startsWith('file://')) return index;
60 0 : if (!isDriveLetter(path, index + 1)) return index;
61 0 : return path.length == index + 3 ? index + 3 : index + 4;
62 : }
63 : }
64 :
65 0 : var index = path.indexOf("/");
66 0 : if (index > 0 && path.startsWith('://', index - 1)) {
67 : }
68 : return 0;
69 : }
70 :
71 : bool isRootRelative(String path) =>
72 0 : path.isNotEmpty && isSeparator(path.codeUnitAt(0));
73 :
74 0 : String getRelativeRoot(String path) => isRootRelative(path) ? '/' : null;
75 :
76 0 : String pathFromUri(Uri uri) => uri.toString();
77 :
78 0 : Uri relativePathToUri(String path) => Uri.parse(path);
79 0 : Uri absolutePathToUri(String path) => Uri.parse(path);
80 : }
|