From a2b6b9ab699cfe0614051a73ea446ca5ff88e290 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Niklas=20Laxstr=C3=B6m?= Date: Fri, 9 Feb 2007 20:34:57 +0000 Subject: [PATCH] * Some enhancements to live preview --- includes/DefaultSettings.php | 2 +- includes/EditPage.php | 16 +++--- includes/Skin.php | 8 +++ languages/messages/MessagesEn.php | 15 ++++-- maintenance/language/messages.inc | 6 +++ skins/common/preview.js | 87 +++++++++++++++++++++++++++---- 6 files changed, 113 insertions(+), 21 deletions(-) diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index df57c77014..40e09f8e90 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -1110,7 +1110,7 @@ $wgCacheEpoch = '20030516000000'; * to ensure that client-side caches don't keep obsolete copies of global * styles. */ -$wgStyleVersion = '55'; +$wgStyleVersion = '56'; # Server-side caching: diff --git a/includes/EditPage.php b/includes/EditPage.php index 84ee98b57d..b49e3a5d74 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -1765,8 +1765,8 @@ END * failure, etc). * * @todo This doesn't include category or interlanguage links. - * Would need to enhance it a bit, maybe wrap them in XML - * or something... that might also require more skin + * Would need to enhance it a bit, maybe wrap them in XML + * or something... that might also require more skin * initialization, so check whether that's a problem. */ function livePreview() { @@ -1774,10 +1774,14 @@ END $wgOut->disable(); header( 'Content-type: text/xml' ); header( 'Cache-control: no-cache' ); - # FIXME - echo $this->getPreviewText( ); - /* To not shake screen up and down between preview and live-preview */ - echo "
\n"; + + $s = + '' . "\n" . + Xml::openElement( 'livepreview' ) . + Xml::element( 'preview', null, $this->getPreviewText() ) . + Xml::element( 'br', array( 'style' => 'clear: both;' ) ) . + Xml::closeElement( 'livepreview' ); + echo $s; } diff --git a/includes/Skin.php b/includes/Skin.php index 09099e8b67..b91c23f950 100644 --- a/includes/Skin.php +++ b/includes/Skin.php @@ -320,6 +320,14 @@ class Skin extends Linker { 'wgCurRevisionId' => isset( $wgArticle ) ? $wgArticle->getLatest() : 0, ); + global $wgLivePreview; + if ( $wgLivePreview && $wgUser->getOption( 'uselivepreview' ) ) { + $vars['wgLivepreviewMessageLoading'] = wfMsg( 'livepreview-loading' ); + $vars['wgLivepreviewMessageReady'] = wfMsg( 'livepreview-ready' ); + $vars['wgLivepreviewMessageFailed'] = wfMsg( 'livepreview-failed' ); + $vars['wgLivepreviewMessageError'] = wfMsg( 'livepreview-error' ); + } + return self::makeVariablesScript( $vars ); } diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index a2e13e364b..17e9888c00 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -589,7 +589,7 @@ parent class in order maintain consistency across languages. 'help' => 'Help', 'helppage' => 'Help:Contents', 'bugreports' => 'Bug reports', -'bugreportspage' => 'Project:Bug_reports', +'bugreportspage' => 'Project:Bug reports', 'sitesupport' => 'Donations', 'sitesupport-url' => 'Project:Site support', 'faq' => 'FAQ', @@ -618,9 +618,9 @@ parent class in order maintain consistency across languages. 'currentevents-url' => 'Current events', 'disclaimers' => 'Disclaimers', -'disclaimerpage' => 'Project:General_disclaimer', +'disclaimerpage' => 'Project:General disclaimer', 'privacy' => 'Privacy policy', -'privacypage' => 'Project:Privacy_policy', +'privacypage' => 'Project:Privacy policy', 'errorpagetitle' => 'Error', 'returnto' => 'Return to $1.', 'tagline' => 'From {{SITENAME}}', @@ -1063,10 +1063,9 @@ Please check the URL you used to access this page.", 'currentrevisionlink' => 'Current revision', 'cur' => 'cur', 'next' => 'next', +'first' => 'first', 'last' => 'last', 'orig' => 'orig', -'page_first' => 'first', -'page_last' => 'last', 'histlegend' => 'Diff selection: mark the radio boxes of the versions to compare and hit enter or the button at the bottom.
Legend: (cur) = difference with current version, (last) = difference with preceding version, M = minor edit.', @@ -2782,6 +2781,12 @@ Please confirm that really want to recreate this page.', 'size-megabytes' => '$1 MB', 'size-gigabytes' => '$1 GB', +# Live preview +'livepreview-loading' => 'Loading…', +'livepreview-ready' => 'Loading… Ready!', +'livepreview-failed' => "Live preview failed!\nTry normal preview.", +'livepreview-error' => "Failed to connect: $1 \"$2\"\nTry normal preview.", + ); ?> diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc index a53e324244..cb9af8573c 100644 --- a/maintenance/language/messages.inc +++ b/maintenance/language/messages.inc @@ -2007,6 +2007,12 @@ $wgMessageStructure = array( 'size-megabytes', 'size-gigabytes', ), + 'livepreview' => array( + 'livepreview-loading', + 'livepreview-ready', + 'livepreview-failed', + 'livepreview-error', + ), ); /** Comments for each block */ $wgBlockComments = array( diff --git a/skins/common/preview.js b/skins/common/preview.js index aaa57bc30e..ec6129637d 100644 --- a/skins/common/preview.js +++ b/skins/common/preview.js @@ -18,9 +18,8 @@ function openXMLHttpRequest() { function livePreview(target, text, postUrl) { prevTarget = target; if( !target ) { - window.alert('Live preview failed!\nTry normal preview.'); - var fallback = document.getElementById('wpPreview'); - if ( fallback ) { fallback.style.display = 'inline'; } + window.alert(i18n(wgLivepreviewMessageFailed)); + showFallback(); } prevReq = openXMLHttpRequest(); if( !prevReq ) return false; @@ -35,19 +34,89 @@ function livePreview(target, text, postUrl) { } function updatePreviewText() { - if( prevReq.readyState != 4 ) { + + if (prevReq.readyState > 0 && prevReq.readyState < 4) { + notify(i18n(wgLivepreviewMessageLoading)); + } + + if(prevReq.readyState != 4) { return; } + + dismissNotify(i18n(wgLivepreviewMessageReady), 750); + if( prevReq.status != 200 ) { - window.alert('Failed to connect: ' + prevReq.status + - ' "' + prevReq.statusText + '"'); - var fallback = document.getElementById('wpPreview'); - if ( fallback ) { fallback.style.display = 'inline'; } + var keys = new Array(); + keys[0] = prevReq.status; + keys[1] = prevReq.statusText; + window.alert(i18n(wgLivepreviewMessageError, keys)); + showFallback(); return; } - prevTarget.innerHTML = prevReq.responseText; + + var xmlObject = prevReq.responseXML.documentElement; + var previewElement = xmlObject.getElementsByTagName('preview')[0]; + prevTarget.innerHTML = previewElement.firstChild.data; /* Hide the active diff if it exists */ var diff = document.getElementById('wikiDiff'); if ( diff ) { diff.style.display = 'none'; } } + +function showFallback() { + 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 + */ +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); +} + + + +/* Helper function similar to wfMsgReplaceArgs() */ +function i18n(message, keys) { + var localMessage = message; + if ( !keys ) { return localMessage; } + for( var i = 0; i < keys.length; i++) { + var myregexp = new RegExp("\\$"+(i+1), 'g'); + localMessage = localMessage.replace(myregexp, keys[i]); + } + return localMessage; +} \ No newline at end of file -- 2.20.1