1/** 2 * hash.js 3 * 4 * Copyright (C) 2012 Emmanuel Garcia 5 * MIT Licensed 6 * 7 * **************************************** 8 * 9 * Hash.pushState(true); 10 * 11 * Hash.on('/page/([0-9]+)$', 12 * {yep: function(path, parts) { }, nop: function() { }}, 13 * 'Page $1'); 14 * 15 * Hash.go('/page/1'); 16 **/ 17 18(function() { 19 20'use strict'; 21 22var hashes = {}, 23 regexp = {}, 24 history = [], 25 freq = 100, 26 num = 0, 27 pushState = false, 28 timer = null, 29 currentUrl = null, 30 31 freeze = function(obj) { 32 if (Object.freeze) return Object.freeze(obj); 33 return obj; 34 }, 35 36 getHashParts = function() { 37 return window.location.href.split('#'); 38 }, 39 40 startTimer = function() { 41 42 if (!timer) 43 timer = setInterval(function() { 44 if (num>0 && currentUrl!=window.location.href) { 45 currentUrl = window.location.href; 46 window.Hash.check(); 47 } 48 }, freq); 49 50 }, 51 52 stopTimer = function() { 53 54 if (timer) { 55 clearInterval(timer); 56 timer = null; 57 } 58 59 }; 60 61window.Hash = freeze({ 62 63 pushState: function(yes) { 64 65 if (window.history && window.history.pushState) 66 pushState = yes; 67 68 return this; 69 }, 70 71 fragment: function() { 72 73 var hash = getHashParts(); 74 return (pushState) ? 75 window.location.pathname + ((hash[1]) ? '#' + hash[1] : '') 76 : hash[1] || ''; 77 78 }, 79 80 get: function(path, params) { 81 82 var p, fragment = '', parameters = []; 83 84 for(p in params) { 85 if (!Object.prototype.hasOwnProperty(p)) 86 continue; 87 parameters.push(encodeURIComponent(p) + '=' + encodeURIComponent(params[p])); 88 } 89 90 if (parameters.length>0) 91 parameters = '?' + parameters.join('&'); 92 93 return (pushState) ? path + parameters : 94 getHashParts()[0] + '#' + path + parameters; 95 96 }, 97 98 go: function(hash, params) { 99 100 if (this.fragment()!=hash) { 101 var to = this.get(hash, params); 102 103 if (pushState) 104 window.history.pushState(null, document.title, to); 105 else 106 window.location.href = to; 107 } 108 109 return this; 110 }, 111 112 update: function () { 113 114 currentUrl = window.location.href; 115 return this; 116 117 }, 118 119 on: function(hash, callback, title) { 120 121 if (!hashes[hash]) 122 hashes[hash] = {title: title, listeners: []}; 123 124 hashes[hash].listeners.push(callback); 125 num++; 126 startTimer(); 127 128 return this; 129 }, 130 131 check: function() { 132 133 var i, 134 hash, 135 parts, 136 fragment = this.fragment(); 137 138 139 for (hash in hashes) { 140 if (!Object.prototype.hasOwnProperty.call(hashes, hash)) 141 continue; 142 143 hashes[hash].regexp = hashes[hash].regexp || new RegExp(hash); 144 145 if ((parts = hashes[hash].regexp.exec(fragment))) { 146 if (hashes[hash].title) 147 document.title = hashes[hash].title; 148 149 for (i = 0; i<hashes[hash].listeners.length; i++) 150 if (hashes[hash].listeners[i].yep) 151 hashes[hash].listeners[i].yep(fragment, parts); 152 } else { 153 for (i = 0; i<hashes[hash].listeners.length; i++) 154 if (hashes[hash].listeners[i].nop) 155 hashes[hash].listeners[i].nop(fragment); 156 } 157 158 } 159 160 return this; 161 } 162}); 163 164})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.