Browse Source

About page in config, base

pull/51/merge
Ruud 14 years ago
parent
commit
20772d4ff5
  1. 411
      couchpotato/static/scripts/library/templated.js
  2. 96
      couchpotato/static/scripts/page/about.js
  3. 2
      couchpotato/templates/_desktop.html

411
couchpotato/static/scripts/library/templated.js

@ -0,0 +1,411 @@
/*
---
description: Templated is a MooTools mixin class which creates elements for classes using a string-based HTML template which may included embedded attach points and events.
license: MIT-style
authors:
- David Walsh
requires:
- core/1.3: '*'
provides: [Templated]
...
*/
// Create scope limiter
(function(scope) {
// Create some vars for strings
// This will save bytes when compressed
var strData = "data",
strWidget = "widget",
strAttach = "attach",
dataWidgetType = strData + "-" + strWidget + "-type",
dataWidgetProps = strData + "-" + strWidget + "-props",
dataWidgetAttachPoint = strData + "-" + strWidget + "-" + strAttach + "-point",
dataWidgetAttachEvent = strData + "-" + strWidget + "-" + strAttach + "-event",
dataWidgetized = strData + "-widgetized";
// Templated is a mixin for UI widgets
scope.Templated = new Class({
// The usual options object
options: {
// The default template
template: "<div></div>",
// The URL to get the template from *instead* of the string
templateUrl: "",
// A node reference for where this UI widget will be placed...in reference to
element: null,
// Should this widget be parsed for sub-widgets?
widgetsInTemplate: true,
// Property mappings (should be an object)
// These override defaults
propertyMappings: null,
// Default property mappings
// Thse properties on the element will be moved to the respective nodes within the template
defaultPropertyMappings: null,
// Should messages be debug to the console
debugMode: true
},
// Create placeholders for attached points and events
_attachPoints: [],
_attachEvents: [],
// Parse
parse: function() {
// Get shortcuts to the options and element
var options = this.options,
nodeRef = options.element = options.element || new Element("div").inject(document.body);
// *IF* a templateUrl is specified, can't do anything until template is loaded
// Defer parsing until we've got it
if(options.templateUrl && Templated.templates && !Templated.templates[options.templateUrl]) {
this.debug("[Templated:parse] Need to load template from URL: " + options.templateUrl);
this.getTemplate();
return false;
}
// If already data-widgetized...gtfo
if(nodeRef.retrieve("widget")) {
this.debug("[Templated:parse] Node already widgetized, leaving ", nodeRef);
return nodeRef.domNode;
}
// Mix noderef properties with options
options.defaultPropertyMappings = options.defaultPropertyMappings || { // THESE OVERRIDE CLASSES IN THE TEMPLATE!!!!
"id": "domNode",
"style": "domNode",
"class": "domNode"
};
Object.merge(options, this.getNodeProps(nodeRef));
// postMixInProperties runs after options have been mixed with defaults but before
// any templating is done
this.postMixInProperties();
// Build rendering - creates the actual nodes, attachpoints, and attachevents
this.buildRendering();
// Fire the "postCreate" method, which runs after nodes are created *but* before the nodes are rendered to the page
this.postCreate();
// Cleanup creation
this.cleanupCreation();
// "Startup": The widget is in the DOM and the widget is ready to go
this.startup();
// Return the domNode
this.debug("[Templated:parse] At the end of parse, this is: ", this);
return this.domNode;
},
// Creates build rendering
buildRendering: function() {
// Get shortcuts to the options and element
var options = this.options, nodeRef = options.element;
// Do string substitution on the template
var template = this.template = options.template.substitute(options || {});
// Create the DOM node within a DIV that's not rendered to the page
var bitchNode = this.bitchNode = new Element("div", { html: template.trim() }),
domNode = this.domNode = document.id(bitchNode.childNodes[0]);
// Look for subwidgets if told to...
if(options.widgetsInTemplate) {
this.debug("[Templated:parse] Looking for subwidgets under domNode", domNode);
this.makeSubWidgets(this.domNode);
}
// Create the attachpoints for me, then my kiddies
this.makeAttachPoints(domNode);
if(options.widgetsInTemplate) domNode.getElements("[" + dataWidgetAttachPoint + "]").each(this.makeAttachPoints, this);
this.debug("[Templated:parse] Creating attachpoints", this._attachPoints);
// Create the attachevents for me, then my kiddies
this.makeAttachEvents(domNode);
if(options.widgetsInTemplate) domNode.getElements("[" + dataWidgetAttachEvent + "]").each(this.makeAttachEvents, this);
this.debug("Creating attachevents", this._attachEvents);
// Map properties to nodes within the template
// Mix the custom mappings with the default
// This needs to happen after attachpoints
var mappings = options.propertyMappings ? Object.merge(options.defaultPropertyMappings, options.propertyMappings) : options.defaultPropertyMappings;
Object.each(mappings, function(value, key) {
// Ignore the value if not present in the object
if(!this[value]) return;
// Assign the value to the key
var currentProp = nodeRef.get(key);
if(currentProp != "") this[value].set(key, currentProp);
}.bind(this));
// If this widget has a "containerNode", grab it's childNodes *or* inject innerHTML
if(this.containerNode) {
var kids = nodeRef.childNodes;
kids.length ? $$(kids).inject(this.containerNode) : this.containerNode.set("html", nodeRef.get("html"));
}
},
// "postMixInProperties" -- Fired after options have been mixed in
postMixInProperties: function() {
this.debug("[Templated:postMixInProperties] postMixInProperties!");
},
// "PostCreate" -- Fired after nodes are created, attachpoints and events are found
postCreate: function() {
this.debug("[Templated:postCreate] postCreate!");
},
// "CleanupCreation" -- Removes the old element, destroys bitch node
cleanupCreation: function() {
// Get hold of the dom node and bitch nodes
var domNode = this.domNode, bitchNode = this.bitchNode, nodeRef = this.options.element;
// Put the domNode where it should go and destroy the node reference
domNode.replaces(nodeRef);
nodeRef.destroy();
// Mark as data-widgetized and store the widget within data
domNode.set(dataWidgetized, true);
domNode.store("widget", this);
// Remove the bitch node
bitchNode.destroy();
},
// "StartUp" -- Fired when node is in place
startup: function(){
this.debug("[Templated:startup] startup!");
},
// Focus on focus node, if present
focus: function() {
var node = this.focusNode;
node && node.focus();
},
// Create subwidgets from this
makeSubWidgets: function(domNode) {
if(!domNode) domNode = this.domNode;
domNode.getElements("["+ dataWidgetType +"]:not([" + dataWidgetized + "])").each(function(node){
// Store the subwidget's attachpoints, attachevents, class type, and properties
var points = node.get(dataWidgetAttachPoint),
events = node.get(dataWidgetAttachEvent),
widgetProps = this.getNodeProps(node),
klass = node.get(dataWidgetType).trim();
// Create the widget
if(scope[klass]) {
var widget = new scope[klass](Object.merge(widgetProps, { element: node }));
this.debug("[parse:makeSubWidgets] Creating child widget: ", klass, widget);
// Get access to its dom node
widgetDomNode = widget.domNode;
// Add attachments back to the widget
points && widgetDomNode.set(dataWidgetAttachPoint, points.trim());
events && widgetDomNode.set(dataWidgetAttachEvent, events.trim());
}
}, this);
},
// Makes attachpoints
makeAttachPoints: function(node) {
var points = node.get(dataWidgetAttachPoint);
if(points) {
points.trim().split(",").each(function(attach) {
attach = attach.trim();
this[attach] = node.retrieve("widget") || node;
this.debug("[Templated:makeAttachPoints] " + attach, node);
this._attachPoints.push({ node: node, name: attach });
}, this);
node.set(dataWidgetAttachPoint, "");
node.set("data-widgetized-attach-point", points);
}
},
// Makes attachevents
makeAttachEvents: function(node) {
// Temporarily store this widget's events so they may be added to this.domNode later
var events = node.get(dataWidgetAttachEvent);
// If there are events....
if(events) {
// For every event found....
events.trim().split(",").each(function(event) {
// Trim the event
event = event.trim();
// Split the event:method pair
var eventFn = event.split(":");
// Trim and rename each piece
var nativeEvent = eventFn[0].trim(),
classEvent = eventFn[1].trim();
this.debug("[Templated:makeAttachEvents] " + nativeEvent + " / " + classEvent,node);
// If the method isn't found on this, create a stub for it'
if(!this[classEvent]) {
this.debug("cant find ", classEvent, " in: ", this, " creating sub for it");
this[classEvent] = function(){};
}
// Bind "this" to the event
var ev = this[classEvent].bind(this);
// Add the event to the domNode
node.addEvent(nativeEvent, ev);
// Store the event
this._attachEvents.push({ type: nativeEvent, event: ev, node: node });
}, this);
// Remove the event from its former place and add to -ized data item
var set = {
"data-widgetized-attach-event": events
};
set[dataWidgetAttachEvent] = "";
node.set(set);
//node.set("data-widget-attach-event","");
//node.set("data-widgetized-attach-event",events);
}
},
// Destroy: removes node events
destroy: function() {
// Get reference to domNode
var domNode = this.domNode, events = this._attachEvents, points = this._attachPoints;
// Clear out children
domNode.getElements("[" + dataWidgetized + "]").each(function(widget) {
widget.destroy();
});
// Remove events
if(events.length) {
events.each(function(event) {
if(event.node) event.node.removeEvents();
});
}
// Remove node connections
if(points.length) {
points.each(function(point) {
if(point.name != "domNode") this[point.name] = null;
}, this);
}
// Destroy the dom node and its children, fin
domNode.store("widget", null).destroy();
},
// Gets the in-node properties for a widget
getNodeProps: function(node) {
var props = node.get(dataWidgetProps),
widgetProps = {};
// Create the widget
if(props) {
// Not using JSON.parse because it's too restricting, especially with quotes
var json = "{" + props.trim() + "}";
if(JSON && JSON.decode) { // MooTools
widgetProps = JSON.decode(json);
}
else { // Native
eval("widgetProps = " + json);
}
}
return widgetProps;
},
debug: function(one, two, three, four) {
if(this.options.debugMode && console && console.log) {
console.log("[" + (this.domNode ? this.domNode.id : "") + "] ", one, two || "", three || "", four || "");
}
}
});
// If Request is available....
if(Request) {
Templated.templates = {};
// Return the template
Templated.implement({
// Method to return cached template or retrieve new one synchronously
getTemplate: function() {
/*
var url = this.options.templateUrl;
// Try to return cached first
if(Templated.templates[url]) {
return Templated.templates[url];
}
else {
// Send a new request
return new Request({
url: url,
async: false, // Used to ensure that necessary templates are there
onSuccess: function(template) {
this.options.template = template;
Templated.templates[url] = template;
this.parse();
}.bind(this)
}).send();
}
*/
var url = this.options.templateUrl;
// Try to return cached first
if(!Templated.templates[url]) {
// Send a new request
return new Request({
url: url,
async: false, // Used to ensure that necessary templates are there
onSuccess: function(template) {
this.options.template = template;
Templated.templates[url] = template;
this.parse();
}.bind(this),
onFailure: function() {
Templated.templates[url] = Templated.prototype.options.template;
}
}).send();
}
return Templated.templates[url];
}
});
}
// Allow for parsing of an element and its children
Element.implement({
parse: function() {
var elFn = function(element) {
// Get the widget type
var klass = element.get(dataWidgetType);
// If the class exists....
if(klass && scope[klass]) {
// Create the new class instance
new scope[klass]({ element: element });
}
else {
window.console && console.log && console.log("klass does not exist! ", klass);
}
};
// Grab this and all nodes which are not already widgetized
elFn(this);
$$(this.getElements("["+ dataWidgetType +"]:not(" + dataWidgetized + ")")).each(elFn);
}
});
// Get widget from id
document.widget = function(idOrNode) {
return document.id(idOrNode).retrieve("widget") || null;
};
})(this); // Scope limiter

