From e6655219ee84f4be1e9e1c07e7fbdfb5626a4841 Mon Sep 17 00:00:00 2001
From: chylex <contact@chylex.com>
Date: Sun, 29 Oct 2017 04:39:28 +0100
Subject: [PATCH] Add a context menu item to apply ROT13 to text selection in
 inputs

---
 Core/FormBrowser.cs                 |  4 ++++
 Core/Handling/ContextMenuBrowser.cs | 10 ++++++++++
 Core/TweetDeckBrowser.cs            |  4 ++++
 Resources/Scripts/code.js           | 17 +++++++++++++++++
 4 files changed, 35 insertions(+)

diff --git a/Core/FormBrowser.cs b/Core/FormBrowser.cs
index a86c1ba4..e71dd53e 100644
--- a/Core/FormBrowser.cs
+++ b/Core/FormBrowser.cs
@@ -321,6 +321,10 @@ public void TriggerTweetScreenshot(){
             browser.TriggerTweetScreenshot();
         }
 
+        public void ApplyROT13(){
+            browser.ApplyROT13();
+        }
+
         // callback handlers
         
         public void OnIntroductionClosed(bool showGuide, bool allowDataCollection){
diff --git a/Core/Handling/ContextMenuBrowser.cs b/Core/Handling/ContextMenuBrowser.cs
index 66f69730..25e4b5e4 100644
--- a/Core/Handling/ContextMenuBrowser.cs
+++ b/Core/Handling/ContextMenuBrowser.cs
@@ -17,6 +17,7 @@ sealed class ContextMenuBrowser : ContextMenuBase{
         private const CefMenuCommand MenuOpenQuotedTweetUrl = (CefMenuCommand)26612;
         private const CefMenuCommand MenuCopyQuotedTweetUrl = (CefMenuCommand)26613;
         private const CefMenuCommand MenuScreenshotTweet    = (CefMenuCommand)26614;
+        private const CefMenuCommand MenuInputApplyROT13    = (CefMenuCommand)26615;
 
         private const string TitleReloadBrowser = "Reload browser";
         private const string TitleMuteNotifications = "Mute notifications";
@@ -41,6 +42,11 @@ public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser br
             RemoveSeparatorIfLast(model);
 
             if (parameters.TypeFlags.HasFlag(ContextMenuType.Selection)){
+                if (parameters.TypeFlags.HasFlag(ContextMenuType.Editable)){
+                    model.AddSeparator();
+                    model.AddItem(MenuInputApplyROT13, "Apply ROT13");
+                }
+
                 model.AddSeparator();
             }
 
@@ -136,6 +142,10 @@ public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser b
                 case MenuCopyQuotedTweetUrl:
                     SetClipboardText(form, lastHighlightedQuoteUrl);
                     return true;
+
+                case MenuInputApplyROT13:
+                    form.InvokeAsyncSafe(form.ApplyROT13);
+                    return true;
             }
 
             return false;
diff --git a/Core/TweetDeckBrowser.cs b/Core/TweetDeckBrowser.cs
index ba60a11b..012af918 100644
--- a/Core/TweetDeckBrowser.cs
+++ b/Core/TweetDeckBrowser.cs
@@ -226,5 +226,9 @@ public void ShowTweetDetail(string columnId, string chirpId, string fallbackUrl)
         public void TriggerTweetScreenshot(){
             browser.ExecuteScriptAsync("TDGF_triggerScreenshot()");
         }
+
+        public void ApplyROT13(){
+            browser.ExecuteScriptAsync("TDGF_applyROT13()");
+        }
     }
 }
diff --git a/Resources/Scripts/code.js b/Resources/Scripts/code.js
index d8888d34..5878d553 100644
--- a/Resources/Scripts/code.js
+++ b/Resources/Scripts/code.js
@@ -1072,6 +1072,23 @@
     }
   });
   
+  //
+  // Block: Allow applying ROT13 to input selection.
+  //
+  window.TDGF_applyROT13 = function(){
+    let ele = document.activeElement;
+    return if !ele || !ele.value;
+    
+    let selection = ele.value.substring(ele.selectionStart, ele.selectionEnd);
+    return if !selection;
+    
+    document.execCommand("insertText", false, selection.replace(/[a-zA-Z]/g, function(chr){
+      let code = chr.charCodeAt(0);
+      let start = code <= 90 ? 65 : 97;
+      return String.fromCharCode(start+(code-start+13)%26);
+    }));
+  };
+  
   //
   // Block: Fix DM reply input box not getting focused after opening a conversation.
   //