Wow, after spending some time experimenting with it, I've finally managed to achieve the desired outcome.
Although it may not look perfect due to some necessary workarounds, it does the job. Feel free to check out the fiddle to see it in action.
Here are the steps I took:
Firstly, I had to override the default behavior of addEventListener
:
var addEvent = EventTarget.prototype.addEventListener;
var events = [];
EventTarget.prototype.addEventListener = function(type, listener) {
addEvent.apply(this, [].slice.call(arguments));
events.push({
element: this,
type: type,
listener: listener
});
}
Next, I created a helper function called removeEvents
. This function removes all event listeners from an element.
var removeEvents = function(el, type) {
var elEvents = events.filter(function(ev) {
return ev.element === el && (type ? ev.type === type : true);
});
for (var i = 0; i < elEvents.length; i++) {
el.removeEventListener(elEvents[i].type, elEvents[i].listener);
}
}
When creating the script
tag according to Microsoft's guidelines:
var s = d.createElement('script');
s.type = 'text/javascript';
s.charset = 'UTF-8';
s.src = ((location && location.href && location.href.indexOf('https') == 0) ? 'https://ssl.microsofttranslator.com' : 'http://www.microsofttranslator.com') + '/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKkd965FeEGM5JtQ**&ctf=True&ui=true&settings=Manual&from=';
var p = d.getElementsByTagName('head')[0] || d.dElement;
p.insertBefore(s, p.firstChild);
We need to add a load
event listener to that script
, and the code below explains it thoroughly:
s.addEventListener('load', function() {
// When the translation changes, the plugin calls the TranslateArray method
// So, we store the original method in a variable and then override it
var translate = Microsoft.Translator.TranslateArray;
Microsoft.Translator.TranslateArray = function() {
// We call the original method
translate.apply(this, [].slice.call(arguments));
// Since the translation is not immediately available
// And we have no control over when it will be ready
// I created a function to wait for it
waitForTranslation(function() {
// Once the translation is available
// We select all elements with a lang attribute
// And remove all their mouseover event listeners
[].forEach.call(d.querySelectorAll('[lang]'), function(item, i) {
removeEvents(item, 'mouseover');
});
});
}
// This helper function waits for the translation to be ready
function waitForTranslation(cb) {
// Since we can't control the translation callback
// I checked if the Translating label is visible as a workaround
// The function keeps running until the label is hidden again
// Then it calls our callback function
var visible = d.getElementById('FloaterProgressBar').style.visibility;
if (visible === 'visible') {
setTimeout(function() {
waitForTranslation(cb);
}, 0);
return;
}
cb();
}
});
Update 1
Upon re-evaluating your question, it appears you want to hide all widgets entirely.
To do so, you need to insert the following code once the translation is retrieved:
waitForTranslation(function() {
document.getElementById('MicrosoftTranslatorWidget').style.display = 'none';
document.getElementById('WidgetLauncher').style.display = 'none';
document.getElementById('LauncherTranslatePhrase').style.display = 'none';
document.getElementById('TranslateSpan').style.display = 'none';
document.getElementById('LauncherLogo').style.display = 'none';
document.getElementById('WidgetFloaterPanels').style.display = 'none';
// additional code
});
I've prepared another version of the fiddle for you to demonstrate this new behavior. You can access it here.
Update 2
You can prevent the widget from appearing completely by applying the following CSS code:
#MicrosoftTranslatorWidget, #WidgetLauncher, #LauncherTranslatePhrase, #TranslateSpan, #LauncherLogo, #WidgetFloaterPanels {
opacity: 0!important;
}
Furthermore, you can also hide the pre-translated text initially by setting the document.body
display to none and revealing it only when the page is fully translated:
(function(w, d) {
document.body.style.display = 'none';
/* (...) */
s.addEventListener('load', function() {
var translate = Microsoft.Translator.TranslateArray;
Microsoft.Translator.TranslateArray = function() {
translate.apply(this, [].slice.call(arguments));
waitForTranslation(function() {
/* (...) */
document.body.style.display = 'block';
});
}
});
});
Feel free to check out the final version of the fiddle I've crafted here.