/* Last modified 2008-04-01 10:00 AM by Jeff Ober */ var debug = false; function logMessage(msg) { try { logMessage(err); } catch (err) { return false; } } var Gallery = Class.create(); /* Possible initialization arguments: feed: path to gallery xml (required); showInterstitials: bool to show interstitial ads (default false) adInterstitial: number of clicks to reach interstitial ad (default 5) */ Gallery.prototype = { initialize: function(args) { if (!args) { error('There was an error connecting to the gallery: no gallery was specified.'); throw new Error('Gallery class requires at least one argument.'); } else if (args.feed === undefined) { error('There was an error connecting to the gallery: no gallery was specified.'); throw new Error('No gallery selected in instance creation.'); } this.feed = args.feed; this.xml = null; this.rawMedia = null; this.sort = 'Manual'; this.media = new Array(); this.currentIndex = 0; // Instantiate adswitching this.enableTimedSwitching = (args.enableTimedSwitching) ? args.enableTimedSwitching : false // defaults to false this.adswitcher = new AdSwitcher({ switchPeriod: 20, timedSwitching: this.enableTimedSwitching }); // Configure interstitial ads (built into this class) this.showInterstitials = (args.showInterstitials) ? args.showInterstitials : false; // defaults to false this.adInterstitial = (args.adInterstitial) ? args.adInterstitial : 5; // defaults to 5 this.numClicks = 0; // Get other possible options this.determineBuyPhotoFromXML = (args.determineBuyPhotoFromXML) ? args.determineBuyPhotoFromXML : false; // defaults to false }, getXML: function() { // Gets xml data from server. Runs this.processXML on success. var ajax = new Ajax.Request(this.feed,{ onSuccess: function(rs) { this.processXML(rs); }.bind(this), onFailure: function(t) { if (debug == true) { var err = t.statusText; logMessage(err); throw new Error(err); useAltGallery(); } else { useAltGallery(); } }, on404: function(t) { if (debug == true) { var err = t.status + ' -- ' + t.statusText; logMessage(err); throw new Error(err); useAltGallery(); } else { useAltGallery(); } }, onException: function(rs,err) { if (debug == true) { logMessage(err); throw new Error(err); useAltGallery(); } else { useAltGallery(); } } }); }, processXML: function(rs) { // Takes response xml and turns into useable object, then displays first image and runs buttonState(). /* Workaround: Media Hub passes as application/xhtml+xml (per w3c standards) and IE only handles application/xml */ if (navigator.appName == 'Microsoft Internet Explorer') { var text = rs.responseText; this.xml = new ActiveXObject('Microsoft.XMLDOM'); this.xml.async="false"; this.xml.loadXML(text); // Verify that the xml loaded properly if (null == this.xml.documentElement.nodeName) { if (debug == true) { var err = "Could not load XML."; logMessage(err); throw new Error(err); useAltGallery(); } else { useAltGallery(); } } } else { this.xml = rs.responseXML; } this.rawMedia = this.xml.getElementsByTagName('media'); if (typeof forcedSorting != 'undefined') { // Quick insert to prevent problems until this feature is deployed in the Apparatus this.sort = (forcedSorting != false) ? forcedSorting : this.xml.getElementsByTagName('tag_feed_order')[0].firstChild.nodeValue; } else { this.sort = this.xml.getElementsByTagName('tag_feed_order')[0].firstChild.nodeValue; } this.processMedia(); this.displayIndex(); this.buttonState(); }, validateSortMethod: function(mtd) { // Tests to verify that all values by which we are sorting are not equal var sortField = null; switch (mtd) { case 'By Prominence': sortField = 'prominence'; break; case 'Manual': sortField = 'order'; break; case 'By Submission Date Ascending': sortField = 'submitted'; break; case 'By Submission Date Descending': sortField = 'submitted'; break; case 'By Authored On Date Ascending': sortField = 'authored'; break; case 'By Authored On Date Descending': sortField = 'authored'; break; default: break; } var testValue = eval('this.media[0].'+sortField); var testResult = this.media.findAll(function(n) { return (eval('n.'+sortField) == testValue) ? true : false; }); if (sortField != null) { return (testResult.length == this.media.length) ? false : true; } }, processMedia: function() { // Creates object out of media items in xml, then orders it according to global order field in xml. $A(this.rawMedia).each(function(media) { /* This is apparently not supported by our favorite standards-compliant browser, IE. Object.extend(media, { getTag: function(tagName) { var tagNode = this.getElementsByTagName(tagName)[0]; return (tagNode.childNodes.length > 0) ? tagNode.firstChild.nodeValue : ''; } });*/ function getTag(tagName) { var tagNode = media.getElementsByTagName(tagName)[0]; return (tagNode.childNodes.length > 0) ? tagNode.firstChild.nodeValue : ''; }; var thisMedia = new Object(); thisMedia.id = getTag('id'); thisMedia.thumbnail = getTag('thumbnail_filename'); thisMedia.slideshow = getTag('slideshow_filename'); thisMedia.cutline = getTag('cutline'); thisMedia.credit = getTag('credit'); thisMedia.credit += (getTag('source') != '') ? ' ('+getTag('source')+')' : ''; thisMedia.credit = this.formatCredit(thisMedia.credit); thisMedia.buyOpt = getTag('buy_photo_option'); thisMedia.submitted = (getTag('submitted_on').length > 0) ? this.unCoxifyDateTime(getTag('submitted_on')) : ''; thisMedia.authored = (getTag('authored_on').length > 0) ? this.unCoxifyDateTime(getTag('authored_on')) : ''; thisMedia.prominence = getTag('feed_prominence'); thisMedia.order = getTag('feed_order'); this.media.push(thisMedia); }.bind(this)); // Check sanity on sort method if (this.validateSortMethod(this.sort) == false) { this.sort = defaultSortMethod; } var sort = this.sort; this.media = this.media.sort(function(x, y) { switch (sort) { case 'Random': return Math.round(Math.random()*1000) - Math.round(Math.random()*1000); case 'By Prominence': return x.prominence - y.prominence; case 'Manual': return parseInt(x.order) - parseInt(y.order); case 'By Submission Date Ascending': return x.submitted - y.submitted; case 'By Submission Date Descending': return y.submitted - x.submitted; case 'By Authored On Date Ascending': return x.authored - y.authored; case 'By Authored On Date Descending': return y.authored - x.authored; default: return 0; } }); }, unCoxifyDateTime: function(dt) { // Takes cox-formatted datetime and turns it into seconds //e.g. July 30, 2006 8:55 PM EDT try { // tokenize dt = dt.replace(/,/, '').replace(/:/, ' ').split(' '); var month; switch (dt[0]) { case "January": month = '01'; break; case "February": month = '02'; break; case "March": month = '03'; break; case "April": month = '04'; break; case "May": month = '05'; break; case "June": month = '06'; break; case "July": month = '07'; break; case "August": month = '08'; break; case "September": month = '09'; break; case "October": month = '10'; break; case "November": month = '11'; break; case "December": month = '12'; break; default: break; } var day=dt[1], year=dt[2], hour=dt[3], minute=dt[4], meridiem=dt[5], tz=dt[6]; hour = parseInt(hour); if (meridiem == 'PM' && hour != 12) { hour += 12; } dt = Date.UTC(year, month, day, hour, minute, 0); return dt; } catch (err) { return new Date(); } }, formatCredit: function(str) { // Formats credit for mailto: link for (var i = 0; i < photographers.length; i++) { var p = photographers[i]; if (typeof p.name == 'string') { if (str.toLowerCase().indexOf(p.name.toLowerCase()) != -1) { if (p.email) { str = ''+p.name+''; } else { str = p.name; } } } } return str; }, enablePurchase: function() { // Enables buyPhoto link $('oh_buy_photo').style.display = 'inline'; $('oh_buy_photo_link').href = 'javascript:buyPhoto()'; }, disablePurchase: function() { // Disables buyPhoto link $('oh_buy_photo').style.display = 'none'; $('oh_buy_photo_link').href = ''; }, displayIndex: function() { // Displays media at this.currentIndex $$('.mutable').innerHTML = ''; // Clear mutable elements out new Effect.Appear('loading',{duration: .1}); var p = this.media[this.currentIndex]; $('oh_gallery_index').innerHTML = 'Photo '+(this.currentIndex+1)+' of '+this.media.length; $('oh_gallery_cutline').innerHTML = p.cutline; // Add 'custom' text to cutline if (custom != '') { $('oh_gallery_cutline').innerHTML += '

'+custom+'

'; } $('oh_gallery_credit').innerHTML = p.credit; $('oh_gallery_slideshow').innerHTML = ''; if (navigator.appName.toLowerCase() == 'opera') { // Workaround to support Opera new Effect.Fade('loading',{duration: .5}); new Effect.Appear('oh_gallery_slideshow_image',{ from: 0, to: 1, duration: .5 }); } else { $('oh_gallery_slideshow_image').onload = function() { new Effect.Fade('loading',{duration: .5}); new Effect.Appear('oh_gallery_slideshow_image',{ from: 0, to: 1, duration: .5 }); } } this.updateThumbs(); // Determine whether to show buy photo link if (this.determineBuyPhotoFromXML == false) { if (p.buyOpt == 'yes') { this.enablePurchase(); } else { this.disablePurchase(); } } else { this.disablePurchase(); } photographers.each(function(p) { if ($('oh_gallery_credit').innerHTML.toLowerCase().indexOf(p.name.toLowerCase()) != -1) { this.enablePurchase(); } }.bind(this)); // Preload images this.preLoad('next'); this.preLoad('prev'); this.preLoad('last'); this.preLoad('first'); }, updateThumbs: function() { // Updates thumbnail previews for prev/next photos // Handle left/previous thumbnail var prevIndex = this.currentIndex-1; if (prevIndex >= 0) { $('oh_gallery_left_thumb').style.display = 'none'; $('oh_gallery_left_thumb').style.cursor = 'pointer'; $('oh_gallery_left_thumb').src = this.media[prevIndex].thumbnail; $('oh_gallery_left_thumb').onclick = function() { this.clickTo('previous'); }.bind(this); $('oh_gallery_left_thumb').onload = function() { new Effect.Appear('oh_gallery_left_thumb',{ from: 0, to: 1, duration: .5 }); } } else { $('oh_gallery_left_thumb').style.cursor = 'default'; $('oh_gallery_left_thumb').src = blankImg; $('oh_gallery_left_thumb').onclick = null; } // Handle right/next thumbnail var nextIndex = this.currentIndex+1; if (nextIndex <= this.media.length-1) { $('oh_gallery_right_thumb').style.display = 'none'; $('oh_gallery_right_thumb').style.cursor = 'pointer'; $('oh_gallery_right_thumb').src = this.media[nextIndex].thumbnail; $('oh_gallery_right_thumb').onclick = function() { this.clickTo('next'); }.bind(this); $('oh_gallery_right_thumb').onload = function() { new Effect.Appear('oh_gallery_right_thumb',{ from: 0, to: 1, duration: .5 }); } } else { $('oh_gallery_right_thumb').style.cursor = 'default'; $('oh_gallery_right_thumb').src = blankImg; $('oh_gallery_right_thumb').onclick = null; } }, first: function() { // Button function this.currentIndex = 0; this.buttonState(); this.displayIndex(); }, last: function() { // Button function this.currentIndex = this.media.length-1; this.buttonState(); this.displayIndex(); }, previous: function() { // Button function this.currentIndex = this.currentIndex-1; this.buttonState(); this.displayIndex(); }, next: function() { // Button function this.currentIndex = this.currentIndex+1; this.buttonState(); this.displayIndex(); }, buttonState: function() { // Sets button as disabled/enabled based on currentIndex location var buttons = "oh_gallery_first,oh_gallery_previous,oh_gallery_next,oh_gallery_last".split(/,/); buttons.each(function(id) { $(id).disabled = true; $(id).blur(); }); switch (this.currentIndex) { case 0: $('oh_gallery_next').disabled = false; $('oh_gallery_last').disabled = false; break; case this.media.length-1: $('oh_gallery_previous').disabled = false; $('oh_gallery_first').disabled = false; break; default: buttons.each(function(id) { $(id).disabled = false; }); break; } }, buttonEvent: function() { // Runs on all button events, but not at page load this.sendAnalyticsEvent(''); this.adswitcher.manualSwitch(); this.numClicks++; }, clickTo: function(func) { // Interceptor function to display new image or show ad this.buttonEvent(); if ((this.numClicks%this.adInterstitial == 0) && (this.showInterstitials == true)) { this.displayInterstitialAd(); } else { eval('this.'+func+'()'); } }, displayInterstitialAd: function() { // Displays interstitial ad instead of image var category = getCategory(); var subcategory = getSubcategory(); var iframe = Builder.node('iframe',{ id: 'oh_gallery_interstitial', src: interstitial_url, frameborder: 'no', scrolling: 'no', style: "width: 350px; height: 350px;" }); $('oh_gallery_slideshow').innerHTML = ''; $('oh_gallery_slideshow').appendChild(iframe); $$('.mutable').innerHTML = ''; }, sendAnalyticsEvent: function(accnt) { // Runs site catalyst stats script if (!accnt) { accnt = s_account; try { // G code SC tracking void(s_gs(accnt)); } catch(e) { // H code SC tracking s_gi(accnt); s_coxnews.t(); } } }, preLoad: function(ref) { // Preloads images based on passed reference variable // Clean out target div $('oh_secret_hidden_div').innerHTML = ''; // Determine what to preload switch (ref) { case 'last': var i = this.media.length-1; break; case 'next': var i = this.currentIndex+1; break; case 'prev': var i = this.currentIndex-1; break; case 'first': var i = 0; break; default: return; } // If var i is out of bounds, we do not need to preload switch (i) { case -1: return; case (this.media.length+1): return; default: break; } // Preload and append to hidden div (as a workaround for browsers that do not preload unassigned image objects in memory) if (typeof this.media[i] != 'undefined') { // Load slideshow image var tempSlideshow = document.createElement('img'); tempSlideshow.display = 'none'; tempSlideshow.src = this.media[i].slideshow; $('oh_secret_hidden_div').appendChild(tempSlideshow); // Load thumbnail image var tempThumbnail = document.createElement('img'); tempThumbnail.display = 'none'; tempThumbnail.src = this.media[i].thumbnail; $('oh_secret_hidden_div').appendChild(tempThumbnail); } } }; var AdSwitcher = Class.create(); AdSwitcher.prototype = { initialize: function(args) { this.divId = 'ohleaderboard'; this.url = ad_url; this.switchPeriod = (args.switchPeriod) ? args.switchPeriod : 20; // defaults to 20 seconds this.timedSwitching = (false == args.timedSwitching) ? false : true; // defaults to true if (this.timedSwitching == true) { this.beginSwitching(); } }, swapAds: function() { // Swaps ad div innerHTML for iframe with new ad var iFrame = Builder.node('iframe',{ src: this.url, frameborder: 'no', scrolling: 'no', style: 'width: 734px; height: 100px; margin-top: -10px; margin-left: -10px;' }); $(this.divId).innerHTML = ''; $(this.divId).appendChild(iFrame); }, beginSwitching: function() { // Begins timed adswitching operation; period defined in seconds if (this.timedSwitching == true) { this.timedAd = window.setInterval(function() { this.swapAds(); }.bind(this),this.switchPeriod*1000) } }, stopSwitching: function() { // Halts timed adswitcher in case of manual switch if (this.timedAd) { window.clearInterval(this.timedAd); } }, manualSwitch: function() { // Stops timed switcher and does manual switch, then restarts timed switcher this.stopSwitching(); this.swapAds(); this.beginSwitching(); } }; /* Utility functions */ function error(msg) { if (typeof msg == 'undefined') { var msg = 'There was a problem loading the gallery. Please try the alternate gallery by using the "Can\'t see this gallery?" link.'; } if ($('loading').style.display != 'none') { $('loading').style.display = 'none'; } $('oh_gallery_error').innerHTML = msg; $('oh_gallery_error').style.display = 'block'; }; function useAltGallery() { // Redirects user to CoxNet's flash-based gallery in the event of a load error if (debug == true) { try { logMessage("Error thrown; caller was " + caller); } catch (err) { error('There was a problem while loading the gallery. Please try again later.'); } } else { var alt_url = $('oh_alt_gallery_link').getAttribute('href'); alt_url = alt_url.replace(/http:\/\/.*\.com\/ap/i,"/ap"); error('There was a problem while loading the gallery. Please wait while I try to recover.'); setTimeout('location.href="'+alt_url+'"',3000); } }; function getDomain() { var loc = location.href; var x = loc.replace(/.+?\.(.+?)\..*?$/, '$1'); return x; } function getCategory() { var loc = location.href; var regex = /.+?photos_galleries\//; var x = loc.replace(regex,''); regex = /\/.+$/; x = x.replace(regex,''); return x; }; function getSubcategory() { var loc = location.href; var regex = /.+?photos_galleries\/.+?\// //var category = getCategory(); //var regex = eval('/.+' + category + '\//'); var x = loc.replace(regex,''); regex = /\/.+$/; x = x.replace(regex,''); return x; }; function set_ad_urls() { var domain = getDomain(); var category = getCategory(); var subcategory = getSubcategory(); var base_url = ad_root + domain + '/' + category + '/' + subcategory + '/'; ad_url = base_url + ad_filename; interstitial_url = base_url + interstitial_filename; } function buyPhoto() { var nameSpace = pictopiaNamespaces[ getDomain() ]; var t_url = escape($('oh_gallery_slideshow_image').getAttribute('src')); var n = $('oh_gallery_slideshow_image').getAttribute('src').replace(/http:.+\//,''); var t = escape($('oh_gallery_cutline').innerHTML.replace(/:/,' ')); if (t == '') { t = escape($('oh_gallery_title').innerHTML.replace(/:/,' ')); } var loc = 'http://www.pictopia.com/perl/ptp/' + nameSpace + '?photo_name=' + n + '&title=' + t + '&t_url=' + t_url + '&time=' + new Date().getTime(); var win = window.open(loc, 'ptp_dayt','scrollbars=yes, resizable=yes, toolbar=no, ' + 'status=yes, width=1024,height=768, menubar=no'); win.focus(); }; /* Main */ function initGallery() { // Set gallery title $('oh_gallery_title').innerHTML = galleryTitle; // Set ad url based on current url segments set_ad_urls(); // Scroll down to make gallery visible Element.scrollTo($('ohleaderboard')); // Launch gallery gallery = new Gallery({ feed: file, showInterstitials: enableInterstitials, determineBuyPhotoFromXML: determineBuyPhotoFromXML, enabledTimedSwitching: enableTimedSwitching }); gallery.getXML(); }; /* Global vars */ //var galleryTitle = document.title; var gallery; var adswitcher; var loadimg = 'http://www.daytondailynews.com/custom/images/loading.gif'; var blankImg = "http://www.daytondailynews.com/custom/images/1.gif"; var photographers = [ {name: "Bill Garlow", email: "bgarlow@daytondailynews.com"}, {name: "Bill Reinke", email: "breinke@daytondailynews.com"}, {name: "Chris Stewart", email: "cstewart@daytondailynews.com"}, {name: "Ed Roberts", email: "eroberts@daytondailynews.com"}, {name: "Jan Underwood", email: "junderwood@daytondailynews.com"}, {name: "Jim Witmer", email: "jwitmer@daytondailynews.com"}, {name: "Lisa Powell", email: "lpowell@daytondailynews.com"}, {name: "Ron Alvey", email: "ralvey@daytondailynews.com"}, {name: "Skip Peterson", email: "speterson@daytondailynews.com"}, {name: "Ty Greenlees", email: "tgreenlees@daytondailynews.com"}, {name: 'Barbara Perenic', email: 'bperenic@coxohio.com'}, {name: 'Bill Lackey', email: 'blackey@coxohio.com'}, {name: 'Cam Knight', email: 'cknight@coxohio.com'}, {name: 'Cameron Knight', email: 'cknight@coxohio.com'}, {name: 'Chris Celek', email: 'ccelek@coxohio.com'}, {name: 'David A. Moodie', email: 'dmoodie@coxohio.com'}, {name: 'David Moodie', email: 'mailto:davo6224@aol.com'}, {name: 'Denise Miles', email: 'dmiles@coxohio.com'}, {name: 'Donna Wyatt', email: 'dwyatt@coxohio.com'}, {name: 'Dwight Huff', email: ''}, {name: 'E.L. Hubbard', email: 'ehubbard@coxohio.com'}, {name: 'Eric Hubbard', email: 'ehubbard@coxohio.com'}, {name: 'Gary Stelzer', email: 'gstelzer@coxohio.com'}, {name: 'Greg Lynch', email: 'glynch@coxohio.com'}, {name: 'Jared Holder', email: ''}, {name: 'Jeff Ober', email: 'jober@coxohio.com'}, {name: 'Jenny Haralamos', email: ''}, {name: 'Jessica Uttinger', email: ''}, {name: 'Jim Noelker', email: 'jnoelker@coxohio.com'}, {name: 'Joe Lamb', email: ''}, {name: 'John Boyle', email: 'jboyle@coxohio.com'}, {name: 'John Swartzel', email: ''}, {name: 'Justine Reisinger', email: 'jreisinger@coxohio.com'}, /* Intern summer '07 */ {name: 'Linda Weisenborn', email: ''}, {name: 'Lou Spinnazola', email: ''}, {name: 'Marisa Head', email: 'mhead@coxohio.com'}, /* Intern summer '07 */ {name: 'Marshall Gorby', email: 'mgorby@coxohio.com'}, {name: 'Martin Wheeler', email: ''}, {name: 'Mike Wallace', email: 'mwallace@coxohio.com'}, {name: 'Nick Daggy', email: 'ndaggy@coxohio.com'}, {name: 'Nick Graham', email: 'ngraham@coxohio.com'}, {name: 'Otis Gowens', email: 'ogowens@coxohio.com'}, {name: 'Pat Auckerman', email: 'pauckerman@coxohio.com'}, {name: 'Pat Aukerman', email: 'pauckerman@coxohio.com'}, {name: 'Robert Leifheit', email: ''}, {name: 'Ryan Podracky', email: 'rpodracky@coxohio.com'}, {name: 'Ryan Prodracky', email: ''}, {name: 'Samantha Grier', email: ''}, {name: 'Sarah Buehrle', email: 'sbuehrle@coxohio.com'}, {name: 'Teesha McClam', email: 'tmcclam@coxohio.com'}, {name: 'Teresa Cooper', email: 'tcooper@coxohio.com'}, {name: 'Volunteers', email: 'volunteers@coxohio.com'}, {name: 'Staff photo', email: ''} ]; var pictopiaNamespaces = { 'daytondailynews': 'dayt', 'oxfordpress': 'oxfordpress', 'middletownjournal': 'mtj', 'journal-news': 'journalnews', 'western-star': 'westernstar', 'pulsejournal': 'pulsejournal', 'springfieldnewssun': 'springfieldnewssun', 'activedayton': 'dayt', 'fairfield-echo': 'fairfieldecho' }; var enableTimedSwitching = false; var enableInterstitials = false; var determineBuyPhotoFromXML = false; var defaultSortMethod = 'By Submission Date Descending'; var ad_root = 'http://alt.coxnewsweb.com/daytondailynews/gallery_ads/'; var ad_filename = 'ad.html'; var interstitial_filename = 'interstitial.html'; var ad_url = ''; var interstitial_url = '';