//
// iWeb - HeaderControls.js
// Copyright (c) 2007 Apple Inc. All rights reserved.
//
//
// HeaderControls
//
function HeaderControls(instanceID)
{
if(instanceID != null)
{
Widget.apply(this, arguments);
NotificationCenter.addObserver(this, HeaderControls.prototype.p_prevPage, "PreviousPage", this.p_mediaGridID());
NotificationCenter.addObserver(this, HeaderControls.prototype.p_nextPage, "NextPage", this.p_mediaGridID());
NotificationCenter.addObserver(this, HeaderControls.prototype.p_setPage, "SetPage", this.p_mediaGridID());
this.mRange = new IWPageRange(0, 5);
this.p_updateRange();
}
}
// set up inheritance
HeaderControls.prototype = new Widget();
HeaderControls.prototype.constructor = HeaderControls;
// other subclass setup
HeaderControls.prototype.widgetIdentifier = "com-apple-iweb-widget-headercontrols";
HeaderControls.prototype.onload = function()
{
var defaults = {showBackToIndex: true,
showAddPhoto: true,
showSubscribe: true,
showSlideshow: true,
mediaIndex: false,
entriesPerPage: 99,
entryCount: 0};
this.initializeDefaultPreferences(defaults);
// Ensure that we start on page 0
this.setPage(0);
this.updateFromPreferences();
if (this.preferences && this.preferences.postNotification)
{
this.preferences.postNotification("BLWidgetIsSafeToDrawNotification", 1);
}
}
HeaderControls.prototype.onunload = function()
{
}
HeaderControls.prototype.startup = function()
{
this.p_updateCanvasControls();
this.p_updateBackToIndex();
this.p_updatePaginationControls();
this.p_updateAddPhoto();
this.p_updateSubscribe();
this.p_updateSlideshow();
// Display either the media index- or album-specific controls
if(this.p_mediaIndex())
{
this.getElementById("media_index_only").show();
}
else
{
this.getElementById("album_only").show();
}
}
HeaderControls.prototype.changedPreferenceForKey = function(key)
{
if(key == "entriesPerPage" || key == "entryCount" || key == "x-currentPage")
{
this.p_updateRange();
this.p_updatePaginationControls();
}
else if(key == "showBackToIndex")
{
this.p_updateBackToIndex();
}
else if(key == "showAddPhoto")
{
this.p_updateAddPhoto();
}
else if(key == "showSubscribe")
{
this.p_updateSubscribe();
}
else if(key == "showSlideshow")
{
this.p_updateSlideshow();
}
else if(key == "canvas controls")
{
this.p_updateCanvasControls();
}
else if(this.runningInApp)
{
// These preferences only ever change in app, and are only ever set by the footer
// widget, which shares a prefs model with us.
if(key == "x-nextPage")
{
this.nextPage();
}
else if(key == "x-previousPage")
{
this.prevPage();
}
else if(key == "x-setPage")
{
this.setPage(this.p_setPagePreference());
}
}
}
HeaderControls.prototype.updateFromPreferences = function()
{
this.startup();
}
HeaderControls.prototype.prevPage = function()
{
NotificationCenter.postNotification(new IWNotification("PreviousPage", this.p_mediaGridID(), null));
}
HeaderControls.prototype.nextPage = function()
{
NotificationCenter.postNotification(new IWNotification("NextPage", this.p_mediaGridID(), null));
}
HeaderControls.prototype.setPage = function(pageIndex)
{
NotificationCenter.postNotification(new IWNotification("SetPage", this.p_mediaGridID(), {pageIndex: pageIndex}));
}
HeaderControls.prototype.playSlideshow = function()
{
if(this.mPlaySlideshowFunction)
{
this.mPlaySlideshowFunction();
}
}
HeaderControls.prototype.setPlaySlideshowFunction = function(playSlideshow)
{
this.mPlaySlideshowFunction = playSlideshow;
}
// Private accessors
HeaderControls.prototype.p_canNavigateToPrev = function()
{
return (this.p_currentPage() > 0);
}
HeaderControls.prototype.p_prevPage = function(notification)
{
if(this.p_canNavigateToPrev())
{
this.setPage(this.p_currentPage() - 1);
}
}
HeaderControls.prototype.p_canNavigateToNext = function()
{
return (this.p_currentPage() < this.p_pageCount()-1);
}
HeaderControls.prototype.p_nextPage = function(notification)
{
if(this.p_canNavigateToNext())
{
this.setPage(this.p_currentPage() + 1);
}
}
HeaderControls.prototype.p_setPage = function(notification)
{
var pageIndex = notification.userInfo().pageIndex;
this.setPreferenceForKey(pageIndex, "x-currentPage");
// When published, need to send a range changed notification here to (potentially)
// reload the stream and re-layout the images.
if(!this.runningInApp)
{
var entriesPerPage = this.p_entriesPerPage();
var location = pageIndex * entriesPerPage;
var length = Math.min(this.p_entryCount() - location, entriesPerPage);
var userInfo = { "range" : new IWRange(location, length) };
NotificationCenter.postNotification(new IWNotification("RangeChanged", this.p_mediaGridID(), userInfo));
}
}
HeaderControls.prototype.p_showBackToIndex = function()
{
var show = this.preferenceForKey("showBackToIndex");
(function(){return show !== undefined}).assert();
return show;
}
HeaderControls.prototype.p_showAddPhoto = function()
{
var show = this.preferenceForKey("showAddPhoto");
(function(){return show !== undefined}).assert();
return show;
}
HeaderControls.prototype.p_showSubscribe = function()
{
var show = this.preferenceForKey("showSubscribe");
(function(){return show !== undefined}).assert();
return show;
}
HeaderControls.prototype.p_showSlideshow = function()
{
var show = this.preferenceForKey("showSlideshow");
(function(){return show !== undefined}).assert();
return show;
}
HeaderControls.prototype.p_mediaGridID = function()
{
var mediaGridID = null;
if(this.preferences)
{
mediaGridID = this.preferenceForKey("gridID");
}
if(mediaGridID === undefined)
{
mediaGridID = null;
}
return mediaGridID;
}
HeaderControls.prototype.p_setPagePreference = function()
{
var setPagePreference = null;
if(this.preferences)
{
setPagePreference = this.preferenceForKey("x-setPage");
}
if(setPagePreference === undefined)
{
setPagePreference = null;
}
return setPagePreference;
}
HeaderControls.prototype.p_updatePaginationControls = function()
{
var widgetDiv = this.div();
var currentPage = this.p_currentPage();
// Build the navigation elements
var controls = "";
if(this.p_isPaginated())
{
// Left arrow
var canvasControlURLs = this.preferenceForKey("canvas controls");
if(this.p_canNavigateToPrev())
{
var leftArrowSrc = canvasControlURLs['canvas_arrow-left'];
controls += "";
controls += imgMarkup(leftArrowSrc, '', '', '');
controls += " ";
}
else
{
var leftArrowSrc = canvasControlURLs['canvas_arrow-left-D'];
controls += imgMarkup(leftArrowSrc, '', '', '') + " ";
}
// Page entries
for(var i=this.mRange.min(); i" + (i+1) + " ";
}
else
{
controls += "" + (i+1) + " ";
}
}
// Right arrow
if(this.p_canNavigateToNext())
{
var rightArrowSrc = canvasControlURLs[ 'canvas_arrow-right'];
controls += "";
controls += imgMarkup(rightArrowSrc, '', '', '');
controls += "";
}
else
{
var rightArrowSrc = canvasControlURLs[ 'canvas_arrow-right-D'];
controls += imgMarkup(rightArrowSrc, '', '', '');
}
}
var template = new Template(controls);
var myControls = template.evaluate({WIDGET_ID: this.instanceID});
this.getElementById("pagination_controls").update(myControls);
// Handle pagination element layout
widgetDiv.getElementsByClassName("paginated_only").invoke(this.p_isPaginated() ? 'show' : 'hide');
widgetDiv.getElementsByClassName("non_paginated_only").invoke(this.p_isPaginated() ? 'hide' : 'show');
// Communicate the contents of the pagination control indirectly to the footer control,
// via either the shared prefs bridge, or a notification.
if(this.runningInApp)
{
this.setPreferenceForKey(controls, "x-paginationSpanContents");
}
else
{
NotificationCenter.postNotification(new IWNotification("paginationSpanContents", this.p_mediaGridID(), {controls: controls}));
}
}
HeaderControls.prototype.p_setAnchorsUnderElementToHREF = function(element, href)
{
var links = element.getElementsByTagName("a");
for(var i = 0; i < links.length; ++i)
{
links[i].href = href;
}
}
HeaderControls.prototype.p_updateCanvasControls = function()
{
var canvasControlURLs = this.preferenceForKey("canvas controls");
this.div().getElementsByClassName('canvas').each(function(img)
{
var canvasControlName = "canvas_" + img.classNames().toArray()[1];
setImgSrc(img, canvasControlURLs[canvasControlName]);
});
}
HeaderControls.prototype.p_updateBackToIndex = function()
{
var element = this.getElementById("back_to_index");
this.p_showBackToIndex() ? element.show() : element.hide();
if(!this.runningInApp)
{
this.p_setAnchorsUnderElementToHREF(element, this.p_indexURL());
}
}
HeaderControls.prototype.p_updateAddPhoto = function()
{
var element = this.getElementById("add_photo");
this.p_showAddPhoto() ? element.show() : element.hide();
if(!this.runningInApp)
{
// TODO (mm) -- hook up add a photo
this.p_setAnchorsUnderElementToHREF(element, "javascript:(void)");
}
}
HeaderControls.prototype.p_updateSubscribe = function()
{
this.div().getElementsByClassName("subscribe").invoke(this.p_showSubscribe() ? 'show' : 'hide');
if(!this.runningInApp)
{
var feedURL = "javascript:" + this.instanceID + (this.p_mediaIndex() ? ".mediaIndexSubscribe()" : ".photocastSubscribe()")
var self = this;
this.div().getElementsByClassName("subscribe").each(function(element)
{
self.p_setAnchorsUnderElementToHREF(element, feedURL);
});
}
}
HeaderControls.prototype.mediaIndexSubscribe = function()
{
window.location = this.p_feedURL();
}
HeaderControls.prototype.photocastSubscribe = function()
{
photocastHelper(this.p_feedURL());
}
HeaderControls.prototype.p_updateSlideshow = function()
{
this.div().getElementsByClassName("play_slideshow").invoke(this.p_showSlideshow() ? 'show' : 'hide');
}
HeaderControls.prototype.p_mediaIndex = function()
{
var mediaIndex = null;
if(this.preferences)
{
mediaIndex = this.preferenceForKey("mediaIndex");
}
if(mediaIndex === undefined)
{
mediaIndex = false;
}
return mediaIndex;
}
HeaderControls.prototype.p_currentPage = function()
{
var currentPage = 0;
if(this.preferences)
{
currentPage = this.preferenceForKey("x-currentPage");
}
if(!currentPage)
{
currentPage = 0;
}
return currentPage;
}
HeaderControls.prototype.p_entriesPerPage = function()
{
var entriesPerPage = null;
if(this.preferences)
{
entriesPerPage = this.preferenceForKey("entriesPerPage");
}
if(entriesPerPage == undefined)
{
entriesPerPage = 99;
}
return entriesPerPage;
}
HeaderControls.prototype.p_entryCount = function()
{
var entryCount = null;
if(this.preferences)
{
entryCount = this.preferenceForKey("entryCount");
}
if(entryCount == undefined)
{
entryCount = 0;
}
return entryCount;
}
HeaderControls.prototype.p_indexURL = function()
{
return this.preferenceForKey("indexURL");
}
HeaderControls.prototype.p_feedURL = function()
{
return this.preferenceForKey("feedURL");
}
HeaderControls.prototype.p_isPaginated = function()
{
return (this.p_entryCount() > this.p_entriesPerPage());
}
HeaderControls.prototype.p_pageCount = function()
{
return Math.ceil(this.p_entryCount() / this.p_entriesPerPage());
}
HeaderControls.prototype.p_updateRange = function()
{
var pageCount = this.p_pageCount();
var currentPage = this.p_currentPage();
// Ensure that the current page is valid.
if(currentPage >= pageCount)
{
currentPage = pageCount-1;
this.setPreferenceForKey(currentPage, "x-currentPage");
}
// Keep our range valid for the given page count. Also handle bootstrapping the range when
// it starts small.
if(pageCount <= 5 || this.mRange.length() < 3 || this.mRange.max() > pageCount)
{
this.mRange.setMax(Math.min(5, pageCount));
}
// Keep the current page visible
if(currentPage < this.mRange.min())
{
this.mRange.shift(currentPage - this.mRange.min());
}
else if(currentPage >= this.mRange.max())
{
this.mRange.shift(currentPage - this.mRange.max() + 1);
}
}