Looking clean!
This commit is contained in:
parent
ac1eed06a8
commit
58d0c51c4e
7 changed files with 126 additions and 0 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -25,3 +25,5 @@ doc/api/
|
||||||
# Don't commit pubspec lock file
|
# Don't commit pubspec lock file
|
||||||
# (Library packages only! Remove pattern if developing an application package)
|
# (Library packages only! Remove pattern if developing an application package)
|
||||||
pubspec.lock
|
pubspec.lock
|
||||||
|
|
||||||
|
.idea
|
2
README.md
Normal file
2
README.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# angel_route
|
||||||
|
Advanced routing API, supports both server and browser.
|
3
lib/angel_route.dart
Normal file
3
lib/angel_route.dart
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
library angel_route;
|
||||||
|
|
||||||
|
export 'src/route.dart';
|
99
lib/src/route.dart
Normal file
99
lib/src/route.dart
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
final RegExp _rgxEnd = new RegExp(r'\$');
|
||||||
|
final RegExp _rgxStart = new RegExp(r'\^');
|
||||||
|
final RegExp _straySlashes = new RegExp(r'(^/+)|(/+$)');
|
||||||
|
|
||||||
|
class Route {
|
||||||
|
final List<Route> _children = [];
|
||||||
|
final List _handlers = [];
|
||||||
|
RegExp _matcher;
|
||||||
|
Route _parent;
|
||||||
|
String _path;
|
||||||
|
List<Route> get children => new List.unmodifiable(_children);
|
||||||
|
List get handlers => new List.unmodifiable(_handlers);
|
||||||
|
RegExp get matcher => _matcher;
|
||||||
|
final String method;
|
||||||
|
final String name;
|
||||||
|
Route get parent => _parent;
|
||||||
|
String get path => _path;
|
||||||
|
|
||||||
|
Route(Pattern path,
|
||||||
|
{Iterable<Route> children: const [],
|
||||||
|
Iterable handlers: const [],
|
||||||
|
this.method: "GET",
|
||||||
|
this.name: null}) {
|
||||||
|
if (children != null) _children.addAll(children);
|
||||||
|
if (handlers != null) _handlers.addAll(handlers);
|
||||||
|
|
||||||
|
if (path is RegExp) {
|
||||||
|
_matcher = path;
|
||||||
|
_path = path.pattern;
|
||||||
|
} else {
|
||||||
|
_matcher = new RegExp(_path = path
|
||||||
|
.toString()
|
||||||
|
.replaceAll(_straySlashes, '')
|
||||||
|
.replaceAll(new RegExp(r'\/\*$'), "*")
|
||||||
|
.replaceAll(new RegExp('\/'), r'\/')
|
||||||
|
.replaceAll(new RegExp(':[a-zA-Z_]+'), '([^\/]+)')
|
||||||
|
.replaceAll(new RegExp('\\*'), '.*'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
factory Route.join(Route parent, Route child) {
|
||||||
|
final String path1 = parent.path.replaceAll(_straySlashes, '');
|
||||||
|
final String path2 = child.path.replaceAll(_straySlashes, '');
|
||||||
|
final String pattern1 = parent.matcher.pattern.replaceAll(_rgxEnd, '');
|
||||||
|
final String pattern2 = child.matcher.pattern.replaceAll(_rgxStart, '');
|
||||||
|
|
||||||
|
final route = new Route(new RegExp('$pattern1/$pattern2'),
|
||||||
|
children: child.children,
|
||||||
|
handlers: child.handlers,
|
||||||
|
method: child.method,
|
||||||
|
name: child.name);
|
||||||
|
|
||||||
|
return route
|
||||||
|
..parent = parent
|
||||||
|
.._path = '$path1/$path2';
|
||||||
|
}
|
||||||
|
|
||||||
|
Route addChild(Route route, {bool join: true}) {
|
||||||
|
Route created = join ? new Route.join(this, route) : route;
|
||||||
|
_children.add(created);
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
Route child(Pattern path,
|
||||||
|
{Iterable<Route> children: const [],
|
||||||
|
Iterable handlers: const [],
|
||||||
|
String method: "GET",
|
||||||
|
String name: null}) {
|
||||||
|
final route = new Route(path,
|
||||||
|
children: children, handlers: handlers, method: method, name: name);
|
||||||
|
return addChild(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
Match match(String path) => matcher.firstMatch(path);
|
||||||
|
|
||||||
|
Route resolve(String path) {
|
||||||
|
if (path.isEmpty ||
|
||||||
|
path == '.' ||
|
||||||
|
path.replaceAll(_straySlashes, '').isEmpty) {
|
||||||
|
return this;
|
||||||
|
} else {
|
||||||
|
final segments = path.split('/');
|
||||||
|
|
||||||
|
for (Route route in children) {
|
||||||
|
final subPath = '${this.path}/${segments[0]}';
|
||||||
|
|
||||||
|
if (route.match(subPath) != null) {
|
||||||
|
if (segments.length == 1)
|
||||||
|
return route;
|
||||||
|
else {
|
||||||
|
return route.resolve(segments.skip(1).join('/'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
pubspec.yaml
Normal file
7
pubspec.yaml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
name: angel_route
|
||||||
|
description: Advanced routing API, supports both server and browser.
|
||||||
|
version: 1.0.0-dev
|
||||||
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
|
homepage: https://github.com/angel-dart/angel_route
|
||||||
|
dev_dependencies:
|
||||||
|
test: ">=0.12.15 <0.13.0"
|
8
test/all_tests.dart
Normal file
8
test/all_tests.dart
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import '../lib/angel_route.dart';
|
||||||
|
|
||||||
|
main() {
|
||||||
|
final foo = new Route('/foo');
|
||||||
|
final bar = foo.child('/bar');
|
||||||
|
print(foo.path);
|
||||||
|
print(bar.path);
|
||||||
|
}
|
5
uri.dart
Normal file
5
uri.dart
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
main() {
|
||||||
|
final uri = Uri.parse('/foo');
|
||||||
|
print(uri);
|
||||||
|
print(uri.resolve('/bar'));
|
||||||
|
}
|
Loading…
Reference in a new issue