From a729fc7287a8cf8ff6157188d80e2cc2bed96420 Mon Sep 17 00:00:00 2001 From: Fahim Farook Date: Sun, 19 Feb 2017 21:58:57 +0530 Subject: [PATCH 1/9] Update README.markdown --- README.markdown | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 9d00af4..009af80 100644 --- a/README.markdown +++ b/README.markdown @@ -1,6 +1,8 @@ -# PathJS # +# Forken from PathJS # -PathJS is a lightweight, client-side routing library that allows you to create "single page" applications using Hashbangs and/or HTML5 pushState. +PathJS is a lightweight, client-side routing library that allows you to create "single page" applications using Hashbangs and/or HTML5 pushState. + +Even though PathJS available on bower, it does not have proper bower.json with main:{} section. Also the bower.json files are missing on git repository. Ibn-Battuta is the restructured version of Path JS with proper bower configurations. # Features # * Lightweight From 225ac4f53d5897ae0f9119e74cb17a2685981a3a Mon Sep 17 00:00:00 2001 From: Fahim Farook Date: Sun, 19 Feb 2017 21:59:22 +0530 Subject: [PATCH 2/9] Update README.markdown --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 009af80..db0735e 100644 --- a/README.markdown +++ b/README.markdown @@ -1,4 +1,4 @@ -# Forken from PathJS # +# Forked from PathJS # PathJS is a lightweight, client-side routing library that allows you to create "single page" applications using Hashbangs and/or HTML5 pushState. From fd8136cbdf5aaa706b0c1510e3907dcd77f06b70 Mon Sep 17 00:00:00 2001 From: Fahim Farook Date: Sun, 19 Feb 2017 23:23:26 +0530 Subject: [PATCH 3/9] Initial commit --- Gruntfile.js | 273 +++++++++++++++++++++++++++ bower.json | 24 +++ dist/ibn-battuta.min.js | 1 + package.json | 39 ++++ src/path.js | 200 ++++++++++++++++++++ test/.bowerrc | 4 + test/bower.json | 9 + test/index.html | 36 ++++ test/path.js.test.html | 191 +++++++++++++++++++ test/path.min.js.test.html | 191 +++++++++++++++++++ test/pushstate/path.js.test.html | 190 +++++++++++++++++++ test/pushstate/path.min.js.test.html | 190 +++++++++++++++++++ test/spec/test.js | 13 ++ 13 files changed, 1361 insertions(+) create mode 100644 Gruntfile.js create mode 100644 bower.json create mode 100644 dist/ibn-battuta.min.js create mode 100644 package.json create mode 100644 src/path.js create mode 100644 test/.bowerrc create mode 100644 test/bower.json create mode 100644 test/index.html create mode 100644 test/path.js.test.html create mode 100644 test/path.min.js.test.html create mode 100644 test/pushstate/path.js.test.html create mode 100644 test/pushstate/path.min.js.test.html create mode 100644 test/spec/test.js diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..7d3c1f4 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,273 @@ +/** + * @description The Gruntfile.js - build file. Tragets are: + * - grunt test + * - grunt package // package for production + * - options --concat, --minify, --no-concat, --no-minify + * - grunt // test, package + * + * @author Fahim Farook + * + */ +module.exports = function(grunt) { + + "use strict"; + + // display the elapsed execution time of grunt tasks + require("time-grunt")(grunt); + + // load grunt plugins automatically by looking at task names + // so no need explicit loading. i.e. grunt.loadNpmTasks('grunt-contrib-clean'); + // task -- plugin matching rules + // - -> + // - -> grunt- + // - -> grunt-contrib- + require("jit-grunt")(grunt, { + // for tasks whose name doesn't match the plugin name, load it explicitily. + useminPrepare: "grunt-usemin" + }); + + // build properties + // build properties + var config = (function() { + var build = grunt.file.readJSON(".ibn-battutarc"); + if (!build) { + grunt.fail.fatal([".ibn-battutarc doesnt exists"]); + } + + // optimize + var defaults = { + js: { + minify: true, + concat: true + } + } + if (!build.optimize) { + grunt.log.error([".ibn-battutarc doesnt define optimize. Commnad line options or defaults will be used."]); + build.optimize = defaults; + } else { + for (var prop in defaults) { + if (!build.optimize[prop]) { + build.optimize[prop] = {}; + } + } + } + + // dirs + if (!(build.src && build.test && build.dist && build.temp)) { + grunt.fail.fatal([".ibn-battutarc doesnt define mandatory directories: src, test, dist, temp"]); + } + + // .bowerrc + var bower = grunt.file.readJSON(".bowerrc"); + if (bower) { + build.bower = bower; + } else { + build.bower = { + directory: "bower_components" + }; + } + // bower.json + bower = grunt.file.readJSON("bower.json"); + if (!bower || !bower.main) { + grunt.fail.fatal(["bower.json or main section in bower.json is missing. bower.json=" + bower]); + } + for (prop in bower) { + if (bower.hasOwnProperty(prop)) { + build.bower[prop] = bower[prop]; + } + } + + // routes + var routes = {}; + routes["/" + build.bower.directory] = "./" + build.bower.directory; + build.routes = routes; + + return build; + }()); + + // configuring grunt... + grunt.initConfig({ + + // settings + config: config, + + // delete files/ directories + clean: { + dist: { + files: [{ + dot: true, // .tmp + src: [ + "<%= config.dist %>", + "<%= config.temp %>" + ] + }] + }, + temp: ["<%= config.temp %>"] + }, + + // copy resources to dist or tmp + copy: { + // copy js files + // from: src, to: temp + // to allow minification (without requirejs) + js_src_temp: { + expand: true, + dot: true, + cwd: "<%= config.src %>", + src: "**/*.js", + dest: "<%= config.temp %>" + }, + // copy js files + // from: temp, to: dist + js_temp_dist: { + expand: true, + dot: true, + cwd: "<%= config.temp %>", + src: "**/*.js", + dest: "<%= config.dist %>" + } + }, + + concat: { + dist: { + src: ["<%= config.src %>/**/*.js"], + dest: "<%= config.temp %>/<%= config.bower.main %>" + } + }, + + // minify js files + uglify: { + target: { + options: { + mangle: false + }, + files: [{ + expand: true, + cwd: "<%= config.temp %>", + src: ["**/*.js", "!**/*.min.css"], + dest: "<%= config.dist %>" + }] + } + }, + + // run predefined tasks whenever watched file patterns are added, changed or deleted. + watch: { + // by default, if Gruntfile.js is being watched, then changes to it will trigger the watch task to restart + gruntfile: { + files: ["Gruntfile.js"] + }, + scripts: { + files: ["<%= config.src %>/**/*.js"], + tasks: ["eslint"] + }, + testScripts: { + files: ["<%= config.test %>/**/*.js"], + tasks: ["test"] // registered test task - basically run mocha + } + }, + + // start browserSync web server - for unit testing only + // https://github.com/Browsersync/recipes + // http://www.browsersync.io/docs/options/ + browserSync: { + options: { + notify: false, // don't show any ui notifications in the browser. + background: true + }, + fromTest: { + options: { + port: config.browserSync.testPort, + host: config.browserSync.testHost, + open: false, + server: { + baseDir: [config.temp, config.test, config.src], + routes: config.routes // The key - url to match : value - which folder to serve (relative to current directory) + } + } + } + }, + + // validate javascript + eslint: { + options: { + configFile: ".eslintrc" // where to find eslint configurations + }, + target: [ + "Gruntfile.js", + "<%= config.src %>/**/*.js", + "<%= config.test %>/**/*.js", + "!**/<%= config.bower.directory %>/**/*.js" + ] + }, + + // mocha unit test configurations + mocha: { + task: { + options: { + run: true, // inject mocha run code to html. i.e. mocha.run(); into following url page + // urls to test via browserSync server + urls: ["http://<%= browserSync.fromTest.options.host %>:<%= browserSync.fromTest.options.port %>/index.html"] + }, + dest: "<%= config.temp %>/mocha.out" // test report + } + } + }); + + // usage: grunt test + grunt.registerTask("test", function() { + grunt.task.run([ + "clean:temp", + "browserSync:fromTest", + "mocha" + ]); + }); + + // usage + // grunt package - package for production. Concat and minify based on settings provided in .zahrawirc + // grunt package --concat - Overrides settings provided in .zahrawirc + // grunt package --minify - Overrides settings provided in .zahrawirc + // grunt package --no-concat - Overrides settings provided in .zahrawirc + // grunt package --no-minify - Overrides settings provided in .zahrawirc + grunt.registerTask("package", function() { + // do configs + var options = [ + "concat", + "minify", + "no-concat", + "no-minify" + ]; + + for (var i = 0, len = options.length; i < len; i++) { + if (grunt.option(options[i])) { + var opts = options[i].split("-"); + + var val = opts[0] === "no" ? false : true; + var action = opts[opts.length - 1]; // concat or minify + config.optimize.js[action] = val; + } + } + + var tasks = ["clean"]; // both .tmp and dist + + if (config.optimize.js.concat) { + tasks.push("concat"); + } else { + tasks.push("copy:js_src_temp"); // 2.a + } + + if (config.optimize.js.minify) { // minify + tasks.push("uglify"); + } else { + tasks.push("copy:js_temp_dist"); + } + + grunt.task.run(tasks); + }); + + // usage: grunt + grunt.registerTask("default", [ + "newer:eslint", + "test", + "package" + ]); +}; diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..1e0bf42 --- /dev/null +++ b/bower.json @@ -0,0 +1,24 @@ +{ + "name": "ibn-battuta", + "description": "Bower friendly routing libraray forked from PathJS", + "main": "ibn-battuta.min.js", + "authors": [ + "Fahim Farook" + ], + "license": "ISC", + "keywords": [ + "router", + "pathjs" + ], + "moduleType": [ + "globals" + ], + "homepage": "https://github.com/fahimfarookme/ibn-battuta#readme", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] +} diff --git a/dist/ibn-battuta.min.js b/dist/ibn-battuta.min.js new file mode 100644 index 0000000..b8946b9 --- /dev/null +++ b/dist/ibn-battuta.min.js @@ -0,0 +1 @@ +var Path={version:"0.8.4",map:function(path){return Path.routes.defined.hasOwnProperty(path)?Path.routes.defined[path]:new Path.core.route(path)},root:function(path){Path.routes.root=path},rescue:function(fn){Path.routes.rescue=fn},history:{initial:{},pushState:function(state,title,path){Path.history.supported?Path.dispatch(path)&&history.pushState(state,title,path):Path.history.fallback&&(window.location.hash="#"+path)},popState:function(event){var initialPop=!Path.history.initial.popped&&location.href==Path.history.initial.URL;Path.history.initial.popped=!0,initialPop||Path.dispatch(document.location.pathname)},listen:function(fallback){if(Path.history.supported=!(!window.history||!window.history.pushState),Path.history.fallback=fallback,Path.history.supported)Path.history.initial.popped="state"in window.history,Path.history.initial.URL=location.href,window.onpopstate=Path.history.popState;else if(Path.history.fallback){for(route in Path.routes.defined)"#"!=route.charAt(0)&&(Path.routes.defined["#"+route]=Path.routes.defined[route],Path.routes.defined["#"+route].path="#"+route);Path.listen()}}},match:function(path,parameterize){var possible_routes,slice,i,j,compare,params={},route=null;for(route in Path.routes.defined)if(null!==route&&void 0!==route)for(route=Path.routes.defined[route],possible_routes=route.partition(),j=0;j0)for(i=0;i=8)?window.onhashchange=fn:setInterval(fn,50),""!==location.hash&&Path.dispatch(location.hash)},core:{route:function(path){this.path=path,this.action=null,this.do_enter=[],this.do_exit=null,this.params={},Path.routes.defined[path]=this}},routes:{current:null,root:null,rescue:null,previous:null,defined:{}}};Path.core.route.prototype={to:function(fn){return this.action=fn,this},enter:function(fns){return fns instanceof Array?this.do_enter=this.do_enter.concat(fns):this.do_enter.push(fns),this},exit:function(fn){return this.do_exit=fn,this},partition:function(){for(var text,i,parts=[],options=[],re=/\(([^}]+?)\)/g;text=re.exec(this.path);)parts.push(text[1]);for(options.push(this.path.split("(")[0]),i=0;i0)for(i=0;i 0) { + for (i = 0; i < slice.split("/").length; i++) { + if ((i < compare.split("/").length) && (slice.split("/")[i].charAt(0) === ":")) { + params[slice.split("/")[i].replace(/:/, "")] = compare.split("/")[i]; + compare = compare.replace(compare.split("/")[i], slice.split("/")[i]); + } + } + } + if (slice === compare) { + if (parameterize) { + route.params = params; + } + return route; + } + } + } + } + return null; + }, + "dispatch": function(passed_route) { + var previous_route, matched_route; + if (Path.routes.current !== passed_route) { + Path.routes.previous = Path.routes.current; + Path.routes.current = passed_route; + matched_route = Path.match(passed_route, true); + + if (Path.routes.previous) { + previous_route = Path.match(Path.routes.previous); + if (previous_route !== null && previous_route.do_exit !== null) { + previous_route.do_exit(); + } + } + + if (matched_route !== null) { + matched_route.run(); + return true; + } else { + if (Path.routes.rescue !== null) { + Path.routes.rescue(); + } + } + } + }, + "listen": function() { + var fn = function() { + Path.dispatch(location.hash); + } + + if (location.hash === "") { + if (Path.routes.root !== null) { + location.hash = Path.routes.root; + } + } + + // The "document.documentMode" checks below ensure that PathJS fires the right events + // even in IE "Quirks Mode". + if ("onhashchange" in window && (!document.documentMode || document.documentMode >= 8)) { + window.onhashchange = fn; + } else { + setInterval(fn, 50); + } + + if (location.hash !== "") { + Path.dispatch(location.hash); + } + }, + "core": { + "route": function(path) { + this.path = path; + this.action = null; + this.do_enter = []; + this.do_exit = null; + this.params = {}; + Path.routes.defined[path] = this; + } + }, + "routes": { + "current": null, + "root": null, + "rescue": null, + "previous": null, + "defined": {} + } +}; +Path.core.route.prototype = { + "to": function(fn) { + this.action = fn; + return this; + }, + "enter": function(fns) { + if (fns instanceof Array) { + this.do_enter = this.do_enter.concat(fns); + } else { + this.do_enter.push(fns); + } + return this; + }, + "exit": function(fn) { + this.do_exit = fn; + return this; + }, + "partition": function() { + var parts = [], + options = [], + re = /\(([^}]+?)\)/g, + text, i; + while (text = re.exec(this.path)) { + parts.push(text[1]); + } + options.push(this.path.split("(")[0]); + for (i = 0; i < parts.length; i++) { + options.push(options[options.length - 1] + parts[i]); + } + return options; + }, + "run": function() { + var halt_execution = false, + i, result, previous; + + if (Path.routes.defined[this.path].hasOwnProperty("do_enter")) { + if (Path.routes.defined[this.path].do_enter.length > 0) { + for (i = 0; i < Path.routes.defined[this.path].do_enter.length; i++) { + result = Path.routes.defined[this.path].do_enter[i].apply(this, null); + if (result === false) { + halt_execution = true; + break; + } + } + } + } + if (!halt_execution) { + Path.routes.defined[this.path].action(); + } + } +}; diff --git a/test/.bowerrc b/test/.bowerrc new file mode 100644 index 0000000..d5e4114 --- /dev/null +++ b/test/.bowerrc @@ -0,0 +1,4 @@ +{ + "directory": "bower_components", + "registry": "http://localhost:5678" +} diff --git a/test/bower.json b/test/bower.json new file mode 100644 index 0000000..824e6f3 --- /dev/null +++ b/test/bower.json @@ -0,0 +1,9 @@ +{ + "name": "zahrawi", + "private": true, + "dependencies": { + "chai": "~1.8.0", + "mocha": "~1.14.0" + }, + "devDependencies": {} +} diff --git a/test/index.html b/test/index.html new file mode 100644 index 0000000..c5390f8 --- /dev/null +++ b/test/index.html @@ -0,0 +1,36 @@ + + + + + + Mocha Spec Runner + + + + +
+ + + + + + + + + + + + + + + + + diff --git a/test/path.js.test.html b/test/path.js.test.html new file mode 100644 index 0000000..9d870fa --- /dev/null +++ b/test/path.js.test.html @@ -0,0 +1,191 @@ + + + + PathJS Test + + + + + + +
+

