0

I've written an userscript for geocaching.com which switches the language automatically to a specified language (German), if English was set by an external app.
It worked fine until about 10 days ago, for no reason I could imagine.

If I remove @grant from the script, it works again, but causes several issues with the rest of the page.
Any @grant I tried, including none, breaks the script.

It's still working as it's supposed to do in Chrome. But I've already heard, Tampermonkey and Chrome are a little different than Greasemonkey on Firefox.

Any idea I can give a try is very welcome. Here's the script:

// ==UserScript==
// @name     c:geo LangFix Deutsch BETA
// @include  https://www.geocaching.com/*/*/*
// @include  https://www.geocaching.com/*/*
// @include  https://www.geocaching.com/*
// @include  https://www.geocaching.com
// @include  http://www.geocaching.com/*/*/*
// @include  http://www.geocaching.com/*/*
// @include  http://www.geocaching.com/*
// @include  http://www.geocaching.com
// @exclude  http://www.geocaching.com/account/messagecenter
// @exclude  https://www.geocaching.com/map/*
// @exclude  https://www.geocaching.com/map
// @version  1.2
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @grant    GM_xmlhttpRequest
// ==/UserScript==

var TargetLink          = $('a[href*="LocaleList$ctl04$uxLocaleItem"]');
var LanguageSwitch      = $("div.LocaleText:contains('Choose Language')");

if (TargetLink.length && LanguageSwitch.length)
    window.location.assign (TargetLink[0].href);
Brock Adams
  • 90,639
  • 22
  • 233
  • 295

1 Answers1

2

The main issue is that the href, that the script is trying to assign, is actually a javascript function. That is:

TargetLink[0].href has a value of javascript:__doPostBack('ctl00$uxLocaleList$uxLocaleList$ctl04$uxLocaleItem','').

Many browsers will still allow you to pass a javascript: URL to location.assign(), but Firefox has been restricting this practice of late. (See GM bug 2232,  Firefox bug 1192821, etc.) This is especially true across sandboxes (@grant set to other than none).

A better practice is to click on such links by sending mouse event(s), see below.

Other minor issues with that script:

  1. The @includes are overlapping, redundant, and possibly a performance drag. The @match statement, below, should be all you need.
  2. Likewise, the @excludes can be condensed.
  3. Some geocaching.com pages use a different structure for the language change mechanism. I added an extra selector to catch an additional scheme. (There is at least one more, rarer, scheme that is not caught by either script.)
  4. Selector components like LocaleList$ctl04$uxLocaleItem are extremely brittle and liable to change on a whim. Avoid these as much as possible.
  5. Under some circumstances, that site loads many iframes -- leading to jQuery errors on some of the frames. Use @noframes to block that and speed things up.

Given all that, this complete script should work much better for you than the old one did:

// ==UserScript==
// @name     c:geo LangFix Deutsch BETA
// @match    *://www.geocaching.com/*
// @exclude  http://www.geocaching.com/account/messagecenter
// @exclude  https://www.geocaching.com/map/*
// @version  2.0
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @noframes
// @grant    GM_xmlhttpRequest
// ==/UserScript==

var EnglishPageIndicator    = $(".selected-language > a:contains(English)");
if (EnglishPageIndicator.length) {
    var GermanLnk   = $(
        ".language-selector > .language-list > ul > li > a:contains(Deutsch)," +
        ".LocaleList > .language-list > li > a:contains(Deutsch)"
    );
    //-- Don't try to assign a JS location!  Click the link instead.
    var clickEvent  = document.createEvent('MouseEvents');
    clickEvent.initEvent ("click", true, true);
    GermanLnk[0].dispatchEvent (clickEvent);
}
Community
  • 1
  • 1
Brock Adams
  • 90,639
  • 22
  • 233
  • 295