אונטערשייד צווישן ווערסיעס פון "מעדיעוויקי:Gadget-quickLinker.js"

קפיצה לניווט קפיצה לחיפוש
קיין רעדאגירונג באמערקונג
ק (רעדאגירונגען דורך תנא קמא (שמועס) צוריקגעשטעלט צו דער לעצטער ווערסיע פון צמא לדעת)
צייכן: צוריקדריי
אין תקציר עריכה
שורה 4: שורה 4:
Author: [[:he:User:ערן]]
Author: [[:he:User:ערן]]
*/
*/
if (mw.config.get('wgContentNamespaces').includes(mw.config.get('wgNamespaceNumber'))) $(function(){
if (mw.config.get('wgContentNamespaces').includes(mw.config.get('wgNamespaceNumber'))) $(function () {
var titleNoBrackets = /(.+?)( \(|$)/.exec(mw.config.get('wgTitle')), allowedSuffix, allowedPrefix;
    var titleNoBrackets = /(.+?)( \(|$)/.exec(mw.config.get('wgTitle')), allowedSuffix, allowedPrefix;
if (titleNoBrackets) titleNoBrackets = titleNoBrackets[1];
    if (titleNoBrackets) titleNoBrackets = titleNoBrackets[1];
else return;
    else return;


// allowedSuffix and allowedPrefix to have strict match for valid words (BOOK => BOOKs and not BOOKmark). default is non strict (which works better for long title)
    // allowedSuffix and allowedPrefix to have strict match for valid words (BOOK => BOOKs and not BOOKmark). default is non strict (which works better for long title)
switch ( mw.config.get('wgContentLanguage') ) {
    switch (mw.config.get('wgContentLanguage')) {
case 'he':
        case 'he':
allowedSuffix = '(?=ים|ות|[^א-ת])';
            allowedSuffix = '(?=ים|ות|[^א-ת])';
allowedPrefix = '(?:[כלבמשהו]|[^א-ת])';
            allowedPrefix = '(?:[כלבמשהו]|[^א-ת])';
break;
            break;
default:
        default:
allowedSuffix = 's?[^a-z]';
            allowedSuffix = 's?[^a-z]';
allowedPrefix = '';
            allowedPrefix = '';
}
    }


switch (mw.config.get('wgUserLanguage') ) {
    switch (mw.config.get('wgUserLanguage')) {
case 'he':
        case 'he':
mw.messages.set({
            mw.messages.set({
'qlinker-edit' : 'עריכה מהירה',
                'qlinker-edit': 'עריכה מהירה',
'qlinker-cancel' : 'ביטול',
                'qlinker-cancel': 'ביטול',
'linkify-summary': 'הוספת קישור ל[[$1]]',
                'linkify-summary': 'הוספת קישור ל[[$1]]',
'qlinker-save-success': 'שמירת $1 בוצעה בהצלחה!',
                'qlinker-save-success': 'שמירת $1 בוצעה בהצלחה!',
'qlinker-save-continue': 'שמירה',
                'qlinker-save-continue': 'שמירה',
'qlinker-skip': 'דילוג דף',
                'qlinker-skip': 'דילוג דף',
'qlinker-skip-match': 'דילוג מופע',
                'qlinker-skip-match': 'דילוג מופע',
'qlinker-safe-search': 'חיפוש בטוח',
                'qlinker-safe-search': 'חיפוש בטוח',
'qlinker-invoke': 'הוספת בזק של קישורים',
                'qlinker-invoke': 'הוספת בזק של קישורים',
'qlinker-sidelink': 'הוספת קישורים',
                'qlinker-sidelink': 'הוספת קישורים',
'qlinker-no-results': 'לא נמצאו תוצאות',
                'qlinker-no-results': 'לא נמצאו תוצאות',
'qlinker-confirm-masslink': 'לדף זה יש כבר הרבה קישורים, ונדרשת זהירות בהוספת הקישורים. האם נחוצים קישורים נוספים?'
                'qlinker-confirm-masslink': 'לדף זה יש כבר הרבה קישורים, ונדרשת זהירות בהוספת הקישורים. האם נחוצים קישורים נוספים?'
});
            });
break;
            break;
default:
        default:
mw.messages.set({
            mw.messages.set({
'qlinker-edit' : 'Quick edit',
                'qlinker-edit': 'Quick edit',
'qlinker-cancel' : 'Cancel',
                'qlinker-cancel': 'Cancel',
'linkify-summary': 'Adding link to [[$1]]',
                'linkify-summary': 'Adding link to [[$1]]',
'qlinker-save-success': '$1 has been saved successfully!',
                'qlinker-save-success': '$1 has been saved successfully!',
'qlinker-save-continue': 'Save',
                'qlinker-save-continue': 'Save',
'qlinker-skip': 'Skip page',
                'qlinker-skip': 'Skip page',
'qlinker-skip-match': 'Skip match',
                'qlinker-skip-match': 'Skip match',
'qlinker-safe-search': 'Safe search',
                'qlinker-safe-search': 'Safe search',
'qlinker-invoke': 'Quickly add links',
                'qlinker-invoke': 'Quickly add links',
'qlinker-sidelink': 'Add links',
                'qlinker-sidelink': 'Add links',
'qlinker-no-results': 'No results found',
                'qlinker-no-results': 'No results found',
'qlinker-confirm-masslink': 'This page already has many links. Are you sure?'
                'qlinker-confirm-masslink': 'This page already has many links. Are you sure?'
});
            });
break;
            break;
}
    }




function createQuickEditorDialog(searchRes, safeMode){
    function createQuickEditorDialog(searchRes, safeMode) {
function QuickEditorDialog( config ) {
        function QuickEditorDialog(config) {
  this.contextRgx = new RegExp('(.*[^\\[])(' + mw.util.escapeRegExp(titleNoBrackets) +')((?![^\\[\\{]*[\\]\\}]).*)', 'ig');
            this.contextRgx = new RegExp('(.*[^\\[])(' + mw.util.escapeRegExp(titleNoBrackets) + ')((?![^\\[\\{]*[\\]\\}]).*)', 'ig');
  this.contextRgxLink = new RegExp('(.*\\[\\[)([^\\]]+?)\\|(' + mw.util.escapeRegExp(titleNoBrackets) +')(\\]\\].*)', 'ig');
            this.contextRgxLink = new RegExp('(.*\\[\\[)([^\\]]+?)\\|(' + mw.util.escapeRegExp(titleNoBrackets) + ')(\\]\\].*)', 'ig');
  this.pageI = -1;
            this.pageI = -1;
  this.matchI = 0;
            this.matchI = 0;
  this.searchData = null;
            this.searchData = null;
  this.curPage = null;
            this.curPage = null;
  this.safeMode = safeMode;
            this.safeMode = safeMode;
  this.skipsCounter = 0;
            this.skipsCounter = 0;
  this.starttimestamp = null;
            this.starttimestamp = null;
  this.timestamp = null;
            this.timestamp = null;
  QuickEditorDialog.super.call( this, config );
            QuickEditorDialog.super.call(this, config);
}
        }
OO.inheritClass( QuickEditorDialog, OO.ui.ProcessDialog );  
        OO.inheritClass(QuickEditorDialog, OO.ui.ProcessDialog);


// Specify a name for .addWindows()
        // Specify a name for .addWindows()
QuickEditorDialog.static.name = 'QuickEditorDialog';
        QuickEditorDialog.static.name = 'QuickEditorDialog';
// Specify a title statically (or, alternatively, with data passed to the opening() method).  
        // Specify a title statically (or, alternatively, with data passed to the opening() method).  
QuickEditorDialog.static.title = mw.msg('qlinker-edit');
        QuickEditorDialog.static.title = mw.msg('qlinker-edit');


QuickEditorDialog.static.actions = [
        QuickEditorDialog.static.actions = [
  { action: 'saveContinue', label: mw.msg('qlinker-save-continue'), flags: [ 'other', 'progressive' ], icon: 'link' },
            { action: 'saveContinue', label: mw.msg('qlinker-save-continue'), flags: ['other', 'progressive'], icon: 'link' },
  { action: 'skipOne', label: mw.msg('qlinker-skip'), flags: [ 'other', 'progressive' ], icon: 'next' },
            { action: 'skipOne', label: mw.msg('qlinker-skip'), flags: ['other', 'progressive'], icon: 'next' },
  { action: 'skipMatch', label: mw.msg('qlinker-skip-match'), flags: [ 'other', 'progressive' ], icon: 'arrowNext' },
            { action: 'skipMatch', label: mw.msg('qlinker-skip-match'), flags: ['other', 'progressive'], icon: 'arrowNext' },
  { action: 'safeSearch', label: mw.msg('qlinker-safe-search'), flags: [ 'other' ], icon: 'search' },
            { action: 'safeSearch', label: mw.msg('qlinker-safe-search'), flags: ['other'], icon: 'search' },
  { label: mw.msg('qlinker-cancel'), flags: 'safe' }
            { label: mw.msg('qlinker-cancel'), flags: 'safe' }
];
        ];


// Customize the initialize() function: This is where to add content to the dialog body and set up event handlers.  
        // Customize the initialize() function: This is where to add content to the dialog body and set up event handlers.  
QuickEditorDialog.prototype.initialize = function () {
        QuickEditorDialog.prototype.initialize = function () {
  // Call the parent method
            // Call the parent method
  QuickEditorDialog.super.prototype.initialize.call( this );
            QuickEditorDialog.super.prototype.initialize.call(this);
  // Create and append a layout and some content.
            // Create and append a layout and some content.
  this.content = new OO.ui.PanelLayout( { padded: true, expanded: true } );
            this.content = new OO.ui.PanelLayout({ padded: true, expanded: true });
  this.$body.append( this.content.$element );
            this.$body.append(this.content.$element);
};
        };
 
QuickEditorDialog.prototype.getBodyHeight = function () {
  return 400;
};


QuickEditorDialog.prototype.getSetupProcess = function ( data ) {
        QuickEditorDialog.prototype.getBodyHeight = function () {
  data = data || {};
            return 400;
  return QuickEditorDialog.super.prototype.getSetupProcess.call( this, data )
        };
  .next( function () {
// Set up contents based on data
    this.searchData = data.searchData.query;
    this.starttimestamp = data.searchData.curtimestamp;
this.nextPage();
  }, this );
};


// Use the getActionProcess() method to specify a process to handle the
        QuickEditorDialog.prototype.getSetupProcess = function (data) {
// actions (for the 'save' action, in this example).
            data = data || {};
QuickEditorDialog.prototype.getActionProcess = function ( action ) {
            return QuickEditorDialog.super.prototype.getSetupProcess.call(this, data)
  var dialog = this;
                .next(function () {
  switch ( action ) {
                    // Set up contents based on data
case 'skipOne':
                    this.searchData = data.searchData.query;
return new OO.ui.Process( function () {
                    this.starttimestamp = data.searchData.curtimestamp;
  dialog.skipsCounter++;
                    this.nextPage();
  dialog.nextPage();
                }, this);
}, this );
        };
case 'skipMatch':
return new OO.ui.Process( function () {
  dialog.skipsCounter++;
  dialog.nextMatch();
}, this );
case 'saveContinue':
return new OO.ui.Process( function () {
  dialog.savePage();
}, this );
case 'safeSearch':
return new OO.ui.Process( function () {
  dialog.close();
  protectedSearchQuery(true);
}, this );
  }


  // Fallback to parent handler.
        // Use the getActionProcess() method to specify a process to handle the
  return QuickEditorDialog.super.prototype.getActionProcess.call( this, action );
        // actions (for the 'save' action, in this example).
};
        QuickEditorDialog.prototype.getActionProcess = function (action) {
            var dialog = this;
            switch (action) {
                case 'skipOne':
                    return new OO.ui.Process(function () {
                        dialog.skipsCounter++;
                        dialog.nextPage();
                    }, this);
                case 'skipMatch':
                    return new OO.ui.Process(function () {
                        dialog.skipsCounter++;
                        dialog.nextMatch();
                    }, this);
                case 'saveContinue':
                    return new OO.ui.Process(function () {
                        dialog.savePage();
                    }, this);
                case 'safeSearch':
                    return new OO.ui.Process(function () {
                        dialog.close();
                        protectedSearchQuery(true);
                    }, this);
            }


QuickEditorDialog.prototype.savePage = function ( ) {
            // Fallback to parent handler.
if (this.curPage)
            return QuickEditorDialog.super.prototype.getActionProcess.call(this, action);
{
        };
var api = new mw.Api(), pagename = this.curPage;
api.postWithToken('csrf', {
action: 'edit',
title: this.curPage,
summary: mw.msg('linkify-summary', mw.config.get('wgTitle')),
minor: 1,
basetimestamp: this.timestamp,
starttimestamp: this.starttimestamp,
text: this.text,
tags: 'quick linker'
}).done(function(d) {
if (d && d.edit && d.edit.result == 'Success') mw.notify(mw.msg('qlinker-save-success', pagename));
});
}
var self = this;
if(this.safeMode) setTimeout(function(){ self.nextPage(); }, 5000/(self.skipsCounter+1));
else self.nextPage();
};


QuickEditorDialog.prototype.nextMatch = function ( ) {
        QuickEditorDialog.prototype.savePage = function () {
var m, contextPre, contextPost, contextInner, contextInnerOld, newContext, context;
            if (this.curPage) {
this.matchI++;
                var api = new mw.Api(), pagename = this.curPage;
if (this.searchData.pageids.length <= this.pageI) {
                api.postWithToken('csrf', {
return this.nextPage();
                    action: 'edit',
}
                    title: this.curPage,
                    summary: mw.msg('linkify-summary', mw.config.get('wgTitle')),
                    minor: 1,
                    basetimestamp: this.timestamp,
                    starttimestamp: this.starttimestamp,
                    text: this.text,
                    tags: 'quick linker'
                }).done(function (d) {
                    if (d && d.edit && d.edit.result == 'Success') mw.notify(mw.msg('qlinker-save-success', pagename));
                });
            }
            var self = this;
            if (this.safeMode) setTimeout(function () { self.nextPage(); }, 5000 / (self.skipsCounter + 1));
            else self.nextPage();
        };


var page = this.searchData.pages[this.searchData.pageids[this.pageI]],
        QuickEditorDialog.prototype.nextMatch = function () {
pagecontent = page.revisions[0]['*'];
            var m, contextPre, contextPost, contextInner, contextInnerOld, newContext, context;
if (page.title == mw.config.get('wgTitle')) {
            this.matchI++;
return this.nextPage();
            if (this.searchData.pageids.length <= this.pageI) {
}
                return this.nextPage();
            }


if (m = this.contextRgx.exec(pagecontent)) {
            var page = this.searchData.pages[this.searchData.pageids[this.pageI]],
contextPost = m[3];
                pagecontent = page.revisions[0]['*'];
contextInner = (m[2] == mw.config.get('wgTitle')) ? '[['+mw.config.get('wgTitle')+']]' : '[['+mw.config.get('wgTitle')+'|' + m[2] + ']]';
            if (page.title == mw.config.get('wgTitle')) {
contextInnerOld = '';
                return this.nextPage();
}
            }
else if (m = this.contextRgxLink.exec(pagecontent)) {
if(m[2].endsWith(')'))
{
m = null; // other existing meaning
}
else
{
contextPost = m[3] == mw.config.get('wgTitle')? m[4] : '|' + m[3] + m[4];
contextInner = mw.config.get('wgTitle');
contextInnerOld = '<s>' + m[2] + (m[3] == mw.config.get('wgTitle')? '|' : '') + '</s>';
}
}


if (!m) return this.nextPage();
            if (m = this.contextRgx.exec(pagecontent)) {
                contextPost = m[3];
                contextInner = (m[2] == mw.config.get('wgTitle')) ? '[[' + mw.config.get('wgTitle') + ']]' : '[[' + mw.config.get('wgTitle') + '|' + m[2] + ']]';
                contextInnerOld = '';
            }
            else if (m = this.contextRgxLink.exec(pagecontent)) {
                if (m[2].endsWith(')')) {
                    m = null; // other existing meaning
                }
                else {
                    contextPost = m[3] == mw.config.get('wgTitle') ? m[4] : '|' + m[3] + m[4];
                    contextInner = mw.config.get('wgTitle');
                    contextInnerOld = '<s>' + m[2] + (m[3] == mw.config.get('wgTitle') ? '|' : '') + '</s>';
                }
            }


context = m[0];
            if (!m) return this.nextPage();
contextPre = m[1];
newContext = contextPre+contextInner+contextPost;
this.content.$element.html('<h1><a href="/'+encodeURI(page.title)+'" target="_blank">'+page.title+'</a></h1><p>'+contextPre+contextInnerOld+'<b>'+contextInner+'</b>'+contextPost+'</p>');
this.curPage = page.title;
this.text = pagecontent.replace(context, newContext);
this.timestamp = page.revisions[0].timestamp;
};


QuickEditorDialog.prototype.nextPage = function ( ) {
            context = m[0];
var m, contextPre, contextPost, contextInner, contextInnerOld, newContext;
            contextPre = m[1];
this.pageI++;
            newContext = contextPre + contextInner + contextPost;
this.matchI = 0;
            this.content.$element.html('<h1><a href="/' + encodeURI(page.title) + '" target="_blank">' + page.title + '</a></h1><p>' + contextPre + contextInnerOld + '<b>' + contextInner + '</b>' + contextPost + '</p>');
if (this.searchData.pageids.length <= this.pageI)
            this.curPage = page.title;
{
            this.text = pagecontent.replace(context, newContext);
if(this.curPage === null) {
            this.timestamp = page.revisions[0].timestamp;
this.content.$element.html('<h1><a target="_blank" href="/Special:Search/'+encodeURI('"' + titleNoBrackets +'" -linksto:"'+mw.config.get('wgPageName') + '"')+'">'+mw.msg('qlinker-no-results')+'</a></h1>');
this.actions.setAbilities( {
saveContinue: false, skipOne: false
} );
} else {
this.close();
}
return;
}


this.nextMatch();
        };
}


// Make the window.
        QuickEditorDialog.prototype.nextPage = function () {
var qlinkerEditor = new QuickEditorDialog( {
            var m, contextPre, contextPost, contextInner, contextInnerOld, newContext;
  size: 'medium'
            this.pageI++;
} );
            this.matchI = 0;
            if (this.searchData.pageids.length <= this.pageI) {
                if (this.curPage === null) {
                    this.content.$element.html('<h1><a target="_blank" href="/Special:Search/' + encodeURI('"' + titleNoBrackets + '" -linksto:"' + mw.config.get('wgPageName') + '"') + '">' + mw.msg('qlinker-no-results') + '</a></h1>');
                    this.actions.setAbilities({
                        saveContinue: false, skipOne: false
                    });
                } else {
                    this.close();
                }
                return;
            }


// Create and append a window manager, which will open and close the window.  
            this.nextMatch();
var windowManager = new OO.ui.WindowManager();
        }
$( 'body' ).append( windowManager.$element );


// Add the window to the window manager using the addWindows() method.
        // Make the window.
windowManager.addWindows( [ qlinkerEditor ] );
        var qlinkerEditor = new QuickEditorDialog({
            size: 'medium'
        });


// Open the window!
        // Create and append a window manager, which will open and close the window.
windowManager.openWindow( qlinkerEditor,  { searchData: searchRes } );
        var windowManager = new OO.ui.WindowManager();
}
        $('body').append(windowManager.$element);


function createAddLinksButton(){
        // Add the window to the window manager using the addWindows() method.
var addLinksWizard = $(mw.util.addPortletLink(
        windowManager.addWindows([qlinkerEditor]);
'p-tb',
'#',
mw.msg('qlinker-sidelink'),
't-quicklinker',
mw.msg('qlinker-invoke'),
null,
'#t-whatlinkshere'
));
addLinksWizard.click(function(e){
protectedSearchQuery(false);
e.preventDefault();
});
return addLinksWizard;
}
function protectedSearchQuery(safeSearch)
{
var api = new mw.Api();
api.get( {
action: 'query',
prop: 'linkshere',
lhlimit: 500,
titles: mw.config.get('wgPageName'),
indexpageids: 1
}).done(function(d) {
var isValid = true, safeMode = false;
if(d.query && d.query.pages && d.query.pages[d.query.pageids[0]] && d.query.pages[d.query.pageids[0]].linkshere && d.query.pages[d.query.pageids[0]].linkshere.length > 100)
{
isValid = confirm(mw.msg('qlinker-confirm-masslink'));
safeMode = true;
}
if (!isValid) return;
searchLinksApi(safeSearch).done(function(q){
if (q.error) mw.notify(q.error.info);
if (!q.query || !q.query.pageids || q.query.pageids.length<=1) {
mw.notify(mw.msg('qlinker-no-results'));
return;
}
mw.loader.using(['oojs-ui-windows', 'oojs-ui.styles.icons-movement', 'oojs-ui.styles.icons-editing-core'], function() { createQuickEditorDialog(q, safeMode) } );
});
})
}


function searchLinksApi(protectPrefixSuffix) {
        // Open the window!
var api = new mw.Api(),
        windowManager.openWindow(qlinkerEditor, { searchData: searchRes });
searchRegexPreSufFix = 'insource:/' + allowedPrefix + mw.util.escapeRegExp(titleNoBrackets) + allowedSuffix +'/',
    }
searchRegexNonSafe = 'insource:/' + mw.util.escapeRegExp(titleNoBrackets) +'/',
 
searchRegex = protectPrefixSuffix? searchRegexPreSufFix : searchRegexNonSafe;
    function createAddLinksButton() {
return api.get( {
        var addLinksWizard = $(mw.util.addPortletLink(
action: 'query',
            'p-tb',
generator: 'search',
            '#',
gsrnamespace: 0,
            mw.msg('qlinker-sidelink'),
gsrsearch: searchRegex + ' -linksto:'+mw.config.get('wgPageName'),
            't-quicklinker',
gsrlimit: 50,
            mw.msg('qlinker-invoke'),
prop: 'revisions',
            null,
rvprop: 'content|timestamp',
            '#t-whatlinkshere'
indexpageids: 1,
        ));
curtimestamp: 1
 
});
        addLinksWizard.click(function (e) {
}
            console.log(e);
if ($('.dmbox').length === 0) { // Don't show the tool at Disambiguation pages because it is useless
            protectedSearchQuery(false);
if ($('.orphanpage, .stub').length>0) {
            e.preventDefault();
searchLinksApi().done(function(d){
        });
if (d.query && d.query.pageids && d.query.pageids.length>1) createAddLinksButton().css('font-weight', 'bold')
        return addLinksWizard;
});
    }
}
    function protectedSearchQuery(safeSearch) {
else {
        var api = new mw.Api();
createAddLinksButton();
        api.get({
}
            action: 'query',
}
            prop: 'linkshere',
            lhlimit: 500,
            titles: mw.config.get('wgPageName'),
            indexpageids: 1
        }).done(function (d) {
            var isValid = true, safeMode = false;
            if (d.query && d.query.pages && d.query.pages[d.query.pageids[0]] && d.query.pages[d.query.pageids[0]].linkshere && d.query.pages[d.query.pageids[0]].linkshere.length > 100) {
                isValid = confirm(mw.msg('qlinker-confirm-masslink'));
                safeMode = true;
            }
            if (!isValid) return;
            searchLinksApi(safeSearch).done(function (q) {
                if (q.error) mw.notify(q.error.info);
                if (!q.query || !q.query.pageids || q.query.pageids.length <= 1) {
                    mw.notify(mw.msg('qlinker-no-results'));
                    return;
                }
                mw.loader.using(['oojs-ui-windows', 'oojs-ui.styles.icons-movement', 'oojs-ui.styles.icons-editing-core'], function () { createQuickEditorDialog(q, safeMode) });
            });
        })
    }
 
    function searchLinksApi(protectPrefixSuffix) {
        var api = new mw.Api(),
            searchRegexPreSufFix = 'insource:/' + allowedPrefix + mw.util.escapeRegExp(titleNoBrackets) + allowedSuffix + '/',
            searchRegexNonSafe = 'insource:/' + mw.util.escapeRegExp(titleNoBrackets) + '/',
            searchRegex = protectPrefixSuffix ? searchRegexPreSufFix : searchRegexNonSafe;
        return api.get({
            action: 'query',
            generator: 'search',
            gsrnamespace: 0,
            gsrsearch: searchRegex + ' -linksto:' + mw.config.get('wgPageName'),
            gsrlimit: 50,
            prop: 'revisions',
            rvprop: 'content|timestamp',
            indexpageids: 1,
            curtimestamp: 1
        });
    }
    if ($('.dmbox').length === 0) { // Don't show the tool at Disambiguation pages because it is useless
        if ($('.orphanpage, .stub').length > 0) {
            searchLinksApi().done(function (d) {
                if (d.query && d.query.pageids && d.query.pageids.length > 1) createAddLinksButton().css('font-weight', 'bold')
            });
        }
        else {
            createAddLinksButton();
        }
    }
});
});

נאוויגאציע מעניו