Test Suite

+

+ Path.js uses a very straightforward method of testing. We manually construct + a series of method calls that the library should execute under normal working + conditions. We then use JavaScript to simulate the URL changes, and compare + the final result with what the result should actually be. If the end result + is anything but perfect, the test is a failure, and this version of Path.JS + is not suitable for use. The expected test results are as follows: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Token Reason
F[enter] Enter method of F, as it is root
F[action] True action of F, as it is root
A[enter] Enter method of A, as it is looped
A[action] True action of A, as it is looped
A[exit] Exit method of A, as we move to next route
B[enter] Enter method of B, as it is looped
B[action] True action of B, as it is looped
C[action] True action of C
C[exit] Exit method of C, as we move to next route
RESCUE Rescue a route that wasn't found (D1)
RESCUE Rescue a route that wasn't found (D2)
E[enter](parse id=1) Enter method of a param parsed route
E[action](parse id=1) True action of the route, with param of id=1
E[enter](parse id=2) Enter method of the same route again
E[action](parse id=2) True action of the route, with param of id=2
E[action](check id=3) True action of the next route, with param id=3
E[exit](check id=3) Exit method of parameterized route
F[enter] Enter method of F again, our final route
F[action] True action of F, our final route
G[enter 1] First enter method of G
G[enter 2] Second enter method of G
G[enter 3] Third enter method of G
G[enter 4] Last enter method of G - Returns false, stops execution
H(one=N/A, two=N/A) Optional parameters with only the require part submitted
H(one=10, two=N/A) Optional parameters with one optional part submitted
H(one=10, two=20) Optional parameters two levels deep
H(one=10, two=N/A) Testing "back" functionality
+


