Zum Inhalt springen
Wikipedia Die freie Enzyklopädie

Benutzer:Schnark/js/veHint.js

aus Wikipedia, der freien Enzyklopädie
Diese Seite enthält Code als JavaScript; siehe auch WP:JS.

Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.

  • Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
  • Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
  • Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
 //Dokumentation unter [[Benutzer:Schnark/js/veHint]] <nowiki>
 /*global mediaWiki, OO, ve*/
 (function($,mw){
 "use strict";

 varl10n={
 en:{
 'schnark-ve-problems-total-count':'All problems: 1ドル',
 'schnark-ve-problems-find-prev':'Find previous problem',
 'schnark-ve-problems-find-next':'Find next problem',
 'schnark-ve-problems-replace':'Fix problem',
 'schnark-ve-problems-replace-all':'Fix all problems',
 'schnark-ve-problems-enable-all':'Enable all problems',
 'schnark-ve-problems-disable-all':'Disable all problems',
 'schnark-ve-problems-done':'Done',
 'schnark-ve-problems-title':'Find problems'
 },
 de:{
 'schnark-ve-problems-total-count':'Alle Probleme: 1ドル',
 'schnark-ve-problems-find-prev':'Finde vorheriges Problem',
 'schnark-ve-problems-find-next':'Finde nächstes Problem',
 'schnark-ve-problems-replace':'Behebe Problem',
 'schnark-ve-problems-replace-all':'Behebe alle Probleme',
 'schnark-ve-problems-enable-all':'Aktiviere alle Probleme',
 'schnark-ve-problems-disable-all':'Deaktiviere alle Probleme',
 'schnark-ve-problems-done':'Fertig',
 'schnark-ve-problems-title':'Finde Probleme'
 }
 },SOURCE=1,VISUAL=2,problemsForProjects={};

 functioninitL10N(l10n){
 vari,chain=mw.language.getFallbackLanguageChain();
 for(i=chain.length-1;i>=0;i--){
 if(chain[i]inl10n){
 mw.messages.set(l10n[chain[i]]);
 }
 }
 }

 functionaddToToolbar(tool){
 vari,include;
 try{
 include=ve.init.mw.DesktopArticleTarget.static.actionGroups[1].include;
 i=include.indexOf('findAndReplace');
 if(i===-1){
 include.push(tool);
 }else{
 include.splice(i+1,0,tool);
 }
 }catch(e){
 mw.log.warn('veHint.js: addToToolbar failed: '+e);
 }
 }

 functioninit(problems){
 //virtual indent

 varcss=
 '.schnark-ve-problems-current-problem-highlight {'+
 'background-color: #fc3;'+
 '}'+
 '.schnark-multicol-layout {'+
 'padding: 0 0.5em;'+
 'max-height: 8em;'+
 'overflow: auto;'+
 '}'+
 '.schnark-multicol-layout .oo-ui-fieldLayout {'+
 'width: 20em;'+
 'height: 2.5em;'+
 'float: left;'+
 '}';
 mw.util.addCSS(css);

 functionMulticolLayout(){
 MulticolLayout.parent.apply(this,arguments);
 this.$element.addClass('schnark-multicol-layout');
 this.$group.prepend($('<span>'));//don't remove the margin-top from the first widget
 }

 OO.inheritClass(MulticolLayout,OO.ui.FieldsetLayout);

 functionFindProblemsDialog(){
 FindProblemsDialog.parent.apply(this,arguments);
 }

 OO.inheritClass(FindProblemsDialog,ve.ui.FindAndReplaceDialog);

 FindProblemsDialog.static.name='findProblems';
 FindProblemsDialog.static.padded=false;//strange issue with padding + overflow
 //TODO besser lösen, ohne padding sieht es blöd aus
 FindProblemsDialog.static.problemsVisual=[];
 FindProblemsDialog.static.problemsSource=[];
 FindProblemsDialog.static.addProblem=function(desc,re,fix,mode){
 varproblem={desc:desc,rawRe:re,re:newRegExp('^'+re+'$')};
 if(fix!==false){
 problem.replace=fix;
 }
 if(mode===VISUAL||mode===VISUAL+SOURCE){
 FindProblemsDialog.static.problemsVisual.push(
 $.extend({index:FindProblemsDialog.static.problemsVisual.length},problem)
 );
 }
 if(mode===SOURCE||mode===VISUAL+SOURCE){
 FindProblemsDialog.static.problemsSource.push(
 $.extend({index:FindProblemsDialog.static.problemsSource.length},problem)
 );
 }
 };

 FindProblemsDialog.prototype.initialize=function(){
 varproblemGroup,navigateGroup,replaceGroup,onoffGroup,doneButton,$problemRow,$navRow;

 ve.ui.FindAndReplaceDialog.parent.prototype.initialize.apply(this,arguments);//eine Hierarchiestufe überspringen

 this.surface=null;
 this.invalidRegex=false;
 this.$findResults=$('<div>').addClass('ve-ui-findAndReplaceDialog-findResults');
 this.initialFragment=null;
 this.startOffset=0;
 this.fragments=[];
 this.results=0;
 this.renderedResultsCache={};
 this.renderedFragments=newve.Range();
 this.replacing=false;
 this.focusedIndex=0;
 this.query=null;
 this.problemsForIndexCache=null;

 if(ve.init.target.getSurface().getMode()==='source'){
 this.constructor.static.problems=this.constructor.static.problemsSource;
 }else{
 this.constructor.static.problems=this.constructor.static.problemsVisual;
 }
 this.problemSwitches=this.constructor.static.problems.map(function(problem,index){
 varid='schnark-ve-problems-problem-'+index,
 toggleSwitch=newOO.ui.CheckboxInputWidget({
 selected:true
 }),fieldLayout=newOO.ui.FieldLayout(toggleSwitch,{
 align:'inline',
 label:newOO.ui.HtmlSnippet(
 '<span id="'+id+'">'+problem.desc+'<span class="count"></span></span>'
 )
 });

 return{toggleSwitch:toggleSwitch,fieldLayout:fieldLayout};
 });

 this.previousButton=newOO.ui.ButtonWidget({
 icon:'previous',
 title:ve.msg('schnark-ve-problems-find-prev'),
 tabIndex:1
 });
 this.nextButton=newOO.ui.ButtonWidget({
 icon:'next',
 title:ve.msg('schnark-ve-problems-find-next'),
 tabIndex:1
 });
 this.replaceButton=newOO.ui.ButtonWidget({
 label:ve.msg('schnark-ve-problems-replace'),
 tabIndex:1
 });
 this.replaceAllButton=newOO.ui.ButtonWidget({
 label:ve.msg('schnark-ve-problems-replace-all'),
 tabIndex:1
 });
 this.enableAllButton=newOO.ui.ButtonWidget({
 label:ve.msg('schnark-ve-problems-enable-all'),
 tabIndex:1
 });
 this.disableAllButton=newOO.ui.ButtonWidget({
 label:ve.msg('schnark-ve-problems-disable-all'),
 tabIndex:1
 });

 problemGroup=newMulticolLayout({
 items:this.problemSwitches.map(function(item){
 returnitem.fieldLayout;
 }),
 label:newOO.ui.HtmlSnippet(
 ve.msg('schnark-ve-problems-total-count','<span id="schnark-problems-totalcount">0</span>')
 )
 });
 navigateGroup=newOO.ui.ButtonGroupWidget({
 classes:['ve-ui-findAndReplaceDialog-cell'],
 items:[
 this.previousButton,
 this.nextButton
 ]
 });
 replaceGroup=newOO.ui.ButtonGroupWidget({
 classes:['ve-ui-findAndReplaceDialog-cell'],
 items:[
 this.replaceButton,
 this.replaceAllButton
 ]
 });
 onoffGroup=newOO.ui.ButtonGroupWidget({
 classes:['ve-ui-findAndReplaceDialog-cell'],
 items:[
 this.enableAllButton,
 this.disableAllButton
 ]
 });
 doneButton=newOO.ui.ButtonWidget({
 classes:['ve-ui-findAndReplaceDialog-cell'],
 label:ve.msg('schnark-ve-problems-done'),
 tabIndex:1
 });
 $problemRow=$('<div>');
 $navRow=$('<div>').addClass('ve-ui-findAndReplaceDialog-row').css('padding','0 0.5em');

 this.onWindowScrollThrottled=ve.throttle(this.onWindowScroll.bind(this),250);
 this.updateFragmentsThrottled=ve.throttle(this.updateFragments.bind(this),250);
 this.renderFragmentsThrottled=ve.throttle(this.renderFragments.bind(this),250);
 this.problemSwitches.forEach(function(item){
 item.toggleSwitch.connect(this,{change:'onProblemsChange'});
 },this);
 this.nextButton.connect(this,{click:'findNext'});
 this.previousButton.connect(this,{click:'findPrevious'});
 this.replaceButton.connect(this,{click:'onReplaceButtonClick'});
 this.replaceAllButton.connect(this,{click:'onReplaceAllButtonClick'});
 this.enableAllButton.connect(this,{click:'onEnableAllButtonClick'});
 this.disableAllButton.connect(this,{click:'onDisableAllButtonClick'});
 doneButton.connect(this,{click:'close'});

 this.tabIndexScope=newve.ui.TabIndexScope({
 root:this.$element
 });

 this.$content.addClass('ve-ui-findAndReplaceDialog-content');
 this.$body
 .append(
 $navRow.append(navigateGroup.$element,replaceGroup.$element,onoffGroup.$element,doneButton.$element),
 $problemRow.append(problemGroup.$element)
 );
 };

 FindProblemsDialog.prototype.onProblemsChange=function(){
 this.updateFragments();
 this.clearRenderedResultsCache();
 this.renderFragments();
 this.highlightFocused(true);
 };

 FindProblemsDialog.prototype.onEnableAllButtonClick=function(){
 this.problemSwitches.forEach(function(item){
 item.toggleSwitch.setSelected(true);
 },this);
 };

 FindProblemsDialog.prototype.onDisableAllButtonClick=function(){
 this.problemSwitches.forEach(function(item){
 item.toggleSwitch.setSelected(false);
 },this);
 };

 FindProblemsDialog.prototype.getProblemSelectionStates=function(){
 returnthis.problemSwitches.map(function(item){
 returnitem.toggleSwitch.isSelected();
 });
 };

 FindProblemsDialog.prototype.updateFragments=function(){
 vari,l,startIndex,
 surfaceModel=this.surface.getModel(),
 documentModel=surfaceModel.getDocument(),
 isReadOnly=surfaceModel.isReadOnly(),
 ranges=[],
 selectionStates=this.getProblemSelectionStates(),
 problemCounts,countHtml;

 this.query=this.constructor.static.problems.filter(function(el,index){
 returnselectionStates[index];
 }).map(function(problem){
 return'(?:'+problem.rawRe+')';
 }).join('|');

 this.fragments=[];
 this.problemsForIndexCache=null;
 if(this.query){
 this.query=newRegExp(this.query,'g');
 ranges=documentModel.findText(this.query,{
 noOverlaps:true
 });
 for(i=0,l=ranges.length;i<l;i++){
 this.fragments.push(surfaceModel.getLinearFragment(ranges[i],true,true));
 if(startIndex===undefined&&ranges[i].start>=this.startOffset){
 startIndex=this.fragments.length-1;
 }
 }
 }
 this.results=this.fragments.length;
 this.focusedIndex=startIndex||0;
 this.nextButton.setDisabled(!this.results);
 this.previousButton.setDisabled(!this.results);
 this.replaceAllButton.setDisabled(!this.results||isReadOnly);

 problemCounts=this.getCounts();
 this.$element.find('#schnark-problems-totalcount').html(this.results);
 for(i=0;i<problemCounts.length;i++){
 if(selectionStates[i]){
 countHtml=' ('+problemCounts[i]+')';
 }else{
 countHtml='';
 }
 this.$element.find('#schnark-ve-problems-problem-'+i+' .count').html(countHtml);
 }
 };

 FindProblemsDialog.prototype.getCounts=function(){
 vari,problemCounts=[];

 functionadd(problem){
 problemCounts[problem.index]++;
 }

 for(i=0;i<this.constructor.static.problems.length;i++){
 problemCounts.push(0);
 }

 for(i=0;i<this.fragments.length;i++){
 this.getProblemsForIndex(i).list.forEach(add);
 }
 returnproblemCounts;
 };

 FindProblemsDialog.prototype.createProblemsForIndexCache=function(){
 vari;
 this.problemsForIndexCache=[];
 for(i=0;i<this.fragments.length;i++){
 this.problemsForIndexCache.push(this.createProblemsForIndex(i));
 }
 };

 FindProblemsDialog.prototype.createProblemsForIndex=function(index){
 vartext=this.fragments[index].getText(true).replace(/\n/g,'\uFFFC'),
 selectionStates=this.getProblemSelectionStates(),
 fixProblem=false,
 list=this.constructor.static.problems.filter(function(problem,index){
 //FIXME teilweise sprechen auch falsche REs an
 varmatches=selectionStates[index]&&text.search(problem.re)===0;
 if(text.indexOf('\uFFFC')===-1&&matches&&fixProblem===false&&problem.replace!==undefined){
 fixProblem=index;
 }
 returnmatches;
 });
 return{list:list,fixProblem:fixProblem};
 };

 FindProblemsDialog.prototype.getProblemsForIndex=function(index){
 if(!this.problemsForIndexCache){
 this.createProblemsForIndexCache();
 }
 returnthis.problemsForIndexCache[index]||{list:[],fixProblem:false};
 };

 FindProblemsDialog.prototype.highlightFocused=function(){
 this.findText={setLabel:function(){}};
 FindProblemsDialog.parent.prototype.highlightFocused.apply(this,arguments);
 this.$element.find('.schnark-ve-problems-current-problem-highlight')
 .removeClass('schnark-ve-problems-current-problem-highlight');
 varcurrentProblems=this.getProblemsForIndex(this.focusedIndex);
 currentProblems.list.forEach(function(problem){
 this.$element.find('#schnark-ve-problems-problem-'+problem.index)
 .addClass('schnark-ve-problems-current-problem-highlight')[0]
 .scrollIntoView(false);
 },this);
 this.replaceButton.setDisabled(
 currentProblems.fixProblem===false||this.surface.getModel().isReadOnly()
 );
 };

 FindProblemsDialog.prototype.findFirst=function(){
 varinitialFragment=this.surface.getModel().getFragment(null,true);
 this.startOffset=ve.getProp(
 initialFragment.getSelection().getRanges(initialFragment.getDocument()),
 0,'start'
 )||0;
 this.onProblemsChange();
 };

 FindProblemsDialog.prototype.focus=function(){};

 FindProblemsDialog.prototype.replace=function(index){
 varfix=this.getProblemsForIndex(index).fixProblem;
 if(fix===false){
 return;
 }
 fix=this.constructor.static.problems[fix];
 this.replacing=true;
 this.fragments[index].insertContent(
 this.fragments[index].getText().replace(fix.re,fix.replace),
 true
 );
 setTimeout(function(){
 this.replacing=false;
 }.bind(this));
 };

 ve.ui.windowFactory.register(FindProblemsDialog);

 ve.ui.commandRegistry.register(
 newve.ui.Command(
 'findProblems','window','open',{args:['findProblems',null,'findFirst']}
 )
 );

 functionFindProblemsTool(){
 FindProblemsTool.parent.apply(this,arguments);
 }

 OO.inheritClass(FindProblemsTool,ve.ui.FindAndReplaceTool);
 FindProblemsTool.static.name='findProblems';
 FindProblemsTool.static.icon='alert';
 FindProblemsTool.static.title=ve.msg('schnark-ve-problems-title');
 FindProblemsTool.static.commandName='findProblems';
 ve.ui.toolFactory.register(FindProblemsTool);

 addToToolbar('findProblems');

 ve.ui.triggerRegistry.register(
 'findProblems',{mac:newve.ui.Trigger('cmd+p'),pc:newve.ui.Trigger('ctrl+p')}
 );

 problems(FindProblemsDialog.static.addProblem);

 //virtual outdent
 }

 problemsForProjects.dewiki=function(add){
 functionallowCapital(re){
 varfirst=re.charAt(0),
 firstCapital=first.toUpperCase();
 if(first===firstCapital){
 returnre;
 }
 return'['+first+firstCapital+']'+re.slice(1);
 }

 vartypo={//FIXME erweitern
 'aberufen':'abgerufen',
 'Addresse':'Adresse',
 'anderere':'andere',
 'andereren':'anderen',
 'andererer':'anderer',
 'Gallerie':'Galerie',
 'Standart':'Standard'
 },words=[//evt. weitere aus wikilint übernehmen
 'bedauerlicherweise',
 'bedeutendste',
 'bekannte',
 'bekannteste',
 'berühmteste',
 'derzeit',
 'einzigste',
 'ich',
 'in der Regel',
 'in den letzten Jahren',
 'sogar',
 'wichtigste',
 'zum Glück',
 'zurzeit',
 'Insider'
 ],abbr=[
 'z. B.',
 'bzw.',
 'd. h.',
 'jährl.',
 'u. a.',
 'hl.',
 'engl.',
 'ital.',
 'span.',
 'lat.',
 'ca.',
 'sog.'
 ],months=[
 'Januar',
 'Februar',
 'März',
 'April',
 'Mai',
 'Juni',
 'Juli',
 'August',
 'September',
 'Oktober',
 'November',
 'Dezember'
 ],
 opening='([„«',closing=')]"»',digitPunct='.,',punct=':;?!',object='\uFFFC';
 add('Wortdopplung','\\b(\\S+)\\b(\\W+)\\b\1円\\b','1ドル2ドル',SOURCE+VISUAL);
 add('Plenk','\\s+(['+mw.util.escapeRegExp(digitPunct+punct+closing+'/')+
 '])|(['+mw.util.escapeRegExp(opening+'/')+'])\\s+','1ドル2ドル',SOURCE+VISUAL);
 add('Klemp',
 '(['+mw.util.escapeRegExp(punct)+'])([^ '+mw.util.escapeRegExp(closing)+object+'])|'+
 '(,)([^ \\d'+mw.util.escapeRegExp(closing)+object+'])|'+
 '(\\.)([^ \\-\\da-z'+mw.util.escapeRegExp(closing)+object+'])',
 '1ドル3ドル5ドル 2ドル4ドル6ドル',VISUAL);
 add('Mehrfache Leerzeichen',' {2,}',' ',VISUAL);
 add('Überflüssige Leerzeichen',' +$','',VISUAL+SOURCE);
 add('Kleinschreibung','([.!?]\\s+)([a-zäöü])',function(all,pre,char){
 returnpre+char.toUpperCase();
 },SOURCE+VISUAL);
 add('Tippfehler','\\b(?:'+Object.keys(typo).map(mw.util.escapeRegExp).join('|')+')\\b',function(word){
 returntypo[word];
 },SOURCE+VISUAL);
 add('Zahlenformat (4-stellig)','\\b(\\d)\\.(\\d{3})\\b','1ドル2ドル',VISUAL+SOURCE);
 add('Zahlenformat',' \\d{5,}\\b',function(number){
 functiongroup(n){
 if(n.length<=3){
 returnn;
 }
 returngroup(n.slice(0,-3))+'.'+n.slice(-3);
 }
 return' '+group(number.slice(1));
 },SOURCE+VISUAL);
 add('Unerwünschte Wörter','\\b(?:'+words.map(mw.util.escapeRegExp).map(allowCapital).join('|')+')\\b',
 false,SOURCE+VISUAL);
 add('Abkürzung','\\b(?:'+abbr.map(mw.util.escapeRegExp).map(allowCapital).join('|')+')',false,SOURCE+VISUAL);
 add('Langer Satz','(?:\\b\\S+\\b[ ,]){50,}',false,SOURCE+VISUAL);
 add('Datum','\\b([0-3]?[0-9])\\.\\s*([01]?[0-9])\\.\\s*',function(all,day,month){
 returnString(Number(day))+'. '+months[Number(month)-1]+' ';
 },SOURCE+VISUAL);
 add('Gedankenstrich',' - ',' – ',SOURCE+VISUAL);
 add('Bis-Strich zwischen Jahren','([^-0-9][12][0-9]{3}) *- *([12][0-9]{3}[^-0-9])','1ドル–2ドル',SOURCE+VISUAL);
 add('Bis-Strich zwischen Seiten','\\b(Sp?\\.|Seiten?|Spalten?) *(\\d+) *- *','1ドル 2ドル–',SOURCE+VISUAL);
 add('Bis-Strich mit Leerzeichen','(\\d) +(–) +(\\d)','1ドル2ドル3ドル',SOURCE+VISUAL);
 add('Auslassungspunkte','\\.\\.\\.','...',SOURCE+VISUAL);
 add('Anführungszeichen','"([^"\\n]{0,100})"','„1ドル"',VISUAL);
 add('Apostroph','\'','’',VISUAL);
 add('Zusammenstoßende Links','\\]\\]\\[\\[',false,SOURCE);
 add('Weblinks','^\\s*(?:[eE]xterner?|[eE]xternal)?\\s*(?:[wW]eblink|[lL]inks?|[wW]ebseiten?|[wW]ebsites?)\\s*$',
 'Weblinks',SOURCE+VISUAL);
 };

 problemsForProjects['*']=function(add){
 mw.log.warn('veHint.js: No config for this project!');
 add('Placeholder','^.*$',false,SOURCE+VISUAL);
 };

 //'oojs-ui.styles.icons-movement' nicht aufgeführt, da diese Icons auch vom beerbten Suchdialog verwendet werden
 mw.loader.using([
 'mediawiki.language','mediawiki.util',
 'ext.visualEditor.core','ext.visualEditor.desktopArticleTarget','oojs-ui.styles.icons-alerts'
 ]).then(function(){
 initL10N(l10n);
 init(problemsForProjects[mw.config.get('wgDBname')]||problemsForProjects['*']);
 mw.hook('userjs.script-ready.veHint').fire();
 });

 })(jQuery,mediaWiki);
 //</nowiki>

AltStyle によって変換されたページ (->オリジナル) /