diff --git a/templates/html/assets/images/menu-flap.png b/templates/html/assets/images/menu-flap.png new file mode 100644 index 0000000..4424406 Binary files /dev/null and b/templates/html/assets/images/menu-flap.png differ diff --git a/templates/html/assets/images/search-background.png b/templates/html/assets/images/search-background.png new file mode 100644 index 0000000..7629500 Binary files /dev/null and b/templates/html/assets/images/search-background.png differ diff --git a/templates/html/assets/images/section-background.png b/templates/html/assets/images/section-background.png new file mode 100644 index 0000000..d3cf11e Binary files /dev/null and b/templates/html/assets/images/section-background.png differ diff --git a/templates/html/assets/javascripts/tabs.js b/templates/html/assets/javascripts/tabs.js new file mode 100644 index 0000000..7c97420 --- /dev/null +++ b/templates/html/assets/javascripts/tabs.js @@ -0,0 +1,506 @@ +/** + * @author Ryan Johnson + * @copyright 2008 PersonalGrid Corporation + * @package LivePipe UI + * @license MIT + * @url http://livepipe.net/core + * @require prototype.js + */ + +if(typeof(Control) == 'undefined') + Control = {}; + +var $proc = function(proc){ + return typeof(proc) == 'function' ? proc : function(){return proc}; +}; + +var $value = function(value){ + return typeof(value) == 'function' ? value() : value; +}; + +Object.Event = { + extend: function(object){ + object._objectEventSetup = function(event_name){ + this._observers = this._observers || {}; + this._observers[event_name] = this._observers[event_name] || []; + }; + object.observe = function(event_name,observer){ + if(typeof(event_name) == 'string' && typeof(observer) != 'undefined'){ + this._objectEventSetup(event_name); + if(!this._observers[event_name].include(observer)) + this._observers[event_name].push(observer); + }else + for(var e in event_name) + this.observe(e,event_name[e]); + }; + object.stopObserving = function(event_name,observer){ + this._objectEventSetup(event_name); + if(event_name && observer) + this._observers[event_name] = this._observers[event_name].without(observer); + else if(event_name) + this._observers[event_name] = []; + else + this._observers = {}; + }; + object.observeOnce = function(event_name,outer_observer){ + var inner_observer = function(){ + outer_observer.apply(this,arguments); + this.stopObserving(event_name,inner_observer); + }.bind(this); + this._objectEventSetup(event_name); + this._observers[event_name].push(inner_observer); + }; + object.notify = function(event_name){ + this._objectEventSetup(event_name); + var collected_return_values = []; + var args = $A(arguments).slice(1); + try{ + for(var i = 0; i < this._observers[event_name].length; ++i) + collected_return_values.push(this._observers[event_name][i].apply(this._observers[event_name][i],args) || null); + }catch(e){ + if(e == $break) + return false; + else + throw e; + } + return collected_return_values; + }; + if(object.prototype){ + object.prototype._objectEventSetup = object._objectEventSetup; + object.prototype.observe = object.observe; + object.prototype.stopObserving = object.stopObserving; + object.prototype.observeOnce = object.observeOnce; + object.prototype.notify = function(event_name){ + if(object.notify){ + var args = $A(arguments).slice(1); + args.unshift(this); + args.unshift(event_name); + object.notify.apply(object,args); + } + this._objectEventSetup(event_name); + var args = $A(arguments).slice(1); + var collected_return_values = []; + try{ + if(this.options && this.options[event_name] && typeof(this.options[event_name]) == 'function') + collected_return_values.push(this.options[event_name].apply(this,args) || null); + for(var i = 0; i < this._observers[event_name].length; ++i) + collected_return_values.push(this._observers[event_name][i].apply(this._observers[event_name][i],args) || null); + }catch(e){ + if(e == $break) + return false; + else + throw e; + } + return collected_return_values; + }; + } + } +}; + +/* Begin Core Extensions */ + +//Element.observeOnce +Element.addMethods({ + observeOnce: function(element,event_name,outer_callback){ + var inner_callback = function(){ + outer_callback.apply(this,arguments); + Element.stopObserving(element,event_name,inner_callback); + }; + Element.observe(element,event_name,inner_callback); + } +}); + +//mouseenter, mouseleave +//from http://dev.rubyonrails.org/attachment/ticket/8354/event_mouseenter_106rc1.patch +Object.extend(Event, (function() { + var cache = Event.cache; + + function getEventID(element) { + if (element._prototypeEventID) return element._prototypeEventID[0]; + arguments.callee.id = arguments.callee.id || 1; + return element._prototypeEventID = [++arguments.callee.id]; + } + + function getDOMEventName(eventName) { + if (eventName && eventName.include(':')) return "dataavailable"; + //begin extension + if(!Prototype.Browser.IE){ + eventName = { + mouseenter: 'mouseover', + mouseleave: 'mouseout' + }[eventName] || eventName; + } + //end extension + return eventName; + } + + function getCacheForID(id) { + return cache[id] = cache[id] || { }; + } + + function getWrappersForEventName(id, eventName) { + var c = getCacheForID(id); + return c[eventName] = c[eventName] || []; + } + + function createWrapper(element, eventName, handler) { + var id = getEventID(element); + var c = getWrappersForEventName(id, eventName); + if (c.pluck("handler").include(handler)) return false; + + var wrapper = function(event) { + if (!Event || !Event.extend || + (event.eventName && event.eventName != eventName)) + return false; + + Event.extend(event); + handler.call(element, event); + }; + + //begin extension + if(!(Prototype.Browser.IE) && ['mouseenter','mouseleave'].include(eventName)){ + wrapper = wrapper.wrap(function(proceed,event) { + var rel = event.relatedTarget; + var cur = event.currentTarget; + if(rel && rel.nodeType == Node.TEXT_NODE) + rel = rel.parentNode; + if(rel && rel != cur && !rel.descendantOf(cur)) + return proceed(event); + }); + } + //end extension + + wrapper.handler = handler; + c.push(wrapper); + return wrapper; + } + + function findWrapper(id, eventName, handler) { + var c = getWrappersForEventName(id, eventName); + return c.find(function(wrapper) { return wrapper.handler == handler }); + } + + function destroyWrapper(id, eventName, handler) { + var c = getCacheForID(id); + if (!c[eventName]) return false; + c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); + } + + function destroyCache() { + for (var id in cache) + for (var eventName in cache[id]) + cache[id][eventName] = null; + } + + if (window.attachEvent) { + window.attachEvent("onunload", destroyCache); + } + + return { + observe: function(element, eventName, handler) { + element = $(element); + var name = getDOMEventName(eventName); + + var wrapper = createWrapper(element, eventName, handler); + if (!wrapper) return element; + + if (element.addEventListener) { + element.addEventListener(name, wrapper, false); + } else { + element.attachEvent("on" + name, wrapper); + } + + return element; + }, + + stopObserving: function(element, eventName, handler) { + element = $(element); + var id = getEventID(element), name = getDOMEventName(eventName); + + if (!handler && eventName) { + getWrappersForEventName(id, eventName).each(function(wrapper) { + element.stopObserving(eventName, wrapper.handler); + }); + return element; + + } else if (!eventName) { + Object.keys(getCacheForID(id)).each(function(eventName) { + element.stopObserving(eventName); + }); + return element; + } + + var wrapper = findWrapper(id, eventName, handler); + if (!wrapper) return element; + + if (element.removeEventListener) { + element.removeEventListener(name, wrapper, false); + } else { + element.detachEvent("on" + name, wrapper); + } + + destroyWrapper(id, eventName, handler); + + return element; + }, + + fire: function(element, eventName, memo) { + element = $(element); + if (element == document && document.createEvent && !element.dispatchEvent) + element = document.documentElement; + + var event; + if (document.createEvent) { + event = document.createEvent("HTMLEvents"); + event.initEvent("dataavailable", true, true); + } else { + event = document.createEventObject(); + event.eventType = "ondataavailable"; + } + + event.eventName = eventName; + event.memo = memo || { }; + + if (document.createEvent) { + element.dispatchEvent(event); + } else { + element.fireEvent(event.eventType, event); + } + + return Event.extend(event); + } + }; +})()); + +Object.extend(Event, Event.Methods); + +Element.addMethods({ + fire: Event.fire, + observe: Event.observe, + stopObserving: Event.stopObserving +}); + +Object.extend(document, { + fire: Element.Methods.fire.methodize(), + observe: Element.Methods.observe.methodize(), + stopObserving: Element.Methods.stopObserving.methodize() +}); + +//mouse:wheel +(function(){ + function wheel(event){ + var delta; + // normalize the delta + if(event.wheelDelta) // IE & Opera + delta = event.wheelDelta / 120; + else if (event.detail) // W3C + delta =- event.detail / 3; + if(!delta) + return; + var custom_event = Event.element(event).fire('mouse:wheel',{ + delta: delta + }); + if(custom_event.stopped){ + Event.stop(event); + return false; + } + } + document.observe('mousewheel',wheel); + document.observe('DOMMouseScroll',wheel); +})(); + +/* End Core Extensions */ + +//from PrototypeUI +var IframeShim = Class.create({ + initialize: function() { + this.element = new Element('iframe',{ + style: 'position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);display:none', + src: 'javascript:void(0);', + frameborder: 0 + }); + $(document.body).insert(this.element); + }, + hide: function() { + this.element.hide(); + return this; + }, + show: function() { + this.element.show(); + return this; + }, + positionUnder: function(element) { + var element = $(element); + var offset = element.cumulativeOffset(); + var dimensions = element.getDimensions(); + this.element.setStyle({ + left: offset[0] + 'px', + top: offset[1] + 'px', + width: dimensions.width + 'px', + height: dimensions.height + 'px', + zIndex: element.getStyle('zIndex') - 1 + }).show(); + return this; + }, + setBounds: function(bounds) { + for(prop in bounds) + bounds[prop] += 'px'; + this.element.setStyle(bounds); + return this; + }, + destroy: function() { + if(this.element) + this.element.remove(); + return this; + } +}); + +/** + * @author Ryan Johnson + * @copyright 2008 PersonalGrid Corporation + * @package LivePipe UI + * @license MIT + * @url http://livepipe.net/control/tabs + * @require prototype.js, livepipe.js + */ + +/*global window, document, Prototype, $, $A, $H, $break, Class, Element, Event, Control */ + +if(typeof(Prototype) == "undefined") { + throw "Control.Tabs requires Prototype to be loaded."; } +if(typeof(Object.Event) == "undefined") { + throw "Control.Tabs requires Object.Event to be loaded."; } + +Control.Tabs = Class.create({ + initialize: function(tab_list_container,options){ + if(!$(tab_list_container)) { + throw "Control.Tabs could not find the element: " + tab_list_container; } + this.activeContainer = false; + this.activeLink = false; + this.containers = $H({}); + this.links = []; + Control.Tabs.instances.push(this); + this.options = { + beforeChange: Prototype.emptyFunction, + afterChange: Prototype.emptyFunction, + hover: false, + linkSelector: 'li a', + setClassOnContainer: false, + activeClassName: 'active', + defaultTab: 'first', + autoLinkExternal: true, + targetRegExp: /#(.+)$/, + showFunction: Element.show, + hideFunction: Element.hide + }; + Object.extend(this.options,options || {}); + (typeof(this.options.linkSelector == 'string') ? + $(tab_list_container).select(this.options.linkSelector) : + this.options.linkSelector($(tab_list_container)) + ).findAll(function(link){ + return (/^#/).exec((Prototype.Browser.WebKit ? decodeURIComponent(link.href) : link.href).replace(window.location.href.split('#')[0],'')); + }).each(function(link){ + this.addTab(link); + }.bind(this)); + this.containers.values().each(Element.hide); + if(this.options.defaultTab == 'first') { + this.setActiveTab(this.links.first()); + } else if(this.options.defaultTab == 'last') { + this.setActiveTab(this.links.last()); + } else { + this.setActiveTab(this.options.defaultTab); } + var targets = this.options.targetRegExp.exec(window.location); + if(targets && targets[1]){ + targets[1].split(',').each(function(target){ + this.setActiveTab(this.links.find(function(link){ + return link.key == target; + })); + }.bind(this)); + } + if(this.options.autoLinkExternal){ + $A(document.getElementsByTagName('a')).each(function(a){ + if(!this.links.include(a)){ + var clean_href = a.href.replace(window.location.href.split('#')[0],''); + if(clean_href.substring(0,1) == '#'){ + if(this.containers.keys().include(clean_href.substring(1))){ + $(a).observe('click',function(event,clean_href){ + this.setActiveTab(clean_href.substring(1)); + }.bindAsEventListener(this,clean_href)); + } + } + } + }.bind(this)); + } + }, + addTab: function(link){ + this.links.push(link); + link.key = link.getAttribute('href').replace(window.location.href.split('#')[0],'').split('#').last().replace(/#/,''); + var container = $(link.key); + if(!container) { + throw "Control.Tabs: #" + link.key + " was not found on the page."; } + this.containers.set(link.key,container); + link[this.options.hover ? 'onmouseover' : 'onclick'] = function(link){ + if(window.event) { + Event.stop(window.event); } + this.setActiveTab(link); + return false; + }.bind(this,link); + }, + setActiveTab: function(link){ + if(!link && typeof(link) == 'undefined') { + return; } + if(typeof(link) == 'string'){ + this.setActiveTab(this.links.find(function(_link){ + return _link.key == link; + })); + }else if(typeof(link) == 'number'){ + this.setActiveTab(this.links[link]); + }else{ + if(this.notify('beforeChange',this.activeContainer,this.containers.get(link.key)) === false) { + return; } + if(this.activeContainer) { + this.options.hideFunction(this.activeContainer); } + this.links.each(function(item){ + (this.options.setClassOnContainer ? $(item.parentNode) : item).removeClassName(this.options.activeClassName); + }.bind(this)); + (this.options.setClassOnContainer ? $(link.parentNode) : link).addClassName(this.options.activeClassName); + this.activeContainer = this.containers.get(link.key); + this.activeLink = link; + this.options.showFunction(this.containers.get(link.key)); + this.notify('afterChange',this.containers.get(link.key)); + } + }, + next: function(){ + this.links.each(function(link,i){ + if(this.activeLink == link && this.links[i + 1]){ + this.setActiveTab(this.links[i + 1]); + throw $break; + } + }.bind(this)); + }, + previous: function(){ + this.links.each(function(link,i){ + if(this.activeLink == link && this.links[i - 1]){ + this.setActiveTab(this.links[i - 1]); + throw $break; + } + }.bind(this)); + }, + first: function(){ + this.setActiveTab(this.links.first()); + }, + last: function(){ + this.setActiveTab(this.links.last()); + } +}); +Object.extend(Control.Tabs,{ + instances: [], + findByTabId: function(id){ + return Control.Tabs.instances.find(function(tab){ + return tab.links.find(function(link){ + return link.key == id; + }); + }); + } +}); +Object.Event.extend(Control.Tabs);