+
+

Expected

+
F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse id=1)::E[action](parse id=1)::E[enter](parse id=2)::E[action](parse id=2)::E[action](check id=3)::E[exit](check id=3)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)::H(one=10, two=20)::H(one=10, two=N/A)
+

Actual

+
+

Grade

+
+
+ + diff --git a/test/path.min.js.test.html b/test/path.min.js.test.html new file mode 100644 index 0000000..bdcb2e1 --- /dev/null +++ b/test/path.min.js.test.html @@ -0,0 +1,191 @@ + + + + PathJS Test + + + + + + +
+

Test Suite

+

+ Path.js uses a very straightforward method of testing. We manually construct + a series of method calls that the library should execute under normal working + conditions. We then use JavaScript to simulate the URL changes, and compare + the final result with what the result should actually be. If the end result + is anything but perfect, the test is a failure, and this version of Path.JS + is not suitable for use. The expected test results are as follows: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Token Reason
F[enter] Enter method of F, as it is root
F[action] True action of F, as it is root
A[enter] Enter method of A, as it is looped
A[action] True action of A, as it is looped
A[exit] Exit method of A, as we move to next route
B[enter] Enter method of B, as it is looped
B[action] True action of B, as it is looped
C[action] True action of C
C[exit] Exit method of C, as we move to next route
RESCUE Rescue a route that wasn't found (D1)
RESCUE Rescue a route that wasn't found (D2)
E[enter](parse) Enter method of a param parsed route
E[action](parse id=1) True action of the route, with param of id=1
E[enter](parse) Enter method of the same route again
E[action](parse id=2) True action of the route, with param of id=2
E[action](check id=3) True action of the next route, with param id=3
E[exit](check) Exit method of parameterized route
F[enter] Enter method of F again, our final route
F[action] True action of F, our final route
G[enter 1] First enter method of G
G[enter 2] Second enter method of G
G[enter 3] Third enter method of G
G[enter 4] Last enter method of G - Returns false, stops execution
H(one=N/A, two=N/A) Optional parameters with only the require part submitted
H(one=10, two=N/A) Optional parameters with one optional part submitted
H(one=10, two=20) Optional parameters two levels deep
H(one=10, two=N/A) Testing "back" functionality
+


