/** * Copyright (c) 2008 Google Inc. * * You are free to copy and use this sample. * License can be found here: http://code.google.com/apis/ajaxsearch/faq/#license */ function GSvideoBar(barRoot, opt_playerRoot, options) { this.processArguments(barRoot, opt_playerRoot, options); this.setGlobals(); this.buildSuperStructure(); this.buildSearchControl(); // if we have an auto execute list, then start it up if (this.autoExecuteMode) { this.cycleTimeClosure = this.methodClosure(this, GSvideoBar.prototype.cycleTimeout, [null]); // if there is only a single item in the execute list, then // disable autoExecuteMode... if ( this.executeList.length == 1) { this.switchToListItem(0); } else { this.cycleTimeout(); } } } // cycle time for selecting a video set GSvideoBar.CYCLE_TIME_EXTRA_SHORT = 3000; GSvideoBar.CYCLE_TIME_SHORT = 10000; GSvideoBar.CYCLE_TIME_MEDIUM = 15000; GSvideoBar.CYCLE_TIME_LONG = 30000; // cycle mode GSvideoBar.CYCLE_MODE_RANDOM = 1; GSvideoBar.CYCLE_MODE_LINEAR = 2; GSvideoBar.MAX_CACHE_LIFETIME = 50; GSvideoBar.MIN_CACHE_LIFETIME = 2; GSvideoBar.DEFAULT_CACHE_LIFETIME = 2; GSvideoBar.MAX_ERROR_COUNT = 4; GSvideoBar.DEFAULT_QUERY = "VW GTI"; GSvideoBar.THUMBNAILS_SMALL = 1; GSvideoBar.THUMBNAILS_MEDIUM = 2; // floating player option GSvideoBar.PLAYER_ROOT_FLOATING = "floating"; GSvideoBar.prototype.processArguments = function(barRoot, opt_playerRoot, opt_options) { this.floatingPlayerBox = null; this.barRoot = barRoot; this.playerRoot = opt_playerRoot; this.statusRoot = null; this.externalMaster = null; this.verticalMode = true; this.thumbSize = GSvideoBar.THUMBNAILS_MEDIUM; this.autoExecuteMode = false; this.executeList = new Array(); this.cycleTime = GSvideoBar.CYCLE_TIME_MEDIUM; this.cycleMode = GSvideoBar.CYCLE_MODE_RANDOM; this.cycleNext = 0; this.cycleTimer = null; this.cacheLifetime = GSvideoBar.DEFAULT_CACHE_LIFETIME; // set defaults that are changable via options this.resultSetSize = GSearch.SMALL_RESULTSET; this.ST_ALL_DONE = GSearch.strings["im-done"]; if (opt_options) { // option.largetResultSet if (opt_options.largeResultSet && opt_options.largeResultSet == true ) { this.resultSetSize = GSearch.LARGE_RESULTSET; } else { this.resultSetSize = GSearch.SMALL_RESULTSET; } if ( opt_options.master ) { this.externalMaster = opt_options.master; } if (opt_options.horizontal && opt_options.horizontal == true ) { this.verticalMode = false; } else { this.verticalMode = true; } if (opt_options.thumbnailSize) { if (opt_options.thumbnailSize == GSvideoBar.THUMBNAILS_MEDIUM ) { this.thumbSize = GSvideoBar.THUMBNAILS_MEDIUM; } else if ( opt_options.thumbnailSize == GSvideoBar.THUMBNAILS_SMALL ) { this.thumbSize = GSvideoBar.THUMBNAILS_SMALL; } else { this.thumbSize = GSvideoBar.THUMBNAILS_MEDIUM; } } if (opt_options.string_allDone) { this.ST_ALL_DONE = opt_options.string_allDone; } // the auto execute list contains // a cycleTime value, a cycleMode value, and an array // of searchExpressions if (opt_options.autoExecuteList) { // if specified and valid, then use it, otherwise // use default set above if (opt_options.autoExecuteList.cycleTime) { var cycleTime = opt_options.autoExecuteList.cycleTime; if (cycleTime == GSvideoBar.CYCLE_TIME_EXTRA_SHORT || cycleTime == GSvideoBar.CYCLE_TIME_SHORT || cycleTime == GSvideoBar.CYCLE_TIME_MEDIUM || cycleTime == GSvideoBar.CYCLE_TIME_LONG ) { this.cycleTime = cycleTime; } } if (opt_options.autoExecuteList.cycleMode) { var cycleMode = opt_options.autoExecuteList.cycleMode; if (cycleMode == GSvideoBar.CYCLE_MODE_RANDOM || cycleMode == GSvideoBar.CYCLE_MODE_LINEAR) { this.cycleMode = cycleMode; } } // now grab the list... if (opt_options.autoExecuteList.executeList && opt_options.autoExecuteList.executeList.length > 0 ) { // grab from the list for (var i=0; i < opt_options.autoExecuteList.executeList.length; i++) { this.executeList.push( this.newListItem(opt_options.autoExecuteList.executeList[i])); } this.autoExecuteMode = true; this.currentIndex = 0; if (opt_options.autoExecuteList.statusRoot) { this.statusRoot = opt_options.autoExecuteList.statusRoot; } } } } } GSvideoBar.prototype.resetAutoExecuteListItems = function(newList) { if (this.autoExecuteMode && newList.length > 0) { // stop the timer... if (this.cycleTimer) { clearTimeout(this.cycleTimer); this.cycleTimer = null; } // clear the status area if (this.statusRoot) { this.removeChildren(this.statusRoot); } // nuke the old list this.executeList = new Array(); // build the new list for (var i=0; i < newList.length; i++) { this.executeList.push(this.newListItem(newList[i])); } this.currentIndex = 0; if (this.statusRoot) { this.populateStatusRoot(); } if ( this.executeList.length == 1) { this.switchToListItem(0); } else { this.cycleTimeout(); } } } GSvideoBar.prototype.setGlobals = function() { this.br_AgentContains_cache_ = {}; // subserstructure boxes this.CL_PLAYERBOX = "playerBox_gsvb"; this.CL_PLAYING = "playerBox_gsvb playing_gsvb"; this.CL_IDLE = "playerBox_gsvb idle_gsvb"; this.CL_FLOATING_BOX = "floatingPlayerBox_gsvb"; this.CL_FLOATING_BRANDING = "floatingBranding_gsvb"; this.CL_FLOATING_BOX_PLAYING = "floatingPlayerBox_gsvb playing_gsvb"; this.CL_FLOATING_BOX_IDLE = "floatingPlayerBox_gsvb idle_gsvb"; this.CL_FLOATING_PLAYER = "floatingPlayer_gsvb"; this.CL_FLOATING_PLAYER_PLAYING = "floatingPlayer_gsvb playing_gsvb"; this.CL_FLOATING_PLAYER_IDLE = "floatingPlayer_gsvb idle_gsvb"; this.CL_PLAYERINNERBOX = "playerInnerBox_gsvb"; this.CL_VIDEOBARBOX = "videoBarBox_gsvb"; this.CL_VIDEOBARBOXFULL = "videoBarBox_gsvb full_gsvb"; this.CL_VIDEOBARBOXEMPTY = "videoBarBox_gsvb empty_gsvb"; // major app states this.CL_ACTIVE = "active_gsvb"; // player this.CL_PLAYER = "player_gsvb"; this.CL_ALLDONE = "alldone_gsvb"; this.CL_TITLE = "title_gsvb"; // results this.CL_RESULTSBOX = "resultsBox_gsvb"; this.CL_BRANDINGBOX = "brandingBox_gsvb"; this.CL_RESULTTABLE_VERTICAL = "resultTable_gsvb vertical_gsvb"; this.CL_RESULTTABLE_HORIZONTAL = "resultTable_gsvb horizontal_gsvb"; this.CL_RESULTCELL = "resultCell_gsvb"; this.CL_RESULTDIV = "resultDiv_gsvb"; this.CL_RESULTDIV_SMALL = "resultDiv_gsvb smallResultDiv_gsvb"; // status this.CL_STATUSBOX = "statusBox_gsvb"; this.CL_STATUSITEM = "statusItem_gsvb"; this.CL_STATUSITEM_SELECTED = "statusItem_gsvb statusItemSelected_gsvb"; this.smallResultBoxHeight = 39; this.resultBoxHeight = 77; } GSvideoBar.prototype.buildSuperStructure = function() { // build the player box if we are a master, if not // link up to the master's player if (this.externalMaster == null) { if ( this.playerRoot == GSvideoBar.PLAYER_ROOT_FLOATING ) { this.floatingPlayerBox = this.createDiv(null, this.CL_FLOATING_BOX_IDLE); this.playerRoot = this.createDiv(null, this.CL_FLOATING_PLAYER_IDLE); document.body.appendChild(this.floatingPlayerBox); document.body.appendChild(this.playerRoot); if (this.br_IsMac()) { // disable opacity on mac this.floatingPlayerBox.style.opacity = "1.00"; } } else { this.removeChildren(this.playerRoot); } this.playerBox = this.createDiv(null, this.CL_PLAYERBOX); this.playerAllDone = this.createDiv(this.ST_ALL_DONE, this.CL_ALLDONE); this.playerAllDone.onclick = this.methodClosure(this, this.stopVideo, []); this.playerInnerBox = this.createDiv(null, this.CL_PLAYERINNERBOX); this.playerBox.appendChild(this.playerAllDone); this.playerBox.appendChild(this.playerInnerBox); this.playerRoot.appendChild(this.playerBox); this.cssSetClass(this.playerBox, this.CL_IDLE); } this.player = null; // create the videoBar box this.removeChildren(this.barRoot); this.barBox = this.createDiv(null, this.CL_VIDEOBARBOX); this.barRoot.appendChild(this.barBox); // add results box and branding box this.resultsBox = this.createDiv(null, this.CL_RESULTSBOX); this.barBox.appendChild(this.resultsBox); this.cssSetClass(this.barBox, this.CL_VIDEOBARBOXEMPTY); // clear and optionally populate the status area if (this.statusRoot) { this.populateStatusRoot(); } } GSvideoBar.prototype.buildSearchControl = function() { this.vs = new GvideoSearch(); this.vs.setResultSetSize(this.resultSetSize); this.vs.setSearchCompleteCallback(this, GSvideoBar.prototype.searchComplete, [true]); this.vsBypass = new GvideoSearch(); this.vsBypass.setResultSetSize(this.resultSetSize); this.vsBypass.setSearchCompleteCallback(this, GSvideoBar.prototype.searchComplete, [false]); } GSvideoBar.prototype.execute = function(query) { this.vsBypass.execute(query); } GSvideoBar.prototype.executeInternal = function(query) { this.vs.execute(query); } GSvideoBar.prototype.clearAllResults = function() { this.cssSetClass(this.barBox, this.CL_VIDEOBARBOXEMPTY); } GSvideoBar.prototype.searchComplete = function(fromListItem) { var results = null; if (fromListItem) { var currentListItem = this.executeList[this.currentIndex]; if (this.vs.results && this.vs.results.length > 0) { // populate cache currentListItem.results = new Array(); currentListItem.cacheCount = 1; currentListItem.errorCount = 0; for (var i = 0; i < this.vs.results.length; i++) { currentListItem.results.push(this.vs.results[i]); } results = currentListItem.results; } else { currentListItem.errorCount++; // if the error is due to a bad search term, then // nuke right away if (this.vs.completionStatus == 200) { currentListItem.errorCount = GSvideoBar.MAX_ERROR_COUNT + 1; } } } else { // normal .execute called, no caching... if (this.vsBypass.results && this.vsBypass.results.length > 0) { results = this.vsBypass.results; } } this.processResults(results); } GSvideoBar.prototype.processResults = function(results) { if ( results && results.length > 0) { this.cssSetClass(this.barBox, this.CL_VIDEOBARBOXFULL); this.removeChildren(this.resultsBox); var cell; var table; var row = null; if (this.verticalMode) { table = this.createTable(this.CL_RESULTTABLE_VERTICAL); } else { table = this.createTable(this.CL_RESULTTABLE_HORIZONTAL); } table.setAttribute("align", "center"); for (var i = 0; i < results.length; i++) { var res = results[i]; var imageScaler; var resultBoxHeight; var resultClass = null; if (this.thumbSize == GSvideoBar.THUMBNAILS_MEDIUM ) { // full size image imageScaler = {width:120,height:90}; resultBoxHeight = this.resultBoxHeight; resultClass = this.CL_RESULTDIV; } else { // small size image imageScaler = {width:50,height:37}; resultBoxHeight = this.smallResultBoxHeight; resultClass = this.CL_RESULTDIV_SMALL; } var scaled = GSearch.scaleImage(res.tbWidth, res.tbHeight, imageScaler); var img = this.createImage(res.tbUrl, scaled.width, scaled.height, null); if (this.externalMaster) { img.onclick = this.methodClosure(this.externalMaster, this.externalMaster.playVideo, [res]); } else { img.onclick = this.methodClosure(this, this.playVideo, [res]); } // manually set the top padding if ((resultBoxHeight - scaled.height) > 0) { var padTop = Math.round((resultBoxHeight - scaled.height)/2); img.setAttribute("vspace", padTop); } // compute duration var seconds = res.duration; var minutes = parseInt(seconds/60); var durationString; if (minutes > 0) { durationString = minutes + "m"; var remainder = seconds%60; if (remainder > 20) { durationString += " " + remainder + "s"; } } else { durationString = seconds + "s"; } var toolTip = res.titleNoFormatting + " ( " + durationString + " )"; var div = this.createDiv(null, resultClass); div.title = toolTip; div.appendChild(img); // create a new row for each result when in vertical mode // otherwise, jam everything into a single row. if (this.verticalMode) { row = this.createTableRow(table); } else { if (row == null) { row = this.createTableRow(table); } } cell = this.createTableCell(row, this.CL_RESULTCELL); cell.setAttribute("align", "center"); cell.appendChild(div); } // now add in the branding... row = this.createTableRow(table); var brandingOrientation; if (this.verticalMode) { cell = this.createTableCell(row, this.CL_RESULTCELL); brandingOrientation = GSearch.VERTICAL_BRANDING; } else { cell = this.createTableCell(row, this.CL_RESULTCELL); if (this.br_IsIE()) { cell.setAttribute("colSpan", results.length); } else { cell.setAttribute("colspan", results.length); } brandingOrientation = GSearch.HORIZONTAL_BRANDING; } GSearch.getBranding(cell, brandingOrientation, "http://www.youtube.com"); this.brandingCell = cell; this.resultsBox.appendChild(table); } else { this.cssSetClass(this.barBox, this.CL_VIDEOBARBOXEMPTY); } } GSvideoBar.prototype.playVideo = function(result) { this.stopVideo(); if (this.autoExecuteMode && this.cycleTimer) { clearTimeout(this.cycleTimer); this.cycleTimer = null; } if (result.playUrl && result.playUrl != "") { this.cssSetClass(this.playerBox, this.CL_PLAYING); if (this.floatingPlayerBox) { this.cssSetClass(this.floatingPlayerBox, this.CL_FLOATING_BOX_PLAYING); this.cssSetClass(this.playerRoot, this.CL_FLOATING_PLAYER_PLAYING); } this.player = GvideoSearch.createPlayer(result, this.CL_PLAYER); this.playerInnerBox.appendChild(this.player); // the title var title = this.createDivLink(result.url, result.title, null, this.CL_TITLE); this.playerInnerBox.appendChild(title); if (this.floatingPlayerBox) { var playerBounds = GSvideoBar.nodeBounds(this.playerRoot); var bounds = GSvideoBar.nodeBounds(this.barRoot); var x; var y; if (this.verticalMode) { x = bounds.x - playerBounds.width; y = bounds.y + bounds.height / 2 - playerBounds.height / 2; var brandingBounds = GSvideoBar.nodeBounds(this.brandingCell); y = y - brandingBounds.height / 2; if (x < 10) { x = bounds.x + bounds.width; } } else { x = bounds.x + bounds.width / 2 - playerBounds.width / 2; y = bounds.y - playerBounds.height; if (y < 10) { y = bounds.y + bounds.height; } } this.playerRoot.style.top = y + "px"; this.playerRoot.style.left = x + "px"; this.floatingPlayerBox.style.top = y - 10 + "px"; this.floatingPlayerBox.style.left = x - 10 + "px"; boxWidth = (playerBounds.width + 20) + "px"; this.floatingPlayerBox.style.width = boxWidth; this.floatingPlayerBox.style.height = (playerBounds.height + 20) + "px"; } } } GSvideoBar.prototype.stopVideo = function() { this.cssSetClass(this.playerBox, this.CL_IDLE); if (this.floatingPlayerBox) { this.cssSetClass(this.floatingPlayerBox, this.CL_FLOATING_BOX_IDLE); this.cssSetClass(this.playerRoot, this.CL_FLOATING_PLAYER_IDLE); } this.removeChildren(this.playerInnerBox); if (this.player) { delete(this.player); this.player = null; } if (this.autoExecuteMode && this.executeList.length > 1) { this.clearTimer(); this.cycleTimer = setTimeout(this.cycleTimeClosure, this.cycleTime); } } GSvideoBar.prototype.clearTimer = function() { if (this.cycleTimer) { clearTimeout(this.cycleTimer); this.cycleTimer = null; } } GSvideoBar.prototype.cycleTimeout = function() { // select a new video // execute a search // restart the timer if ( this.player == null ) { // if there is only a single item in the execute list, // run it if ( this.executeList.length == 1) { this.switchToListItem(0); } else { var index = 0; if (this.cycleMode == GSvideoBar.CYCLE_MODE_RANDOM) { var max = this.executeList.length - 1; index = Math.round(max * Math.random()); } else if (this.cycleMode == GSvideoBar.CYCLE_MODE_LINEAR){ index = this.cycleNext; this.cycleNext++; if (this.cycleNext >= this.executeList.length) { this.cycleNext = 0; } } this.switchToListItem(index); this.clearTimer(); this.cycleTimer = setTimeout(this.cycleTimeClosure, this.cycleTime); } } } /** * Autoexecute List Item Support */ GSvideoBar.prototype.newListItem = function(q) { var listItem = new Object(); listItem.node = null; listItem.query = q; listItem.results = new Array(); listItem.errorCount = 0; listItem.cacheCount = 0; return listItem; } GSvideoBar.prototype.switchToListItem = function(i) { // reset selcted class of previous item // note, first time through this sets // node 0 if (this.executeList[this.currentIndex].node) { this.cssSetClass(this.executeList[this.currentIndex].node, this.CL_STATUSITEM); } this.currentIndex = i; if (this.executeList[this.currentIndex].node) { this.cssSetClass(this.executeList[this.currentIndex].node, this.CL_STATUSITEM_SELECTED); } var queryTerm = this.executeList[this.currentIndex].query; var cacheResults = false; var currentListItem = null; currentListItem = this.executeList[this.currentIndex]; // if the error count of an item has reached max, reset query term if (currentListItem.errorCount > GSvideoBar.MAX_ERROR_COUNT) { currentListItem.errorCount = 0; queryTerm = GSvideoBar.DEFAULT_QUERY; currentListItem.query = queryTerm; } // if the listItem has no cached results, OR if // we have used the cached results several times // already, initiate a real search if (currentListItem.cacheCount == 0 || currentListItem.cacheCount > this.cacheLifetime ) { currentListItem.cacheCount = 0; this.executeInternal(queryTerm); } else { currentListItem.cacheCount++; this.processResults(currentListItem.results); } } GSvideoBar.prototype.populateStatusRoot = function() { this.removeChildren(this.statusRoot); this.statusBox = this.createDiv(null, this.CL_STATUSBOX); this.statusRoot.appendChild(this.statusBox); if ( this.executeList.length > 0) { for (var i=0; i < this.executeList.length; i++ ) { var listItem = this.executeList[i]; var displayTerm = listItem.query; // if we are looking at our special feed: terms, strip // feed: from the display var m = displayTerm.match(/feed:(top100|top100new)$/); if (m && m.length == 2) { displayTerm = m[1]; } var div = this.createDiv(displayTerm, this.CL_STATUSITEM); // add click handler... div.onclick = this.methodClosure(this, GSvideoBar.prototype.switchToListItem, [i] ); listItem.node = div; this.statusBox.appendChild(div); this.statusBox.appendChild(document.createTextNode(" ")); } } } /** * Static Helper Method */ GSvideoBar.methodCallback = function(object, method) { return function() { return method.apply(object, arguments); } } /** * Class methods */ GSvideoBar.prototype.methodClosure = function(object, method, opt_argArray) { return function() { return method.apply(object, opt_argArray); } } GSvideoBar.prototype.createDiv = function(opt_text, opt_className) { var el = document.createElement("div"); if (opt_text) { el.innerHTML = opt_text; } if (opt_className) { el.className = opt_className; } return el; } GSvideoBar.prototype.removeChildren = function(parent) { while (parent.firstChild) { parent.removeChild(parent.firstChild); } } GSvideoBar.prototype.removeChild = function(parent, child) { parent.removeChild(child); } GSvideoBar.prototype.cssSetClass = function(el, className) { el.className = className; } GSvideoBar.prototype.createTable = function(opt_className) { var el = document.createElement("table"); if (opt_className) { el.className = opt_className; } return el; } GSvideoBar.prototype.createTableRow = function(table, opt_className) { var tr = table.insertRow(-1); if (opt_className) { tr.className = opt_className; } return tr; } GSvideoBar.prototype.createTableCell = function(tr, opt_className) { var td = tr.insertCell(-1); if (opt_className) { td.className = opt_className; } return td; } GSvideoBar.prototype.createDivLink = function(href, text, opt_target, opt_className) { var div = this.createDiv(null, opt_className); var el = document.createElement("a"); el.href = href; el.appendChild(document.createTextNode(text)); if (opt_className) { el.className = opt_className; } if (opt_target) { el.target = opt_target; } div.appendChild(el); return div; } GSvideoBar.prototype.createImage = function(src, opt_w, opt_h, opt_className) { var el = document.createElement("img"); el.src = src; if (opt_w) { el.width = opt_w; } if (opt_h) { el.height = opt_h; } if (opt_className) { el.className = opt_className; } return el; } GSvideoBar.prototype.getNodeWidth = function(node) { return node.offsetWidth; } GSvideoBar.prototype.br_AgentContains_ = function(str) { if (str in this.br_AgentContains_cache_) { return this.br_AgentContains_cache_[str]; } return this.br_AgentContains_cache_[str] = (navigator.userAgent.toLowerCase().indexOf(str) != -1); } GSvideoBar.prototype.br_IsIE = function() { return this.br_AgentContains_('msie'); } GSvideoBar.prototype.br_IsMac = function() { return this.br_AgentContains_('macintosh') || this.br_AgentContains_('mac_powerpc'); } GSvideoBar.prototype.br_IsKonqueror = function() { return this.br_AgentContains_('konqueror'); } GSvideoBar.prototype.br_IsOpera = function() { return this.br_AgentContains_('opera'); } GSvideoBar.prototype.br_IsSafari = function() { return this.br_AgentContains_('safari') || this.br_IsKonqueror(); } GSvideoBar.prototype.br_IsNav = function() { return !this.br_IsIE() && !this.br_IsSafari() && this.br_AgentContains_('mozilla'); } GSvideoBar.prototype.br_IsWin = function() { return this.br_AgentContains_('win'); } GSvideoBar.nodeBounds = function(obj) { var result = {}; function fixRectForScrolling(r) { // Need to take into account scrolling offset of ancestors (IE already does // this) for (var o = obj.offsetParent; o && o.offsetParent; o = o.offsetParent) { if (o.scrollLeft) { r.x -= o.scrollLeft; } if (o.scrollTop) { r.y -= o.scrollTop; } } } // Mozilla if (obj.ownerDocument && obj.ownerDocument.getBoxObjectFor) { var box = obj.ownerDocument.getBoxObjectFor(obj); result.x = box.x; result.y = box.y; result.width = box.width; result.height = box.height; fixRectForScrolling(result); return result; } // IE if (obj.getBoundingClientRect) { var refWindow; if (obj.ownerDocument && obj.ownerDocument.parentWindow) { refWindow = obj.ownerDocument.parentWindow; } else { refWindow = window; } var rect = obj.getBoundingClientRect(); result.x = rect.left + GSvideoBar.GetIEScrollLeft(refWindow); result.y = rect.top + GSvideoBar.GetIEScrollTop(refWindow); result.width = rect.right - rect.left; result.height = rect.bottom - rect.top; return result; } // Fallback to recursively computing this var left = 0; var top = 0; for (var o = obj; o.offsetParent; o = o.offsetParent) { left += o.offsetLeft; top += o.offsetTop; } result.x = left; result.y = top; result.width = obj.offsetWidth; result.height = obj.offsetHeight; fixRectForScrolling(result); return result; } // Get the y position scroll offset. GSvideoBar.GetIEScrollTop = function(win) { if ("compatMode" in win.document && win.document.compatMode == "CSS1Compat") { return win.document.documentElement.scrollTop; } else { return win.document.body.scrollTop; } } // Get the x position scroll offset. GSvideoBar.GetIEScrollLeft = function(win) { if ("compatMode" in win.document && win.document.compatMode == "CSS1Compat") { return win.document.documentElement.scrollLeft; } else { return win.document.body.scrollLeft; } }