MediaWiki:AjaxEdit.js

/** * @Name           AjaxEdit * @Version        v1.0 * @Author         TheGoldenPatrik1 * @Description    Edit without opening the editor. * @Protect */ require([   'wikia.window',    'jquery',    'mw',    'BannerNotification',    'wikia.browserDetect',    'ext.wikia.design-system.loading-spinner' ], function (window, $, mw, BannerNotification, browserDetect, Spinner) {    'use strict';    var config = mw.config.get([ 'wgAction', 'wgArticleId', 'wgCurRevisionId', 'wgPageName', 'wgScript', 'wgUserLanguage' ]);   if ( window.AjaxEditLoaded || !$('#ca-edit').exists || config.wgAction !== 'view' || config.wgArticleId === 0 || browserDetect.isMobile ) {       return;    }    var i18n;    var $button;    var $edit;    var $text;    var $minor;    var $summary;    var $spinner;    var $article = $('#mw-content-text');    var $rail = $('#WikiaRail');    var $wrapper = $('#WikiaMainContent');    var preloads = 3;    var options = $.extend( {           minor: mw.user.options.get('minordefault') === '1', reloadContent: false, restart: false, watchlist: 'preferences', hideRail: false, height: '500px', replaceGlobal: true, replaceCase: false, replaceRegex: false, summaries: false, summaryNotice: false, buttons: false },       window.AjaxEdit );   /**     * @class Main     * @description Central AjaxEdit class     */    var Main = {        /**         * @method publish         * @description Publishes the edit         */        publish: function  {            $spinner.show;            new mw.Api.post({ action: 'edit', title: config.wgPageName, summary: options.summaryNotice ? ('[AjaxEdit] ' + $summary.val).trim : $summary.val.trim, text: $text.val, minor: $minor.prop('checked') ? true : undefined, token: mw.user.tokens.get('editToken'), watchlist: options.watchlist })           .done( $.proxy(this.success, this) )           .fail( $.proxy(this.fail, this) );       },        /**         * @method success         * @description Outputs .done results         * @param {JSON} d - Data retured from .done         */        success: function (d) {            $spinner.hide;            if (d.error) {                this.notif( i18n.msg('errorKnown', d.error.code).escape, 'error' );           } else {                location.reload(true);            }        },        /**         * @method fail         * @description Outputs .fail results         */        fail: function  {            $spinner.hide;            this.notif( i18n.msg('errorUnknown').escape, 'error' );       },        /**         * @method back         * @description Returns to viewing the article         */        back: function  {            $edit.hide;            $article.show;            $button.show;            if (options.hideRail) {                $rail.show;                $wrapper.css( 'width', ($('.WikiaPageContentWrapper').width - 330) + 'px' );           }        },        /**         * @method restart         * @description Reverts all changes         */        restart: function  {            $text.val(this.content);            $summary.val('');            $minor.prop('checked', options.minor);        },        /**         * @method diff         * @description Gets the diff         */        diff: function  {            $spinner.show;            $.post( config.wgScript, {                   action: 'ajax', rs: 'EditPageLayoutAjax', title: config.wgPageName, method: 'diff', content: $text.val, page: 'SpecialCustomEditPage' },               $.proxy(this.loadDiff, this) );       },        /**         * @method loadDiff         * @description Outputs the diff in a modal         * @param {JSON} d - The diff data         */        loadDiff: function (d) {            var diffModalContent = $(' ', { 'class': 'ajax-edit__diff-modal', 'append': d.html }).prop('outerHTML');           if (this.diffModal) {                this.diffModal.setContent(diffModalContent).show;                $spinner.hide;                return;            }            this.diffModal = new this.modal({ content: diffModalContent, id: 'ajax-edit__diff', size: 'large', title: i18n.msg('diffButton').escape, buttons: [ {                       text: i18n.msg('publishButton').escape, primary: true, event: 'publish' },                   {                        text: i18n.msg('close').escape, event: 'close' }               ],                events: { publish: this.publish }           });            this.diffModal.create;            this.diffModal.show;            $spinner.hide;        },        /**         * @method preview         * @description Gets the preview data         */        preview: function  {            $spinner.show;            $.ajax({ type: 'POST', url: mw.util.wikiScript('index'), data: { action: 'ajax', rs: 'EditPageLayoutAjax', page: 'SpecialCustomEditPage', method: 'preview', content: $text.val }           }).done( $.proxy(this.loadPreview, this) );       },        /**         * @method loadPreview         * @description Outputs the preview in a modal         * @param {JSON} d - The preview data         */        loadPreview: function (d) {            var previewModalContent = $(' ', { 'class': 'ajax-edit__preview-modal', 'append': d.html }).prop('outerHTML');           if (this.previewModal) {                this.previewModal.setContent(previewModalContent).show;                $spinner.hide;                return;            }            this.previewModal = new this.modal({ content: previewModalContent, id: 'ajax-edit__preview', size: 'large', title: i18n.msg('previewButton').escape, buttons: [ {                       text: i18n.msg('publishButton').escape, primary: true, event: 'publish' },                   {                        text: i18n.msg('close').escape, event: 'close' }               ],                events: { publish: this.publish }           });            this.previewModal.create;            this.previewModal.show;            $spinner.hide;        },        /**         * @method replace         * @description Outputs the replace modal         */        replace: function  {            if (this.replaceModal) {                this.replaceModal.show;                return;            }            var replaceModalContent = $(' ', { 'class': 'ajax-edit__replace-modal' }).append( $(' ').append(                   i18n.msg('farFind').escape,                    $(' ', { 'rows': '4', 'wrap': 'off', 'id': 'ajax-edit__replace-find' })               ),                $(' ').append(                    i18n.msg('farReplace').escape,                    $(' ', { 'rows': '4', 'wrap': 'off', 'id': 'ajax-edit__replace-replace', })               ),                $(' ').append(                    i18n.msg('farRegex').escape,                    ''               ), $(' ').append(                   i18n.msg('farCase').escape,                    ''               ), $(' ').append(                   i18n.msg('farRegex').escape,                    ''               ) ).prop('outerHTML');           this.replaceModal = new this.modal({ content: replaceModalContent, id: 'ajax-edit__replace', size: 'medium', title: i18n.msg('replaceButton').escape, buttons: [ {                       text: i18n.msg('farExecute').escape, primary: true, event: 'execute' },                   {                        text: i18n.msg('close').escape, event: 'close' }               ],                events: { execute: this.loadReplace }           });            this.replaceModal.create;            this.replaceModal.show;        },        /**         * @method loadReplace         * @description Performs the replace action         */        loadReplace: function  {            var searchfor = ,                searchexp,                $find = $('#ajax-edit__replace-find').val,                replacewith = $('#ajax-edit__replace-replace').val.replace(/\r/gi, ),                text = $text.val.replace(/\r/gi, ),                flagg = 'g',                flagi = 'i',                enableregex = false;            if ($('#ajax-edit__replace-global').prop('checked') === false) {                flagg = ;            }            if ($('#ajax-edit__replace-case').prop('checked') === true) {                flagi = '';            }            if ($('#ajax-edit__replace-regex').prop('checked') === true) { enableregex = true; }           var flags = flagg + flagi + 'm'; if (enableregex) { searchfor = $find; } else { searchfor = $find.replace(/\r/gi, '').replace(/([.*+?^=!:${}|\[\]\/\\])/g, '\\$1'); }           searchexp = new RegExp(searchfor, flags); var rcount = 0; var matched = text.match(searchexp); if (matched !== null) { rcount = matched.length; }           text = text.replace(searchexp, replacewith); $text.val(text); $('#ajax-edit__replace-tally').html(               ' ' + i18n.msg('farFound', rcount).escape            ); replaceModal.close; },       /**         * @method notif * @description Outputs a BannerNotification * @param {String} text - The notif text * @param {String} type - The notif type */       notif: function (text, type) { new BannerNotification(               text,                type            ).show; },       /**         * @method create * @description Creates the AjaxEdit interface */       create: function  { $('#WikiaArticle').prepend(               $(' ', { 'class': 'ajax-edit__edit' }).append( $(' ', {                       'id': 'ajax-edit__edit-publisharea'                    }).append(                        $(' ', { 'for': 'ajax-edit-minor', 'text': i18n.msg('minor').plain }),                       $(' ', {                            'type': 'checkbox', 'id': 'ajax-edit__edit-minor', 'name': 'ajax-edit-minor' }),                       $(' ', {                            'for': 'ajax-edit-summary', 'text': i18n.msg('summary').plain }),                       $(' ', {                            'type': 'text', 'id': 'ajax-edit__edit-summary', 'name': 'ajax-edit-summary' }),                       $(' '),                        this.button('back'),                        this.button('restart'),                        this.button('publish'),                        this.button('diff'),                        this.button('preview'),                        this.button('replace'),                        $(' ', { 'id': 'ajax-edit__replace-tally' })                   ),                    $(' ', {                        id: 'ajax-edit__edit-text',                        css: {                            height: options.height                        }                    }) )           );            if ($article.find('#mw-clearyourcache').length !== 0) { $('#ajax-edit__buttons-preview').remove; }           $edit = $('.ajax-edit__edit'); $text = $('#ajax-edit__edit-text'); $minor = $('#ajax-edit__edit-minor'); $summary = $('#ajax-edit__edit-summary'); $text.val(this.content); $minor.prop('checked', options.minor); if (options.summaries) { $summary.after(                   $(' ', { 'id': 'ajax-edit__edit-summaries', 'change': function { $summary.val(                               $(this).val                            ); }                   }).append( $(' ', {                           disabled: true,                            text: i18n.msg('summaries').plain                        }) )               );                $.each(options.summaries, function (k, v) {                    $('#ajax-edit__edit-summaries').append( $(' ', {                           'value': v,                            'text': k                        }) );               });            }            if (options.buttons) { if (options.buttons === 'defaults') { options.buttons = [ {                           label: i18n.msg('inputBold').plain, open: '\'\'\'', close: '\'\'\'' },                       {                            label: i18n.msg('inputItalics').plain, open: '\'\'', close: '\'\'' },                       {                            label: i18n.msg('inputLink').plain, open: ,                           close:  },                       {                            label: i18n.msg('inputHeader').plain, open: '== ', close: ' ==' },                       {                            label: i18n.msg('inputNowiki').plain, open: ' ', close: '' },                       {                            label: i18n.msg('inputSig').plain, middle: '~' },                   ];                }                $.each(options.buttons, function (k, v) {                    $('#ajax-edit__buttons-replace').after( $('', {                           'class': 'button',                            'click': function  {                                var textarea = document.getElementById('ajax-edit__edit-text');                                var start = textarea.selectionStart;                                var stop = textarea.selectionEnd;                                var selectedText = textarea.value.slice(start, stop);                                textarea.value =                                    textarea.value.slice(0, start) +                                    (v.open || ) +                                    (v.middle || selectedText) +                                    (v.close || ) +                                    textarea.value.slice(stop);                            },                            'text': v.label                        }) );               });                $('#ajax-edit__buttons-replace').after(' '); }           $spinner.hide; },       /**         * @method button * @description Creates a button * @param {String} name - The button name */       button: function (name) { return $('', {               'class': 'button',                'id': 'ajax-edit__buttons-' + name,                'click': $.proxy(this[name], this),                'text': i18n.msg(name + 'Button').plain,                'title': i18n.msg(name + 'Title').plain            }); },       /**         * @method loadData * @description Processes the data from the API */       loadData: function (d) { this.content = d;           this.create; },       /**         * @method click * @description Gets the content and loads the interface */       click: function  { if (this.content && !options.reloadContent) { $edit.show; if (options.restart) { $text.val(this.content); }           } else { $(' ', {                   id: 'ajax-edit__throbber',                    html: new Spinner(38, 2).html.replace('wds-block', 'wds-spinner__block').replace('wds-path', 'wds-spinner__stroke')                }).appendTo(document.body); $spinner = $('#ajax-edit__throbber'); if ($('#WikiaRail .content-review-module').length) { this.content = $article.find('pre').text; this.create; } else { $.get(                       mw.util.getUrl( config.wgPageName, {                               action: 'raw', maxage: '0', smaxage: '0', oldid: mw.util.getParamValue('diff') || mw.util.getParamValue('oldid') || config.wgCurRevisionId }                       )                    ).done(                        $.proxy(this.loadData, this)                    ); }           }            $article.hide; $button.hide; if (options.hideRail) { $rail.hide; $wrapper.css('width', '100%'); }       },        /**         * @method init * @description Initiates the script * @param {String} i18nData - Variable for I18n-js */       init: function (i18nData) { i18n = i18nData; $(               this.placement.element('editdropdown')            )[this.placement.type('append')](                $('',{ id: 'ca-ajax-edit' }).append( $('', {                       click: $.proxy(this.click, this),                        text: i18n.msg('buttonText').plain,                        title: i18n.msg('buttonTitle').plain                    }) )           );            $button = $('#ca-ajax-edit'); },       /**         * @method preload * @description Preloads the script */       preload: function  { if (--preloads === 0) { this.placement = window.dev.placement.loader; this.placement.script('AjaxEdit'); this.modal = window.dev.modal.Modal; window.dev.i18n.loadMessages('AjaxEdit').then(                   $.proxy(this.init, this)                ); }       },        /**         * @method hooks * @description Preloads the hooks and imports */       hooks: function  { mw.hook('dev.i18n').add(               $.proxy(this.preload, this)            ); mw.hook('dev.modal').add(               $.proxy(this.preload, this)            ); mw.hook('dev.placement').add(               $.proxy(this.preload, this)            ); importArticles(               {                    type: 'script',                    articles: [                        'u:dev:MediaWiki:I18n-js/code.js',                        'u:dev:MediaWiki:Modal.js',                        'u:dev:MediaWiki:Placement.js'                    ]                },                {                    type: 'style',                    articles: [                        'u:dev:MediaWiki:AjaxEdit.css'                    ]                }            ); }   };    mw.loader.using([        'mediawiki.api',        'mediawiki.util',        'mediawiki.user'    ]).then(        $.proxy(Main.hooks, Main)    ); });