+
+

Expected

+
F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse)::E[action](parse id=1)::E[enter](parse)::E[action](parse id=2)::E[action](check id=3)::E[exit](check)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)::H(one=10, two=20)::H(one=10, two=N/A)
+

Actual

+
+

Grade

+
+
+ + diff --git a/test/pushstate/path.js.test.html b/test/pushstate/path.js.test.html new file mode 100644 index 0000000..d480b11 --- /dev/null +++ b/test/pushstate/path.js.test.html @@ -0,0 +1,190 @@ + + + + PathJS Test + + + + + + +
+

Test Suite

+

+ Path.js uses a very straightforward method of testing. We manually construct + a series of method calls that the library should execute under normal working + conditions. We then use JavaScript to simulate the URL changes, and compare + the final result with what the result should actually be. If the end result + is anything but perfect, the test is a failure, and this version of Path.JS + is not suitable for use. The expected test results are as follows: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Token Reason
A[enter] Enter method of A, as it is looped
A[action] True action of A, as it is looped
A[exit] Exit method of A, as we move to next route
B[enter] Enter method of B, as it is looped
B[action] True action of B, as it is looped
C[action] True action of C
C[exit] Exit method of C, as we move to next route
RESCUE Rescue a route that wasn't found (D1)
RESCUE Rescue a route that wasn't found (D2)
E[enter](parse) Enter method of a param parsed route
E[action](parse id=1) True action of the route, with param of id=1
E[enter](parse) Enter method of the same route again
E[action](parse id=2) True action of the route, with param of id=2
E[action](check id=3) True action of the next route, with param id=3
E[exit](check) Exit method of parameterized route
F[enter] Enter method of F again, our final route
F[action] True action of F, our final route
G[enter 1] First enter method of G
G[enter 2] Second enter method of G
G[enter 3] Third enter method of G
G[enter 4] Last enter method of G - Returns false, stops execution
H(one=N/A, two=N/A) Optional parameters with only the require part submitted
H(one=10, two=N/A) Optional parameters with one optional part submitted
H(one=10, two=20) Optional parameters two levels deep
H(one=10, two=N/A) Testing the "back" functionality
+


+
+

Expected

+
A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse)::E[action](parse id=1)::E[enter](parse)::E[action](parse id=2)::E[action](check id=3)::E[exit](check)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)::H(one=10, two=20)::H(one=10, two=N/A)
+

