Adds buttons to help you with formatting your comments and managing pictures and emoticons.
// ==UserScript== // @name SteamGifts comment formatting // @description Adds buttons to help you with formatting your comments and managing pictures and emoticons. // @author Bladito // @version 0.7.1 // @homepageURL https://greasyfork.org/en/users/55159-bladito // @match https://www.steamgifts.com/* // @namespace Bladito/sg-comment-formatting // @require http://code.jquery.com/jquery-latest.js // @grant GM_addStyle // ==/UserScript== (function($) { 'use strict'; var storageImage = 'Bladito_sg_comments_images'; var storageEmojis = 'Bladito_sg_comments_emojis'; var commentTextareas = $('textarea[name="description"]'); var targetTextarea; //textarea used for inserting images/emojis var lastRemovedImage, lastRemovedEmoji; if (commentTextareas.length) { enrichJquery(); addStyles(); addControls(); } //-------------------------------------------------------------------------------------------------- function addControls() { addWrappingFormatter('<i class="fa fa-italic"></i>', 'Italics', '*'); addWrappingFormatter('<i class="fa fa-bold"></i>', 'Bold', '**'); addWrappingFormatter('<i class="fa fa-italic"></i><i class="fa fa-bold"></i>', 'Italics and bold', '***'); addWrappingFormatter('<i class="fa fa-low-vision"></i>', 'Spoiler', '~'); addWrappingFormatter('<i class="fa fa-strikethrough"></i>', 'Strike through', '~~'); addEmojis(); addImages(); commentTextareas.on('paste', handlePastedURL); } function addWrappingFormatter(buttonText, title, wrappingCharacters) { var bold = $('<button type="button" class="bsg-formatting-btn" title="' + title + '">' + buttonText + '</button>'); bold.on('click', function() { insertToTextarea($(this).siblings('textarea'), wrappingCharacters, undefined, wrappingCharacters, function(textarea, textSelection) { textarea.bsgSelectRange(textSelection.start + wrappingCharacters.length, textSelection.end + wrappingCharacters.length); }); }); commentTextareas.before(bold); } function addEmojis() { var emojiPopup = $('<div class="bsg-emojis-popup">'+ '<div class="bsg-emojis-undo-area">Emoji removed. <a class="bsg-undo-emoji-btn">Undo</a><i class="bsg-emojis-undo-area-close fa fa-times"></i></div>' + '<div class="bsg-emojis-add-area">' + '<input class="bsg-add-emoji-input" placeholder="Add new Emoji here..."/>' + '<button class="bsg-add-emoji-btn" type="button"><i class="fa fa-plus"></i></button>' + '</div>' + '<div class="bsg-emojis-container"></div></div>'), emojiButton = $('<button type="button" class="bsg-formatting-btn bsg-emojis-dropdown"><i class="fa fa-smile-o"></i></button>'), storedEmojis = getStoredEmojis(); $('body').append(emojiPopup); commentTextareas.before(emojiButton); for (var i=0; i<storedEmojis.length; i+=1) { addEmoji(storedEmojis[i]); } $(document).mouseup(function(e) { if (!emojiPopup.is(e.target) && emojiPopup.has(e.target).length === 0) { emojiPopup.removeClass('m-shown'); } }); $('.bsg-emojis-dropdown').click(function() { var $this = $(this); targetTextarea = $this.siblings('textarea').eq(0); positionAndShowPopup(emojiPopup, $this); }); $('.bsg-add-emoji-input').on('keypress', function(e) { if(e.which === 13){ addNewUserEmoji(); } }); $('.bsg-add-emoji-btn').click(addNewUserEmoji); $('.bsg-undo-emoji-btn').click(undoRemovedEmoji); $('.bsg-emojis-undo-area-close').click(abandonRemovedEmoji); } function addNewUserEmoji() { var addEmojiInput = $('.bsg-add-emoji-input'); var newEmoji = addEmojiInput.val(); if (newEmoji && newEmoji.length > 0) { storeEmoji(newEmoji); addEmoji(newEmoji); addEmojiInput.val(''); $('.bsg-emojis-container').scrollTop($('.bsg-emojis-container')[0].scrollHeight); } } function addEmoji(emojiString) { var emojiPopup = $('.bsg-emojis-popup'), emojiContainer = $('.bsg-emojis-container'), emojiElement = $('<div class="bsg-emoji-wrapper"><span class="bsg-emoji">' + emojiString + '</span></div>'), emojiRemoveButton = $('<span class="bsg-emoji-remove-button"><i class="fa fa-times"></i></span>'); emojiElement.click(function() { insertToTextarea(targetTextarea, '', normalizeEmoji(emojiString), '', function(textarea, textSelection) { textarea.bsgSelectRange(textSelection.start + emojiString.length); }); emojiPopup.toggleClass('m-shown'); }); emojiRemoveButton.click(function(event) { event.stopPropagation(); removeEmoji(emojiRemoveButton.prev().text()); emojiRemoveButton.parent().remove(); $('.bsg-emojis-undo-area').addClass('m-shown'); }); emojiElement.append(emojiRemoveButton); emojiContainer.append(emojiElement); } function addImages() { var imgPopup = $('<div class="bsg-images-popup">' + '<div class="bsg-images-undo-area">Image removed. <a class="bsg-undo-image-btn">Undo</a><i class="bsg-images-undo-area-close fa fa-times"></i></div>' + '<div class="bsg-images-add-area">' + '<input class="bsg-add-image-input" placeholder="Add new Image url here..."/>' + '<button class="bsg-add-image-btn" type="button"><i class="fa fa-plus"></i></button>' + '</div>' + '<div class="bsg-images-container"></div></div>'), imgButton = $('<button type="button" class="bsg-formatting-btn bsg-images-dropdown"><i class="fa fa-picture-o"></i></button>'), storedImages = getStoredImages(); $('body').append(imgPopup); commentTextareas.before(imgButton); for (var i=0; i<storedImages.length; i+=1) { addImage(storedImages[i]); } $(document).mouseup(function(e) { if (!imgPopup.is(e.target) && imgPopup.has(e.target).length === 0) { imgPopup.removeClass('m-shown'); } }); $('.bsg-images-dropdown').click(function() { var $this = $(this); targetTextarea = $this.siblings('textarea').eq(0); positionAndShowPopup(imgPopup, $this); }); $('.bsg-add-image-input').on('keypress', function(e) { if(e.which === 13){ addNewUserImage(); } }); $('.bsg-add-image-btn').click(addNewUserImage); $('.bsg-undo-image-btn').click(undoRemovedImage); $('.bsg-images-undo-area-close').click(abandonRemovedImage); } function addNewUserImage() { var addImageInput = $('.bsg-add-image-input'); var newImage = addImageInput.val(); if (newImage && newImage.length > 0) { storeImage(newImage); addImage(newImage); addImageInput.val(''); $('.bsg-images-container').scrollTop($('.bsg-images-container')[0].scrollHeight); } } function addImage(imageUrl) { var imgPopup = $('.bsg-images-popup'), imgContainer = $('.bsg-images-container'), imgElement = $('<div class="bsg-image-wrapper"><img class="bsg-image" src="' + imageUrl + '"/></div>'), imgRemoveButton = $('<span class="bsg-image-remove-button"><i class="fa fa-times"></i></span>'); imgElement.click(function() { insertToTextarea(targetTextarea, '', function(textarea, textSelection) { textarea.bsgSelectRange(textarea.val().length - imageUrl.length - 3); }, true); imgPopup.toggleClass('m-shown'); }); imgRemoveButton.click(function(event) { event.stopPropagation(); removeImage(imgRemoveButton.prev().attr('src')); imgRemoveButton.parent().remove(); $('.bsg-images-undo-area').addClass('m-shown'); }); imgElement.append(imgRemoveButton); imgContainer.append(imgElement); } function undoRemovedImage() { if (lastRemovedImage) { //TODO insert it in correct position (lastRemovedImage.index) storeImage(lastRemovedImage.url); addImage(lastRemovedImage.url); abandonRemovedImage(); } } function abandonRemovedImage() { $('.bsg-images-undo-area').removeClass('m-shown'); lastRemovedImage = undefined; } function undoRemovedEmoji() { if (lastRemovedEmoji) { //TODO insert it in correct position (lastRemovedEmoji.index) storeEmoji(lastRemovedEmoji.text); addEmoji(lastRemovedEmoji.text); abandonRemovedEmoji(); } } function abandonRemovedEmoji() { $('.bsg-emojis-undo-area').removeClass('m-shown'); lastRemovedEmoji = undefined; } function positionAndShowPopup(popupElement, triggerElement) { var buttonWidth = 22, left = triggerElement.offset().left + buttonWidth; if (left + popupElement.width() > document.documentElement.clientWidth) { left = left - buttonWidth - popupElement.width(); } popupElement.toggleClass('m-shown'); popupElement.css({ 'top': triggerElement.offset().top - 306, 'left': left }); } function handlePastedURL(e) { var preChars = '[](', textArea = $(e.target), pastedData = (e.originalEvent || e).clipboardData.getData('text/plain'); if (pastedData && /^https?:\/\/(?:[a-z0-9\-]+\.)+[a-z]{2,6}(?:\/[^/#?]+)+/i.test(pastedData)) { isValidImageUrl(pastedData, function(isImage) { if (isImage) { preChars = '!' + preChars; storeImage(pastedData); addImage(pastedData); } insertToTextarea(textArea, preChars, pastedData, ')', function(textarea, textSelection) { textarea.bsgSelectRange(textSelection.start + (preChars.length === 3 ? 1 : 2)); }); }); e.stopPropagation(); e.preventDefault(); } function isValidImageUrl(url, callback) { var img = new Image(); img.onerror = function() { callback(false); }; img.onload = function() { callback(true); }; img.src = url; } } function insertToTextarea(commentTextarea, preChars, textBetween, postChars, callback, pasteAtEnd) { var newText, text = commentTextarea.val(), textSelection = commentTextarea.bsgGetSelection(), insertion = preChars + (textBetween || textSelection.text) + postChars; if (pasteAtEnd) { newText = (text.length ? (text + '\n') : '') + insertion; } else { newText = text.slice(0,textSelection.start) + insertion + text.slice(textSelection.end); } commentTextarea.val(newText); if (callback) { callback(commentTextarea, textSelection); } } function normalizeEmoji(emojiString) { return emojiString.replace(/\\/g, '\\\\').replace(/_/g, '\\_'); } function enrichJquery() { $.fn.bsgSelectRange = function(start, end) { if(end === undefined) { end = start; } return this.each(function() { this.focus(); if('selectionStart' in this) { this.selectionStart = start; this.selectionEnd = end; } else if(this.setSelectionRange) { this.setSelectionRange(start, end); } else if(this.createTextRange) { var range = this.createTextRange(); range.collapse(true); range.moveEnd('character', end); range.moveStart('character', start); range.select(); } }); }; //copied from https://github.com/localhost/jquery-fieldselection/blob/master/jquery-fieldselection.js $.fn.bsgGetSelection = function() { var e = (this.jquery) ? this[0] : this; return ( /* mozilla / dom 3.0 */ ('selectionStart' in e && function() { var l = e.selectionEnd - e.selectionStart; return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) }; }) || /* exploder */ (document.selection && function() { e.focus(); var r = document.selection.createRange(); if (r === null) { return { start: 0, end: e.value.length, length: 0 }; } var re = e.createTextRange(); var rc = re.duplicate(); re.moveToBookmark(r.getBookmark()); rc.setEndPoint('EndToStart', re); return { start: rc.text.length, end: rc.text.length + r.text.length, length: r.text.length, text: r.text }; }) || /* browser not supported */ function() { return null; } )(); }; } function storeImage(url) { var images = getStoredImages(); images.push(url); localStorage.setItem(storageImage, JSON.stringify(images)); } function removeImage(url) { var images = getStoredImages(), index = images.indexOf(url); images.splice(index, 1); lastRemovedImage = {index: index, url: url}; localStorage.setItem(storageImage, JSON.stringify(images)); } function getStoredImages() { return JSON.parse(localStorage.getItem(storageImage)) || defaultImages(); } function storeEmoji(emojiString) { var emojis = getStoredEmojis(); emojis.push(emojiString); localStorage.setItem(storageEmojis, JSON.stringify(emojis)); } function removeEmoji(emojiString) { var emojis = getStoredEmojis(), index = emojis.indexOf(emojiString); emojis.splice(index, 1); lastRemovedEmoji = {index: index, text: emojiString}; localStorage.setItem(storageEmojis, JSON.stringify(emojis)); } function getStoredEmojis() { return JSON.parse(localStorage.getItem(storageEmojis)) || defaultEmojis(); } function defaultImages() { return [ 'https://i.imgflip.com/cnudu.jpg', 'https://s-media-cache-ak0.pinimg.com/564x/9c/76/1f/9c761ffd187eef6e11e28188a6ff7075.jpg', 'http://webtrax.hu/myfacewhen/faces/animals/kitty-facepalm.jpg', 'http://www.getcatnipdaily.com/wp-content/uploads/sites/713/2015/05/4Kitty-barlow-250x200.jpg', 'http://i24.photobucket.com/albums/c12/InkBlotPsycho/Cats/KITTY_crazy.jpg', 'https://femmolitical.files.wordpress.com/2013/03/shocked-cat.jpg', 'http://sadcatdiary.com/wp-content/uploads/2015/07/sadcatsmall.jpg' ]; } function defaultEmojis() { return [ '¯\\_(ツ)_/¯', '( ͡° ͜ʖ ͡°)', '( ͡⊙ ͜ʖ ͡⊙)', '(ノಠ益ಠ)ノ', '(╯°□°)╯︵ ┻━┻', '┬─┬ノ( º _ ºノ)', 'ლ(ಠ益ಠლ)', '(◕‿-)✌', '(。◕‿◕。)', '(◑‿◐)', '◔_◔', '(•‿•)', '(ಠ_ಠ)', '(¬、¬)', '(─‿‿─)', '(ಥ﹏ಥ)', '(ಥ‸ಥ)', '(⌐■_■)', '(▰˘◡˘▰)', '乁( ◔ ౪◔)ㄏ', '(ง ͠° ͟ʖ ͡°)ง', 'ζ༼Ɵ͆ل͜Ɵ͆༽ᶘ', 'ʕ•ᴥ•ʔ', '( ͝° ͜ʖ͡°)', '(/゚Д゚)/', '୧༼ಠ益ಠ༽୨', '(ง •̀_•́)ง' ]; } function addStyles() { GM_addStyle('.bsg-formatting-btn { ' + 'display: inline-block;' + 'margin: 1px;' + 'border: 1px solid #d6d6d6;' + 'cursor: pointer;' + 'text-align: center;' + 'border-radius: 4px;' + 'background-color: #f3f3f3;' + 'background-image: none;' + 'color: #757575;' + 'min-width: 22px;' + 'height: 22px;' + '}'); GM_addStyle('.bsg-formatting-btn:hover {' + 'border-color: #B9D393 #96BC69 #73A442 #A0C870;' + 'background-image: linear-gradient(#cef2aa 0%, #b4e08a 50%, #9AC96A 100%);' + 'background-image: -moz-linear-gradient(#cef2aa 0%, #b4e08a 50%, #9AC96A 100%);' + 'background-image: -webkit-linear-gradient(#cef2aa 0%, #b4e08a 50%, #9AC96A 100%);' + '}'); GM_addStyle('.bsg-formatting-btn.bsg-emojis-dropdown, .bsg-formatting-btn.bsg-images-dropdown {' + 'float: right;' + '}'); GM_addStyle('.bsg-images-popup {' + 'display: none;' + 'position: absolute;' + 'width: 317px;' + 'height: 500px;' + '}'); GM_addStyle('.bsg-images-container {' + 'font-size: 0;' + 'overflow-y: auto;' + 'height: 450px;' + 'background: repeating-linear-gradient(-55deg,#222,#222 10px,#333 10px,#333 20px);' + '}'); GM_addStyle('.bsg-emojis-popup {' + 'display: none;' + 'position: absolute;' + 'height: 470px;' + 'min-width: 160px;' + 'max-width: 320px;' + 'color: black;' + '}'); GM_addStyle('.bsg-emojis-container {' + 'overflow-y: auto;' + 'height: 420px;' + 'background: repeating-linear-gradient(-55deg,#222,#222 10px,#333 10px,#333 20px);' + '}'); GM_addStyle('.bsg-emoji-wrapper {' + 'position: relative;' + 'display: block;' + 'margin: 0;' + 'padding: 5px;' + 'background: #fff;' + 'cursor: pointer;' + 'overflow: hidden;' + 'min-height: 17px;' + 'text-align: center;' + '}'); GM_addStyle('.bsg-emoji-wrapper:hover {' + 'background: #e8eeff;' + '}'); GM_addStyle('.bsg-emoji-wrapper:hover .bsg-emoji-remove-button {' + 'display: block;' + '}'); GM_addStyle('.bsg-emojis-add-area, .bsg-images-add-area {' + 'display: flex;' + '}'); GM_addStyle('input.bsg-add-emoji-input, input.bsg-add-image-input {' + 'border-left-width: 0;' + 'border-right-width: 0;' + 'border-radius: 0;' + 'flex: 1' + '}'); GM_addStyle('.bsg-add-emoji-btn, .bsg-add-image-btn {' + 'cursor: pointer;' + 'width: 17px;' + 'color: #545454;' + 'background-color: #dddddd;' + '}'); GM_addStyle('.bsg-add-emoji-btn:hover, .bsg-add-image-btn:hover {' + 'border-color: #B9D393 #96BC69 #73A442 #A0C870;' + 'background-image: linear-gradient(#cef2aa 0%, #b4e08a 50%, #9AC96A 100%);' + 'background-image: -moz-linear-gradient(#cef2aa 0%, #b4e08a 50%, #9AC96A 100%);' + 'background-image: -webkit-linear-gradient(#cef2aa 0%, #b4e08a 50%, #9AC96A 100%);' + '}'); GM_addStyle('.bsg-images-popup.m-shown, .bsg-emojis-popup.m-shown {' + 'display: block;' + '}'); GM_addStyle('.bsg-image-wrapper {' + 'cursor: pointer;' + 'position: relative;' + 'display: inline-block;' + 'width: 150px;' + 'height: 150px;' + 'margin: 0;' + 'padding: 0;' + 'background: #fff;' + 'overflow: hidden;' + '}'); GM_addStyle('.bsg-image-wrapper:hover .bsg-image-remove-button {' + 'display: block;' + '}'); GM_addStyle('.bsg-image {' + 'width: 150px;' + 'height: 150px;' + '-webkit-transform: scale(1);' + 'transform: scale(1);' + '-webkit-transition: .3s ease-in-out;' + 'transition: .3s ease-in-out;' + '}'); GM_addStyle('.bsg-images-undo-area, .bsg-emojis-undo-area {' + 'opacity: 0;' + 'background-color: #ffd5d5;' + 'height: 20px;' + 'line-height: 20px;' + 'padding-left: 5px;' + 'padding-right: 5px;' + '}'); GM_addStyle('.bsg-images-undo-area.m-shown, .bsg-emojis-undo-area.m-shown {' + 'opacity: 1;' + '}'); GM_addStyle('.bsg-undo-image-btn, .bsg-undo-emoji-btn {' + 'cursor: pointer;' + 'text-decoration: underline;' + '}'); GM_addStyle('.bsg-images-undo-area-close, .bsg-emojis-undo-area-close {' + 'cursor: pointer;' + 'float: right;' + 'top: 2px;' + 'position: relative;' + '}'); GM_addStyle('.bsg-image-remove-button, .bsg-emoji-remove-button {' + 'display: none;' + 'position: absolute;' + 'right: 5px;' + 'top: 5px;' + 'color: black' + '}'); GM_addStyle('.bsg-image-remove-button > .fa {' + 'font-size: 20px;' + '}'); GM_addStyle('.bsg-emoji-remove-button > .fa {' + 'font-size: 15px;' + 'color: #b7b7b7;' + '}'); GM_addStyle('.bsg-image-remove-button:hover > .fa, .bsg-emoji-remove-button:hover > .fa {' + 'color: red' + '}'); GM_addStyle('.bsg-image-wrapper:hover .bsg-image {' + 'height: 150px;' + '-webkit-transform: scale(1.3);' + 'transform: scale(1.3);' + '}'); } })(jQuery);