import SETTINGS from "../../../common/Settings" ; import DFChatEditor from './DFChatEditor' ; const PREF_EDIT_ALLOWED = 'edit-allowed' ; const PREF_GM_ALL = 'gm-edit-all' ; const PREF_IGNORE_HTML = 'edit-ignore-html' ; export default class DFChatEdit { static ready ( ) { SETTINGS . register ( DFChatEditor . PREF_MARKDOWN , { name : 'DF_CHAT_EDIT.Settings_MarkdownName' , hint : 'DF_CHAT_EDIT.Settings_MarkdownHint' , type : Boolean , default : true , config : true , scope : 'world' } ) ; SETTINGS . register ( PREF_EDIT_ALLOWED , { name : 'DF_CHAT_EDIT.Settings_AllowEditName' , hint : 'DF_CHAT_EDIT.Settings_AllowEditHint' , type : Boolean , default : true , scope : 'world' , config : true } ) ; SETTINGS . register ( PREF_GM_ALL , { name : 'DF_CHAT_EDIT.Settings_GMEditAllName' , hint : 'DF_CHAT_EDIT.Settings_GMEditAllHint' , type : Boolean , default : false , config : true , scope : 'world' } ) ; SETTINGS . register ( PREF_IGNORE_HTML , { name : 'DF_CHAT_EDIT.Settings_IgnoreHtmlName' , hint : 'DF_CHAT_EDIT.Settings_IgnoreHtmlHint' , type : Boolean , default : false , config : true , scope : 'world' } ) ; libWrapper . register ( SETTINGS . MOD_NAME , 'ChatLog.prototype._onChatKeyDown' , ( wrapper , ... args ) => { const event = args [ 0 ] as KeyboardEvent ; if ( event . code === "ArrowUp" && event . ctrlKey ) { event . preventDefault ( ) ; let messages = < ChatMessage [ ] > [ ... ( ui . chat . collection . values ( ) ) ] ; messages = messages . sort ( ( a , b ) => b . data . timestamp - a . data . timestamp ) ; const message = messages . find ( x => x . data . user === game . user . id ) ; if ( ! message ) return ; DFChatEdit . editChatMessage . bind ( message ) ( ) ; } else wrapper ( ... args ) ; } , 'MIXED' ) ; libWrapper . register ( SETTINGS . MOD_NAME , 'ChatLog.prototype.processMessage' , function ( this , wrapper , message ) { let originalMessage = null ; if ( SETTINGS . get ( DFChatEditor . PREF_MARKDOWN ) ) { if ( message . trim ( ) . startsWith ( '/' ) ) { const token = message . split ( ' ' ) [ 0 ] . trim ( ) ; switch ( token ) { case '/ooc' : case '/ic' : case '/emote' : case '/whisper' : case '/w' : [ originalMessage , message ] = DFChatEditor . processMarkdown ( message . substr ( token . length ) ) ; originalMessage = `${ token } ${ originalMessage . trimStart ( ) }` ; message = `${ token } ${ message . trimStart ( ) }` ; break ; case 'log' : case 'gmlog' : case '/gmroll' : case '/blindroll' : case '/selfroll' : case '/r' : case '/roll' : default : break ; } } else { [ originalMessage , message ] = DFChatEditor . processMarkdown ( message ) ; } } const result = wrapper ( message ) ; if ( originalMessage ) { this . _sentMessages . splice ( 0 , 1 ) ; this . _sentMessages . unshift ( originalMessage ) ; } return result ; } , 'WRAPPER' ) ; } static appendChatContextMenuOptions ( options ) { options . push ( { name : 'DF_CHAT_EDIT.ContextOption' , icon : '<i class="fas fa-pencil-alt"></i>' , condition : ( header ) => { const chatData = ui . chat . collection . get ( $ ( header ) . attr ( 'data-message-id' ) ) ; return this . processChatMessage ( chatData ) ; } , callback : ( header ) => { const chatData = ui . chat . collection . get ( $ ( header ) . attr ( 'data-message-id' ) ) ; DFChatEdit . editChatMessage . bind ( chatData ) ( ) ; return { } ; } } ) ; } static editChatMessage ( this ) { if ( ! SETTINGS . get ( PREF_EDIT_ALLOWED ) ) { ui . notifications . warn ( 'DF_CHAT_EDIT.Error_NoPermission' . localize ( ) ) ; return ; } if ( ( < any > this ) . chatEditor ) { ( < any > this ) . chatEditor . bringToTop ( ) ; } else { ( < any > this ) . chatEditor = new DFChatEditor ( this ) ; ( < any > this ) . chatEditor . render ( true ) ; } } static isHTML ( str ) { const doc = new DOMParser ( ) . parseFromString ( str , "text/html" ) ; return Array . from ( doc . body . childNodes ) . some ( node => { return ( node instanceof HTMLElement && ! node . classList . contains ( 'df-edited' ) ) && ! ( node instanceof HTMLBRElement ) && node . nodeType === 1 ; } ) ; } static processChatMessage ( chatMessage ) { if ( ! ui . chat . collection . has ( chatMessage . id ) ) return false ; if ( ! SETTINGS . get ( PREF_EDIT_ALLOWED ) || chatMessage . isRoll || ( chatMessage . data . user !== game . userId && ! ( game . user . isGM && SETTINGS . get ( PREF_GM_ALL ) ) ) ) return false ; if ( SETTINGS . get ( PREF_IGNORE_HTML ) && DFChatEdit . isHTML ( chatMessage . data . content ) ) return false ; return true ; } }