96
couchpotato/static/scripts/page/about.js

@ -0,0 +1,96 @@
var AboutSettingTab = new Class({
tab: '',
content: '',
initialize: function(){
var self = this;
App.addEvent('load', self.addSettings.bind(self))
},
addSettings: function(){
var self = this;
self.settings = App.getPage('Settings')
self.settings.addEvent('create', function(){
var tab = self.settings.createTab('about', {
'label': 'About',
'name': 'about'
});
self.tab = tab.tab;
self.content = tab.content;
self.createAbout();
})
},
createAbout: function(){
var self = this;
var millennium = new Date(2008, 7, 16),
today = new Date(),
one_day = 1000*60*60*24;
self.settings.createGroup({
'label': 'About CouchPotato'
}).inject(self.content).adopt(
new Element('div.shutdown').adopt(
new Element('a.button.red', {
'text': 'Shutdown',
'events': {
'click': App.shutdown.bind(App)
}
}),
new Element('a.button.orange', {
'text': 'Restart',
'events': {
'click': App.restart.bind(App)
}
})
),
new Element('div.usenet').adopt(
new Element('span', {
'text': 'Help support CouchPotato and save some money for yourself by signing up for an account at'
}),
new Element('a', {
'href': 'https://usenetserver.com/partners/?a_aid=couchpotato&amp;a_bid=3f357c6f',
'text': 'UsenetServer'
}),
new Element('a', {
'href': 'http://www.newshosting.com/partners/?a_aid=couchpotato&amp;a_bid=a0b022df',
'text': 'Newshosting'
}),
new Element('span', {
'text': 'For as low as $7.95 per month, you’ll get:'
}),
new Element('ul').adopt(
new Element('li[text=Unlimited downloads]'),
new Element('li[text=Uncapped speeds]'),
new Element('li[text=Free SSL Encrypted connections]'),
new Element('li', {
'text': Math.ceil((today.getTime()-millennium.getTime())/(one_day))+" days retention"
})
)
),
new Element('div.donate', {
'html': '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----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-----END PKCS7-----">
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
</form>
I'm building CouchPotato in my spare time, so if you want to buy me a Pepsi while I'm coding, that would be awesome!'
})
);
}
});
window.addEvent('domready', function(){
window.About = new AboutSettingTab();
});

2
couchpotato/templates/_desktop.html

@ -11,6 +11,7 @@
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/library/mootools.js') }}"></script>
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/library/mootools_more.js') }}"></script>
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/library/templated.js') }}"></script>
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/library/uniform.js') }}"></script>
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/library/form_replacement/form_check.js') }}"></script>
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/library/form_replacement/form_radio.js') }}"></script>
@ -33,6 +34,7 @@
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/wanted.js') }}"></script>
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/settings.js') }}"></script>
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/about.js') }}"></script>
<!--<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/soon.js') }}"></script>
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/manage.js') }}"></script>-->

Loading…
Cancel
Save