Skip to content

Commit

Permalink
Added Emoji encoder enhancement for postBox
Browse files Browse the repository at this point in the history
  • Loading branch information
WombatFromHell committed Jul 3, 2019
1 parent 241f36f commit 6406ec3
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 36 deletions.
43 changes: 17 additions & 26 deletions common.js
Expand Up @@ -229,22 +229,14 @@ function getCookieValue(name, defaultValue)
return ret;
}

function removeUtf16SurrogatePairs(str) {
// shacknews doesn't support these and will remove them without counting them towards the post preview limit
// https://stackoverflow.com/a/22664154
return str.replace(/([\uD800-\uDBFF][\uDC00-\uDFFF])/g, '');
}

function generatePreview(text) {
var preview = removeUtf16SurrogatePairs(text);

function generatePreview(postText) {
// simple replacements
preview = preview.replace(/&/g, "&");
preview = preview.replace(/</g, "&lt;");
preview = preview.replace(/>/g, "&gt;");
preview = preview.replace(/\r\n/g, "<br>");
preview = preview.replace(/\n/g, "<br>");
preview = preview.replace(/\r/g, "<br>");
//postText = postText.replace(/&/g, "&amp;"); // breaks Astral encoding
postText = postText.replace(/</g, "&lt;");
postText = postText.replace(/>/g, "&gt;");
postText = postText.replace(/\r\n/g, "<br>");
postText = postText.replace(/\n/g, "<br>");
postText = postText.replace(/\r/g, "<br>");

var complexReplacements = {
'red': {'from': ['r{','}r'], 'to': ['<span class="jt_red">','</span>']},
Expand All @@ -268,11 +260,11 @@ function generatePreview(text) {
};

// replace matching pairs first
for(var ix in complexReplacements) {
if(complexReplacements.hasOwnProperty(ix)) {
for (var ix in complexReplacements) {
if (complexReplacements.hasOwnProperty(ix)) {
var rgx = new RegExp(complexReplacements[ix].from[0] + '(.*?)' + complexReplacements[ix].from[1], 'g');
while(preview.match(rgx) !== null) {
preview = preview.replace(rgx, complexReplacements[ix].to[0] + '$1' + complexReplacements[ix].to[1]);
while (postText.match(rgx) !== null) {
postText = postText.replace(rgx, complexReplacements[ix].to[0] + '$1' + complexReplacements[ix].to[1]);
}
}
}
Expand All @@ -281,17 +273,16 @@ function generatePreview(text) {
// this still has (at least) one bug, the shack code does care about nested tag order:
// b[g{bold and green}g]b <-- correct
// b[g{bold and green]b}g <-- }g is not parsed by the shack code
for(var ix in complexReplacements) {
if(complexReplacements.hasOwnProperty(ix)) {
for (var ix in complexReplacements) {
if (complexReplacements.hasOwnProperty(ix)) {
var rgx = new RegExp(complexReplacements[ix].from[0], 'g');
while(preview.match(rgx) !== null) {
preview = preview.replace(rgx, complexReplacements[ix].to[0]);
preview = preview + complexReplacements[ix].to[1];
while (postText.match(rgx) !== null) {
postText = postText.replace(rgx, complexReplacements[ix].to[0]);
postText = postText + complexReplacements[ix].to[1];
}
}
}

return convertUrlToLink(preview);
return convertUrlToLink(postText);
}

function debounce(cb, delay)
Expand Down
3 changes: 2 additions & 1 deletion manifest.json
Expand Up @@ -61,7 +61,8 @@
"scripts/options_link.js",
"scripts/post_length_counter.js",
"scripts/thread_pane.js",
"scripts/post_style.js"
"scripts/post_style.js",
"scripts/emoji_poster.js"
],
"css": [
"styles/chromeshack.css",
Expand Down
1 change: 1 addition & 0 deletions release_notes.html
Expand Up @@ -10,6 +10,7 @@
<h1>Chrome Shack Release Notes</h1>
<h2>Version 1.62</h2>
<ul>
<li>Added: Emoji's entered on the reply box are now properly encoded (WombatFromHell)</li>
<li>Removed: ChattyPics support in Image Uploader - now defaults to Imgur (WombatFromHell)</li>
<li>Changed: All embedding scripts now use strong sanitization for improved security (WombatFromHell)</li>
<li>Changed: Shack message envelope icon is no longer hidden (WombatFromHell)</li>
Expand Down
86 changes: 86 additions & 0 deletions scripts/emoji_poster.js
@@ -0,0 +1,86 @@
settingsLoadedEvent.addHandler(function() {
/*
* Encodes string Astrals (Emoji's) into prefixed HTML entities to
* workaround Chatty's poor support for unicode surrogate pairs.
*/
EmojiPoster = {
install: function(postBox) {
// install only once per postbox
let _postBtn = postBox.querySelector("button#frm_submit");
if (!_postBtn.hasAttribute("cloned")) {
// remove all events on the 'Post' button so we can intercept submission
let _clonedPostBtn = _postBtn.cloneNode(true);
_clonedPostBtn.removeAttribute("onclick");
_clonedPostBtn.setAttribute("cloned", "");
_postBtn.parentNode.replaceChild(_clonedPostBtn, _postBtn);

// monkeypatch the submit and click events
[ "click", "submit" ].forEach(evt => {
document.addEventListener(evt, (e) => {
if (e.target.matches("#frm_submit")) {
// block any remaining attached listeners
e.preventDefault();
e.stopImmediatePropagation();
//console.log("EmojiPoster redirected submit event");
let _postBox = document.getElementById("frm_body");
if (_postBox && _postBox.value.length > 0) {
_postBox.value = EmojiPoster.handleEncoding(_postBox.value);
EmojiPoster.handleSubmit(_postBox.value);
}
}
}, true);
});

// educate the user on how to open the OS' Emoji Picker
let _postFormParent = postBox.querySelector("#postform fieldset");
let _emojiTaglineElem = document.createElement("p");
_emojiTaglineElem.setAttribute("class", "emoji-tagline");
_emojiTaglineElem.innerHTML = "Use <span>Win + ;</span> (Windows) or <span>Cmd + Ctrl + Space</span> (MacOS) to bring up the OS Emoji Picker.";
_postFormParent.appendChild(_emojiTaglineElem);
}
},

handleSubmit: function(postText) {
if (EmojiPoster.countEntities(postText) > 5) {
// normal post
$('#frm_submit').attr('disabled', 'disabled').css('color', '#E9E9DE');
$('#postform').submit();
$('body').trigger(
'chatty-new-post-reply',
[ ($('#frm_submit').closest('div.root > ul > li').first().attr('id')) ]
);
return false;
} else {
// the server doesn't know that an astral is a single character
alert("Please post something at least 5 characters long.");
}
},

handleEncoding: function(text) {
// see: https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
// credit: Mathias Bynens (https://github.com/mathiasbynens/he)
let _matchAstrals = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
let _matchBMPs = /[\x01-\t\x0B\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g;
let escapeBmp = symbol => escapeCodePoint(symbol.charCodeAt(0));
let escapeCP = codePoint => `&#x${codePoint.toString(16).toUpperCase()};`;
return text.replace(_matchAstrals, $0 => {
let _high = $0.charCodeAt(0);
let _low = $0.charCodeAt(1);
let _cp = (_high - 0xd800) * 0x400 + _low - 0xdc00 + 0x10000;
return escapeCP(_cp);
}).replace(_matchBMPs, escapeBmp);
},

countEntities: function(text) {
// sums to the real length of text containing astrals
let _astrals = text.match(/(&#x[A-Fa-f0-9]+;)/igm);
let _astralsLen = _astrals ? _astrals.reduce((t, v) => t + v.length, 0) : 0;
let _count = _astrals ?
(text.length - _astralsLen + _astrals.length) :
text.length;
return _count;
}
};

processPostBoxEvent.addHandler(EmojiPoster.install);
});
17 changes: 8 additions & 9 deletions scripts/media_helpers.js
Expand Up @@ -238,7 +238,7 @@ function appendMedia(src, link, postId, index, container, overrides) {
* Misc. Functions
*/

function insertScript(elem, { filePath, code }, id, overwrite) {
function insertScript({ elem, filePath, code, id, overwrite}) {
// insert a script that executes synchronously (caution!)
var _elem = elem ? elem : document.getElementsByTagName("head")[0];
var _script = document.getElementById(id);
Expand All @@ -249,7 +249,7 @@ function insertScript(elem, { filePath, code }, id, overwrite) {
if (code && code.length > 0)
_script.textContent = code;
else if (filePath && filePath.length > 0)
_script.setAttribute("src", filePath);
_script.setAttribute("src", browser.runtime.getURL(filePath));
else
throw Error("Must pass a file path or code content in string format!");
_elem.appendChild(_script);
Expand Down Expand Up @@ -377,12 +377,11 @@ function attachChildEvents(elem, id, index) {
function triggerReflow(elem) {
$(elem).ready(function() {
// trigger a resize via jQuery ready() to recalc the carousel
var body = document.getElementsByTagName("body")[0];
insertScript(
body,
{ code: "window.dispatchEvent(new Event('resize'));" },
"reflow-wjs",
true
);
insertScript({
url: document.getElementsByTagName("body")[0],
code: "window.dispatchEvent(new Event('resize'));",
id: "reflow-wjs",
overwrite: true
});
});
}
14 changes: 14 additions & 0 deletions styles/chromeshack.css
Expand Up @@ -404,3 +404,17 @@ div.article-chatty span.lol-tags {
div.read-only-tags {
height: 1px;
}

/* emoji tagline on the postbox form */
#postform fieldset p.emoji-tagline {
display: flex !important;
justify-content: center !important;
align-items: center !important;
font-size: 12px;
margin: 0 !important;
}
p.emoji-tagline > span {
font-weight: bold;
font-style: italic;
padding: 0 0.5em 0 0.5em;
}

0 comments on commit 6406ec3

Please sign in to comment.