|
|
@@ -0,0 +1,249 @@
|
|
|
+// Licensed to Cloudera, Inc. under one
|
|
|
+// or more contributor license agreements. See the NOTICE file
|
|
|
+// distributed with this work for additional information
|
|
|
+// regarding copyright ownership. Cloudera, Inc. licenses this file
|
|
|
+// to you under the Apache License, Version 2.0 (the
|
|
|
+// "License"); you may not use this file except in compliance
|
|
|
+// with the License. You may obtain a copy of the License at
|
|
|
+//
|
|
|
+// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+//
|
|
|
+// Unless required by applicable law or agreed to in writing, software
|
|
|
+// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
+// See the License for the specific language governing permissions and
|
|
|
+// limitations under the License.
|
|
|
+
|
|
|
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
+//
|
|
|
+// THIS IS A MODIFIED VERSION OF THE PLUGIN
|
|
|
+// it has an extra pathname to "pause" hashchange events when the app is not loaded currently on Hue 4
|
|
|
+//
|
|
|
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
+
|
|
|
+/*!
|
|
|
+ * routie - a tiny hash router
|
|
|
+ * v0.3.2
|
|
|
+ * http://projects.jga.me/routie
|
|
|
+ * copyright Greg Allen 2016
|
|
|
+ * MIT License
|
|
|
+*/
|
|
|
+var Routie = function(w, isModule) {
|
|
|
+
|
|
|
+ var routes = [];
|
|
|
+ var pathname = '';
|
|
|
+ var map = {};
|
|
|
+ var reference = "routie";
|
|
|
+ var oldReference = w[reference];
|
|
|
+
|
|
|
+ var Route = function(path, name) {
|
|
|
+ this.name = name;
|
|
|
+ this.path = path;
|
|
|
+ this.keys = [];
|
|
|
+ this.fns = [];
|
|
|
+ this.params = {};
|
|
|
+ this.regex = pathToRegexp(this.path, this.keys, false, false);
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ Route.prototype.addHandler = function(fn) {
|
|
|
+ this.fns.push(fn);
|
|
|
+ };
|
|
|
+
|
|
|
+ Route.prototype.removeHandler = function(fn) {
|
|
|
+ for (var i = 0, c = this.fns.length; i < c; i++) {
|
|
|
+ var f = this.fns[i];
|
|
|
+ if (fn == f) {
|
|
|
+ this.fns.splice(i, 1);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ Route.prototype.run = function(params) {
|
|
|
+ for (var i = 0, c = this.fns.length; i < c; i++) {
|
|
|
+ this.fns[i].apply(this, params);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ Route.prototype.match = function(path, params){
|
|
|
+ var m = this.regex.exec(path);
|
|
|
+
|
|
|
+ if (!m) return false;
|
|
|
+
|
|
|
+
|
|
|
+ for (var i = 1, len = m.length; i < len; ++i) {
|
|
|
+ var key = this.keys[i - 1];
|
|
|
+
|
|
|
+ var val = ('string' == typeof m[i]) ? decodeURIComponent(m[i]) : m[i];
|
|
|
+
|
|
|
+ if (key) {
|
|
|
+ this.params[key.name] = val;
|
|
|
+ }
|
|
|
+ params.push(val);
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ };
|
|
|
+
|
|
|
+ Route.prototype.toURL = function(params) {
|
|
|
+ var path = this.path;
|
|
|
+ for (var param in params) {
|
|
|
+ path = path.replace('/:'+param, '/'+params[param]);
|
|
|
+ }
|
|
|
+ path = path.replace(/\/:.*\?/g, '/').replace(/\?/g, '');
|
|
|
+ if (path.indexOf(':') != -1) {
|
|
|
+ throw new Error('missing parameters for url: '+path);
|
|
|
+ }
|
|
|
+ return path;
|
|
|
+ };
|
|
|
+
|
|
|
+ var pathToRegexp = function(path, keys, sensitive, strict) {
|
|
|
+ if (path instanceof RegExp) return path;
|
|
|
+ if (path instanceof Array) path = '(' + path.join('|') + ')';
|
|
|
+ path = path
|
|
|
+ .concat(strict ? '' : '/?')
|
|
|
+ .replace(/\/\(/g, '(?:/')
|
|
|
+ .replace(/\+/g, '__plus__')
|
|
|
+ .replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional){
|
|
|
+ keys.push({ name: key, optional: !! optional });
|
|
|
+ slash = slash || '';
|
|
|
+ return '' + (optional ? '' : slash) + '(?:' + (optional ? slash : '') + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' + (optional || '');
|
|
|
+ })
|
|
|
+ .replace(/([\/.])/g, '\\$1')
|
|
|
+ .replace(/__plus__/g, '(.+)')
|
|
|
+ .replace(/\*/g, '(.*)');
|
|
|
+ return new RegExp('^' + path + '$', sensitive ? '' : 'i');
|
|
|
+ };
|
|
|
+
|
|
|
+ var addHandler = function(path, fn) {
|
|
|
+ var s = path.split(' ');
|
|
|
+ var name = (s.length == 2) ? s[0] : null;
|
|
|
+ path = (s.length == 2) ? s[1] : s[0];
|
|
|
+
|
|
|
+ if (!map[path]) {
|
|
|
+ map[path] = new Route(path, name);
|
|
|
+ routes.push(map[path]);
|
|
|
+ }
|
|
|
+ map[path].addHandler(fn);
|
|
|
+ };
|
|
|
+
|
|
|
+ var routie = function(path, fn) {
|
|
|
+ if (typeof fn == 'function') {
|
|
|
+ addHandler(path, fn);
|
|
|
+ routie.reload();
|
|
|
+ } else if (typeof path == 'object') {
|
|
|
+ for (var p in path) {
|
|
|
+ addHandler(p, path[p]);
|
|
|
+ }
|
|
|
+ routie.reload();
|
|
|
+ } else if (typeof fn === 'undefined') {
|
|
|
+ routie.navigate(path);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ routie.setPathname = function(name) {
|
|
|
+ pathname = name;
|
|
|
+ }
|
|
|
+
|
|
|
+ routie.lookup = function(name, obj) {
|
|
|
+ for (var i = 0, c = routes.length; i < c; i++) {
|
|
|
+ var route = routes[i];
|
|
|
+ if (route.name == name) {
|
|
|
+ return route.toURL(obj);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ routie.remove = function(path, fn) {
|
|
|
+ var route = map[path];
|
|
|
+ if (!route)
|
|
|
+ return;
|
|
|
+ route.removeHandler(fn);
|
|
|
+ };
|
|
|
+
|
|
|
+ routie.removeAll = function() {
|
|
|
+ map = {};
|
|
|
+ routes = [];
|
|
|
+ };
|
|
|
+
|
|
|
+ routie.navigate = function(path, options) {
|
|
|
+ options = options || {};
|
|
|
+ var silent = options.silent || false;
|
|
|
+
|
|
|
+ if (silent) {
|
|
|
+ removeListener();
|
|
|
+ }
|
|
|
+ setTimeout(function() {
|
|
|
+ window.location.hash = path;
|
|
|
+
|
|
|
+ if (silent) {
|
|
|
+ setTimeout(function() {
|
|
|
+ addListener();
|
|
|
+ }, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ }, 1);
|
|
|
+ };
|
|
|
+
|
|
|
+ routie.noConflict = function() {
|
|
|
+ w[reference] = oldReference;
|
|
|
+ return routie;
|
|
|
+ };
|
|
|
+
|
|
|
+ var getHash = function() {
|
|
|
+ return window.location.hash.substring(1);
|
|
|
+ };
|
|
|
+
|
|
|
+ var checkRoute = function(hash, route) {
|
|
|
+ var params = [];
|
|
|
+ if (route.match(hash, params)) {
|
|
|
+ route.run(params);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ };
|
|
|
+
|
|
|
+ var hashChanged = routie.reload = function() {
|
|
|
+ if (pathname === '' || window.location.pathname.indexOf(pathname) > -1) {
|
|
|
+ console.log('ahsh cahgne or path', pathname)
|
|
|
+ var hash = getHash();
|
|
|
+ for (var i = 0, c = routes.length; i < c; i++) {
|
|
|
+ var route = routes[i];
|
|
|
+ if (checkRoute(hash, route)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ var addListener = function() {
|
|
|
+ if (w.addEventListener) {
|
|
|
+ w.addEventListener('hashchange', hashChanged, false);
|
|
|
+ } else {
|
|
|
+ w.attachEvent('onhashchange', hashChanged);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ var removeListener = function() {
|
|
|
+ if (w.removeEventListener) {
|
|
|
+ w.removeEventListener('hashchange', hashChanged);
|
|
|
+ } else {
|
|
|
+ w.detachEvent('onhashchange', hashChanged);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ addListener();
|
|
|
+
|
|
|
+ if (isModule){
|
|
|
+ return routie;
|
|
|
+ } else {
|
|
|
+ w[reference] = routie;
|
|
|
+ }
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+if (typeof module == 'undefined'){
|
|
|
+ Routie(window);
|
|
|
+} else {
|
|
|
+ module.exports = Routie(window,true);
|
|
|
+}
|