diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 6a05a2f6..72441cb2 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -18,3 +18,4 @@
//= require moment.min
//= require fullcalendar.min
//= require jquery.multi-select
+//= require emotes
diff --git a/app/views/layouts/_emote_handler.html.erb b/app/views/layouts/_emote_handler.html.erb
new file mode 100644
index 00000000..48f26aae
--- /dev/null
+++ b/app/views/layouts/_emote_handler.html.erb
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index f0a375a2..1a8b07ee 100755
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -16,6 +16,7 @@
<%= render 'layouts/url_helpers' %>
<%= javascript_include_tag "application" %>
<%= javascript_pack_tag "application" %>
+ <%= render 'layouts/emote_handler' %>
<%= csrf_meta_tags %>
diff --git a/vendor/assets/javascripts/emotes.js b/vendor/assets/javascripts/emotes.js
new file mode 100644
index 00000000..9a8867d6
--- /dev/null
+++ b/vendor/assets/javascripts/emotes.js
@@ -0,0 +1,59 @@
+/* Adds selected emotes to all pages.
+ * Allows copy-paste from ABTech Slack
+ *
+ * Usage:
+ * -----
+ * Just use the emotes in any text :blobeyes:
+ */
+
+
+let emotes = {
+ ':party-blob:': 'https://emojis.slackmojis.com/emojis/images/1643514770/7808/party-blob.gif?1643514770',
+ ':blobsob:': 'https://emojis.slackmojis.com/emojis/images/1643514690/6921/blob_sob.png?1643514690',
+ ':blobtoiletspin:': 'https://github.com/thomplinds/custom-slack-emojis/blob/main/images/blobtoiletflush.gif?raw=true',
+ ':blobsad:': 'https://emojis.slackmojis.com/emojis/images/1643514688/6904/blob_sad.png?1643514688',
+ ':blob-spin:': 'https://emojis.slackmojis.com/emojis/images/1643515247/12652/blobspin.png?1643515247',
+ ':blob-go:': 'https://emojis.slackmojis.com/emojis/images/1643514683/6858/blob_go.png?1643514683',
+ ':blob_excited:': 'https://emojis.slackmojis.com/emojis/images/1643514936/9579/blob_excited.gif?1643514936',
+ ':blobeyes:': 'https://emojis.slackmojis.com/emojis/images/1643514682/6848/blob_eyes.png?1643514682',
+ ':blobfearful:': 'https://emojis.slackmojis.com/emojis/images/1643514682/6850/blob_fearful.png?1643514682',
+};
+
+function renderEmoteTags() {
+ for (const [emote_text, url] of Object.entries(emotes)) {
+ let text_nodes = $(`:contains("${emote_text}")`).contents();
+
+ // Filter to text (type 3) nodes that definitely contain it
+ // (:contains doesn't guarantee this: https://stackoverflow.com/a/29418265)
+ text_nodes = text_nodes.filter(function() {
+ return this.nodeType === 3 && this.textContent.indexOf(emote_text) > -1;
+ });
+
+ // replace the emote text with the img
+ text_nodes.replaceWith(function() {
+ return this.nodeValue.replace(RegExp(emote_text, "g"),
+ // .emote-inline doesn't actually do anything
+ // height should end up roughly true line height
+ // alt text shows if image is not found and allows copy-paste
+ `
`
+ );
+ });
+ }
+}
+
+function removeEmoteTags() {
+ for (const [emote_text, url] of Object.entries(emotes)) {
+ let text_nodes = $(`:contains("${emote_text}")`).contents();
+
+ // Filter to text (type 3) nodes that definitely contain it
+ // (:contains doesn't guarantee this: https://stackoverflow.com/a/29418265)
+ text_nodes = text_nodes.filter(function() {
+ return this.nodeType === 3 && this.textContent.indexOf(emote_text) > -1;
+ });
+
+ // remove emote tags
+ text_nodes.replaceWith(function() {
+ return this.nodeValue.replace(RegExp(emote_text, "g"), "");
+ });
+ }
+}