Actual

+
+

Grade

+
+
+ + diff --git a/test/pushstate/path.min.js.test.html b/test/pushstate/path.min.js.test.html new file mode 100644 index 0000000..461eb7d --- /dev/null +++ b/test/pushstate/path.min.js.test.html @@ -0,0 +1,190 @@ + + + + PathJS Test + + + + + + +
+

Test Suite

+

+ Path.js uses a very straightforward method of testing. We manually construct + a series of method calls that the library should execute under normal working + conditions. We then use JavaScript to simulate the URL changes, and compare + the final result with what the result should actually be. If the end result + is anything but perfect, the test is a failure, and this version of Path.JS + is not suitable for use. The expected test results are as follows: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Token Reason
A[enter] Enter method of A, as it is looped
A[action] True action of A, as it is looped
A[exit] Exit method of A, as we move to next route
B[enter] Enter method of B, as it is looped
B[action] True action of B, as it is looped
C[action] True action of C
C[exit] Exit method of C, as we move to next route
RESCUE Rescue a route that wasn't found (D1)
RESCUE Rescue a route that wasn't found (D2)
E[enter](parse) Enter method of a param parsed route
E[action](parse id=1) True action of the route, with param of id=1
E[enter](parse) Enter method of the same route again
E[action](parse id=2) True action of the route, with param of id=2
E[action](check id=3) True action of the next route, with param id=3
E[exit](check) Exit method of parameterized route
F[enter] Enter method of F again, our final route
F[action] True action of F, our final route
G[enter 1] First enter method of G
G[enter 2] Second enter method of G
G[enter 3] Third enter method of G
G[enter 4] Last enter method of G - Returns false, stops execution
H(one=N/A, two=N/A) Optional parameters with only the require part submitted
H(one=10, two=N/A) Optional parameters with one optional part submitted
H(one=10, two=20) Optional parameters two levels deep
H(one=10, two=N/A) Testing the "back" functionality
+


+
+

Expected

+
A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse)::E[action](parse id=1)::E[enter](parse)::E[action](parse id=2)::E[action](check id=3)::E[exit](check)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)::H(one=10, two=20)::H(one=10, two=N/A)
+

Actual

+
+

Grade

