MediaWiki:Gadget-section-links.js: Różnice pomiędzy wersjami

Z Wikisłownika – wolnego słownika wielojęzycznego
Usunięta treść Dodana treść
na razie nie bede korzystal z module.exports, jedyne uzycie w translation-editor juz wycofane; wiem, ze dziala, na razie nie mam dobrego pomyslu i chce najpierw dokonczyc przerobke skryptu
przenosze zamiane lacznika na polpauze w zakresach do MediaWiki:Gadget-term-num.js
Linia 9: Linia 9:
/*
/*
Funkcje skryptu:
Funkcje skryptu:
* zmiana linka w polu {{odmiana}} w zależności od języka sekcji
* obsługa szablonu {{język linków}}
* obsługa szablonu {{język linków}}
* dodanie kodów języka do linków w artykułach i w kategoriach
* dodanie kodów języka do linków w artykułach i w kategoriach
* czarne self-linki tylko jeśli prowadzą do tej samej sekcji językowej
* czarne self-linki tylko jeśli prowadzą do tej samej sekcji językowej
* klasy CSS dla sekcji językowych i pól
* klasy CSS dla sekcji językowych i pól
* zamiana łącznika na półpauzę w zakresach, np. (1.1-2) na (1.1–2)
* justowanie indeksu a tergo do prawej
* równe szerokości kolumn w kategoriach
Przetestowane pod IE 7, IE 8, FF 3.6, Opera 10.50, Google Chrome 4.1.249.1036, Opera Mini, Nokia OSS
Przetestowane pod IE 7, IE 8, FF 3.6, Opera 10.50, Google Chrome 4.1.249.1036, Opera Mini, Nokia OSS
Autor: [[user:Olaf]]. Zmierzony narzut czasowy: 0.1-0.3 s
Autor: [[user:Olaf]]. Zmierzony narzut czasowy: 0.1-0.3 s
Linia 60: Linia 56:
// http://stackoverflow.com/questions/14947307
// http://stackoverflow.com/questions/14947307
var om$RegexpHref = /^(\d+)?[^\d]/;
var om$RegexpHref = /^(\d+)?[^\d]/;

// https://regex101.com/r/v7tm5S/1/
var om$RegexpNum = /\((?:(?:\d+|\d+-\d+|\d+\.\d+(?:-\d+)?)(?:, *)?)+\)/g;

var om$RegexpDash = /([0-9])-([0-9])/g;

var om$NumParser = function ( textNode ) {
var matches, num, trailingText,
initialContent = textNode.nodeValue,
j = 0;

// https://developer.mozilla.org/en-US/docs/Web/API/Text/splitText
while ( ( matches = om$RegexpNum.exec( initialContent ) ) !== null ) {
trailingText = textNode.splitText( textNode.nodeValue.indexOf( matches[ 0 ] ) );
num = document.createElement( 'span' );
num.className = mw.format( 'term-num lang-$1 fldn-$2 fldt-$3', om$CurLanguageId, om$SectNum, om$CurField );
num.textContent = matches[ 0 ].replace( om$RegexpDash, '$1–$2' );
textNode.parentNode.insertBefore( num, trailingText );
trailingText.nodeValue = trailingText.nodeValue.slice( num.textContent.length );
textNode = trailingText;
j++;
}
return j;
};


function om$ChangeLinks( node ) {
function om$ChangeLinks( node ) {
Linia 509: Linia 480:
}
}
}
}
}
if ( subNode.nodeType === Node.TEXT_NODE ) {
j += om$NumParser( subNode );
}
}
}
}

Wersja z 20:22, 1 maj 2020

// Kod przeniesiony z Common.js: [[Specjalna:Niezmienny link/4475173]]

if ( typeof String.prototype.endsWith !== 'function' ) {
    String.prototype.endsWith = function ( suffix ) {
        return this.indexOf( suffix, this.length - suffix.length ) !== -1;
    };
}

/*
Funkcje skryptu:
 * obsługa szablonu {{język linków}}
 * dodanie kodów języka do linków w artykułach i w kategoriach
 * czarne self-linki tylko jeśli prowadzą do tej samej sekcji językowej
 * klasy CSS dla sekcji językowych i pól
Przetestowane pod IE 7, IE 8, FF 3.6, Opera 10.50, Google Chrome 4.1.249.1036, Opera Mini, Nokia OSS
Autor: [[user:Olaf]]. Zmierzony narzut czasowy: 0.1-0.3 s
*/

