Twit box
by Sasá Rafalsky
HTML
<!-- Contenteditable-->
<div class="tweet-box">
<div class="placeholder" id="tweet_highlights"></div>
<div id="tweet" contenteditable="true"></div>
<div class="tweet_action">
<div id="tweet_chars"></div>
<button id="tweet_btn" onclick="createPost()" disabled="disabled">Post</button>
</div>
</div>
CSS
*{
box-sizing: border-box;
font-family: sans-serif;
}
.tweet-box{
padding: 0;
max-width: 590px;
margin: 0 auto;
border-radius: 8px;
position: relative;
}
#tweet_highlights{
position: absolute;
width: calc(100% - 20px);
padding: 13px 9px;
font-size: 16px;
color: transparent;
overflow: hidden;
white-space: pre-wrap;
pointer-events: none;
}
#tweet_highlights.placeholder
{
color: #afafaf;
}
#tweet
{
padding: 12px 8px;
width: 100%;
min-height: 100px;
border-radius: 8px;
background-color: #f5f5f5;
border: 1px solid #afafaf;
font-size: 16px;
margin-bottom: 10px;
overflow: hidden;
white-space: pre-wrap;
}
@media (min-width: 560px)
{
.tweet-box
{
padding: 40px;
}
#tweet_highlights
{
width: calc(100% - 80px);
}
}
.link
{
background-color: rgba(245, 245, 245, 0.35);
color: #1c94e0;
}
.danger
{
background-color: rgba(255, 0, 0, 0.25);
}
.danger .link
{
background: transparent;
}
.tweet_action
{
text-align: right;
}
#tweet_chars
{
display: inline-block;
text-align: right;
line-height: 20px;
margin-right: 8px;
color: #657786;
}
#tweet_chars.warning
{
color: red;
}
#tweet_btn
{
display: inline-block;
width: 75px;
border-radius: 0;
font-size: 14px;
font-weight: bold;
line-height: 20px;
padding: 6px 16px;
text-align: center;
box-shadow: none;
cursor: pointer;
}
#tweet_btn:hover
{
background-color: #006dbf;
border: 1px solid #006dbf;
}
#tweet_btn:disabled
{
opacity: 0.45;
}
JavaScript
const maxTweetLength = 280;
const urlLength = 23;
const placeholder = "What's happening?";
const urlRegex = /(http|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?/g;
var overLimit = false;
var diff = 0;
var virtualMaxTweetLength = maxTweetLength;
var tweet = document.getElementById('tweet');
var highlighter = document.getElementById('tweet_highlights');
var tweetChars = document.getElementById('tweet_chars');
var tweetBtn = document.getElementById('tweet_btn');
tweet.addEventListener('input', refresh);
tweet.addEventListener('keydown', refresh);
tweetChars.innerHTML = maxTweetLength;
highlighter.innerHTML = placeholder;
function refresh(){
diff = calcChars();
tweetChars.innerHTML = diff;
handleStates(diff);
parseTweet();
handlePlaceholder(diff);
}
function calcChars(){
var charCount = tweet.innerText.length;
var urls = tweet.innerText.match(urlRegex);
var alter = 0;
virtualMaxTweetLength = maxTweetLength;
if(urls){
var totalUrls = 0;
alter = urlLength * urls.length;
for(var i in urls)
totalUrls += urls[i].length;
charCount = (tweet.innerText.length - totalUrls) + alter;
virtualMaxTweetLength = (maxTweetLength - alter) + totalUrls;
}
return maxTweetLength - charCount;
}
function handleStates(diff){
if(diff<0){
overLimit = true;
tweetChars.className = 'warning';
} else if(diff>=0) {
overLimit = false;
tweetChars.className = '';
}
if(diff < 0 || diff == maxTweetLength)
tweetBtn.disabled = true;
else
tweetBtn.disabled = false;
}
function handlePlaceholder(diff){
if(diff == maxTweetLength) {
highlighter.innerHTML = placeholder;
highlighter.className = 'placeholder';
} else {
highlighter.className = '';
}
}
function parseTweet(){
var str = tweet.innerText;
//str = str.replace(/</g,...