| Index: third_party/pkg/route_hierarchical/lib/url_pattern.dart
|
| diff --git a/third_party/pkg/route_hierarchical/lib/url_pattern.dart b/third_party/pkg/route_hierarchical/lib/url_pattern.dart
|
| deleted file mode 100644
|
| index ee465f9bd642357fd6e41942c66c6d5c9b47a727..0000000000000000000000000000000000000000
|
| --- a/third_party/pkg/route_hierarchical/lib/url_pattern.dart
|
| +++ /dev/null
|
| @@ -1,306 +0,0 @@
|
| -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -library route.url_pattern;
|
| -
|
| -import 'url_matcher.dart';
|
| -
|
| -// From the PatternCharacter rule here:
|
| -// http://ecma-international.org/ecma-262/5.1/#sec-15.10
|
| -// removed '( and ')' since we'll never escape them when not in a group
|
| -final _specialChars = new RegExp(r'[$.|+[\]{}^]');
|
| -
|
| -UrlPattern urlPattern(String p) => new UrlPattern(p);
|
| -
|
| -/**
|
| - * A pattern, similar to a [RegExp], that is designed to match against URL
|
| - * paths, easily return groups of a matched path, and produce paths from a list
|
| - * of arguments - this is they are "reversible".
|
| - *
|
| - * `UrlPattern`s also allow for handling plain paths and URLs with a fragment in
|
| - * a uniform way so that they can be used for client side routing on browsers
|
| - * that support `window.history.pushState` as well as legacy browsers.
|
| - *
|
| - * The differences from a plain [RegExp]:
|
| - * * All non-literals must be in a group. Everything outside of a groups is
|
| - * considered a literal and special regex characters are escaped.
|
| - * * There can only be one match, and it must match the entire string. `^` and
|
| - * `$` are automatically added to the beginning and end of the pattern,
|
| - * respectively.
|
| - * * The pattern must be un-ambiguous, eg `(.*)(.*)` is not allowed at the
|
| - * top-level.
|
| - * * The hash character (#) matches both '#' and '/', and it is only allowed
|
| - * once per pattern. Hashes are not allowed inside groups.
|
| - *
|
| - * With those differences, `UrlPatterns` become much more useful for routing
|
| - * URLs and constructing them, both on the client and server. The best practice
|
| - * is to define your application's set of URLs in a shared library.
|
| - *
|
| - * urls.dart:
|
| - *
|
| - * library urls;
|
| - *
|
| - * final articleUrl = new UrlPattern(r'/articles/(\d+)');
|
| - *
|
| - * server.dart:
|
| - *
|
| - * import 'urls.dart';
|
| - * import 'package:route/server.dart';
|
| - *
|
| - * main() {
|
| - * var server = new HttpServer();
|
| - * server.addRequestHandler(matchesUrl(articleUrl), serveArticle);
|
| - * }
|
| - *
|
| - * serveArcticle(req, res) {
|
| - * var articleId = articleUrl.parse(req.path)[0];
|
| - * // ...
|
| - * }
|
| - *
|
| - * Use with older browsers
|
| - * -----------------------
|
| - *
|
| - * Since '#' matches both '#' and '/' it can be used in as a path separator
|
| - * between the "static" portion of your URL and the "dynamic" portion. The
|
| - * dynamic portion would be the part that change when a user navigates to new
|
| - * data that's loaded dynamically rather than loading a new page.
|
| - *
|
| - * In newer browsers that support `History.pushState()` an entire new path can
|
| - * be pushed into the location bar without reloading the page. In older browsers
|
| - * only the fragment can be changed without reloading the page. By matching both
|
| - * characters, and by producing either, we can use pushState in newer browsers,
|
| - * but fall back to fragments when necessary.
|
| - *
|
| - * Examples:
|
| - *
|
| - * var pattern = new UrlPattern(r'/app#profile/(\d+)');
|
| - * pattern.matches('/app/profile/1234'); // true
|
| - * pattern.matches('/app#profile/1234'); // true
|
| - * pattern.reverse([1234], useFragment: true); // /app#profile/1234
|
| - * pattern.reverse([1234], useFragment: false); // /app/profile/1234
|
| - */
|
| -class UrlPattern implements UrlMatcher, Pattern {
|
| - final String pattern;
|
| - RegExp _regex;
|
| - bool _hasFragment;
|
| - RegExp _baseRegex;
|
| -
|
| - UrlPattern(this.pattern) {
|
| - _parse(pattern);
|
| - }
|
| -
|
| - RegExp get regex => _regex;
|
| -
|
| - String reverse(Iterable args, {bool useFragment: false}) {
|
| - var sb = new StringBuffer();
|
| - var chars = pattern.split('');
|
| - var argsIter = args.iterator;
|
| -
|
| - int depth = 0;
|
| - int groupCount = 0;
|
| - bool escaped = false;
|
| -
|
| - for (int i = 0; i < chars.length; i++) {
|
| - var c = chars[i];
|
| - if (c == '\\' && escaped == false) {
|
| - escaped = true;
|
| - } else {
|
| - if (c == '(') {
|
| - if (escaped && depth == 0) {
|
| - sb.write(c);
|
| - }
|
| - if (!escaped) depth++;
|
| - } else if (c == ')') {
|
| - if (escaped && depth == 0) {
|
| - sb.write(c);
|
| - } else if (!escaped) {
|
| - if (depth == 0) throw new ArgumentError('unmatched parentheses');
|
| - depth--;
|
| - if (depth == 0) {
|
| - // append the nth arg
|
| - if (argsIter.moveNext()) {
|
| - sb.write(argsIter.current.toString());
|
| - } else {
|
| - throw new ArgumentError('more groups than args');
|
| - }
|
| - }
|
| - }
|
| - } else if (depth == 0) {
|
| - if (c == '#' && !useFragment) {
|
| - sb.write('/');
|
| - } else {
|
| - sb.write(c);
|
| - }
|
| - }
|
| - escaped = false;
|
| - }
|
| - }
|
| - if (depth > 0) {
|
| - throw new ArgumentError('unclosed group');
|
| - }
|
| - return sb.toString();
|
| - }
|
| -
|
| - /**
|
| - * Parses a URL path, or path + fragment, and returns the group matches.
|
| - * Throws [ArgumentError] if this pattern does not match [path].
|
| - */
|
| - List<String> parse(String path) {
|
| - var match = regex.firstMatch(path);
|
| - if (match == null) {
|
| - throw new ArgumentError('no match for $path');
|
| - }
|
| - var result = <String>[];
|
| - for (int i = 1; i <= match.groupCount; i++) {
|
| - result.add(match[i]);
|
| - }
|
| - return result;
|
| - }
|
| -
|
| - UrlMatch match(String url) {
|
| - var matches = allMatches(url);
|
| - if (matches.isEmpty) {
|
| - return null;
|
| - }
|
| - var match = matches.first;
|
| - var tail = url.substring(match.group(0).length);
|
| - Map parameters = new Map();
|
| - for (var i = 0; i < match.groupCount; i++) {
|
| - parameters[i] = match.group(i + 1);
|
| - }
|
| - return new UrlMatch(match.group(0), tail, parameters);
|
| - }
|
| -
|
| - /**
|
| - * Returns true if this pattern matches [path].
|
| - */
|
| - bool matches(String str) => _matches(regex, str);
|
| -
|
| - // TODO(justinfagnani): file bug for similar method to be added to Pattern
|
| - bool _matches(Pattern p, String str) {
|
| - var iter = p.allMatches(str).iterator;
|
| - if (iter.moveNext()) {
|
| - var match = iter.current;
|
| - return (match.start == 0) && (match.end == str.length)
|
| - && (!iter.moveNext());
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - /**
|
| - * Returns true if the path portion of the pattern, the part before the
|
| - * fragment, matches [str]. If there is no fragment in the pattern, this is
|
| - * equivalent to calling [matches].
|
| - *
|
| - * This method is most useful on a server that is serving the HTML of a
|
| - * single page app. Clients that don't support pushState will not send the
|
| - * fragment to the server, so the server will have to handle just the path
|
| - * part.
|
| - */
|
| - bool matchesNonFragment(String str) {
|
| - if (!_hasFragment) {
|
| - return matches(str);
|
| - } else {
|
| - return _matches(_baseRegex, str);
|
| - }
|
| - }
|
| -
|
| - Iterable<Match> allMatches(String str) {
|
| - return regex.allMatches(str);
|
| - }
|
| -
|
| - bool operator ==(other) =>
|
| - (other is UrlPattern) && (other.pattern == pattern);
|
| -
|
| - int get hashCode => pattern.hashCode;
|
| -
|
| - String toString() => pattern.toString();
|
| -
|
| - _parse(String pattern) {
|
| - var sb = new StringBuffer();
|
| - int depth = 0;
|
| - int lastGroupEnd = -2;
|
| - bool escaped = false;
|
| -
|
| - sb.write('^');
|
| - var chars = pattern.split('');
|
| - for (var i = 0; i < chars.length; i++) {
|
| - var c = chars[i];
|
| -
|
| - if (depth == 0) {
|
| - // outside of groups, transform the pattern to matches the literal
|
| - if (c == r'\') {
|
| - if (escaped) {
|
| - sb.write(r'\\');
|
| - }
|
| - escaped = !escaped;
|
| - } else {
|
| - if (_specialChars.hasMatch(c)) {
|
| - sb.write('\\$c');
|
| - } else if (c == '(') {
|
| - if (escaped) {
|
| - sb.write(r'\(');
|
| - } else {
|
| - sb.write('(');
|
| - if (lastGroupEnd == i - 1) {
|
| - throw new ArgumentError('ambiguous adjecent top-level groups');
|
| - }
|
| - depth = 1;
|
| - }
|
| - } else if (c == ')') {
|
| - if (escaped) {
|
| - sb.write(r'\)');
|
| - } else {
|
| - throw new ArgumentError('unmatched parenthesis');
|
| - }
|
| - } else if (c == '#') {
|
| - _setBasePattern(sb.toString());
|
| - sb.write('[/#]');
|
| - } else {
|
| - sb.write(c);
|
| - }
|
| - escaped = false;
|
| - }
|
| - } else {
|
| - // in a group, don't modify the pattern, but track escaping and depth
|
| - if (c == '(' && !escaped) {
|
| - depth++;
|
| - } else if (c == ')' && !escaped) {
|
| - depth--;
|
| - if (depth < 0) throw new ArgumentError('unmatched parenthesis');
|
| - if (depth == 0) {
|
| - lastGroupEnd = i;
|
| - }
|
| - } else if (c == '#') {
|
| - // TODO(justinfagnani): what else should be banned in groups? '/'?
|
| - throw new ArgumentError('illegal # inside group');
|
| - }
|
| - escaped = (c == r'\' && !escaped);
|
| - sb.write(c);
|
| - }
|
| - }
|
| -// sb.write(r'$');
|
| - _regex = new RegExp(sb.toString());
|
| - }
|
| -
|
| - void _setBasePattern(String basePattern) {
|
| - if (_hasFragment == true) {
|
| - throw new ArgumentError('multiple # characters');
|
| - }
|
| - _hasFragment = true;
|
| - _baseRegex = new RegExp('$basePattern\$');
|
| - }
|
| -
|
| - Match matchAsPrefix(String string, [int start = 0]) {
|
| - throw new UnimplementedError('matchAsPrefix is not implemented');
|
| - }
|
| -
|
| - List<String> urlParameterNames() {
|
| - throw new UnimplementedError('urlParameterNames is not implemented');
|
| - }
|
| -
|
| - int compareTo(UrlMatcher another) {
|
| - throw new UnimplementedError('compareTo is not implemented');
|
| - }
|
| -}
|
|
|