Hallo Leute, ich brauche mal eure Hilfe.
Ich habe hier ein GreaseMonkey-Skript, mit dem ich die Oberfläche von Facebook ins Obersorbische bzw. Niedersorbische übersetzen kann, obwohl diese beiden Sprachen von FB nicht unterstützt werden. Das Skript setzt auf Deutsch auf.
Am Anfang des Skripts werden 3 Arrays für die verwendeten HTML-Tags, die DIV-Klassen und die SPAN-Klasssen definiert. Am Ende des Skripts steht der entsprechende JS-Sourcecode. In der Mitte des SKripts werden die Strings mit dem deutschen Original-Text und dem zu verwendenden sorbischen Text erfasst. Die deutschen Original-Strings werden also bei FB ausgelesen und durch die sorbischen Strings ersetzt. Das klappt ganz gut, manchmal ohne Nutzung einer CSS-Klasse, manchmal mit Nutzung einer CSS-Klasse eines DIV-Elements und manchmal mit Hilfe einer CSS-Klasse eines SPAN-Elements. Dafür die oben erwähnten drei Arrays.
Es gibt jedoch einen Spezialfall, der sich hartnäckig weigert zu funktionieren. Das ist, wenn der Originalstring aus einem HTML-Attribut ausgelesen wird, das sind meistens die HTML5-Attribute placeholder und aria-label für die Tags TEXTAREA und INPUT. Teilweise ist auch zusätzlich noch das Attribut title angegeben, das, obwohl hier der String ebenfalls in einem Attribut steht, funktioniert. Aber eben nur als Tooltip. Da ich bei TEXTAREA placeholder="" bzw. INPUT placeholder="" Platzhaltertext habe, der den Tooltip-Text überlagert, steht dann immer der unübersetzte Text drüber und nur der Tooltip-Text wird bei Mouseover übersetzt angezeigt, sofern vorhanden.
Ich hoffe nun, dass ihr ein Häppchen JS-Code für mein Skript habt, um die Attribute placeholder und aria-label auslesen zu können.
Das Skript ist stark verkürzt, im Original hat es momentan 1905 Zeilen. Lediglich der Quellcode am Ende dieses Code-Fensters hier ist vollständig. Als String-Beispiel ist lediglich der hartnäckige String "Was machst du gerade?" angegeben, der sich auf der FB-Startseite in der Mitte oben als Platzhaltertext im Statusfeld befindet. Er steht als Text im placeholder-Attribut eines TEXTAREA-Tags.
Vielen Dank im voraus.
milupo
var tags = new Array();
tags.push('h2');
//tags.push('h3'); // Friend Requests, Notifications, ...
tags.push('h4'); // Sponsored, Ticker, ...
tags.push('h5'); // new in Sept 2012 for "was tagged in...", "added %d new photos", etc.
tags.push('h6'); // %a commented on %a.
tags.push('label'); // Comment
tags.push('a'); // many... (should do last for "context sensitive" stuff)
tags.push('abbr'); // Day change in Message window
tags.push('th');
tags.push('td');
tags.push('button');
tags.push('p');
//tags.push('input');
tags.push('option');
tags.push('textarea');
tags.push('strong');
var divclasses = new Array();
divclasses.push('innerWrap'); // Write a comment... <textarea>
//divclasses.push('UIImageBlock_Content UIImageBlock_ICON_Content'); // 2 people like this
divclasses.push('_8m _8u'); // 2 people like this (etc.)
divclasses.push('mvm pll uiP fsm');
divclasses.push('mvm pll uiP fsm fcg');
divclasses.push('linkWrap');
divclasses.push('_4rk');
divclasses.push('_43qm _43qf');
function translate(x) {
d = x;
// Translations go here
...
...
...
d = r(d, '(^|="|>)Was machst du gerade\\?(?=($|"|<))', "$1"+"Co cyniš rowno?");
...
return d;
}
function translateOnInsert( node ) {
//var logmsg = 'inserted a ' + node.nodeName + ' node; untranslated elements: ';
for (n = 0; n < tags.length; n++) {
var tagmatches = node.getElementsByTagName(tags[n]);
for ( i = 0; i < tagmatches.length; i++ ) {
// innerHTML often empty (never null)
if (!tagmatches[i].hasAttribute('indigenous') &&
tagmatches[i].innerHTML != '') {
// logmsg = logmsg + tagmatches[i].nodeName + ' ';
tagmatches[i].innerHTML = translate(tagmatches[i].innerHTML);
tagmatches[i].setAttribute('indigenous', true);
}
}
}
var divs = node.getElementsByTagName('div');
for (i = 0; i < divs.length; i++ ) {
if (!divs[i].hasAttribute('indigenous')) {
for (n = 0; n < divclasses.length; n++) {
if (divs[i].className == divclasses[n]) {
// logmsg = logmsg + 'DIV.' + divclasses[n] + ' ';
divs[i].innerHTML = translate(divs[i].innerHTML);
divs[i].setAttribute('indigenous', true);
break;
}
}
}
}
var spans = node.getElementsByTagName('span');
for (i = 0; i < spans.length; i++ ) {
if (!spans[i].hasAttribute('indigenous')) {
for (n = 0; n < spanclasses.length; n++) {
if (spans[i].className == spanclasses[n]) {
// logmsg = logmsg + 'SPAN.' + spanclasses[n] + ' ';
spans[i].innerHTML = translate(spans[i].innerHTML);
spans[i].setAttribute('indigenous', true);
break;
}
}
}
}
// GM_log(logmsg);
}
// This was (only) needed to handle updates to time stamps
function listen_for_change(evt)
{
var node = evt.target;
//GM_log('in change node, data='+node.data+'; was='+evt.prevValue);
document.body.removeEventListener( 'DOMCharacterDataModified', listen_for_change, false );
node.data = translate(node.data);
document.body.addEventListener( 'DOMCharacterDataModified', listen_for_change, false );
}
function listen_for_add(evt)
{
var node = evt.target;
if (node.nodeType == document.ELEMENT_NODE &&
node.nodeName != 'SCRIPT' &&
node.nodeName != 'INPUT') {
document.body.removeEventListener( 'DOMNodeInserted', listen_for_add, false );
translateOnInsert(node);
document.body.addEventListener( 'DOMNodeInserted', listen_for_add, false );
}
else if (node.nodeType == document.TEXT_NODE) { // time stamps only
document.body.removeEventListener( 'DOMNodeInserted', listen_for_add, false );
node.data = translate(node.data);
document.body.addEventListener( 'DOMNodeInserted', listen_for_add, false );
}
}
function initme()
{
document.body.addEventListener( 'DOMNodeInserted', listen_for_add, false );
// document.body.addEventListener( 'DOMCharacterDataModified', listen_for_change, false );
document.body.innerHTML = translate(document.body.innerHTML);
}
document.addEventListener( "DOMContentLoaded", initme, false);
Alles anzeigen