//podział sekcji
var om$START = 0; //początek sekcji językowej
var om$KEEP = 1; //nie zmieniamy linków
var om$PL = 2; //linkujemy do języka polskiego
var om$EXAMPL = 3; //linkujemy do języka obcego przed strzałką i polskiego po strzałce
var om$FOREIGN = 4; //linkujemy do języka obcego
var om$TRANSL = 5; //linkujemy w zależności od nazwy języka
var om$SET = 6; //ustawione za pomocą szablonu {{język linków}}
var om$TABLE = 7; //linkujemy w zależności od kolumny
var om$ESPERANTO = 8; //linkujemy do sekcji esperanto

var om$CurLanguageId = '';
var om$CurSectionName = '';
var om$CurField = '';
var om$Field = om$KEEP;
var om$ArrowPassed = 0;
var om$ExpliciteBlock = 0;
var om$TransSection = 'other';
var om$LastNodeName = '';
var om$NewClasses = null;
var om$SectNum = 0;
var om$LocationUrl = null;
var om$LangOfColumn = null;
var om$Column = 0;
var om$Row = 0;
var om$CatContent = 0;
var om$DefHeader = 0;

var config = mw.config.get( [
	'wgNamespaceNumber',
	'wgServer',
	'wgPageName',
	'wgArticlePath',
	'wgNamespaceIds',
	'lang2code'
] );

// http://stackoverflow.com/questions/14947307
var om$RegexpHref = /^(\d+)?[^\d]/;