+
+
+ + diff --git a/test/spec/test.js b/test/spec/test.js new file mode 100644 index 0000000..f148eb5 --- /dev/null +++ b/test/spec/test.js @@ -0,0 +1,13 @@ +/* global describe, it */ + +(function() { + "use strict"; + + describe("Give it some context", function() { + describe("maybe a bit more context here", function() { + it("should run here few assertions", function() { + + }); + }); + }); +})(); From fccb5f20164e6227011da031001d79560c7749ae Mon Sep 17 00:00:00 2001 From: Fahim Farook Date: Sun, 19 Feb 2017 23:25:09 +0530 Subject: [PATCH 4/9] Delete path.js --- path.js | 192 -------------------------------------------------------- 1 file changed, 192 deletions(-) delete mode 100644 path.js diff --git a/path.js b/path.js deleted file mode 100644 index d56a2d8..0000000 --- a/path.js +++ /dev/null @@ -1,192 +0,0 @@ -var Path = { - 'version': "0.8.4", - 'map': function (path) { - if (Path.routes.defined.hasOwnProperty(path)) { - return Path.routes.defined[path]; - } else { - return new Path.core.route(path); - } - }, - 'root': function (path) { - Path.routes.root = path; - }, - 'rescue': function (fn) { - Path.routes.rescue = fn; - }, - 'history': { - 'initial':{}, // Empty container for "Initial Popstate" checking variables. - 'pushState': function(state, title, path){ - if(Path.history.supported){ - if(Path.dispatch(path)){ - history.pushState(state, title, path); - } - } else { - if(Path.history.fallback){ - window.location.hash = "#" + path; - } - } - }, - 'popState': function(event){ - var initialPop = !Path.history.initial.popped && location.href == Path.history.initial.URL; - Path.history.initial.popped = true; - if(initialPop) return; - Path.dispatch(document.location.pathname); - }, - 'listen': function(fallback){ - Path.history.supported = !!(window.history && window.history.pushState); - Path.history.fallback = fallback; - - if(Path.history.supported){ - Path.history.initial.popped = ('state' in window.history), Path.history.initial.URL = location.href; - window.onpopstate = Path.history.popState; - } else { - if(Path.history.fallback){ - for(route in Path.routes.defined){ - if(route.charAt(0) != "#"){ - Path.routes.defined["#"+route] = Path.routes.defined[route]; - Path.routes.defined["#"+route].path = "#"+route; - } - } - Path.listen(); - } - } - } - }, - 'match': function (path, parameterize) { - var params = {}, route = null, possible_routes, slice, i, j, compare; - for (route in Path.routes.defined) { - if (route !== null && route !== undefined) { - route = Path.routes.defined[route]; - possible_routes = route.partition(); - for (j = 0; j < possible_routes.length; j++) { - slice = possible_routes[j]; - compare = path; - if (slice.search(/:/) > 0) { - for (i = 0; i < slice.split("/").length; i++) { - if ((i < compare.split("/").length) && (slice.split("/")[i].charAt(0) === ":")) { - params[slice.split('/')[i].replace(/:/, '')] = compare.split("/")[i]; - compare = compare.replace(compare.split("/")[i], slice.split("/")[i]); - } - } - } - if (slice === compare) { - if (parameterize) { - route.params = params; - } - return route; - } - } - } - } - return null; - }, - 'dispatch': function (passed_route) { - var previous_route, matched_route; - if (Path.routes.current !== passed_route) { - Path.routes.previous = Path.routes.current; - Path.routes.current = passed_route; - matched_route = Path.match(passed_route, true); - - if (Path.routes.previous) { - previous_route = Path.match(Path.routes.previous); - if (previous_route !== null && previous_route.do_exit !== null) { - previous_route.do_exit(); - } - } - - if (matched_route !== null) { - matched_route.run(); - return true; - } else { - if (Path.routes.rescue !== null) { - Path.routes.rescue(); - } - } - } - }, - 'listen': function () { - var fn = function(){ Path.dispatch(location.hash); } - - if (location.hash === "") { - if (Path.routes.root !== null) { - location.hash = Path.routes.root; - } - } - - // The 'document.documentMode' checks below ensure that PathJS fires the right events - // even in IE "Quirks Mode". - if ("onhashchange" in window && (!document.documentMode || document.documentMode >= 8)) { - window.onhashchange = fn; - } else { - setInterval(fn, 50); - } - - if(location.hash !== "") { - Path.dispatch(location.hash); - } - }, - 'core': { - 'route': function (path) { - this.path = path; - this.action = null; - this.do_enter = []; - this.do_exit = null; - this.params = {}; - Path.routes.defined[path] = this; - } - }, - 'routes': { - 'current': null, - 'root': null, - 'rescue': null, - 'previous': null, - 'defined': {} - } -}; -Path.core.route.prototype = { - 'to': function (fn) { - this.action = fn; - return this; - }, - 'enter': function (fns) { - if (fns instanceof Array) { - this.do_enter = this.do_enter.concat(fns); - } else { - this.do_enter.push(fns); - } - return this; - }, - 'exit': function (fn) { - this.do_exit = fn; - return this; - }, - 'partition': function () { - var parts = [], options = [], re = /\(([^}]+?)\)/g, text, i; - while (text = re.exec(this.path)) { - parts.push(text[1]); - } - options.push(this.path.split("(")[0]); - for (i = 0; i < parts.length; i++) { - options.push(options[options.length - 1] + parts[i]); - } - return options; - }, - 'run': function () { - var halt_execution = false, i, result, previous; - - if (Path.routes.defined[this.path].hasOwnProperty("do_enter")) { - if (Path.routes.defined[this.path].do_enter.length > 0) { - for (i = 0; i < Path.routes.defined[this.path].do_enter.length; i++) { - result = Path.routes.defined[this.path].do_enter[i].apply(this, null); - if (result === false) { - halt_execution = true; - break; - } - } - } - } - if (!halt_execution) { - Path.routes.defined[this.path].action(); - } - } -}; \ No newline at end of file From 83490e53c254c3806fbaa21da34087f4ae134c64 Mon Sep 17 00:00:00 2001 From: Fahim Farook Date: Sun, 19 Feb 2017 23:25:20 +0530 Subject: [PATCH 5/9] Delete path.min.js --- path.min.js | 1 - 1 file changed, 1 deletion(-) delete mode 100644 path.min.js diff --git a/path.min.js b/path.min.js deleted file mode 100644 index f44e647..0000000 --- a/path.min.js +++ /dev/null @@ -1 +0,0 @@ -var Path={version:"0.8.4",map:function(a){if(Path.routes.defined.hasOwnProperty(a)){return Path.routes.defined[a]}else{return new Path.core.route(a)}},root:function(a){Path.routes.root=a},rescue:function(a){Path.routes.rescue=a},history:{initial:{},pushState:function(a,b,c){if(Path.history.supported){if(Path.dispatch(c)){history.pushState(a,b,c)}}else{if(Path.history.fallback){window.location.hash="#"+c}}},popState:function(a){var b=!Path.history.initial.popped&&location.href==Path.history.initial.URL;Path.history.initial.popped=true;if(b)return;Path.dispatch(document.location.pathname)},listen:function(a){Path.history.supported=!!(window.history&&window.history.pushState);Path.history.fallback=a;if(Path.history.supported){Path.history.initial.popped="state"in window.history,Path.history.initial.URL=location.href;window.onpopstate=Path.history.popState}else{if(Path.history.fallback){for(route in Path.routes.defined){if(route.charAt(0)!="#"){Path.routes.defined["#"+route]=Path.routes.defined[route];Path.routes.defined["#"+route].path="#"+route}}Path.listen()}}}},match:function(a,b){var c={},d=null,e,f,g,h,i;for(d in Path.routes.defined){if(d!==null&&d!==undefined){d=Path.routes.defined[d];e=d.partition();for(h=0;h0){for(g=0;g=8)){window.onhashchange=a}else{setInterval(a,50)}if(location.hash!==""){Path.dispatch(location.hash)}},core:{route:function(a){this.path=a;this.action=null;this.do_enter=[];this.do_exit=null;this.params={};Path.routes.defined[a]=this}},routes:{current:null,root:null,rescue:null,previous:null,defined:{}}};Path.core.route.prototype={to:function(a){this.action=a;return this},enter:function(a){if(a instanceof Array){this.do_enter=this.do_enter.concat(a)}else{this.do_enter.push(a)}return this},exit:function(a){this.do_exit=a;return this},partition:function(){var a=[],b=[],c=/\(([^}]+?)\)/g,d,e;while(d=c.exec(this.path)){a.push(d[1])}b.push(this.path.split("(")[0]);for(e=0;e0){for(b=0;b Date: Sun, 19 Feb 2017 23:29:40 +0530 Subject: [PATCH 6/9] Removed old tests --- tests/path.js.test.html | 191 -------------------------- tests/path.min.js.test.html | 191 -------------------------- tests/pushstate/path.js.test.html | 190 ------------------------- tests/pushstate/path.min.js.test.html | 190 ------------------------- 4 files changed, 762 deletions(-) delete mode 100644 tests/path.js.test.html delete mode 100644 tests/path.min.js.test.html delete mode 100644 tests/pushstate/path.js.test.html delete mode 100644 tests/pushstate/path.min.js.test.html diff --git a/tests/path.js.test.html b/tests/path.js.test.html deleted file mode 100644 index 9d870fa..0000000 --- a/tests/path.js.test.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - PathJS Test - - - - - - -
-

Test Suite

-

- Path.js uses a very straightforward method of testing. We manually construct - a series of method calls that the library should execute under normal working - conditions. We then use JavaScript to simulate the URL changes, and compare - the final result with what the result should actually be. If the end result - is anything but perfect, the test is a failure, and this version of Path.JS - is not suitable for use. The expected test results are as follows: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Token Reason
F[enter] Enter method of F, as it is root
F[action] True action of F, as it is root
A[enter] Enter method of A, as it is looped
A[action] True action of A, as it is looped
A[exit] Exit method of A, as we move to next route
B[enter] Enter method of B, as it is looped
B[action] True action of B, as it is looped
C[action] True action of C
C[exit] Exit method of C, as we move to next route
RESCUE Rescue a route that wasn't found (D1)
RESCUE Rescue a route that wasn't found (D2)
E[enter](parse id=1) Enter method of a param parsed route
E[action](parse id=1) True action of the route, with param of id=1
E[enter](parse id=2) Enter method of the same route again
E[action](parse id=2) True action of the route, with param of id=2
E[action](check id=3) True action of the next route, with param id=3
E[exit](check id=3) Exit method of parameterized route
F[enter] Enter method of F again, our final route
F[action] True action of F, our final route
G[enter 1] First enter method of G
G[enter 2] Second enter method of G
G[enter 3] Third enter method of G
G[enter 4] Last enter method of G - Returns false, stops execution
H(one=N/A, two=N/A) Optional parameters with only the require part submitted
H(one=10, two=N/A) Optional parameters with one optional part submitted
H(one=10, two=20) Optional parameters two levels deep
H(one=10, two=N/A) Testing "back" functionality
-


-
-

Expected

-
F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse id=1)::E[action](parse id=1)::E[enter](parse id=2)::E[action](parse id=2)::E[action](check id=3)::E[exit](check id=3)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)::H(one=10, two=20)::H(one=10, two=N/A)
-

