From 58d0c51c4ee83dad37c19dc3ae075b5d7bda91c2 Mon Sep 17 00:00:00 2001 From: thosakwe Date: Tue, 11 Oct 2016 14:53:32 -0400 Subject: [PATCH] Looking clean! --- .gitignore | 2 + README.md | 2 + lib/angel_route.dart | 3 ++ lib/src/route.dart | 99 ++++++++++++++++++++++++++++++++++++++++++++ pubspec.yaml | 7 ++++ test/all_tests.dart | 8 ++++ uri.dart | 5 +++ 7 files changed, 126 insertions(+) create mode 100644 README.md create mode 100644 lib/angel_route.dart create mode 100644 lib/src/route.dart create mode 100644 pubspec.yaml create mode 100644 test/all_tests.dart create mode 100644 uri.dart diff --git a/.gitignore b/.gitignore index 7c280441..68b3a77c 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ doc/api/ # Don't commit pubspec lock file # (Library packages only! Remove pattern if developing an application package) pubspec.lock + +.idea \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..57d0b0b5 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# angel_route +Advanced routing API, supports both server and browser. \ No newline at end of file diff --git a/lib/angel_route.dart b/lib/angel_route.dart new file mode 100644 index 00000000..37565e32 --- /dev/null +++ b/lib/angel_route.dart @@ -0,0 +1,3 @@ +library angel_route; + +export 'src/route.dart'; \ No newline at end of file diff --git a/lib/src/route.dart b/lib/src/route.dart new file mode 100644 index 00000000..8fec987c --- /dev/null +++ b/lib/src/route.dart @@ -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 _children = []; + final List _handlers = []; + RegExp _matcher; + Route _parent; + String _path; + List 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 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 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; + } + } +} diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 00000000..c0e5e021 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,7 @@ +name: angel_route +description: Advanced routing API, supports both server and browser. +version: 1.0.0-dev +author: Tobe O +homepage: https://github.com/angel-dart/angel_route +dev_dependencies: + test: ">=0.12.15 <0.13.0" \ No newline at end of file diff --git a/test/all_tests.dart b/test/all_tests.dart new file mode 100644 index 00000000..2f0c9266 --- /dev/null +++ b/test/all_tests.dart @@ -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); +} \ No newline at end of file diff --git a/uri.dart b/uri.dart new file mode 100644 index 00000000..75c95ccc --- /dev/null +++ b/uri.dart @@ -0,0 +1,5 @@ +main() { + final uri = Uri.parse('/foo'); + print(uri); + print(uri.resolve('/bar')); +} \ No newline at end of file