2020-10-20 23:25:34 +02:00
/ * *
* @ name SpellCheck
* @ authorId 278543574059057154
* @ invite Jx3TjNS
* @ donate https : //www.paypal.me/MircoWittrien
* @ patreon https : //www.patreon.com/MircoWittrien
* @ website https : //github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/SpellCheck
* @ source https : //raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/SpellCheck/SpellCheck.plugin.js
2020-11-12 17:30:48 +01:00
* @ updateUrl https : //raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/SpellCheck/SpellCheck.plugin.js
2020-10-20 23:25:34 +02:00
* /
2018-10-11 10:21:26 +02:00
2020-09-19 20:49:33 +02:00
module . exports = ( _ => {
2020-10-09 21:09:35 +02:00
const config = {
2020-09-19 20:49:33 +02:00
"info" : {
"name" : "SpellCheck" ,
"author" : "DevilBro" ,
2020-09-20 07:20:57 +02:00
"version" : "1.5.4" ,
2020-10-16 10:25:30 +02:00
"description" : "Add a spellcheck to all textareas. Select a word and rightclick it to add it to your dictionary"
2020-02-20 17:23:49 +01:00
}
2020-09-19 20:49:33 +02:00
} ;
2020-10-09 21:09:35 +02:00
return ! window . BDFDB _Global || ( ! window . BDFDB _Global . loaded && ! window . BDFDB _Global . started ) ? class {
2021-01-06 12:38:36 +01:00
getName ( ) { return config . info . name ; }
getAuthor ( ) { return config . info . author ; }
getVersion ( ) { return config . info . version ; }
2021-01-14 16:14:44 +01:00
getDescription ( ) { return ` The Library Plugin needed for ${ config . info . name } is missing. Open the Plugin Settings to download it. \n \n ${ config . info . description } ` ; }
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
load ( ) {
2020-11-19 16:51:14 +01:00
if ( ! window . BDFDB _Global || ! Array . isArray ( window . BDFDB _Global . pluginQueue ) ) window . BDFDB _Global = Object . assign ( { } , window . BDFDB _Global , { pluginQueue : [ ] } ) ;
2020-09-19 20:49:33 +02:00
if ( ! window . BDFDB _Global . downloadModal ) {
window . BDFDB _Global . downloadModal = true ;
2021-01-14 16:14:44 +01:00
BdApi . showConfirmationModal ( "Library Missing" , ` The Library Plugin needed for ${ config . info . name } is missing. Please click "Download Now" to install it. ` , {
2020-09-19 20:49:33 +02:00
confirmText : "Download Now" ,
cancelText : "Cancel" ,
onCancel : _ => { delete window . BDFDB _Global . downloadModal ; } ,
2020-09-20 08:15:13 +02:00
onConfirm : _ => {
delete window . BDFDB _Global . downloadModal ;
require ( "request" ) . get ( "https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js" , ( e , r , b ) => {
2020-10-20 23:25:34 +02:00
if ( ! e && b && b . indexOf ( ` * @name BDFDB ` ) > - 1 ) require ( "fs" ) . writeFile ( require ( "path" ) . join ( BdApi . Plugins . folder , "0BDFDB.plugin.js" ) , b , _ => { } ) ;
2021-01-14 16:14:44 +01:00
else BdApi . alert ( "Error" , "Could not download BDFDB Library Plugin, try again later or download it manually from GitHub: https://github.com/mwittrien/BetterDiscordAddons/tree/master/Library/" ) ;
2020-09-20 08:15:13 +02:00
} ) ;
}
2020-09-19 20:49:33 +02:00
} ) ;
}
if ( ! window . BDFDB _Global . pluginQueue . includes ( config . info . name ) ) window . BDFDB _Global . pluginQueue . push ( config . info . name ) ;
2020-10-09 21:09:35 +02:00
}
2021-01-06 12:38:36 +01:00
start ( ) { this . load ( ) ; }
stop ( ) { }
getSettingsPanel ( ) {
2020-11-28 23:12:09 +01:00
let template = document . createElement ( "template" ) ;
2021-01-14 16:14:44 +01:00
template . innerHTML = ` <div style="color: var(--header-primary); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The Library Plugin needed for ${ config . info . name } is missing. \n Please click <a style="font-weight: 500;">Download Now</a> to install it.</div> ` ;
2020-11-28 23:12:09 +01:00
template . content . firstElementChild . querySelector ( "a" ) . addEventListener ( "click" , _ => {
require ( "request" ) . get ( "https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js" , ( e , r , b ) => {
if ( ! e && b && b . indexOf ( ` * @name BDFDB ` ) > - 1 ) require ( "fs" ) . writeFile ( require ( "path" ) . join ( BdApi . Plugins . folder , "0BDFDB.plugin.js" ) , b , _ => { } ) ;
2021-01-14 16:14:44 +01:00
else BdApi . alert ( "Error" , "Could not download BDFDB Library Plugin, try again later or download it manually from GitHub: https://github.com/mwittrien/BetterDiscordAddons/tree/master/Library/" ) ;
2020-11-28 23:12:09 +01:00
} ) ;
} ) ;
return template . content . firstElementChild ;
}
2020-10-09 21:09:35 +02:00
} : ( ( [ Plugin , BDFDB ] ) => {
2020-09-19 20:49:33 +02:00
var languages , dictionaries , langDictionaries , languageToasts , checkTimeout , currentText ;
var settings = { } , choices = { } , amounts = { } ;
2020-10-09 21:09:35 +02:00
return class SpellCheck extends Plugin {
2021-01-06 12:38:36 +01:00
onLoad ( ) {
2020-09-19 20:49:33 +02:00
languages = { } ;
dictionaries = { } ;
langDictionaries = { } ;
languageToasts = { } ;
this . defaults = {
settings : {
2020-11-19 16:51:14 +01:00
downloadDictionary : { value : false , description : "Use local dictionary file (downloads dictionary on first usage)" }
2020-09-19 20:49:33 +02:00
} ,
choices : {
2020-11-19 16:51:14 +01:00
dictionaryLanguage : { value : "en" , force : true , description : "Primary Language: " } ,
secondaryLanguage : { value : "-" , force : false , description : "Secondary Language: " }
2020-09-19 20:49:33 +02:00
} ,
amounts : {
2020-11-19 16:51:14 +01:00
maxSimilarAmount : { value : 6 , min : 1 , max : 30 , description : "Maximal Amount of suggested Words: " }
2020-02-20 17:23:49 +01:00
}
2020-09-19 20:49:33 +02:00
} ;
2020-02-20 17:23:49 +01:00
2020-09-19 20:49:33 +02:00
this . patchedModules = {
after : {
SlateChannelTextArea : [ "componentDidMount" , "componentDidUpdate" ]
}
} ;
2020-02-20 17:23:49 +01:00
2020-09-19 20:49:33 +02:00
this . css = `
$ { BDFDB . dotCNS . _spellcheckoverlay + BDFDB . dotCN . _spellcheckerror } {
2020-11-19 16:56:08 +01:00
background - image : url ( 'data:image/png;base64,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' ) ;
2020-09-19 20:49:33 +02:00
background - repeat : repeat - x ;
background - position : bottom ;
}
` ;
}
2021-01-06 12:38:36 +01:00
onStart ( ) {
2020-06-05 20:03:21 +02:00
BDFDB . LibraryRequires . request ( "https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/SpellCheck/dic" , ( error , response , body ) => {
let dictionaryLanguageIds = Array . from ( BDFDB . DOMUtils . create ( body ) . querySelectorAll ( ` [href*="/mwittrien/BetterDiscordAddons/blob/master/Plugins/SpellCheck/dic/"] ` ) ) . map ( n => n . innerText . split ( "." ) [ 0 ] ) . filter ( n => n ) ;
languages = BDFDB . ObjectUtils . filter ( BDFDB . LanguageUtils . languages , langId => dictionaryLanguageIds . includes ( langId ) , true ) ;
2020-06-09 09:30:21 +02:00
if ( ( BDFDB . LibraryModules . StoreChangeUtils && BDFDB . LibraryModules . StoreChangeUtils . get ( "SpellcheckStore" ) || { } ) . enabled ) BDFDB . LibraryModules . SpellCheckUtils . toggleSpellcheck ( ) ;
this . forceUpdateAll ( ) ;
2020-06-05 20:03:21 +02:00
for ( let key in choices ) {
2020-06-16 09:20:23 +02:00
if ( key == "dictionaryLanguage" && ! languages [ choices [ key ] ] ) {
2020-06-05 20:03:21 +02:00
choices [ key ] = "en" ;
2020-06-09 09:30:21 +02:00
BDFDB . DataUtils . save ( choices [ key ] , this , "choices" , key ) ;
2020-06-05 20:03:21 +02:00
}
this . setDictionary ( key , choices [ key ] ) ;
}
} ) ;
2020-02-20 17:23:49 +01:00
}
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
onStop ( ) {
2020-09-19 20:49:33 +02:00
this . forceUpdateAll ( ) ;
2020-02-20 17:23:49 +01:00
BDFDB . DOMUtils . remove ( BDFDB . dotCN . _spellcheckoverlay ) ;
2019-01-26 22:45:19 +01:00
2020-05-23 10:59:15 +02:00
for ( let key in languageToasts ) this . killLanguageToast ( key ) ;
2020-02-20 17:23:49 +01:00
}
2018-10-11 10:21:26 +02:00
2020-09-19 20:49:33 +02:00
getSettingsPanel ( collapseStates = { } ) {
let ownDictionary = BDFDB . DataUtils . load ( this , "owndics" , choices . dictionaryLanguage ) || [ ] ;
let settingsPanel , settingsItems = [ ] ;
for ( let key in settings ) settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
className : BDFDB . disCN . marginbottom8 ,
type : "Switch" ,
plugin : this ,
keys : [ "settings" , key ] ,
label : this . defaults . settings [ key ] . description ,
value : settings [ key ]
} ) ) ;
for ( let key in choices ) settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
className : BDFDB . disCN . marginbottom8 ,
type : "Select" ,
plugin : this ,
keys : [ "choices" , key ] ,
label : this . defaults . choices [ key ] . description ,
basis : "70%" ,
value : choices [ key ] ,
2020-11-19 16:51:14 +01:00
options : ( this . defaults . choices [ key ] . force ? [ ] : [ { value : "-" , label : BDFDB . LanguageUtils . LanguageStrings . FORM _LABEL _NOTHING } ] ) . concat ( BDFDB . ObjectUtils . toArray ( BDFDB . ObjectUtils . map ( languages , ( lang , id ) => ( { value : id , label : this . getLanguageName ( lang ) } ) ) ) ) ,
2020-09-19 20:49:33 +02:00
searchable : true ,
onChange : value => {
this . setDictionary ( key , value ) ;
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel ) ;
}
} ) ) ;
for ( let key in amounts ) settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
className : BDFDB . disCN . marginbottom8 ,
type : "TextInput" ,
childProps : {
type : "number"
} ,
plugin : this ,
keys : [ "amounts" , key ] ,
label : this . defaults . amounts [ key ] . description ,
basis : "20%" ,
min : this . defaults . amounts [ key ] . min ,
max : this . defaults . amounts [ key ] . max ,
value : amounts [ key ]
} ) ) ;
2020-12-15 10:35:30 +01:00
if ( ownDictionary . length ) settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsPanelList , {
2020-09-19 20:49:33 +02:00
title : "Your own Dictionary:" ,
children : ownDictionary . map ( word => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Card , {
children : word . toLowerCase ( ) ,
onRemove : _ => {
BDFDB . ArrayUtils . remove ( ownDictionary , word ) ;
BDFDB . DataUtils . save ( ownDictionary , this , "owndics" , choices . dictionaryLanguage ) ;
dictionaries . dictionaryLanguage = this . formatDictionary ( langDictionaries . dictionaryLanguage . concat ( ownDictionary ) ) ;
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel ) ;
}
} ) )
} ) ) ;
return settingsPanel = BDFDB . PluginUtils . createSettingsPanel ( this , settingsItems ) ;
}
2019-01-26 22:45:19 +01:00
2021-01-06 12:38:36 +01:00
onSettingsClosed ( ) {
2020-09-19 20:49:33 +02:00
if ( this . SettingsUpdated ) {
delete this . SettingsUpdated ;
this . forceUpdateAll ( ) ;
2020-02-20 17:23:49 +01:00
}
2019-02-19 13:34:09 +01:00
}
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
forceUpdateAll ( ) {
2020-09-19 20:49:33 +02:00
settings = BDFDB . DataUtils . get ( this , "settings" ) ;
choices = BDFDB . DataUtils . get ( this , "choices" ) ;
amounts = BDFDB . DataUtils . get ( this , "amounts" ) ;
BDFDB . PatchUtils . forceAllUpdates ( this ) ;
2020-02-20 17:23:49 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
onSlateContextMenu ( e ) {
2020-11-19 16:51:14 +01:00
let [ SCparent , SCindex ] = BDFDB . ContextMenuUtils . findItem ( e . returnvalue , { id : "spellcheck" , group : true } ) ;
2020-09-19 20:49:33 +02:00
if ( SCindex > - 1 ) SCparent . splice ( SCindex , 1 ) ;
let textarea = BDFDB . DOMUtils . getParent ( BDFDB . dotCN . textarea , e . instance . props . target ) , word = null ;
if ( textarea ) for ( let error of textarea . parentElement . querySelectorAll ( BDFDB . dotCN . _spellcheckerror ) ) {
let rects = BDFDB . DOMUtils . getRects ( error ) ;
2020-09-20 07:20:57 +02:00
let position = BDFDB . ListenerUtils . getPosition ( ) ;
if ( position . pageX > rects . x && position . pageX < ( rects . x + rects . width ) && position . pageY > rects . y && position . pageY < ( rects . y + rects . height ) ) {
2020-09-19 20:49:33 +02:00
word = error . innerText ;
break ;
}
}
if ( word && this . isWordNotInDictionary ( word ) ) {
let similarWords = this . getSimilarWords ( word . toLowerCase ( ) . trim ( ) ) ;
let [ children , index ] = BDFDB . ContextMenuUtils . findItem ( e . returnvalue , { id : "devmode-copy-id" , group : true } ) ;
children . splice ( index > - 1 ? index : children . length , 0 , BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuGroup , {
children : BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
label : BDFDB . LanguageUtils . LanguageStrings . SPELLCHECK ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "spellcheck" ) ,
children : [
BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2020-12-21 19:56:36 +01:00
label : this . labels . context _spellcheck ,
2020-09-19 20:49:33 +02:00
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "add-to-spellcheck" ) ,
hint : _ => {
return BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . MenuItems . MenuHint , {
hint : word
} ) ;
} ,
action : _ => {
this . addToOwnDictionary ( word ) ;
}
} ) ,
BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuSeparator , { } ) ,
! similarWords . length ? BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2020-12-21 19:56:36 +01:00
label : this . labels . context _nosimilarwords ,
2020-09-19 20:49:33 +02:00
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "no-suggestions" ) ,
disabled : true
} ) : similarWords . sort ( ) . map ( suggestion => BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
label : suggestion ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "suggestion" , suggestion ) ,
action : _ => {
this . replaceWord ( e . instance . props . editor , word , suggestion ) ;
}
} ) )
] . flat ( 10 ) . filter ( n => n )
} )
} ) ) ;
}
2020-06-09 09:30:21 +02:00
}
2020-09-19 20:49:33 +02:00
processSlateChannelTextArea ( e ) {
let newText = BDFDB . LibraryModules . SlateUtils . serialize ( e . instance . props . value ) ;
if ( newText != currentText ) {
currentText = newText ;
BDFDB . DOMUtils . remove ( e . node . parentElement . querySelectorAll ( BDFDB . dotCN . _spellcheckoverlay ) ) ;
BDFDB . TimeUtils . clear ( checkTimeout ) ;
checkTimeout = BDFDB . TimeUtils . timeout ( _ => {
let overlay = e . node . cloneNode ( true ) , wrapper = BDFDB . DOMUtils . getParent ( BDFDB . dotCN . textareainner , e . node ) ;
BDFDB . DOMUtils . addClass ( overlay , BDFDB . disCN . _spellcheckoverlay ) ;
let style = Object . assign ( { } , getComputedStyle ( e . node ) ) ;
for ( let i in style ) if ( i . indexOf ( "webkit" ) == - 1 && isNaN ( parseInt ( i ) ) ) overlay . style [ i ] = style [ i ] ;
overlay . style . setProperty ( "color" , "transparent" , "important" ) ;
overlay . style . setProperty ( "background" , "none" , "important" ) ;
overlay . style . setProperty ( "mask" , "none" , "important" ) ;
overlay . style . setProperty ( "pointer-events" , "none" , "important" ) ;
overlay . style . setProperty ( "position" , "absolute" , "important" ) ;
overlay . style . setProperty ( "left" , BDFDB . DOMUtils . getRects ( e . node ) . left - BDFDB . DOMUtils . getRects ( wrapper ) . left + "px" , "important" ) ;
overlay . style . setProperty ( "width" , BDFDB . DOMUtils . getRects ( e . node ) . width - style . paddingLeft - style . paddingRight + "px" , "important" ) ;
overlay . style . setProperty ( "height" , style . height , "important" ) ;
for ( let child of overlay . querySelectorAll ( "*" ) ) {
child . style . setProperty ( "color" , "transparent" , "important" ) ;
child . style . setProperty ( "background-color" , "transparent" , "important" ) ;
child . style . setProperty ( "border-color" , "transparent" , "important" ) ;
child . style . setProperty ( "text-shadow" , "none" , "important" ) ;
child . style . setProperty ( "pointer-events" , "none" , "important" ) ;
if ( child . getAttribute ( "data-slate-string" ) && child . parentElement . getAttribute ( "data-slate-leaf" ) ) {
let newline = child . querySelector ( "br" ) ;
if ( newline ) newline . remove ( ) ;
child . innerHTML = this . spellCheckText ( child . textContent ) ;
if ( newline ) child . appendChild ( newline ) ;
}
2020-06-09 19:42:00 +02:00
}
2020-09-19 20:49:33 +02:00
e . node . parentElement . appendChild ( overlay ) ;
} , 300 ) ;
}
2020-06-09 19:42:00 +02:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
spellCheckText ( string ) {
let htmlString = [ ] ;
string . replace ( /\n/g , "\n " ) . split ( " " ) . forEach ( word => {
let hasNewline = word . endsWith ( "\n" ) ;
word = word . replace ( /\n/g , "" ) ;
htmlString . push ( ` <label class=" ${ this . isWordNotInDictionary ( word ) ? BDFDB . disCN . _spellcheckerror : "" } " style="color: transparent !important; text-shadow: none !important;"> ${ BDFDB . StringUtils . htmlEscape ( word ) } </label> ${ hasNewline ? "\n" : "" } ` ) ;
} ) ;
return htmlString . join ( " " ) . replace ( /\n /g , "\n" ) ;
}
2020-01-15 21:46:41 +01:00
2020-09-19 20:49:33 +02:00
replaceWord ( editor , toBeReplaced , replacement ) {
let editorContainer = BDFDB . ReactUtils . findOwner ( editor , { name : "ChannelEditorContainer" , up : true } ) ;
if ( ! editor || ! editorContainer || ! editorContainer . props || ! editorContainer . props . textValue ) return ;
toBeReplaced = toBeReplaced . toUpperCase ( ) ;
let newString = [ ] ;
editorContainer . props . textValue . replace ( /\n/g , "\n " ) . split ( " " ) . forEach ( word => {
let hasNewline = word . endsWith ( "\n" ) ;
word = word . replace ( /\n/g , "" ) ;
if ( word . toUpperCase ( ) == toBeReplaced ) {
let firstLetter = word . charAt ( 0 ) ;
let isCapitalised = firstLetter . toUpperCase ( ) == firstLetter && firstLetter . toLowerCase ( ) != firstLetter ;
newString . push ( ( isCapitalised ? replacement . charAt ( 0 ) . toUpperCase ( ) + replacement . slice ( 1 ) : replacement ) + ( hasNewline ? "\n" : "" ) ) ;
}
else newString . push ( word + ( hasNewline ? "\n" : "" ) ) ;
} ) ;
editor . setValue ( BDFDB . SlateUtils . copyRichValue ( newString . join ( " " ) . replace ( /\n /g , "\n" ) , editor . props . value ) ) ;
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
addToOwnDictionary ( word ) {
word = word . split ( " " ) [ 0 ] . split ( "\n" ) [ 0 ] . split ( "\r" ) [ 0 ] . split ( "\t" ) [ 0 ] ;
if ( word ) {
let wordLow = word . toLowerCase ( ) ;
if ( languages [ choices . dictionaryLanguage ] ) {
let ownDictionary = BDFDB . DataUtils . load ( this , "owndics" , choices . dictionaryLanguage ) || [ ] ;
if ( ! ownDictionary . includes ( wordLow ) ) {
ownDictionary . push ( wordLow ) ;
BDFDB . DataUtils . save ( ownDictionary , this , "owndics" , choices . dictionaryLanguage ) ;
2020-12-21 19:56:36 +01:00
BDFDB . NotificationUtils . toast ( this . labels . toast _wordadd . replace ( "{{word}}" , word ) . replace ( "{{dicName}}" , this . getLanguageName ( languages [ choices . dictionaryLanguage ] ) ) , { type : "success" } ) ;
2020-09-19 20:49:33 +02:00
dictionaries . dictionaryLanguage = this . formatDictionary ( langDictionaries . dictionaryLanguage . concat ( ownDictionary ) ) ;
}
2020-05-23 10:59:15 +02:00
}
2020-02-20 17:23:49 +01:00
}
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
setDictionary ( key , lang ) {
this . killLanguageToast ( key ) ;
if ( languages [ lang ] ) {
let ownDictionary = BDFDB . DataUtils . load ( this , "owndics" , lang ) || [ ] ;
2020-11-19 16:51:14 +01:00
languageToasts [ key ] = BDFDB . NotificationUtils . toast ( "Grabbing dictionary (" + this . getLanguageName ( languages [ lang ] ) + "). Please wait" , { timeout : 0 } ) ;
2020-09-19 20:49:33 +02:00
languageToasts [ key ] . interval = BDFDB . TimeUtils . interval ( _ => {
languageToasts [ key ] . textContent = languageToasts [ key ] . textContent . indexOf ( "....." ) > - 1 ? "Grabbing dictionary (" + this . getLanguageName ( languages [ lang ] ) + "). Please wait" : languageToasts [ key ] . textContent + "." ;
} , 500 ) ;
languageToasts [ key ] . lang = lang
let folder = BDFDB . LibraryRequires . path . join ( BDFDB . BDUtils . getPluginsFolder ( ) , "dictionaries" ) ;
let filePath = BDFDB . LibraryRequires . path . join ( folder , lang + ".dic" ) ;
let parse = ( error , response , body , download ) => {
this . killLanguageToast ( key ) ;
if ( error || ( response && body . toLowerCase ( ) . indexOf ( "<!doctype html>" ) > - 1 ) ) {
BDFDB . NotificationUtils . toast ( "Failed to grab dictionary (" + this . getLanguageName ( languages [ lang ] ) + ")." , { type : "error" } ) ;
2020-05-25 21:03:56 +02:00
}
2020-09-19 20:49:33 +02:00
else if ( response && languageToasts [ key ] . lang == lang ) {
if ( download ) {
if ( ! BDFDB . LibraryRequires . fs . existsSync ( folder ) ) BDFDB . LibraryRequires . fs . mkdirSync ( folder ) ;
BDFDB . LibraryRequires . fs . writeFile ( filePath , body , _ => { } ) ;
}
langDictionaries [ key ] = body . toLowerCase ( ) . replace ( /\r/g , "" ) . split ( "\n" ) ;
dictionaries [ key ] = this . formatDictionary ( langDictionaries [ key ] . concat ( ownDictionary ) ) ;
BDFDB . NotificationUtils . toast ( "Successfully grabbed dictionary (" + this . getLanguageName ( languages [ lang ] ) + ")." , { type : "success" } ) ;
}
} ;
if ( settings . downloadDictionary && BDFDB . LibraryRequires . fs . existsSync ( filePath ) ) BDFDB . LibraryRequires . fs . readFile ( filePath , ( error , buffer ) => {
parse ( error , buffer , buffer . toString ( ) , false ) ;
} ) ;
else BDFDB . LibraryRequires . request ( "https://mwittrien.github.io/BetterDiscordAddons/Plugins/SpellCheck/dic/" + lang + ".dic" , ( error , response , body ) => {
parse ( error , response , body , settings . downloadDictionary ) ;
} ) ;
}
else {
delete dictionaries [ key ] ;
delete langDictionaries [ key ] ;
}
2020-05-23 10:59:15 +02:00
}
2020-09-19 20:49:33 +02:00
formatDictionary ( words ) {
let i = 0 ;
return words . reduce ( ( dictionary , word ) => {
let firstLetterLower = word . charAt ( 0 ) . toLowerCase ( ) ;
if ( ! dictionary [ firstLetterLower ] ) dictionary [ firstLetterLower ] = { } ;
if ( ! dictionary [ firstLetterLower ] [ word . length ] ) dictionary [ firstLetterLower ] [ word . length ] = [ ] ;
dictionary [ firstLetterLower ] [ word . length ] . push ( word ) ;
return dictionary ;
} , { } ) ;
2020-05-23 10:59:15 +02:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
killLanguageToast ( key ) {
if ( languageToasts [ key ] && typeof languageToasts [ key ] . close == "function" ) {
BDFDB . TimeUtils . clear ( languageToasts [ key ] . interval ) ;
languageToasts [ key ] . close ( ) ;
}
2020-02-20 17:23:49 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
isWordNotInDictionary ( unformatedWord ) {
let wordLow = unformatedWord . toLowerCase ( ) ;
let wordWithoutSymbols = wordLow . replace ( /[0-9\µ\@\$\£\€\¥\¢\²\³\>\<\|\,\;\.\:\-\_\#\+\*\~\?\¿\\\´ \`\}\=\]\)\[\(\{\/\&\%\§\"\!\¡\^\°\n\t\r]/g , "" ) ;
if ( wordLow . indexOf ( "http://" ) != 0 && wordLow . indexOf ( "https://" ) != 0 && wordWithoutSymbols && wordWithoutSymbols . length > wordLow . length / 2 ) {
let wordStartingPos = /^.{1}'/ . test ( wordWithoutSymbols ) ? wordWithoutSymbols . split ( "'" ) [ 1 ] : "" ;
let wordEndingPos = /'.{1}$/ . test ( wordWithoutSymbols ) ? wordWithoutSymbols . split ( "'" ) . reverse ( ) [ 1 ] : "" ;
for ( let key in dictionaries ) for ( let word of BDFDB . ArrayUtils . removeCopies ( [ wordLow , wordWithoutSymbols , wordStartingPos , wordEndingPos ] . filter ( n => n ) ) ) {
let firstLetterLower = word . charAt ( 0 ) ;
if ( dictionaries [ key ] && dictionaries [ key ] [ firstLetterLower ] && dictionaries [ key ] [ firstLetterLower ] [ word . length ] && dictionaries [ key ] [ firstLetterLower ] [ word . length ] . includes ( word ) ) return false ;
}
return true ;
2020-05-23 10:59:15 +02:00
}
2020-09-19 20:49:33 +02:00
return false ;
2020-05-23 10:59:15 +02:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
getSimilarWords ( word ) {
let similarWords = [ ] ;
if ( amounts . maxSimilarAmount > 0 ) {
let firstLetterLower = word . charAt ( 0 ) . toLowerCase ( ) ;
let possibilities = [ ] ;
for ( let key in dictionaries ) if ( dictionaries [ key ] && dictionaries [ key ] [ firstLetterLower ] ) possibilities = possibilities . concat ( BDFDB . ObjectUtils . toArray ( dictionaries [ key ] [ firstLetterLower ] ) . flat ( ) ) ;
possibilities = BDFDB . ArrayUtils . removeCopies ( possibilities ) ;
let similarities = { } ;
for ( let string of possibilities ) {
let value = this . wordSimilarity ( word , string ) ;
if ( ! similarities [ value ] ) similarities [ value ] = [ ] ;
similarities [ value ] . push ( string ) ;
}
let amount = 0 ;
for ( let value of Object . keys ( similarities ) . sort ( ) . reverse ( ) ) {
for ( let similarWord of similarities [ value ] ) {
if ( amount < amounts . maxSimilarAmount && ! similarWords . includes ( similarWord ) ) {
similarWords . push ( similarWord ) ;
amount ++ ;
}
if ( amount >= amounts . maxSimilarAmount ) break ;
2020-02-20 17:23:49 +01:00
}
2020-06-09 19:42:00 +02:00
if ( amount >= amounts . maxSimilarAmount ) break ;
2018-10-11 10:21:26 +02:00
}
}
2020-09-19 20:49:33 +02:00
return similarWords ;
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
wordSimilarity ( a , b ) {
let temp ;
if ( a . length === 0 || b . length === 0 || a . length - b . length > 3 || b . length - a . length > 3 ) return 0 ;
if ( a . length > b . length ) {
temp = a ;
a = b ;
b = temp ;
}
let result = 0 , row = [ ... Array ( a . length + 1 ) . keys ( ) ] ;
for ( let i = 1 ; i <= b . length ; i ++ ) {
result = i ;
for ( let j = 1 ; j <= a . length ; j ++ ) {
temp = row [ j - 1 ] ;
row [ j - 1 ] = result ;
result = b [ i - 1 ] === a [ j - 1 ] ? temp : Math . min ( temp + 1 , Math . min ( result + 1 , row [ j ] + 1 ) ) ;
}
2020-02-20 17:23:49 +01:00
}
2020-09-19 20:49:33 +02:00
return ( b . length - result ) / b . length ;
2020-02-20 17:23:49 +01:00
}
2020-06-09 09:30:21 +02:00
2020-09-19 20:49:33 +02:00
getLanguageName ( language ) {
if ( language . name . startsWith ( "Discord" ) ) return language . name . slice ( 0 , - 1 ) + ( language . ownlang && languages [ language . id ] . name != language . ownlang ? ` / ${ language . ownlang } ` : "" ) + ")" ;
else return language . name + ( language . ownlang && language . name != language . ownlang ? ` / ${ language . ownlang } ` : "" ) ;
2020-02-20 17:23:49 +01:00
}
2020-07-26 17:02:25 +02:00
2021-01-06 12:38:36 +01:00
setLabelsByLanguage ( ) {
2020-09-19 20:49:33 +02:00
switch ( BDFDB . LanguageUtils . getLanguage ( ) . id ) {
2020-12-21 19:56:36 +01:00
case "bg" : // Bulgarian
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Няма подобни думи" ,
context _spellcheck : "Добавяне към речника" ,
toast _wordadd : "Думата '{{word}}' е добавена към речника '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "da" : // Danish
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Ingen lignende ord" ,
context _spellcheck : "Føj til ordbog" ,
toast _wordadd : "Ordet '{{word}}' blev føjet til ordbogen '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "de" : // German
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Keine ähnlichen Wörter" ,
context _spellcheck : "Zum Wörterbuch hinzufügen" ,
toast _wordadd : "Wort '{{word}}' zum Wörterbuch '{{dicName}}' hinzugefügt."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "el" : // Greek
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Δεν υπάρχουν παρόμοιες λέξεις" ,
context _spellcheck : "Προσθήκη στο λεξικό" ,
toast _wordadd : "Προστέθηκε η λέξη '{{word}}' στο λεξικό '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "es" : // Spanish
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "No hay palabras similares" ,
context _spellcheck : "Agregar al diccionario" ,
toast _wordadd : "Se agregó la palabra '{{word}}' al diccionario '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "fi" : // Finnish
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Ei vastaavia sanoja" ,
context _spellcheck : "Lisää sanakirjaan" ,
toast _wordadd : "Sana '{{word}}' lisättiin sanakirjaan '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "fr" : // French
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Pas de mots similaires" ,
context _spellcheck : "Ajouter au dictionnaire" ,
toast _wordadd : "Mot '{{word}}' ajouté au dictionnaire '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "hr" : // Croatian
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Nema sličnih riječi" ,
context _spellcheck : "Dodaj u rječnik" ,
toast _wordadd : "Riječ '{{word}}' dodana je u rječnik '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "hu" : // Hungarian
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Nincsenek hasonló szavak" ,
context _spellcheck : "Hozzáadás a szótárhoz" ,
toast _wordadd : "A '{{word}}' szó hozzáadva a '{{dicName}}' szótárhoz."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "it" : // Italian
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Nessuna parola simile" ,
context _spellcheck : "Aggiungi al dizionario" ,
toast _wordadd : "Parola '{{word}}' aggiunta al dizionario '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "ja" : // Japanese
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "同様の言葉はありません" ,
context _spellcheck : "辞書に追加" ,
toast _wordadd : "単語'{{word}}'が辞書'{{dicName}}'に追加されました。"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "ko" : // Korean
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "유사한 단어 없음" ,
context _spellcheck : "사전에 추가" ,
toast _wordadd : "단어 '{{word}}'이 '{{dicName}}' 사전에 추가되었습니다."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "lt" : // Lithuanian
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Jokių panašių žodžių" ,
context _spellcheck : "Pridėti prie žodyno" ,
toast _wordadd : "Žodis '{{word}}' pridėtas prie žodyno '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "nl" : // Dutch
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Geen vergelijkbare woorden" ,
context _spellcheck : "Toevoegen aan woordenboek" ,
toast _wordadd : "Woord '{{word}}' toegevoegd aan woordenboek '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "no" : // Norwegian
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Ingen lignende ord" ,
context _spellcheck : "Legg til ordbok" ,
toast _wordadd : "Ordet '{{word}}' ble lagt til ordboken '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "pl" : // Polish
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Brak podobnych słów" ,
context _spellcheck : "Dodaj do słownika" ,
toast _wordadd : "Słowo '{{word}}' zostało dodane do słownika '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "pt-BR" : // Portuguese (Brazil)
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Sem palavras semelhantes" ,
context _spellcheck : "Adicionar ao Dicionário" ,
toast _wordadd : "Palavra '{{word}}' adicionada ao dicionário '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "ro" : // Romanian
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Fără cuvinte similare" ,
context _spellcheck : "Adăugați la dicționar" ,
toast _wordadd : "Cuvântul '{{word}}' a fost adăugat în dicționar '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "ru" : // Russian
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Нет похожих слов" ,
context _spellcheck : "Добавить в словарь" ,
toast _wordadd : "Слово '{{word}}' добавлено в словарь '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "sv" : // Swedish
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "Inga liknande ord" ,
context _spellcheck : "Lägg till ordbok" ,
toast _wordadd : "Ordet '{{word}}' har lagts till i ordboken '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "th" : // Thai
2020-09-19 20:49:33 +02:00
return {
2020-12-21 19:56:36 +01:00
context _nosimilarwords : "ไม่มีคำที่คล้ายกัน" ,
context _spellcheck : "เพิ่มในพจนานุกรม" ,
toast _wordadd : "เพิ่มคำ '{{word}}' ในพจนานุกรม '{{dicName}}' แล้ว"
} ;
case "tr" : // Turkish
return {
context _nosimilarwords : "Benzer kelime yok" ,
context _spellcheck : "Sözlüğe Ekle" ,
toast _wordadd : "'{{word}}' kelimesi, '{{dicName}}' sözlüğüne eklendi."
} ;
case "uk" : // Ukrainian
return {
context _nosimilarwords : "Немає подібних слів" ,
context _spellcheck : "Додати до словника" ,
toast _wordadd : "Слово '{{word}}' додано до словника '{{dicName}}'."
} ;
case "vi" : // Vietnamese
return {
context _nosimilarwords : "Không có từ tương tự" ,
context _spellcheck : "Thêm vào từ điển" ,
toast _wordadd : "Đã thêm từ '{{word}}' vào từ điển '{{dicName}}'."
} ;
2021-01-15 17:54:22 +01:00
case "zh-CN" : // Chinese (China)
2020-12-21 19:56:36 +01:00
return {
context _nosimilarwords : "没有类似的词" ,
context _spellcheck : "添加到字典" ,
toast _wordadd : "将单词'{{word}}'添加到字典'{{dicName}}'中。"
} ;
2021-01-15 17:54:22 +01:00
case "zh-TW" : // Chinese (Taiwan)
2020-12-21 19:56:36 +01:00
return {
context _nosimilarwords : "沒有類似的詞" ,
context _spellcheck : "添加到字典" ,
toast _wordadd : "將單詞'{{word}}'添加到字典'{{dicName}}'中。"
} ;
default : // English
return {
context _nosimilarwords : "No similar Words" ,
context _spellcheck : "Add to Dictionary" ,
toast _wordadd : "Word '{{word}}' added to dictionary '{{dicName}}'."
2020-09-19 20:49:33 +02:00
} ;
}
}
} ;
2020-10-09 21:09:35 +02:00
} ) ( window . BDFDB _Global . PluginUtils . buildPlugin ( config ) ) ;
2020-09-25 14:36:36 +02:00
} ) ( ) ;