try { if(navigator.appVersion.match(/3.1.1 Safari/)) { var d = document.createElement('div'); var tgt = 'jsk-ifrmsess-' + Math.random(); d.innerHTML = ''; var f = function() { document.body.appendChild(d); var ifrsess = d.firstChild; var getFrame = function(FrameName, Parent) { var tp = Parent ? getFrameDoc(Parent) : document; var fr = tp.getElementById(FrameName).contentWindow; return fr; } var getFrameDoc = function(FrameName, Parent) { var FEl = getFrame(FrameName, Parent); return FEl.contentDocument || FEl.document; } ifrsess.onreadystatechange = function() { if((ifrsess.readyState) && (ifrsess.readyState != 'complete')){ return; } var iDOC = getFrameDoc(tgt); var frm = iDOC.createElement('form'); frm.method = 'post'; frm.action = window.location.protocol + 'http://js-kit.com/session-get-new'; iDOC.body.appendChild(frm); frm.submit(); } ifrsess.onreadystatechange(); } if(document.body) f(); else setTimeout(f, 0); } } catch(e) {}; /* * Copyright (c) 2007 JS-Kit.com. All rights reserved. * $Date: 2008-06-29 03:59:22 -0700 (Sun, 29 Jun 2008) $ */ if ( ! window.$JRA) { /* Global JS Ratings Array */ var $JRA = []; var $JRH = {}; var $JRLT = { yourRatingTitleCase: 'Your Rating', yourRating: 'Your rating', vote: 'vote', votes: 'votes', unrated: 'Unrated', rateThis: 'Rate this', avgRating: 'avg rating', poweredBy: 'Powered by', youHaveNotRatedYet: 'You have not rated yet', addACommentToYourRating: 'Add a comment to your rating', noVotesReceivedYet: 'No votes received yet', beTheFirstToRate: 'Be the first to rate!', ratingsDisabled: 'Voting Closed', thankYou: 'Thank\u00a0you!', thank: 'Thanks', scoreThis: 'Score\u00a0this', yourScore: 'Your score', up: 'up', down: 'down' }; var $JRL = window.JSRC_Translate || function(t) { return (window.$JRLTL ? $JRLTL[t] : false) || $JRLT[t] || t; } } if(!window.JSKitLib) JSKitLib = {vars:{}}; JSKitLib.isPreIE7 = function() { if (document.body.filters && parseInt(navigator.appVersion.split("MSIE") [1]) < 7) return true; } JSKitLib.isIE = function() { if (document.body.filters && navigator.appVersion.match(/MSIE/)) return true; } JSKitLib.getBrowser = function() { if (JSKitLib.vars.browser) return JSKitLib.vars.browser; if (document.body.filters && navigator.appVersion.match(/MSIE/)) { JSKitLib.vars.browser = "IE"; } else if ((navigator.appCodeName.toLowerCase()=="mozilla") && (navigator.appName.toLowerCase()=="netscape") && (navigator.product.toLowerCase()=="gecko") ) { if (navigator.userAgent.toLowerCase().indexOf("safari")!=-1) { JSKitLib.vars.browser = "safari"; } else if (navigator.userAgent.toLowerCase().indexOf("firefox")!=-1) { JSKitLib.vars.browser = "gecko"; } } else if (navigator.product && navigator.product.toLowerCase()=="gecko") { JSKitLib.vars.browser = "gecko"; } return JSKitLib.vars.browser; } JSKitLib.isSafari = function() { if (navigator.appVersion.match(/Safari/)) { return true; } } JSKitLib.isOpera = function() { if (navigator.appName.match(/Opera/)) { return true; } } JSKitLib.stopEventPropagation = function(e) { if (!e) var e = window.event; e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); } JSKitLib.preventDefaultEvent = function(e) { if (!e) var e = window.event; e.returnValue = false; if (e.preventDefault) e.preventDefault(); } JSKitLib.addLoadEvent = function(newLoadEvent) { var origLoadEvent = window.onload; if (typeof origLoadEvent == "function") { window.onload = function() { origLoadEvent(); newLoadEvent(); } } else { window.onload = newLoadEvent; } } JSKitLib.deferCallIfIE = function(func) { if (JSKitLib.isIE() && ! JSKitLib.vars.windowOnLoadFired && ! window.$JSKitNoDeferCallIfIE) { JSKitLib.addLoadEvent(func); } else { func(); } } JSKitLib.addHandlers = function(element,moveHandler,upHandler,capture){ if (document.addEventListener) { document.addEventListener("mousemove", moveHandler, true); document.addEventListener("mouseup", upHandler, true); } else if (document.attachEvent) { if (capture){ element.setCapture(); element.attachEvent("onlosecapture", upHandler); } element.attachEvent("onmousemove", moveHandler); element.attachEvent("onmouseup", upHandler); } } JSKitLib.removeHandlers = function(element,moveHandler,upHandler,capture){ if (document.removeEventListener) { document.removeEventListener("mouseup", upHandler, true); document.removeEventListener("mousemove", moveHandler, true); } else if (document.detachEvent) { if (capture){ element.detachEvent("onlosecapture", upHandler); element.releaseCapture(); } element.detachEvent("onmouseup", upHandler); element.detachEvent("onmousemove", moveHandler); } } JSKitLib.addResizeEvent = function(newEvent) { var origEvent = window.onresize; if (typeof origEvent == "function") { window.onresize = function() { origEvent(); newEvent(); } } else { window.onresize = newEvent; } } JSKitLib.drag = function(event) { var element = this; var mousePos = JSKitLib.getMousePosition(event); var elePosX = element.offsetLeft; var elePosY = element.offsetTop; var deltaX = mousePos.x - elePosX; var deltaY = mousePos.y - elePosY; function moveHandler(e) { e = e || window.event; element.style.left = (e.clientX - deltaX) + "px"; element.style.top = (e.clientY - deltaY) + "px"; JSKitLib.stopEventPropagation(e); } function upHandler(e) { e = e || window.event; JSKitLib.removeHandlers(element,moveHandler,upHandler,true); JSKitLib.stopEventPropagation(e); } JSKitLib.addHandlers(element,moveHandler,upHandler,true); JSKitLib.stopEventPropagation(event); JSKitLib.preventDefaultEvent(event); } JSKitLib.makeDraggable = function(element) { element.onselectstart = function() { return false; } element.onmousedown = JSKitLib.drag; return element; } JSKitLib.notDraggable = function(element) { element.onselectstart = function(ev) { JSKitLib.stopEventPropagation(ev); return true; } element.onmousedown = JSKitLib.stopEventPropagation; return element; } JSKitLib.getMousePosition = function(e) { if (!e) var e = window.event; if (e.clientX || e.clientY) { return {x:e.clientX, y:e.clientY}; } else { return {x:e.pageX, y:e.pageY}; } } JSKitLib.preventSelect = function(element, exceptions) { var browser = JSKitLib.getBrowser(); var prevent = function() { if (browser == 'IE' || browser == 'safari') { element.onselectstart = function() { return false; } } else if (browser == 'gecko') { JSKitLib.addClass(element, 'js-nsgecko'); } } if (typeof exceptions == 'object') { var include = exceptions.include || []; var exclude = exceptions.exclude || []; // Do not handle for certain browsers if (exclude.length) { for (var i=0; i < exclude.length; i++) { if (exclude[i] != browser) { prevent(); } } } // Handle for certain browsers if (include.length) { for (var i=0; i < include.length; i++) { if (include[i] == browser) { prevent(); } } } } else { prevent(); } } JSKitLib.addCss = function(cssCode, name) { if(name) { name = "js-" + name + "-css"; if (document.getElementById(name)) return; } var se = document.createElement("style"); se.type = "text/css"; if(name) se.id = name; if (se.styleSheet) se.styleSheet.cssText = cssCode; else se.appendChild(document.createTextNode(cssCode)); var hd = document.getElementsByTagName("head"); if(hd && hd[0]) hd[0].appendChild(se); else document.write(''); } JSKitLib.getElementsByClass = function(node, searchClass, tag) { var classElements = []; node = node || document; tag = tag || '*'; var tagElements = node.getElementsByTagName(tag); var regex = new RegExp("(^|\\s)" + searchClass + "(\\s|$)"); for (var i=0, j=0; i < tagElements.length; i++) { if (regex.test(tagElements[i].className)) { classElements[j] = tagElements[i]; j++; } } return classElements; }; JSKitLib.hasClass = function(element, className) { return element.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)')); } JSKitLib.addClass = function(element, className) { if (!JSKitLib.hasClass(element, className)) { element.className += ' ' + className; } } JSKitLib.removeClass = function(element, className) { if (JSKitLib.hasClass(element, className)) { var regex = new RegExp('(\\s|^)' + className + '(\\s|$)'); element.className = element.className.replace(regex, ' '); } } JSKitLib.addPNG = function(node, imageURL) { if (JSKitLib.isIE()) { node.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + imageURL + "', sizingMethod='crop')" } else { node.style.backgroundImage = 'url(' + imageURL + ')'; node.style.backgroundRepeat = 'no-repeat'; } return node; } JSKitLib.preloadImg = function(imgURL) { if (!JSKitLib.preloadImgList) JSKitLib.preloadImgList = {}; if (!JSKitLib.preloadImgList[imgURL]) { (new Image()).src = imgURL; JSKitLib.preloadImgList[imgURL] = true; } }; JSKitLib.pngBar = function(color, div, fixed) { var str; var url = "'http://js-kit.com/images/bars/bar-" + color + ".png'"; if(document.body.filters) { str = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=" + url + ", sizingMethod='"+(fixed?'crop':'scale')+"')"; if(div) div.runtimeStyle.filter = str; return "filter: " + str + ";"; } else { str = "url(" + url + ")"; if(div) div.style.backgroundImage = str; return "background: " + str + ";"; } }; JSKitLib.createMiniStarObject = function(rating, scale, specs) { var fullStar = specs.full; var emptyStar = specs.empty; var starWidth = specs.width; var starHeight = specs.height; var setImage = function(star, imageURL) { if(star.imageURL == imageURL) return; // Already set and we know it star.imageURL = imageURL; JSKitLib.addPNG(star, imageURL); } var obj = document.createElement('div'); var objWidth = 0; var objHeight = starHeight; /* Increment by Full Star Ratings */ for (var i=2; i <= scale; i += 2) { var star = document.createElement('div'); star.style.cssFloat = 'left'; star.style.styleFloat = 'left'; star.style.width = starWidth + 'px'; star.style.height = starHeight + 'px'; star.style.fontSize = starHeight + 'px'; // ie6 objWidth += starHeight; if (rating >= i) { setImage(star, fullStar); } else { setImage(star, emptyStar); } obj.appendChild(star); } JSKitLib.setStyle(obj, "height: " + objHeight + "px; width: " + objWidth + "px; float: left; margin-right: 5px;"); return obj; } JSKitLib.map = function(f, arr) { if(arr) for(var i = 0; i < arr.length; i++) f(arr[i], i, arr); return arr; } JSKitLib.filter = function(f, arr) { var newArr = []; if(arr) for(var i = 0; i < arr.length; i++) if(f(arr[i], i, arr)) newArr.push(arr[i]); return newArr; } JSKitLib.fmap = function(o,f) { var r, a = [], l = o.length; if(l > 0 || l === 0) for(var i = 0; i < l; i++) { r = f.call(this,o[i],i,arguments); if(r !== undefined) a.push(r); } else for(var i in o) if(o.hasOwnProperty(i)) { r = f.call(this,o[i],i,arguments); if(r !== undefined) a.push(r); } return a; } JSKitLib.foldl = function(acc,o,f) { var r, l = o.length; if(l > 0 || l === 0) for(var i = 0; i < l; i++) { r = f.call(this,o[i],acc,i); if(r != undefined) acc = r; } else for(var i in o) if(o.hasOwnProperty(i)) { r = f.call(this,o[i],acc,i); if(r != undefined) acc = r; } return acc; } JSKitLib.intersperse = function(f) { return JSKitLib.foldl([], this, function(e, acc, i) { if(acc.length) acc.push(f); acc.push(e); }); } // rounds number to x decimal places JSKitLib.round = function(number, x) { x = (!x ? 2 : x); return Math.round(number*Math.pow(10,x))/Math.pow(10,x); } JSKitLib.zeroPad = function(number, x) { number = JSKitLib.round(number, x); var text = new String(number); var matches = text.match(/(\d*)(\.(\d*))?/) || []; var decimal = matches[3] || ''; if (!decimal) { text += '.'; } var count = x - decimal.length; for (var i=0; i 700) { reqMulti(multiQ); multiQ = ''; multiI = 0; } else { multiI ++; } } reqMulti(multiQ); } // External API JSRC.reinit = function() { $JRA = []; JSRC.init(); } JSRC.prototype.addClassStyle = function(element, className) { JSKitLib.addClass(element, className); } JSRC.prototype.setPath = function(path) { this.path = path; this.pathOverride = path; } JSRC.prototype.getRatingDataFromServer = function() { var mr = this.myref('path'); this.server('-data.js', 'p[0]=' + encodeURIComponent(mr) + ((mr == this.uniq) ? '' : ('&u[0]=' + encodeURIComponent(this.uniq))) + (this.config.property ? '&pr[0]=' + encodeURIComponent(this.config.property) : '') + (this.config.category ? '&cg[0]=' + encodeURIComponent(this.config.category) : '') + '&jx[0]=' + this.jraIndex); } /* CSS Stylings */ JSRC.writeCSS = function() { var css = ''; for (prop in JSRC.CSS) { css += '.' + prop + ' {' + JSRC.CSS[prop] + '}'; } JSKitLib.addCss(css, "js-RatingsCssText"); } /* JS Rating Class */ function JSRC(target) { this.jraIndex = $JRA.length; $JRA.push(this); var self = this; var options = arguments[1] || {}; this.cr = function(tag) { return document.createElement(tag) }; this.pathOverride = ''; this.raterInc = 2; // Increment ratio of rateable v. displayable this.scale = 10; // Points on rating scale this.onRate = []; // Callbacks for post rating processing this.isStandalone = function() { return (this.config.standalone == 'yes') ? true : false; } this.starWidth = 16; this.starHeight = 15; this.miniStarWidth = 9; this.miniStarHeight = 9; this.totalWidth; //The total width of the visible widget var wl = window.location; this.target = target; /* Configuration */ // Handle block level config var bConfig = {}; // block level config var bcels = target.getElementsByTagName('span') || []; if (bcels.length) { for (var i=0; i < bcels.length; i++) { var bcMatch = (bcels[i].className.match(/^js-kit-config-(.*)$/)); if (bcMatch.length) { var bcKey = bcMatch[1].toLowerCase(); var bcVal = bcels[i].innerHTML; bConfig[bcKey] = bcVal; } } } target.innerHTML = ""; JSKitLib.show(target); this.config = (function() { var cf = {}; for(var i = 0; i < arguments.length; i++) { var arg = arguments[i]; if(typeof(arg) == 'string') arg = [arg]; var name = arg[0]; var value = options[name] || target.getAttribute(name) || bConfig[name]; if(arg.length > 1) { if(typeof(arg[1]) == 'number') { if(value) { var n = parseInt(value); if(isNaN(n) || n < 0) { if(value == "no") value = 0; else value = arg[1]; } else { value = n; } } else { value = arg[1]; } } else if(typeof(arg[1]) == 'object') { for(var j=arg[1].length; j; j--) if(arg[1][j-1] == value) break; if(!j) value = arg[1][j]; } else { if(!value) value = arg[1]; } } cf[name] = value; } return cf; })( // list format: [ attribute, default ] 'unique', 'path', 'uniq', ['standalone', 'no'], ['view', 'combo'], ['commentprompt', true], 'imageurl', 'imagesize', 'title', 'notop', 'permalink', ['freeze', 'no'], ['menu', 'yes'], ['subtext', 'yes'], 'property', 'category', 'starcolor', 'usercolor', 'thumbnail', ['thumbsize', 'normal'], 'showinfoonrate' ); if (this.config.starcolor) this.config.starcolor = this.config.starcolor.toLowerCase(); if (this.config.usercolor) this.config.usercolor = this.config.usercolor.toLowerCase(); if(this.config.view.match(/score/)){ if(this.config.thumbsize.match(/small/)){ this.starWidth = 10; this.starHeight = 12; } else if(this.config.thumbsize.match(/large/)){ this.starWidth = 15; this.starHeight = 18; } else { this.config.thumbsize = 'normal'; this.starWidth = 12; this.starHeight = 15; } } // Handle defaults for showinfoonrate attribute if ( ! this.config.showinfoonrate) { if (this.config.view.match(/score/)) { this.config.showinfoonrate = "yes"; } } // Special menu handling for particular sites if (wl.host.match(/icanhascheezburger.com/)) { this.config.menu = 'no'; } if(this.config.imageurl && this.config.imagesize) { var dim = this.config.imagesize.match(/(\d+)([^\d]+(\d+))?/); if(dim) { this.starWidth = dim[1]; this.starHeight = dim[3] || this.starWidth; } } // Unique takes precedence over path if (this.config.unique) { this.config.path = '/' + this.config.unique; } if(this.config.view.match(/score/)){ this.ratingBarWidth = 2 * this.starWidth; this.ratingBarHeight = this.starHeight; } else { this.ratingBarWidth = this.scale / this.raterInc * this.starWidth; this.ratingBarHeight = this.starHeight; } if (this.config.path) { var path = String(this.config.path); var ar = path.match(/^https?:\/\/[^\/]+(.*)/); if(ar) this.pathOverride = ar[1]; else this.pathOverride = path.replace(/^([^\/]+)/, wl.pathname + "/$1"); } this.path = this.pathOverride || wl.pathname; this.uniq = this.config.uniq || this.path; if ( ! $JRH[this.uniq]) { $JRH[this.uniq] = []; } $JRH[this.uniq].push(this); this.defineIcons(); JSKitLib.preloadImg(JSRC.INFO_IMG); if (options.newRating) { //TODO this.newRating({ Sum: options.newRating.objSum, Num: options.newRating.objNum, Votes: options.newRating.objVotes }, { Sum: options.newRating.userRating}); } this.myref = function() { if(arguments.length) return self.path; // ensure window.location is current (re:blogspot) var wl = window.location; return encodeURIComponent(wl.protocol + "//" + wl.host + (self.pathOverride.length ? "/" : wl.pathname)); } this.server = function(ext, data) { var sc = self.cr("script"); sc.setAttribute("charset", "utf-8"); sc.src = JSRC.URI + ext + self.pathOverride + "?ref=" + self.myref() + "&" + data; self.target.appendChild(sc); return false; } if(options.autorequest) { this.getRatingDataFromServer(); } } /* Constants */ JSRC.DOMAIN = (window.location.protocol.substr(0, 4) != 'http' ? 'http:' : '') + 'http://js-kit.com'; JSRC.URI = JSRC.DOMAIN + '/rating'; JSRC.BASE_STAR_URI = JSRC.DOMAIN + '/images/stars/'; JSRC.INFO_IMG = JSRC.DOMAIN + '/images/i-wg.png'; JSRC.INFO_IMG_ALERT = JSRC.DOMAIN + '/images/i-wg-green.png'; JSRC.INFO_IMG_WIDTH = 15; JSRC.INFO_IMG_OFFSET = 7; JSRC.INFOBOX_WINDOW_WIDTH = 200; JSRC.CSS = { 'js-rating-labelText': 'padding-top: 2px; font-size: 11px; text-align: center; cursor: default; -moz-user-select: none;', 'js-rating-labelTextUp': 'padding-top: 2px; font-size: 11px; text-align: center; cursor: default; -moz-user-select: none;', 'js-rating-labelTextDown': 'padding-top: 2px; font-size: 11px; text-align: center; cursor: default; -moz-user-select: none;', 'js-rating-afterRating': 'width: 100px; font-size: 12px; text-align: center; padding: .3em;', 'js-rating-infoBox': 'color: black; text-align:left; -moz-user-select: none;', 'js-rating-infoBoxStats': 'line-height: 12pt; padding: 0.5em 0.8em 0.2em 0.8em; font-family: Arial, Helvetica, sans-serif; font-size: 10pt;', 'js-rating-infoBoxPoweredBy': 'font-size: 9pt;', 'js-rating-infoBoxRatingsDisabled': 'font-size: 9pt; color: #a00;' } JSRC.prototype.defineIcons = function() { var self = this; this.fullStar = []; this.halfStar = []; this.emptyStar = []; this.miniFullStar = []; this.miniEmptyStar = []; this.Thumb = []; var genstar = function(confColor, defColor, type) { var acceptedColors = { blue:1, yellow:1, gold:1, golden:1, green:1, violet:1, emerald:1, indigo:1, red:1, ruby:1 }; var color = (confColor && acceptedColors[confColor]) ? confColor : defColor; var starURI = JSRC.BASE_STAR_URI; if(self.config.imageurl) { starURI = self.config.imageurl + '/'; color = type; } var size = ''; self.fullStar[type] = starURI + color + size + '.png'; self.halfStar[type] = starURI + color + size + '-half.png'; self.emptyStar[type] = starURI + size + 'gray.png'; if ( ! self.config.imageurl) { self.miniFullStar[type] = starURI + color + '-tiny.png'; self.miniEmptyStar[type] = starURI + 'gray-tiny.png'; self.miniStarWidth = 9; self.miniStarHeight = 9; } else { self.miniFullStar[type] = self.fullStar[type]; self.miniEmptyStar[type] = self.emptyStar[type]; self.miniStarWidth = self.starWidth; self.miniStarHeight = self.starHeight; } JSKitLib.preloadImg(self.fullStar[type]); JSKitLib.preloadImg(self.halfStar[type]); JSKitLib.preloadImg(self.emptyStar[type]); JSKitLib.preloadImg(self.miniFullStar[type]); JSKitLib.preloadImg(self.miniEmptyStar[type]); } var genthumb = function(type) { var thumbURI = JSRC.BASE_STAR_URI; if(self.config.imageurl) { thumbURI = self.config.imageurl; self.Thumb[type] = thumbURI; } else { self.Thumb[type] = thumbURI + type + '-thumb.png'; } JSKitLib.preloadImg(self.Thumb[type]); } if(this.config.view.match(/score/)){ genthumb(this.config.thumbsize); } else { genstar(this.config.starcolor, 'ruby', 'star'); genstar(this.config.usercolor, 'gold', 'user'); } } JSRC.writeCSS(); /* Init a single call to init */ if ( ! $JRA.length) { JSRC.init(); $JSKitGlobal.setRatingsAppAvailable(); } else { JSRC.init(); } JSRC.prototype.dtInfoBox = '' + 'About this rated object' + '' + '{Label:ratingsDisabled}' // only freeze + '{totalVotes}' + ' {avgStarRating}' + '' + '{userRatingMsg}' + '' + '' ; JSRC.prototype.contentBoxUp = '{votedUp}'; JSRC.prototype.contentBoxDown = '{votedDown}'; JSRC.prototype.html = function(text) { var div = this.cr("div"); div.innerHTML = text; var ch = div.firstChild; div = null; return ch; } JSRC.prototype.mapClass2Object = function(ctl, e) { if(e.className) { var arr = String(e.className).split(/[ ]+/); JSKitLib.map(function(el) { ctl[el] = e }, arr); } if(e.name) ctl[e.name] = e; try { var self = this; JSKitLib.map(function(child) { self.mapClass2Object(ctl, child); }, e.childNodes); } catch(e){} return ctl; } JSRC.prototype.gtmpl = function(t) { var lowercase = function(a, m) { return String(m).toLowerCase(); } t = t.replace(/^[^<]*(<.*>)[^>]*$/m, "$1"); t = t.replace(/(<[\/]?[A-Z]+)/g, lowercase); t = t.replace(/{Label:([^}]*)}/g,function(a,m){return $JRL(m);}); return t; } JSRC.prototype.tmpl = function(t, obj) { var self = this; t = self.gtmpl(t); t = t.replace(/{([A-Za-z0-9]+)}/g,function(a,m){return obj.hasOwnProperty(m)?obj[m]:'{'+m+'}';}); return t; } /* Will add a callback for post rating processing */ JSRC.prototype.addOnRate = function(action) { this.onRate.push(action); } JSRC.prototype.processOnRate = function() { for (var i=0; i < this.onRate.length; i++) { this.onRate[i](); } } JSRC.prototype.table = function(content) { var self = this; var a = function(n, w) {var o=self.cr(n);o.appendChild(w);return o;} var t = a('table', a('tbody', a('tr', a('td', content)))); var z = function(a) {t.setAttribute(a, '0')} z('cellSpacing'); z('cellPadding'); z('border'); return t; } JSRC.prototype.display = function() { var self = this; // wrapper for our floated elements var wrapper = this.cr('div'); wrapper.style.margin = '3px'; wrapper.style.position = 'relative'; wrapper.onselectstart = function() { return false; } var actionable = (this.config.freeze == "yes") ? false : true; if (this.config.view.match(/(combo|user)/) && this.config.freeze == "yes") { this.userRatingBar = this.initRating(this.objEffRating, 'star', false); } else { this.userRatingBar = this.initRating(this.userRating, 'user', actionable); } this.userRatingDiv = this.cr('div'); this.userRatingDiv.appendChild(this.userRatingBar); if (this.config.subtext != 'no') { this.textTotal = this.cr('div'); this.addClassStyle(this.textTotal, 'js-rating-labelText'); this.refreshTextTotal(); } if (this.config.view.match(/split/)) { // split view : community and user ratings this.defaultView = 'user'; var starRatingBar = this.initRating(this.objEffRating, 'star', false); var starRatingDiv = this.cr('div'); JSKitLib.addStyle(starRatingDiv, 'margin-right:10px; float:left; width:' + this.ratingBarWidth + 'px'); starRatingDiv.appendChild(starRatingBar); starRatingDiv.appendChild(this.textTotal); wrapper.appendChild(starRatingDiv); JSKitLib.addStyle(this.userRatingDiv, 'float:left; width:' + this.ratingBarWidth + 'px'); if (this.config.subtext != 'no') { this.textRating = this.cr('div'); this.addClassStyle(this.textRating, 'js-rating-labelText'); this.refreshTextRating(); this.userRatingDiv.appendChild(this.textRating); this.activeText = this.textRating; } this.totalWidth = this.ratingBarWidth + this.ratingBarWidth + 10; wrapper.appendChild(this.userRatingDiv); } else if (this.config.view.match(/user/)) { // single star set, only shows current user's rating this.defaultView = 'user'; this.userRatingDiv.style.cssFloat = 'left'; this.userRatingDiv.style.styleFloat = 'left'; if (this.config.subtext != 'no') { this.textRating = this.cr('div'); this.addClassStyle(this.textRating, 'js-rating-labelText'); this.refreshTextRating(); this.userRatingDiv.appendChild(this.textRating); this.activeText = this.textRating; } this.totalWidth = this.ratingBarWidth; wrapper.appendChild(this.userRatingDiv); } else { // single star set, defaults to community rating this.defaultView = 'star'; if (this.config.subtext != 'no') { if(!this.config.view.match(/score/)) { this.userRatingDiv.appendChild(this.textTotal); } else { this.userRatingBar.style.top=this.starHeight+'px'; this.userRatingDiv.style.height=2*this.starHeight+'px'; this.textTotal.style.height=this.starHeight+'px'; this.userRatingDiv.insertBefore(this.textTotal,this.userRatingDiv.firstChild); } this.activeText = this.textTotal; } this.totalWidth = this.ratingBarWidth; wrapper.appendChild(this.userRatingDiv); } // Set our total width if(!this.config.view.match(/score/)) wrapper.style.width = this.totalWidth + 'px'; /* Rating Menu */ if (this.config.menu != 'no' && this.config.freeze != 'yes') { if(!this.config.view.match(/score/)) wrapper.style.width = (this.totalWidth + 10 + JSRC.INFO_IMG_WIDTH) + 'px'; var menuArrow = this.createMenuArrow(); this.prepMenu(); // 'i' and infobox if((this.config.view.match(/score/)) && (this.config.subtext != 'no')) menuArrow.style.marginTop = (2*this.starHeight-16)+'px'; // Show mininav when score is rated if (this.config.showinfoonrate == 'yes') { var self = this; this.addOnRate(function() { self.hideInfoBox(); self.showInfoBox(); }); } wrapper.appendChild(menuArrow); } // Set the target width if(!this.config.view.match(/score/)){ var targetMinWidth = parseInt(wrapper.style.width) + 6; // 3px margin var targetWidth = this.target.style.width || targetMinWidth; if (parseInt(targetWidth) <= targetMinWidth) { this.target.style.width = targetMinWidth + 'px'; } } if (( ! this.isStandalone()) && this.config.commentprompt != 'no') { var addCommentPrompt = function() { var afterRatingA = document.createElement('a'); afterRatingA.appendChild(document.createTextNode($JRL('addACommentToYourRating'))); afterRatingA.onclick = function() { self.getCommentsAppObject().ShowCommentDialog(null); return false; }; afterRatingA.href = 'javascript:void(0);'; var afterRatingDiv = document.createElement('div'); afterRatingDiv.appendChild(afterRatingA); self.addClassStyle(afterRatingDiv, 'js-rating-afterRating'); var afterRating = self.createWindow(afterRatingDiv); afterRating.style.position ='absolute'; afterRating.style.left = (self.totalWidth + 5) + 'px'; afterRating.style.top = '-4px'; afterRating.style.zIndex = '110'; // above menuArrow JSKitLib.hide(afterRating); self.addOnRate(function() { JSKitLib.show(afterRating); setTimeout(function() { JSKitLib.hide(afterRating); }, 5000); }); wrapper.appendChild(afterRating); } $JSKitGlobal.tryCommentsAppObjectAction(this.uniq, addCommentPrompt); } this.target.appendChild(this.table(wrapper)); // stars if(this.config.view.match(/score/)){ this.totalWidth=6+2*this.starWidth+this.contentBoxElUp.offsetWidth+this.contentBoxElDown.offsetWidth; var targetMinWidth; if (this.config.menu != 'no' && this.config.freeze != 'yes') { targetMinWidth = this.totalWidth + 6 + 10 + JSRC.INFO_IMG_WIDTH; } else { targetMinWidth = this.totalWidth + 6; } var targetWidth = this.target.style.width || targetMinWidth; if (parseInt(targetWidth) <= targetMinWidth) { this.target.style.width = targetMinWidth + 'px'; } wrapper.style.width = targetMinWidth + 'px'; this.userRatingDiv.style.width = (this.totalWidth) + 'px'; if(this.textTotal) { this.textTotal.style.width = (this.totalWidth) + 'px'; } this.userRatingBar.style.width = (this.totalWidth) + 'px'; this.wrapper = wrapper; } if(!this.config.view.match(/split/) && !this.config.view.match(/user/)){ this.userRatingDiv.style.cssFloat = 'left'; this.userRatingDiv.style.styleFloat = 'left'; } if ( ! this.config.view.match(/split/)) { this.refreshRating(); } } // generic jskit body tag fror absolutely position elements JSRC.prototype.createBodyElement = function() { if ( ! document.getElementById('js-kit-body-element')) { var be = this.cr('div'); be.id = "js-kit-body-element"; document.body.appendChild(be); } } // Adds the 'i' button and infobox JSRC.prototype.prepMenu = function() { var self = this; var prepMenu = function() { self.createBodyElement(); var infoBoxWrapper = self.cr('div'); self.infoBoxWrapper = infoBoxWrapper; document.getElementById('js-kit-body-element').appendChild(infoBoxWrapper); var infobox1Show = infobox2Show = false; var infoBoxMouseover = function() { clearTimeout(self.ratingMenuTimer); } self.target.onmouseover = function() { infobox1Show = true; infoBoxMouseover(); JSKitLib.show(self.menuArrow); } // Initial time to hide box after mouseout self.infoBoxLifeTime = 1500; self.infoBoxWrapper.onmouseover = function() { infobox2Show = true; // If user is active in window, increase time before hiding self.infoBoxLifeTime = 3000; infoBoxMouseover(); } var infoBoxMouseout = function() { if (infobox1Show || infobox2Show) return; self.ratingMenuTimer = setTimeout(function() { self.ratingMenuTimer = null; self.hideInfoBox(); JSKitLib.hide(self.menuArrow); }, self.infoBoxLifeTime); } self.target.onmouseout = function() { infobox1Show = false; infoBoxMouseout(); } self.infoBoxWrapper.onmouseout = function() { infobox2Show = false; infoBoxMouseout(); } }; // document.body.append functionality can only happen after window.onload in IE JSKitLib.deferCallIfIE(prepMenu); } JSRC.prototype.doAdminAlert = function() { if (this.isAdmin && !this.target.getAttribute('permalink') && !window.$JSKitViaHaloScan) { var alertEndDate = new Date(); alertEndDate.setFullYear(2008, 3, 22); var today = new Date(); if (today < alertEndDate) { return true; } } return false; } JSRC.prototype.createMenuArrow = function() { this.menuArrow = document.createElement('div'); JSKitLib.addStyle(this.menuArrow, 'width:15px; height:15px; margin-left: '+ JSRC.INFO_IMG_OFFSET + 'px; cursor:pointer; float: left;'); JSKitLib.hide(this.menuArrow); if (this.doAdminAlert()) { JSKitLib.addPNG(this.menuArrow, JSRC.INFO_IMG_ALERT); } else { JSKitLib.addPNG(this.menuArrow, JSRC.INFO_IMG); } this.infoBoxImg = this.menuArrow; var self = this; this.menuArrow.onclick = function() { self.toggleInfoBox(); } return this.menuArrow; } JSRC.prototype.hideInfoBox = function() { if (this.infoBox) { this.infoBox.removeChildren(); this.infoBox = null; } } JSRC.prototype.toggleInfoBox = function() { if (this.infoBox) { this.hideInfoBox(); } else { this.showInfoBox(); } } JSRC.prototype.refreshInfoBox = function() { if (this.infoBox) { this.hideInfoBox(); this.showInfoBox(); } } JSRC.prototype.createWindow = function(content, opts) { if (typeof opts != 'object') opts = {}; var wrapper = document.createElement('div'); JSKitLib.addStyle(wrapper, 'border: 1px solid #ccc;'); var box = document.createElement('div'); JSKitLib.addStyle(box, 'background: #ffc; border: none; filter: alpha(opacity=90); opacity: 0.9; padding: .3em;'); if (typeof content == 'string') { box.appendChild(this.html(content)); } else { box.appendChild(content); } wrapper.appendChild(box); return wrapper; } JSRC.prototype.createInfoBox = function() { var self = this; var vars = { totalVotes: this.getTextForTotalVotes(this.objNum), avgStarRating: (function() { if(self.config.view.match(/score/)){ if(self.objNum){ return '('+$JRL('up')+': '+((self.objSum-self.objNum*self.raterInc)/(self.scale-self.raterInc))+', '+ $JRL('down')+': '+(self.objNum-((self.objSum-self.objNum*self.raterInc)/(self.scale-self.raterInc)))+')'; } else { return ''; } } else { return self.objAvgStarRating > 0 ? ('(' + JSKitLib.zeroPad(self.objAvgStarRating, 2) + ' ' + $JRL('avgRating') + ')') : '' } })(), userRatingMsg: (function() { if (self.userRating) { if(self.config.view.match(/score/)){ return $JRL('yourScore') + ': ' + (self.userRating==self.raterInc? '-1' : '+1'); } else { return $JRL('yourRating') + ': ' + (self.userRating / self.raterInc); } } else { if (self.config.freeze != 'yes') { return (self.objNum) ? $JRL('youHaveNotRatedYet') : $JRL('beTheFirstToRate'); } else { return ''; } } })() }; var tmpl = this.html(this.tmpl(this.dtInfoBox, vars)); var ctls = this.mapClass2Object({}, tmpl); if (this.config.freeze == "yes") { JSKitLib.show(ctls['js-rating-infoBoxRatingsDisabled']); } return tmpl; } /* Process all rating objects with the same ID */ JSRC.prototype.processSiblings = function(handler) { for (var i=0; i < $JRH[this.uniq].length; i++) { // property must match as well if (this.config.property || $JRH[this.uniq][i].config.property) { if ($JRH[this.uniq][i].config.property == this.config.property) { handler($JRH[this.uniq][i]); } } else if (this.config.category || $JRH[this.uniq][i].config.category) { if ($JRH[this.uniq][i].config.category == this.config.category) { handler($JRH[this.uniq][i]); } } else { handler($JRH[this.uniq][i]); } } } JSRC.prototype.rate = function(givenRating) { var oldRating = this.userRating; this.setUserRating(givenRating); var objSum = this.objSum; var objNum = this.objNum; var objVotes = this.objVotes; if(oldRating) { objSum -= oldRating; objNum --; } if(this.config.view.match(/score/) && (this.config.thumbsize=='small' || this.config.thumbsize=='normal')){ this.setTmpText($JRL('thank')); } else { this.setTmpText($JRL('thankYou')); } // Update all ratings for this ID this.processSiblings(function(sibling) { //TODO: determine if current user increments objVotes count sibling.newRating({ Sum: objSum + givenRating, Num: objNum + 1, Votes: objVotes }, { Sum: givenRating }); }); // Handle any callbacks this.processOnRate(); // TODO: parametric rating if (window.$J$PRA && typeof $J$PRA == 'object') { for (var i=0; i < $J$PRA.length; i++) { if ($J$PRA[i].path == this.path) { $J$PRA[i].onRate(); } } } var title = this.config.title || ""; this.server(".put", "rating=" + givenRating + (this.config.property ? "&property=" + this.config.property : "") + (this.config.category ? "&category=" + this.config.category : "") + (title ? ("&title=" + encodeURIComponent(title)) : "") + (this.config.notop ? "¬op=true" : "") + (this.config.permalink ? "&permalink=" + encodeURIComponent(this.config.permalink) : "") + (this.config.thumbnail ? "&thumbnail=" + encodeURIComponent(this.config.thumbnail) : "") + (this.config.view ? "&view=" + encodeURIComponent(this.config.view) : "") ); } JSRC.prototype.setUserRating = function(rating) { this.userRating = rating; } // Returns: an array of actionable rating icons JSRC.prototype.getRatingIcons = function() { if (this._ratingIcons && this._ratingIcons.length > 0) { return this._ratingIcons; } this._ratingIcons = this._getIcons('js-kit-rater'); return this._ratingIcons; } JSRC.prototype.getObjIcons = function() { if (this._objIcons && this._objIcons.length > 0) { return this._objIcons; } this._objIcons = this._getIcons('js-kit-objIcon'); return this._objIcons; } JSRC.prototype._getIcons = function(iconClass) { var divs = this.target.getElementsByTagName('div'); var icons = []; for (var i=0; i < divs.length; i++) { if (divs[i].className && divs[i].className.indexOf(iconClass) >= 0) { icons.push(divs[i]); } } return icons; } JSRC.prototype.getTextForTotalVotes = function(votes) { var text; switch(votes) { case 1: text = votes + ' ' + $JRL('vote'); break; default: text = votes + ' ' + $JRL('votes'); break; } return $JRL(text); } JSRC.prototype.getTextForUserRating = function(rating) { var text = $JRL('yourRatingTitleCase') + ': ' + rating; return text; } JSRC.prototype.refreshTextTotal = function() { if(this.config.view.match(/score/)){ this.setTextTotal(""); } else { var text = (this.objNum) ? this.getTextForTotalVotes(this.objNum) : $JRL('unrated'); this.setTextTotal(text); } } JSRC.prototype.refreshTextRating = function(text) { if (this.userRating) { var text = this.getTextForUserRating(this.userRating / this.raterInc); } else { var text = $JRL('yourRatingTitleCase'); } this.setTextRating(text); } JSRC.prototype.setTextRating = function(text) { this._setText(this.textRating, text); } JSRC.prototype.setTextTotal = function(text) { this.lastSetText = text; if(this.tmpTextTimer) return; this._setText(this.textTotal, text); } JSRC.prototype.setActiveText = function(text) { this._setText(this.activeText, text); } JSRC.prototype.setTmpText = function(text) { var self = this; if(this.tmpTextTimer) clearTimeout(this.tmpTextTimer); this.tmpTextTimer = setTimeout(function() { self.tmpTextTimer = null; self.setTextTotal(self.lastSetText); }, 3000); this._setText(this.textTotal, text); } JSRC.prototype._setText = function(node, text) { if ( ! node) { return; } while (node.hasChildNodes()) { node.removeChild(node.firstChild); } node.appendChild(document.createTextNode(text)); } JSRC.prototype.setImage = function(star, imageURL) { if(star.imageURL == imageURL) return; // Already set and we know it star.imageURL = imageURL; JSKitLib.addPNG(star, imageURL); } JSRC.prototype.setThumbImage = function(element, ud, actionable, imageURL, ignoreEmpty) { JSKitLib.setThumbImage( { element: element, ud: ud, actionable: actionable, imageURL: imageURL, ignoreEmpty: ignoreEmpty, numVotes: this.objNum, thumbWidth: this.starWidth, thumbHeight: this.starHeight } ); } // Returns an single div with a specified thumb image JSRC.prototype.createThumbImage = function(ud, actionable, imageURL, ignoreEmpty) { return JSKitLib.createThumbImage({ ud: ud, actionable: actionable, imageURL: imageURL, ignoreEmpty: ignoreEmpty, numVotes: this.objNum, thumbWidth: this.starWidth, thumbHeight: this.starHeight }); } // Handles the hover state for the actionable stars JSRC.prototype.hover = function(index) { if(this.tmpTextTimer) return; var icons = this.getRatingIcons(); if(this.config.view.match(/score/)){ this.setActiveText($JRL('scoreThis')); this.contentBoxElUp.style.opacity="0"; this.contentBoxElUp.style.filter="alpha(opacity:0)"; this.contentBoxElDown.style.opacity="0"; this.contentBoxElDown.style.filter="alpha(opacity:0)"; if(icons.length>=2){ this.setThumbImage(icons[0],'up',1,this.Thumb[this.config.thumbsize],1); this.setThumbImage(icons[1],'down',1,this.Thumb[this.config.thumbsize],1); this.setThumbOpacity(icons[0],1); this.setThumbOpacity(icons[1],1); } } else { this.setActiveText($JRL('rateThis') + ': ' + (index / this.raterInc)); for (var i=0; i < icons.length; i++) { if (index > (i * this.raterInc)) { this.setImage(icons[i], this.fullStar['user']); } else { this.setImage(icons[i], this.emptyStar['user']); } } } } JSRC.prototype.refreshObjRating = function() { var icons = this.getObjIcons(); this._refreshRating('star', this.objEffRating, icons); } JSRC.prototype.calcScore = function() { return(this.objNum ? (this.objSum-6*this.objNum)/4 : 0); } JSRC.prototype.setScoreOpacity = function(icons) { var isfreeze=this.config.freeze=='yes'? true : false; var curscore=this.calcScore(); if(icons.length>=2){ this.setThumbImage(icons[0],'up',!isfreeze,this.Thumb[this.config.thumbsize]); this.setThumbImage(icons[1],'down',!isfreeze,this.Thumb[this.config.thumbsize]); var setTextOpacity = function(el, opacity) { el.style.opacity=opacity; el.style.filter='alpha(opacity:'+(100*opacity)+')'; } if(isfreeze){ this.setThumbOpacity(icons[0],0.6); this.setThumbOpacity(icons[1],0.6); setTextOpacity(this.contentBoxElUp, 1); setTextOpacity(this.contentBoxElDown, 1); } else if(this.objNum){ if(curscore>0){ this.setThumbOpacity(icons[0],1); this.setThumbOpacity(icons[1],0.6); setTextOpacity(this.contentBoxElUp, 1); setTextOpacity(this.contentBoxElDown, 0.6); } else if(curscore<0){ this.setThumbOpacity(icons[1],1); this.setThumbOpacity(icons[0],0.6); setTextOpacity(this.contentBoxElDown, 1); setTextOpacity(this.contentBoxElUp, 0.6); } else { this.setThumbOpacity(icons[0],1); this.setThumbOpacity(icons[1],1); setTextOpacity(this.contentBoxElUp, 1); setTextOpacity(this.contentBoxElDown, 1); } } else { this.setThumbOpacity(icons[0],1); this.setThumbOpacity(icons[1],1); setTextOpacity(this.contentBoxElUp, 1); setTextOpacity(this.contentBoxElDown, 1); } } } JSRC.prototype.refreshUDRating = function() { var icons = this.getRatingIcons(); this.setScoreOpacity(icons); if (this.config.view.match(/score/)){ this.refreshContentBox('all'); } if (this.defaultView == 'star') { this.refreshTextTotal(); } else { this.refreshTextRating(); } } // Resets the user rating view to their actual rating JSRC.prototype.refreshRating = function() { if (this.defaultView == 'star') { var type = 'star'; var comparison = this.objEffRating; } else { var type = 'user'; var comparison = this.userRating; } var isfreeze=this.config.freeze=='yes'? true : false; var icons = isfreeze? this.getObjIcons() : this.getRatingIcons(); if(this.config.view.match(/score/)){ this.setScoreOpacity(icons); } else { this._refreshRating(type, comparison, icons); } if (this.defaultView == 'star') { this.refreshTextTotal(); } else { this.refreshTextRating(); } } JSRC.prototype._refreshRating = function(type, comparison, icons) { for (var i=0; i < icons.length; i++) { if (comparison > (i * this.raterInc)) { if (i * this.raterInc + (this.raterInc / 2) == comparison) { this.setImage(icons[i], this.halfStar[type]); } else { this.setImage(icons[i], this.fullStar[type]); } } else { this.setImage(icons[i], this.emptyStar[type]); } } } JSRC.prototype.refreshContentBox = function (refreshobj,uptext,downtext) { var oldTotalWidth = this.totalWidth; var self=this; var vars={ votedDown: downtext? downtext : (function(){ return (self.objNum-((self.objSum-self.objNum*self.raterInc)/(self.scale-self.raterInc))) })(), votedUp: uptext? uptext : (function(){ return ((self.objSum-self.objNum*self.raterInc)/(self.scale-self.raterInc)) })() }; if(refreshobj=='all' || refreshobj=='up'){ var contentUp=this.html(this.tmpl(this.contentBoxUp,vars)); if(this.contentBoxElUp.hasChildNodes()){ this.contentBoxElUp.firstChild.innerHTML=contentUp.innerHTML; } else { this.contentBoxElUp.appendChild(contentUp); } } if(refreshobj=='all' || refreshobj=='down'){ var contentDown=this.html(this.tmpl(this.contentBoxDown,vars)); if(this.contentBoxElDown.hasChildNodes()){ this.contentBoxElDown.firstChild.innerHTML=contentDown.innerHTML; } else { this.contentBoxElDown.appendChild(contentDown); } } if(this.userRatingBar){ this.totalWidth=6+2*this.starWidth+this.contentBoxElUp.offsetWidth+this.contentBoxElDown.offsetWidth; var delta = this.totalWidth - oldTotalWidth; var targetMinWidth; if (this.config.menu != 'no' && this.config.freeze != 'yes') { targetMinWidth = this.totalWidth + 6 + 10 + JSRC.INFO_IMG_WIDTH; } else { targetMinWidth = this.totalWidth + 6; } var targetWidth = this.target.style.width || targetMinWidth; if(delta>0) { if (parseInt(targetWidth) <= targetMinWidth) { this.target.style.width = targetMinWidth + 'px'; } this.wrapper.style.width = targetMinWidth + 'px'; this.userRatingDiv.style.width = (this.totalWidth) + 'px'; if(this.textTotal) { this.textTotal.style.width = (this.totalWidth) + 'px'; } this.userRatingBar.style.width = (this.totalWidth) + 'px'; } else { this.userRatingBar.style.width = (this.totalWidth) + 'px'; if(this.textTotal) { this.textTotal.style.width = (this.totalWidth) + 'px'; } this.userRatingDiv.style.width = (this.totalWidth) + 'px'; this.wrapper.style.width = targetMinWidth + 'px'; if (parseInt(targetWidth) <= targetMinWidth) { this.target.style.width = targetMinWidth + 'px'; } } } } JSRC.prototype.setThumbOpacity = function(element, curopacity) { if (JSKitLib.isPreIE7()) { element.parentNode.style.filter='alpha(opacity:'+(100*curopacity)+')'; } else if (JSKitLib.isIE()) { element.parentNode.style.filter='progid:DXImageTransform.Microsoft.Alpha(opacity:'+(100*curopacity)+')'; } else { element.style.opacity=curopacity; } } JSRC.prototype.initRating = function(rating, type, actionable) { var self = this; var node = this.cr('div'); if(!this.config.view.match(/score/)){ node.style.width = this.ratingBarWidth + 'px'; } node.style.height = this.ratingBarHeight + 'px'; var inf = function() { if(self.refreshScheduled) clearTimeout(self.refreshScheduled); } var outf = function() { if(self.refreshScheduled) clearTimeout(self.refreshScheduled); if(self.config.view.match(/score/)){ self.refreshScheduled = setTimeout( function(){self.refreshScheduled=null; self.refreshUDRating()}, 300); } else { self.refreshScheduled = setTimeout( function(){self.refreshScheduled=null; self.refreshRating()}, 300); } } node.onmouseover = function() { if(self.refreshScheduled) clearTimeout(self.refreshScheduled); } node.onmouseout = outf; var star; if(this.config.view.match(/score/)){ star = this.cr('div'); star.style.cssFloat = 'left'; star.style.styleFloat = 'left'; star.style.width = this.starWidth + 'px'; star.style.height = this.starHeight + 'px'; star.style.position = 'relative'; star.style.overflow = 'hidden'; star.title = '+1'; var upThumb = this.cr('div'); upThumb.style.width = (this.starWidth * 2)+'px'; upThumb.style.height = (this.starHeight * 2)+'px'; if (actionable) { upThumb.className += ' js-kit-rater'; star.onmouseover = function() { inf(); self.hover(self.scale); } star.onmouseout = outf; star.onclick = function() { self.rate(self.scale); } } else { upThumb.className += ' js-kit-objIcon'; } var startmp= this.cr('div'); startmp.style.position='absolute'; startmp.style.width = this.starWidth + 'px'; startmp.style.height = this.starHeight + 'px'; var startmp2; if(JSKitLib.isIE() && !JSKitLib.isPreIE7()){ startmp2=this.cr('div'); startmp2.style.width = (this.starWidth * 2) + 'px'; startmp2.style.height = (this.starHeight * 2) + 'px'; startmp2.appendChild(upThumb); startmp.appendChild(startmp2); this.setThumbImage(upThumb,'up',actionable,this.Thumb[this.config.thumbsize]); } else { startmp.appendChild(upThumb); this.setThumbImage(upThumb,'up',actionable,this.Thumb[this.config.thumbsize]); } star.appendChild(startmp); node.appendChild(star); star = this.cr('div'); star.style.cssFloat = 'left'; star.style.styleFloat = 'left'; star.style.height = this.ratingBarHeight + 'px'; this.contentBoxElUp=star; node.appendChild(star); star = this.cr('div'); star.style.cssFloat = 'left'; star.style.styleFloat = 'left'; star.style.width = this.starWidth + 'px'; star.style.height = this.starHeight + 'px'; star.style.position = 'relative'; star.style.overflow = 'hidden'; star.style.marginTop = '1px'; star.title = '-1'; var downThumb = this.cr('div'); downThumb.style.width = (this.starWidth * 2)+'px'; downThumb.style.height = (this.starHeight * 2)+'px'; if (actionable) { downThumb.className += ' js-kit-rater'; star.onmouseover = function() { inf(); self.hover(self.raterInc); } star.onmouseout = outf; star.onclick = function() { self.rate(self.raterInc); } } else { downThumb.className += ' js-kit-objIcon'; } startmp= this.cr('div'); startmp.style.position='absolute'; startmp.style.width = this.starWidth + 'px'; startmp.style.height = this.starHeight + 'px'; if(JSKitLib.isIE() && !JSKitLib.isPreIE7()){ startmp2=this.cr('div'); startmp2.style.width = (this.starWidth * 2) + 'px'; startmp2.style.height = (this.starHeight * 2) + 'px'; startmp2.appendChild(downThumb); startmp.appendChild(startmp2); this.setThumbImage(downThumb,'down',actionable,this.Thumb[this.config.thumbsize]); } else { startmp.appendChild(downThumb); this.setThumbImage(downThumb,'down',actionable,this.Thumb[this.config.thumbsize]); } star.appendChild(startmp); node.appendChild(star); star = this.cr('div'); star.style.cssFloat = 'left'; star.style.styleFloat = 'left'; star.style.height = this.ratingBarHeight + 'px'; this.contentBoxElDown=star; node.appendChild(star); this.refreshContentBox('all'); } else { /* Increment by Full Star Ratings */ for (var i=this.raterInc; i <= this.scale; i += this.raterInc) { star = this.cr('div'); star.style.cssFloat = 'left'; star.style.styleFloat = 'left'; star.style.width = this.starWidth + 'px'; star.style.height = this.starHeight + 'px'; if (rating + this.raterInc > i) { if (rating + this.raterInc - i >= this.raterInc) { this.setImage(star, this.fullStar[type]); } else { this.setImage(star, this.halfStar[type]); } } else { this.setImage(star, this.emptyStar[type]); } if (actionable) { (function(i) { star.className += ' js-kit-rater'; star.onmouseover = function() { inf(); self.hover(i); } star.onmouseout = outf; star.onclick = function() { self.rate(i); } })(i); } else { star.className += ' js-kit-objIcon'; } node.appendChild(star); } } if (actionable) { node.style.cursor = 'pointer'; } return node; } JSRC.prototype.getCommentsAppObject = function() { if (this.isStandalone()) { return null; } else { return $JSKitGlobal.getCommentsAppObject(this.uniq); } } JSRC.prototype.hasCommentsAppObject = function() { return this.getCommentsAppObject() ? true : false; } JSRC.prototype.clone = function(node, options) { if ( ! options) { options = {}; } var clone = new JSRC(node, { 'newRating' : { 'objSum' : this.objSum, 'objNum' : this.objNum, 'userRating' : this.userRating }, 'path' : options.path || this.config.path, 'uniq' : options.uniq || this.config.uniq, 'view' : options.view || this.config.view, 'notop' : options.notop || this.config.notop, 'commentprompt' : options.commentprompt || this.config.commentprompt, 'starcolor' : options.starcolor || this.config.starcolor, 'usercolor' : options.usercolor || this.config.usercolor, 'imageurl' : options.imageurl || this.config.imageurl, 'imagesize' : options.imagesize || this.config.imagesize, 'menu' : options.menu || this.config.menu }); return clone; } // Part of externally useable API JSRC.prototype.rerender = function() { this.getRatingDataFromServer(); } JSRC.prototype.newRating = function() { var args = arguments; if(typeof args[0] != 'object') args = [ args[3], args[4], args[5] || {} ]; var community = args[0]; var user = args[1] || { Sum: 0 }; var opts = args[2] || { admin: false}; this.isAdmin = opts.admin; if(user.frozen) this.config.freeze = "yes"; this.objSum = community.Sum; this.objNum = community.Num; this.objVotes = community.Votes || community.Num; this.userRating = user.Sum; if(this.config.view.match(/score/)){ if(this.objNum){ this.objAvgStarRating = JSKitLib.round(((this.objSum / this.objNum)-(this.scale+this.raterInc)/2)/ this.raterInc, 1); } else { this.objAvgStarRating = 0; } } else { this.objAvgStarRating = JSKitLib.round((this.objSum / this.objNum) / this.raterInc, 1); } this.objEffRating = Math.round(this.objSum / this.objNum) || 0; // Used for star display purposes if(this.refreshScheduled) { clearTimeout(this.refreshScheduled); this.refreshScheduled = null; } if (this.constructed) { this.refreshTextTotal(); this.refreshObjRating(); if(this.config.view.match(/score/)){ this.refreshUDRating(); } else { this.refreshRating(); } } else { this.constructed = true; this.display(); } // TODO: use JSKitGlobal if (window.$J$PRA && typeof $J$PRA == 'object') { for (var i=0; i < $J$PRA.length; i++) { $J$PRA[i].updateComposite(); } } } JSRC.prototype.showInfoBox = function(xOpts) { // Only one infobox should be displayed at a time JSKitLib.map(function(obj) { obj.hideInfoBox(); }, $JRA); var div = this.cr('div'); var pos = JSKitLib.findPos(this.target); JSKitLib.setStyle(div, 'width: ' + JSRC.INFOBOX_WINDOW_WIDTH + 'px; position: absolute; top: ' + (pos[3] + 3) + 'px; z-index:10000;'); // If rating widget is too close to left side, show on the right side if (pos[0] > JSRC.INFOBOX_WINDOW_WIDTH || this.totalWidth >= JSRC.INFOBOX_WINDOW_WIDTH) { div.style.left = (pos[2] - JSRC.INFOBOX_WINDOW_WIDTH - 6) + 'px'; // 3px margin } else { div.style.left = pos[0] + 'px'; // 3px margin } this.infoBoxWrapper.appendChild(div); var infoBox = new JSRTC(div, { count: 3 }, this, xOpts); this.infoBox = infoBox; } if(!window.$JRTA) { var $JRTA = []; var $JRTLT = { vote: 'vote', votes: 'votes', msgNoHotItems: 'There are currently no Hot items on this site.', msgNoUserItems: 'Rating this will add it to your profile.', msgNoTopItems: 'There are currently no Top Rated items on this site.', adminMsgPermalinkHelp: 'This new "My" tab will allow your users to build their own personal list of their favorite content on your site.All you need to do is to implement permalinks and titles on your rateable content.For instructions, see item #8 on this page, or feel free to contact support@js-kit.com for assistance.', adminMsgNoRatings: 'There are currently no items in your Top Rated view. Listings will be displayed when enough votes have been collected.', adminMsgNoRatingsNoHot: 'There are currently no items in your Hot view. Listings will be displayed when enough data has been collected.', adminMsgAlert: 'Testing', hotInProgress: 'JS-Kit is measuring raters\' activity to present the most popular items here. Please allow some time for meaningful data to be collected.' }; var $JRTL = window.JSRTC_Translate || function(t) { return $JRTLT[t] || t; } } /* Constants */ JSRTC.DOMAIN = (window.location.protocol.substr(0, 4) != 'http' ? 'http:' : '') + 'http://js-kit.com'; JSRTC.IMG_DIR = JSRTC.DOMAIN + '/images/top'; JSRTC.SKIN_DIR = JSRTC.IMG_DIR + '/skins'; /* CSS Base Style */ // Note: This differs from JSRC.CSS in that the keys here are complete JSRTC.CSS = { // User Generic '.js-rTopFont': 'font-family: Arial, Helvetica, sans-serif; font-size: 10pt;', '.js-rTopTitleFont': 'font-weight: bold;', '.js-rTopTabFont': 'font-weight: bold;', '.js-rTopDetailFont': 'font-family: Arial, Helvetica, sans-serif; font-size: 8pt;', '.js-rTopRowColor1': '', '.js-rTopRowColor2': '', // General 'div.js-rTopFrame': 'background: #f8f8f8; border: solid 1px #e0e0e0; padding: 0; margin: 0.5em; -moz-user-select: none; -webkit-box-shadow: 0px 10px 50px #222; cursor: default; z-Index: 15000;', 'div.js-rTop': 'cursor: default; border: solid 1px #f8f8f8; padding:1px;', 'div.js-rTopBg': 'width: 100%;', // width needed for ie redraw 'div.js-rTopView': 'margin: -2pt -2px 0px; padding: 0 0 1px 0; zoom: 1;', 'div.js-rTopBody': 'margin: 0;', 'div.js-rTopTop': 'margin: 0;', 'div.js-rTopHot': 'margin: 0;', '.js-nsgecko': '-moz-user-select: none;', // Tab Navigation 'div.js-rTopNav': 'margin: 0;', 'div.js-rTopNavTabWrap': 'float: left;', 'div.js-rTopNavTab': 'height: 1.6em; padding-top: 0.4em; text-align: center; cursor: pointer; margin-top: 1px; border-left: 1px solid #e0e0e0; border-bottom: 1px solid #e0e0e0;', 'div.js-rTopNavTabActive': 'border-bottom: none; cursor: default;', 'div.js-rTopNavTabLeft': 'border-left: none;', 'div.js-rTopNavTabRight': 'border-right: none;', // Top Rated 'div.js-rTopItems': 'margin: 0; text-align: left;', 'div.js-rTopItem': 'padding: 0.3em 0.6em;', 'span.js-rTopItemCounter': 'margin-right: .3em;', 'a.js-rTopItemLink': 'zoom: 1;', 'span.js-rTopItemRating': 'margin: 0; white-space: nowrap', // User Top Rated 'div.js-rTopUserItems': 'margin: 0; text-align: left;', 'div.js-rTopUserItem': 'padding: 0.3em 0.6em;', 'a.js-rTopUserItemLink': 'zoom: 1;', 'div.js-rTopUserThisItems': 'margin: 0; text-align: left;', 'div.js-rTopUserThisItem': 'padding: 0.3em 0.6em;', 'a.js-rTopUserThisItemLink': 'zoom: 1;', // Top Scored 'div.js-rTopScoreItems': 'margin: 0; text-align: left;', 'div.js-rTopScoreItem': 'padding: 0.3em 0.6em 0.3em 0.6em;', 'span.js-rTopScoreItemCounter': 'margin-right: .3em;', 'div.js-rTopScoreItemInfo': 'margin-top: 0.0em;', 'a.js-rTopScoreItemLink': 'zoom: 1;', 'span.js-rTopScoreItemRating': 'margin: 0; white-space: nowrap', // Hot 'div.js-rTopHotItems': 'margin: 0; text-align: left;', 'div.js-rTopHotItem': 'padding: 0.3em 0.6em;', //'span.js-rTopHotItemInfo': 'margin: 0.2em .4em .3em 0;', 'a.js-rTopHotItemLink': 'zoom: 1;', // User Top Scored 'div.js-rTopUserScoreItems': 'margin: 0; text-align: left;', 'div.js-rTopUserScoreItem': 'padding: 0.3em 0.6em 0.3em 0.6em;', 'div.js-rTopUserScoreItemInfo': 'margin: 0.2em 0;', 'a.js-rTopUserScoreItemLink': 'zoom: 1;', 'div.js-rTopUserThisScoreItems': 'margin: 0; text-align: left;', 'div.js-rTopUserThisScoreItem': 'padding: 0.3em 0.6em 0.3em 0.6em;', 'div.js-rTopUserThisScoreItemInfo': 'margin: 0.2em 0;', 'a.js-rTopUserThisScoreItemLink': 'zoom: 1;', // Footer 'div.js-rTopFooter': 'padding: 0; margin: 0; overflow: hidden; position: relative; zoom: 1;', 'div.js-rTopPoweredBy': 'text-align:right; cursor: pointer; font-size:8pt; padding-bottom: 3px; padding-right:5px;', 'div.js-rTopPoweredByLink': 'font-family: Arial; text-decoration: none;', 'div.js-rTopBodyMsg': 'padding: 0.7em 0.5em 0.3em 0.5em;', 'div.js-rTopBodyAdminMsg': 'padding: 0.7em 0.5em;', 'div.js-rTopBodyAdminMsgHeader': 'padding-bottom: 0.3em;', 'div.js-rTopBodyAdminMsgBody': '' } JSRTC.writeCSS = function() { var css = ''; for (prop in JSRTC.CSS) { css += prop + ' {' + JSRTC.CSS[prop] + '}'; } JSKitLib.addCss(css, "js-RatingsTopCssText"); } JSRTC.writeCSS(); /* Object and Methods */ // TODO: how do we want to handle skins, etc? JSRTC.writeSkinCSS = function() { var titleFont = ''; var tabFont = ''; var navTab = ''; var detailFont = ''; var msgBody = ''; var skin = 'ice'; if (skin != 'none') { var skinDir = JSRTC.SKIN_DIR + '/' + skin; var header = 'background: url(' + skinDir + '/navi-header-bg.gif) -20px top repeat; border: none;'; var footer = 'background-color: #fff'; var view = 'background: #ffffff url(' + JSRTC.IMG_DIR + '/navi-tab-front-bg.gif) top repeat-x;'; var rowColor2 = "background: #f8f8f8;"; var navTab = "background: url(" + JSRTC.IMG_DIR + "/navi-tab-back-bg.gif) 0 -1px repeat-x;"; var adminNote = 'color: #009933'; switch (skin) { case 'default': titleFont = ' color: #435362'; tabFont = ' color: #003366'; detailFont = ' color: #435362'; msgBody = ' color: #435362'; break; case 'ice': titleFont = ' color: #3d6883'; tabFont = ' color: #003366'; detailFont = ' color: #3d6883'; msgBody = ' color: #3d6883'; break; case 'silver': titleFont = ' color: #5d5954'; tabFont = ' color: #003366'; detailFont = ' color: #5d5954'; msgBody = ' color: #5d5954'; break; case 'suede': titleFont = ' color: #603a13'; tabFont = ' color: #9a6329'; detailFont = ' color: #603a13'; msgBody = ' color: #603a13'; break; default: break; } } else { var skinDir = JSRTC.SKIN_DIR + '/none'; var poweredBy = 'background: url(' + skinDir + '/navi-footer-buttons.gif) -20px -32px no-repeat;'; } var css = "div.js-rTopHeader {" + header + "}" + ".js-rTopTitleFont {" + titleFont + "}" + "div.js-rTopView {" + view + "}" + ".js-rTopTabFont {" + tabFont + "}" + "div.js-rTopNavTab {" + navTab + "}" + ".js-rTopDetailFont {" + detailFont + "}" + "div.js-rTopFooter {" + footer + "}" + "div.js-rTopPoweredByLink {" + tabFont + "}" + ".js-rTopRowColor2 {" + rowColor2 + "}" + "div.js-rTopBodyMsgBody {" + msgBody + "}" + "div.js-rTopBodyAdminMsgBody {" + msgBody + "}" + "div.js-rTopNavTabActive { background: none; }" + "a.js-rTopItemLink {" + tabFont + "}" + "a.js-rTopScoreItemLink {" + tabFont + "}" + "a.js-rTopHotItemLink {" + tabFont + "}" + "a.js-rTopUserItemLink {" + tabFont + "}" + "a.js-rTopUserScoreItemLink {" + tabFont + "}" + "div.js-rTopBodyAdminMsgHeader {" + adminNote + "}" ; JSKitLib.addCss(css, "js-RatingsTopSkinCss"); } JSRTC.writeSkinCSS(); /* Class JSRTC */ function JSRTC(target, options, parentObj, xOpts) { this.jtaIndex = $JRTA.length; $JRTA.push(this); this.cr = function(tag) { return document.createElement(tag); } var wl = window.location; this.parentObj = parentObj; this.target = target; // Tab/Body data this.views = []; this.part = {}; // TR, HH, HD, HW parent object this.starWidth = 9; this.starHeight = 9; var self = this; /* Config */ this.config = {}; this.config.inline = {}; this.config.server = {}; // config from server, or recently saved this.config.get = function(key) { return self.config.inline[key] || self.config.server[key] }; this.config.getInline = function(key) { return self.config.inline[key] }; this.config.getServer = function(key) { return self.config.server[key] }; // TODO: change over to standard config function var iConfig = {}; iConfig.skin = options["skin"] || 'default'; iConfig.target = options["target"] || ''; iConfig.category = options["category"] || ''; if (options["count"]) iConfig.count = options["count"]; this.config.inline = iConfig; this.domain = target.getAttribute("site") || wl.host; this.domain = this.domain.replace(/^[a-z]+:\/\//, ''); this.domain = wl.protocol + "//" + this.domain; this.server = function(smod, ext, data) { var wl = window.location; var sc = self.cr("script"); sc.setAttribute("charset", "utf-8"); var domain; if (self.domain) { domain = self.domain; } else { domain = wl.protocol + "//" + wl.host; } var categ = self.config.get('category') ? "&category=" + self.config.get('category') : ""; sc.src = JSRTC.DOMAIN + '/' + smod + ext + "?ref=" + encodeURIComponent(domain + "/") + "&" + data + categ self.target.appendChild(sc); return false; } this.serverPut = function(ext, data) { return self.server("navapi.cgi/", ext, data); } var maxAdSize = function(prepend) { var styleVar = function(name) { var cs = self.target.currentStyle || document.defaultView.getComputedStyle(self.target, null); var v = cs[name] || self.target.style[name] || 0; var a = String(v).match(/^([0-9]+)px/); return a ? a[1] : 0; } var ww = styleVar('width'); var w = self.target.offsetWidth; var h = 0; return prepend + w + "x" + h; } // Process xOpts (additional values we may need passed in by callee) this.xOpts = (typeof xOpts == 'object') ? xOpts : {}; self.server("bestof", "-data.js","app=mininav&jx="+self.jtaIndex+"&count="+self.config.get('count')); } // TODO: templates should all be dynamic JSRTC.prototype.getMainTemplate = function() { var html = '' + '' + '' + '' + '' // View is instance of a Tab/Body + '' + '' // Tab Navigation + '' // Body + '' // Top Footer + '' + 'Powered by JS-Kit' + '' + '' + '' // js-rTopBg + '' // js-rTop + '' ; return html; } JSRTC.prototype.dtBodyAdminMsg = '' + '' + 'Hello admin:' + '' + '' + '' ; JSRTC.prototype.dtBodyMsg = '' + '' + '' ; JSRTC.prototype.dtBodyTop = '' + 'Sitewide top rated objects' + '' + '' + '{title}' + '' + '' + '' + '' + '{rating} ({votes})' + '' + '' + '' + '' + '' ; JSRTC.prototype.dtBodyTopScore = '' + 'Sitewide top rated objects' + '' + '' + '{title}' + '' + '' + '' + '' + '{rating} ({votes})' + '' + '' + '' + '' + '' ; JSRTC.prototype.dtBodyHot = '' + 'Sitewide hot objects' + '' + '' + '{title}' + '' + ' ({votes})' + '' + '' + '' + '' ; JSRTC.prototype.dtBodyUser = '' + '' + 'My vote on this object' + '' + '' + '{title}' + '' + '' + '' + '' + ' ' // Needed for even spacing with dtBodyTop + '' + '' + '' + '' + '' + '' + 'My recent top ratings' + '' + '' + '{title}' + '' + '' + '' + '' + ' ' // Needed for even spacing with dtBodyTop + '' + '' + '' + '' + '' + '' ; JSRTC.prototype.dtBodyUserScore = '' + '' + 'My vote on this object' + '' + '' + '' + '' + '' + '{title}' + '' + '' + '' + '' + '' + 'My recent top ratings' + '' + '' + '' + '' + '' + '{title}' + '' + '' + '' + '' + '' + '' ; JSRTC.prototype.addChild = function(to, what) { if(arguments.length == 3 && arguments[2]) to.insertBefore(what, to.firstChild); else to.appendChild(what); } JSRTC.prototype.html = function() { var div = this.cr("div"); for(var text = '', i = 0; i < arguments.length; i++) text += arguments[i]; div.innerHTML = text; var ch = div.firstChild; div = null; return ch; } JSRTC.prototype.mapClass2Object = function(ctl, e) { if(e.className) { var arr = String(e.className).split(/[ ]+/); JSKitLib.map(function(el) { ctl[el] = e }, arr); } if(e.name) ctl[e.name] = e; try { var self = this; JSKitLib.map(function(child) { self.mapClass2Object(ctl, child); }, e.childNodes); } catch(e){} return ctl; } JSRTC.prototype.gtmpl = function(t) { var lowercase = function(a, m) { return String(m).toLowerCase(); } t = t.replace(/^[^<]*(<.*>)[^>]*$/m, "$1"); t = t.replace(/(<[\/]?[A-Z]+)/g, lowercase); t = t.replace(/{Label:([^}]*)}/g,function(a,m){return $JRTL(m);}); return t; } JSRTC.prototype.tmpl = function(t, obj) { var self = this; t = self.gtmpl(t); var purify = function(text) { var text = String(text).replace(/^[ \s]+|[ \s]+$/, ''); text = text.replace(/([^&<>\s]{12})([^&<>\s]{12})/g, '$1$2'); text = text.replace(/[ \t\r\n]+/g, ' '); return text; } t = t.replace(/{([A-Za-z0-9]+)}/g,function(a,m){return obj.hasOwnProperty(m)?purify(obj[m]):'{'+m+'}';}); return t; } JSRTC.prototype.getMiniStars = function(rating, scale) { rating = Math.round(rating); var fullStar = this.config.get('image1url') || JSRTC.DOMAIN + '/images/stars/gold-tiny.png'; var emptyStar = this.config.get('image2url') || JSRTC.DOMAIN + '/images/stars/gray-tiny.png'; var stars = JSKitLib.createMiniStarObject(rating, scale, { full: fullStar, empty: emptyStar, width: this.starWidth, height: this.starHeight }); return stars; } JSRTC.prototype.getMiniThumb = function(score) { var thumbImage = JSRTC.DOMAIN + '/images/stars/small-thumb.png'; var upDown = score >=0 ? 'up' : 'down'; var miniThumb = JSKitLib.createThumbImage({ ud: upDown, actionable: true, imageURL: thumbImage, ignoreEmpty: true, thumbWidth: 10, thumbHeight: 12 }); return miniThumb; } JSRTC.prototype.getScoreIcons = function(rating, scale) { rating = Math.round(rating); var fullStar = this.config.get('image1url') || JSRTC.DOMAIN + '/images/stars/gold-tiny.png'; var emptyStar = this.config.get('image2url') || JSRTC.DOMAIN + '/images/stars/gray-tiny.png'; var stars = JSKitLib.createMiniStarObject(rating, scale, { full: fullStar, empty: emptyStar, width: this.starWidth, height: this.starHeight }); return stars; } /* * Extract all info from our config and place in our object */ JSRTC.prototype.processConfig = function(config) { // Note: Until BestOf is ensured of having permalinks, we will // base our tab selection on whether or not a particular // rating div has a permalink or not var dataTypes = this.getServerDataTypes(); var myTab = (this.parentObj.config.view.match(/score/)) ? { type:"US", title:"My", active: true } : { type:"UR", title:"My", active: true } ; var topTab = (this.parentObj.config.view.match(/score/)) ? { type:"TS", title:"Top", active: true } : { type:"TR", title:"Top", active: true } ; if (this.parentObj.target.getAttribute('permalink')) { if (dataTypes['TR'] || dataTypes['TS'] || this.isAdmin) { this.views = [ myTab, topTab, { type:"HT", title:"Hot", active: true }, { type:"RI", title:"Info", active: true } ]; } else { this.views = [ myTab, { type:"RI", title:"Info", active: true } ]; } } else if ((dataTypes['UR'] && myTab.type == 'UR') || (dataTypes['US'] && myTab.type == 'US')) { this.views = [ myTab, { type:"RI", title:"Info", active: true } ]; } else { this.views = [ { type:"RI", title:"Info", active: true } ]; } } // Returns a hash of server provided data types JSRTC.prototype.getServerDataTypes = function() { var data = this.serverData[0].data; var dataTypes = {}; for (var i=0; i < data.length; i++) { dataTypes[data[i].type] = true; } return dataTypes; } JSRTC.prototype.toggleViews = function(id) { // Iterate through hide/unactivate as necessary var views = this.getActiveViews(); if (!views.length) return; for (var i=0; i < views.length; i++) { if (i != id) { JSKitLib.removeClass(views[i].tab, "js-rTopNavTabActive"); JSKitLib.hide(views[i].content); } } // Now display the proper view JSKitLib.addClass(views[id].tab, "js-rTopNavTabActive"); JSKitLib.show(views[id].content); } JSRTC.prototype.table = function(tr) { var self = this; var a = function(n, w) {var o=self.cr(n);o.appendChild(w);return o;} var t = a('table', a('tbody', tr)); var z = function(a) {t.setAttribute(a, '0')} z('cellSpacing'); z('cellPadding'); z('border'); return t; } JSRTC.prototype.getViews = function() { return this.views; } JSRTC.prototype.getActiveViews = function() { var views = this.views; var aViews = []; for (var i=0; i < views.length; i++) { if (typeof views[i] == 'object' && views[i].active) { aViews.push(views[i]); } } return aViews; } JSRTC.prototype.isViewActive = function(type) { var views = this.getActiveViews(); for (var i=0; i < views.length; i++) { if (typeof views[i] == 'object' && (views[i].type == type) && views[i].active) { return true; } } return false; } JSRTC.prototype.createTabs = function() { var self = this; var views = this.getActiveViews(); var numTabs = views.length; // TODO: Show no tab if only one // Calculate the width of each tab var width = Math.floor(100/numTabs); var adjWidth = (numTabs * width != 100) ? (100 - ((numTabs - 1) * width)) : width; var tr = this.cr('tr'); for (var i=0; i < views.length; i++) { var td = this.cr('td'); td.setAttribute('width', width + '%'); var tabWrap = this.cr('div'); tabWrap.className = "js-rTopNavTabWrap"; tabWrap.style.width = '100%'; var tabMain = this.cr('div'); tabMain.className = "js-rTopNavTab"; JSKitLib.preventSelect(tabMain); // preventSelect for tabs titles // Left, Right if (i==0) { td.setAttribute('width', adjWidth + '%'); JSKitLib.addClass(tabMain, "js-rTopNavTabLeft"); JSKitLib.addClass(tabMain, "js-rTopNavTabActive"); } else { if (i == (views.length - 1)) { JSKitLib.addClass(tabMain, "js-rTopNavTabRight"); } } var divTitle = document.createElement("div"); divTitle.style.display = "inline"; divTitle.innerHTML = views[i].title; (function(i) { tabMain.onclick = function() { self.toggleViews(i); self.positionAffiliate(); }; })(i); tabMain.appendChild(divTitle); tabWrap.appendChild(tabMain); views[i].tab = tabMain; // Obj ref to tab node td.appendChild(tabWrap); tr.appendChild(td); } var table = this.table(tr); table.setAttribute('width', '100%'); return table; } JSRTC.prototype.createBody = function(navData) { var self = this; var views = this.getActiveViews(); var contentDiv = this.cr('div'); for (var i=0; i < views.length; i++) { switch (views[i].type) { /* Rating Info */ case "RI": var content = this.parentObj.createInfoBox(); break; /* User Ratings */ case "UR": var content = this.createBodyUser(navData); break; case "US": var content = this.createBodyUserScore(navData); break; case "AA": var content = this.createBodyAdminMsg($JRTL('adminMsgAlert')); break; case "TR": var content = this.createBodyTop(navData); JSKitLib.preventSelect(content); break; case "TS": var content = this.createBodyTopScore(navData); JSKitLib.preventSelect(content); break; case "HT": var content = this.createBodyHot(navData); JSKitLib.preventSelect(content); break; case "EP" : /* Not handling EP */ break; case "PL" : var content = this.cr("div"); content.className = "js-kit-poll"; } if (typeof content == 'object') { views[i].content = content; contentDiv.appendChild(content); } } return contentDiv; } JSRTC.prototype.createBodyTop = function(navData) { var self = this; var body = this.html(this.dtBodyTop); var ctls = this.mapClass2Object({}, body); /* Top TR */ var tip = ctls['js-rTopItems']; var tTemplate = tip.innerHTML; tip.innerHTML = ''; var topItem = function(items, idx) { var item = items[idx]; var idiv = self.html(self.tmpl(tTemplate, item)); if (idx % 2 != 0) JSKitLib.addClass(idiv, "js-rTopRowColor2"); var ictls = self.mapClass2Object({}, idiv); var link = ictls['js-rTopItemLink']; if (item.url.match(/^[a-z]+:\/\//)) { link.href = item.url; } else { link.href = self.domain + item.url; } if (self.config.get('target')) { link.target = self.config.get('target'); } var stars = ictls['js-rTopItemStars']; stars.appendChild(item.stars); return idiv; } if (navData.part.TR.items.length) { JSKitLib.map(function(item, i, items) { self.addChild(tip, topItem(items, i)); }, navData.part.TR.items); } else { if (this.isAdmin) { tip.appendChild(this.createBodyAdminMsg($JRTL('adminMsgNoRatings'))); } else { tip.appendChild(this.createBodyMsg($JRTL('msgNoTopItems'))); } } return body; } JSRTC.prototype.createBodyTopScore = function(navData) { var self = this; var body = this.html(this.dtBodyTopScore); var ctls = this.mapClass2Object({}, body); /* Top TS */ var tip = ctls['js-rTopScoreItems']; var tTemplate = tip.innerHTML; tip.innerHTML = ''; var topItem = function(items, idx) { var item = items[idx]; var idiv = self.html(self.tmpl(tTemplate, item)); if (idx % 2 != 0) JSKitLib.addClass(idiv, "js-rTopRowColor2"); var ictls = self.mapClass2Object({}, idiv); var link = ictls['js-rTopScoreItemLink']; if (item.url.match(/^[a-z]+:\/\//)) { link.href = item.url; } else { link.href = self.domain + item.url; } if (self.config.get('target')) { link.target = self.config.get('target'); } var stars = ictls['js-rTopScoreItemStars']; stars.appendChild(item.stars); return idiv; } if (navData.part.TS.items.length) { JSKitLib.map(function(item, i, items) { self.addChild(tip, topItem(items, i)); }, navData.part.TS.items); } else { if (this.isAdmin) { tip.appendChild(this.createBodyAdminMsg($JRTL('adminMsgNoRatings'))); } else { tip.appendChild(this.createBodyMsg($JRTL('msgNoTopItems'))); } } return body; } JSRTC.prototype.createBodyUser = function(navData) { var self = this; var body = this.html(this.dtBodyUser); var ctls = this.mapClass2Object({}, body); /* Top UR */ var tip = ctls['js-rTopUserItems']; var tipthis = ctls['js-rTopUserThisItems']; var tTemplate = tip.innerHTML; var tThisTemplate = tipthis.innerHTML; tip.innerHTML = ''; tipthis.innerHTML = ''; var existOther = 0; var isThis = function(item) { return (String(item.path || '').toLowerCase() == String(self.parentObj.config.path || '').toLowerCase()); }; var userThisItem = function(pObj) { var item = {url: pObj.config.permalink,title: pObj.config.title}; var idiv = self.html(self.tmpl(tThisTemplate, item)); var ictls = self.mapClass2Object({}, idiv); var link = ictls['js-rTopUserThisItemLink']; if (item.url && item.url.match(/^[a-z]+:\/\//)) { link.href = item.url; } else { link.href = self.domain + (item.url ? item.url : ''); } if (self.config.get('target')) { link.target = self.config.get('target'); } var stars = ictls['js-rTopUserThisItemStars']; var istars = self.getMiniStars(pObj.userRating, 10); stars.appendChild(istars); return idiv; } var userItem = function(items, idx) { var item = items[idx]; if(isThis(item)) return undefined; existOther = 1; var idiv = self.html(self.tmpl(tTemplate, item)); if (idx % 2 != 0) JSKitLib.addClass(idiv, "js-rTopRowColor2"); var ictls = self.mapClass2Object({}, idiv); var link = ictls['js-rTopUserItemLink']; if (item.url.match(/^[a-z]+:\/\//)) { link.href = item.url; } else { link.href = self.domain + item.url; } if (self.config.get('target')) { link.target = self.config.get('target'); } var stars = ictls['js-rTopUserItemStars']; stars.appendChild(item.stars); return idiv; } if (navData.part.UR.items.length || (self.parentObj.userRating && self.parentObj.config.title && self.parentObj.config.permalink)) { if(self.parentObj.userRating && self.parentObj.config.title && self.parentObj.config.permalink){ var cd = userThisItem(self.parentObj); if(cd) self.addChild(tipthis, cd); ctls['js-rTopUserThis'].style.display = 'block'; } else { ctls['js-rTopUserThis'].style.display = 'none'; } JSKitLib.map(function(item, i, items) { var cd = userItem(items, i); if(cd) self.addChild(tip, cd); }, navData.part.UR.items); if(existOther){ ctls['js-rTopUserOther'].style.display = 'block'; } else { ctls['js-rTopUserOther'].style.display = 'none'; } } else { if (this.isAdmin) { if (this.parentObj.target.getAttribute('permalink')) { ctls['js-rTopUserOther'].style.display = 'block'; tip.appendChild(this.createBodyMsg($JRTL('msgNoUserItems'))); } else { ctls['js-rTopUserOther'].style.display = 'block'; tip.appendChild(this.createBodyAdminMsg($JRTL('adminMsgPermalinkHelp'))); } } else { ctls['js-rTopUserOther'].style.display = 'block'; tip.appendChild(this.createBodyMsg($JRTL('msgNoUserItems'))); } } return body; } JSRTC.prototype.createBodyUserScore = function(navData) { var self = this; var body = this.html(this.dtBodyUserScore); var ctls = this.mapClass2Object({}, body); /* Top UR */ var tip = ctls['js-rTopUserScoreItems']; var tipthis = ctls['js-rTopUserThisScoreItems']; var tTemplate = tip.innerHTML; var tThisTemplate = tipthis.innerHTML; tip.innerHTML = ''; tipthis.innerHTML = ''; var existOther = 0; var isThis = function(item) { return (String(item.path || '').toLowerCase() == String(self.parentObj.config.path || '').toLowerCase()); }; var userThisItem = function(pObj) { var item = {url: pObj.config.permalink,title: pObj.config.title}; var idiv = self.html(self.tmpl(tThisTemplate, item)); var ictls = self.mapClass2Object({}, idiv); var link = ictls['js-rTopUserThisScoreItemLink']; if (item.url && item.url.match(/^[a-z]+:\/\//)) { link.href = item.url; } else { link.href = self.domain + (item.url ? item.url : ''); } if (self.config.get('target')) { link.target = self.config.get('target'); } var stars = ictls['js-rTopUserThisScoreItemStars']; var istars = self.getMiniThumb(pObj.calcScore()); stars.appendChild(istars); return idiv; } var userItem = function(items, idx) { var item = items[idx]; if(isThis(item)) return undefined; existOther = 1; var idiv = self.html(self.tmpl(tTemplate, item)); if (idx % 2 != 0) JSKitLib.addClass(idiv, "js-rTopRowColor2"); var ictls = self.mapClass2Object({}, idiv); var link = ictls['js-rTopUserScoreItemLink']; if (item.url && item.url.match(/^[a-z]+:\/\//)) { link.href = item.url; } else { link.href = self.domain + (item.url ? item.url : ''); } if (self.config.get('target')) { link.target = self.config.get('target'); } var stars = ictls['js-rTopUserScoreItemStars']; stars.appendChild(item.stars); return idiv; } if (navData.part.US.items.length || (self.parentObj.userRating && self.parentObj.config.title && self.parentObj.config.permalink)) { if(self.parentObj.userRating && self.parentObj.config.title && self.parentObj.config.permalink){ var cd = userThisItem(self.parentObj); if(cd) self.addChild(tipthis, cd); ctls['js-rTopUserThisScore'].style.display = 'block'; } else { ctls['js-rTopUserThisScore'].style.display = 'none'; } JSKitLib.map(function(item, i, items) { var cd = userItem(items, i); if(cd) self.addChild(tip, cd); }, navData.part.US.items); if(existOther){ ctls['js-rTopUserOtherScore'].style.display = 'block'; } else { ctls['js-rTopUserOtherScore'].style.display = 'none'; } } else { if (this.isAdmin) { if (this.parentObj.target.getAttribute('permalink')) { ctls['js-rTopUserOtherScore'].style.display = 'block'; tip.appendChild(this.createBodyMsg($JRTL('msgNoUserItems'))); } else { ctls['js-rTopUserOtherScore'].style.display = 'block'; tip.appendChild(this.createBodyAdminMsg($JRTL('adminMsgPermalinkHelp'))); } } else { ctls['js-rTopUserOtherScore'].style.display = 'block'; tip.appendChild(this.createBodyMsg($JRTL('msgNoUserItems'))); } } return body; } JSRTC.prototype.createBodyAdminMsg = function(msg) { var body = this.html(this.dtBodyAdminMsg); var ctls = this.mapClass2Object({}, body); var msgBody = ctls["js-rTopBodyAdminMsgBody"]; msgBody.innerHTML = msg; return body; } JSRTC.prototype.createBodyMsg = function(msg) { var body = this.html(this.dtBodyMsg); var ctls = this.mapClass2Object({}, body); var msgBody = ctls["js-rTopBodyMsgBody"]; msgBody.innerHTML = msg; return body; } JSRTC.prototype.createBodyHot = function(navData) { var self = this; var body = this.html(this.dtBodyHot); var ctls = this.mapClass2Object({}, body); /* Hot */ var hotp = ctls['js-rTopHotItems']; var hTemplate = hotp.innerHTML; hotp.innerHTML = ''; var hotItem = function(items, idx) { var item = items[idx]; var idiv = self.html(self.tmpl(hTemplate, item)); if (idx % 2 != 0) JSKitLib.addClass(idiv, "js-rTopRowColor2"); var ictls = self.mapClass2Object({}, idiv); var link = ictls['js-rTopHotItemLink']; if (item.url.match(/^[a-z]+:\/\//)) { link.href = item.url; } else { link.href = self.domain + item.url; } if (self.config.get('target')) { link.target = self.config.get('target'); } return idiv; } if (navData.part.HT.items.length) { JSKitLib.map(function(item, i, items) { self.addChild(hotp, hotItem(items, i)); }, navData.part.HT.items); } else { var dataTypes = this.getServerDataTypes(); if (dataTypes.TR) { hotp.appendChild(this.createBodyMsg($JRTL('hotInProgress'))); } else { if (this.isAdmin) { hotp.appendChild(this.createBodyAdminMsg($JRTL('adminMsgNoRatingsNoHot'))); } else { hotp.appendChild(this.createBodyMsg($JRTL('msgNoHotItems'))); } } } return body; } JSRTC.prototype.displayTop = function(navData, opts) { var self = this; navData.Title = this.config.get('title'); var template = this.getMainTemplate(); var pdiv = this.html(this.tmpl(template, navData)); var ctls = this.mapClass2Object({}, pdiv); this.ctls = ctls; /* Navigation Tabs */ var topNav = ctls['js-rTopNav']; topNav.appendChild(this.createTabs()); /* Main Content */ var topBody = ctls['js-rTopBody']; topBody.appendChild(this.createBody(navData)); /* Activate the Main View */ // TODO: handle for single view this.toggleViews(0); this.target.innerHTML = ''; this.addChild(this.target, pdiv); if (opts.ad) { //this.displayAd(opts.ad); } } JSRTC.prototype.displayAd = function(ad) { /* Ads */ if (typeof ad == 'object' && ad.data) { if (ad.flags && ad.flags.match(/a/)) { try { eval("ad.data = " + ad.data); this.doAffiliateAbsolute(ad); } catch(e) {}; } else { if (ad.data.match(/