مدیاویکی:Gadget-CheckDictation.js: تفاوت میان نسخه‌ها

از اسلامیکال
پرش به ناوبری پرش به جستجو
(صفحه‌ای تازه حاوی «//<nowiki> $.when($.ready, mw.loader.using(['mediawiki.api', 'mediawiki.util'])).then(function() { 'use strict'; var projectPageAllowedCats = [ 'رهنمودهای ویکی‌پدیا', 'سیاست‌های ویکی‌پدیا', 'راهنمای ویکی‌پدیا', 'انشاهای ویکی‌پدیا', 'انشاهای مکمل ویکی‌پدیا', 'ابزارهای ویکی‌...» ایجاد کرد)
 
بدون خلاصۀ ویرایش
 
(یک نسخهٔ میانی ویرایش شده توسط یک کاربر دیگر نشان داده نشد)
خط ۴: خط ۴:


     var projectPageAllowedCats = [
     var projectPageAllowedCats = [
         'رهنمودهای ویکی‌پدیا',
         'رهنمودهای اسلامیکال',
         'سیاست‌های ویکی‌پدیا',
         'سیاست‌های اسلامیکال',
         'راهنمای ویکی‌پدیا',
         'راهنمای اسلامیکال',
         'انشاهای ویکی‌پدیا',
         'انشاهای اسلامیکال',
         'انشاهای مکمل ویکی‌پدیا',
         'انشاهای مکمل اسلامیکال',
         'ابزارهای ویکی‌پدیا',
         'ابزارهای اسلامیکال',
         'خودآموز ویکی‌پدیا'
         'خودآموز اسلامیکال'
     ];
     ];


     var projectPageAllowedTitles = [
     var projectPageAllowedTitles = [
         'ویکی‌پدیا:اشتباه‌یاب/تست',
         'اسلامیکال:اشتباه‌یاب/تست',
         'ویکی‌پدیا:اشتباه‌یاب/تمرین',
         'اسلامیکال:اشتباه‌یاب/تمرین',
         'ویکی‌پدیا:صفحه تمرین'
         'اسلامیکال:صفحه تمرین'
     ];
     ];


     var projectPageWrongListedTitles = 'ویکی‌پدیا:اشتباه‌یاب/موارد_درست/';
     var projectPageWrongListedTitles = 'اسلامیکال:اشتباه‌یاب/موارد_درست/';


     if (mw.config.get('wgAction') !== 'view' ||
     if (mw.config.get('wgAction') !== 'view' ||
خط ۲۴۵: خط ۲۴۵:
                 class: 'ui-button-blue',
                 class: 'ui-button-blue',
                 click: function() {
                 click: function() {
                     var exceptionsPage = 'ویکی‌پدیا:اشتباه‌یاب/موارد درست/' + mw.config.get('wgPageName').replace(/_/g, ' ');
                     var exceptionsPage = 'اسلامیکال:اشتباه‌یاب/موارد درست/' + mw.config.get('wgPageName').replace(/_/g, ' ');
                     var exceptionsUrl = mw.util.getUrl(exceptionsPage);
                     var exceptionsUrl = mw.util.getUrl(exceptionsPage);
                     loadPage(exceptionsPage)
                     loadPage(exceptionsPage)
خط ۲۸۹: خط ۲۸۹:
     }
     }


     var exceptionsPage = 'ویکی‌پدیا:اشتباه‌یاب/موارد درست/' + mw.config.get('wgPageName').replace(/_/g, ' ');
     var exceptionsPage = 'اسلامیکال:اشتباه‌یاب/موارد درست/' + mw.config.get('wgPageName').replace(/_/g, ' ');
     var exceptionsUrl = mw.util.getUrl(exceptionsPage);
     var exceptionsUrl = mw.util.getUrl(exceptionsPage);
     $.when(
     $.when(
         $.getJSON('//checkdictation-fa.toolforge.org/check/' + mw.config.get('wgPageName')),
         $.getJSON('' + mw.config.get('wgPageName')),
         loadPage(exceptionsPage)
         loadPage(exceptionsPage)
     ).then(
     ).then(
خط ۵۷۹: خط ۵۷۹:
                        $('CheckDictation-marked-' + word.replace(/ /g, '_')).css('background-color', '');
                        $('CheckDictation-marked-' + word.replace(/ /g, '_')).css('background-color', '');
                        element.css('background-color', '').css('color', 'grey').off();
                        element.css('background-color', '').css('color', 'grey').off();
                        loadPage('ویکی‌پدیا:اشتباه‌یاب/فهرست موارد درست').then(function(text) {
                        loadPage('اسلامیکال:اشتباه‌یاب/فهرست موارد درست').then(function(text) {
                            if ((text + '\n').indexOf('* ' + (cleanedWord || word) + '\n') !== -1) {
                            if ((text + '\n').indexOf('* ' + (cleanedWord || word) + '\n') !== -1) {
                                return;
                                return;
                            }
                            }
                            return savePage('ویکی‌پدیا:اشتباه‌یاب/فهرست موارد درست', text + '\n* ' + (cleanedWord || word), 'افزودن لغت درست و پرکاربرد «' + (cleanedWord || word) + '» به فهرست کلمات [[وپ:اشتباه|اشتباه‌یاب]]. موجود در مقالهٔ [[' + mw.config.get('wgPageName') + ']]');
                            return savePage('اسلامیکال:اشتباه‌یاب/فهرست موارد درست', text + '\n* ' + (cleanedWord || word), 'افزودن لغت درست و پرکاربرد «' + (cleanedWord || word) + '» به فهرست کلمات [[وپ:اشتباه|اشتباه‌یاب]]. موجود در مقالهٔ [[' + mw.config.get('wgPageName') + ']]');
                        }).then(function() {
                        }).then(function() {
                            mw.notify('کلمهٔ «' + word + '» به فهرست کلمات درست و پرکاربرد افزوده شد.');
                            mw.notify('کلمهٔ «' + word + '» به فهرست کلمات درست و پرکاربرد افزوده شد.');
                        });
                        });
                        $.get('//checkdictation-fa.toolforge.org/check/Botupdate').then(function() {}, function() {});
                        $.get('').then(function() {}, function() {});
                    });
                    });
                });
                });
