There are 4 previous versions of this script.
Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)
/*
Geocaching Google Map Enhancements
http://www.lildevil.org/greasemonkey/geocaching-google-map-enhancements
--------------------------------------------------------------------------------
This is a Greasemonkey user script.
Follow the instructions on http://www.lildevil.org/greasemonkey/
to install Greasemonkey and this user script.
--------------------------------------------------------------------------------
*/
// ==UserScript==
// @name GC Google Map Enhancements
// @description This script enhances the geocaching.com Google map page by increasing the map size, hiding disabled caches, showing cache names, and much more!
// @namespace http://www.lildevil.org/greasemonkey/
// @version 1.3
// @copyright 2010-2011, Lil Devil
// @license Attribution-Noncommercial-Share Alike; http://creativecommons.org/licenses/by-nc-sa/3.0/
// @include http://www.lildevil.org/greasemonkey/versions
// @include http://*.geocaching.com/map/*
// ==/UserScript==
// the following is for http://www.jslint.com/
/*jslint bitwise: true, browser: true, nomen: false, undef: true */
/*global $ GM_deleteValue GM_getValue GM_log GM_openInTab GM_registerMenuCommand GM_setValue GM_xmlhttpRequest escape localStorage unescape xPath XPathResult unsafeWindow window Add_Prototypes Adjust_List_Height Adjust_Map_Height Backwards_Compatibility Change_Label_Type Check_for_Update Early_Initialization firstElementChild Get_Google_Link Get_Logged_In_User Get_Offsets Get_Parent Get_URL_Parameter Handle_Filter_Click Hide_Columns Init_PM_Filters Late_Initialization LD_Close_Options_Window LD_Create_Options_Window LD_Open_Options_Window LD_addScript LD_addStyle LD_deleteValue LD_getValue LD_log LD_removeStyle LD_setValue Open_Google_Earth Open_Google_Maps Read_Filter_States Set_Label_Style Toggle_Background_Ovals Toggle_Cache_States Toggle_Filters_Visibility Toggle_Option_Appearance Toggle_Smooth_Zooming Update_Filter_States newElement */
(function(){
Check_for_Update('GC Google Map Enhancements', '1.3');
var mapContainer = $('map-content');
var topLinkBar = $('MapOptions');
if (!mapContainer || !topLinkBar) { return; }
Add_Prototypes();
var MinusButtonGray = 'data:image/gif;base64,' +
'R0lGODlhDAAMAOMMAIqvwoywwo6xxJG0xZO1xpa3x5i4yJq6yZ27y5+9zKG+zaTAzqXBz6XBz6XBz6XBzyH5BAEAAA8ALAAAAAAM' +
'AAwAAAQt8IFJ6wsv6x3E/o8wgNtAkBpRPEXrtqzxGHRNzweaHYj+IAlfQuEjLo7I5CMCADs=';
var PlusButtonGray = 'data:image/gif;base64,' +
'R0lGODlhDAAMAOMMAIqvwoywwo6xxJG0xZO1xpa3x5i4yJq6yZ27y5+9zKG+zaTAzqXBz6XBz6XBz6XBzyH5BAEAAA8ALAAAAAAM' +
'AAwAAAQ58IFJ6wsv6x3EFp4mDNtAagOxEapGFE8hz3JsPEau5/ixHT7NAbFBEDWIxCah1CQUm+gDuqhar48IADs=';
var cm_x = 'data:image/png;base64,' +
'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAT9JREFUOMu1' +
'1aFLg0EcxvHv3Y17EYvdZBZMYrLJgiwZBMFifZNNEIwa12RvMgkmg6AWg8O0MOP+BC3TsjR27vVnOhgv7/bevbIH3nDH3ee98HCn' +
'RASft0TtbGjS4S8nROTHcXtvyNpT6fk5JSI8JspsOdpfllP+kcRx/WG52J/ICBFhAJ2+RfoWERHqfH7/ADoigjoztA4NT7N/3p6I' +
'ijnpe6JkdvyQc6yPctIiVlwYinqjmZPq3NIqO2kIXoYCrFp2dXFxKD4P9dFlm6rwKnQuvAgPQRfCZXgoWgnPA0LqqFlSdGz5Q6uo' +
'Y3oa03Md29NQXNcpfwiu65Q/BNffjudYtAofO3q6a8jqoIvwF0O2tIu+AfBpuVp3MLakMXdxMSuObGjJNv2b53PeUAd7OemapRkD' +
'jhyvXcPN5VTu/NwfKAkh27eh1nMAAAAASUVORK5CYII=';
var cm_dis = 'http://www.geocaching.com/images/gmn/cm_dis.png';
var cm_t = 'data:image/png;base64,' +
'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAACNJREFUOMtj' +
'/P//PwMtABMDjcCowaMGjxo8avCowaMGjxSDAYZXAyl/RY8+AAAAAElFTkSuQmCC';
var cm_hvr = 'data:image/png;base64,' +
'iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAUNJREFUOMvt' +
'lT9LAmEcxz/3R8GcCqlIyMHNq6lyvDfQ1CAI7YIR9AZao6mp8EhocegNFLjrEGTCEV5DTTUcdhAhcQpXei33YDRdnS3hZ/rxGz58' +
'eR74fSXf9xFUNS0PlIE1YJVw3AFtwChZ1pVYSr7vU9U0BTgC9ojGCbBfsqyeGiyOg6SsFIssZjLER6NQpndF4dm2ua3VAHYBBdiR' +
'TnO5TeByNptlvVAgNhz+Ou5NvY7T6QBsyyJpRtcjSQGWdV2MZTn4KJZSKaIyn0yKMS8DCSaImkgAxGX+iKl4Kv4vYm+Swo/BAMCT' +
'gWsAx3UjS1/Hp7YtAwbAU6MRWfw4dhjKheM8tCuVBddxNt76fWLpNDOq+iPhi+dx32xit1oEFXUoDAcAXdMsd00zSmhDvID0rUy3' +
'vpTpXEhZLyjTs5JlnYvlJ6A1ZyNEKksNAAAAAElFTkSuQmCC';
// a few global vars for drag and drop support
var dragTarget = null; // The target object
var dragXoffset = 0; // How much we've moved the element on the horizontal
var dragYoffset = 0; // How much we've moved the element on the vertical
LD_addStyle('.dragable { cursor:move; }');
var PMUpgradeOriginalStyleDisplay = $('uxPMUpgrade').style.display;
var advertHidden = false;
var timeout = null;
var Login_Name = Get_Logged_In_User();
var DEBUG = (Login_Name == 'Lil Devil');
Backwards_Compatibility();
Early_Initialization();
window.addEventListener('load', Late_Initialization, false);
function Early_Initialization() {
// In Greasemonkey 0.8.6 this will run before any page functions run.
// This will also run early in Opera if "user." is removed from the filename.
// In older versions of Greasemonkey, and in Opera with "user." in the filename,
// this function (and everything else in this file) will run after all the page functions.
LD_Create_Options_Window();
// provide spacing for certain links
LD_addStyle('#MapOptions li { white-space:nowrap; margin-right:1em !important; }');
// create a style to prevent certain elements from printing
LD_addStyle('@media print {' +
'.InvisiblePrint { visibility:hidden; } ' +
'hr { display:none; }' +
'}');
// remove a little extra spacing from the Navigation bar
LD_addStyle('#Navigation .BanManWidget { margin-bottom:0; }');
// hide the right-most empty cell in the cache list table
LD_addStyle('#cacheListTable td:last-child, #cacheListTable th:last-child { display:none; }');
// provide a more prominent hover icon for map markers
LD_addStyle('img[src$="cm_hvr.png"] { background:url(' + cm_hvr + ') no-repeat left bottom transparent !important;' +
' height: 0 !important;' +
' width: 0 !important;' +
' padding: 0 0 22px 22px !important;' +
' overflow: hidden !important;' +
' border: 0 !important;' +
' }');
// set the style for the marker labels
LD_addStyle('div.LabeledMarker_markerLabel { font-weight:bold; font-size:85%; ' +
'padding:0 1px; white-space:nowrap; }');
// add some functions to the page
LD_addScript(Toggle_Cache_States);
// hide some stuff at the top and bottom of the page
Toggle_Option_Appearance('Show_Login_Bar');
LD_addStyle('h2, .BreadcrumbsWidget, .OptionSpacer, #ft { display:none; }');
// adjust some margins and padding
document.body.style.padding = '14px'; // originally 1.5em = 19.5px
$('doc3').style.minWidth = '700px'; // originally 950px
Get_Parent($('ctl00_HDHomeLink'), 'div').style.width = 'auto';
Get_Parent($('ctl00_LoginUrl'), 'div').style.width = 'auto';
$('doc3').style.margin = 'auto'; // originally auto 10px
$('Content').style.paddingTop = '3px'; // originally 25px
$('Content').style.paddingRight = '2px'; // originally 1.5em = 19.5px
$('Content').style.paddingBottom = '0'; // originally 1.5em = 19.5px
$('lblMapContent').style.marginTop = '7px'; // originally 1.5em = 19.5px
$('uxSideBar').style.paddingRight = '10px'; // originally part of $('Content').style.paddingRight
// hide the "map size" links
firstElementChild(topLinkBar).style.display = 'none';
// adjust spacing on the right-side info bar
var filterBox = $('uxPremiumFeatures');
var refreshMapLink = $('uxMapRefresh');
$('txtGeocode').style.width = '75%';
$('uxPocketQueryHomePage').childNodes[1].className = 'NoSpacing';
filterBox.style.marginTop = '0.5em';
filterBox.style.padding = '0.4em 0.5em 0.4em 0.6em';
var hideStuffContainer = Get_Parent($('chkHideFound'), 'p');
hideStuffContainer.className = 'NoSpacing';
refreshMapLink.parentNode.style.marginTop = '0.5em';
$('cacheListBounding').style.margin = '0.5em 0 0 0';
$('cacheListBounding').style.height = 'auto';
// set a few items to not show up when printing
topLinkBar.className += ' HidePrint';
$('uxZoomToAddress').className = 'HidePrint';
$('uxPocketQueryHomePage').className = 'HidePrint';
$('uxSideBarCollapse').className += ' InvisiblePrint';
refreshMapLink.className += ' HidePrint';
var chkShowNumbers = $('chkShowNumbers');
chkShowNumbers.className += ' HidePrint';
chkShowNumbers.nextSibling.className = 'HidePrint';
// redefine onclick handlers for a couple of native checkboxes
$('chkHideFound').setAttribute('onclick', 'Toggle_Cache_States(true);');
$('chkHideOwned').setAttribute('onclick', 'Toggle_Cache_States(true);');
// add new checkboxes for hiding ovals and disabled caches
var PQlink = xPath(
'.//a[contains(@href, "/pocket/default.aspx")]',
hideStuffContainer, XPathResult.FIRST_ORDERED_NODE_TYPE);
if (PQlink) {
var targetSpan = PQlink.parentNode;
var newSpan = newElement('label', { 'class' : 'FilterContainer',
style : 'margin-bottom:0; font-weight:normal;',
title : "Hide caches I haven't found and don't own" },
newElement('input', { id : 'chkHideUnfound',
'class' : 'Checkbox',
type : 'checkbox',
onclick : 'Toggle_Cache_States(true);' }),
newElement('img', { src : 'http://www.geocaching.com/images/gmn/cm.png',
width : 16,
height : 16 }),
newElement('img', { src : 'http://www.geocaching.com/images/WptTypes/sm/2.gif',
style : 'position:relative; right:14px; bottom:2px; margin-right:-12px;',
width : 12,
height : 12 }),
newElement(' Hide Unfound Caches')
);
hideStuffContainer.insertBefore(newSpan, targetSpan);
hideStuffContainer.insertBefore(newElement('br', {}), targetSpan);
hideStuffContainer.insertBefore(newElement('span', { 'class' : 'Clear' }), targetSpan);
newSpan = newElement('label', { 'class' : 'FilterContainer',
style : 'margin-bottom:0; font-weight:normal;',
title : 'Hide caches that are disabled' },
newElement('input', { id : 'chkHideDisabled',
'class' : 'Checkbox',
type : 'checkbox',
onclick : 'Toggle_Cache_States(true);' }),
newElement('img', { id : 'sampleDisabled',
src : ($('chk_Highlight_Disabled').checked ? cm_x:cm_dis),
width : 16,
height : 16 }),
newElement(' Hide Disabled Caches')
);
hideStuffContainer.insertBefore(newSpan, targetSpan);
hideStuffContainer.insertBefore(newElement('br', {}), targetSpan);
hideStuffContainer.insertBefore(newElement('span', { 'class' : 'Clear' }), targetSpan);
newSpan = newElement('label', { 'class' : 'FilterContainer',
style : 'margin-bottom:0; font-weight:normal;',
title : 'Hide the white ovals around the cache icons' },
newElement('input', { id : 'chkHideOvals',
'class' : 'Checkbox',
type : 'checkbox',
onclick : Toggle_Background_Ovals }),
newElement('img', { src : 'http://www.geocaching.com/images/gmn/cm.png',
width : 16,
height : 16 }),
newElement(' Hide Backgound Ovals')
);
hideStuffContainer.insertBefore(newSpan, targetSpan);
hideStuffContainer.insertBefore(newElement('br', {}), targetSpan);
hideStuffContainer.insertBefore(newElement('span', { 'class' : 'Clear' }), targetSpan);
}
// add button to hide the filters
filterBox.insertBefore(newElement('img', { id : 'ToggleFilters',
src : MinusButtonGray,
title : 'Click to hide filters',
'class' : 'HidePrint',
style : 'cursor:pointer; float:right; margin-top:2px;',
onclick : Toggle_Filters_Visibility }),
filterBox.firstChild);
// set previous states to the filters
Init_PM_Filters();
// alert(unsafeWindow.lgnds);
// Add Google Map link
var GoogleMapIcon = 'data:image/gif;base64,' +
'R0lGODlhEAAQAMZ2AO4YG9geIeMbH0VLUUhOUOQnH0lRWkxSU0hTYU1TWUxWY1FXWExYa1ZcYlFdbXhUVvA0ODxfuFpfYVVhb1Bi' +
'iUpjm1VlhEVltkVmvFlnf25lZ4RgYdtJS0lquF1tiE1tuk1vwG9wWmJwhFNwtGxxcnp4S1Z4x2h4k3p6WHV5em1+nXh+h36Cg3iE' +
'l2SFzX+FiWyGy4eIfnmJp4eKi4iLjPRucHGR1JOWl4WYsH6X1KedNfSJIpqcnZCgvomg2J+hooaj3PaKjIyi2Iymy6OkpZSlyZWp' +
'vZ+sw6ytrpay4qaxx6e316+4yba4uam44K6719fELr6+v7TB5M3Hf8HExLnH5sfHx7HN78DN6LPS87/P7s/Q0u7ZKrrV87rW88jT' +
'7bjX9c7X7cnZ7frjJ8Hg+tvc3PvU1PrlNMjk/Nrh8fvpXczo/ubn5/zi4ubr9fzxkv31uv3w8PLz8/b5/P788f7+/v//////////' +
'/////////////////////////////yH5BAEKAH8ALAAAAAAQABAAAAfUgH+Cg4SFhVY8JAQOBgspUYZEDR49Mi0tMioKNIQ8CkUr' +
'M1RsdVtNWhksgp5HB011sG01HHI+DEhWCUuusHFBAAEacmkVKTQnLzewZhAAAhtysCAEErvRdGc7BQ/RdXMRCgNKM7BqY1wlZbB1' +
'WBgDCkw/dW9jUCjq6zAfEgRiP3BjdMToBktKBAo0Uhh5MiUElXWwvkTokMAKkgldcjgJU8cNlipCTFxAwEMQCxFgrgCxkcSLiwgj' +
'FJQcREMBjixk1qAZYqEBEUNRUiwwoIAAiZmDAgEAOw==';
topLinkBar.appendChild(newElement('li', {},
newElement('a', { id : 'ViewInMap',
'class' : 'lnk',
href : '#',
onclick : Open_Google_Maps },
newElement('img', { src : GoogleMapIcon }),
newElement(' '),
newElement('span', {}, newElement('View in Google Maps'))
)));
// Add Google Earth link
var GoogleEarthIcon = 'data:image/gif;base64,' +
'R0lGODlhEAAQAOf6AAMHRAsQFggMOQwONRATJBMWNw4WVxUWTBcaQxQcShgaTRcZVhkcRR4eQhwhPhwcYhggYR8iRR4fWBgedCEj' +
'TB4kYh4kciYmXB8oaygnYCgoXiQpaSssSyouRyUrZSAmliotWiQphygpgystZi4yYiUpri0ugSwuhScvkikxhCgvlzM4TDUyaSw3' +
'eSw1hDAzhCowqigypSs0my02ky41py80qi84lzs8ajA9gy44qTU/dDk8fzM7njE8pjY7oUFDXDY9sTpEgTdApzY/uDlEnkZIcTlD' +
'sjhDtjtDsEBKfz9Ik0dJekFNdzxEwztFwUROi0tNgE5WY01Wc0tPpkdSvE5aglpbb1dbiEtV0Fpbh1xcgE9fnWBdfE1YzFBYxU5g' +
'rFtgl1Fcz2Jjf2VmaF5jpWRllWZnhl5omVhnvF9qomVnsWhyfmBxp2hrsnByiWp1i3F0g2R2pHZ1lXp3jGZ013p5i3p6ln1/i32B' +
'gnJ8w357qnt6vG156XyCnHyDnYOBmX6DoXeDt31/yn+ErISJjH2Eun2IpneE4IOLnoGFxIaIrnyI0oiKsISQpomNs4GN132N5IqU' +
'oI+Ss5CSuIyWr4OU3I6R1JWYy5CczpifsZeW5JqksJykt6CiyaOlzqeovaGuwZqv2puv4aiw36Sx5qSz3qu12Ki43K232re7x7C7' +
'6bq9xLe/wrC85ru62a7B4bHB2ru737q99LjF1sS95rfA/7/J1b/L4cfL1LzP78bQ68vU2c/P8c3P/8/O/87T8dbV9dfY9s/b/9jf' +
'2NHd/87k787i/9fi9ODh/9Lp+9np/9nr/97p/+Pv/9/z/+Xw/+Dz/+H1/+/v+/Hu//Xx/+X6//Tz//f0//P3//f48+37//32/vb6' +
'//P8//v5/Pj7//r6//z5//H///f8//r7/fz6//r99vn/8fb+//f+///6//r9//z8///7/vf////7//n///79///9/fv///3+///9' +
'//7/+f/+////+v7//////////////////////////yH5BAEKAP8ALAAAAAAQABAAAAj+AP8JFKhJkKVLgyYNXPjP0YgdatokktVL' +
'kR2GiCiZGkXmhQgTe5C5qjPQEDNt4sQ1qzXlxAMoyD79EYhJWKlczqItI/XEAwlGweT8e7QIxxY2oYxVg3aKSQIQnmLJ8SKDCJpD' +
'kCqJSlYMVpUFErT8AJKjB5UwfOh8ifNKWSswBwZwsCEERhMnWLococEjjypdfW5cUJJCxQckRmIMKVFjgo43mTqVKZQkUJoWLmag' +
'8BHCQgUBDlbA+efn2S1UZ4JgMABhAwAFBQIIJMRql61js0A1knJlSRYxeAaOWZUqyppImzgBkmTGCsM5XBpQQMAgQgcCdxgO1MMi' +
'g4YibhgCBgQAOw==';
topLinkBar.appendChild(newElement('li', {},
newElement('a', { id : 'ViewInEarth',
'class' : 'lnk',
href : '#',
onclick : Open_Google_Earth },
newElement('img', { src : GoogleEarthIcon }),
newElement(' '),
newElement('span', {}, newElement('View in Google Earth'))
)));
// add duplicate "Refresh" link
var dupRefresh = $('uxMapRefresh').cloneNode(true);
dupRefresh.id += '_dup';
topLinkBar.appendChild(newElement('li', {}, dupRefresh));
// add selection for cache labels
var labelType = LD_getValue('Label_Type', 0, Login_Name) - 0;
Set_Label_Style(labelType);
var newSelect = newElement('select', { id : 'labelType',
style : 'font-weight:bold; font-family:inherit;' +
'font-size:inherit; color:inherit;',
'class' : 'HidePrint',
onchange : Change_Label_Type },
newElement('option', { value : 0,
selected : (labelType === 0),
text : 'Number' }),
newElement('option', { value : 1,
selected : (labelType == 1),
text : 'GC Code' }),
newElement('option', { value : 3,
selected : (labelType == 3),
text : 'Code' }),
newElement('option', { value : 2,
selected : (labelType == 2),
text : 'Name' })
);
chkShowNumbers.nextSibling.textContent = 'Show ';
chkShowNumbers.parentNode.insertBefore(newSelect, chkShowNumbers.nextSibling.nextSibling);
var dupLabel = chkShowNumbers.nextSibling.cloneNode(false);
dupLabel.textContent = ' on Map';
chkShowNumbers.parentNode.insertBefore(dupLabel, newSelect.nextSibling);
if (Login_Name) {
GM_registerMenuCommand('Map Enhancements', LD_Open_Options_Window, '', '', 'E');
Toggle_Option_Appearance('Show_MyTopo_Link');
Toggle_Option_Appearance('Show_Self_Link');
Toggle_Option_Appearance('Show_Beta_Map_Link');
Toggle_Option_Appearance('Show_Google_Map_Link');
Toggle_Option_Appearance('Show_Google_Earth_Link');
Toggle_Option_Appearance('Show_Dup_Refresh_Link');
Toggle_Background_Ovals();
}
window.addEventListener('resize', Adjust_Map_Height, false);
// support for FastGCUserMenu
$('hd').addEventListener('DOMNodeInserted', Adjust_Map_Height, false);
var center = null;
if (unsafeWindow.map) {
center = unsafeWindow.map.getCenter();
}
Adjust_Map_Height();
if (center) {
unsafeWindow.map.setCenter(center);
}
// Since this script is now controlling the map height,
// remove functionality from the page function.
unsafeWindow.setMapSize = function (b) { return; };
// getIcon() defines the icon and background graphic for each cache.
// Insert a hook that will add a red "X" overlay if the cache is disabled.
unsafeWindow._getIcon = unsafeWindow.getIcon;
unsafeWindow.getIcon = function (f,e,b,a) { var ico = unsafeWindow._getIcon(f,e,b,a);
if (!a) {
if ($('chk_Highlight_Disabled').checked) {
ico.transparent = cm_x;
} else {
ico.transparent = cm_t;
}
}
return ico;
};
// updateSideBarList() is called after hiding My Finds and My Caches
// so before calling updateSideBarList(), also hide Disabled Caches.
unsafeWindow._updateSideBarList = unsafeWindow.updateSideBarList;
unsafeWindow.updateSideBarList = function() { unsafeWindow.Toggle_Cache_States();
unsafeWindow._updateSideBarList();
};
// setMapLabelDisplay() needs entirely different logic,
// so it's easiest to just rewrite it here instead of hooking it.
unsafeWindow.setMapLabelDisplay =
function (c) { var mrks = unsafeWindow.mrks;
for(var a=0,b=mrks.length;a<b;a++){
if(c){
if(!mrks[a].isHidden()) {
mrks[a].showLabel();
}
}else{
mrks[a].hideLabel();
}
}
Hide_Columns();
};
// createMarker() is called for each cache that is retrieved from the server.
// insert a hook to change the label text
unsafeWindow._createMarker = unsafeWindow.createMarker;
unsafeWindow.createMarker = function (e) { var m = unsafeWindow._createMarker(e);
var labelType = $('labelType').value-0;
switch (labelType) {
case 1 :
m.labelText_ = m.waypointId;
break;
case 2 :
m.labelText_ = m.waypointTitle.trim();
break;
case 3 :
m.labelText_ = m.waypointId.substring(2);
break;
}
return m;
};
// hacker fun - uncomment the following 2 lines to show what is returned by the AJAX call
// unsafeWindow._csae = unsafeWindow.csae;
// unsafeWindow.csae = function(f,d,a) { window.alert(a); unsafeWindow._csae(f,d,a); };
}
function Late_Initialization() {
// This function will run after all the page functions.
// Enable continuous smooth zooming for select browsers
Toggle_Smooth_Zooming();
// Enable the Google Earth Plugin - cool to play with, but not ready for prime time
// unsafeWindow.map.addMapType(unsafeWindow.G_SATELLITE_3D_MAP);
// The "new Maps Beta" link is not initialized properly. Fix it.
var betaMaps = $('lnkViewMapBeta');
var parts = document.location.toString().split('?');
if ((betaMaps.href.indexOf('?') === -1) && (parts.length > 1)) {
betaMaps.href += '?' + parts[1].replace(/&mt=(.*?)(?=&|$)/, '');
// remove any &mt= parameter because it screws up the new map
}
// for some reason the table height is a little short at this point, so resize it again
Adjust_List_Height();
// If not logged in, or not a Premium Member, all the checkboxes get disabled by page script.
// Re-enable the ones that this script created.
if (Login_Name) {
$('chkHideUnfound').removeAttribute('disabled');
}
$('chkHideDisabled').removeAttribute('disabled');
$('chkHideOvals').removeAttribute('disabled');
$('statusbar').style.display = 'none';
}
function Toggle_Filters_Visibility() {
var theButton = $('ToggleFilters');
var filterBox = $('filterLegend');
var PMUpgrade = $('uxPMUpgrade');
if (filterBox.style.display == 'none') { // hidden - show it
filterBox.style.display = 'block';
PMUpgrade.style.display = PMUpgradeOriginalStyleDisplay;
theButton.src = MinusButtonGray;
theButton.title= 'Click to hide filters';
} else { // visible - hide it
filterBox.style.display = 'none';
PMUpgrade.style.display = 'none';
theButton.src = PlusButtonGray;
theButton.title= 'Click to show filters';
}
Adjust_List_Height();
}
function Init_PM_Filters() {
var PMfilters = $('uxSideBar').getElementsByTagName('input');
var states = Read_Filter_States();
for (var i=0, len=PMfilters.length; i < len; i++) {
var thisID = PMfilters[i].id;
if (/^chk(Legend|Hide|Show)/.test(thisID)) { // chkLegend
if (states.hasOwnProperty(thisID)) {
PMfilters[i].checked = states[thisID];
}
PMfilters[i].addEventListener('click', Handle_Filter_Click, false);
}
}
}
function Handle_Filter_Click() {
Update_Filter_States(this.id, this.checked);
}
function Read_Filter_States() {
var filtersStates = {},
str = LD_getValue('PM_Filters', '', Login_Name);
if (str) {
str.split(',').forEach(function(x) {var arr2 = x.split(':');
filtersStates[arr2[0]] = (arr2[1] == 'true');
});
}
return filtersStates;
}
function Write_Filter_States(filtersStates) {
var f, arr=[];
for (f in filtersStates) {
if (filtersStates.hasOwnProperty(f)) {
arr.push(f + ':' + filtersStates[f]);
}
}
LD_setValue('PM_Filters', arr.sort().join(','), Login_Name);
}
function Update_Filter_States(key, val) {
var states = Read_Filter_States();
states[key] = val;
Write_Filter_States(states);
}
function Backwards_Compatibility() {
// adjust for changes from version 1.1 to 1.2
var compat = { 'chkHideOvals' : 'Hide_Background_Ovals',
'chkHideDisabled' : 'Hide_Disabled_Caches',
'chkHideUnfound' : 'Hide_Unfound_Caches'
},
states = Read_Filter_States(),
b, c;
for (c in compat) {
b = LD_getValue(compat[c], null, Login_Name);
if (typeof b == 'boolean') {
states[c] = b;
}
LD_deleteValue(compat[c], Login_Name);
LD_deleteValue(compat[c]);
}
Write_Filter_States(states);
}
function Adjust_Map_Height() {
// if the left navbar is too tall, hide the advertisement so the page won't have any scrollbars
if (!advertHidden) {
var leftNavBar = $('Navigation');
if ((leftNavBar.offsetTop + leftNavBar.offsetHeight + 15) > window.innerHeight) {
advertHidden = true;
LD_addStyle('.BanManWidget { display:none; }');
}
}
var newHeight = window.innerHeight - Get_Offsets(mapContainer).top - 16;
mapContainer.style.height = newHeight + 'px';
if (unsafeWindow.map) {
unsafeWindow.map.checkResize();
}
Adjust_List_Height();
}
function Adjust_List_Height() {
var list = $('cacheListBounding');
var newHeight = window.innerHeight - Get_Offsets(list).top - 21;
list.style.maxHeight = newHeight + 'px';
}
function Set_Label_Style(labelType) {
if (labelType == 2) { // name
LD_addStyle('div.LabeledMarker_markerLabel { font-weight:normal; }', 'LD_Marker_Style');
} else {
LD_removeStyle('LD_Marker_Style');
}
}
function Change_Label_Type() {
var labelType = $('labelType').value-0;
LD_setValue('Label_Type', labelType, Login_Name);
Set_Label_Style(labelType);
var markerLabels = xPath(
'.//div[contains(@class, "LabeledMarker_markerLabel")]',
$('map'), XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
for (var i=0, len=markerLabels.snapshotLength; i<len; i++) {
var thisLabel = markerLabels.snapshotItem(i),
cacheNumber = i.toString(), GCcode = 'error', cacheName = 'error', noGCcode = 'error';
var m = thisLabel.title.match(/^(.*)\((\w+)\)$/);
if (m) {
cacheName = m[1].trim();
GCcode = m[2];
noGCcode = m[2].substring(2);
}
switch (labelType) {
case 1 : // GC code
thisLabel.innerHTML = GCcode;
break;
case 2 : // name
thisLabel.innerHTML = cacheName;
break;
case 3 : // no GC code
thisLabel.innerHTML = noGCcode;
break;
default : // number
thisLabel.innerHTML = cacheNumber;
}
}
Hide_Columns();
}
function Hide_Columns() {
if ($('chkShowNumbers').checked && (Number($('labelType').value) === 0)) {
LD_removeStyle('Hide_Columns_Style');
} else {
LD_addStyle('#cacheListTable td[cellType="cacheIndex"],' +
'#cacheListTable th[cellType="cacheIndex"] { display:none; }', 'Hide_Columns_Style');
}
}
function Handle_Highlight_Disabled_Option() {
var newState = this.checked;
LD_setValue('Highlight_Disabled', newState, Login_Name);
var oldOverlay = cm_x,
newOverlay = cm_t,
newSample = cm_dis;
if (newState) {
oldOverlay = cm_t;
newOverlay = cm_x;
newSample = cm_x;
}
$('sampleDisabled').src = newSample;
var XPath = xPath(
'.//img[contains(@src, "' + oldOverlay + '")]',
$('map'), XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE);
for (var i=0, len=XPath.snapshotLength; i<len; i++) {
XPath.snapshotItem(i).src = newOverlay;
}
}
function Handle_Option_Click() {
var valName = this.id.substring(4);
LD_setValue(valName, this.checked, Login_Name);
switch (valName) {
case 'Show_Login_Bar' : Toggle_Option_Appearance(valName); break;
case 'Show_Link_Bar' : Toggle_Option_Appearance(valName); break;
case 'Show_MyTopo_Link' : Toggle_Option_Appearance(valName); break;
case 'Show_Self_Link' : Toggle_Option_Appearance(valName); break;
case 'Show_Beta_Map_Link' : Toggle_Option_Appearance(valName); break;
case 'Show_Google_Map_Link' : Toggle_Option_Appearance(valName); break;
case 'Show_Google_Earth_Link' : Toggle_Option_Appearance(valName); break;
case 'Show_Dup_Refresh_Link' : Toggle_Option_Appearance(valName); break;
case 'Smooth_Zooming' : Toggle_Smooth_Zooming(); return; // don't adjust map
default : Toggle_Option_Appearance(valName);
}
Adjust_Map_Height();
}
function Toggle_Option_Appearance(valueName) {
var show = LD_getValue(valueName, true, Login_Name),
obj;
switch (valueName) {
case 'Show_Login_Bar' : obj = $('hd'); break;
case 'Show_Link_Bar' : obj = $('MapOptions'); break;
case 'Show_MyTopo_Link' : obj = $('lnkOrderMyTopo').parentNode; break;
case 'Show_Self_Link' : obj = $('lp').parentNode; break;
case 'Show_Beta_Map_Link' : obj = $('lnkViewMapBeta').parentNode; break;
case 'Show_Google_Map_Link' : obj = $('ViewInMap').parentNode; break;
case 'Show_Google_Earth_Link' : obj = $('ViewInEarth').parentNode; break;
case 'Show_Dup_Refresh_Link' : obj = $('uxMapRefresh_dup').parentNode; break;
}
if (obj) {
obj.style.display = show ? '' : 'none';
}
}
function Toggle_Smooth_Zooming() {
if (LD_getValue('Smooth_Zooming', true, Login_Name)) {
unsafeWindow.map.enableContinuousZoom();
} else {
unsafeWindow.map.disableContinuousZoom();
}
}
function Toggle_Background_Ovals() {
var newState = $('chkHideOvals').checked;
Update_Filter_States('chkHideOvals', newState);
if (newState) {
LD_addStyle('#map img[src$="/gmn/cm.png"] { visibility:hidden; }', 'Hide_Background_Oval_Style');
} else {
LD_removeStyle('Hide_Background_Oval_Style');
}
}
function Toggle_Cache_States(upd) { // this function will be injected into the page
// window.alert(lgnds[0]);
var chkHideFound = $('chkHideFound').checked;
var chkHideOwned = $('chkHideOwned').checked;
var chkHideUnfound = $('chkHideUnfound').checked;
var chkHideDisabled = $('chkHideDisabled').checked;
var i, len = mrks.length;
for (i=0; i<len; i++) {
var thisMark = mrks[i];
if ((chkHideFound && thisMark.found) ||
(chkHideOwned && thisMark.owned) ||
(chkHideUnfound && !thisMark.found && !thisMark.owned) ||
(chkHideDisabled && !thisMark.isAvailable)) {
thisMark.hide();
} else if (lgnds.byTypeID(thisMark.wptTypeId).visible) {
thisMark.show();
}
}
if (upd===true) {
updateSideBarList();
}
}
function Get_Google_Link() {
// find the "Powered by Google" image/link and return it's url
var PbGlink;
var poweredBy = xPath(
'.//a/img[contains(@src, "/mapfiles/poweredby.png")]',
mapContainer, XPathResult.FIRST_ORDERED_NODE_TYPE);
if (poweredBy) {
PbGlink = poweredBy.parentNode.href;
} else {
LD_log('"Powered By Google" image/link not found.');
}
return PbGlink;
}
function Open_Google_Earth() {
var viewLink = $('ViewInEarth');
var glink = Get_Google_Link();
if (glink) {
viewLink.href = 'http://maps.google.com/maps?q=' + Get_URL_Parameter('ll', glink) +
'&spn=' + Get_URL_Parameter('spn', glink) + '&output=kml';
} else {
viewLink.href = '#';
return false;
}
}
function Open_Google_Maps() {
var viewLink = $('ViewInMap');
var glink = Get_Google_Link();
if (glink) {
viewLink.target = '_blank';
viewLink.href = glink;
} else {
viewLink.target = '';
viewLink.href = '#';
return false;
}
}
// drag and drop support adapted from http://www.hunlock.com/blogs/Javascript_Drag_and_Drop
function moveHandler(e){
if (!e) { e = window.event; }
dragTarget.parentNode.style.left = e.clientX - dragXoffset + 'px';
dragTarget.parentNode.style.top = e.clientY - dragYoffset + 'px';
e.preventDefault();
}
function dragEnd(e) {
document.removeEventListener('mousemove', moveHandler, false);
document.removeEventListener('mouseup', dragEnd, false);
dragTarget.style.cursor = '';
LD_setValue('Options_X_Position', parseInt(dragTarget.parentNode.style.left, 10), Login_Name);
LD_setValue('Options_Y_Position', parseInt(dragTarget.parentNode.style.top, 10), Login_Name);
}
function dragStart(e){
var dragCursor = '-moz-grabbing';
if (!e) { e = window.event; dragCursor = ''; }
if (e.button > 0) { return; }
dragTarget = e.target || e.srcElement;
if (dragTarget.className.match(/(^|\s)dragable(\s|$)/)) {
dragTarget.style.cursor = dragCursor;
dragXoffset = e.clientX - parseInt(dragTarget.parentNode.style.left, 10);
dragYoffset = e.clientY - parseInt(dragTarget.parentNode.style.top, 10);
document.addEventListener('mousemove', moveHandler, false);
document.addEventListener('mouseup', dragEnd, false);
e.preventDefault();
}
}
function LD_Open_Options_Window() {
var optionsWindow = $('LD_options');
optionsWindow.style.display = '';
var Xpos = LD_getValue('Options_X_Position', -9999, Login_Name);
var Ypos = LD_getValue('Options_Y_Position', -9999, Login_Name);
// set position to center if top edge is off the top of the screen,
// or if half the box is off any other edge of the screen
if ((Ypos < 0) ||
(Xpos + (optionsWindow.offsetWidth / 2) < 0) ||
(Ypos + (optionsWindow.offsetHeight / 2) > window.innerHeight) ||
(Xpos + (optionsWindow.offsetWidth / 2) > window.innerWidth) ) {
Xpos = (window.innerWidth - optionsWindow.offsetWidth) / 2;
Ypos = (window.innerHeight - optionsWindow.offsetHeight) / 2;
}
optionsWindow.style.left = Xpos + 'px';
optionsWindow.style.top = Ypos + 'px';
}
function LD_Close_Options_Window() {
$('LD_options').style.display = 'none';
}
function LD_Create_Options_Window() {
LD_addStyle('#LD_options { position:fixed; background-color:white; z-index:999;' +
'padding-bottom:1em; border:1px solid gray;' +
'border-radius:1.2em; -moz-border-radius:1.2em; -webkit-border-radius:1.2em;' +
'-moz-box-shadow:20px 20px 10px rgba(0,0,0,0.5); }' +
'#LD_options .title { font-weight:bold; padding:0.7em 1em 0.3em;' +
'border-radius:1em 1em 0 0; -moz-border-radius:1em 1em 0 0; -webkit-border-radius:1em 1em 0 0;' +
'background-color:gray; color:white; white-space:nowrap; }' +
'#LD_options label { font-weight:normal; display:block; }');
var optionsWindow = newElement('div', { id : 'LD_options',
style : 'display:none;' });
optionsWindow.appendChild(newElement('div', { 'class' : 'title dragable',
onmousedown : dragStart },
newElement('Geocaching Google Map Enhancement Options')));
var optionsTable = optionsWindow.appendChild(newElement('table',
{ style : 'margin-top:1em; margin-bottom:1em;',
align : 'center' }));
var optionsCell = optionsTable.insertRow(-1).insertCell(-1);
optionsCell.style.textAlign = 'left';
optionsCell.appendChild(newElement('label', { title : 'Disable this to make more room for the map.'},
newElement('input', { type : 'checkbox',
id : 'chk_Show_Login_Bar',
checked : LD_getValue('Show_Login_Bar', true, Login_Name),
onclick : Handle_Option_Click }),
newElement(' Show title/login bar')));
optionsCell.appendChild(newElement('label', { style : 'margin-top:1em;',
title : 'Disable this to make more room for the map.' },
newElement('input', { type : 'checkbox',
id : 'chk_Show_Link_Bar',
checked : LD_getValue('Show_Link_Bar', true, Login_Name),
onclick : Handle_Option_Click }),
newElement(' Show link bar')));
optionsCell.appendChild(newElement('label', { style : 'margin-left:1em;' },
newElement('input', { type : 'checkbox',
id : 'chk_Show_MyTopo_Link',
checked : LD_getValue('Show_MyTopo_Link', true, Login_Name),
onclick : Handle_Option_Click }),
newElement(' Show MyTopo.com link')));
optionsCell.appendChild(newElement('label', { style : 'margin-left:1em;' },
newElement('input', { type : 'checkbox',
id : 'chk_Show_Self_Link',
checked : LD_getValue('Show_Self_Link', true, Login_Name),
onclick : Handle_Option_Click }),
newElement('span', { innerHTML : ' Show “Link to this page” link' } )));
optionsCell.appendChild(newElement('label', { style : 'margin-left:1em;' },
newElement('input', { type : 'checkbox',
id : 'chk_Show_Beta_Map_Link',
checked : LD_getValue('Show_Beta_Map_Link', true, Login_Name),
onclick : Handle_Option_Click }),
newElement('span', { innerHTML : ' Show Beta Maps link' } )));
optionsCell.appendChild(newElement('label', { style : 'margin-left:1em;' },
newElement('input', { type : 'checkbox',
id : 'chk_Show_Google_Map_Link',
checked : LD_getValue('Show_Google_Map_Link', true, Login_Name),
onclick : Handle_Option_Click }),
newElement(' Show Google Maps link')));
optionsCell.appendChild(newElement('label', { style : 'margin-left:1em;' },
newElement('input', { type : 'checkbox',
id : 'chk_Show_Google_Earth_Link',
checked : LD_getValue('Show_Google_Earth_Link', true, Login_Name),
onclick : Handle_Option_Click }),
newElement(' Show Google Earth link')));
optionsCell.appendChild(newElement('label', { style : 'margin-left:1em;' },
newElement('input', { type : 'checkbox',
id : 'chk_Show_Dup_Refresh_Link',
checked : LD_getValue('Show_Dup_Refresh_Link', true, Login_Name),
onclick : Handle_Option_Click }),
newElement('span', { innerHTML : ' Show Duplicate “Refresh Map Now” link' } )));
optionsCell.appendChild(newElement('label', { style : 'margin-top:1em;',
title : 'Enable smooth, continuous zoom animation in Firefox and IE.' },
newElement('input', { type : 'checkbox',
id : 'chk_Smooth_Zooming',
checked : LD_getValue('Smooth_Zooming', true, Login_Name),
onclick : Handle_Option_Click }),
newElement(' Enable smooth zooming')));
optionsCell.appendChild(newElement('label', { style : 'margin-top:1em;',
title : 'Show a red X over disabled caches in addition to the normal gray background.' },
newElement('input', { type : 'checkbox',
id : 'chk_Highlight_Disabled',
checked : LD_getValue('Highlight_Disabled', true, Login_Name),
onclick : Handle_Highlight_Disabled_Option }),
newElement(' Make disabled caches more distinctive')));
optionsWindow.appendChild(newElement('button', { onclick : LD_Close_Options_Window }, newElement('Close')));
document.body.appendChild(optionsWindow);
}
// standard functions
function Add_Prototypes() {
String.prototype.trim = function() {
if (!this.length) { return ''; }
// remove leading and trailing spaces and non-breaking spaces
var s = this.replace(/^[\s\xA0]*/i, '');
return s.replace(/[\s\xA0]*$/i, '');
};
String.prototype.parseHTMLentities = function() {
var d = document.createElement('div');
d.innerHTML = this;
return d.textContent;
};
String.prototype.repeat = function(len) {
return Array(len + 1).join(this);
};
String.prototype.zeroPad = function(len) {
return '0'.repeat(len - this.length) + this;
};
Number.prototype.zeroPad = function(len) {
return this.toString().zeroPad(len);
};
}
function Get_Logged_In_User() {
var loginLogoutLink = $('ctl00_LoginUrl') || $('ctl00_ContentLogin_uxLoginStatus_uxLoginURL');
if (!loginLogoutLink) { return; } // print-friendly page?
var loginNameLink = loginLogoutLink.parentNode.getElementsByTagName('a')[0];
// if logged in, loginNameLink will be the link to the username
// if not logged in, loginNameLink will be the same as loginLogoutLink
if (loginLogoutLink != loginNameLink) {
return loginNameLink.textContent.trim();
}
return '';
}
function Get_URL_Parameter(fieldName, theUrl) {
var parts = (theUrl || document.location).toString().split(/[?#]/);
var queryString = parts[1];
var re = new RegExp('(^|&)' + fieldName + '=(.*?)(&|$)', 'i');
if (queryString.match(re)) {
return RegExp.$2;
}
return '';
}
// offsetHeight and offsetWidth: total size of object
// clientHeight and clientWidth: total size of content area in view
// scrollHeight and scrollWidth: total size of content, some may not be visible due to scrollbars
function Get_Offsets(obj) {
var top = 0, left = 0, width = obj.offsetWidth, height = obj.offsetHeight;
do {
top += obj.offsetTop;
left += obj.offsetLeft;
} while ((obj = obj.offsetParent));
return {top : top,
left : left,
bottom : top + height,
right : left + width };
}
function Get_Parent(thisNode) {
if (!thisNode || !thisNode.parentNode) { return thisNode; }
if (arguments.length < 2) { return thisNode.parentNode; }
for (var i=1; i < arguments.length; i++) {
var nodeNameToLookFor = arguments[i].toLowerCase();
do {
thisNode = thisNode.parentNode;
} while (thisNode && (thisNode.nodeName.toLowerCase() !== nodeNameToLookFor));
}
return thisNode;
}
function firstElementChild(p) {
if (typeof(p.firstElementChild) != 'undefined') {
return p.firstElementChild;
} else {
var child = p.firstChild;
while (child && child.nodeType !== 1) {
child = child.nextSibling;
}
return child;
}
}
function nextElementSibling(p) {
if (typeof(p.nextElementSibling) != 'undefined') {
return p.nextElementSibling;
} else {
var sibling = p.nextSibling;
while (sibling && sibling.nodeType !== 1) {
sibling = sibling.nextSibling;
}
return sibling;
}
}
function previousElementSibling(p) {
if (typeof(p.previousElementSibling) != 'undefined') {
return p.previousElementSibling;
} else {
var sibling = p.previousSibling;
while (sibling && sibling.nodeType !== 1) {
sibling = sibling.previousSibling;
}
return sibling;
}
}
function xPath(expr, context, typ) {
var result = document.evaluate( (expr || '//body'),
(context || document),
null,
(typ || XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE),
null);
switch (typ) {
case XPathResult.NUMBER_TYPE: return result.numberValue;
case XPathResult.STRING_TYPE: return result.stringValue;
case XPathResult.BOOLEAN_TYPE: return result.booleanValue;
case XPathResult.ANY_UNORDERED_NODE_TYPE:
case XPathResult.FIRST_ORDERED_NODE_TYPE: return result.singleNodeValue;
default: return result;
}
}
function newElement() {
if(arguments.length == 1) {
return document.createTextNode(arguments[0]);
} else {
var newNode = document.createElement(arguments[0]),
newProperties = arguments[1];
for (var prop in newProperties) {
if ((prop.indexOf('on') === 0) && (typeof(newProperties[prop]) == 'function')) {
newNode.addEventListener(prop.substring(2), newProperties[prop], false);
} else if (',innerHTML,textContent'.indexOf(','+prop) != -1) {
newNode[prop] = newProperties[prop];
} else if ((',checked,disabled,selected'.indexOf(','+prop) != -1) && !newProperties[prop]) {
// value is false, which browsers do not support, so don't set the property at all
} else if (/\&/.test(newProperties[prop])) {
newNode.setAttribute(prop, newProperties[prop].parseHTMLentities());
} else {
newNode.setAttribute(prop, newProperties[prop]);
}
}
for(var i=2, len=arguments.length; i<len; ++i) {
newNode.appendChild(arguments[i]);
}
return newNode;
}
}
function $() {
if (arguments.length==1) {
return document.getElementById(arguments[0]);
}
var elements = [];
for (var i = 0; i < arguments.length; i++) {
var e = arguments[i];
if (typeof e == 'string') {
e = document.getElementById(e);
}
elements.push(e);
}
return elements;
}
function encodeName(str) {
str = str.replace(/^\s+/,''); // remove leading spaces
str = str.replace(/\s+$/,''); // remove trailing spaces
str = str.replace(/\s+/g,' '); // replace interior spaces with single space
return encodeURIComponent(str).replace(/%20/g, '+');
}
function decodeName(str) {
str += '';
return decodeURIComponent(str.replace(/\+/g, ' '));
}
function LD_setCookie(key, val, life) {
if (!key) { return; }
if (!life) { life = 31536000; }
var expires = new Date().getTime() + (1000 * life);
document.cookie = escape(key) + '=' + escape(val) +
';expires=' + new Date(expires).toGMTString() + ';path=/';
}
function LD_getCookie(key) {
var cookieJar = document.cookie.split('; ');
for (var i=0, len=cookieJar.length; i<len; i++ ) {
var oneCookie = cookieJar[i].split('=');
if (oneCookie[0] == escape(key)) {
return unescape(oneCookie[1]);
}
}
return null;
}
function LD_setValue(key, val, username) {
if (username !== undefined) {
if (username) { // if username is supplied, it must not be blank (i.e. not logged in)
key += '_' + encodeName(username);
} else {
return;
}
}
if ((typeof(GM_setValue) != 'undefined') &&
(GM_setValue.toString().indexOf('not supported') < 0) &&
!window.opera) { // don't use Opera compatibility script because it probably uses cookies
GM_setValue(key, val);
return;
}
val = (typeof(val)).toString().substring(0,1) + val;
try {
localStorage.setItem(key, val);
} catch (err) {
// if we get here, either localStorage doesn't exist, or we got a Security Error using it
LD_setCookie(key, val);
}
}
function LD_getValue(key, defVal, username) {
if (username !== undefined) {
if (username) { // if username is supplied, it must not be blank (i.e. not logged in)
key += '_' + encodeName(username);
} else {
return;
}
}
if ((typeof(GM_setValue) != 'undefined') &&
(GM_setValue.toString().indexOf('not supported') < 0) &&
!window.opera) { // don't use Opera compatibility script because it probably uses cookies
return GM_getValue(key, defVal);
}
var val;
try {
val = localStorage.getItem(key);
} catch (err) {
val = LD_getCookie(key);
}
if (typeof(val) != 'string' || val.length === 0) {
return defVal;
}
var type = val.substr(0,1);
val = val.substr(1);
switch (type) {
case 'b':
return (val == 'true');
case 'n':
return Number(val);
default:
return val;
}
}
function LD_deleteValue(key, username) {
if (username !== undefined) {
if (username) { // if username is supplied, it must not be blank (i.e. not logged in)
key += '_' + encodeName(username);
} else {
return;
}
}
if ((typeof(GM_deleteValue) != 'undefined') && !window.opera) {
GM_deleteValue(key);
} else {
try {
localStorage.removeItem(key);
} catch (err) {
LD_setCookie(key, '', -1);
}
}
}
function LD_removeStyle(theID) {
var styleSheet = document.getElementById(theID);
if (styleSheet) {
styleSheet.parentNode.removeChild(styleSheet);
}
}
function LD_addStyle(css, theID) {
var head = document.getElementsByTagName('head');
if (!head) { return; }
var styleSheet = document.createElement('style');
styleSheet.type = 'text/css';
try {
styleSheet.innerHTML = css;
} catch(err) {
styleSheet.innerText = css;
}
if (theID) {
LD_removeStyle(theID); // no duplicate IDs
styleSheet.id = theID;
}
head[0].appendChild(styleSheet);
}
function LD_addScript(source) {
var head = document.getElementsByTagName('head');
if (!head) { return; }
// Create a script node holding the source code.
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.textContent = source.toString();
// Insert the script node into the page.
document.body.appendChild(script);
}
function LD_xmlhttpRequest(request) {
if ((typeof(GM_xmlhttpRequest) != 'undefined') && !window.opera) {
GM_xmlhttpRequest(request);
} else {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
var responseState = { responseXML : '',
responseText : '',
readyState : xmlhttp.readyState,
responseHeaders : '',
status : 0,
statusText : ''
};
if (xmlhttp.readyState == 4) {
responseState = { responseXML : xmlhttp.responseXML,
responseText : xmlhttp.responseText,
readyState : xmlhttp.readyState,
responseHeaders : xmlhttp.getAllResponseHeaders(),
status : xmlhttp.status,
statusText : xmlhttp.statusText
};
}
if (request['onreadystatechange']) {
request['onreadystatechange'](responseState);
}
if (xmlhttp.readyState == 4) {
if (request['onload'] && xmlhttp.status >= 200 && xmlhttp.status < 300) {
request['onload'](responseState);
}
if (request['onerror'] && (xmlhttp.status < 200 || xmlhttp.status >= 300)) {
request['onerror'](responseState);
}
}
};
try {
//cannot do cross domain
xmlhttp.open(request.method, request.url);
} catch(e) {
if(request['onerror']) {
//simulate a real error
request['onerror']({responseXML : '',
responseText : '',
readyState : 4,
responseHeaders : '',
status : 403,
statusText : 'Forbidden'
});
}
return;
}
if (request.headers) {
for (var prop in request.headers) {
xmlhttp.setRequestHeader(prop, request.headers[prop]);
}
}
xmlhttp.send((typeof(request.data) != 'undefined') ? request.data : null);
}
}
function LD_log(str) {
if ((typeof(GM_log) != 'undefined') && !window.opera) {
GM_log(str);
return;
}
try {
console.log(str);
} catch (err) {}
}
function Debug_Log(str) {
if (DEBUG) {
var now = new Date();
GM_log(now.toLocaleTimeString().slice(0, -3) + '.' + now.getMilliseconds().zeroPad(3) + ': ' + str);
}
}
function Check_for_Update(scriptName, scriptVersion) {
try {
var checkURL = 'http://www.lildevil.org/greasemonkey/current-versions.txt';
if (window.opera) {
// Opera doesn't support cross-domain xmlhttpRequests so use a URL on geocaching.com
checkURL = 'http://www.geocaching.com/seek/log.aspx?LUID=606117a5-b2d0-4450-8fa1-f7faae43e4be';
}
// show version number on http://www.lildevil.org/greasemonkey/versions
var versObj = document.getElementById(scriptName);
if (versObj) {
versObj.innerHTML = scriptVersion;
}
// avoid a flood of dialogs e.g. when opening a browser with multiple tabs open
var now = new Date().getTime();
var DOSpreventionTime = 2 * 60 * 1000; // two minutes
var abbrev = scriptName.replace(/[^A-Z]/g, '');
var lastStart = LD_getValue(abbrev + '_Update_Start', null);
LD_setValue(abbrev + '_Update_Start', now.toString());
if (lastStart && (now - lastStart) < DOSpreventionTime) { return; }
// time to check yet?
var oneDay = 24 * 60 * 60 * 1000;
var lastChecked = LD_getValue(abbrev + '_Update_Last', null);
var checkDays = LD_getValue(abbrev + '_Update_Days', 1);
if (lastChecked && (now - lastChecked) < (oneDay * checkDays)) { return; }
LD_xmlhttpRequest({
method: 'GET',
url: checkURL,
headers: { 'User-Agent' : scriptName + ' v' + scriptVersion + ' auto updater' },
onload: function(result) {
var matches,
regex = new RegExp('[\\s\\>]' + scriptName +
'\\s+v([\\d\\.]+)\\s+(\\d+)\\s+(.+?)[\\<\\s]', 'i');
if (!(matches = regex.exec(result.responseText))) {
LD_log(scriptName + ': Updater: response unrecognized');
return;
}
var theOtherVersion = matches[1];
LD_setValue(abbrev + '_Update_Days', +matches[2]);
var theOtherURL = matches[3];
if (theOtherVersion.replace(/\./g, '') <= scriptVersion.replace(/\./g, '')) { return; } // no updates or older version
if (theOtherURL.indexOf('http') !== 0) { theOtherURL = 'http://' + theOtherURL; }
if (window.confirm( 'The Greasemonkey script "' + scriptName +
'" has been updated.\n\n' +
'The new version is ' + theOtherVersion +
'\nYou are currently using version ' + scriptVersion +
'\n\nClick OK for instructions on how to upgrade.')) {
document.location = theOtherURL; // open in same window to avoid popup blockers
}
}
});
LD_setValue(abbrev + '_Update_Last', new Date().getTime().toString());
}
catch (err) { }
}
})();