Skip to content

Commit

Permalink
moved MM.Hash into core
Browse files Browse the repository at this point in the history
  • Loading branch information
Shawn Allen committed Dec 13, 2011
1 parent 841c133 commit 95e7a24
Show file tree
Hide file tree
Showing 5 changed files with 239 additions and 3 deletions.
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -9,6 +9,7 @@ JS_FILES = \
src/projection.js \
src/provider.js \
src/mouse.js \
src/hash.js \
src/touch.js \
src/callbacks.js \
src/requests.js \
Expand Down
3 changes: 1 addition & 2 deletions examples/hash/index.html
Expand Up @@ -3,15 +3,14 @@
<head>
<title>ModestMaps JS: Hash URLs</title>
<script type="text/javascript" src="../../modestmaps.js"></script>
<script type="text/javascript" src="modestmaps.hash.js"></script>
<!-- <script type="text/javascript" src="modestmaps.hash.js"></script> -->
<script type="text/javascript">
var MM = com.modestmaps,
map, hash;

function initMap() {
var provider = new MM.TemplatedMapProvider("http://acetate.geoiq.com/tiles/acetate/{Z}/{X}/{Y}.png");
map = new MM.Map("map", provider);

hash = new MM.Hash(map);
}

Expand Down
118 changes: 118 additions & 0 deletions modestmaps.js
Expand Up @@ -1038,6 +1038,124 @@ var MM = com.modestmaps = {
}
}
};

var HAS_HASHCHANGE = (function() {
var doc_mode = window.documentMode;
return ('onhashchange' in window)
&& (doc_mode === undefined || doc_mode > 7);
})();

MM.Hash = function(map) {
this.onMapMove = MM.bind(this.onMapMove, this);
this.onHashChange = MM.bind(this.onHashChange, this);
if (map) {
this.init(map);
}
};

MM.Hash.prototype = {
map: null,
lastHash: null,

parseHash: function(hash) {
var args = hash.split("/");
if (args.length == 3) {
var zoom = parseInt(args[0]),
lat = parseFloat(args[1]),
lon = parseFloat(args[2]);
if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
return false;
} else {
return {
center: new MM.Location(lat, lon),
zoom: zoom
};
}
} else {
return false;
}
},

formatHash: function(map) {
var center = map.getCenter(),
zoom = map.getZoom(),
precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
return "#" + [zoom,
center.lat.toFixed(precision),
center.lon.toFixed(precision)
].join("/");
},

init: function(map) {
this.map = map;
this.map.addCallback("drawn", this.onMapMove);
// reset the hash
this.lastHash = null;
this.onHashChange();

if (!this.isListening) {
this.startListening();
}
},

remove: function() {
this.map = null;
if (this.isListening) {
this.stopListening();
}
},

onMapMove: function(map) {
if (this.movingMap) {
return false;
}
var hash = this.formatHash(map);
if (this.lastHash != hash) {
location.replace(hash);
this.lastHash = hash;
}
},

onHashChange: function() {
var hash = location.hash;
if (hash === this.lastHash) {
// console.info("(no change)");
return;
}
var sansHash = hash.substr(1),
parsed = this.parseHash(sansHash);
if (parsed) {
// console.log("parsed:", parsed.zoom, parsed.center.toString());
this.movingMap = true;
this.map.setCenterZoom(parsed.center, parsed.zoom);
this.movingMap = false;
} else {
// console.warn("parse error; resetting");
this.onMapMove(this.map);
}
},

isListening: false,
hashChangeInterval: null,
startListening: function() {
if (HAS_HASHCHANGE) {
window.addEventListener("hashchange", this.onHashChange, false);
} else {
clearInterval(this.hashChangeInterval);
this.hashChangeInterval = setInterval(this.onHashChange, 50);
}
this.isListening = true;
},

stopListening: function() {
if (HAS_HASHCHANGE) {
window.removeEventListener("hashchange", this.onHashChange);
} else {
clearInterval(this.hashChangeInterval);
}
this.isListening = false;
}
};
MM.TouchHandler = function() { };

MM.TouchHandler.prototype = {
Expand Down
2 changes: 1 addition & 1 deletion modestmaps.min.js

Large diffs are not rendered by default.

118 changes: 118 additions & 0 deletions src/hash.js
@@ -0,0 +1,118 @@

var HAS_HASHCHANGE = (function() {
var doc_mode = window.documentMode;
return ('onhashchange' in window)
&& (doc_mode === undefined || doc_mode > 7);
})();

MM.Hash = function(map) {
this.onMapMove = MM.bind(this.onMapMove, this);
this.onHashChange = MM.bind(this.onHashChange, this);
if (map) {
this.init(map);
}
};

MM.Hash.prototype = {
map: null,
lastHash: null,

parseHash: function(hash) {
var args = hash.split("/");
if (args.length == 3) {
var zoom = parseInt(args[0]),
lat = parseFloat(args[1]),
lon = parseFloat(args[2]);
if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
return false;
} else {
return {
center: new MM.Location(lat, lon),
zoom: zoom
};
}
} else {
return false;
}
},

formatHash: function(map) {
var center = map.getCenter(),
zoom = map.getZoom(),
precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
return "#" + [zoom,
center.lat.toFixed(precision),
center.lon.toFixed(precision)
].join("/");
},

init: function(map) {
this.map = map;
this.map.addCallback("drawn", this.onMapMove);
// reset the hash
this.lastHash = null;
this.onHashChange();

if (!this.isListening) {
this.startListening();
}
},

remove: function() {
this.map = null;
if (this.isListening) {
this.stopListening();
}
},

onMapMove: function(map) {
if (this.movingMap) {
return false;
}
var hash = this.formatHash(map);
if (this.lastHash != hash) {
location.replace(hash);
this.lastHash = hash;
}
},

onHashChange: function() {
var hash = location.hash;
if (hash === this.lastHash) {
// console.info("(no change)");
return;
}
var sansHash = hash.substr(1),
parsed = this.parseHash(sansHash);
if (parsed) {
// console.log("parsed:", parsed.zoom, parsed.center.toString());
this.movingMap = true;
this.map.setCenterZoom(parsed.center, parsed.zoom);
this.movingMap = false;
} else {
// console.warn("parse error; resetting");
this.onMapMove(this.map);
}
},

isListening: false,
hashChangeInterval: null,
startListening: function() {
if (HAS_HASHCHANGE) {
window.addEventListener("hashchange", this.onHashChange, false);
} else {
clearInterval(this.hashChangeInterval);
this.hashChangeInterval = setInterval(this.onHashChange, 50);
}
this.isListening = true;
},

stopListening: function() {
if (HAS_HASHCHANGE) {
window.removeEventListener("hashchange", this.onHashChange);
} else {
clearInterval(this.hashChangeInterval);
}
this.isListening = false;
}
};

0 comments on commit 95e7a24

Please sign in to comment.