/*This file is built from source files. Please do not edit this file directly*/
/* BEGINNING OF pageload.js */
/* globals window Modernizr Hammer */
/* Simple click wrapper */
(function($){
var callback_pathname = {},
$html,
pageload_init = function(){
$html = $("html").bind("doc:page-change", pageload_pagechange);
},
pageload_pagechange = function(event){
var pathname_contains,
pathname = window.location.pathname,
callback,
i;
for(pathname_contains in callback_pathname){
if(pathname.indexOf(pathname_contains) !== -1 ) {
//console.log("calling " + pathname_contains);
for(i = 0; i < callback_pathname[pathname_contains].length; i++){
callback_pathname[pathname_contains][i](event);
}
}
}
};
window.pageload = function(callback, pathname_contains){
if(pathname_contains) {
if(!callback) {
throw "window.pageload() called with callback=" + callback;
}
if(callback_pathname[pathname_contains] === undefined) {
callback_pathname[pathname_contains] = [];
}
callback_pathname[pathname_contains].push(callback);
}
if(pathname_contains && window.location.pathname.indexOf(pathname_contains) === -1 ) return;
if (window.Media && navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) {
document.addEventListener("deviceready", callback, false);
} else {
$(document).ready(callback);
}
};
window.pageload(pageload_init);
}(jQuery));/* END OF pageload.js */
/* BEGINNING OF console.js */
// Avoid `console` errors in browsers that lack a console.
if(!(window.console && console.log)) {
(function() {
var noop = function() {};
var methods = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'markTimeline', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'];
var length = methods.length;
var console = window.console = {};
while (length--) {
console[methods[length]] = noop;
}
}());
};/* END OF console.js */
/* BEGINNING OF find-an-adventure.js */
/*globals alert Modernizr window navigator document setTimeout clearTimeout*/
(function($){
"use strict";
var find_init = function(){
var close_modal_timer,
$last_modal,
delete_any_modal_backdrops = function(){
$(".modal-backdrop").remove();
};
$(".resetFinder").click(function(event){
$(".modal .active").removeClass("active");
$("#no-results").hide();
$("#results").hide();
}),
$(".modal").on("click", "a", function(event){
var $this = $(this),
$list_item = $this.closest("li"),
$modal = $this.closest(".modal"),
modal_id = $modal.attr("id"),
$results = $("#results"),
$no_results = $("#no-results"),
$results_search = $results.find("li"),
$modals = $(".modal"),
$warning_one_two_days = $("#warning-1-2-days");
$last_modal = $modal;
if(modal_id === "where" || modal_id === "time") {
$list_item.toggleClass("active").siblings().removeClass("active");
} else if($modal.is("#see")) {
$list_item.toggleClass("active");
}
$modal.modal('hide');
if(close_modal_timer) {
clearTimeout(close_modal_timer);
}
close_modal_timer = setTimeout(delete_any_modal_backdrops, 250);
$results_search.show();
$warning_one_two_days.hide();
$modals.each(function(index){
var $modal = $(this),
modal_id = $modal.attr("id"),
$active_selections = $modal.find(".active");
$active_selections.each(function(){
var $active_selection = $(this),
active_selection_id = $active_selection.attr("id"),
selector = "." + active_selection_id;
$results_search.not(selector).hide();
$results_search = $results_search.filter(selector);
if(active_selection_id === "time-1-2-days") {
$warning_one_two_days.show();
}
});
});
if($results_search.length > 0) {
$results.show();
$no_results.hide();
} else {
$results.hide();
$no_results.show();
}
event.preventDefault();
});
};
window.pageload(find_init, "/find-an-adventure.html");
}(jQuery));
/* END OF find-an-adventure.js */
/* BEGINNING OF walk.js */
/*global navigator document alert console */
(function($){
"use strict";
var walk_init = function(){
var $dont_miss = $(".dont-miss"),
$shadow = $dont_miss.find(".shadow"),
is_shadowed = false,
$current_dont_miss,
disable_all_dont_miss = function(event){
is_shadowed = false;
if($current_dont_miss !== undefined) {
$current_dont_miss.css("z-index", "auto");
window.hide_all_popovers.apply($current_dont_miss);
$current_dont_miss = undefined;
}
$shadow.removeClass("shadow-visible");
},
$html = $("html").bind("popover-click close-modal", disable_all_dont_miss);
$('#carousel').carousel();
$("body").on("click", ".audio", function(event){
var $this = $(this),
audio_path,
media_player;
if(window.Media) { //use Phonegap-style audio
var onSuccess = function(){},
onError = function onError(error) {
console.log('AUDIO ERROR code: ' + error.code + '\nmessage: ' + error.message + '\n');
};
audio_path = $this.data('audio');
if ( navigator.userAgent.match(/android/i) ) {
audio_path = "/android_asset/www/" + $this.data("audio");
}
media_player = new window.Media(audio_path, onSuccess, onError);
media_player.play();
} else {// Use HTML5 Audio approach
var $audio = $("audio"),
audio_element;
audio_path = $this.data("audio");
if($audio.length === 0) {
$audio = $("").attr("src", audio_path);
$("body").append($audio);
} else {
$audio.attr("src", audio_path);
}
audio_element = $audio.get(0);
audio_element.load();
audio_element.play();
}
});
$(".walk-detail-header a").fastPress(function(){
$(this).parent().toggleClass("open").next(".walk-detail").toggleClass('expanded');
return false;
});
$(".dont-miss a").fastPress();
$("a.icon").click(window.toggle_popover);
$dont_miss.find("a").click(function(){
var $this = $(this);
if(is_shadowed) {
disable_all_dont_miss();
} else {
$current_dont_miss = $this;
$current_dont_miss.css("z-index", "3");
$shadow.addClass("shadow-visible");
is_shadowed = true;
window.show_popover.apply($current_dont_miss);
}
return false;
});
$shadow.click(disable_all_dont_miss);
};
window.pageload(walk_init, "/walk-");
}(jQuery));
/* END OF walk.js */
/* BEGINNING OF map.js */
/*globals map_details maps_details difference_between_positions_in_kilometers format_distance geolocation position_expires_after_milliseconds Modernizr Camera alert*/
(function($){
"use strict";
(function(){
var PIx = 3.141592653589793,
degrees_to_radians = function(degrees) {
return degrees * PIx / 180;
},
kilometres_to_miles = 0.621371,
one_hour_in_milliseconds = 60 * 60 * 1000;
window.format_distance = function(kilometres){
return (Math.round(kilometres * 100) / 100) + "km / " + (Math.round(kilometres * kilometres_to_miles * 100) / 100) + "mi";
};
window.difference_between_positions_in_kilometers = function(lat1, lon1, lat2, lon2, lat3, lon3){
if(lat3 !== undefined && lon3 !== undefined) {
//normally lat3/lon3 aren't given and this function just figures out the distance
// between two points.
// however if lat3/lon3 are given then this function finds out the distance between
// a point and the closest side of a square (e.g. a map graphic).
if(lat1 < lat3) {
lat2 = lat3;
}
if(lon1 > lon3) {
lon2 = lon3;
}
}
// courtesy of http://stackoverflow.com/questions/27928/how-do-i-calculate-distance-between-two-latitude-longitude-points/27943#27943
var R = 6371; // adverage radius of the earth in km
var dLat = degrees_to_radians(lat2-lat1); // Javascript functions in radians
var dLon = degrees_to_radians(lon2-lon1);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(degrees_to_radians(lat1)) * Math.cos(degrees_to_radians(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c; // Distance in km
};
window.position_expires_after_milliseconds = one_hour_in_milliseconds;
}());
var map_init = function(){
var map_id = $("#map_id").text(),
map_details = maps_details[map_id],
open_tooltip,
hammer_defaults = {
prevent_default: true,
scale_treshold: 0,
drag_min_distance: 0
},
pixels_to_longitude_latitude = function(map_x, map_y){
return {
longitude: map_details.longitude + (map_x / map_details.degrees_per_pixel),
latitude: map_details.latitude + (map_y / map_details.degrees_per_pixel)
};
},
longitude_latitude_to_pixels = function(longitude, latitude){
return {
left: Math.abs((longitude - map_details.longitude) / map_details.degrees_per_pixel) + "px",
top: Math.abs((latitude - map_details.latitude) / map_details.degrees_per_pixel) + "px"
};
},
geolocation_success = function(event, position){
/*
Latitude: position.coords.latitude
Longitude: position.coords.longitude
Altitude: position.coords.altitude
Accuracy: position.coords.accuracy
Altitude Accuracy: position.coords.altitudeAccuracy
Heading: position.coords.heading
Speed: position.coords.speed
*/
var youarehere_pixels = {
"top": -parseInt((position.coords.latitude - window.map_details.latitude) / window.map_details.degrees_per_pixel, 10),
"left": parseInt((position.coords.longitude - window.map_details.longitude) / window.map_details.degrees_per_pixel, 10)
},
edge_buffer_pixels = 10,
$youarehere = $("#youarehere").data("latitude", position.coords.latitude).data("longitude", position.coords.longitude),
$youarehere_offmap = $youarehere.find(".offmap"),
youarehere_css = {position: "absolute"},
youarehere_offmap_css = {position: "absolute", left: $youarehere.width() - 15, top: $youarehere.height()},
offmap = false,
difference_distance_in_kilometres = Math.round(
difference_between_positions_in_kilometers(
position.coords.latitude, position.coords.longitude,
window.map_details.latitude, window.map_details.longitude,
window.map_details.extent_latitude, window.map_details.extent_longitude
) * 100) / 100;
$youarehere_offmap.html("you are off the map by about " + format_distance(difference_distance_in_kilometres));
if(youarehere_pixels.left < 0) {
youarehere_pixels.left = edge_buffer_pixels;
youarehere_offmap_css.left = edge_buffer_pixels;
offmap = true;
} else if(youarehere_pixels.left > window.map_details.map_pixel_width){
youarehere_pixels.left = window.map_details.map_pixel_width - edge_buffer_pixels;
youarehere_offmap_css.left -= $youarehere_offmap.width() + edge_buffer_pixels;
offmap = true;
}
if(youarehere_pixels.top < 0) {
youarehere_pixels.top = edge_buffer_pixels;
youarehere_offmap_css.top = edge_buffer_pixels;
offmap = true;
} else if(youarehere_pixels.top > window.map_details.map_pixel_height){
youarehere_pixels.top = window.map_details.map_pixel_height - edge_buffer_pixels;
youarehere_offmap_css.top = -$youarehere_offmap.height() - edge_buffer_pixels;
offmap = true;
}
youarehere_css.left = youarehere_pixels.left + "px";
youarehere_css.top = youarehere_pixels.top + "px";
youarehere_offmap_css.left += "px";
youarehere_offmap_css.top += "px";
$youarehere.css("webkit-box-shadow", "0px 0px 5px " + (position.coords.accuracy / 5000) + "px rgba(0, 0, 255, 0.3)");
if(!offmap){
$youarehere_offmap.hide();
} else {
$youarehere_offmap.css(youarehere_offmap_css).show();
}
$youarehere.css(youarehere_css).show();
user_actions.update_last_updated();
},
geolocation_failure = function(event, msg){
user_actions.$user_actions_panel.find("#refresh-geolocation").addClass("disabled").html("GeoLocation failure,
try again?").attr("title", msg);
user_actions.$user_actions_panel.find(".last-updated").hide();
},
current_time_in_epoch_milliseconds,
user_actions = {
$user_actions_panel: $("#user_actions"),
$photo_preview: $("#photo-preview"),
initialize_user_photos: function(){
var user_photos_string = localStorage["user-photos"],
user_photos,
user_map_photos,
user_map_photo,
i;
if(user_photos_string === undefined) return;
user_photos = JSON.parse(user_photos_string);
if(user_photos[map_details.map_id] === undefined) return;
user_map_photos = user_photos[map_details.map_id];
for(i = 0; i < user_map_photos.length; i++){
user_map_photo = user_map_photos[i];
user_actions.add_photo_to_map(user_map_photo.imageURI, user_map_photo.latitude, user_map_photo.longitude);
}
},
panel_toggle: function(event){
var user_is_off_map = $("#youarehere").find(".offmap").is(":visible"),
error_html,
hyperlink;
if(navigator.camera && !user_is_off_map) {
if(user_actions.$user_actions_panel.hasClass("hidden")){
user_actions.$user_actions_panel.removeClass("hidden");
} else {
user_actions.$user_actions_panel.addClass("hidden");
}
} else {
if(navigator.camera && user_is_off_map) {
error_html = "You're off the map so we can't take location photos
Use your regular camera app";
} else if(!navigator.camera && user_is_off_map) {
error_html = "No camera available
(and you're off the map anyway so we can't take location photos)";
} else if(!navigator.camera && !user_is_off_map) {
error_html = "No camera available";
}
hyperlink = $("").html(error_html).addClass("btn disabled");
user_actions.$user_actions_panel.toggleClass("hidden");
user_actions.$camera_error.html(hyperlink);
user_actions.update_last_updated();
}
},
update_last_updated: function(){
var last_updated_at = window.geolocation_get_last_update(),
difference_in_seconds,
difference_in_minutes,
text;
if(user_actions.$user_actions_panel.is(".hidden")){
return;
}
if(last_updated_at !== undefined) {
difference_in_seconds = Math.round(((new Date()).getTime() - last_updated_at.getTime()) / 1000);
if(difference_in_seconds < 10) {
text = "Last updated a few seconds ago.";
} else if(difference_in_seconds < 120) {
text = "Last updated " + difference_in_seconds + " seconds ago.";
} else {
difference_in_minutes = Math.round(difference_in_seconds / 60);
text = "Last updated " + difference_in_minutes + " minutes ago.";
}
user_actions.$last_updated.attr("title", difference_in_seconds + " seconds").text(text).hide().fadeIn();
} else {
user_actions.$last_updated.hide();
}
},
data_photo_uri_key: "content-image-uri",
show_user_photo: function(event){
var $photo = user_actions.$photo_preview,
$this = $(this);
$photo.attr("src", $this.data(user_actions.data_photo_uri_key)).show();
},
add_photo_to_map: function(imageURI, latitude, longitude, display_immediately, add_to_localStorage){
var user_photo_data = {
"longitude": longitude,
"latitude": latitude
},
user_photo_style,
user_photos,
user_photo;
if(latitude !== undefined && longitude !== undefined) {
user_photo_style = longitude_latitude_to_pixels(longitude, latitude);
user_photo_style.position = "absolute";
}
user_photo_data[user_actions.data_photo_uri_key] = imageURI;
var $photo_icon = $("").addClass("location location-icon location-user-photo").data(user_photo_data);
if(user_photo_style){
$photo_icon.css(user_photo_style);
}
$("#map").append($photo_icon);
if(Modernizr.touch) {
$photo_icon.hammer(hammer_defaults).bind('tap', user_actions.show_user_photo);
} else {
$photo_icon.click(user_actions.show_user_photo);
}
if(display_immediately === true) {
user_actions.show_user_photo.call($photo_icon); //I could unwrap it with .get(0) but it'll still work in show_user_photo
}
if(add_to_localStorage === true) {
user_photos = localStorage["user-photos"];
if(user_photos === undefined) {
user_photos = {};
}
if(user_photos[map_details.map_id] === undefined){
user_photos[map_details.map_id] = [];
}
user_photo = {
"imageURI": imageURI,
"latitude": latitude,
"longitude": longitude
};
user_photos[map_details.map_id].push(user_photo);
localStorage["user-photos"] = JSON.stringify(user_photos);
}
},
take_photo: function(){
var camera_success = function(imageURI) {
var $photo_preview = $("#photo-preview").attr("src", imageURI),
last_known_position = window.geolocation_get_last_position();
if(last_known_position !== undefined) {
user_actions.add_photo_to_map(imageURI, last_known_position.coords.latitude, last_known_position.coords.longitude, true, true);
} else {
user_actions.add_photo_to_map(imageURI, undefined, undefined, true, true);
}
user_actions.$user_actions_panel.addClass("hidden");
},
camera_fail = function onFail(message) {
alert('Failed because: ' + message);
};
navigator.camera.getPicture(camera_success, camera_fail, {quality: 50, destinationType: Camera.DestinationType.FILE_URI});
return false;
},
camera_error_timer:undefined,
$camera_error: $("#user_actions").find(".take-photo"),
$refresh_geolocation: $("#user_actions").find(".refresh-geolocation"),
refresh_geolocation: function(event){
user_actions.$user_actions_panel.find("#refresh-geolocation").removeClass("disabled").text("Refresh GeoLocation");
user_actions.$user_actions_panel.find(".last-updated").show();
window.geolocation_refresh();
return false;
},
$last_updated: $("#user_actions").find(".last-updated")
},
youarehere_hammer,
toggle_map_key = function(event){
var $map_key = $("#map-key");
$map_key.toggle();
return false;
},
$html = $("html"),
last_position = window.geolocation_get_last_position();
$html.bind("doc:geolocation:failure", geolocation_failure);
$html.bind("doc:geolocation:success", geolocation_success);
window.map_details = map_details;
if(last_position){
console.log("there is a position", last_position);
geolocation_success(undefined, last_position);
}
$html.bind("doc:geolocation:success", geolocation_success);
$("#weta").fastPress(window.toggle_popover);
$("#map .location").fastPress(window.toggle_popover);
$("#take-photo").fastPress(user_actions.take_photo);
$("#toggle-map-key, #map-key").fastPress(toggle_map_key);
$("#youarehere, #no_gps").fastPress(user_actions.panel_toggle);
user_actions.initialize_user_photos();
user_actions.$refresh_geolocation.fastPress(user_actions.refresh_geolocation);
};
window.pageload(map_init, "/map-");
}(jQuery));/* END OF map.js */
/* BEGINNING OF visitor-centre.js */
/*globals window localStorage JSON geolocation navigator */
(function($){
"use strict";
var one_second_in_milliseconds = 1000,
geolocation_watchId,
geolocation_key = "geolocation-last-known-position",
last_known_position_json = localStorage[geolocation_key],
geolocationSettings = {
maximumAge:600000,
enableHighAccuracy: true,
timeout: one_second_in_milliseconds * 15
},
$locations,
$visitor_centres_list,
geolocation_success = function(event, position){
var locations;
/*
Latitude: position.coords.latitude
Longitude: position.coords.longitude
Altitude: position.coords.altitude
Accuracy: position.coords.accuracy
Altitude Accuracy: position.coords.altitudeAccuracy
Heading: position.coords.heading
Speed: position.coords.speed
*/
$locations.each(function(){
var $this = $(this),
location_coords = {
"longitude": $this.data("longitude"),
"latitude": $this.data("latitude")
},
distance_away = window.difference_between_positions_in_kilometers(position.coords.latitude, position.coords.longitude, location_coords.latitude, location_coords.longitude);
$this.find(".distance_away").text(distance_away);
$this.data("distance-away", distance_away);
});
locations = $locations.get();
locations.sort(function(a,b){
var $a = $(a),
$b = $(b),
a_distance_away = $a.data("distance-away"),
b_distance_away = $b.data("distance-away");
if(a_distance_away > b_distance_away) return 1;
if(a_distance_away < b_distance_away) return -1;
return 0;
});
$.each(locations, function(index, item){
$visitor_centres_list.append(item);
});
},
visitor_centre_init = function(){
$locations = $(".visitor-centre-location");
$visitor_centres_list = $("#visitor-centres-list");
$("html").bind("doc:geolocation:success", geolocation_success);
};
window.pageload(visitor_centre_init, "visitor-centre.html");
}(jQuery));/* END OF visitor-centre.js */
/* BEGINNING OF helper.js */
/**
* MBP - Mobile boilerplate helper functions
*/
(function(document) {
window.MBP = window.MBP || {};
/**
* Fix for iPhone viewport scale bug
* http://www.blog.highub.com/mobile-2/a-fix-for-iphone-viewport-scale-bug/
*/
MBP.viewportmeta = document.querySelector && document.querySelector('meta[name="viewport"]');
MBP.ua = navigator.userAgent;
MBP.scaleFix = function() {
if (MBP.viewportmeta && /iPhone|iPad|iPod/.test(MBP.ua) && !/Opera Mini/.test(MBP.ua)) {
MBP.viewportmeta.content = 'width=device-width, minimum-scale=1.0, maximum-scale=1.0';
document.addEventListener('gesturestart', MBP.gestureStart, false);
}
};
MBP.gestureStart = function() {
MBP.viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1.6';
};
/**
* Normalized hide address bar for iOS & Android
* (c) Scott Jehl, scottjehl.com
* MIT License
*/
// If we split this up into two functions we can reuse
// this function if we aren't doing full page reloads.
// If we cache this we don't need to re-calibrate everytime we call
// the hide url bar
MBP.BODY_SCROLL_TOP = false;
// So we don't redefine this function everytime we
// we call hideUrlBar
MBP.getScrollTop = function() {
var win = window;
var doc = document;
return win.pageYOffset || doc.compatMode === 'CSS1Compat' && doc.documentElement.scrollTop || doc.body.scrollTop || 0;
};
// It should be up to the mobile
MBP.hideUrlBar = function() {
var win = window;
// if there is a hash, or MBP.BODY_SCROLL_TOP hasn't been set yet, wait till that happens
if (!location.hash && MBP.BODY_SCROLL_TOP !== false) {
win.scrollTo( 0, MBP.BODY_SCROLL_TOP === 1 ? 0 : 1 );
}
};
MBP.hideUrlBarOnLoad = function() {
var win = window;
var doc = win.document;
var bodycheck;
// If there's a hash, or addEventListener is undefined, stop here
if ( !location.hash && win.addEventListener ) {
// scroll to 1
window.scrollTo( 0, 1 );
MBP.BODY_SCROLL_TOP = 1;
// reset to 0 on bodyready, if needed
bodycheck = setInterval(function() {
if ( doc.body ) {
clearInterval( bodycheck );
MBP.BODY_SCROLL_TOP = MBP.getScrollTop();
MBP.hideUrlBar();
}
}, 15 );
win.addEventListener('load', function() {
setTimeout(function() {
// at load, if user hasn't scrolled more than 20 or so...
if (MBP.getScrollTop() < 20) {
// reset to hide addr bar at onload
MBP.hideUrlBar();
}
}, 0);
});
}
};
/**
* Fast Buttons - read wiki below before using
* https://github.com/h5bp/mobile-boilerplate/wiki/JavaScript-Helper
*/
MBP.fastButton = function(element, handler, pressedClass) {
this.handler = handler;
// styling of .pressed is defined in the project's CSS files
this.pressedClass = typeof pressedClass === 'undefined' ? 'pressed' : pressedClass;
if (element.length && element.length > 1) {
for (var singleElIdx in element) {
this.addClickEvent(element[singleElIdx]);
}
} else {
this.addClickEvent(element);
}
};
MBP.fastButton.prototype.handleEvent = function(event) {
event = event || window.event;
switch (event.type) {
case 'touchstart': this.onTouchStart(event); break;
case 'touchmove': this.onTouchMove(event); break;
case 'touchend': this.onClick(event); break;
case 'click': this.onClick(event); break;
}
};
MBP.fastButton.prototype.onTouchStart = function(event) {
var element = event.srcElement;
event.stopPropagation();
element.addEventListener('touchend', this, false);
document.body.addEventListener('touchmove', this, false);
this.startX = event.touches[0].clientX;
this.startY = event.touches[0].clientY;
element.className+= ' ' + this.pressedClass;
};
MBP.fastButton.prototype.onTouchMove = function(event) {
if (Math.abs(event.touches[0].clientX - this.startX) > 10 ||
Math.abs(event.touches[0].clientY - this.startY) > 10) {
this.reset(event);
}
};
MBP.fastButton.prototype.onClick = function(event) {
event = event || window.event;
var element = event.srcElement;
if (event.stopPropagation) {
event.stopPropagation();
}
this.reset(event);
this.handler.apply(event.currentTarget, [event]);
if (event.type == 'touchend') {
MBP.preventGhostClick(this.startX, this.startY);
}
var pattern = new RegExp(' ?' + this.pressedClass, 'gi');
element.className = element.className.replace(pattern, '');
};
MBP.fastButton.prototype.reset = function(event) {
var element = event.srcElement;
rmEvt(element, 'touchend', this, false);
rmEvt(document.body, 'touchmove', this, false);
var pattern = new RegExp(' ?' + this.pressedClass, 'gi');
element.className = element.className.replace(pattern, '');
};
MBP.fastButton.prototype.addClickEvent = function(element) {
addEvt(element, 'touchstart', this, false);
addEvt(element, 'click', this, false);
};
MBP.preventGhostClick = function(x, y) {
MBP.coords.push(x, y);
window.setTimeout(function() {
MBP.coords.splice(0, 2);
}, 2500);
};
MBP.ghostClickHandler = function(event) {
if (!MBP.hadTouchEvent && MBP.dodgyAndroid) {
// This is a bit of fun for Android 2.3...
// If you change window.location via fastButton, a click event will fire
// on the new page, as if the events are continuing from the previous page.
// We pick that event up here, but MBP.coords is empty, because it's a new page,
// so we don't prevent it. Here's we're assuming that click events on touch devices
// that occur without a preceding touchStart are to be ignored.
event.stopPropagation();
event.preventDefault();
return;
}
for (var i = 0, len = MBP.coords.length; i < len; i += 2) {
var x = MBP.coords[i];
var y = MBP.coords[i + 1];
if (Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) {
event.stopPropagation();
event.preventDefault();
}
}
};
// This bug only affects touch Android 2.3 devices, but a simple ontouchstart test creates a false positive on
// some Blackberry devices. https://github.com/Modernizr/Modernizr/issues/372
// The browser sniffing is to avoid the Blackberry case. Bah
MBP.dodgyAndroid = ('ontouchstart' in window) && (navigator.userAgent.indexOf('Android 2.3') != -1);
if (document.addEventListener) {
document.addEventListener('click', MBP.ghostClickHandler, true);
}
addEvt(document.documentElement, 'touchstart', function() {
MBP.hadTouchEvent = true;
}, false);
MBP.coords = [];
// fn arg can be an object or a function, thanks to handleEvent
// read more about the explanation at: http://www.thecssninja.com/javascript/handleevent
function addEvt(el, evt, fn, bubble) {
if ('addEventListener' in el) {
// BBOS6 doesn't support handleEvent, catch and polyfill
try {
el.addEventListener(evt, fn, bubble);
} catch(e) {
if (typeof fn == 'object' && fn.handleEvent) {
el.addEventListener(evt, function(e){
// Bind fn as this and set first arg as event object
fn.handleEvent.call(fn,e);
}, bubble);
} else {
throw e;
}
}
} else if ('attachEvent' in el) {
// check if the callback is an object and contains handleEvent
if (typeof fn == 'object' && fn.handleEvent) {
el.attachEvent('on' + evt, function(){
// Bind fn as this
fn.handleEvent.call(fn);
});
} else {
el.attachEvent('on' + evt, fn);
}
}
}
function rmEvt(el, evt, fn, bubble) {
if ('removeEventListener' in el) {
// BBOS6 doesn't support handleEvent, catch and polyfill
try {
el.removeEventListener(evt, fn, bubble);
} catch(e) {
if (typeof fn == 'object' && fn.handleEvent) {
el.removeEventListener(evt, function(e){
// Bind fn as this and set first arg as event object
fn.handleEvent.call(fn,e);
}, bubble);
} else {
throw e;
}
}
} else if ('detachEvent' in el) {
// check if the callback is an object and contains handleEvent
if (typeof fn == 'object' && fn.handleEvent) {
el.detachEvent("on" + evt, function() {
// Bind fn as this
fn.handleEvent.call(fn);
});
} else {
el.detachEvent('on' + evt, fn);
}
}
}
/**
* Autogrow
* http://googlecode.blogspot.com/2009/07/gmail-for-mobile-html5-series.html
*/
MBP.autogrow = function(element, lh) {
function handler(e) {
var newHeight = this.scrollHeight;
var currentHeight = this.clientHeight;
if (newHeight > currentHeight) {
this.style.height = newHeight + 3 * textLineHeight + 'px';
}
}
var setLineHeight = (lh) ? lh : 12;
var textLineHeight = element.currentStyle ? element.currentStyle.lineHeight : getComputedStyle(element, null).lineHeight;
textLineHeight = (textLineHeight.indexOf('px') == -1) ? setLineHeight : parseInt(textLineHeight, 10);
element.style.overflow = 'hidden';
element.addEventListener ? element.addEventListener('keyup', handler, false) : element.attachEvent('onkeyup', handler);
};
/**
* Enable CSS active pseudo styles in Mobile Safari
* http://alxgbsn.co.uk/2011/10/17/enable-css-active-pseudo-styles-in-mobile-safari/
*/
MBP.enableActive = function() {
document.addEventListener('touchstart', function() {}, false);
};
/**
* Prevent default scrolling on document window
*/
MBP.preventScrolling = function() {
document.addEventListener('touchmove', function(e) {
e.preventDefault();
}, false);
};
/**
* Prevent iOS from zooming onfocus
* https://github.com/h5bp/mobile-boilerplate/pull/108
* Adapted from original jQuery code here: http://nerd.vasilis.nl/prevent-ios-from-zooming-onfocus/
*/
MBP.preventZoom = function() {
var formFields = document.querySelectorAll('input, select, textarea');
var contentString = 'width=device-width,initial-scale=1,maximum-scale=';
var i = 0;
for (i = 0; i < formFields.length; i++) {
formFields[i].onfocus = function() {
MBP.viewportmeta.content = contentString + '1';
};
formFields[i].onblur = function() {
MBP.viewportmeta.content = contentString + '10';
};
}
};
})(document);/* END OF helper.js */
/* BEGINNING OF popover.js */
/*
* Wrapper for Bootstrap's PopOver
* http://twitter.github.com/bootstrap/javascript.html#popovers
* This wrapper ensures that all other popovers are closed when
* a new one opens, and that they can be closed by clicking on
* the body tag and so on.
* NOTE: there's a popular plugin called BootstrapX that claims
* to do the same but it was very buggy on touch devices.
*/
(function($){
"use strict";
var existing_popovers = [],
$window = $(window),
$body,
loaded_init_once = false,
hide_popovers_timeout,
too_small_for_popovers = function($this){
if ($window.width() > 600) return false;
if($("body.walk").length === 1) return true;
if($this.is("#weta")) return true;
return false;
},
popover_init = function(event){
$body = $("body");
$("body.map, #wrapper,#map").click(function(event){
if($(event.target).is(this)) { //if we reached this event directly without bubbling...
window.hide_all_popovers_no_bubbling(event);
}
});
if(!loaded_init_once){
$("body").on("click", ".popover", function(event){
var $html = $("html");
window.hide_all_popovers_no_bubbling(event);
$html.trigger("popover-click");
//there can be detached popovers (e.g. after a page change)
//where the source link is now missing.
//these need to be removed.
if(hide_popovers_timeout){
clearTimeout(hide_popovers_timeout);
}
hide_popovers_timeout = setTimeout(function(){
$(".popover").remove();
//console.log("removing all popovers");
}, 100);
});
loaded_init_once = true;
}
},
get_distance = function(latitude, longitude, include_description){
var last_known_position = localStorage["geolocation-last-known-position"],
current_time_in_epoch_milliseconds = (new Date()).getTime(),
distance_away_in_kilometers,
description_class = include_description ? "with-description" : "";
if(last_known_position !== undefined) {
last_known_position = JSON.parse(last_known_position);
if(last_known_position.timestamp > current_time_in_epoch_milliseconds - window.position_expires_after_milliseconds) {
distance_away_in_kilometers = window.difference_between_positions_in_kilometers(last_known_position.coords.latitude, last_known_position.coords.longitude, latitude, longitude);
return 'Distance: ' + window.format_distance(distance_away_in_kilometers) + '';
}
}
return "";
},
get_popover_placement = function($sender){
//console.log("Determining placement");
var placement = $sender.data("placement"),
offset,
window_dimensions,
scroll_top;
if(placement !== undefined) return placement;
//console.log("No default placement...determining it dynamically");
window_dimensions = {"width": $window.width(), "height": $window.height()};
scroll_top = $window.scrollTop();
offset = $sender.offset();
offset.top -= scroll_top;
offset.top += $sender.height() / 2;
offset.left += $sender.width() / 2;
if(window_dimensions.width > 650) { //use left/right
//console.log("widescreen " + window_dimensions.width + " " + offset.left);
if(offset.left > window_dimensions.width / 2) {
return "left";
} else {
return "right";
}
}
//console.log("smallscreen" + window_dimensions.width);
if(offset.top > window_dimensions.height / 2) {
return "top";
} else {
return "bottom";
}
};
window.hide_all_popovers = function(event, except_this_one){
var $popover;
while(existing_popovers.length){
$popover = existing_popovers.pop();
if(!except_this_one || !$popover.is(except_this_one)) {
$popover.popover('hide');
}
}
};
window.hide_all_popovers_no_bubbling = function(event, except_this_one){
window.hide_all_popovers(event, except_this_one);
if(!event) return;
event.preventDefault();
event.stopPropagation();
if(event.originalEvent) {
event.originalEvent.stopPropagation();
}
};
window.hide_popover = function(event){
$(this).popover('hide');
};
window.toggle_popover_modal = function(event, options) {
var $this = $(this),
this_id = $this.attr("id") || 'generated-id-xxxxxxxxxxxxxx'.replace(/[x]/g, function(){
return (Math.random()*16|0).toString(16);
}),
modal_id = "modal_" + this_id,
$modal = $("#" + modal_id);
if($modal.length === 0) {
$modal = $("