drafts.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // The draft save object
  2. function smf_DraftAutoSave(oOptions)
  3. {
  4. this.opt = oOptions;
  5. this.bInDraftMode = false;
  6. this.sCurDraftId = '';
  7. this.oCurDraftDiv = null;
  8. this.interval_id = null;
  9. this.oDraftHandle = window;
  10. this.sLastSaved = '';
  11. this.bPM = this.opt.bPM ? true : false;
  12. this.sCheckDraft = '';
  13. // slight delay on autosave init to allow sceditor to create the iframe
  14. setTimeout('addLoadEvent(' + this.opt.sSelf + '.init())', 4000);
  15. }
  16. // Start our self calling routine
  17. smf_DraftAutoSave.prototype.init = function ()
  18. {
  19. if (this.opt.iFreq > 0)
  20. {
  21. // find the editors wysiwyg iframe and gets its window
  22. var oIframe = document.getElementsByTagName('iframe')[0];
  23. var oIframeWindow = oIframe.contentWindow || oIframe.contentDocument;
  24. // start the autosave timer
  25. this.interval_id = window.setInterval(this.opt.sSelf + '.draft' + (this.bPM ? 'PM' : '') + 'Save();', this.opt.iFreq);
  26. // Set up window focus and blur events
  27. var instanceRef = this;
  28. this.oDraftHandle.onblur = function (oEvent) {return instanceRef.draftBlur(oEvent, true);};
  29. this.oDraftHandle.onfocus = function (oEvent) {return instanceRef.draftFocus(oEvent, true);};
  30. // If we found the iframe window, set body focus/blur events for it
  31. if (oIframeWindow.document)
  32. {
  33. var oIframeDoc = oIframeWindow.document;
  34. // @todo oDraftAutoSave should use the this.opt.sSelf name not hardcoded
  35. oIframeDoc.body.onblur = function (oEvent) {return parent.oDraftAutoSave.draftBlur(oEvent, false);};
  36. oIframeDoc.body.onfocus = function (oEvent) {return parent.oDraftAutoSave.draftFocus(oEvent, false);};
  37. };
  38. }
  39. }
  40. // Moved away from the page, where did you go? ... till you return we pause autosaving
  41. smf_DraftAutoSave.prototype.draftBlur = function(oEvent, source)
  42. {
  43. if ($('#' + this.opt.sSceditorID).data("sceditor").inSourceMode() == source)
  44. {
  45. // save what we have and turn of the autosave
  46. if (this.bPM)
  47. this.draftPMSave();
  48. else
  49. this.draftSave();
  50. if (this.interval_id != "")
  51. window.clearInterval(this.interval_id);
  52. this.interval_id = "";
  53. }
  54. return;
  55. }
  56. // Since your back we resume the autosave timer
  57. smf_DraftAutoSave.prototype.draftFocus = function(oEvent, source)
  58. {
  59. if ($('#' + this.opt.sSceditorID).data("sceditor").inSourceMode() == source)
  60. {
  61. if (this.interval_id == "")
  62. this.interval_id = window.setInterval(this.opt.sSelf + '.draft' + (this.bPM ? 'PM' : '') + 'Save();', this.opt.iFreq);
  63. }
  64. return;
  65. }
  66. // Make the call to save this draft in the background
  67. smf_DraftAutoSave.prototype.draftSave = function ()
  68. {
  69. var sPostdata = $('#' + this.opt.sSceditorID).data("sceditor").getText(true);
  70. // nothing to save or already posting or nothing changed?
  71. if (isEmptyText(sPostdata) || smf_formSubmitted || this.sCheckDraft == sPostdata)
  72. return false;
  73. // Still saving the last one or other?
  74. if (this.bInDraftMode)
  75. this.draftCancel();
  76. // Flag that we are saving a draft
  77. document.getElementById('throbber').style.display = '';
  78. this.bInDraftMode = true;
  79. // Get the form elements that we want to save
  80. var aSections = [
  81. 'topic=' + parseInt(document.forms.postmodify.elements['topic'].value),
  82. 'id_draft=' + (('id_draft' in document.forms.postmodify.elements) ? parseInt(document.forms.postmodify.elements['id_draft'].value) : 0),
  83. 'subject=' + escape(document.forms.postmodify['subject'].value.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
  84. 'message=' + escape(sPostdata.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
  85. 'icon=' + escape(document.forms.postmodify['icon'].value.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
  86. 'save_draft=true',
  87. smf_session_var + '=' + smf_session_id,
  88. ];
  89. // Get the locked an/or sticky values if they have been selected or set that is
  90. if (this.opt.sType == 'post')
  91. {
  92. if (document.getElementById('check_lock') && document.getElementById('check_lock').checked)
  93. aSections[aSections.length] = 'lock=1';
  94. if (document.getElementById('check_sticky') && document.getElementById('check_sticky').checked)
  95. aSections[aSections.length] = 'sticky=1';
  96. }
  97. // keep track of source or wysiwyg
  98. aSections[aSections.length] = 'message_mode=' + $('#' + this.opt.sSceditorID).data("sceditor").inSourceMode();
  99. // Send in document for saving and hope for the best
  100. sendXMLDocument.call(this, smf_prepareScriptUrl(smf_scripturl) + "action=post2;board=" + this.opt.iBoard + ";xml", aSections.join("&"), this.onDraftDone);
  101. // Save the latest for compare
  102. this.sCheckDraft = sPostdata;
  103. }
  104. // Make the call to save this PM draft in the background
  105. smf_DraftAutoSave.prototype.draftPMSave = function ()
  106. {
  107. var sPostdata = $('#' + this.opt.sSceditorID).data("sceditor").getText();
  108. // nothing to save or already posting or nothing changed?
  109. if (isEmptyText(sPostdata) || smf_formSubmitted || this.sCheckDraft == sPostdata)
  110. return false;
  111. // Still saving the last one or some other?
  112. if (this.bInDraftMode)
  113. this.draftCancel();
  114. // Flag that we are saving
  115. document.getElementById('throbber').style.display = '';
  116. this.bInDraftMode = true;
  117. // Get the to and bcc values
  118. var aTo = this.draftGetRecipient('recipient_to[]');
  119. var aBcc = this.draftGetRecipient('recipient_bcc[]');
  120. // Get the rest of the form elements that we want to save, and load them up
  121. var aSections = [
  122. 'replied_to=' + parseInt(document.forms.postmodify.elements['replied_to'].value),
  123. 'id_pm_draft=' + (('id_pm_draft' in document.forms.postmodify.elements) ? parseInt(document.forms.postmodify.elements['id_pm_draft'].value) : 0),
  124. 'subject=' + escape(document.forms.postmodify['subject'].value.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
  125. 'message=' + escape(sPostdata.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"),
  126. 'recipient_to=' + aTo,
  127. 'recipient_bcc=' + aBcc,
  128. 'save_draft=true',
  129. smf_session_var + '=' + smf_session_id,
  130. ];
  131. // account for wysiwyg
  132. if (this.opt.sType == 'post')
  133. aSections[aSections.length] = 'message_mode=' + parseInt(document.forms.postmodify.elements['message_mode'].value);
  134. // Send in (post) the document for saving
  135. sendXMLDocument.call(this, smf_prepareScriptUrl(smf_scripturl) + "action=pm;sa=send2;xml", aSections.join("&"), this.onDraftDone);
  136. // Save the latest for compare
  137. this.sCheckDraft = sPostdata;
  138. }
  139. // Callback function of the XMLhttp request for saving the draft message
  140. smf_DraftAutoSave.prototype.onDraftDone = function (XMLDoc)
  141. {
  142. // If it is not valid then clean up
  143. if (!XMLDoc || !XMLDoc.getElementsByTagName('draft'))
  144. return this.draftCancel();
  145. // Grab the returned draft id and saved time from the response
  146. this.sCurDraftId = XMLDoc.getElementsByTagName('draft')[0].getAttribute('id');
  147. this.sLastSaved = XMLDoc.getElementsByTagName('draft')[0].childNodes[0].nodeValue;
  148. // Update the form to show we finished, if the id is not set, then set it
  149. document.getElementById(this.opt.sLastID).value = this.sCurDraftId;
  150. oCurDraftDiv = document.getElementById(this.opt.sLastNote);
  151. setInnerHTML(oCurDraftDiv, this.sLastSaved);
  152. // hide the saved draft infobox in the event they pressed the save draft button at some point
  153. if (this.opt.sType == 'post')
  154. document.getElementById('draft_section').style.display = 'none';
  155. // thank you sir, may I have another
  156. this.bInDraftMode = false;
  157. document.getElementById('throbber').style.display = 'none';
  158. }
  159. // function to retrieve the to and bcc values from the pseudo arrays
  160. smf_DraftAutoSave.prototype.draftGetRecipient = function (sField)
  161. {
  162. var oRecipient = document.forms.postmodify.elements[sField];
  163. var aRecipient = []
  164. if (typeof(oRecipient) != 'undefined')
  165. {
  166. // just one recipient
  167. if ('value' in oRecipient)
  168. aRecipient.push(parseInt(oRecipient.value));
  169. else
  170. {
  171. // or many !
  172. for (var i = 0, n = oRecipient.length; i < n; i++)
  173. aRecipient.push(parseInt(oRecipient[i].value));
  174. }
  175. }
  176. return aRecipient;
  177. }
  178. // If another auto save came in with one still pending
  179. smf_DraftAutoSave.prototype.draftCancel = function ()
  180. {
  181. // can we do anything at all ... do we want to (e.g. sequence our async events?)
  182. // @todo if not remove this function
  183. this.bInDraftMode = false;
  184. document.getElementById('throbber').style.display = 'none';
  185. }