MediaWiki:CommentPreview/code.js

//preview button for article comments //todo: monobook? (function ($) {   var skeen = ['', 'oasis', 'monobook'].indexOf(skin);//1:oasis; 2:stereobook;    if (skeen < 1) return;//oasis&quadrobook only    var cp = {};//me    //create settings    window.fng = $.extend(true, {}, window.fng, {cp:cp});    cp = window.fng.cp;    //error on custom cp.lang with en=nil is intended by design    cp = $.extend(true, {}, cp, {lang: { en: {preview: 'Preview', cancel: 'Cancel', publish: 'Publish'}, ru: {preview: 'Предпросмотр', cancel: 'Отмена', publish: 'Сохранить'}, be: {preview: 'Перадпрагляд', cancel: 'Скасаванне', publish: 'Захаваць'}, uk: {preview: 'Попередній перегляд', cancel: 'Скасування', publish: 'Зберегти'}, }});//not just $.extend(true, cp, ...). because of reasons.   var urlVars = $.getUrlVars;    cp.debug = cp.debug || urlVars.debug;

cp.rte2wiki = function (content) { //extract wikitext from rte-content var c = $(' ', {html: content}); c.find('[data-rte-meta]').replaceWith(function {            var $this = $(this);            var jstring = decodeURIComponent($(' ', {html: $this.data('rteMeta')}).text);            var jo = JSON.parse(jstring);            return jo.wikitext ? jo.wikitext : this;        });//replacewith return c.html; };//rte2wiki cp.getContent = function { //get *book content if (cp.debug) console.log('cp.getcontent', this); return this.val; };//getcontent cp.onPreview = function (e) { //btnpreview click e.preventDefault; var MEW = $(e.target).closest('.article-comm-form');//('.MiniEditorWrapper'); if (!MEW) { if (cp.debug) console.log('cp.onpreview mew not found for', e); return; }       var editor = MEW.find('.editarea textarea:first').data('wikiaEditor'); if (!editor) { if (cp.debug) console.log('cp.onpreview editor not found for', e); //monobook presumed is           //wikiaeditor emulation mode on            editor = MEW.find('.article-comm-input-text textarea:first'); editor.element = MEW; editor.mode = 'source'; editor.getContent = cp.getContent; //editor = {element: MEW, src: MEW.find('.editarea textarea:first'), mode: 'source', getContent: cp.getContent}; //return; }       cp.e = e;        cp.editor = editor; cp.throbber = MEW.find('.buttons .throbber:first'); cp.throb(true); var content = editor.getContent; //nothing to parse if (!content || content.length < 1) { cp.throb(false); cp.onCancel; return;//cp.showPreview(''); }       if (editor.mode === 'wysiwyg') { if (cp.debug) console.log('cp.onpreview wysiwyg'); content = cp.rte2wiki(content); }//if wysiwyg var apiUri = (new mw.Uri({path: '/index.php'}).extend({action: 'ajax', rs: 'EditPageLayoutAjax', title: wgTitle, page: 'SpecialCustomEditPage', method: 'preview', content: content})); if (cp.debug) console.log('cp.onpreview api', apiUri); $.getJSON(apiUri) .done(function (data) {           if (cp.debug) console.log('cp.onpreview getjson.done', data);            cp.showPreview(data.html);        })//getjson.done .fail(function (data) {           if (cp.debug) console.log('cp.onpreview getjson.fail', data);            cp.showPreview('Can\'t parse data. ' + data.responseText);       });//getjson.fail };//onpreview cp.onCancel = function (e) { //btncancel click. also, generic remove preview if (cp.debug) console.log('cp.oncancel', e); //fire trigger to detach attached to previewed content stuff $(window).trigger('EditPagePreviewClosed'); $('.cp-modal').remove; cp.editor = null; cp.e = null; $(document).off('keydown', cp.onkeydown); };//oncancel cp.onPublish = function (e) { //btnpublish click e.stopPropagation; if (cp.debug) console.log('cp.onpublish', e); cp.editor.element.find('input[name=wpArticleSubmit]').click; cp.onCancel; };//onpublish cp.throb = function (state) { if (cp.throbber && cp.throbber.length) cp.throbber.css('visibility', state ? 'visible' : 'hidden'); };//throb cp.onkeydown = function (e) { //keydown handler. and mouse if ($(e.target).closest('.cp-window').length) return; if (e.keyCode === 27 || e.button !== undefined) cp.onCancel; };//onkeydown cp.disablePreview = function (target) { //disable preview button if (!target) return; if (!(target instanceof jQuery)) target = $(target); var btnpreview = target.closest('.article-comments').find('.buttons .cp-button-preview'); if (!btnpreview.length) return; btnpreview.attr('disabled', 'disabled'); };//disablepreview cp.enablePreview = function (target) { //enable preview button if (!target) return; if (!(target instanceof jQuery)) target = $(target); var btnpreview = target.closest('.article-comments').find('.buttons .cp-button-preview'); if (!btnpreview.length) return; btnpreview.removeAttr('disabled'); };//enablepreview cp.addButtons = function (content) { if (cp.debug) console.log('cp.addbuttons', content); if (!(content instanceof jQuery)) content = $(content); //is it comments //if (content.selector !== '#article-comments') return; //var comments = content;//monobook //if (!comments.length) return; var buttons = content.find('>:not(#article-comments-ul) .buttons');//comments.find('.buttons');//monobook if (!buttons.length) return; buttons.find('.cp-button').remove; buttons.append(cp.btnPreview.clone); };//addbuttons cp.mo = new MutationObserver(function(records, obj){       //mutation observer callback        //if (cp.debug) console.log('cp.mo', obj, records);        $.each(records, function{ if (!this.addedNodes) return true; var arr = [].slice.call(this.addedNodes); //if (cp.debug) console.log('cp.mo.arr', arr); arr.map(function(v){               var $this = $(v);                if (cp.debug) console.log('cp.mo.map', $this);                if ($this.hasClass('article-comments') || $this.hasClass('article-comm-edit-box')) {                    //if (cp.debug) console.log('cp.mo.map addbuttons to', $this);                    cp.addButtons($this);                    //return false;                }//if article-comments            });//map });//each record   });//mutation observer cp.init = function { if (cp.debug) console.log('cp. init');

if (cp.clang) { if (cp.debug) console.log('cp.init 2nd init detected'); return; }       //is there smth to do        if (!$('#WikiaArticleComments').length) { if (cp.debug) console.log('cp.init no comments found'); return; }       //build gui //current lang cp.clang = cp.lang[urlVars.uselang || cp.uselang] || cp.lang[wgContentLanguage] || cp.lang.en; cp.btnPreviewText = cp.clang.preview || (cp.lang[wgContentLanguage] || cp.lang.en).preview; cp.btnCancelText = cp.clang.cancel || (cp.lang[wgContentLanguage] || cp.lang.en).cancel; cp.btnPublishText = cp.clang.publish || (cp.lang[wgContentLanguage] || cp.lang.en).publish; cp.modal = $(' ', {           class: 'cp-modal'            ,style: 'z-index:10000;position:absolute;left:0;top:0;width:100%;height:100%;background-color:rgba(0,0,0,0.8);overflow:visible;'        }); cp.window = $(' ', {           class: 'cp-window WikiaArticle'            ,style: 'z-index:1000;position:absolute;width:700px;height:400px;background-color:rgba(200,200,200,0.3);overflow:visible;padding:5px 20px;'        }); cp.content = $(' ', {           class: 'cp-content'            //,id: 'mw-content-text'            ,style: 'overflow:auto;margin:5px;border-style:groove;border-width:thin;border-color:silver;height:300px;max-height:350px;'        }); cp.footer = $(' ', {           class: 'cp-footer'            ,style: 'position:absolute;right:0;bottom:0;padding:20px;'        }); cp.btnPreview = $(' ', {           class: 'cp-button cp-button-preview wikia-button secondary',            type: 'button',            value: cp.btnPreviewText            ,style: 'float:right;'        }); cp.btnCancel = $(' ', {           class: 'cp-button cp-button-cancel wikia-button secondary',            type: 'button',            value: cp.btnCancelText            ,style: 'float:right;margin-right:7px;'        }); cp.btnPublish = $(' ', {           class: 'cp-button cp-button-publish wikia-button',            type: 'button',            value: cp.btnPublishText            ,style: 'float:right;margin-right:7px;'        });

cp.footer.append(cp.btnPublish).append(cp.btnCancel); cp.window.append($(' ', {text: cp.btnPreviewText})) .append(cp.content) .append(cp.footer); cp.modal.append(cp.window); //events $('body').on('click', '.cp-button-preview', cp.onPreview); $('body').on('click', '.cp-button-cancel', cp.onCancel); $('body').on('click', '.cp-button-publish', cp.onPublish); $('body').on('click', '.cp-modal', cp.onkeydown); //add hook var hcb = function(content) { //add preview button to new-article-comment if (!$(content).hasClass('article-comments')) return; mw.hook('wikipage.content').remove(hcb); cp.addButtons(content); //set observer to add buttons to all mew's           if (content instanceof jQuery) content = content.get(0); if (cp.debug) console.log('cp.init.wikipage.content', content); cp.mo.observe(content, {childList: true, subtree: true}); };//hcb

mw.hook('wikipage.content').add(hcb); $.extend(window.fng.cp, cp); };//init cp.showPreview = function (content) { if (cp.debug) { console.log('cp.showpreview content:', content); }       cp.modal.find('.cp-content').html(content); cp.throb(false); cp.throbber = null; //prepend to "fix" gallery-slider searching for id       //causes bunches of timer-related errors from original slider (in the comment) // til preview is alive. it's fine. sort of       $('body').prepend(cp.modal); cp.modal.find('.cp-window').css({           left: (window.innerWidth > cp.window.width ? window.innerWidth / 2 - cp.window.width / 2 : 0) + $('body').scrollLeft,           top: (window.innerHeight > cp.window.height ? window.innerHeight / 2 - cp.window.height / 2 : 50) + (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop)       }); //enlarge modal: *book fix if (cp.modal.height < $('body').height) cp.modal.height($('body').height); if (cp.modal.width < $('body').width) cp.modal.width($('body').width); $(document).on('keydown', cp.onkeydown);//doc.keydown mw.hook('wikipage.content').fire(cp.modal); };//showPreview //doc.rdy $(cp.init); }(jQuery));