progress on using the actual web page gen code

This commit is contained in:
Sam Tobin-Hochstadt 2013-10-12 13:22:21 -04:00 committed by Matthew Flatt
parent 879256dbd5
commit af2b3ccb39
37 changed files with 3461 additions and 42 deletions

View File

@ -44,3 +44,6 @@ dwsync.xml
.idea
output
*/compiled
compiled/
web/out

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
.codecomment {
color: #c2741f;
}
.codeparenthesis {
color: #843c24;
}
.codeconstant, .codestring {
color: #228b22;
}
.codeid, .codemodpath {
color: #262680;
}
.codeimportid {
color: blue;
}
.codeimportform {
font-weight: bold;
}
.codelinkimportid {
color: blue;
text-decoration: none;
}
.codelinkimportform {
font-weight: bold;
color: black;
text-decoration: none;
}
.codelinkimportid:hover {
text-decoration: none;
}
.codelinkimportform:hover {
text-decoration: none;
}
.codemodpath:hover {
text-decoration: none;
}
.codesnip { display: none }
.codesnip.active { display: block}

View File

@ -0,0 +1,24 @@
/*
We highly recommend you use SASS and write your custom styles in sass/_custom.scss.
However, this blank file is available if you prefer
*/
body { background: url(loud.png) center 60% no-repeat fixed; }
.modal h2, .modal .btn { margin: 10px 0 0px; }
.navbar div ul li a:hover { background: #292929; }
#growboxes { margin-top: 10pt; }
.panetitle { color: red; font-size: 120%; margin-bottom: 4pt }
pre.codesnip { font-size: 140%; }
.racketnav { display: none }
.wide_only { display: block; }
.narrow_only { display: none; }
@media only screen and (max-width: 767px) {
.wide_only { display: none; }
.narrow_only { display: block; }
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

View File

@ -259,9 +259,55 @@
(when news-flashes (error 'set-news-flashes! "text already set"))
(set! news-flashes text))
(require racket/format)
(define (css url) @link[href: url rel: "stylesheet" type: "text/css"]{})
(define (icon name) @i[class: name]{})
(define (row . content) (apply div class: "row" content))
(define (js . args) @script[type: "text/javascript" @(apply literal args) "\n"])
(define (tagline l) @span[style: "font-style: italic" l])
(define (panetitle l) @div[class: "panetitle" l])
(define (growbox title . body)
@columns[4 (panetitle (string-append "Grow your " title)) (apply p body)])
(define (docelem kw name link . text)
(apply p @a[href: link]{@strong[kw]: @|name| } text))
(define (sectitle name) @columns[10 #:center? #t #:row? #t]{@h3[name]})
(define (print-num n)
(list-ref
'("one" "two" "three" "four" "five" "six" "seven" "eight" "nine" "ten" "eleven" "twelve" "thirteen")
(sub1 n)))
(define (columns n #:row? [row? #f] #:center? [center? #f] #:tag [tag div] #:push [push #f] . body)
(define d (apply tag class: (~a (print-num n) " columns"
(if center? " centered" "")
(if push (~a " push_" (print-num push)) "")) body))
(if row? (row d) d))
(define prev @img[src: (copyfile (in-here "img/prev.png")) style: "width: 50px"])
(define next @img[src: (copyfile (in-here "img/next.png")) style: "width: 50px"])
(define gumby-css (copyfile (in-here "css/gumby.css")
"css/gumby.css"))
(define style (copyfile (in-here "css/style.css")
"css/style.css"))
(define scribble-css (copyfile (in-here "css/scribble.css")
"css/scribble.css"))
(define gumby-js (copyfile (in-here "js/libs/gumby.min.js")))
(define plugins-js (copyfile (in-here"js/plugins.js")))
(define main-js (copyfile (in-here "js/main.js")))
(define jquery-js (copyfile (in-here "js/libs/jquery-1.9.1.min.js")))
(copyfile (in-here "fonts/icons/entypo.woff") "fonts/icons/entypo.woff")
(copyfile (in-here "fonts/icons/entypo.ttf") "fonts/icons/entypo.ttf")
(copyfile (in-here "fonts/icons/entypo.eot") "fonts/icons/entypo.eot")
(provide index)
(define index
(page #:link-title "About" #:window-title "The Racket Language"
@page[#:window-title "The Racket Language"
#:description
@'{Racket is a modern programming language in the Lisp/Scheme family, @;
suitable for a wide range of applications. @;
@ -270,47 +316,239 @@
libraries.}
@; Ask google to not use the ODP description
#:extra-headers @list{@meta[name: "robots" content: "NOODP"]
@(lazy more.css)}
@div[class: 'leftpane]{
@span[style: "font-size: large; font-weight: bold;"]{Racket}
is a programming language.
@(and news-flashes (list br (div style: "width: 100%;" news-flashes)))}
@div[class: 'downloadbutton]{@download-button}
@div[class: 'aboutpane]{
@div[class: 'panetitle]{Start Quickly}
@div{@(apply slideshow-panel examples)}
@p{@doc["quick/"]{Draw more pictures} or
@doc["more/"]{build a web server from scratch}. Racket includes both
@doc[""]{batteries} and a @doc["drracket/"]{programming environment},
so @doc["getting-started/"]{get started}!}}
@((λ xs (table class: 'threepanes
(tr (map (λ (x) (td (div class: 'panetitle (car x)) (cdr x)))
xs))))
(list "Grow your Program"
@p{Racket's
@doc["guide/intro.html#(part._.Interacting_with_.Racket)"]{
interactive mode}
encourages experimentation, and quick scripts easily compose into
larger systems. Small scripts and large systems both benefit from
@doc["guide/performance.html"]{native-code JIT compilation}.
When a system gets too big to keep in your head, you can add
@doc["ts-guide/index.html"]{static types}.})
(list "Grow your Language"
@p{@doc["guide/languages.html"]{Extend Racket} whenever you need to.
Mold it to better suit your tasks without sacrificing
@doc["guide/dialects.html"]{interoperability} with existing
libraries and without having to modify the
@doc["guide/intro.html"]{tool chain}. When less is more, you can
remove parts of a language or start over and build a new one.})
(list "Grow your Skills"
@p{Whether you're just @-htdp{starting out}, want to know more about
programming language @-plai{applications} or @-redex{models},
looking to @continue{expand your horizons}, or ready to dive into
@learning{research}, Racket can help you become a better programmer
and system builder.}))))
(define index2
@page{
new stuff here
@;<!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline -->
@script[src: (copyfile (in-here "js/libs/modernizr-2.6.2.min.js"))]
@script[src: "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"]
@js{window.jQuery || document.write('<script src="@|jquery-js|"><\/script>')}
@script[src: gumby-js]
@script[src: plugins-js]
@script[src: main-js]
@css[gumby-css]
@css[style]
@css[scribble-css]}]{
@div[class: "navbar" gumby-fixed: "top" id: "nav1"]{
@row{
@a[class: "toggle" gumby-trigger: "#nav1 > .row > ul" href: "#"]{
@icon{icon-menu}}
@a[class: "five columns logo" href: ""]{
@img[class: "logo" src: (copyfile (in-here "img/logo-new.png"))]}
@ul[class: "five columns"]{
@li{@a[href: "https://pkg.racket-lang.org"]{Packages}}
@li{@a[href: "https://docs.racket-lang.org"]{Documentation}}
@li{@a[href: "https://blog.racket-lang.org"]{Blog}}
@li{@button[class: "medium metro info btn icon-left entypo icon-install"]{
@a[href: "#"]{Download}}}}}}
@columns[10 #:row? #t #:center? #t]{
@h2[style: "font-size: 180%; margin-bottom: 10pt"]{
@strong{Racket} @|nbsp mdash nbsp|
@tagline{a programmable programming language}}}
@columns[8 #:center? #t #:row? #t
style: "margin-bottom: 10pt; font-size: 120%; text-align:justify;"]{
Racket is a full-spectrum programming language that inherits from Lisp
and Scheme but also provides dialects that support objects, types,
laziness, and many other paradigms. Racket's module system allows
programmers to write and link together components written in different
dialects. Racket's libraries range from web servers to distributed
computing and from databases to charts.
}
@div[id: "topcontent"]{
@row{
@columns[1]
@columns[7]{
@h2[style: "font-size: 180%; margin-bottom: 10pt"]{Start Quickly}
@div[style: "position: relative"]{
@p[class: "metro primary btn"
style: "position: absolute; top: -10%; right: 0%;"]{
@a[href: "#" class: "switch" gumby-trigger: "#modal1"]{
@icon["icon-help"]}}
@a[href: "#" class: "toggle narrow_only"
gumby-trigger: ".unique_lines|.web_scraper"
style: "position: absolute; top: -40%; left: 35%"]{@prev}
@a[href: "#" class: "toggle narrow_only"
gumby-trigger: ".unique_lines|.web_scraper"
style: "position: absolute; top: -40%; right: 35%"]{@next}
@a[href: "#" class: "toggle wide_only"
gumby-trigger: ".unique_lines|.web_scraper"
style: "position: absolute; top: 40%; left: -15%"]{@prev}
@a[href: "#" class: "toggle wide_only"
gumby-trigger: ".unique_lines|.web_scraper"
style: "position: absolute; top: 40%; right: -15%"]{@next}}}
@columns[1]
@columns[3 style: "text-color: black"]{
@h2[style: "font-size: 180%; margin-bottom: 10pt"]{News}
@p{Racket version 5.3.5 has been released.}
@p{Racket videos are now available.}
@p{@a[href: "racketcon.html"]{RacketCon 2013} will be in September in Boston.}}}
@columns[12 #:row? #t #:center? #t style: "text-align:justify;font-size: 120%; margin-top: 20pt; "]{
@a[href: "http://docs.racket-lang.org/quick/"]{Draw more pictures} or
@a[href: "http://docs.racket-lang.org/more/"]{build a web server from scratch}. Racket includes both
@a[href: "http://docs.racket-lang.org/"]{batteries} and a @a[href: "http://docs.racket-lang.org/drracket/"]{programming environment},
so @a[href: "http://docs.racket-lang.org/getting-started/"]{get started}!
}}
@sectitle{Go Further}
@row[id: 'growboxes]{
@growbox["Program"]{Racket's
@a[href: "http://docs.racket-lang.org/guide/intro.html#(part._.Interacting_with_.Racket)"]{interactive
mode} encourages experimentation, and quick scripts easily compose
into larger systems. Small scripts and large systems both benefit
from
@a[href: "http://docs.racket-lang.org/guide/performance.html"]{native-code
JIT compilation} When a system gets too big to keep in your head, you
can add
@a[href: "http://docs.racket-lang.org/ts-guide/index.html"]{static
types}.}
@growbox["Language"]{@a[href: "http://docs.racket-lang.org/guide/languages.html"]{Extend
Racket} whenever you need to. Mold it to better suit your tasks
without sacrificing
@a[href: "http://docs.racket-lang.org/guide/dialects.html"]{interoperability}
with existing libraries and without having to modify the
@a[href: "http://docs.racket-lang.org/guide/intro.html"]{tool chain}.
When less is more, you can remove parts of a language or start over
and build a new one.}
@growbox["Skills"]{Whether you're just
@a[href: "http://htdp.org/"]{starting out}, want to know more about
programming language @a[href: "http://www.plai.org/"]{applications} or
@a[href: "http://redex.racket-lang.org/"]{models}, looking to
@a[href: "http://docs.racket-lang.org/continue/"]{expand your
horizons}, or ready to dive into @a[href: "learning.html"]{research},
Racket can help you become a better programmer and system builder.}}
@sectitle{Documentation}
@row{
@columns[5]{
@panetitle{For getting started}
@docelem['Quick "An Introduction to Racket with Pictures" "http://docs.racket-lang.org/quick/"]{
gives you a taste of Racket.}
@docelem['More "Systems Programming with Racket" "http://docs.racket-lang.org/more/"]{
dives much deeper and much faster, showing how to build a complete
continuation-based web server.}
@docelem['Guide "Racket" "http://docs.racket-lang.org/guide/"]{
starts with a tutorial on Racket basics, and then it
describes the rest of the Racket language.}}
@columns[5 #:push 2]{
@panetitle{For experienced Racketeers}
@docelem['Reference "Racket" "http://docs.racket-lang.org/reference/"]{
provides comprehensive coverage of all of Racket.}
@docelem['Continue "Web Applications in Racket" "http://docs.racket-lang.org/continue/"]{
describes how to use the
Racket @a[href: "http://docs.racket-lang.org/web-server/"]{web
server} to build dynamic web applications.}
@docelem["Package Management" "Racket" "http://docs.racket-lang.org/pkg/"]{
explains how to install
@a[href: "https://pkg.racket-lang.org"]{packages}, and how to
build and distribute your own.}}
}
@sectitle{Community}
@row{
@columns[4]{
@panetitle{News & Events}
@p{@a[href: "racketcon.html"]{RacketCon} the annual
Racket meeting, coming up in September. Previously
in @a[href: "http://con.racket-lang.org/2012"]{2012}
and @a[href: "http://con.racket-lang.org/2012"]{2011}.}
@p{@a[href: "http://blog.racket-lang.org/"]{Blog}
announcements, helpful hints, and thoughtful rants.}
@p{@a[href: "http://twitter.com/#!/racketlang"]{Twitter}
short bits of Racket news.}
}
@columns[4]{
@panetitle{Discussion}
@p{@a[href: "http://lists.racket-lang.org/"]{Mailing lists}
discussion for using and developing Racket.}
@p{@a[href: "http://racket-lang.org/irc-chat.html"]{IRC}
Chat in the @tt[style: "background-color: #d8d8e8;"]{@big{@strong{#racket}}} channel on
@a[href: "http://freenode.net"]{@tt{freenode.net}} an informal
discussion channel for all things related to Racket.
(@a[href: "https://botbot.me/freenode/racket/"]{Browse the logs}.)}
@p{@a[href: "http://racket-lang.org/people.html"]{People}
The people behind Racket.}
}
@columns[4]{
@panetitle{Contributing}
@p{@a[href: "https://github.com/plt/racket/"]{Code}
the Racket source code on GitHub.}
@p{@a[href: "https://github.com/plt/racket/wiki"]{Wiki}
Useful pages
include @a[href: "https://github.com/plt/racket/wiki/Intro-Projects"]{Intro
Projects}
and @a[href: "https://github.com/plt/racket/wiki/Videos"]{Videos},
including tutorials, interviews, and more.}
@p{@a[href: "http://www.cs.utah.edu/plt/snapshots"]{Snapshot builds}
The freshest versions of Racket.}
@p{@a[href: "http://bugs.racket-lang.org"]{Bug reports}
File, query and maybe fix existing reports.}}}
@sectitle{Learning}
@row{
@row{
@div[class: "two columns image rounded" style: "margin-top: 2pt"]{
@a[href: "http://www.htdp.org"]{@img[src: (copyfile (in-here "img/htdp-cover.gif"))]}}
@columns[4]{@panetitle{How to Design Programs}
@p{A principled approach to program design}
@ul{
@li{Teaching language support built-in to DrRacket}
@li{Aimed at the programming novice}}}
@columns[4]{@panetitle{Realm of Racket}
@p{Learn Racket and programming, one game at a time}
@ul{
@li{Sample game code comes with the Racket distribution}
@li{For those just starting out with Racket}
}}
@div[class: "two columns image rounded" style: "margin-top: 2pt"]{
@a[href: "http://www.realmofracket.com"]{@img[src: (copyfile (in-here "img/racket_cover_web.png"))]}}
}}
@row{
@row{
@div[class: "two columns image rounded" style: "margin-top: 2pt"]{
@a[href: "http://cs.brown.edu/~sk/Publications/Books/ProgLangs/2007-04-26/"]{@img[src: (copyfile (in-here "img/plai-cover.jpg"))]}}
@columns[4]{@panetitle{PLAI}
@p{Foundations of programming languages}
@ul{
@li{Understand the features that make languages tick}
@li{For undergraduates, graduate students, and experts}}}
@columns[4]{@panetitle{Semantics Engineering with PLT Redex}
@p{Lightweight automation for semantics}
@ul{
@li{Model your own programming language semantics}
@li{For the working language engineer}
}}
@div[class: "two columns image rounded" style: "margin-top: 2pt"]{
@a[href: "http://redex.racket-lang.org/"]{@img[src: (copyfile (in-here "img/redex-cover.jpg"))]}}
}}
})
(define (slideshow-panel l1 l2)
@ -418,6 +656,7 @@
(define loud (copyfile (in-here "loud.png")))
(define more.css
@plain[#:referrer (λ (url) (link rel: "stylesheet" type: "text/css"
href: url title: "default"))]{

View File

@ -0,0 +1,27 @@
/**
* Gumby Init
*/
// test for touch event support
Modernizr.load({
test: Modernizr.touch,
// if present load custom jQuery mobile build and update Gumby.click
yep: Gumby.path+'/jquery.mobile.custom.min.js',
callback: function(url, result, key) {
// check jQuery mobile has successfully loaded before using tap events
if($.mobile) {
window.Gumby.click = 'tap';
}
},
// either way initialize Gumby
complete: function() {
window.Gumby.init();
// if AMD return Gumby object to define
if(typeof define == "function" && define.amd) {
define(window.Gumby);
}
}
});

View File

@ -0,0 +1,150 @@
/**
* Gumby Framework
* ---------------
*
* Follow @gumbycss on twitter and spread the love.
* We worked super hard on making this awesome and released it to the web.
* All we ask is you leave this intact. #gumbyisawesome
*
* Gumby Framework
* http://gumbyframework.com
*
* Built with love by your friends @digitalsurgeons
* http://www.digitalsurgeons.com
*
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/
!function() {
'use strict';
function Gumby() {
this.$dom = $(document);
this.isOldie = !!this.$dom.find('html').hasClass('oldie');
this.click = 'click';
this.onReady = this.onOldie = this.onTouch = false;
this.uiModules = {};
this.inits = {};
// check and set path with js/libs default
this.path = $('script[gumby-path]').attr('gumby-path') ||
$('script[data-path]').attr('data-path') ||
$('script[path]').attr('path') ||
'js/libs';
}
// initialize Gumby
Gumby.prototype.init = function() {
// init UI modules
this.initUIModules();
var scope = this;
// call ready() code when dom is ready
this.$dom.ready(function() {
if(scope.onReady) {
scope.onReady();
}
// call oldie() callback if applicable
if(scope.isOldie && scope.onOldie) {
scope.onOldie();
}
// call touch() callback if applicable
if(Modernizr.touch && scope.onTouch) {
scope.onTouch();
}
});
};
// public helper - set Gumby ready callback
Gumby.prototype.ready = function(code) {
if(code && typeof code === 'function') {
this.onReady = code;
}
};
// public helper - set oldie callback
Gumby.prototype.oldie = function(code) {
if(code && typeof code === 'function') {
this.onOldie = code;
}
};
// public helper - set touch callback
Gumby.prototype.touch = function(code) {
if(code && typeof code === 'function') {
this.onTouch = code;
}
};
// public helper - return debuggin object including uiModules object
Gumby.prototype.debug = function() {
return {
$dom: this.$dom,
isOldie: this.isOldie,
uiModules: this.uiModules,
click: this.click
};
};
// grab attribute value, testing data- gumby- and no prefix
Gumby.prototype.selectAttr = function() {
var i = 0;
// any number of attributes can be passed
for(; i < arguments.length; i++) {
// various formats
var attr = arguments[i],
dataAttr = 'data-'+arguments[i],
gumbyAttr = 'gumby-'+arguments[i];
// first test for data-attr
if(this.attr(dataAttr)) {
return this.attr(dataAttr);
// next test for gumby-attr
} else if(this.attr(gumbyAttr)) {
return this.attr(gumbyAttr);
// finally no prefix
} else if(this.attr(attr)) {
return this.attr(attr);
}
}
// none found
return false;
};
// add an initialisation method
Gumby.prototype.addInitalisation = function(ref, code) {
this.inits[ref] = code;
};
// initialize a uiModule
Gumby.prototype.initialize = function(ref) {
if(this.inits[ref] && typeof this.inits[ref] === 'function') {
this.inits[ref]();
}
};
// store a UI module
Gumby.prototype.UIModule = function(data) {
var module = data.module;
this.uiModules[module] = data;
};
// loop round and init all UI modules
Gumby.prototype.initUIModules = function() {
var x;
for(x in this.uiModules) {
this.uiModules[x].init();
}
};
window.Gumby = new Gumby();
}();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,93 @@
/**
* Gumby Checkbox
*/
!function() {
'use strict';
function Checkbox($el) {
this.$el = $el;
var scope = this;
// listen for click event and custom gumby check/uncheck events
this.$el.on(Gumby.click, function(e) {
scope.click(e);
}).on('gumby.check', function() {
scope.update(true);
}).on('gumby.uncheck', function() {
scope.update(false);
});
// update any .checked checkboxes on load
if(scope.$el.hasClass('checked')) {
scope.update(true);
}
}
// handle checkbox click event
Checkbox.prototype.click = function(e) {
// element responsible for event trigger
var $target = $(e.target);
// prevent propagation
e.stopPropagation();
// prevent checkbox checking, we'll do that manually
e.preventDefault();
// check/uncheck
if(this.$el.hasClass('checked')) {
this.update(false);
} else {
this.update(true);
}
};
// update checkbox, check equals true/false to sepcify check/uncheck
Checkbox.prototype.update = function(check) {
var $input = this.$el.find('input'),
$span = this.$el.find('span');
// check checkbox - check input, add checked class, append <i>
if(check) {
$span.append('<i class="icon-check" />');
$input.prop('checked', true).end()
.addClass('checked')
.trigger('gumby.onCheck').trigger('gumby.onChange');
// uncheck checkbox - uncheck input, remove checked class, remove <i>
} else {
$input.prop('checked', false).end()
.find('i').remove().end()
.removeClass('checked').trigger('gumby.onUncheck').trigger('gumby.onChange');
}
};
// add initialisation
Gumby.addInitalisation('checkboxes', function() {
$('.checkbox').each(function() {
var $this = $(this);
// this element has already been initialized
if($this.data('isCheckbox')) {
return true;
}
// mark element as initialized
$this.data('isCheckbox', true);
new Checkbox($this);
});
});
// register UI module
Gumby.UIModule({
module: 'checkbox',
events: ['onCheck', 'onUncheck', 'onChange', 'check', 'uncheck'],
init: function() {
Gumby.initialize('checkboxes');
}
});
}();

View File

@ -0,0 +1,83 @@
/**
* Gumby FitText
*
* Adapted from the awesome FitText jQuery plugin
* brought to you by Paravel - http://paravelinc.com/
*/
!function() {
'use strict';
function FitText($el) {
this.$el = $el;
// optional compressor rate
this.rate = Gumby.selectAttr.apply(this.$el, ['rate']) || 1;
// optional font sizes (min|max)
this.fontSizes = this.parseSizes(Gumby.selectAttr.apply(this.$el, ['sizes']));
var scope = this;
// lets go
$(window).on('load resize orientationchange', function() {
scope.resize();
});
}
// apply the resizing
FitText.prototype.resize = function() {
this.$el.css('font-size', this.calculateSize());
};
// calculate the font size
FitText.prototype.calculateSize = function() {
return Math.max(Math.min(this.$el.width() / (this.rate*10), parseFloat(this.fontSizes.max)), parseFloat(this.fontSizes.min));
};
// parse size attributes with min|max syntax
FitText.prototype.parseSizes = function(attrStr) {
var sizes = {
min: Number.NEGATIVE_INFINITY,
max: Number.POSITIVE_INFINITY
};
// attribute is optional
if(!attrStr) { return sizes; }
// min and/or max specified
if(attrStr.indexOf('|') > -1) {
attrStr = attrStr.split('|');
// both are optional
sizes.min = Number(attrStr[0]) || sizes.min;
sizes.max = Number(attrStr[1]) || sizes.max;
}
// only one value specific without | so use as min
sizes.min = Number(attrStr) || sizes.min;
return sizes;
};
// add initialisation
Gumby.addInitalisation('fittext', function() {
$('.fittext').each(function() {
var $this = $(this);
// this element has already been initialized
if($this.data('isFittext')) {
return true;
}
// mark element as initialized
$this.data('isFittext', true);
new FitText($this);
});
});
// register UI module
Gumby.UIModule({
module: 'fittext',
events: [],
init: function() {
Gumby.initialize('fittext');
}
});
}();

View File

@ -0,0 +1,111 @@
/**
* Gumby Fixed
*/
!function() {
'use strict';
function Fixed($el) {
this.$el = $el;
this.$holder = Gumby.selectAttr.apply(this.$el, ['holder']);
this.fixedPoint = Gumby.selectAttr.apply(this.$el, ['fixed']);
this.unfixPoint = false;
// if holder attr set then create jQuery object
// otherwise use window for scrolling cals
if(this.$holder) {
this.$holder = $(this.$holder);
} else {
this.$holder = $(window);
}
// fix/unfix points specified
if(this.fixedPoint.indexOf('|') > -1) {
var points = this.fixedPoint.split('|');
this.fixedPoint = points[0];
this.unfixPoint = points[1];
}
// parse possible parameters
this.fixedPoint = this.parseAttrValue(this.fixedPoint);
if(this.unfixPoint) {
this.unfixPoint = this.parseAttrValue(this.unfixPoint);
}
var scope = this;
this.$holder.scroll(function() {
scope.scroll();
});
}
// handle scroll event on window/specified holder
Fixed.prototype.scroll = function() {
var offset = this.$holder.scrollTop(),
fixedPoint = this.fixedPoint,
unfixPoint = this.unfixPoint,
endPoint = this.endPoint;
// if fixed point, unfix point or end point are DOM fragements
// then re-calculate values as could have been updated
fixedPoint = fixedPoint instanceof jQuery ? this.fixedPoint.offset().top : this.fixedPoint;
unfixPoint = unfixPoint instanceof jQuery ? this.unfixPoint.offset().top : this.unfixPoint;
// ensure unfix point is never reached if not set
if(!unfixPoint) {
unfixPoint = offset * 2;
}
// scrolled past fixed point and no fixed class present
if((offset >= fixedPoint) && (offset < unfixPoint) && !this.$el.hasClass('fixed')) {
this.$el.addClass('fixed').trigger('gumby.onFixed');
// before fixed point, pass 0 to onUnfixed event
} else if((offset <= fixedPoint) && this.$el.hasClass('fixed')) {
this.$el.removeClass('fixed').trigger('gumby.onUnfixed', 0);
}
// after unfix point, pass 1 to onUnfixed event
// separate conditional as should override
if(unfixPoint && (offset >= unfixPoint) && this.$el.hasClass('fixed')) {
this.$el.removeClass('fixed').trigger('gumby.onUnfixed', 1);
}
};
// parse attribute values, could be px, top, selector
Fixed.prototype.parseAttrValue = function(attr) {
// px value fixed point
if($.isNumeric(attr)) {
return Number(attr);
// 'top' string fixed point
} else if(attr === 'top') {
return this.$el.offset().top;
// selector specified
} else {
var $el = $(attr);
return $el.length ? $el : false;
}
};
// add initialisation
Gumby.addInitalisation('fixed', function() {
$('[data-fixed],[gumby-fixed],[fixed]').each(function() {
var $this = $(this);
// this element has already been initialized
if($this.data('isFixed')) {
return true;
}
// mark element as initialized
$this.data('isFixed', true);
new Fixed($this);
});
});
// register UI module
Gumby.UIModule({
module: 'fixed',
events: ['onFixed', 'onUnfixed'],
init: function() {
Gumby.initialize('fixed');
}
});
}();

View File

@ -0,0 +1,69 @@
/**
* Gumby Navbar
*/
!function() {
'use strict';
// define module class and init only if we're on touch devices
if(!Modernizr.touch) {
return;
}
function Navbar($el) {
this.$el = $el;
var scope = this;
// when navbar items are tapped hide/show dropdowns
this.$el.find('li').on(Gumby.click, function(e) {
var $this = $(this);
e.stopPropagation();
// prevent jump to top of page
if(this.href === '#') {
e.preventDefault();
}
scope.dropdown($this);
});
}
// hide/show dropdowns
Navbar.prototype.dropdown = function($this) {
// we have dropdowns so open/cose
if($this.children('.dropdown').length) {
if($this.hasClass('active')) {
$this.removeClass('active');
} else {
$this.addClass('active');
}
// no dropdown so close others
} else {
this.$items.removeClass('active');
}
};
// add initialisation
Gumby.addInitalisation('navbars', function() {
$('.navbar').each(function() {
var $this = $(this);
// this element has already been initialized
if($this.data('isNavbar')) {
return true;
}
// mark element as initialized
$this.data('isNavbar', true);
new Navbar($this);
});
});
// register UI module
Gumby.UIModule({
module: 'navbar',
events: [],
init: function() {
Gumby.initialize('navbars');
}
});
}();

View File

@ -0,0 +1,83 @@
/**
* Gumby RadioBtn
*/
!function() {
'use strict';
function RadioBtn($el) {
this.$el = $el;
var scope = this;
// listen for click event and custom gumby check event
this.$el.on(Gumby.click, function(e) {
scope.click(e);
}).on('gumby.check', function() {
scope.update();
});
// update any .checked checkboxes on load
if(scope.$el.hasClass('checked')) {
scope.update();
}
}
// handle radio button click event
RadioBtn.prototype.click = function(e) {
// element responsible for event trigger
var $target = $(e.target);
// prevent propagation
e.stopPropagation();
// prevent radio button checking, we'll do that manually
e.preventDefault();
// check radio button
this.update();
};
// check radio button, uncheck all others in name group
RadioBtn.prototype.update = function() {
var // this specific radio button
$input = this.$el.find('input[type=radio]'),
$span = this.$el.find('span'),
// the group of radio buttons
group = 'input[name="'+$input.attr('name')+'"]';
// uncheck radio buttons in same group - uncheck input, remove checked class, remove <i>
$('.radio').has(group).removeClass('checked')
.find('input').prop('checked', false).end()
.find('i').remove();
// check this radio button - check input, add checked class, append <i>
$input.prop('checked', true);
$span.append('<i class="icon-dot" />');
this.$el.addClass('checked').trigger('gumby.onChange');
};
// add initialisation
Gumby.addInitalisation('radiobtns', function() {
$('.radio').each(function() {
var $this = $(this);
// this element has already been initialized
if($this.data('isRadioBtn')) {
return true;
}
// mark element as initialized
$this.data('isRadioBtn', true);
new RadioBtn($this);
});
});
// register UI module
Gumby.UIModule({
module: 'radiobtn',
events: ['onChange', 'check'],
init: function() {
Gumby.initialize('radiobtns');
}
});
}();

View File

@ -0,0 +1,74 @@
/**
* Gumby Retina
*/
!function() {
'use strict';
function Retina($el) {
this.$el = $el;
this.imageSrc = this.$el.attr('src');
this.retinaSrc = this.fetchRetinaImage();
this.$retinaImg = $(new Image());
var scope = this
// image src not valid
if(!this.retinaSrc) {
return false;
}
// load retina image
this.$retinaImg.attr('src', this.retinaSrc).load(function() {
scope.retinaImageLoaded();
});
}
// fetch retina src by appending '@2x' to image string before extension
Retina.prototype.fetchRetinaImage = function() {
var imgSrc = this.imageSrc,
index = this.imageSrc.search(/(\.|\/)(gif|jpe?g|png)$/i);
// image src is not valid
if(index < 0) {
return false;
}
// return retina src
return imgSrc.substr(0, index) + '@2x' + imgSrc.substr(index, imgSrc.length);
};
// once retina image loaded swap original src
Retina.prototype.retinaImageLoaded = function() {
this.$el.attr('src', this.$retinaImg.attr('src')).trigger('gumby.onRetina');
};
// add initialisation
Gumby.addInitalisation('retina', function() {
// this module is for retina devices only
if(!window.devicePixelRatio || window.devicePixelRatio <= 1) {
return;
}
$('img[data-retina],img[gumby-retina],img[retina]').each(function() {
var $this = $(this);
// this element has already been initialized
if($this.data('isRetina')) {
return true;
}
// mark element as initialized
$this.data('isRetina', true);
new Retina($this);
});
});
// register UI module
Gumby.UIModule({
module: 'retina',
events: ['onRetina'],
init: function() {
Gumby.initialize('retina');
}
});
}();

View File

@ -0,0 +1,112 @@
/**
* Gumby SkipLink
*/
!function() {
'use strict';
function SkipLink($el) {
this.$el = $el;
this.targetPos = 0;
this.duration = Number(Gumby.selectAttr.apply(this.$el, ['duration'])) || 200;
this.offset = Gumby.selectAttr.apply(this.$el, ['offset']) || false;
this.easing = Gumby.selectAttr.apply(this.$el, ['easing']) || 'swing';
var scope = this;
// skip to target element on click or trigger of gumby.skipTo event
this.$el.on(Gumby.click+' gumby.skip', function(e) {
e.preventDefault();
// calculate target on each click
// other UI interactions could effect this
scope.calculateTarget();
});
}
// calculate target px point to skip to
SkipLink.prototype.calculateTarget = function() {
var scope = this,
target = Gumby.selectAttr.apply(this.$el, ['goto']),
$target;
// 'top' specified so target is 0px
if(target == 'top') {
this.targetPos = 0;
// px point specified
} else if($.isNumeric(target)) {
this.targetPos = Number(target);
} else {
// check for element with target as selector
$target = $(target);
// target does not exist, we need a target
if(!$target) {
return false;
}
this.targetPos = $target.offset().top;
}
// skip to target
this.skipTo();
};
// animate body, html scrollTop value to target px point
SkipLink.prototype.skipTo = function() {
var scope = this;
// slide to position of target
$('html,body').animate({
'scrollTop' : this.calculateOffset()
}, this.duration, this.easing).promise().done(function() {
scope.$el.trigger('gumby.onComplete');
});
};
// calculate offset with current target point
SkipLink.prototype.calculateOffset = function() {
// no offset so return target here
if(!this.offset) {
return this.targetPos;
}
// negative / positive
var op = this.offset.substr(0, 1),
off = Number(this.offset.substr(1, this.offset.length));
// subtract offset from target position
if(op === '-') {
return this.targetPos - off;
// add offset to target position
} else if(op === '+') {
return this.targetPos + off;
}
};
// add initialisation
Gumby.addInitalisation('skiplinks', function() {
$('.skiplink > a, .skip').each(function() {
var $this = $(this);
// this element has already been initialized
if($this.data('isSkipLink')) {
return true;
}
// mark element as initialized
$this.data('isSkipLink', true);
new SkipLink($this);
});
});
// register UI module
Gumby.UIModule({
module: 'skiplink',
events: ['onComplete', 'skip'],
init: function() {
Gumby.initialize('skiplinks');
}
});
}();

View File

@ -0,0 +1,70 @@
/**
* Gumby Tabs
*/
!function() {
'use strict';
function Tabs($el) {
this.$el = $el;
this.$nav = this.$el.find('ul.tab-nav > li');
this.$content = this.$el.find('.tab-content');
var scope = this;
// listen for click event on tab nav and custom gumby set event
this.$nav.children('a').on(Gumby.click, function(e) {
e.preventDefault();
scope.click($(this));
});
// listen for gumby.set value for dynamically set tabs
this.$el.on('gumby.set', function(e, index) {
scope.set(e, index);
});
}
// handle tab nav click event
Tabs.prototype.click = function($this) {
// index of item to activate
var index = $this.parent().index();
// deactivate other tab navigation and content
this.$nav.add(this.$content).removeClass('active');
// activate this tab nav link and content
this.$nav.eq(index).add(this.$content.eq(index)).addClass('active');
// trigger gumby.change event and pass current active tab index
this.$el.trigger('gumby.onChange', index);
};
// set specific tab
Tabs.prototype.set = function(e, index) {
this.$nav.eq(index).find('a').trigger(Gumby.click);
};
// add initialisation
Gumby.addInitalisation('tabs', function() {
$('.tabs').each(function() {
var $this = $(this);
// this element has already been initialized
if($this.data('isTabs')) {
return true;
}
// mark element as initialized
$this.data('isTabs', true);
new Tabs($this);
});
});
// register UI module
Gumby.UIModule({
module: 'tabs',
events: ['onChange', 'set'],
init: function() {
Gumby.initialize('tabs');
}
});
}();

View File

@ -0,0 +1,176 @@
/**
* Gumby Toggles/Switches
*/
!function() {
'use strict';
// Toggle constructor
function Toggle($el) {
this.$el = $($el);
this.targets = [];
this.on = '';
if(this.$el.length) {
this.init();
}
}
// Switch constructor
function Switch($el) {
this.$el = $($el);
this.targets = [];
this.on = '';
if(this.$el.length) {
this.init();
}
}
// intialise toggles, switches will inherit method
Toggle.prototype.init = function() {
this.targets = this.parseTargets();
this.on = Gumby.selectAttr.apply(this.$el, ['on']) || Gumby.click;
var scope = this;
// bind to specified event and trigger
this.$el.on(this.on, function(e) {
// only disable default if <a>
if($(this).prop('tagName') === 'A') {
e.preventDefault();
}
// stop propagation
e.stopPropagation();
scope.trigger(scope.triggered);
// listen for gumby.trigger to dynamically trigger toggle/switch
}).on('gumby.trigger', function() {
scope.trigger(scope.triggered);
});
};
// parse data-for attribute, switches will inherit method
Toggle.prototype.parseTargets = function() {
var targetStr = Gumby.selectAttr.apply(this.$el, ['trigger']),
secondaryTargets = 0,
targets = [];
// no targets so return false
if(!targetStr) {
return false;
}
secondaryTargets = targetStr.indexOf('|');
// no secondary targets specified so return single target
if(secondaryTargets === -1) {
return [$(targetStr)];
}
// return array of both targets, split and return 0, 1
targets = targetStr.split('|');
return targets.length > 1 ? [$(targets[0]), $(targets[1])] : [$(targets[0])];
};
// call triggered event and pass target data
Toggle.prototype.triggered = function() {
// trigger gumby.onTrigger event and pass array of target status data
this.$el.trigger('gumby.onTrigger', [this.$el.hasClass('active')]);
};
// Switch object inherits from Toggle
Switch.prototype = new Toggle();
// Toggle specific trigger method
Toggle.prototype.trigger = function(cb) {
// no targets just toggle active class on toggle
if(!this.targets) {
this.$el.toggleClass('active');
// combine single target with toggle and toggle active class
} else if(this.targets.length == 1) {
this.$el.add(this.targets[0]).toggleClass('active');
// if two targets check active state of first
// always combine toggle and first target
} else if(this.targets.length > 1) {
if(this.targets[0].hasClass('active')) {
this.$el.add(this.targets[0]).removeClass('active');
this.targets[1].addClass('active');
} else {
this.targets[1].removeClass('active');
this.$el.add(this.targets[0]).addClass('active');
}
}
// call event handler here, applying scope of object Switch/Toggle
if(cb && typeof cb === 'function') {
cb.apply(this);
}
};
// Switch specific trigger method
Switch.prototype.trigger = function(cb) {
// no targets just add active class to switch
if(!this.targets) {
this.$el.addClass('active');
// combine single target with switch and add active class
} else if(this.targets.length == 1) {
this.$el.add(this.targets[0]).addClass('active');
// if two targets check active state of first
// always combine switch and first target
} else if(this.targets.length > 1) {
this.$el.add(this.targets[0]).addClass('active');
this.targets[1].removeClass('active');
}
// call event handler here, applying scope of object Switch/Toggle
if(cb && typeof cb === 'function') {
cb.apply(this);
}
};
// add toggle initialisation
Gumby.addInitalisation('toggles', function() {
$('.toggle').each(function() {
var $this = $(this);
// this element has already been initialized
if($this.data('isToggle')) {
return true;
}
// mark element as initialized
$this.data('isToggle', true);
new Toggle($this);
});
});
// add switches initialisation
Gumby.addInitalisation('switches', function() {
$('.switch').each(function() {
var $this = $(this);
// this element has already been initialized
if($this.data('isSwitch')) {
return true;
}
// mark element as initialized
$this.data('isSwitch', true);
new Switch($this);
});
});
// register UI module
Gumby.UIModule({
module: 'toggleswitch',
events: ['trigger', 'onTrigger'],
init: function() {
// Run initialize methods
Gumby.initialize('switches');
Gumby.initialize('toggles');
}
});
}();

View File

@ -0,0 +1,138 @@
/**
* Gumby jQuery Validation Plugin
*/
!function($) {
'use strict';
function Validation($this, req) {
// input and holder .field
this.$this = $this;
this.$field = this.$this.parents('.field');
// supplied validation function with default length check
this.req = req || function() {
return !!this.$this.val().length;
};
// reference to this class
var scope = this;
// checkboxes and radio buttons use gumby.onChange event to validate
if(this.$this.is('[type=checkbox], [type=radio]')) {
this.$field = this.$this.parent('label');
this.$field.on('gumby.onChange', function() {
scope.validate();
});
// selects validate on change
} else if(this.$this.is('select')) {
this.$field = this.$this.parents('.picker');
this.$field.on('change', function() {
scope.validate();
});
// others (text input, textarea) use blur
} else {
this.$this.on('blur', function(e) {
// ignore tab
if(e.which !== 9) {
scope.validate();
}
});
}
}
// validate field
Validation.prototype.validate = function() {
var result = this.req(this.$this);
// failed
if(!result) {
this.$field.removeClass('success').addClass('danger');
// passed
} else {
//} else if(this.$field.hasClass('danger')) {
this.$field.removeClass('danger').addClass('success');
}
return result;
};
// jQuery plugin definition
$.fn.validation = function(options) {
var // extend params with defaults
settings = $.extend({
submit : false,
fail: false,
required : []
}, options),
// store validation objects
validations = [];
// init each form plugin is called on
return this.each(function() {
// no required fields so plugin is pointless
if(!settings.required.length) {
return false;
}
var $this = $(this),
reqLength = settings.required.length,
i;
// loop round each required field and instantiate new validation object
for(i = 0; i < reqLength; i++) {
validations.push(new Validation(
$this.find('[name="'+settings.required[i].name+'"]'),
settings.required[i].validate || false
));
}
// hijack submit event
$this.on('submit', function(e) {
// reference to whole form pass/fail
var failed = false;
// if no passed attribute found we should halt form submit
if(!$this.data('passed')) {
e.preventDefault();
// loop round validation objects and validate each
var reqLength = validations.length, i;
for(i = 0; i < reqLength; i++) {
if(!validations[i].validate()) {
failed = true;
}
}
// passed
if(!failed) {
// if submit method present call that otherwise submit form
if(settings.submit && typeof settings.submit === 'function') {
settings.submit($this.serializeArray());
return;
}
// store passed bool and re-submit
$this.data('passed', true).submit();
// failed
} else {
// call fail method if present
if(settings.fail && typeof settings.fail === 'function') {
settings.fail();
return;
}
}
}
});
});
};
}(jQuery);

View File

@ -0,0 +1,25 @@
// Gumby is ready to go
Gumby.ready(function() {
console.log('Gumby is ready to go...', Gumby.debug());
// placeholder polyfil
if(Gumby.isOldie || Gumby.$dom.find('html').hasClass('ie9')) {
$('input, textarea').placeholder();
}
});
// Oldie document loaded
Gumby.oldie(function() {
console.log("This is an oldie browser...");
});
// Touch devices loaded
Gumby.touch(function() {
console.log("This is a touch enabled device...");
});
// Document ready
$(function() {
});

View File

@ -0,0 +1,8 @@
window.log=function(){log.history=log.history||[];log.history.push(arguments);if(this.console){arguments.callee=arguments.callee.caller;var a=[].slice.call(arguments);(typeof console.log==="object"?log.apply.call(console.log,console,a):console.log.apply(console,a))}};
(function(b){function c(){}for(var d="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","),a;a=d.pop();){b[a]=b[a]||c}})((function(){try
{console.log();return window.console;}catch(err){return window.console={};}})());
/*! http://mths.be/placeholder v2.0.7 by @mathias */
;(function(f,h,$){var a='placeholder' in h.createElement('input'),d='placeholder' in h.createElement('textarea'),i=$.fn,c=$.valHooks,k,j;if(a&&d){j=i.placeholder=function(){return this};j.input=j.textarea=true}else{j=i.placeholder=function(){var l=this;l.filter((a?'textarea':':input')+'[placeholder]').not('.placeholder').bind({'focus.placeholder':b,'blur.placeholder':e}).data('placeholder-enabled',true).trigger('blur.placeholder');return l};j.input=a;j.textarea=d;k={get:function(m){var l=$(m);return l.data('placeholder-enabled')&&l.hasClass('placeholder')?'':m.value},set:function(m,n){var l=$(m);if(!l.data('placeholder-enabled')){return m.value=n}if(n==''){m.value=n;if(m!=h.activeElement){e.call(m)}}else{if(l.hasClass('placeholder')){b.call(m,true,n)||(m.value=n)}else{m.value=n}}return l}};a||(c.input=k);d||(c.textarea=k);$(function(){$(h).delegate('form','submit.placeholder',function(){var l=$('.placeholder',this).each(b);setTimeout(function(){l.each(e)},10)})});$(f).bind('beforeunload.placeholder',function(){$('.placeholder').each(function(){this.value=''})})}function g(m){var l={},n=/^jQuery\d+$/;$.each(m.attributes,function(p,o){if(o.specified&&!n.test(o.name)){l[o.name]=o.value}});return l}function b(m,n){var l=this,o=$(l);if(l.value==o.attr('placeholder')&&o.hasClass('placeholder')){if(o.data('placeholder-password')){o=o.hide().next().show().attr('id',o.removeAttr('id').data('placeholder-id'));if(m===true){return o[0].value=n}o.focus()}else{l.value='';o.removeClass('placeholder');l==h.activeElement&&l.select()}}}function e(){var q,l=this,p=$(l),m=p,o=this.id;if(l.value==''){if(l.type=='password'){if(!p.data('placeholder-textinput')){try{q=p.clone().attr({type:'text'})}catch(n){q=$('<input>').attr($.extend(g(this),{type:'text'}))}q.removeAttr('name').data({'placeholder-password':true,'placeholder-id':o}).bind('focus.placeholder',b);p.data({'placeholder-textinput':q,'placeholder-id':o}).before(q)}p=p.removeAttr('id').hide().prev().attr('id',o).show()}p.addClass('placeholder');p[0].value=p.attr('placeholder')}else{p.removeClass('placeholder')}}}(this,document,jQuery));
// place any jQuery/helper plugins in here, instead of separate, slower script files.