Actual

-
-

Grade

-
-
- - diff --git a/tests/path.min.js.test.html b/tests/path.min.js.test.html deleted file mode 100644 index bdcb2e1..0000000 --- a/tests/path.min.js.test.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - PathJS Test - - - - - - -
-

Test Suite

-

- Path.js uses a very straightforward method of testing. We manually construct - a series of method calls that the library should execute under normal working - conditions. We then use JavaScript to simulate the URL changes, and compare - the final result with what the result should actually be. If the end result - is anything but perfect, the test is a failure, and this version of Path.JS - is not suitable for use. The expected test results are as follows: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Token Reason
F[enter] Enter method of F, as it is root
F[action] True action of F, as it is root
A[enter] Enter method of A, as it is looped
A[action] True action of A, as it is looped
A[exit] Exit method of A, as we move to next route
B[enter] Enter method of B, as it is looped
B[action] True action of B, as it is looped
C[action] True action of C
C[exit] Exit method of C, as we move to next route
RESCUE Rescue a route that wasn't found (D1)
RESCUE Rescue a route that wasn't found (D2)
E[enter](parse) Enter method of a param parsed route
E[action](parse id=1) True action of the route, with param of id=1
E[enter](parse) Enter method of the same route again
E[action](parse id=2) True action of the route, with param of id=2
E[action](check id=3) True action of the next route, with param id=3
E[exit](check) Exit method of parameterized route
F[enter] Enter method of F again, our final route
F[action] True action of F, our final route
G[enter 1] First enter method of G
G[enter 2] Second enter method of G
G[enter 3] Third enter method of G
G[enter 4] Last enter method of G - Returns false, stops execution
H(one=N/A, two=N/A) Optional parameters with only the require part submitted
H(one=10, two=N/A) Optional parameters with one optional part submitted
H(one=10, two=20) Optional parameters two levels deep
H(one=10, two=N/A) Testing "back" functionality
-


-
-

Expected

-
F[enter]::F[action]::A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse)::E[action](parse id=1)::E[enter](parse)::E[action](parse id=2)::E[action](check id=3)::E[exit](check)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)::H(one=10, two=20)::H(one=10, two=N/A)
-

Actual

-
-

Grade

-
-
- - diff --git a/tests/pushstate/path.js.test.html b/tests/pushstate/path.js.test.html deleted file mode 100644 index d480b11..0000000 --- a/tests/pushstate/path.js.test.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - PathJS Test - - - - - - -
-

Test Suite

-

- Path.js uses a very straightforward method of testing. We manually construct - a series of method calls that the library should execute under normal working - conditions. We then use JavaScript to simulate the URL changes, and compare - the final result with what the result should actually be. If the end result - is anything but perfect, the test is a failure, and this version of Path.JS - is not suitable for use. The expected test results are as follows: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Token Reason
A[enter] Enter method of A, as it is looped
A[action] True action of A, as it is looped
A[exit] Exit method of A, as we move to next route
B[enter] Enter method of B, as it is looped
B[action] True action of B, as it is looped
C[action] True action of C
C[exit] Exit method of C, as we move to next route
RESCUE Rescue a route that wasn't found (D1)
RESCUE Rescue a route that wasn't found (D2)
E[enter](parse) Enter method of a param parsed route
E[action](parse id=1) True action of the route, with param of id=1
E[enter](parse) Enter method of the same route again
E[action](parse id=2) True action of the route, with param of id=2
E[action](check id=3) True action of the next route, with param id=3
E[exit](check) Exit method of parameterized route
F[enter] Enter method of F again, our final route
F[action] True action of F, our final route
G[enter 1] First enter method of G
G[enter 2] Second enter method of G
G[enter 3] Third enter method of G
G[enter 4] Last enter method of G - Returns false, stops execution
H(one=N/A, two=N/A) Optional parameters with only the require part submitted
H(one=10, two=N/A) Optional parameters with one optional part submitted
H(one=10, two=20) Optional parameters two levels deep
H(one=10, two=N/A) Testing the "back" functionality
-


