This repository has been archived by the owner on Feb 5, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
hashable.min.js
1 lines (1 loc) · 7.76 KB
/
hashable.min.js
1
(function(hashable){"use strict";hashable.version="1.5.5";hashable.hash=function(loc){if(!loc)loc=window.location;var hash={},data=null,current,format=hashable.format.path(),parse=format.parse,onchange=function(){return},def=hashable.functor(null),valid=hashable.functor(false),writing=false;hash.data=function(d){if(!arguments.length)return data;data=d;return hash};hash.set=function(d){if(typeof d==="string"){loc.hash=d;return hash}else{return hash.data(d).write()}};hash.update=function(d){hashable.extend(data,d);return hash};hash.write=function(silent){if(silent)writing=true;loc.hash=format(data);if(silent)writing=false;return hash};hash.read=function(){change();return hash};hash.format=function(fmt){if(!arguments.length)return format;if(typeof fmt==="string"){fmt=hashable.format(fmt)}format=fmt;if(typeof format.parse==="function"){parse=format.parse}return hash};hash.parse=function(fn){if(!arguments.length)return parse;parse=fn;return hash};hash.url=function(d,merge){if(!arguments.length)d=data;if(merge)d=hashable.extend({},data,d);return"#"+format(d)};hash.enable=function(){window.addEventListener("hashchange",change);return hash};hash.disable=function(){window.removeEventListener("hashchange",change);return hash};hash.change=function(callback){if(!arguments.length)return onchange;onchange=callback;return hash};hash.valid=function(f){if(!arguments.length)return valid;valid=hashable.functor(f);return hash};hash.href=function(selection){selection.on("click.hashable",function(d){this.href=hash.url(d)})};hash.href.merge=function(selection){selection.on("click.hashable",function(d){this.href=hash.url(d,true)})};hash.href.parse=function(d){return parse(this.getAttribute("href").substr(1))};hash.check=function(){if(loc.hash){return hash.read()}else{}onchange.call(hash,{previous:null,data:data||(data=def.call(hash)),diff:hashable.diff({},data)});return hash.write()};hash.default=function(d){if(!arguments.length)return def;def=hashable.functor(d);return hash};function change(){if(writing)return;var url=loc.hash.substr(1);if(url!=current){var previous=data;data=parse.call(hash,url);if(!data&&valid.call(format,url)){}else if(!data&&def){data=def.call(hash,previous);hash.write(true);url=loc.hash.substr(1)}var diff=hashable.diff(previous,data);onchange.call(hash,{url:url,data:data,previous:previous,diff:diff});current=url}}return hash};hashable.validFragment=function(fragment){return!!document.getElementById(fragment)};hashable.format=function(fmt){var query=false;if(!fmt)fmt="";else if(fmt.charAt(fmt.length-1)==="?"){query=true;fmt=fmt.substr(0,fmt.length-1)}var keys=[],word="([-\\w\\.]+)",wordPattern=new RegExp("{"+word+"}","g"),pattern=new RegExp("^"+fmt.replace(wordPattern,function(_,key){keys.push(key);return word})+"$");var format=function(data){if(!data)data={};var used=[],str=fmt.replace(wordPattern,function(_,key){return data[key]});if(!query)return str;var qkeys=Object.keys(data).filter(function(key){return keys.indexOf(key)===-1});return qkeys.length?[str,hashable.qs.format(hashable.copy(data,qkeys))].join("?"):str};format.match=function(str){if(query){str=str.split("?",2)[0]}return str.match(pattern)};format.parse=function(str){var qdata;if(query){var bits=str.split("?",2);str=bits[0];qdata=hashable.qs.parse(bits[1]);if(qdata){if(Array.isArray(query)){qdata=hashable.copy(qdata,query)}else{var qkeys=Object.keys(qdata).filter(function(key){return keys.indexOf(key)===-1});qdata=hashable.copy(qdata,qkeys)}}}var match=format.match(str);if(match){var data={};keys.forEach(function(key,i){data[key]=match[i+1]});if(qdata)hashable.extend(data,qdata);return data}return null};format.query=function(q){if(!arguments.length)return query;query=q;return format};format.toString=function(){return fmt};return format};hashable.format.path=function(){var format=function(data){data=hashable.extend({},data);var path=data.path||"";delete data.path;var query=hashable.qs.format(data);return query?[path,query].join("?"):path};format.match=function(str){return true};format.parse=function(str){var bits=str.split("?",2),data={path:bits[0]};if(bits.length>1){var query=hashable.qs.parse(bits[1]);if(query){return hashable.extend(data,query)}}return data};return format};hashable.format.map=function(f){var fmt=hashable.format(f||"{z}/{y}/{x}").query(true),precision=function(z){return Math.max(0,Math.ceil(Math.log(z)/Math.LN2))};var format=function(data){if(data&&!hashable.empty(data.z)){var p=precision(+data.z);data.x=(+data.x).toFixed(p);data.y=(+data.y).toFixed(p)}return fmt(data)};format.match=function(str){return fmt.match(str)};format.parse=function(str){var parsed=fmt.parse(str);if(parsed){parsed.z=+parsed.z;parsed.x=+parsed.x;parsed.y=+parsed.y;if(isNaN(parsed.z)||isNaN(parsed.x)||isNaN(parsed.y)){return null}}return parsed};format.query=function(q){if(!arguments.length)return fmt.query();fmt.query(q);return fmt};format.precision=function(p){if(!arguments.length)return precision;precision=hashable.functor(p);return format};return format};hashable.qs=function(){var qs={separator:"&"};var replacements=qs.replacements={"%20":"+","%2C":","};qs.parse=function(str){if(!str||str==="?")return null;if(str.charAt(0)==="?")str=str.substr(1);var data={};str.split(qs.separator).forEach(function(bit){var parts=bit.split("="),key=decode(parts[0]),val=bit.substr(key.length+1);if(parts.length===1||val==="true"){data[key]=true}else if(val==="false"){data[key]=false}else{data[key]=decode(val)}});return data};qs.format=function(data,sortKeys){if(typeof data==="string")return data;else if(data===null||typeof data==="undefined")return"";var keys=Object.keys(data).filter(function(key){return!hashable.empty(data[key])});if(sortKeys){keys=keys.sort(function(a,b){return a>b?1:a<b?-1:0})}var bits=keys.map(function(key){return data[key]===true?key:[key,encode(data[key])].join("=")});return bits.length?bits.join(qs.separator):""};function encode(d){return encodeURIComponent(d).replace(/(\%[A-F0-9]{2})/g,function(_,hex){return hex in replacements?replacements[hex]:hex})}function decode(str){return decodeURIComponent(str.replace(/\+/g," "))}return qs}();hashable.extend=function(a,b,etc){[].slice.call(arguments,1).forEach(function(o){if(!o)return;for(var key in o){a[key]=o[key]}});return a};hashable.diff=function(a,b){var ak=Object.keys(a||{}),bk=Object.keys(b||{}),diff={},key,i;while(ak.length){key=ak.shift();i=bk.indexOf(key);if(i===-1){diff[key]={op:"remove",value:a[key]}}else if(b[key]!=a[key]){diff[key]={op:"change",value:[a[key],b[key]]};bk.splice(i,1)}else{bk.splice(i,1)}}while(bk.length){key=bk.shift();diff[key]={op:"add",value:b[key]}}return Object.keys(diff).length>0?diff:null};hashable.copy=function(obj,keys){var copy={};keys.forEach(function(key){if(key in obj)copy[key]=obj[key]});return copy};hashable.empty=function(d){return d===null||typeof d==="undefined"||d.length===0};hashable.functor=function(d){return typeof d==="function"?d:function(){return d}};if(typeof L==="object"){L.Hash=L.hash=function(){var hash=hashable.hash().format(hashable.format.map()).enable();var moveend,zoomend,viewreset,changed=false;hash.onAdd=function(map){hash.change(function(e){var view=e.data;if(view){map.setView([view.y,view.x],view.z,changed?null:{animate:false});changed=true;map.fireEvent("hashchange",e)}}).default(function(){return{z:map.getZoom(),x:map.getCenter().lng,y:map.getCenter().lat}}).enable();map.on("moveend",moveend=function(){var c=map.getCenter();hash.update({x:c.lng,y:c.lat}).write()}).on("zoomend",zoomend=function(){var z=map.getZoom();hash.update({z:z}).write()}).on("viewreset",viewreset=function(){var c=map.getCenter(),z=map.getZoom();hash.update({x:c.lng,y:c.lat,z:z}).write()})};hash.onRemove=function(map){hash.change(null).disable();map.off("moveend",moveend).off("zoomend",zoomend).off("viewreset",viewreset)};hash.addTo=function(map){map.addLayer(hash);return hash};return hash}}})(typeof module==="object"?module.exports:this.hashable={});