From f9a3ab439cf012e27362ed925a57d191b88917e7 Mon Sep 17 00:00:00 2001 From: Andrew Garrett Date: Tue, 18 Aug 2009 17:27:19 +0000 Subject: [PATCH] Rewrite JS-based Live Preview to use jQuery, was 200 lines, now less than 35. TODO: LiquidThreads support, some sort of progress indicator. --- includes/EditPage.php | 13 +-- skins/common/preview.js | 197 +++++++--------------------------------- 2 files changed, 35 insertions(+), 175 deletions(-) diff --git a/includes/EditPage.php b/includes/EditPage.php index 5a4031b02e..23eb60085f 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -1706,14 +1706,7 @@ END function doLivePreviewScript() { global $wgOut, $wgTitle; $wgOut->addScriptFile( 'preview.js' ); - $liveAction = $wgTitle->getLocalUrl( array( - 'action' => $this->action, - 'wpPreview' => 'true', - 'live' => 'true' - ) ); - return "return !lpDoPreview(" . - "editform.wpTextbox1.value," . - '"' . $liveAction . '"' . ")"; + return ""; } protected function showTosSummary() { @@ -2271,6 +2264,8 @@ END ++$tabindex; // use the same for preview and live preview if ( $wgLivePreview && $wgUser->getOption( 'uselivepreview' ) ) { + $this->doLivePreviewScript(); // Add to output + $temp = array( 'id' => 'wpPreview', 'name' => 'wpPreview', @@ -2291,8 +2286,8 @@ END 'value' => wfMsg('showlivepreview'), 'accesskey' => wfMsg('accesskey-preview'), 'title' => '', - 'onclick' => $this->doLivePreviewScript(), ); + $buttons['live'] = Xml::element('input', $temp, ''); } else { $temp = array( diff --git a/skins/common/preview.js b/skins/common/preview.js index faf611f071..724e992ae9 100644 --- a/skins/common/preview.js +++ b/skins/common/preview.js @@ -1,175 +1,40 @@ /** * Live preview script for MediaWiki - * - * 2007-04-25 – Nikerabbit: - * Worked around text cutoff in mozilla-based browsers - * Support for categories */ - -lpIdPreview = 'wikiPreview'; -lpIdCategories = 'catlinks'; -lpIdDiff = 'wikiDiff'; - -/* - * Returns XMLHttpRequest based on browser support or null - */ -function openXMLHttpRequest() { - if( window.XMLHttpRequest ) { - return new XMLHttpRequest(); - } else if( window.ActiveXObject && navigator.platform != 'MacPPC' ) { - // IE/Mac has an ActiveXObject but it doesn't work. - return new ActiveXObject("Microsoft.XMLHTTP"); - } else { - return null; - } -} - -/** - * Returns true if could open the request, - * false otherwise (eg no browser support). - */ -function lpDoPreview(text, postUrl) { - lpRequest = openXMLHttpRequest(); - if( !lpRequest ) return false; - - lpRequest.onreadystatechange = lpStatusUpdate; - lpRequest.open("POST", postUrl, true); - - var postData = 'wpTextbox1=' + encodeURIComponent(text); - lpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); - lpRequest.send(postData); - return true; -} - -function lpStatusUpdate() { - - /* We are at some stage of loading */ - if (lpRequest.readyState > 0 && lpRequest.readyState < 4) { - notify(i18n(wgLivepreviewMessageLoading)); - } - - /* Not loaded yet */ - if(lpRequest.readyState != 4) { - return; - } - - /* We got response, bug it not what we wanted */ - if( lpRequest.status != 200 ) { - var keys = new Array(); - keys[0] = lpRequest.status; - keys[1] = lpRequest.statusText; - window.alert(i18n(wgLivepreviewMessageError, keys)); - lpShowNormalPreview(); - return; - } - - /* All good */ - dismissNotify(i18n(wgLivepreviewMessageReady), 750); - +function setupLivePreview() { + var livePreviewButton = $j('#wpLivePreview'); - var XMLObject = lpRequest.responseXML.documentElement; - - - /* Work around Firefox (Gecko?) limitation where it shows only the first 4096 - * bytes of data. Ref: http://www.thescripts.com/forum/thread482760.html - */ - XMLObject.normalize(); - - var previewElement = XMLObject.getElementsByTagName('preview')[0]; - var categoryElement = XMLObject.getElementsByTagName('category')[0]; - - /* Hide the active diff if it exists */ - var diff = document.getElementById(lpIdDiff); - if ( diff ) { diff.style.display = 'none'; } - - /* Inject preview */ - var previewContainer = document.getElementById( lpIdPreview ); - if ( previewContainer && previewElement ) { - previewContainer.innerHTML = previewElement.firstChild.data; - previewContainer.style.display = 'block'; - } else { - /* Should never happen */ - window.alert(i18n(wgLivepreviewMessageFailed)); - lpShowNormalPreview(); - return; - } - - - /* Inject categories */ - var categoryContainer = document.getElementById( lpIdCategories ); - if ( categoryElement && categoryElement.firstChild ) { - if ( categoryContainer ) { - categoryContainer.innerHTML = categoryElement.firstChild.data; - /* May be hidden */ - categoryContainer.style.display = 'block'; - } else { - /* Just dump them somewhere */ - /* previewContainer.innerHTML += categoryElement.firstChild.data;*/ - } - } else { - /* Nothing to show, hide old data */ - if ( categoryContainer ) { - categoryContainer.style.display = 'none'; - } - } - + livePreviewButton.click( doLivePreview ); } -function lpShowNormalPreview() { - var fallback = document.getElementById('wpPreview'); - if ( fallback ) { fallback.style.display = 'inline'; } -} - - -// TODO: move elsewhere -/* Small non-intrusive popup which can be used for example to notify the user - * about completed AJAX action. Supports only one notify at a time. - */ -function notify(message) { - var notifyElement = document.getElementById('mw-js-notify'); - if ( !notifyElement ) { - createNotify(); - var notifyElement = document.getElementById('mw-js-notify'); - } - notifyElement.style.display = 'block'; - notifyElement.innerHTML = message; -} - -function dismissNotify(message, timeout) { - var notifyElement = document.getElementById('mw-js-notify'); - if ( notifyElement ) { - if ( timeout == 0 ) { - notifyElement.style.display = 'none'; - } else { - notify(message); - setTimeout("dismissNotify('', 0)", timeout); - } - } -} - -function createNotify() { - var div = document.createElement("div"); - var txt = '###PLACEHOLDER###' - var txtNode = document.createTextNode(txt); - div.appendChild(txtNode); - div.id = 'mw-js-notify'; - // TODO: move styles to css - div.setAttribute('style', - 'display: none; position: fixed; bottom: 0px; right: 0px; color: white; background-color: DarkRed; z-index: 5; padding: 0.1em 1em 0.1em 1em; font-size: 120%;'); - var body = document.getElementsByTagName('body')[0]; - body.appendChild(div); +function doLivePreview( e ) { + e.preventDefault(); + var previewText = $j('#wpTextbox1').val(); + var postData = { 'action' : 'submit', 'wpTextbox1' : previewText, 'wpPreview' : true, + 'title' : wgPageName }; + + // Hide active diff, used templates, old preview if shown + $j('#wikiDiff').slideUp(); + $j('#wikiPreview').slideUp(); + $j('.templatesUsed').slideUp(); + $j('.hiddencats').slideUp(); + + var page = $j(''); + page.load( wgScript+'?action=submit', + postData, + function() { + var copyElements = ['#wikiPreview', '.templatesUsed', '.hiddencats']; + + for( var i=0; i