preview.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /**
  2. * Live preview script for MediaWiki
  3. *
  4. * 2007-04-25 – Nikerabbit:
  5. * Worked around text cutoff in mozilla-based browsers
  6. * Support for categories
  7. */
  8. lpIdPreview = 'wikiPreview';
  9. lpIdCategories = 'catlinks';
  10. lpIdDiff = 'wikiDiff';
  11. /*
  12. * Returns XMLHttpRequest based on browser support or null
  13. */
  14. function openXMLHttpRequest() {
  15. if( window.XMLHttpRequest ) {
  16. return new XMLHttpRequest();
  17. } else if( window.ActiveXObject && navigator.platform != 'MacPPC' ) {
  18. // IE/Mac has an ActiveXObject but it doesn't work.
  19. return new ActiveXObject("Microsoft.XMLHTTP");
  20. } else {
  21. return null;
  22. }
  23. }
  24. /**
  25. * Returns true if could open the request,
  26. * false otherwise (eg no browser support).
  27. */
  28. function lpDoPreview(text, postUrl) {
  29. lpRequest = openXMLHttpRequest();
  30. if( !lpRequest ) return false;
  31. lpRequest.onreadystatechange = lpStatusUpdate;
  32. lpRequest.open("POST", postUrl, true);
  33. var postData = 'wpTextbox1=' + encodeURIComponent(text);
  34. lpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  35. lpRequest.send(postData);
  36. return true;
  37. }
  38. function lpStatusUpdate() {
  39. /* We are at some stage of loading */
  40. if (lpRequest.readyState > 0 && lpRequest.readyState < 4) {
  41. notify(i18n(wgLivepreviewMessageLoading));
  42. }
  43. /* Not loaded yet */
  44. if(lpRequest.readyState != 4) {
  45. return;
  46. }
  47. /* We got response, bug it not what we wanted */
  48. if( lpRequest.status != 200 ) {
  49. var keys = new Array();
  50. keys[0] = lpRequest.status;
  51. keys[1] = lpRequest.statusText;
  52. window.alert(i18n(wgLivepreviewMessageError, keys));
  53. lpShowNormalPreview();
  54. return;
  55. }
  56. /* All good */
  57. dismissNotify(i18n(wgLivepreviewMessageReady), 750);
  58. var XMLObject = lpRequest.responseXML.documentElement;
  59. /* Work around Firefox (Gecko?) limitation where it shows only the first 4096
  60. * bytes of data. Ref: http://www.thescripts.com/forum/thread482760.html
  61. */
  62. XMLObject.normalize();
  63. var previewElement = XMLObject.getElementsByTagName('preview')[0];
  64. var categoryElement = XMLObject.getElementsByTagName('category')[0];
  65. /* Hide the active diff if it exists */
  66. var diff = document.getElementById(lpIdDiff);
  67. if ( diff ) { diff.style.display = 'none'; }
  68. /* Inject preview */
  69. var previewContainer = document.getElementById( lpIdPreview );
  70. if ( previewContainer && previewElement ) {
  71. previewContainer.innerHTML = previewElement.firstChild.data;
  72. previewContainer.style.display = 'block';
  73. } else {
  74. /* Should never happen */
  75. window.alert(i18n(wgLivepreviewMessageFailed));
  76. lpShowNormalPreview();
  77. return;
  78. }
  79. /* Inject categories */
  80. var categoryContainer = document.getElementById( lpIdCategories );
  81. if ( categoryElement && categoryElement.firstChild ) {
  82. if ( categoryContainer ) {
  83. categoryContainer.innerHTML = categoryElement.firstChild.data;
  84. /* May be hidden */
  85. categoryContainer.style.display = 'block';
  86. } else {
  87. /* Just dump them somewhere */
  88. /* previewContainer.innerHTML += categoryElement.firstChild.data;*/
  89. }
  90. } else {
  91. /* Nothing to show, hide old data */
  92. if ( categoryContainer ) {
  93. categoryContainer.style.display = 'none';
  94. }
  95. }
  96. }
  97. function lpShowNormalPreview() {
  98. var fallback = document.getElementById('wpPreview');
  99. if ( fallback ) { fallback.style.display = 'inline'; }
  100. }
  101. // TODO: move elsewhere
  102. /* Small non-intrusive popup which can be used for example to notify the user
  103. * about completed AJAX action. Supports only one notify at a time.
  104. */
  105. function notify(message) {
  106. var notifyElement = document.getElementById('mw-js-notify');
  107. if ( !notifyElement ) {
  108. createNotify();
  109. var notifyElement = document.getElementById('mw-js-notify');
  110. }
  111. notifyElement.style.display = 'block';
  112. notifyElement.innerHTML = message;
  113. }
  114. function dismissNotify(message, timeout) {
  115. var notifyElement = document.getElementById('mw-js-notify');
  116. if ( notifyElement ) {
  117. if ( timeout == 0 ) {
  118. notifyElement.style.display = 'none';
  119. } else {
  120. notify(message);
  121. setTimeout("dismissNotify('', 0)", timeout);
  122. }
  123. }
  124. }
  125. function createNotify() {
  126. var div = document.createElement("div");
  127. var txt = '###PLACEHOLDER###'
  128. var txtNode = document.createTextNode(txt);
  129. div.appendChild(txtNode);
  130. div.id = 'mw-js-notify';
  131. // TODO: move styles to css
  132. div.setAttribute('style',
  133. '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%;');
  134. var body = document.getElementsByTagName('body')[0];
  135. body.appendChild(div);
  136. }
  137. /* Helper function similar to wfMsgReplaceArgs() */
  138. function i18n(message, keys) {
  139. var localMessage = message;
  140. if ( !keys ) { return localMessage; }
  141. for( var i = 0; i < keys.length; i++) {
  142. var myregexp = new RegExp("\\$"+(i+1), 'g');
  143. localMessage = localMessage.replace(myregexp, keys[i]);
  144. }
  145. return localMessage;
  146. }