function om$ChangeLinks( node ) {
	for( var j = 0; j < node.childNodes.length; j++) {
		var subNode = node.childNodes[ j ];
		var nodeName = subNode.nodeName.toLowerCase();
		var $subNode = $( subNode );
		
		if (
			subNode.nodeType === 1 &&
			!$subNode.hasClass( 'mw-editTools' ) &&
			!$subNode.hasClass( 'portlet' ) &&
			nodeName !== 'textarea'
		) {
			//rozpoznanie końca artykułu
			if ( subNode.id === 'toolbar' ) {
				om$Field = om$START;
				om$ExpliciteBlock = 0;
				om$CurSectionName = '';
				om$CurField = '';
				om$CurLanguageId = '';
				om$NewClasses = null;
			}

			if ( nodeName === 'span' ) {
				//znacznik szablonu {{język linków}}
				if ( subNode.id === 'linkLanguage' ) {
					var title = subNode.getAttribute( 'title' );
					var iso;
					
					if ( ( title + ' ' ).substring( 0, 1 ) === '#' ) {
						iso = title.substring( 1 );
					} else {
						iso = config.lang2code[ title ];
					}
						
					if ( iso ) {
						om$CurLanguageId = iso;
					}
						
					if ( subNode.getAttribute( 'title' ) == '' ) {
						om$Field = om$START;
					} else {
						om$Field = om$SET;
					}
				}

				//rozpoznanie sekcji językowej
				if (
					$subNode.hasClass( 'mw-headline' ) &&
					//!$( om$LastNodeName ).hasClass( 'mw-headline' ) &&
					om$Field !== om$SET
				) {
					om$Field = om$START;
					om$ExpliciteBlock = 0;
					om$CurSectionName = subNode.id;
					om$CurField = 'header';
					om$CurLanguageId = '';
					om$NewClasses = null;
					om$ArrowPassed = 0;
					
					for ( var k = 0; k < subNode.childNodes.length; k++ ) {
						var subSubNode = subNode.childNodes[ k ];
						var $subSubNode = $( subSubNode );
						
						if ( $subSubNode.hasClass( 'primary-lang-code' ) ) {
							om$SectNum++;
							om$CurLanguageId = subSubNode.id.replace( '-foreign', '' );
							om$NewClasses = 'lang-' + om$CurLanguageId + ' fldt-header';
							
							if ( !$subSubNode.hasClass( 'no-headline-links' ) ) {
								om$Field = om$FOREIGN;
							}
							
							break;
						}
					}
				}

				if (
					$subNode.hasClass( 'field' ) &&
					!$( om$LastNodeName ).hasClass( 'field' ) &&
					om$Field !== om$SET
				) {
					om$SectNum++;
					var start = ( ' ' + subNode.className ).indexOf( ' fld-' );
					
					if ( start >= 0 ) {
						var end = ( subNode.className + ' ' ).indexOf( ' ', start );
						om$CurField = subNode.className.substring( start + 4, end );
					}
					
					om$NewClasses = 'lang-' + ( om$CurLanguageId || 'other' ) +
						' fldn-' + om$SectNum +
						( om$CurField  ? ' fldt-' + om$CurField : '' );
					
					if ( $subNode.hasClass( 'field-keep' ) ) {
						om$Field = om$KEEP;
					} else if ( $subNode.hasClass( 'field-pl' ) ) {
						om$Field = om$PL;
					} else if ( $subNode.hasClass( 'field-foreign' ) ) {
						om$Field = om$FOREIGN;
					} else if ( $subNode.hasClass( 'field-exampl' ) ) {
						om$Field = om$EXAMPL;
					} else if ( $subNode.hasClass( 'field-transl' ) ) {
						om$Field = om$TRANSL;
					} else if ( $subNode.hasClass( 'field-esperanto' ) ) {
						om$Field = om$ESPERANTO;
					}
				}
			}

			if ( nodeName === 'a' ) {
				var href, isSelfLink;
				
				if (
					config.wgNamespaceNumber === 0 &&
					$subNode.hasClass( 'mw-selflink' )
				) {
					isSelfLink = true;
					href = om$LocationUrl;
					
					try {
						subNode.setAttribute( 'href', om$LocationUrl );
					} catch ( err ) {
						var hrefAttr = document.createAttribute( 'href' );
						subNode.setAttribute( hrefAttr, om$LocationUrl );
					}
				} else {
					isSelfLink = false;
					href = subNode.getAttribute( 'href' );
				}
				
				if ( href ) {
					var startTitle = href.lastIndexOf( '/' ) + 1;
					//var firstChar=href.charAt(startTitle).toLowerCase();
					
					if (
						// wykluczenie innych przestrzeni nazw oraz linków zewnętrznych
						// TODO: ignoruje linki do haseł z dwukropkiem w nazwie
						// przykład: [[daj kurze grzędę, a ona: wyżej siędę]]
						( href.indexOf( ':' ) < 0 ||
							href.substring( 0, config.wgServer.length ) === config.wgServer &&
							href.substring( config.wgServer.length ).indexOf( ':' ) < 0
						) &&
						// wykluczenie linków do siostrzanych projektów
						subNode.className.indexOf( 'extiw' ) === -1 &&
						href.indexOf( '/S%C5%82ownik_' ) < 0 && //nie jest to link np. do Słownika języka pol.
						href.indexOf( '#' ) < 0 && //sekcja nie jest podana w linku
						//!$subNode.hasClass( 'new' ) && //nie jest to czerwony link
						( href.indexOf( '?' ) < 0 || href.indexOf( '&action=edit' ) >= 0 ) && //np. link pod polem edycji
						//'0123456789'.indexOf( firstChar ) < 0 && //nie jest to liczba
						om$RegexpHref.test( href.substring( startTitle ) ) &&
						( om$Field == om$SET || om$Field == om$TABLE ||
							om$CurField != '' && om$CurLanguageId != '')
					) {
						var newLang = null;
						if (
							(
								om$Field === om$PL &&
								//nie jest to rozwinięcie skrótu
								om$ExpliciteBlock == 0
							) ||
							//przykłady za strzałką
							om$ArrowPassed == 1
						) {
							newLang = 'pl';
						}

						if ( om$Field === om$ESPERANTO ) {
							newLang = 'eo';
						}

						if (
							(
								om$Field == om$FOREIGN ||
								om$Field == om$EXAMPL ||
								om$Field == om$SET ||
								om$ExpliciteBlock > 0
							) &&
							om$ArrowPassed == 0
						) {
							newLang = om$CurLanguageId;
						}
						
						// wyjątek: rozwinięcie skrótów w użyciu międzynarodowym,
						// pole znaczeń (np. [[BWA#inter]])
						if (
							om$Field == om$PL &&
							om$ExpliciteBlock > 0 &&
							om$CurLanguageId === 'inter'
						) {
							newLang = 'pl';
						}

						if ( om$Field === om$TRANSL ) {
							newLang = om$TransSection;
						}

						if ( om$Field === om$TABLE ) {
							newLang = om$LangOfColumn[ om$Column ];
						}
						
						if ( om$Field == om$PL && om$DefHeader ) {
							newLang = om$CurLanguageId; // naglowek w polu znaczen
						}
						
						if ( newLang === 'pl' ) {
							var nhref = decodeURI( href );
							if ( nhref.substring( nhref.length - 1 ) >= '\u0250' ) {
								newLang = null;
							}
						}

						if ( newLang != null ) {
							href += '#' + newLang;
							subNode.setAttribute( 'href', href );
						}
					}
					
					var i = href.indexOf( '#' );

					//wyłączenie boldów w self-linkach
					if ( isSelfLink && (
						i === -1 ||
						href === '#' ||
						!(
							href.substring( i + 1 ) === om$CurLanguageId ||
							href.substring( i + 1 ) === om$CurSectionName
						) ||
						( om$LocationUrl + '#' ).indexOf( href.substring( 0, i + 1 ) ) === -1 ||
						href.endsWith( '#zh' ) ||
						href.endsWith( '#zh-char' ) ||
						href.endsWith( '#zh-min-nan' ) ||
						href.endsWith( '#ja' ) ||
						href.endsWith( '#gan' ) ||
						href.endsWith( '#ain' ) ||
						href.endsWith( '#chi' )
					) ) {
						$subNode.addClass( 'mw-selflink-suppressed' );
					}
				}
			}
			
			// pusty <dd> w każdym polu: [[Dyskusja szablonu:pole#Dwukropek]]
			if ( nodeName === 'dd' && subNode.textContent === '' ) {
				subNode.parentNode.removeChild( subNode );
				j--;
				continue;
			}

			if ( nodeName === 'dd' || nodeName === 'li') {
				om$ExpliciteBlock = 0;
				om$ArrowPassed = 0;
				om$TransSection = 'other';
			}

			if ( nodeName === 'tr' ) {
				om$Column = 0;
				om$Row++;
			}
			
			if ( nodeName === 'th' || nodeName === 'td' ) {
				om$Column++;
			}

			if (
				subNode.id === 'mw-pages' &&
				config.wgNamespaceNumber === config.wgNamespaceIds.category
			) {
				om$CatContent = 1;
			}
			
			if ( nodeName === 'p' && om$CurField === 'znaczenia' ) {
				om$DefHeader = 1;
			}
			
			if ( nodeName === 'td' && om$CatContent ) {
				subNode.style.width = '30%';
			}

			if ( om$Field === om$TABLE && om$Row == 1 && !om$LangOfColumn[ om$Column ] ) {
				var text = subNode.innerHTML;
				
				if ( text == null ) {
					text = subNode.innerText;
				}
					
				if ( text != null ) {
					var i = text.indexOf( ' ' );
					
					if ( i >= 0 ) {
						text = text.substring( 0, i );
					}
						
					var iso = config.lang2code[ text.toLowerCase() ];
					
					if ( iso ) {
						om$LangOfColumn[ om$Column ] = iso;
					}
				}
			}

			om$LastNodeName = nodeName;

			if ( nodeName === 'table' && om$Field !== om$SET ) {
				var field = om$Field;
				var column = om$Column;
				var row = om$Row;
				var lang = om$LangOfColumn;

				om$Field = om$TABLE;
				om$Column = 0;
				om$Row = 0;
				om$LangOfColumn = {};

				om$ChangeLinks( subNode );

				om$Field = field;
				om$Column = column;
				om$Row = row;
				om$LangOfColumn = lang;
			} else if ( nodeName === 'span' && $subNode.hasClass( 'set-foreign' ) ) {
				//obsługa linków z szablonów zobacz
				var field = om$Field;
				var arrow = om$ArrowPassed;
				var expl = om$ExpliciteBlock;
				
				om$Field = om$FOREIGN;
				om$ArrowPassed = 0;
				om$ExpliciteBlock = 0;

				//rekurencyjne przeszukanie podwęzłów
				om$ChangeLinks( subNode );

				om$Field = field;
				om$ArrowPassed = arrow;
				om$ExpliciteBlock = expl;
			} else if ( nodeName === 'span' && $subNode.hasClass( 'colLanguage' ) ) {
				//obsługa szablonu {{język kolumny}}
				var text = subNode.getAttribute( 'title' );
				
				if ( ( text + ' ' ).substring( 0, 1 ) === '#' ) {
					om$LangOfColumn[ om$Column ] = text.substring( 1 );
				} else if ( text != null ) {
					var i = text.indexOf( ' ' );
					
					if ( i >= 0 ) {
						text = text.substring( 0, i );
					}
					var iso = config.lang2code[ text.toLowerCase() ];
					
					if ( iso ) {
						om$LangOfColumn[ om$Column ] = iso;
					}
				}

				//rekurencyjne przeszukanie podwęzłów
				om$ChangeLinks( subNode );
			} else {
				//rekurencyjne przeszukanie podwęzłów
				om$ChangeLinks( subNode );
			}

			if (
				om$NewClasses &&
				nodeName !== 'div' &&
				nodeName !== 'dl' &&
				!$subNode.hasClass( 'editsection' )
			) {
				$subNode.addClass( om$NewClasses );
			}
			
			if ( nodeName === 'p' && om$CurField === 'znaczenia' ) {
				om$DefHeader = 0;
			}
		}

		var cont = subNode.nodeValue;
		
		if ( cont != null && nodeName !== 'textarea' ) {
			var pos = cont.lastIndexOf( '(=' );
			
			if ( om$ExpliciteBlock == 0 && pos >= 0 && cont.indexOf( ')', pos ) < 0 ) {
				om$ExpliciteBlock = 1;
			} else if ( om$ExpliciteBlock == 1 && cont.indexOf( ')' ) >= 0 ) {
				om$ExpliciteBlock = 0;
			}
			
			if ( pos < 0 && om$ExpliciteBlock == 0 && cont.indexOf( '=' ) >= 0 ) {
				om$ExpliciteBlock = 2;
			}
			
			if ( subNode.nodeType === 1 ) {
				if ( subNode.getAttribute( 'title' ) == 'zobacz' ) {
					om$ExpliciteBlock = 2;
				}
			}
			
			if ( om$Field !== om$EXAMPL && cont.indexOf( '•' ) >= 0 ) {
				if (
					cont.indexOf( '→' ) >= 0 &&
					cont.indexOf( '•' ) < cont.indexOf( '→' )
				) {
					om$ArrowPassed = 1;
				} else {
					om$ArrowPassed = 0;
				}
			} else if ( cont.indexOf( '→' ) >= 0 ) {
				om$ArrowPassed = 1;
			}

			if ( om$Field === om$TRANSL ) {
				var i = cont.indexOf( ':' );
				
				if ( i > 0 ) {
					var lang = config.lang2code[ cont.substring(
							cont.charAt( 0 ) === ' ' ? 1 : 0,
							i
						) ];
					
					if ( lang ) {
						om$TransSection = lang;
					}
				}
			}
		}
	}
};

if (
	!mw.util.getParamValue( 'nosectionlinks' ) &&
	config.wgNamespaceNumber >= 0 &&
	!config.wgPageName.endsWith( '.js' ) &&
	config.wgNamespaceNumber !== config.wgNamespaceIds.mediawiki
) {
	om$LocationUrl = mw.format(
			config.wgArticlePath,
			encodeURIComponent( config.wgPageName )
				.replace( /%20/ig, ' ' )
				.replace( /%2F/ig, '/' )
				.replace( /%3A/ig, ':' )
		);

	mw.hook( 'wikipage.content' ).add( function ( $content ) {
		om$ChangeLinks( $content[ 0 ] );
	} );
}