خط ۶۵۲: خط ۶۵۲:
                         mw.config.get('wgPageName'),
                         mw.config.get('wgPageName'),
                         text = postEdit(text),
                         text = postEdit(text),
                         'ویرایش خودکار: اصلاح برچسب‌های نادرست ([[ویکی‌پدیا:اشتباه‌یاب|اشتباه‌یاب]])'
                         'ویرایش خودکار: اصلاح برچسب‌های نادرست ([[اسلامیکال:اشتباه‌یاب|اشتباه‌یاب]])'
                     );
                     );
             });
             });

نسخهٔ کنونی تا ‏۲۵ ژانویهٔ ۲۰۲۳، ساعت ۰۷:۳۸

//<nowiki>
$.when($.ready, mw.loader.using(['mediawiki.api', 'mediawiki.util'])).then(function() {
    'use strict';

    var projectPageAllowedCats = [
        'رهنمودهای اسلامیکال',
        'سیاست‌های اسلامیکال',
        'راهنمای اسلامیکال',
        'انشاهای اسلامیکال',
        'انشاهای مکمل اسلامیکال',
        'ابزارهای اسلامیکال',
        'خودآموز اسلامیکال'
    ];

    var projectPageAllowedTitles = [
        'اسلامیکال:اشتباه‌یاب/تست',
        'اسلامیکال:اشتباه‌یاب/تمرین',
        'اسلامیکال:صفحه تمرین'
    ];

    var projectPageWrongListedTitles = 'اسلامیکال:اشتباه‌یاب/موارد_درست/';

    if (mw.config.get('wgAction') !== 'view' ||
    	([0, 4, 12, 118].indexOf(mw.config.get('wgNamespaceNumber')) === -1 &&
    	 mw.config.get('wgPageName') !== 'کاربر:' + mw.config.get('wgUserName') + '/صفحه_تمرین') ||
        mw.util.getParamValue('diff') ||
        mw.util.getParamValue('oldid') ||
        $('.noarticletext').length) {
        return;
    }
    
    var siteSub = $('#siteSub');
    if (mw.config.get('skin') === 'timeless') {
    	siteSub = $('#p-namespaces');
    }

    if (mw.config.get('wgNamespaceNumber') === 4 && mw.config.get('wgPageName').search(projectPageWrongListedTitles) === 0) {
        var returnTitle = mw.config.get('wgPageName').split(projectPageWrongListedTitles)[1]
        siteSub.append(' ', $('<span>', {
            html: 'این صفحه حاوی موارد مستثنی‌شده برای صفحهٔ <a href="//fa.wikipedia.org/wiki/' + returnTitle + '">' + returnTitle.replace(/\_/g, ' ') + '</a> است.',
            class: 'CheckDictation-allgood-label'
        }));
    }

    if (mw.config.get('wgNamespaceNumber') === 4 &&
        projectPageAllowedTitles.indexOf(mw.config.get('wgPageName').replace(/_/g, ' ')) === -1 &&
        mw.config.get("wgCategories").every(function(x) {
            return projectPageAllowedCats.indexOf(x) === -1;
        })) {
        return;
    }
    if ($('ul[class="redirectText"]')[0]) {
        return;
    } //صفحه تغییرمسیر را بررسی نکند
    var pageContentCache;

    function getPageTextCache() {
        return pageContentCache ? $.Deferred().resolve(pageContentCache) : loadPage(mw.config.get('wgPageName'));
    }

    // Copyedited from https://de.wikipedia.org/wiki/MediaWiki:Gadget-Rechtschreibpruefung.js
    function markWord(node, text, word, hint, color, preparedId) {
        var pos, len, newnodes = 0;
        var newnode, middlenode, endnode;

        // textnode - search for word
        if (node.nodeType == 3) {
            pos = node.data.search(text);
            if (pos >= 0) {
                // create new span-element
                newnode = $('<span>', {
                    title: hint,
                    class: 'CheckDictation-marked CheckDictation-marked-' + word.replace(/ /g, '_'),
                    id: preparedId
                }).css('background-color', color)[0];

                // get length of the matching part
                len = node.data.match(text)[0].length;

                // splits content in three parts: begin, middle and end
                middlenode = node.splitText(pos);
                endnode = middlenode.splitText(len);

                // appends a copy of the middle to the new span-node
                newnode.appendChild(middlenode.cloneNode(true));
                // replace middlenode with the new span-node
                middlenode.parentNode.replaceChild(newnode, middlenode);

                newnodes = 1;
            }
        } else if ((node.nodeType == 1) // element node
            &&
            (node.hasChildNodes()) // with child nodes
            &&
            (node.tagName.toLowerCase() != "script") // no script, style and form
            &&
            (node.tagName.toLowerCase() != "style") && (node.tagName.toLowerCase() != "form")) {
            var this_child;
            for (this_child = 0; this_child < node.childNodes.length; this_child++) {
                this_child = this_child + markWord(node.childNodes[this_child], text, word, hint, color, preparedId);
            }
        }
        return newnodes;
    }

    function markWord2(node, text, word, hint, preparedId) {
        var pos, len, newnodes = 0;
        var newnode, middlenode, endnode;

        // textnode - search for word
        if (node.nodeType == 3) {
            pos = node.data.search(text);
            if (pos >= 0) {
                // create new span-element
                newnode = $('<span>', {
                    title: hint,
                    class: 'CheckDictation-marked CheckDictation-marked-' + word.replace(/ /g, '_'),
                    id: preparedId
                })[0];

                // get length of the matching part
                len = node.data.match(text)[0].length;

                // splits content in three parts: begin, middle and end
                middlenode = node.splitText(pos);
                endnode = middlenode.splitText(len);

                // appends a copy of the middle to the new span-node
                newnode.appendChild(middlenode.cloneNode(true));
                // replace middlenode with the new span-node
                middlenode.parentNode.replaceChild(newnode, middlenode);

                newnodes = 1;
            }
        } else if ((node.nodeType == 1) // element node
            &&
            (node.hasChildNodes()) // with child nodes
            &&
            (node.tagName.toLowerCase() != "script") // no script, style and form
            &&
            (node.tagName.toLowerCase() != "style") && (node.tagName.toLowerCase() != "form")) {
            var this_child;
            for (this_child = 0; this_child < node.childNodes.length; this_child++) {
                this_child = this_child + markWord2(node.childNodes[this_child], text, word, hint, preparedId);
            }
        }
        return newnodes;
    }

    function loadPage(title) {
        return (new mw.Api()).get({
            action: 'query',
            prop: 'revisions',
            titles: title,
            rvprop: 'content',
            format: 'json'
        }).then(function(data) {
            return ((data.query.pages[Object.keys(data.query.pages)[0] || ''].revisions || '')[0] || '')['*'];
        });
    }

    function savePage(title, text, summary) {
        return (new mw.Api()).post({
            action: 'edit',
            title: title,
            text: text,
            summary: summary,
            minor: '',
            token: mw.user.tokens.get('csrfToken')
        }).then(function(data) {
            if (data.error && data.error.info) {
                mw.notify(data.error.info);
            }
        }, function(data) {
            mw.notify(data);
        });
    }

    function postEdit(text){
        // رفع مشکل [[Special:Permalink/25174868#متن هایلایت‌شده]]
        var otext = ''
        while (otext!=text){
            otext = text
            text=text.replace(/\<span[^>]+CheckDictation\-marked[^>]+\>([^<>]+)\<\/span\>/g, '$1')
        }
        return text
    }

    function dictationReplaceDialog(title, diatext, word, suggestions) {


        var defer = $.Deferred();
        $('#CheckDictation-form, #CheckDictation-form-input').remove();
        $('<div>', {
            html: title
        }).append('<br><br><br>' + diatext).append(
            '<br><br>',
            $('<input>', {
                id: 'CheckDictation-form-input',
                value: word,
                style: 'line-height: 2;'
            }),
            ' ',
            persianWikiTools && persianWikiTools.superTool ? $('<img>', {
                src: '//upload.wikimedia.org/wikipedia/fa/f/fc/Button_super_tool.png',
                alt: 'ابرابزار',
                title: 'ابرابزار'
            }).click(function retrySuperTool() {
                $('#CheckDictation-form-input').val((persianWikiTools.superTool(' ' + $('#CheckDictation-form-input').val() + ' ')).trim());
            }) : '<br><br>',
            $('<div>').append(suggestions.map(function(text) {
                return $('<button>', {
                    text: text.replace('|', '❙')
                }).css({
                    'margin-left': '8px'
                }).click(function() {
                    $('#CheckDictation-form-input').val(text);
                });
            })),
            '<br>جایگزینی موارد بیشتر در متن:<br><br>',
            $('<input>', {
                id: 'CheckDictation-form-input1',
                value: '',
                style: 'line-height: 2;'
            }), ' > ',
            $('<input>', {
                id: 'CheckDictation-form-input2',
                value: '',
                style: 'line-height: 2;'
            })
        ).dialog({
            width: 800,
            title: 'اصلاح یک کلمه به طور عمومی در متن',
            buttons: [{
                text: 'افزودن به فهرست کلمات درست و پرکاربرد',
                class: 'ui-button-red',
                click: function() {
                    if (confirm('کلماتی که به فهرست افزوده می‌شوند باید درست و پرکاربرد باشند. اگر کلمه درست و پرکاربرد است دکمهٔ Ok را کلیک کنید در غیر این صورت دکمهٔ Cancel را کلیک کنید.')) {
                        defer.reject();
                    }
                    $(this).dialog('close');
                }
            }, {
                text: 'فقط برای این مقاله درست است',
                class: 'ui-button-blue',
                click: function() {
                    var exceptionsPage = 'اسلامیکال:اشتباه‌یاب/موارد درست/' + mw.config.get('wgPageName').replace(/_/g, ' ');
                    var exceptionsUrl = mw.util.getUrl(exceptionsPage);
                    loadPage(exceptionsPage)
                    .then(function(exceptionsText) {
                        // Turn exceptions into an array
                        var exceptions = [];
                        if (exceptionsText !== undefined) {
                            var pattern = /(?:\* )([^\n\r]+)(?:[\r\n]|$)/g,
                                matches;
                            while (matches = pattern.exec(exceptionsText)) {
                                exceptions.push(matches[1]);
                            }
                        }
                        var newExceptions = exceptions;
                        newExceptions.push($('#CheckDictation-form-input').val());
                        newExceptions = '* ' + newExceptions.join('\n* ');
                        savePage(exceptionsPage, newExceptions, 'افزودن >' + $('#CheckDictation-form-input').val()).then(function() {
                            location.href = location.href;
                        });
                        $('#CheckDictation-form, #CheckDictation-form-input').remove();
                        $(this).dialog('close');
                    })
                }
            }, {
                text: 'اصلاح شود',
                class: 'ui-button-green',
                click: function() {
                    var box1 = $('#CheckDictation-form-input1', this).val();
                    var box2 = $('#CheckDictation-form-input2', this).val();
                    if (box1 === box2) {
                        box1 = '';
                        box2 = '';
                    }
                    defer.resolve($('#CheckDictation-form-input', this).val(), box1, box2);
                    $(this).dialog('close');
                }
            }],
            close: function() {
                $('#CheckDictation-form, #CheckDictation-form-input').remove();
            }
        }).parent().prop('id', 'CheckDictation-form');
        return defer;
    }

    var exceptionsPage = 'اسلامیکال:اشتباه‌یاب/موارد درست/' + mw.config.get('wgPageName').replace(/_/g, ' ');
    var exceptionsUrl = mw.util.getUrl(exceptionsPage);
    $.when(
        $.getJSON('' + mw.config.get('wgPageName')),
        loadPage(exceptionsPage)
    ).then(
    	function(result, exceptionsText) {
	        result = result[0];
	        if (!Array.isArray(result.result)) {
	            console.error(result.error);
	            return;
	        }
	
	        var issues = result.result;
	        if (issues.length === 0) {
	            siteSub.append(' ', $('<span>', {
	                text: 'اشتباه‌یاب: اشتباهی پیدا نشد!',
	                class: 'CheckDictation-allgood-label',
	            }));
	            return;
	        }
	
	        // Turn exceptions into an array
	        var exceptions = [];
	        if (exceptionsText !== undefined) {
	            var pattern = /(?:\* )([^\n\r]+)(?:[\r\n]|$)/g,
	                matches;
	            while (matches = pattern.exec(exceptionsText)) {
	                exceptions.push(matches[1]);
	            }
	        }
	
	        if (exceptions.length > 0) {
	            var numberOfExceptions = exceptions.length;
	            siteSub.append(' ', $('<span>', {
	                'class': 'CheckDictation-exceptions-label'
	            }).append(
	                'اشتباه‌یاب: ' + numberOfExceptions.toLocaleString('fa') + ' کلمهٔ مشکوک به اشتباه ',
	                $('<a>', {
	                    href: exceptionsUrl,
	                    text: 'مستثنی ' + (numberOfExceptions > 1 ? 'شده‌اند' : 'شده‌است')
	                })
	            ));
	        }
	
	        // Remove those words that are in the exceptions list from the issues list
	        issues = issues.filter(function(issue) {
	            return exceptions.indexOf(issue.word) === -1;
	        });
	
	        if (issues.length === 0) {
	            return;
	        }
	
	        var availableTypes = {};
	        issues.forEach(function(x) {
	            availableTypes[x.type] = true;
	        });
	        var types = result.types;
	
	        var legend = Object.keys(types).filter(function(x) {
	            return availableTypes[x];
	        }).map(function(x) {
	            var type = types[x];
	            return [
	                $('<div>').css({
	                    width: '12px',
	                    height: '12px',
	                    display: 'inline-block',
	                    'background-color': type.color
	                }),
	                ' ',
	                $('<span>', {
	                    text: type.title
	                }).css({
	                    'font-size': '10pt'
	                })
	            ];
	        }).reduce(function(x, y) {
	            return x.concat('، ', y);
	        });
	
	        $('#CheckDictation-tool').remove();
	
	        // رفع تداخل با provit.js
	        var anchor1 = mw.config.get('wgAction') === 'edit' ?
	            '#firstHeading' :
	            'h1:first';
	        var numberOfIssues = issues.length.toLocaleString('fa');
	        siteSub.append(' ', $('<span>', {
	            text: 'اشتباه‌یاب: ' + numberOfIssues + ' مشکل نوشتاری یا شیوه‌نامه‌ای یافت شد؛ برای بررسی و اصلاح اینجا کلیک کنید',
	            class: 'CheckDictation-issues-label'
	        }).click(function() {
	            $(this).hide();
	            $('#CheckDictation-tool').show();
	        }));
	        $(anchor1).after($('<div>', {
	            id: 'CheckDictation-tool'
	        }).hide().append(
	            $('<big>', {
	                text: numberOfIssues + ' مورد مشکوک به اشتباه نوشتاری یا شیوه‌نامه‌ای یافت شد!'
	            }).css('font-style', 'italic'),
	            ' (',
	            legend,
	            ')',
	            $('<div>', {
	                id: 'spellmarkedwords',
	                text: 'موارد مشکوک به اشتباه: '
	            }),
	            '<br><br>',
	            $('<div>', {
	                id: 'CheckDictation-button-place'
	            }),
	            $('<div>', {
	                id: 'CheckDictation-button-place-after',
	            }).css('font-size', '10pt').append(
	                'در صورت کلیک بر روی دکمهٔ فوق موارد درست در ',
	                $('<a>', {
	                    href: exceptionsUrl,
	                    text: exceptionsPage
	                }),
	                ' ذخیره می‌شوند.',
	                '<br>',
	                $('<div>', {
	                    id: 'CheckDictation-button-place-after-2',
	                    text: 'استفادهٔ نادرست از این دکمه، باعث می‌شود دسترسی شما به ابزار بسته شود. پیش از کلیک بر روی دکمه، مطمئن شوید که همهٔ موارد پیشنهادی درست هستند. پیش از کلیک بر روی دکمه، حتماً از ابرابزار استفاده کنید. بسیاری از خطاهای مقاله توسط ابرابزار رفع می‌شوند.'
	                }).css({
	                    'font-size': '10pt',
	                    'font-weight': 'bold',
	                    'color': 'red'
	                }),
	                '<br>', [
	                    'نکتهٔ ۱: بعضی از این موارد، فقط در حالت ویرایش دیده‌ می‌شوند!',
	                    'نکتهٔ ۲: با کلیک کردن بر روی کلمات در بالا، بدون رفتن به پنجرهٔ ویرایش به صورت خودکار می‌توانید کلمهٔ درست را جایگزین کنید.',
	                    'نکتهٔ ۳: می‌توانید چند مورد را پشت سر هم با کلیک انتخاب کنید و با زدن دکمه‌ای که ظاهر می‌شود همهٔ آنها را در یک ویرایش جایگزین کنید.'
	                ].map(function(x) {
	                    return $('<div>', {
	                        text: x
	                    }).css('font-size', '8pt');
	                })
	            )
	        ));
	        $('<button>', {
	            text: 'ابهام‌زدایی با ابزاری دیگر',
	            style: 'margin-right: 2em',
	            id: 'CheckDictation-Disambig'
	        }).click(function() {
	            var my_url = 'https://dispenser.info.tm/~dispenser/cgi-bin/dab_solver.py?lang=fa&page=' + mw.config.get('wgPageName')
	            window.open(my_url, '_blank');
	        }).appendTo('#CheckDictation-button-place').append(
	            '<br><br>')
	        $('#CheckDictation-Disambig').hide();
	
	        if (mw.config.get('wgUserGroups').indexOf('sysop') > -1 || mw.config.get('wgUserGroups').indexOf('eliminator') > -1 || mw.config.get('wgUserGroups').indexOf('patroller') > -1) {
	            $('<button>', {
	                text: 'ذخیره در زیرصفحه: همهٔ موارد برای این مقاله درست است!',
	                style: 'margin-right: 2em',
	                id: 'CheckDictation-close'
	            }).click(function() {
	                var newExceptions = exceptions;
	                var addToExceptions = issues.map(function(issue) {
	                    return issue.word;
	                });
	                addToExceptions.forEach(function(word) {
	                    newExceptions.push(word);
	                });
	                newExceptions = '* ' + newExceptions.join('\n* ');
	
	                savePage(exceptionsPage, newExceptions, 'افزودن >' + addToExceptions.join('، ')).then(function() {
	                    location.href = location.href;
	                });
	
	            }).appendTo('#CheckDictation-button-place');
	        } else {
	            $('#CheckDictation-button-place-after').hide();
	            $('#CheckDictation-button-place-after-2').hide();
	        }
	
	        var arabic_diacritics = "ًٌٍَُِّْٔ"
	        var main_regex = '\[؛؟\\s\\n\\r\\•●⚫⬤\\„\\”\\‚\\’\\‘\\“\\[\\]\\{\\}\\t\\<\\>\\.\\,\\"' + "\\'\\+\\!\\?\\-\\/\\»«،\\:\\|\\(\\)\۰۱۲۳۴۵۶۷۸۹]";
	        var start_regex = '\(\^\|' + main_regex + '\)';
	        var end_regex = '\(\$\|[' + arabic_diacritics + ']*' + main_regex + '\)';
	        var articleBody = $('#bodyContent, #article')[0];
	        var replacements = [];
	        var markedItems = [];
	
	        issues.forEach(function(item, i) {
	            var word = item.word,
	                type = types[item.type],
	                suggestions = item.suggestions.sort(),
	                cleanedWord = item.cleaned_word,
	                regexp, preparedId;
	            var myhint = type.hint
	            if (type.autofix == 'D') {
	                $('#CheckDictation-Disambig').show();
	                myhint = suggestions.join(' | ')
	            }
	            if (i !== 0) {
	                markedItems.push('، ');
	            }
	            regexp = new RegExp(type.syntax ?
	                mw.util.escapeRegExp(word) :
	                (start_regex + '(' +
	                    word.substring(0, word.length - 1).replace(/[ء-يٓ-ٕپچژگکكڪﻙﻚیﻱﻲكﮑﮐﮏﮎﻜﻛﻚﻙىﻯيہەھﻰ-ﻴ]/g, '$&\[ً-ِّْٰٔ\]\*') + word.slice(-1) +
	                    ')' + end_regex),
	                'g'
	            );
	            preparedId = 'tool-' + encodeURI(word).replace(/%/g, '.');
	            if (type.autofix == 'D') {
	                markWord2(articleBody, regexp, word, myhint || suggestions[0], preparedId);
	                $("a.mw-disambig").css("background-color", "#fadbd8");
	                $("a.mw-disambig").css("color", "#999933");
	            } else {
	                markWord(articleBody, regexp, word, myhint || suggestions[0], type.color, preparedId);
	            }
	            var element = $('<span>', {
	                style: 'background-color: ' + type.color,
	                text: word,
	                title: myhint || suggestions[0]
	            });
	            element.css('cursor', 'pointer');
	            element.click(function() {
	                if (!type.autofix) {
	                    location.hash = preparedId;
	                    return;
	                }
	                getPageTextCache().then(function(content) {
	                    var nearWordsRegex = new RegExp('((?:\\S+\\s+){0,5}|\^)(?:[«\\[\\(\\)\\|\\-۰۱۲۳۴۵۶۷۸۹0-9\\u200c\\]])?(' + word.substring(0, word.length - 1).replace(/[^ ]/g, '$&\[ً-ِّْٰٔ\]\*') + word.slice(-1) + ')(\\s*(?:\\S+\\s+){0,5}|\$)', 'g')
	                    var nearWordsList = [],
	                        found;
	                    while (found = nearWordsRegex.exec(content)) {
	                        var myfound = found[0]
	                        if (myfound[0] == '[') {
	                            myfound = '[' + myfound
	                        }
	                        if (type.autofix == 'D') {
	                            if (myfound.includes('[[' + word + ']]') || myfound.includes('[[' + word + '|')) {
	                                nearWordsList.push(myfound);
	                            } else {
	                                continue;
	                            }
	                        } else {
	                            nearWordsList.push(myfound);
	                        }
	                    }
	                    if (nearWordsList != null) {
	                        nearWordsList = '… ' + nearWordsList.join(' …<br>… ') + ' …'
	                        nearWordsList = nearWordsList.replace(/\t/g, '	')
	                        nearWordsList = nearWordsList.replace(/\n\n/g, '<br>')
	                        nearWordsList = nearWordsList.replace(/\n(\*|\#|\;|\=)/g, '<br>$1')
	                    } else {
	                        nearWordsList = ''
	                    }
	                    dictationReplaceDialog(
	                        ('در متن یا متن‌های زیر عبارت «' + word + '» با چه چیزی جایگزین شود؟'),
	                        (nearWordsList.replace(new RegExp('(' + word.substring(0, word.length - 1).replace(/[^ ]/g, '$&\[ً-ِّْٰٔ\]\*') + word.slice(-1) + ')', 'g'), '<big><b> $1 </b></big>')),
	                        word,
	                        suggestions
	                    ).then(function(toWord, toWord1, toWord2) {
	                        // Hide mark as valid button and comments, it confuses the users
	                        $('#CheckDictation-close, #CheckDictation-button-place-after').hide();
	
	                        element.css('background-color', '').css('color', 'grey').text(word + '⟸' + toWord).off();
	                        toWord = toWord.replace(/\200c /g, ' ').replace(/ \200c/g, ' ');
	                        if (mw.config.get('wgAction') === 'edit') {
	                            $('#wpTextbox1').val($('#wpTextbox1').val().replace(regexp, '$1' + toWord + '$3'));
	                            $('#wpTextbox1').val($('#wpTextbox1').val().replace(toWord1, toWord2));
	                        } else {
	                            if (toWord !== word) {
	                                if (type.autofix == 'D') {
	                                    regexp = new RegExp('(\\[\\[) \*(' + word + ') \*(\\]\\]|\\|)', 'g')
	                                }
	                                replacements.push([regexp, '$1' + toWord + '$3', word + '⟸' + toWord]);
	                            }
	                            if (toWord1 !== toWord2) {
	                                replacements.push([toWord1, toWord2, toWord1 + '⟸' + toWord2]);
	                            }
	                            $('#CheckDictation-apply').show();
	                        }
	                    }, function() {
	                        if (/[كڪﻙﻚيىےۍېہەھﭖﭗﭘﭙﭺﭻﭼﭽﮊﮋﮎﮏﮐﮑﻙﻚﻛﻜﮒﮓﮔﮕﮤﮥﯼﯽﯾﯿﻯﻰﻱﻲﻳﻴﺁﺂﺄﺃﺅﺆﺇﺈﺉﺊﺋﺌﺎﺏﺐﺑﺒﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻫﻭﻮﻰﻲﻶﻸﻺﻼ]/.exec(word)) {
	                            alert('لغت پیشنهادی نویسهٔ غیرفارسی یا نویسهٔ نادرست دارد. قبل از گزارش لغت، لطفاً ابرابزار را در صفحه برانید!');
	                            return;
	                        }
	                        if (/((.*\u200c)$|^(\u200c.*))/.exec(word)) {
	                            alert('در انتها یا ابتدای لغت پیشنهادی نویسهٔ فاصلهٔ مجازی اضافی وجود دارد. لطفاً آن را به کمک ابزار جایگزینی یا ابرابزار حذف کنید');
	                            return;
	                        }
	                        $('CheckDictation-marked-' + word.replace(/ /g, '_')).css('background-color', '');
	                        element.css('background-color', '').css('color', 'grey').off();
	                        loadPage('اسلامیکال:اشتباه‌یاب/فهرست موارد درست').then(function(text) {
	                            if ((text + '\n').indexOf('* ' + (cleanedWord || word) + '\n') !== -1) {
	                                return;
	                            }
	                            return savePage('اسلامیکال:اشتباه‌یاب/فهرست موارد درست', text + '\n* ' + (cleanedWord || word), 'افزودن لغت درست و پرکاربرد «' + (cleanedWord || word) + '» به فهرست کلمات [[وپ:اشتباه|اشتباه‌یاب]]. موجود در مقالهٔ [[' + mw.config.get('wgPageName') + ']]');
	                        }).then(function() {
	                            mw.notify('کلمهٔ «' + word + '» به فهرست کلمات درست و پرکاربرد افزوده شد.');
	                        });
	                        $.get('').then(function() {}, function() {});
	                    });
	                });
	            });
	            markedItems.push(element[0]);
	
	        });
	
	        $('#spellmarkedwords').append(markedItems);
	
	        // reset page location to intended hash linked place
	        var hash = location.hash;
	        if (hash) {
	            location.hash = '';
	            location.hash = hash;
	        }
	
	        $('<button>', {
	            text: 'جایگزینی مواردی که انتخاب کردید!',
	            style: 'margin-right: 2em',
	            id: 'CheckDictation-apply'
	        }).click(function() {
	            $(this).prop('disabled', 'disabled').text('در حال دریافت و جایگزینی صفحه...');
	            loadPage(mw.config.get('wgPageName')).then(function(text) {
	                replacements.forEach(function(x) {
	                    text = text.replace(x[0], x[1]);
	                    //solving bug: [[Special:Permalink/24532423#اشتباه‌یاب، ایجاد پیوند درونی با دو آرگومان.مان]]
	                    if (x[1].indexOf("|")!==-1){
	                        var wrong_replacment=x[1].split('|')[1].replace(/\[/g, '').replace(/\$[13]/g, '');
	                        text = text.replace('|'+wrong_replacment+'|', '|');
	                    }
	                });
	                return savePage(
	                    mw.config.get('wgPageName'),
	                    text,
	                    'جایگزینی با [[وپ:اشتباه|اشتباه‌یاب]]: ' + replacements.map(function(x) {
	                        return x[2];
	                    }).join('، ')
	                );
	            }).then(function() {
	                mw.notify('انجام شد، لطفاً بررسی کنید');
	                location.href = mw.util.getUrl(mw.config.get('wgPageName'), {
	                    diff: 'last'
	                });
	            });
	        }).hide().appendTo('#spellmarkedwords');
	    },
	    // if the AJAX call to the webservice failed, show a nice notification to the user
	    function(){
	    	siteSub.append(' ', $('<span>', {
                'class': 'CheckDictation-exceptions-label'
            }).append(
                'اشتباه‌یاب: خدمات‌دهنده در دسترس نیست؛ لطفاً در صورت استمرار این مشکل، در وپ:فنی گزارش دهید. '
            ));
	    }
    );
    // ویرایش بعد از ذخیره برای رفع تداخل با ویرایشگر دیداری
    //در صورتی که ویرایشگر دیداری برای کاربر فعال باشد
    // در مقاله برچسب نادرست توسط ابزار قرار گرفته باشد
    mw.hook('ve.saveDialog.stateChanged').add(function() {
        mw.hook('ve.deactivationComplete').add(function() {
            loadPage(mw.config.get('wgPageName')).then(function(text) {
                    return savePage(
                        mw.config.get('wgPageName'),
                        text = postEdit(text),
                        'ویرایش خودکار: اصلاح برچسب‌های نادرست ([[اسلامیکال:اشتباه‌یاب|اشتباه‌یاب]])'
                    );
            });
        });
    });
});
//</nowiki>