r55239 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r55238‎ | r55239 | r55240 >
Date:17:27, 18 August 2009
Author:werdna
Status:ok (Comments)
Tags:todo 
Comment:
Rewrite JS-based Live Preview to use jQuery, was 200 lines, now less than 35. TODO: LiquidThreads support, some sort of progress indicator.
Modified paths:
  • /trunk/phase3/includes/EditPage.php (modified) (history)
  • /trunk/phase3/skins/common/preview.js (modified) (history)

Diff [purge]

Index: trunk/phase3/skins/common/preview.js
@@ -1,175 +1,40 @@
22 /**
33 * Live preview script for MediaWiki
4 - *
5 - * 2007-04-25 – Nikerabbit:
6 - * Worked around text cutoff in mozilla-based browsers
7 - * Support for categories
84 */
95
10 -
11 -lpIdPreview = 'wikiPreview';
12 -lpIdCategories = 'catlinks';
13 -lpIdDiff = 'wikiDiff';
14 -
15 -/*
16 - * Returns XMLHttpRequest based on browser support or null
17 - */
18 -function openXMLHttpRequest() {
19 - if( window.XMLHttpRequest ) {
20 - return new XMLHttpRequest();
21 - } else if( window.ActiveXObject && navigator.platform != 'MacPPC' ) {
22 - // IE/Mac has an ActiveXObject but it doesn't work.
23 - return new ActiveXObject("Microsoft.XMLHTTP");
24 - } else {
25 - return null;
26 - }
 6+function setupLivePreview() {
 7+ var livePreviewButton = $j('#wpLivePreview');
 8+
 9+ livePreviewButton.click( doLivePreview );
2710 }
2811
29 -/**
30 - * Returns true if could open the request,
31 - * false otherwise (eg no browser support).
32 - */
33 -function lpDoPreview(text, postUrl) {
34 - lpRequest = openXMLHttpRequest();
35 - if( !lpRequest ) return false;
36 -
37 - lpRequest.onreadystatechange = lpStatusUpdate;
38 - lpRequest.open("POST", postUrl, true);
39 -
40 - var postData = 'wpTextbox1=' + encodeURIComponent(text);
41 - lpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
42 - lpRequest.send(postData);
43 - return true;
44 -}
45 -
46 -function lpStatusUpdate() {
47 -
48 - /* We are at some stage of loading */
49 - if (lpRequest.readyState > 0 && lpRequest.readyState < 4) {
50 - notify(i18n(wgLivepreviewMessageLoading));
51 - }
52 -
53 - /* Not loaded yet */
54 - if(lpRequest.readyState != 4) {
55 - return;
56 - }
57 -
58 - /* We got response, bug it not what we wanted */
59 - if( lpRequest.status != 200 ) {
60 - var keys = new Array();
61 - keys[0] = lpRequest.status;
62 - keys[1] = lpRequest.statusText;
63 - window.alert(i18n(wgLivepreviewMessageError, keys));
64 - lpShowNormalPreview();
65 - return;
66 - }
67 -
68 - /* All good */
69 - dismissNotify(i18n(wgLivepreviewMessageReady), 750);
70 -
 12+function doLivePreview( e ) {
 13+ e.preventDefault();
 14+ var previewText = $j('#wpTextbox1').val();
 15+ var postData = { 'action' : 'submit', 'wpTextbox1' : previewText, 'wpPreview' : true,
 16+ 'title' : wgPageName };
7117
72 - var XMLObject = lpRequest.responseXML.documentElement;
73 -
74 -
75 - /* Work around Firefox (Gecko?) limitation where it shows only the first 4096
76 - * bytes of data. Ref: http://www.thescripts.com/forum/thread482760.html
77 - */
78 - XMLObject.normalize();
79 -
80 - var previewElement = XMLObject.getElementsByTagName('preview')[0];
81 - var categoryElement = XMLObject.getElementsByTagName('category')[0];
82 -
83 - /* Hide the active diff if it exists */
84 - var diff = document.getElementById(lpIdDiff);
85 - if ( diff ) { diff.style.display = 'none'; }
86 -
87 - /* Inject preview */
88 - var previewContainer = document.getElementById( lpIdPreview );
89 - if ( previewContainer && previewElement ) {
90 - previewContainer.innerHTML = previewElement.firstChild.data;
91 - previewContainer.style.display = 'block';
92 - } else {
93 - /* Should never happen */
94 - window.alert(i18n(wgLivepreviewMessageFailed));
95 - lpShowNormalPreview();
96 - return;
97 - }
98 -
99 -
100 - /* Inject categories */
101 - var categoryContainer = document.getElementById( lpIdCategories );
102 - if ( categoryElement && categoryElement.firstChild ) {
103 - if ( categoryContainer ) {
104 - categoryContainer.innerHTML = categoryElement.firstChild.data;
105 - /* May be hidden */
106 - categoryContainer.style.display = 'block';
107 - } else {
108 - /* Just dump them somewhere */
109 - /* previewContainer.innerHTML += categoryElement.firstChild.data;*/
110 - }
111 - } else {
112 - /* Nothing to show, hide old data */
113 - if ( categoryContainer ) {
114 - categoryContainer.style.display = 'none';
115 - }
116 - }
117 -
 18+ // Hide active diff, used templates, old preview if shown
 19+ $j('#wikiDiff').slideUp();
 20+ $j('#wikiPreview').slideUp();
 21+ $j('.templatesUsed').slideUp();
 22+ $j('.hiddencats').slideUp();
 23+
 24+ var page = $j('<html/>');
 25+ page.load( wgScript+'?action=submit',
 26+ postData,
 27+ function() {
 28+ var copyElements = ['#wikiPreview', '.templatesUsed', '.hiddencats'];
 29+
 30+ for( var i=0; i<copyElements.length; ++i) {
 31+ // For all the specified elements, find the elements in the loaded page
 32+ // and the real page, empty the element in the real page, and fill it
 33+ // with the content of the loaded page
 34+ var copyContent = page.find( copyElements[i] ).contents();
 35+ $j(copyElements[i]).empty().append( copyContent );
 36+ }
 37+ $j('#wikiPreview').slideDown();
 38+ } );
11839 }
11940
120 -function lpShowNormalPreview() {
121 - var fallback = document.getElementById('wpPreview');
122 - if ( fallback ) { fallback.style.display = 'inline'; }
123 -}
124 -
125 -
126 -// TODO: move elsewhere
127 -/* Small non-intrusive popup which can be used for example to notify the user
128 - * about completed AJAX action. Supports only one notify at a time.
129 - */
130 -function notify(message) {
131 - var notifyElement = document.getElementById('mw-js-notify');
132 - if ( !notifyElement ) {
133 - createNotify();
134 - var notifyElement = document.getElementById('mw-js-notify');
135 - }
136 - notifyElement.style.display = 'block';
137 - notifyElement.innerHTML = message;
138 -}
139 -
140 -function dismissNotify(message, timeout) {
141 - var notifyElement = document.getElementById('mw-js-notify');
142 - if ( notifyElement ) {
143 - if ( timeout == 0 ) {
144 - notifyElement.style.display = 'none';
145 - } else {
146 - notify(message);
147 - setTimeout("dismissNotify('', 0)", timeout);
148 - }
149 - }
150 -}
151 -
152 -function createNotify() {
153 - var div = document.createElement("div");
154 - var txt = '###PLACEHOLDER###'
155 - var txtNode = document.createTextNode(txt);
156 - div.appendChild(txtNode);
157 - div.id = 'mw-js-notify';
158 - // TODO: move styles to css
159 - div.setAttribute('style',
160 - '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%;');
161 - var body = document.getElementsByTagName('body')[0];
162 - body.appendChild(div);
163 -}
164 -
165 -
166 -
167 -/* Helper function similar to wfMsgReplaceArgs() */
168 -function i18n(message, keys) {
169 - var localMessage = message;
170 - if ( !keys ) { return localMessage; }
171 - for( var i = 0; i < keys.length; i++) {
172 - var myregexp = new RegExp("\\$"+(i+1), 'g');
173 - localMessage = localMessage.replace(myregexp, keys[i]);
174 - }
175 - return localMessage;
176 -}
\ No newline at end of file
 41+js2AddOnloadHook( setupLivePreview );
Index: trunk/phase3/includes/EditPage.php
@@ -1706,14 +1706,7 @@
17071707 function doLivePreviewScript() {
17081708 global $wgOut, $wgTitle;
17091709 $wgOut->addScriptFile( 'preview.js' );
1710 - $liveAction = $wgTitle->getLocalUrl( array(
1711 - 'action' => $this->action,
1712 - 'wpPreview' => 'true',
1713 - 'live' => 'true'
1714 - ) );
1715 - return "return !lpDoPreview(" .
1716 - "editform.wpTextbox1.value," .
1717 - '"' . $liveAction . '"' . ")";
 1710+ return "";
17181711 }
17191712
17201713 protected function showTosSummary() {
@@ -2271,6 +2264,8 @@
22722265
22732266 ++$tabindex; // use the same for preview and live preview
22742267 if ( $wgLivePreview && $wgUser->getOption( 'uselivepreview' ) ) {
 2268+ $this->doLivePreviewScript(); // Add to output
 2269+
22752270 $temp = array(
22762271 'id' => 'wpPreview',
22772272 'name' => 'wpPreview',
@@ -2291,8 +2286,8 @@
22922287 'value' => wfMsg('showlivepreview'),
22932288 'accesskey' => wfMsg('accesskey-preview'),
22942289 'title' => '',
2295 - 'onclick' => $this->doLivePreviewScript(),
22962290 );
 2291+
22972292 $buttons['live'] = Xml::element('input', $temp, '');
22982293 } else {
22992294 $temp = array(

Follow-up revisions

RevisionCommit summaryAuthorDate
r55315Add doc comment for JS2 dependency in live preview enhancements from r55239werdna11:06, 19 August 2009

Comments

#Comment by Brion VIBBER (talk | contribs)   20:59, 18 August 2009

Doesn't seem to be working; I get a form submission when I click the 'live preview' button. If this is dependent on JS2 being enabled, then we need some better checks for the dependencies...

#Comment by Siebrand (talk | contribs)   21:17, 22 August 2009

This is broken on translatewiki.net with JS2 enabled. Possibly has something to do with Extension:Google AdSense 2 and its iframe (see r55273).

#Comment by Werdna (talk | contribs)   16:50, 27 August 2009

Changing to TODO, sucks but doesn't block deployment.

Status & tagging log