-
-

Expected

-
A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse)::E[action](parse id=1)::E[enter](parse)::E[action](parse id=2)::E[action](check id=3)::E[exit](check)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)::H(one=10, two=20)::H(one=10, two=N/A)
-

Actual

-
-

Grade

-
-
- - diff --git a/tests/pushstate/path.min.js.test.html b/tests/pushstate/path.min.js.test.html deleted file mode 100644 index 461eb7d..0000000 --- a/tests/pushstate/path.min.js.test.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - PathJS Test - - - - - - -
-

Test Suite

-

- Path.js uses a very straightforward method of testing. We manually construct - a series of method calls that the library should execute under normal working - conditions. We then use JavaScript to simulate the URL changes, and compare - the final result with what the result should actually be. If the end result - is anything but perfect, the test is a failure, and this version of Path.JS - is not suitable for use. The expected test results are as follows: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Token Reason
A[enter] Enter method of A, as it is looped
A[action] True action of A, as it is looped
A[exit] Exit method of A, as we move to next route
B[enter] Enter method of B, as it is looped
B[action] True action of B, as it is looped
C[action] True action of C
C[exit] Exit method of C, as we move to next route
RESCUE Rescue a route that wasn't found (D1)
RESCUE Rescue a route that wasn't found (D2)
E[enter](parse) Enter method of a param parsed route
E[action](parse id=1) True action of the route, with param of id=1
E[enter](parse) Enter method of the same route again
E[action](parse id=2) True action of the route, with param of id=2
E[action](check id=3) True action of the next route, with param id=3
E[exit](check) Exit method of parameterized route
F[enter] Enter method of F again, our final route
F[action] True action of F, our final route
G[enter 1] First enter method of G
G[enter 2] Second enter method of G
G[enter 3] Third enter method of G
G[enter 4] Last enter method of G - Returns false, stops execution
H(one=N/A, two=N/A) Optional parameters with only the require part submitted
H(one=10, two=N/A) Optional parameters with one optional part submitted
H(one=10, two=20) Optional parameters two levels deep
H(one=10, two=N/A) Testing the "back" functionality
-


-
-

Expected

-
A[enter]::A[action]::A[exit]::B[enter]::B[action]::C[action]::C[exit]::RESCUE::RESCUE::E[enter](parse)::E[action](parse id=1)::E[enter](parse)::E[action](parse id=2)::E[action](check id=3)::E[exit](check)::F[enter]::F[action]::G[enter 1]::G[enter 2]::G[enter 3]::G[enter 4]::H(one=N/A, two=N/A)::H(one=10, two=N/A)::H(one=10, two=20)::H(one=10, two=N/A)
-

Actual

-
-

Grade

-
-
- - From b72f65cc22cdd333557de04105fdc70b77fa99d7 Mon Sep 17 00:00:00 2001 From: Fahim Farook Date: Sun, 19 Feb 2017 23:42:04 +0530 Subject: [PATCH 7/9] Corrceted bower main --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 1e0bf42..b9861a9 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "ibn-battuta", "description": "Bower friendly routing libraray forked from PathJS", - "main": "ibn-battuta.min.js", + "main": "dist/ibn-battuta.min.js", "authors": [ "Fahim Farook" ], diff --git a/package.json b/package.json index 1e89dd2..98c6524 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ibn-battuta", - "version": "1.0.0", + "version": "1.0.1", "description": "Bower friendly routing libraray forked from PathJS", "main": "ibn-battuta.min.js", "scripts": { From 04dbde861f02d40d5ff575ded11bb16f6ee013f5 Mon Sep 17 00:00:00 2001 From: Fahim Farook Date: Sun, 26 Feb 2017 19:10:42 +0530 Subject: [PATCH 8/9] Added .rc files --- .bowerrc | 3 +++ .eslintrc | 17 +++++++++++++++++ .ibn-battutarc | 16 ++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 .bowerrc create mode 100644 .eslintrc create mode 100644 .ibn-battutarc diff --git a/.bowerrc b/.bowerrc new file mode 100644 index 0000000..99e3a38 --- /dev/null +++ b/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "bower_components" +} diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..4be6d02 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,17 @@ +{ + "extends": [ + "eslint:recommended" + ], + "env": { + "node": true, + "browser": true, + "es6": true, + "jquery": true, + "mocha": true, + "amd": true + }, + "rules": { + "quotes": [2, "double"], + "indent": [2, 3] + } +} diff --git a/.ibn-battutarc b/.ibn-battutarc new file mode 100644 index 0000000..3cfd956 --- /dev/null +++ b/.ibn-battutarc @@ -0,0 +1,16 @@ +{ + "src": "src", + "test": "test", + "dist": "dist", + "temp": ".tmp", + "browserSync": { + "testPort": 9998, + "testHost": "localhost" + }, + "optimize": { + "js": { + "concat": true, + "minify": true + } + } +} From 77685642cfa510d499800748640f717cba1ac295 Mon Sep 17 00:00:00 2001 From: Fahim Farook Date: Sun, 26 Feb 2017 19:22:18 +0530 Subject: [PATCH 9/9] Added .gitignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..21bc9b6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules +bower_components +.tmp +.sass-cache +.svn