|
|
| (5 גרסאות ביניים של אותו משתמש אינן מוצגות) |
| שורה 1: |
שורה 1: |
| */
| |
| if ( mw.config.get( 'wgNamespaceNumber' ) === 0 ) $(function(){
| |
| var titleNoBrackets = /(.+?)( \(|$)/.exec(mw.config.get('wgTitle')), allowedSuffix, allowedPrefix;
| |
| if (titleNoBrackets) titleNoBrackets = titleNoBrackets[1];
| |
| 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)
| |
| switch ( mw.config.get('wgContentLanguage') ) {
| |
| case 'he':
| |
| allowedSuffix = '(?=ים|ות|[^א-ת])';
| |
| allowedPrefix = '(?:[כלבמשהו]|[^א-ת])';
| |
| break;
| |
| default:
| |
| allowedSuffix = 's?[^a-z]';
| |
| allowedPrefix = '';
| |
| }
| |
|
| |
| switch (mw.config.get('wgUserLanguage') ) {
| |
| case 'he':
| |
| mw.messages.set({
| |
| 'qlinker-edit' : 'עריכה מהירה',
| |
| 'qlinker-cancel' : 'ביטול',
| |
| 'linkify-summary': 'הוספת קישור ל[[$1]]',
| |
| 'qlinker-save-success': 'שמירת $1 בוצעה בהצלחה!',
| |
| 'qlinker-save-continue': 'שמירה',
| |
| 'qlinker-skip': 'דילוג דף',
| |
| 'qlinker-skip-match': 'דילוג מופע',
| |
| 'qlinker-safe-search': 'חיפוש בטוח',
| |
| 'qlinker-invoke': 'הוספת בזק של קישורים',
| |
| 'qlinker-sidelink': 'הוספת קישורים',
| |
| 'qlinker-no-results': 'לא נמצאו תוצאות',
| |
| 'qlinker-confirm-masslink': 'לדף זה יש כבר הרבה קישורים, ונדרשת זהירות בהוספת הקישורים. האם נחוצים קישורים נוספים?'
| |
| });
| |
| break;
| |
| default:
| |
| mw.messages.set({
| |
| 'qlinker-edit' : 'Quick edit',
| |
| 'qlinker-cancel' : 'Cancel',
| |
| 'linkify-summary': 'Adding link to [[$1]]',
| |
| 'qlinker-save-success': '$1 has been saved successfully!',
| |
| 'qlinker-save-continue': 'Save',
| |
| 'qlinker-skip': 'Skip page',
| |
| 'qlinker-skip-match': 'Skip match',
| |
| 'qlinker-safe-search': 'Safe search',
| |
| 'qlinker-invoke': 'Quickly add links',
| |
| 'qlinker-sidelink': 'Add links',
| |
| 'qlinker-no-results': 'No results found',
| |
| 'qlinker-confirm-masslink': 'This page already has many links. Are you sure?'
| |
| });
| |
| break;
| |
| }
| |
|
| |
|
| |
| function createQuickEditorDialog(searchRes, safeMode){
| |
| function QuickEditorDialog( config ) {
| |
| this.contextRgx = new RegExp('(.[^\\[])(' + mw.util.escapeRegExp(titleNoBrackets) +')((?![^\\[\\{][\\]\\}]).*)', 'ig');
| |
| this.contextRgxLink = new RegExp('(.\\[\\[)([^\\]]+?)\\|(' + mw.util.escapeRegExp(titleNoBrackets) +')(\\]\\].)', 'ig');
| |
| this.pageI = -1;
| |
| this.matchI = 0;
| |
| this.searchData = null;
| |
| this.curPage = null;
| |
| this.safeMode = safeMode;
| |
| this.skipsCounter = 0;
| |
| this.starttimestamp = null;
| |
| this.timestamp = null;
| |
| QuickEditorDialog.super.call( this, config );
| |
| }
| |
| OO.inheritClass( QuickEditorDialog, OO.ui.ProcessDialog );
| |
|
| |
| // Specify a name for .addWindows()
| |
| QuickEditorDialog.static.name = 'QuickEditorDialog';
| |
| // Specify a title statically (or, alternatively, with data passed to the opening() method).
| |
| QuickEditorDialog.static.title = mw.msg('qlinker-edit');
| |
|
| |
| QuickEditorDialog.static.actions = [
| |
| { 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: 'skipMatch', label: mw.msg('qlinker-skip-match'), flags: [ 'other', 'progressive' ], icon: 'arrowNext' },
| |
| { action: 'safeSearch', label: mw.msg('qlinker-safe-search'), flags: [ 'other' ], icon: 'search' },
| |
| { 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.
| |
| QuickEditorDialog.prototype.initialize = function () {
| |
| // Call the parent method
| |
| QuickEditorDialog.super.prototype.initialize.call( this );
| |
| // Create and append a layout and some content.
| |
| this.content = new OO.ui.PanelLayout( { padded: true, expanded: true } );
| |
| this.$body.append( this.content.$element );
| |
| };
| |
|
| |
| QuickEditorDialog.prototype.getBodyHeight = function () {
| |
| return 400;
| |
| };
| |
|
| |
| QuickEditorDialog.prototype.getSetupProcess = function ( data ) {
| |
| data = data || {};
| |
| 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
| |
| // 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 );
| |
| }
| |
|
| |
| // Fallback to parent handler.
| |
| return QuickEditorDialog.super.prototype.getActionProcess.call( this, action );
| |
| };
| |
|
| |
| QuickEditorDialog.prototype.savePage = function ( ) {
| |
| if (this.curPage)
| |
| {
| |
| 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 ( ) {
| |
| var m, contextPre, contextPost, contextInner, contextInnerOld, newContext, context;
| |
| this.matchI++;
| |
| if (this.searchData.pageids.length <= this.pageI) {
| |
| return this.nextPage();
| |
| }
| |
|
| |
| var page = this.searchData.pages[this.searchData.pageids[this.pageI]],
| |
| pagecontent = page.revisions[0]['*'];
| |
| if (page.title == mw.config.get('wgTitle')) {
| |
| 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>';
| |
| }
| |
| }
| |
|
| |
| if (!m) return this.nextPage();
| |
|
| |
| context = m[0];
| |
| contextPre = m[1];
| |
| newContext = contextPre+contextInner+contextPost;
| |
| this.content.$element.html('<h1><a href="/wiki/'+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 ( ) {
| |
| var m, contextPre, contextPost, contextInner, contextInnerOld, newContext;
| |
| 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="/wiki/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.
| |
| var qlinkerEditor = new QuickEditorDialog( {
| |
| size: 'medium'
| |
| } );
| |
|
| |
| // Create and append a window manager, which will open and close the window.
| |
| var windowManager = new OO.ui.WindowManager();
| |
| $( 'body' ).append( windowManager.$element );
| |
|
| |
| // Add the window to the window manager using the addWindows() method.
| |
| windowManager.addWindows( [ qlinkerEditor ] );
| |
|
| |
| // Open the window!
| |
| windowManager.openWindow( qlinkerEditor, { searchData: searchRes } );
| |
| }
| |
|
| |
| function createAddLinksButton(){
| |
| var addLinksWizard = $(mw.util.addPortletLink(
| |
| '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) {
| |
| var api = new mw.Api(),
| |
| searchRegexPreSufFix = 'insource:/' + allowedPrefix + mw.util.escapeRegExp(titleNoBrackets) + allowedSuffix +'/',
| |
| searchRegexNonSafe = 'insource:/' + mw.util.escapeRegExp(titleNoBrackets) +'/',
| |
| searchRegex = protectPrefixSuffix? searchRegexPreSufFix : searchRegexNonSafe,
| |
| linkToEscaped = ' -linksto:"'+mw.config.get('wgPageName').replace('"', '\\"')+'"';
| |
|
| |
| return api.get( {
| |
| action: 'query',
| |
| generator: 'search',
| |
| gsrnamespace: 0,
| |
| gsrsearch: searchRegex + linkToEscaped,
| |
| 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();
| |
| }
| |
| }
| |
| });
| |