@@ -278,35 +278,16 @@ function QuickModify(oOptions)
278278 this . sCurMessageId = '' ;
279279 this . oCurMessageDiv = null ;
280280 this . oCurSubjectDiv = null ;
281- this . sMessageBuffer = '' ;
282- this . sSubjectBuffer = '' ;
283- this . aAccessKeys = new Array ( ) ;
281+
282+ for ( const el of document . getElementsByClassName ( this . opt . sClassName ) ) {
283+ el . hidden = false ;
284+ el . addEventListener ( 'click' , this . modifyMsg . bind ( this , el . id . match ( / \d + / ) ) ) ;
285+ }
284286}
285287
286288// Function called when a user presses the edit button.
287289QuickModify . prototype . modifyMsg = function ( iMessageId )
288290{
289- // Add backwards compatibility with old themes.
290- if ( typeof ( sSessionVar ) == 'undefined' )
291- sSessionVar = 'sesc' ;
292-
293- // Removes the accesskeys from the quickreply inputs and saves them in an array to use them later
294- if ( typeof ( this . opt . sFormRemoveAccessKeys ) != 'undefined' )
295- {
296- if ( typeof ( document . forms [ this . opt . sFormRemoveAccessKeys ] ) )
297- {
298- var aInputs = document . forms [ this . opt . sFormRemoveAccessKeys ] . getElementsByTagName ( 'input' ) ;
299- for ( var i = 0 ; i < aInputs . length ; i ++ )
300- {
301- if ( aInputs [ i ] . accessKey != '' )
302- {
303- this . aAccessKeys [ aInputs [ i ] . name ] = aInputs [ i ] . accessKey ;
304- aInputs [ i ] . accessKey = '' ;
305- }
306- }
307- }
308- }
309-
310291 // First cancel if there's another message still being edited.
311292 if ( this . bInEditMode )
312293 this . modifyCancel ( ) ;
@@ -316,7 +297,7 @@ QuickModify.prototype.modifyMsg = function (iMessageId)
316297
317298 // Send out the XMLhttp request to get more info
318299 ajax_indicator ( true ) ;
319- sendXMLDocument . call ( this , smf_prepareScriptUrl ( smf_scripturl ) + 'action=quotefast;quote=' + iMessageId + ';modify;xml;' + smf_session_var + '=' + smf_session_id , '' , this . onMessageReceived ) ;
300+ getXMLDocument . call ( this , smf_prepareScriptUrl ( smf_scripturl ) + 'action=quotefast;quote=' + iMessageId + ';modify;xml;' + smf_session_var + '=' + smf_session_id , this . onMessageReceived ) ;
320301
321302 // Jump to the message
322303 document . getElementById ( 'msg' + iMessageId ) . scrollIntoView ( ) ;
@@ -338,105 +319,116 @@ QuickModify.prototype.onMessageReceived = function (XMLDoc)
338319 return this . modifyCancel ( ) ;
339320
340321 // Replace the body part.
341- for ( var i = 0 ; i < XMLDoc . getElementsByTagName ( "message" ) [ 0 ] . childNodes . length ; i ++ )
322+ for ( let i = 0 ; i < XMLDoc . getElementsByTagName ( "message" ) [ 0 ] . childNodes . length ; i ++ )
342323 sBodyText += XMLDoc . getElementsByTagName ( "message" ) [ 0 ] . childNodes [ i ] . nodeValue ;
343- this . oCurMessageDiv = document . getElementById ( this . sCurMessageId ) ;
344- this . sMessageBuffer = getInnerHTML ( this . oCurMessageDiv ) ;
345324
346- // We have to force the body to lose its dollar signs thanks to IE.
347- sBodyText = sBodyText . replace ( / \$ / g, '{&dollarfix;$}' ) ;
348-
349- // Actually create the content, with a bodge for disappearing dollar signs.
350- setInnerHTML ( this . oCurMessageDiv , this . opt . sTemplateBodyEdit . replace ( / % m s g _ i d % / g, this . sCurMessageId . substr ( 4 ) ) . replace ( / % b o d y % / , sBodyText ) . replace ( / \{ & d o l l a r f i x ; \$ \} / g, '$' ) ) ;
351-
352- // Replace the subject part.
353- this . oCurSubjectDiv = document . getElementById ( 'subject_' + this . sCurMessageId . substr ( 4 ) ) ;
354- this . sSubjectBuffer = getInnerHTML ( this . oCurSubjectDiv ) ;
355-
356- sSubjectText = XMLDoc . getElementsByTagName ( 'subject' ) [ 0 ] . childNodes [ 0 ] . nodeValue . replace ( / \$ / g, '{&dollarfix;$}' ) ;
357- setInnerHTML ( this . oCurSubjectDiv , this . opt . sTemplateSubjectEdit . replace ( / % s u b j e c t % / , sSubjectText ) . replace ( / \{ & d o l l a r f i x ; \$ \} / g, '$' ) ) ;
358-
359- // Field for editing reason.
360- sReasonText = XMLDoc . getElementsByTagName ( 'reason' ) [ 0 ] . childNodes [ 0 ] . nodeValue . replace ( / \$ / g, '{&dollarfix;$}' ) ;
361-
362- $ ( this . oCurMessageDiv ) . prepend ( this . opt . sTemplateReasonEdit . replace ( / % m o d i f y _ r e a s o n % / , sReasonText ) . replace ( / \{ & d o l l a r f i x ; \$ \} / g, '$' ) ) ;
325+ this . oCurMessageDiv = document . getElementById ( this . sCurMessageId ) ;
326+ this . oCurSubjectDiv = document . getElementById ( 'subject_' + this . sCurMessageId . substring ( 4 ) ) ;
327+ if ( this . oCurSubjectDiv !== null )
328+ this . oCurSubjectDiv . hidden = true ;
329+ this . oCurMessageDiv . hidden = true ;
330+
331+ // Actually create the content.
332+ const form = document . createElement ( "form" ) ;
333+ form . id = "quickModifyForm" ;
334+
335+ var messageInput = document . createElement ( "textarea" ) ;
336+ messageInput . name = "message" ;
337+ messageInput . cols = "80" ;
338+ messageInput . rows = "10" ;
339+ messageInput . innerHTML = sBodyText ;
340+ messageInput . addEventListener ( 'keydown' , function ( e ) {
341+ if ( e . key === "Enter" && ( e . metaKey || e . ctrlKey ) ) {
342+ this . modifySave ( ) ;
343+ }
344+ if ( e . key === "Escape" ) {
345+ this . modifyCancel ( ) ;
346+ }
347+ } . bind ( this ) ) ;
348+
349+ var subjectInput = document . createElement ( "input" ) ;
350+ subjectInput . name = "subject" ;
351+ subjectInput . maxLength = "80" ;
352+ subjectInput . size = "80" ;
353+ subjectInput . value = XMLDoc . getElementsByTagName ( 'subject' ) [ 0 ] . childNodes [ 0 ] . nodeValue ;
354+
355+ const reasonLabel = document . createElement ( "label" ) ;
356+ const reasonInput = document . createElement ( "input" ) ;
357+ reasonInput . name = "modify_reason" ;
358+ reasonInput . maxLength = "80" ;
359+ reasonInput . size = "80" ;
360+ reasonInput . value = XMLDoc . getElementsByTagName ( 'reason' ) [ 0 ] . childNodes [ 0 ] . nodeValue ;
361+
362+ const buttonGroup = document . createElement ( "div" ) ;
363+ buttonGroup . className = 'buttonlistend' ;
364+
365+ const cancelButton = document . createElement ( "button" ) ;
366+ cancelButton . className = 'button' ;
367+ cancelButton . textContent = this . opt . sCancelButtonText ;
368+ cancelButton . addEventListener ( 'click' , this . modifyCancel . bind ( this ) ) ;
369+
370+ const saveButton = document . createElement ( "button" ) ;
371+ saveButton . className = 'button active' ;
372+ saveButton . textContent = this . opt . sSaveButtonText ;
373+ saveButton . addEventListener ( 'click' , this . modifySave . bind ( this ) ) ;
374+
375+ reasonLabel . append ( this . opt . sTemplateReasonEdit , reasonInput ) ;
376+ buttonGroup . append ( saveButton , cancelButton ) ;
377+ form . append ( subjectInput , messageInput , reasonLabel , buttonGroup ) ;
378+ this . oCurMessageDiv . after ( form ) ;
379+ messageInput . focus ( ) ;
380+
381+ if ( this . opt . funcOnAfterCreate ) {
382+ this . opt . funcOnAfterCreate . call ( this , form ) ;
383+ }
363384
364385 return true ;
365386}
366387
367388// Function in case the user presses cancel (or other circumstances cause it).
368389QuickModify . prototype . modifyCancel = function ( )
369390{
370- // Roll back the HTML to its original state.
371391 if ( this . oCurMessageDiv )
372392 {
373- this . oCurMessageDiv . innerHTML = this . sMessageBuffer ;
374- this . oCurSubjectDiv . innerHTML = this . sSubjectBuffer ;
393+ this . oCurMessageDiv . hidden = false ;
394+ if ( this . oCurSubjectDiv !== null )
395+ this . oCurSubjectDiv . hidden = false ;
396+ document . forms . quickModifyForm . remove ( ) ;
375397 }
376398
377399 // No longer in edit mode, that's right.
378400 this . bInEditMode = false ;
379401
380- // Let's put back the accesskeys to their original place
381- if ( typeof ( this . opt . sFormRemoveAccessKeys ) != 'undefined' )
382- {
383- if ( typeof ( document . forms [ this . opt . sFormRemoveAccessKeys ] ) )
384- {
385- var aInputs = document . forms [ this . opt . sFormRemoveAccessKeys ] . getElementsByTagName ( 'input' ) ;
386- for ( var i = 0 ; i < aInputs . length ; i ++ )
387- {
388- if ( typeof ( this . aAccessKeys [ aInputs [ i ] . name ] ) != 'undefined' )
389- {
390- aInputs [ i ] . accessKey = this . aAccessKeys [ aInputs [ i ] . name ] ;
391- }
392- }
393- }
394- }
395-
396402 return false ;
397403}
398404
399405// The function called after a user wants to save his precious message.
400- QuickModify . prototype . modifySave = function ( sSessionId , sSessionVar )
406+ QuickModify . prototype . modifySave = function ( e )
401407{
408+ e && e . preventDefault && e . preventDefault ( ) ;
409+
402410 // We cannot save if we weren't in edit mode.
403- if ( ! this . bInEditMode )
411+ if ( ! this . bInEditMode ) {
404412 return true ;
413+ }
405414
406- // Add backwards compatibility with old themes.
407- if ( typeof ( sSessionVar ) == 'undefined' )
408- sSessionVar = 'sesc' ;
415+ const x = [ ] ;
416+ submitThisOnce ( document . forms . quickModifyForm ) ;
417+ const form = document . forms . quickModifyForm ;
409418
410- // Let's put back the accesskeys to their original place
411- if ( typeof ( this . opt . sFormRemoveAccessKeys ) != 'undefined' )
412- {
413- if ( typeof ( document . forms [ this . opt . sFormRemoveAccessKeys ] ) )
414- {
415- var aInputs = document . forms [ this . opt . sFormRemoveAccessKeys ] . getElementsByTagName ( 'input' ) ;
416- for ( var i = 0 ; i < aInputs . length ; i ++ )
417- {
418- if ( typeof ( this . aAccessKeys [ aInputs [ i ] . name ] ) != 'undefined' )
419- {
420- aInputs [ i ] . accessKey = this . aAccessKeys [ aInputs [ i ] . name ] ;
421- }
422- }
423- }
419+ if ( form . firstChild . className === 'errorbox' ) {
420+ form . firstChild . remove ( ) ;
421+ form . message . style . border = '' ;
422+ form . subject . style . border = '' ;
424423 }
425424
426- var i , x = new Array ( ) ,
427- oCaller = this ,
428- formData = {
429- subject : document . forms . quickModForm [ 'subject' ] . value ,
430- message : document . forms . quickModForm [ 'message' ] . value ,
431- topic : parseInt ( document . forms . quickModForm . elements [ 'topic' ] . value ) ,
432- msg : parseInt ( document . forms . quickModForm . elements [ 'msg' ] . value ) ,
433- modify_reason : document . forms . quickModForm . elements [ 'modify_reason' ] . value
434- } ;
425+ for ( const el of form . elements ) {
426+ x . push ( el . name + '=' + el . value . php_to8bit ( ) . php_urlencode ( ) ) ;
427+ }
435428
436429 // Send in the XMLhttp request and let's hope for the best.
437430 ajax_indicator ( true ) ;
438-
439- sendXMLDocument . call ( this , smf_prepareScriptUrl ( this . opt . sScriptUrl ) + "action=jsmodify;topic=" + this . opt . iTopicId + ";" + smf_session_var + "=" + smf_session_id + ";xml" , formData , this . onModifyDone ) ;
431+ sendXMLDocument . call ( this , smf_prepareScriptUrl ( this . opt . sScriptUrl ) + "action=jsmodify;topic=" + this . opt . iTopicId + ";msg=" + this . oCurMessageDiv . id . match ( / \d + / ) + ";" + smf_session_var + "=" + smf_session_id + ";xml" , x . join ( "&" ) , this . onModifyDone ) ;
440432
441433 return false ;
442434}
@@ -450,9 +442,16 @@ QuickModify.prototype.onModifyDone = function (XMLDoc)
450442 // If we didn't get a valid document, just cancel.
451443 if ( ! XMLDoc || ! XMLDoc . getElementsByTagName ( 'smf' ) [ 0 ] )
452444 {
445+ reActivateThis ( document . forms . quickModifyForm ) ;
446+ document . forms . quickModifyForm . message . focus ( ) ;
447+
453448 // Mozilla will nicely tell us what's wrong.
454- if ( XMLDoc . childNodes . length > 0 && XMLDoc . firstChild . nodeName == 'parsererror' )
455- setInnerHTML ( document . getElementById ( 'error_box' ) , XMLDoc . firstChild . textContent ) ;
449+ if ( XMLDoc . childNodes . length > 0 && XMLDoc . firstChild . nodeName == 'parsererror' ) {
450+ const oDiv = document . createElement ( 'div' ) ;
451+ oDiv . innerHTML = XMLDoc . firstChild . textContent ;
452+ oDiv . className = 'errorbox' ;
453+ document . forms . quickModifyForm . prepend ( oDiv ) ;
454+ }
456455 else
457456 this . modifyCancel ( ) ;
458457
@@ -465,40 +464,51 @@ QuickModify.prototype.onModifyDone = function (XMLDoc)
465464
466465 if ( body )
467466 {
467+ this . bInEditMode = false ;
468468 // Show new body.
469- var bodyText = '' ;
470- for ( var i = 0 ; i < body . childNodes . length ; i ++ )
469+ let bodyText = '' ;
470+ for ( let i = 0 ; i < body . childNodes . length ; i ++ )
471471 bodyText += body . childNodes [ i ] . nodeValue ;
472472
473- this . sMessageBuffer = this . opt . sTemplateBodyNormal . replace ( / % b o d y % / , bodyText . replace ( / \$ / g, '{&dollarfix;$}' ) ) . replace ( / \{ & d o l l a r f i x ; \$ \} / g, '$' ) ;
474- setInnerHTML ( this . oCurMessageDiv , this . sMessageBuffer ) ;
473+ this . oCurMessageDiv . innerHTML = bodyText ;
474+ this . oCurMessageDiv . hidden = false ;
475+
476+ // Show new subject div, update in case it changed.
477+ if ( this . oCurSubjectDiv !== null ) {
478+ let oSubject = message . getElementsByTagName ( 'subject' ) [ 0 ] ,
479+ sSubjectText = oSubject . childNodes [ 0 ] . nodeValue ;
475480
476- // Show new subject, but only if we want to...
477- var oSubject = message . getElementsByTagName ( 'subject' ) [ 0 ] ;
478- var sSubjectText = oSubject . childNodes [ 0 ] . nodeValue . replace ( / \$ / g, '{&dollarfix;$}' ) ;
479- var sTopSubjectText = oSubject . childNodes [ 0 ] . nodeValue . replace ( / \$ / g, '{&dollarfix;$}' ) ;
480- this . sSubjectBuffer = this . opt . sTemplateSubjectNormal . replace ( / % m s g _ i d % / g, this . sCurMessageId . substr ( 4 ) ) . replace ( / % s u b j e c t % / , sSubjectText ) . replace ( / \{ & d o l l a r f i x ; \$ \} / g, '$' ) ;
481- setInnerHTML ( this . oCurSubjectDiv , this . sSubjectBuffer ) ;
481+ this . oCurSubjectDiv . innerHTML = sSubjectText ;
482+ this . oCurSubjectDiv . hidden = false ;
483+ }
482484
483- // If this is the first message, also update the topic subject.
484- if ( oSubject . getAttribute ( 'is_first' ) == '1' )
485- setInnerHTML ( document . getElementById ( 'top_subject' ) , this . opt . sTemplateTopSubject . replace ( / % s u b j e c t % / , sTopSubjectText ) . replace ( / \{ & d o l l a r f i x ; \$ \} / g, '$' ) ) ;
485+ document . forms . quickModifyForm . remove ( ) ;
486486
487487 // Show this message as 'modified on x by y'.
488488 if ( this . opt . bShowModify )
489- $ ( '#modified_' + this . sCurMessageId . substr ( 4 ) ) . html ( message . getElementsByTagName ( 'modified' ) [ 0 ] . childNodes [ 0 ] . nodeValue . replace ( / \$ / g, '{&dollarfix;$}' ) ) ;
489+ {
490+ let modified = document . getElementById ( 'modified_' + this . sCurMessageId . substring ( 4 ) ) ;
491+ modified . innerHTML = message . getElementsByTagName ( 'modified' ) [ 0 ] . childNodes [ 0 ] . nodeValue ;
492+ }
490493
491494 // Show a message indicating the edit was successfully done.
492- $ ( '<div/>' , {
493- text : message . getElementsByTagName ( 'success' ) [ 0 ] . childNodes [ 0 ] . nodeValue . replace ( / \$ / g, '{&dollarfix;$}' ) ,
494- class : 'infobox'
495- } ) . prependTo ( '#' + this . sCurMessageId ) . delay ( 5000 ) . fadeOutAndRemove ( 400 ) ;
495+ const oDiv = document . createElement ( 'div' ) ;
496+ oDiv . textContent = message . getElementsByTagName ( 'success' ) [ 0 ] . childNodes [ 0 ] . nodeValue ;
497+ oDiv . className = 'infobox' ;
498+ this . oCurMessageDiv . before ( oDiv ) ;
499+ setTimeout ( ( ) => oDiv . remove ( ) , 4000 ) ;
496500 }
497501 else if ( error )
498502 {
499- setInnerHTML ( document . getElementById ( 'error_box' ) , error . childNodes [ 0 ] . nodeValue ) ;
500- document . forms . quickModForm . message . style . border = error . getAttribute ( 'in_body' ) == '1' ? this . opt . sErrorBorderStyle : '' ;
501- document . forms . quickModForm . subject . style . border = error . getAttribute ( 'in_subject' ) == '1' ? this . opt . sErrorBorderStyle : '' ;
503+ reActivateThis ( document . forms . quickModifyForm ) ;
504+ const oDiv = document . createElement ( 'div' ) ;
505+ oDiv . innerHTML = error . childNodes [ 0 ] . nodeValue ;
506+ oDiv . className = 'errorbox' ;
507+ document . forms . quickModifyForm . prepend ( oDiv ) ;
508+
509+ document . forms . quickModifyForm . message . focus ( ) ;
510+ document . forms . quickModifyForm . message . style . border = error . getAttribute ( 'in_body' ) == '1' ? this . opt . sErrorBorderStyle : '' ;
511+ document . forms . quickModifyForm . subject . style . border = error . getAttribute ( 'in_subject' ) == '1' ? this . opt . sErrorBorderStyle : '' ;
502512 }
503513}
504514
0 commit comments