/*jshint bitwise:true, curly:true, devel:true, eqeqeq:true, evil:true, forin:false, noarg:true, noempty:true, nonew:true, undef:true, strict:false, browser:true, jquery:true */ String.prototype.sReplace = function(find, replace) { return this.split(find).join(replace); }; String.prototype.repeat = function(times) { var rep = new Array(times + 1); return rep.join(this); }; var YShout = function() { var self = this; var args = arguments; $(document).ready(function() { self.init.apply(self, args); }); }; var yShout; YShout.prototype = { animSpeed: 300, p: [], init: function(options) { yShout = this; var self = this; this.initializing = true; var dOptions = { yPath: 'yshout/', log: 1 }; this.options = jQuery.extend(dOptions, options); this.postNum = 0; this.floodAttempt = 0; // Correct for missing trailing / if ((this.options.yPath.length > 0) && (this.options.yPath.charAt(this.options.yPath.length - 1) !== '/')) { this.options.yPath += '/'; } if (this.options.yLink) { if (this.options.yLink.charAt(0) !== '#') { this.options.yLink = '#' + this.options.yLink; } $(this.options.yLink).click(function() { self.openYShout.apply(self); return false; }); } // Load YShout from a link, in-page if (this.options.h_loadlink) { $(this.options.h_loadlink).click(function() { $('#yshout').css('display', 'block'); $(this).unbind('click').click(function() { return false; }); return false; }); this.load(true); } else { this.load(); } }, load: function(hidden) { if ($('#yshout').length === 0) { return; } if (hidden) { $('#yshout').css('display', 'none'); } this.ajax(this.initialLoad, { reqType: 'init', yPath: this.options.yPath, log: this.options.log }); }, initialLoad: function(updates) { if (updates.yError) { alert('There appears to be a problem: \n' + updates.yError + '\n\nIf you haven\'t already, try chmodding everything inside the YShout directory to 777.'); } var self = this; this.prefs = jQuery.extend(updates.prefs, this.options.prefs); this.initForm(); this.initRefresh(); this.initLinks(); if (this.prefs.flood) { this.initFlood(); } if (updates.nickname) { $('#ys-input-nickname') .removeClass('ys-before-focus') .addClass( 'ys-after-focus') .val(updates.nickname); } if (updates) { this.updates(updates); } if (!this.prefs.doTruncate) { $('#ys-posts').css('height', $('#ys-posts').height + 'px'); } if (!this.prefs.inverse) { var postsDiv = $('#ys-posts')[0]; postsDiv.scrollTop = postsDiv.scrollHeight; } this.markEnds(); this.initializing = false; }, initForm: function() { this.d('In initForm'); var postForm = '
'; var postsDiv = ''; if (this.prefs.inverse) { $('#yshout').html(postForm + postsDiv); } else { $('#yshout').html(postsDiv + postForm); } $('#ys-posts') .before('') .after(''); $('#ys-post-form') .before('') .after(''); var self = this; var defaults = { 'ys-input-nickname': self.prefs.defaultNickname, 'ys-input-message': self.prefs.defaultMessage }; var keypress = function(e) { var key = window.event ? e.keyCode : e.which; if (key === 13 || key === 3) { self.send.apply(self); return false; } }; var focus = function() { if (this.value === defaults[this.id]) { $(this).removeClass('ys-before-focus').addClass( 'ys-after-focus').val(''); } }; var blur = function() { if (this.value === '') { $(this).removeClass('ys-after-focus').addClass('ys-before-focus').val(defaults[this.id]); } }; $('#ys-input-message').keypress(keypress).focus(focus).blur(blur); $('#ys-input-nickname').keypress(keypress).focus(focus).blur(blur); $('#ys-input-submit').click(function(){ self.send.apply(self); }); $('#ys-post-form').submit(function(){ return false; }); }, initRefresh: function() { var self = this; if (this.refreshTimer) { clearInterval(this.refreshTimer); } this.refreshTimer = setInterval(function() { self.ajax(self.updates, { reqType: 'refresh' }); }, this.prefs.refresh); // ! 3000..? }, initFlood: function() { this.d('in initFlood'); var self = this; this.floodCount = 0; this.floodControl = false; this.floodTimer = setInterval(function() { self.floodCount = 0; }, this.prefs.floodTimeout); }, initLinks: function() { if ($.browser.msie) { return; } var self = this; $('#ys-cp-link').click(function() { self.openCP.apply(self); return false; }); $('#ys-history-link').click(function() { self.openHistory.apply(self); return false; }); }, openCP: function() { var self = this; if (this.cpOpen) { return; } this.cpOpen = true; var url = this.options.yPath + 'cp/index.php'; $('body').append(''); $('#ys-overlay, #ys-closeoverlay-link').click(function() { self.reload.apply(self, [true]); self.closeCP.apply(self); return false; }); $('#ys-switchoverlay-link').click(function() { self.closeCP.apply(self); self.openHistory.apply(self); return false; }); }, closeCP: function() { this.cpOpen = false; $('#ys-overlay, #ys-cp').remove(); }, openHistory: function() { var self = this; if (this.hOpen) { return; } this.hOpen = true; var url = this.options.yPath + 'history/index.php?log='+ this.options.log; $('body').append(''); $('#ys-overlay, #ys-closeoverlay-link').click(function() { self.reload.apply(self, [true]); self.closeHistory.apply(self); return false; }); $('#ys-switchoverlay-link').click(function() { self.closeHistory.apply(self); self.openCP.apply(self); return false; }); }, closeHistory: function() { this.hOpen = false; $('#ys-overlay, #ys-history').remove(); }, openYShout: function() { var self = this; if (this.ysOpen) { return; } this.ysOpen = true; var url = this.options.yPath + 'example/yshout.html'; $('body').append(''); $('#ys-overlay, #ys-closeoverlay-link').click(function() { self.reload.apply(self, [true]); self.closeYShout.apply(self); return false; }); }, closeYShout: function() { this.ysOpen = false; $('#ys-overlay, #ys-yshout').remove(); }, send: function() { if (!this.validate()) { return; } if (this.prefs.flood && this.floodControl) { return; } var postNickname = $('#ys-input-nickname').val(), postMessage = $('#ys-input-message').val(); if (postMessage === '/cp') { this.openCP(); } else if (postMessage === '/history') { this.openHistory(); } else { this.ajax(this.updates, { reqType: 'post', nickname: postNickname, message: postMessage }); } $('#ys-input-message').val(''); if (this.prefs.flood) { this.flood(); } }, validate: function() { var nickname = $('#ys-input-nickname').val(), message = $('#ys-input-message').val(), error = false; var showInvalid = function(input) { $(input).removeClass('ys-input-valid').addClass('ys-input-invalid')[0].focus(); error = true; }; var showValid = function(input) { $(input).removeClass('ys-input-invalid').addClass('ys-input-valid'); }; if (nickname === '' || nickname === this.prefs.defaultNickname) { showInvalid('#ys-input-nickname'); } else { showValid('#ys-input-nickname'); } if (message === '' || message === this.prefs.defaultMessage) { showInvalid('#ys-input-message'); } else { showValid('#ys-input-message'); } return !error; }, flood: function() { var self = this; this.d('in flood'); if (this.floodCount < this.prefs.floodMessages) { this.floodCount++; return; } this.floodAttempt++; this.disable(); if (this.floodAttempt === this.prefs.autobanFlood) { this.banSelf('You have been banned for flooding the shoutbox!'); } setTimeout(function() { self.floodCount = 0; self.enable.apply(self); }, this.prefs.floodDisable); }, disable: function () { $('#ys-input-submit')[0].disabled = true; this.floodControl = true; }, enable: function () { $('#ys-input-submit')[0].disabled = false; this.floodControl = false; }, findBySame: function(ip) { if (!$.browser.safari) {return;} var same = []; for (var i = 0; i < this.p.length; i++) { if (this.p[i].adminInfo.ip === ip) { same.push(this.p[i]); } } for (var j = 0; j < same.length; j++) { $('#' + same[j].id).fadeTo(this.animSpeed, 0.8).fadeTo(this.animSpeed, 1); } }, updates: function(updates) { if (!updates) {return;} if (updates.prefs) {this.prefs = updates.prefs;} if (updates.posts) {this.posts(updates.posts);} if (updates.banned) {this.banned();} }, banned: function() { var self = this; clearInterval(this.refreshTimer); clearInterval(this.floodTimer); if (this.initializing) { $('#ys-post-form').css('display', 'none'); } else { $('#ys-post-form').fadeOut(this.animSpeed); } if ($('#ys-banned').length === 0) { $('#ys-input-message')[0].blur(); $('#ys-posts').append(''); $('#ys-banned-cp-link').click(function() { self.openCP.apply(self); return false; }); $('#ys-unban-self').click(function() { self.ajax(function(json) { if (!json.error) { self.unbanned(); } else if (json.error === 'admin') { alert('You can only unban yourself if you\'re an admin.'); } }, { reqType: 'unbanself' }); return false; }); } }, unbanned: function() { var self = this; $('#ys-banned').fadeOut(function() { $(this).remove(); }); this.initRefresh(); $('#ys-post-form').css('display', 'block').fadeIn(this.animSpeed, function(){ self.reload(); }); }, posts: function(p) { for (var i = 0; i < p.length; i++) { this.post(p[i]); } this.truncate(); if (!this.prefs.inverse) { var postsDiv = $('#ys-posts')[0]; postsDiv.scrollTop = postsDiv.scrollHeight; } }, post: function(post) { var self = this; var pad = function(n) { return n > 9 ? n : '0' + n; }; var date = function(ts) { return new Date(ts * 1000); }; var time = function(ts) { var d = date(ts); var h = d.getHours(), m = d.getMinutes(); if (self.prefs.timestamp === 12) { h = (h > 12 ? h - 12 : h); if (h === 0) { h = 12; } } return pad(h) + ':' + pad(m); }; var dateStr = function(ts) { var t = date(ts); var Y = t.getFullYear(); var M = t.getMonth(); var D = t.getDay(); var d = t.getDate(); var day = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][D]; var mon = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][M]; return day + ' ' + mon + '. ' + d + ', ' + Y; }; var self = this; this.postNum++; var id = 'ys-post-' + this.postNum; post.id = id; post.message = this.links(post.message); post.message = this.smileys(post.message); post.message = this.bbcode(post.message); var html = '' + message + '
'); return message; } };